diff --git a/README.md b/README.md new file mode 100644 index 00000000..e69de29b diff --git a/spec/main/P4Runtime-Spec-bib.aux b/spec/main/P4Runtime-Spec-bib.aux new file mode 100644 index 00000000..511a858b --- /dev/null +++ b/spec/main/P4Runtime-Spec-bib.aux @@ -0,0 +1,180 @@ +% Generated by Madoko, version 1.1.4 +%mdk-data-line={203} +%mdk-data-line={221} +\citation{P4APIWGCharter} +%mdk-data-line={233} +\citation{P4Revisions124} +%mdk-data-line={234} +\citation{P4Revisions124} +%mdk-data-line={240} +\citation{P4Revisions122} +%mdk-data-line={241} +\citation{P4Revisions122} +%mdk-data-line={242} +\citation{P4Revisions122} +%mdk-data-line={244} +\citation{P4Revisions124} +%mdk-data-line={246} +\citation{P4Revisions124} +%mdk-data-line={247} +\citation{P4Revisions124} +%mdk-data-line={249} +\citation{P4Revisions124} +%mdk-data-line={259} +\citation{PSA} +%mdk-data-line={289} +\citation{OpenConfig} +%mdk-data-line={290} +\citation{Stratum} +%mdk-data-line={299} +\citation{P4Spec} +%mdk-data-line={325} +\citation{gRPC} +%mdk-data-line={347} +\citation{Proto} +%mdk-data-line={349} +\citation{PSA} +%mdk-data-line={405} +\citation{P4RuntimeRepo} +%mdk-data-line={411} +\citation{PIRepo} +%mdk-data-line={766} +\citation{gRPCStreamC} +%mdk-data-line={782} +\citation{gRPCAuth} +%mdk-data-line={813} +\citation{ProtoAny} +%mdk-data-line={1057} +\citation{P4Annotations} +%mdk-data-line={1532} +\citation{P4ActionAnnotations} +%mdk-data-line={1570} +\citation{P4TableProperties} +%mdk-data-line={1591} +\citation{ProtoAny} +%mdk-data-line={1592} +\citation{P4TableProperties} +%mdk-data-line={1767} +\citation{RFC2698} +%mdk-data-line={1779} +\citation{RFC2697} +%mdk-data-line={1784} +\citation{RFC2697} +%mdk-data-line={1921} +\citation{P4ValueSets} +%mdk-data-line={1942} +\citation{P4SelectExpr} +%mdk-data-line={1999} +\citation{P4SelectExpr} +%mdk-data-line={2123} +\citation{ProtoAny} +%mdk-data-line={2201} +\citation{ProtoDefaults} +%mdk-data-line={2296} +\citation{ProtoMessageDifferencer} +%mdk-data-line={2329} +\citation{PSA} +%mdk-data-line={2334} +\citation{PNA} +%mdk-data-line={2349} +\citation{PNA} +%mdk-data-line={2353} +\citation{PNA} +%mdk-data-line={2584} +\citation{P4ComplexTypes} +%mdk-data-line={2824} +\citation{P4Enums} +%mdk-data-line={2843} +\citation{P4NewTypes} +%mdk-data-line={3129} +\citation{P4TableProperties} +%mdk-data-line={4132} +\citation{PSAActionSelector} +%mdk-data-line={4169} +\citation{PSAEmptyGroupActionAppendix} +%mdk-data-line={4302} +\citation{RFC2698} +%mdk-data-line={4303} +\citation{RFC2697} +%mdk-data-line={4589} +\citation{PSATranslation} +%mdk-data-line={4652} +\citation{PSATranslation} +%mdk-data-line={4680} +\citation{PSATranslation} +%mdk-data-line={4704} +\citation{PSATranslation} +%mdk-data-line={5001} +\citation{ProtoAny} +%mdk-data-line={5014} +\citation{gRPCStatus} +%mdk-data-line={5023} +\citation{gRPCStatusCodes} +%mdk-data-line={5026} +\citation{ProtoStatus} +%mdk-data-line={5041} +\citation{gRPCStatusCodes} +%mdk-data-line={5051} +\citation{gRPCErrorDetails} +%mdk-data-line={5077} +\citation{PSAAtomicityOfControlPlaneOps} +%mdk-data-line={5079} +\citation{P4Concurrency} +%mdk-data-line={5212} +\citation{gRPCStatusCodes} +%mdk-data-line={5219} +\citation{gRPCStatusCodes} +%mdk-data-line={5423} +\citation{gRPCStreamC} +%mdk-data-line={5471} +\citation{ProtoOneOfBackwardsCompatibility} +%mdk-data-line={5964} +\citation{ProtoAny} +%mdk-data-line={5982} +\citation{gRPCStatusCodes} +%mdk-data-line={6000} +\citation{gRPCStatusCodes} +%mdk-data-line={6069} +\citation{SemVer} +%mdk-data-line={6096} +\citation{PSATranslation} +%mdk-data-line={6345} +\citation{APIVersioning} +%mdk-data-line={6360} +\citation{APIVersioning} +%mdk-data-line={6366} +\citation{APIVersioningBackwardsCompatibility} +%mdk-data-line={6378} +\citation{P4RuntimeRepo} +%mdk-data-line={6379} +\citation{SemVer} +%mdk-data-line={6441} +\citation{ProtoAny} +%mdk-data-line={6473} +\citation{ProtoAny} +%mdk-data-line={6484} +\citation{P4MatchTypes} +%mdk-data-line={6493} +\citation{ProtoAny} +%mdk-data-line={6504} +\citation{P4TableProperties} +%mdk-data-line={6507} +\citation{ProtoAny} +%mdk-data-line={6566} +\citation{ArenaAllocation} +%mdk-data-line={6599} +\citation{v1model} +%mdk-data-line={6817} +\citation{p4c} +%mdk-data-line={6822} +\citation{p4cTestProgramForConstEntries} +%mdk-data-line={6862;build/P4Runtime-Spec-bib.bbl.mdk:2} + + +%mdk-data-line={2617} + +%\cslstyle{madoko-numeric} +%\csllocale{en-US} +\bibdata{references} +%md5:0bf41f4bfe1cdaf0d78d429b0d61a8d9 +%\citestyle{numeric:sort:"[","]",", ",", ",", "} diff --git a/spec/main/P4Runtime-Spec-bib.bbl.mdk b/spec/main/P4Runtime-Spec-bib.bbl.mdk new file mode 100644 index 00000000..4def86ac --- /dev/null +++ b/spec/main/P4Runtime-Spec-bib.bbl.mdk @@ -0,0 +1,182 @@ +~ begin bibliography { .bib-numeric; cite-style:"numeric:'[',']',', '" ; caption:"45" ; data-style:"numeric" ; data-style:'madoko-numeric'; } +~ begin bibitem {id:"P4Spec"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"1"; caption:"$P4_{16}$ 1.2.1 specification&nl;n.d., "; data-line:"references.bib:78"; searchterm:"%24P4_%7B16%7D%24%201.2.1%20specification%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[1\]"} +\/“$P4_{16}$ 1.2.1 Specification.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"RFC2697"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"2"; caption:"A Single Rate Three Color Marker&nl;n.d., "; data-line:"references.bib:154"; searchterm:"A%20Single%20Rate%20Three%20Color%20Marker%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[2\]"} +\/“A Single Rate Three Color Marker.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"RFC2698"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"3"; caption:"A Two Rate Three Color Marker&nl;n.d., "; data-line:"references.bib:149"; searchterm:"A%20Two%20Rate%20Three%20Color%20Marker%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[3\]"} +\/“A Two Rate Three Color Marker.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"ArenaAllocation"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"4"; caption:"C++ Arena Allocation Guide&nl;n.d., "; data-line:"references.bib:224"; searchterm:"C%2B%2B%20Arena%20Allocation%20Guide%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[4\]"} +\/“C++ Arena Allocation Guide.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"P4ComplexTypes"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"5"; caption:"Complex types in $P4_{16}$&nl;n.d., "; data-line:"references.bib:32"; searchterm:"Complex%20types%20in%20%24P4_%7B16%7D%24%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[5\]"} +\/“Complex Types in $P4_{16}$.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"ProtoDefaults"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"6"; caption:"Default values for Protobuf 3 ($proto3$) fields&nl;n.d., "; data-line:"references.bib:37"; searchterm:"Default%20values%20for%20Protobuf%203%20%24proto3%24%20fields%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[6\]"} +\/“Default Values for Protobuf 3 ($proto3$) Fields.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"P4Enums"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"7"; caption:"Enums in $P4_{16}$&nl;n.d., "; data-line:"references.bib:93"; searchterm:"Enums%20in%20%24P4_%7B16%7D%24%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[7\]"} +\/“Enums in $P4_{16}$.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"APIVersioning"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"8"; caption:"Google Cloud APIs versioning&nl;n.d., "; data-line:"references.bib:134"; searchterm:"Google%20Cloud%20APIs%20versioning%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[8\]"} +\/“Google Cloud APIs Versioning.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"APIVersioningBackwardsCompatibility"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"9"; caption:"Google Cloud APIs versioning - Backwards-compatibility&nl;n.d., "; data-line:"references.bib:139"; searchterm:"Google%20Cloud%20APIs%20versioning%20%20Backwardscompatibility%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[9\]"} +\/“Google Cloud APIs Versioning - Backwards-Compatibility.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"gRPCAuth"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"10"; caption:"gRPC Authentication&nl;n.d., "; data-line:"references.bib:169"; searchterm:"gRPC%20Authentication%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[10\]"} +\/“gRPC Authentication.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"gRPC"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"11"; caption:"gRPC main site&nl;n.d., "; data-line:"references.bib:7"; searchterm:"gRPC%20main%20site%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[11\]"} +\/“gRPC Main Site.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"gRPCStreamC"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"12"; caption:"gRPC Streaming RPCs in C++&nl;n.d., "; data-line:"references.bib:164"; searchterm:"gRPC%20Streaming%20RPCs%20in%20C%2B%2B%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[12\]"} +\/“gRPC Streaming RPCs in C++.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"P4NewTypes"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"13"; caption:"Introducing new types in $P4_{16}$&nl;n.d., "; data-line:"references.bib:129"; searchterm:"Introducing%20new%20types%20in%20%24P4_%7B16%7D%24%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[13\]"} +\/“Introducing New Types in $P4_{16}$.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"P4MatchTypes"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"14"; caption:"Match types in P4&nl;n.d., "; data-line:"references.bib:159"; searchterm:"Match%20types%20in%20P4%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[14\]"} +\/“Match Types in P4.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"p4c"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"15"; caption:"P4\_16 reference compiler&nl;n.d., "; data-line:"references.bib:229"; searchterm:"P4%5C_16%20reference%20compiler%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[15\]"} +\/“P4\_16 Reference Compiler.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"p4cTestProgramForConstEntries"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"16"; caption:"P4\_16 reference compiler test program table-entries-ternary-bmv2.p4&nl;n.d., "; data-line:"references.bib:234"; searchterm:"P4%5C_16%20reference%20compiler%20test%20program%20tableentriesternarybmv2.p4%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[16\]"} +\/“P4\_16 Reference Compiler Test Program Table-Entries-Ternary-bmv2.p4.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"P4Annotations"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"17"; caption:"P4 Annotations&nl;n.d., "; data-line:"references.bib:214"; searchterm:"P4%20Annotations%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[17\]"} +\/“P4 Annotations.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"P4Concurrency"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"18"; caption:"P4 Concurrency Model&nl;n.d., "; data-line:"references.bib:194"; searchterm:"P4%20Concurrency%20Model%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[18\]"} +\/“P4 Concurrency Model.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"P4RuntimeRepo"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"19"; caption:"p4lang/p4Runtime repository:P4Runtime Protobuf definition files and specification&nl;n.d., "; data-line:"references.bib:1"; searchterm:"p4lang%2Fp4Runtime%20repository%3AP4Runtime%20Protobuf%20definition%20files%20and%20specification%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[19\]"} +\/“p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"PIRepo"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"20"; caption:"p4lang/PI repository:Legacy repository for P4Runtime, includes reference implementation&nl;n.d., "; data-line:"references.bib:42"; searchterm:"p4lang%2FPI%20repository%3ALegacy%20repository%20for%20P4Runtime%2C%20includes%20reference%20implementation%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[20\]"} +\/“p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"P4APIWGCharter"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"21"; caption:"P4.org API Working Group Charter&nl;n.d., "; data-line:"references.bib:124"; searchterm:"P4.org%20API%20Working%20Group%20Charter%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[21\]"} +\/“P4.org API Working Group Charter.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"P4ActionAnnotations"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"22"; caption:"P4 standard annotations on table actions&nl;n.d., "; data-line:"references.bib:174"; searchterm:"P4%20standard%20annotations%20on%20table%20actions%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[22\]"} +\/“P4 Standard Annotations on Table Actions.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"PNA"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"23"; caption:"Portable NIC Architecture specification (v0.7)&nl;n.d., "; data-line:"references.bib:88"; searchterm:"Portable%20NIC%20Architecture%20specification%20v0.7%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[23\]"} +\/“Portable NIC Architecture Specification (v0.7).” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"PSA"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"24"; caption:"Portable Switch Architecture specification (v1.1.0)&nl;n.d., "; data-line:"references.bib:83"; searchterm:"Portable%20Switch%20Architecture%20specification%20v1.1.0%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[24\]"} +\/“Portable Switch Architecture Specification (v1.1.0).” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"ProtoOneOfBackwardsCompatibility"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"25"; caption:"Protobuf OneOf backwards-compatibility issues&nl;n.d., "; data-line:"references.bib:209"; searchterm:"Protobuf%20OneOf%20backwardscompatibility%20issues%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[25\]"} +\/“Protobuf OneOf Backwards-Compatibility Issues.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"Proto"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"26"; caption:"Protocol buffers main site&nl;n.d., "; data-line:"references.bib:12"; searchterm:"Protocol%20buffers%20main%20site%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[26\]"} +\/“Protocol Buffers Main Site.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"PSAActionSelector"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"27"; caption:"PSA Action Selector&nl;n.d., "; data-line:"references.bib:179"; searchterm:"PSA%20Action%20Selector%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[27\]"} +\/“PSA Action Selector.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"PSAAtomicityOfControlPlaneOps"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"28"; caption:"PSA Atomicity of Control Plane Operations&nl;n.d., "; data-line:"references.bib:189"; searchterm:"PSA%20Atomicity%20of%20Control%20Plane%20Operations%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[28\]"} +\/“PSA Atomicity of Control Plane Operations.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"PSATranslation"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"29"; caption:"PSA Data Plane vs Control Plane Types&nl;n.d., "; data-line:"references.bib:199"; searchterm:"PSA%20Data%20Plane%20vs%20Control%20Plane%20Types%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[29\]"} +\/“PSA Data Plane vs Control Plane Types.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"PSAEmptyGroupActionAppendix"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"30"; caption:"PSA Empty Group Action Appendix&nl;n.d., "; data-line:"references.bib:184"; searchterm:"PSA%20Empty%20Group%20Action%20Appendix%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[30\]"} +\/“PSA Empty Group Action Appendix.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"P4SelectExpr"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"31"; caption:"Select expressions in $P4_{16}$&nl;n.d., "; data-line:"references.bib:58"; searchterm:"Select%20expressions%20in%20%24P4_%7B16%7D%24%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[31\]"} +\/“Select Expressions in $P4_{16}$.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"SemVer"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"32"; caption:"Semantic versioning&nl;n.d., "; data-line:"references.bib:144"; searchterm:"Semantic%20versioning%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[32\]"} +\/“Semantic Versioning.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"ProtoStatus"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"33"; caption:"status.proto:the Protobuf Status message&nl;n.d., "; data-line:"references.bib:113"; searchterm:"status.proto%3Athe%20Protobuf%20Status%20message%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[33\]"} +\/“Status.proto:the Protobuf Status Message.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"P4Revisions122"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"34"; caption:"Summary of changes made in $P4_{16}$ version 1.2.2&nl;n.d., "; data-line:"references.bib:68"; searchterm:"Summary%20of%20changes%20made%20in%20%24P4_%7B16%7D%24%20version%201.2.2%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[34\]"} +\/“Summary of Changes Made in $P4_{16}$ Version 1.2.2.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"P4Revisions124"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"35"; caption:"Summary of changes made in $P4_{16}$ version 1.2.4&nl;n.d., "; data-line:"references.bib:73"; searchterm:"Summary%20of%20changes%20made%20in%20%24P4_%7B16%7D%24%20version%201.2.4%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[35\]"} +\/“Summary of Changes Made in $P4_{16}$ Version 1.2.4.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"P4TableProperties"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"36"; caption:"Table properties in $P4_{16}$&nl;n.d., "; data-line:"references.bib:48"; searchterm:"Table%20properties%20in%20%24P4_%7B16%7D%24%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[36\]"} +\/“Table Properties in $P4_{16}$.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"ProtoAny"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"37"; caption:"the Any Protobuf message&nl;n.d., "; data-line:"references.bib:98"; searchterm:"the%20Any%20Protobuf%20message%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[37\]"} +\/“The Any Protobuf Message.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"gRPCStatus"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"38"; caption:"the gRPC $Status$ class&nl;n.d., "; data-line:"references.bib:103"; searchterm:"the%20gRPC%20%24Status%24%20class%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[38\]"} +\/“The gRPC $Status$ Class.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"gRPCErrorDetails"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"39"; caption:"the gRPC C++ error details library&nl;n.d., "; data-line:"references.bib:119"; searchterm:"the%20gRPC%20C%2B%2B%20error%20details%20library%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[39\]"} +\/“The gRPC C++ Error Details Library.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"gRPCStatusCodes"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"40"; caption:"the gRPC canonical status codes&nl;n.d., "; data-line:"references.bib:108"; searchterm:"the%20gRPC%20canonical%20status%20codes%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[40\]"} +\/“The gRPC Canonical Status Codes.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"OpenConfig"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"41"; caption:"the OpenConfig project&nl;n.d., "; data-line:"references.bib:22"; searchterm:"the%20OpenConfig%20project%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[41\]"} +\/“The OpenConfig Project.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"ProtoMessageDifferencer"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"42"; caption:"The Protobuf MessageDifferencer in the C++ API&nl;n.d., "; data-line:"references.bib:204"; searchterm:"The%20Protobuf%20MessageDifferencer%20in%20the%20C%2B%2B%20API%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[42\]"} +\/“The Protobuf MessageDifferencer in the C++ API.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"Stratum"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"43"; caption:"the Stratum project&nl;n.d., "; data-line:"references.bib:27"; searchterm:"the%20Stratum%20project%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[43\]"} +\/“The Stratum Project.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"v1model"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"44"; caption:"v1model Architecture Definition&nl;n.d., "; data-line:"references.bib:219"; searchterm:"v1model%20Architecture%20Definition%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[44\]"} +\/“v1model Architecture Definition.” {.bib-url}. +~ end bibitem + +~ begin bibitem {id:"P4ValueSets"; cite-authors:"n.d."; cite-authors-long:"n.d."; cite-label:"45"; caption:"Value Sets in $P4_{16}$&nl;n.d., "; data-line:"references.bib:53"; searchterm:"Value%20Sets%20in%20%24P4_%7B16%7D%24%20n.d.%2C%20"; spellcheck:"false"; bibitem-label:"\[45\]"} +\/“Value Sets in $P4_{16}$.” {.bib-url}. +~ end bibitem + +~ end bibliography diff --git a/spec/main/P4Runtime-Spec-bib.bib.json b/spec/main/P4Runtime-Spec-bib.bib.json new file mode 100644 index 00000000..835b9b38 --- /dev/null +++ b/spec/main/P4Runtime-Spec-bib.bib.json @@ -0,0 +1,333 @@ +{ + "_preamble": "", + "_comments": "", + "p4runtimerepo": { + "id": "P4RuntimeRepo", + "type": "webpage", + "title": "p4lang/p4Runtime repository:P4Runtime Protobuf definition files and specification", + "URL": "https://github.com/p4lang/p4runtime", + "_line": "references.bib:1" + }, + "grpc": { + "id": "gRPC", + "type": "webpage", + "title": "gRPC main site", + "URL": "https://grpc.io", + "_line": "references.bib:7" + }, + "proto": { + "id": "Proto", + "type": "webpage", + "title": "Protocol buffers main site", + "URL": "https://developers.google.com/protocol-buffers", + "_line": "references.bib:12" + }, + "p4.org": { + "id": "P4.org", + "type": "webpage", + "title": "P4.org main site", + "URL": "https://p4.org/", + "_line": "references.bib:17" + }, + "openconfig": { + "id": "OpenConfig", + "type": "webpage", + "title": "the OpenConfig project", + "URL": "http://openconfig.net", + "_line": "references.bib:22" + }, + "stratum": { + "id": "Stratum", + "type": "webpage", + "title": "the Stratum project", + "URL": "https://stratumproject.org/", + "_line": "references.bib:27" + }, + "p4complextypes": { + "id": "P4ComplexTypes", + "type": "webpage", + "title": "Complex types in $P4_{16}$", + "URL": "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-p4-type", + "_line": "references.bib:32" + }, + "protodefaults": { + "id": "ProtoDefaults", + "type": "webpage", + "title": "Default values for Protobuf 3 ($proto3$) fields", + "URL": "https://developers.google.com/protocol-buffers/docs/proto3#default", + "_line": "references.bib:37" + }, + "pirepo": { + "id": "PIRepo", + "type": "webpage", + "title": "p4lang/PI repository:Legacy repository for P4Runtime, includes reference implementation", + "URL": "https://github.com/p4lang/PI", + "_line": "references.bib:42" + }, + "p4tableproperties": { + "id": "P4TableProperties", + "type": "webpage", + "title": "Table properties in $P4_{16}$", + "URL": "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-table-props", + "_line": "references.bib:48" + }, + "p4valuesets": { + "id": "P4ValueSets", + "type": "webpage", + "title": "Value Sets in $P4_{16}$", + "URL": "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-value-set", + "_line": "references.bib:53" + }, + "p4selectexpr": { + "id": "P4SelectExpr", + "type": "webpage", + "title": "Select expressions in $P4_{16}$", + "URL": "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-select", + "_line": "references.bib:58" + }, + "p4revisions110": { + "id": "P4Revisions110", + "type": "webpage", + "title": "Summary of changes made in $P4_{16}$ version 1.1.0", + "URL": "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-summary-of-changes-made-in-version-110", + "_line": "references.bib:63" + }, + "p4revisions122": { + "id": "P4Revisions122", + "type": "webpage", + "title": "Summary of changes made in $P4_{16}$ version 1.2.2", + "URL": "https://p4.org/p4-spec/docs/P4-16-v1.2.4.html#sec-summary-of-changes-made-in-version-122-released-may-17-2021", + "_line": "references.bib:68" + }, + "p4revisions124": { + "id": "P4Revisions124", + "type": "webpage", + "title": "Summary of changes made in $P4_{16}$ version 1.2.4", + "URL": "https://p4.org/p4-spec/docs/P4-16-v1.2.4.html#sec-summary-of-changes-made-in-version-124", + "_line": "references.bib:73" + }, + "p4spec": { + "id": "P4Spec", + "type": "webpage", + "title": "$P4_{16}$ 1.2.1 specification", + "URL": "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html", + "_line": "references.bib:78" + }, + "psa": { + "id": "PSA", + "type": "webpage", + "title": "Portable Switch Architecture specification (v1.1.0)", + "URL": "https://p4.org/p4-spec/docs/PSA-v1.1.0.html", + "_line": "references.bib:83" + }, + "pna": { + "id": "PNA", + "type": "webpage", + "title": "Portable NIC Architecture specification (v0.7)", + "URL": "https://p4.org/p4-spec/docs/PNA-v0.7.html", + "_line": "references.bib:88" + }, + "p4enums": { + "id": "P4Enums", + "type": "webpage", + "title": "Enums in $P4_{16}$", + "URL": "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-enum-types", + "_line": "references.bib:93" + }, + "protoany": { + "id": "ProtoAny", + "type": "webpage", + "title": "the Any Protobuf message", + "URL": "https://developers.google.com/protocol-buffers/docs/proto3#any", + "_line": "references.bib:98" + }, + "grpcstatus": { + "id": "gRPCStatus", + "type": "webpage", + "title": "the gRPC $Status$ class", + "URL": "https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/status.h", + "_line": "references.bib:103" + }, + "grpcstatuscodes": { + "id": "gRPCStatusCodes", + "type": "webpage", + "title": "the gRPC canonical status codes", + "URL": "https://developers.google.com/maps-booking/reference/grpc-api/status_codes", + "_line": "references.bib:108" + }, + "protostatus": { + "id": "ProtoStatus", + "type": "webpage", + "title": "status.proto:the Protobuf Status message", + "URL": "https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto", + "_line": "references.bib:113" + }, + "grpcerrordetails": { + "id": "gRPCErrorDetails", + "type": "webpage", + "title": "the gRPC C++ error details library", + "URL": "https://github.com/grpc/grpc/blob/master/include/grpcpp/support/error_details.h", + "_line": "references.bib:119" + }, + "p4apiwgcharter": { + "id": "P4APIWGCharter", + "type": "webpage", + "title": "P4.org API Working Group Charter", + "URL": "https://p4.org/p4-spec/docs/P4_API_WG_charter.html", + "_line": "references.bib:124" + }, + "p4newtypes": { + "id": "P4NewTypes", + "type": "webpage", + "title": "Introducing new types in $P4_{16}$", + "URL": "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-newtype", + "_line": "references.bib:129" + }, + "apiversioning": { + "id": "APIVersioning", + "type": "webpage", + "title": "Google Cloud APIs versioning", + "URL": "https://cloud.google.com/apis/design/versioning", + "_line": "references.bib:134" + }, + "apiversioningbackwardscompatibility": { + "id": "APIVersioningBackwardsCompatibility", + "type": "webpage", + "title": "Google Cloud APIs versioning - Backwards-compatibility", + "URL": "https://cloud.google.com/apis/design/versioning#backwards_compatibility", + "_line": "references.bib:139" + }, + "semver": { + "id": "SemVer", + "type": "webpage", + "title": "Semantic versioning", + "URL": "https://semver.org/", + "_line": "references.bib:144" + }, + "rfc2698": { + "id": "RFC2698", + "type": "webpage", + "title": "A Two Rate Three Color Marker", + "URL": "https://tools.ietf.org/html/rfc2698", + "_line": "references.bib:149" + }, + "rfc2697": { + "id": "RFC2697", + "type": "webpage", + "title": "A Single Rate Three Color Marker", + "URL": "https://tools.ietf.org/html/rfc2697", + "_line": "references.bib:154" + }, + "p4matchtypes": { + "id": "P4MatchTypes", + "type": "webpage", + "title": "Match types in P4", + "URL": "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-match-kind-type", + "_line": "references.bib:159" + }, + "grpcstreamc": { + "id": "gRPCStreamC", + "type": "webpage", + "title": "gRPC Streaming RPCs in C++", + "URL": "https://grpc.io/docs/tutorials/basic/c.html#streaming-rpcs", + "_line": "references.bib:164" + }, + "grpcauth": { + "id": "gRPCAuth", + "type": "webpage", + "title": "gRPC Authentication", + "URL": "https://grpc.io/docs/guides/auth.html", + "_line": "references.bib:169" + }, + "p4actionannotations": { + "id": "P4ActionAnnotations", + "type": "webpage", + "title": "P4 standard annotations on table actions", + "URL": "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-table-action-anno", + "_line": "references.bib:174" + }, + "psaactionselector": { + "id": "PSAActionSelector", + "type": "webpage", + "title": "PSA Action Selector", + "URL": "https://p4.org/p4-spec/docs/PSA-v1.1.0.html#sec-action-selector", + "_line": "references.bib:179" + }, + "psaemptygroupactionappendix": { + "id": "PSAEmptyGroupActionAppendix", + "type": "webpage", + "title": "PSA Empty Group Action Appendix", + "URL": "https://p4.org/p4-spec/docs/PSA-v1.1.0.html#appendix-empty-action-selector-groups", + "_line": "references.bib:184" + }, + "psaatomicityofcontrolplaneops": { + "id": "PSAAtomicityOfControlPlaneOps", + "type": "webpage", + "title": "PSA Atomicity of Control Plane Operations", + "URL": "https://p4.org/p4-spec/docs/PSA-v1.1.0.html#sec-atomicity-of-control-plane-api-operations", + "_line": "references.bib:189" + }, + "p4concurrency": { + "id": "P4Concurrency", + "type": "webpage", + "title": "P4 Concurrency Model", + "URL": "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-concurrency", + "_line": "references.bib:194" + }, + "psatranslation": { + "id": "PSATranslation", + "type": "webpage", + "title": "PSA Data Plane vs Control Plane Types", + "URL": "https://p4.org/p4-spec/docs/PSA-v1.1.0.html#sec-data-plane-vs-control-plane-values", + "_line": "references.bib:199" + }, + "protomessagedifferencer": { + "id": "ProtoMessageDifferencer", + "type": "webpage", + "title": "The Protobuf MessageDifferencer in the C++ API", + "URL": "https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.util.message_differencer", + "_line": "references.bib:204" + }, + "protooneofbackwardscompatibility": { + "id": "ProtoOneOfBackwardsCompatibility", + "type": "webpage", + "title": "Protobuf OneOf backwards-compatibility issues", + "URL": "https://developers.google.com/protocol-buffers/docs/proto3#backwards-compatibility-issues", + "_line": "references.bib:209" + }, + "p4annotations": { + "id": "P4Annotations", + "type": "webpage", + "title": "P4 Annotations", + "URL": "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-annotations", + "_line": "references.bib:214" + }, + "v1model": { + "id": "v1model", + "type": "webpage", + "title": "v1model Architecture Definition", + "URL": "https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4", + "_line": "references.bib:219" + }, + "arenaallocation": { + "id": "ArenaAllocation", + "type": "webpage", + "title": "C++ Arena Allocation Guide", + "URL": "https://developers.google.com/protocol-buffers/docs/reference/arenas", + "_line": "references.bib:224" + }, + "p4c": { + "id": "p4c", + "type": "webpage", + "title": "P4\\_16 reference compiler", + "URL": "https://github.com/p4lang/p4c", + "_line": "references.bib:229" + }, + "p4ctestprogramforconstentries": { + "id": "p4cTestProgramForConstEntries", + "type": "webpage", + "title": "P4\\_16 reference compiler test program table-entries-ternary-bmv2.p4", + "URL": "https://github.com/p4lang/p4c/blob/main/testdata/p4_16_samples/table-entries-ternary-bmv2.p4", + "_line": "references.bib:234" + } +} \ No newline at end of file diff --git a/spec/main/P4Runtime-Spec-bib.final.aux b/spec/main/P4Runtime-Spec-bib.final.aux new file mode 100644 index 00000000..511a858b --- /dev/null +++ b/spec/main/P4Runtime-Spec-bib.final.aux @@ -0,0 +1,180 @@ +% Generated by Madoko, version 1.1.4 +%mdk-data-line={203} +%mdk-data-line={221} +\citation{P4APIWGCharter} +%mdk-data-line={233} +\citation{P4Revisions124} +%mdk-data-line={234} +\citation{P4Revisions124} +%mdk-data-line={240} +\citation{P4Revisions122} +%mdk-data-line={241} +\citation{P4Revisions122} +%mdk-data-line={242} +\citation{P4Revisions122} +%mdk-data-line={244} +\citation{P4Revisions124} +%mdk-data-line={246} +\citation{P4Revisions124} +%mdk-data-line={247} +\citation{P4Revisions124} +%mdk-data-line={249} +\citation{P4Revisions124} +%mdk-data-line={259} +\citation{PSA} +%mdk-data-line={289} +\citation{OpenConfig} +%mdk-data-line={290} +\citation{Stratum} +%mdk-data-line={299} +\citation{P4Spec} +%mdk-data-line={325} +\citation{gRPC} +%mdk-data-line={347} +\citation{Proto} +%mdk-data-line={349} +\citation{PSA} +%mdk-data-line={405} +\citation{P4RuntimeRepo} +%mdk-data-line={411} +\citation{PIRepo} +%mdk-data-line={766} +\citation{gRPCStreamC} +%mdk-data-line={782} +\citation{gRPCAuth} +%mdk-data-line={813} +\citation{ProtoAny} +%mdk-data-line={1057} +\citation{P4Annotations} +%mdk-data-line={1532} +\citation{P4ActionAnnotations} +%mdk-data-line={1570} +\citation{P4TableProperties} +%mdk-data-line={1591} +\citation{ProtoAny} +%mdk-data-line={1592} +\citation{P4TableProperties} +%mdk-data-line={1767} +\citation{RFC2698} +%mdk-data-line={1779} +\citation{RFC2697} +%mdk-data-line={1784} +\citation{RFC2697} +%mdk-data-line={1921} +\citation{P4ValueSets} +%mdk-data-line={1942} +\citation{P4SelectExpr} +%mdk-data-line={1999} +\citation{P4SelectExpr} +%mdk-data-line={2123} +\citation{ProtoAny} +%mdk-data-line={2201} +\citation{ProtoDefaults} +%mdk-data-line={2296} +\citation{ProtoMessageDifferencer} +%mdk-data-line={2329} +\citation{PSA} +%mdk-data-line={2334} +\citation{PNA} +%mdk-data-line={2349} +\citation{PNA} +%mdk-data-line={2353} +\citation{PNA} +%mdk-data-line={2584} +\citation{P4ComplexTypes} +%mdk-data-line={2824} +\citation{P4Enums} +%mdk-data-line={2843} +\citation{P4NewTypes} +%mdk-data-line={3129} +\citation{P4TableProperties} +%mdk-data-line={4132} +\citation{PSAActionSelector} +%mdk-data-line={4169} +\citation{PSAEmptyGroupActionAppendix} +%mdk-data-line={4302} +\citation{RFC2698} +%mdk-data-line={4303} +\citation{RFC2697} +%mdk-data-line={4589} +\citation{PSATranslation} +%mdk-data-line={4652} +\citation{PSATranslation} +%mdk-data-line={4680} +\citation{PSATranslation} +%mdk-data-line={4704} +\citation{PSATranslation} +%mdk-data-line={5001} +\citation{ProtoAny} +%mdk-data-line={5014} +\citation{gRPCStatus} +%mdk-data-line={5023} +\citation{gRPCStatusCodes} +%mdk-data-line={5026} +\citation{ProtoStatus} +%mdk-data-line={5041} +\citation{gRPCStatusCodes} +%mdk-data-line={5051} +\citation{gRPCErrorDetails} +%mdk-data-line={5077} +\citation{PSAAtomicityOfControlPlaneOps} +%mdk-data-line={5079} +\citation{P4Concurrency} +%mdk-data-line={5212} +\citation{gRPCStatusCodes} +%mdk-data-line={5219} +\citation{gRPCStatusCodes} +%mdk-data-line={5423} +\citation{gRPCStreamC} +%mdk-data-line={5471} +\citation{ProtoOneOfBackwardsCompatibility} +%mdk-data-line={5964} +\citation{ProtoAny} +%mdk-data-line={5982} +\citation{gRPCStatusCodes} +%mdk-data-line={6000} +\citation{gRPCStatusCodes} +%mdk-data-line={6069} +\citation{SemVer} +%mdk-data-line={6096} +\citation{PSATranslation} +%mdk-data-line={6345} +\citation{APIVersioning} +%mdk-data-line={6360} +\citation{APIVersioning} +%mdk-data-line={6366} +\citation{APIVersioningBackwardsCompatibility} +%mdk-data-line={6378} +\citation{P4RuntimeRepo} +%mdk-data-line={6379} +\citation{SemVer} +%mdk-data-line={6441} +\citation{ProtoAny} +%mdk-data-line={6473} +\citation{ProtoAny} +%mdk-data-line={6484} +\citation{P4MatchTypes} +%mdk-data-line={6493} +\citation{ProtoAny} +%mdk-data-line={6504} +\citation{P4TableProperties} +%mdk-data-line={6507} +\citation{ProtoAny} +%mdk-data-line={6566} +\citation{ArenaAllocation} +%mdk-data-line={6599} +\citation{v1model} +%mdk-data-line={6817} +\citation{p4c} +%mdk-data-line={6822} +\citation{p4cTestProgramForConstEntries} +%mdk-data-line={6862;build/P4Runtime-Spec-bib.bbl.mdk:2} + + +%mdk-data-line={2617} + +%\cslstyle{madoko-numeric} +%\csllocale{en-US} +\bibdata{references} +%md5:0bf41f4bfe1cdaf0d78d429b0d61a8d9 +%\citestyle{numeric:sort:"[","]",", ",", ",", "} diff --git a/spec/main/P4Runtime-Spec-math-full.final.tex b/spec/main/P4Runtime-Spec-math-full.final.tex new file mode 100644 index 00000000..20efe055 --- /dev/null +++ b/spec/main/P4Runtime-Spec-math-full.final.tex @@ -0,0 +1,24 @@ +% MathMode: full, MathRender: png, MathDpi: 300, MathEmbedLimit: 524288, MathScale: 108, MathBaseline: 0, MathDocClass: [10pt]book, MathImgDir: math, MathLatex: latex, Dvipng: dvipng, Convert: convert, Dvips: dvips, Ps2pdf: ps2pdf +\documentclass[10pt]{book} +% generated by Madoko, version 1.1.4 +%mdk-data-line={1} +\newcommand\mdmathmode{full} +\newcommand\mdmathrender{png} +\usepackage[heading-base={2},section-num={false},bib-label={true},fontspec={true}]{madoko2} +\usepackage[top=1in, bottom=1.25in, left=1in, right=1in]{geometry} +\usepackage{fancyhdr} +%mdk-data-line={11} + + \setlength{\headheight}{30pt} + \setlength{\emergencystretch}{2em} + +\begin{document} + + +\begin{mdSnippets} +%mdk-data-line={203} +%mdk-data-line={2617} + +\end{mdSnippets} + +\end{document} diff --git a/spec/main/P4Runtime-Spec-math-plain.aux b/spec/main/P4Runtime-Spec-math-plain.aux new file mode 100644 index 00000000..bf551e58 --- /dev/null +++ b/spec/main/P4Runtime-Spec-math-plain.aux @@ -0,0 +1,19 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\providecommand\BKM@entry[2]{} +\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument} +\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined +\global\let\oldcontentsline\contentsline +\gdef\contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}} +\global\let\oldnewlabel\newlabel +\gdef\newlabel#1#2{\newlabelxx{#1}#2} +\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}} +\AtEndDocument{\ifx\hyper@anchor\@undefined +\let\contentsline\oldcontentsline +\let\newlabel\oldnewlabel +\fi} +\fi} +\global\let\hyper@last\relax +\gdef\HyperFirstAtBeginDocument#1{#1} +\providecommand*\HyPL@Entry[1]{} +\HyPL@Entry{0<>} diff --git a/spec/main/P4Runtime-Spec-math-plain.dim b/spec/main/P4Runtime-Spec-math-plain.dim new file mode 100644 index 00000000..73b1769c --- /dev/null +++ b/spec/main/P4Runtime-Spec-math-plain.dim @@ -0,0 +1,59 @@ +\%ordinal,(hash)name,width,(total) height,depth,image width,image height,bbox padding,size,mime,data-url +1,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +2,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +3,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +4,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +5,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +6,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +7,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +8,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +9,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +10,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +11,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +12,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +13,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +14,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +15,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +16,2002bba10a26e42e7324f3842669c712,28.1262pt,8.38889pt,1.94444pt +17,fa3dbcbaeabd35dbb24e3f66f0cbfe14,26.3888pt,7.22429pt,0.39098pt +18,7fc56270e7a70fa81a5935b72eacbe29,7.50002pt,6.83331pt,0.0pt +19,c2043615bebb807e33158410ceb0a1fe,50.12486pt,9.77197pt,1.35971pt +20,8f21874330b0b0d2f91e831f2f0e7f6a,26.3888pt,8.88887pt,1.94443pt +21,7fc56270e7a70fa81a5935b72eacbe29,7.50002pt,6.83331pt,0.0pt +22,323b77d22bf5c16cfde8f2ac3446a479,103.2221pt,9.77197pt,1.35971pt +23,67d25a48b1450fb4f887f3329a504ab8,26.3888pt,6.83331pt,0.0pt +24,a5a2929bc80363d4ffe77ca4cf1911b8,25.83325pt,6.83331pt,0.0pt +25,5206560a306a2e085a437fd258eb57ce,8.05556pt,6.83331pt,0.0pt +26,7fc56270e7a70fa81a5935b72eacbe29,7.50002pt,6.83331pt,0.0pt +27,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +28,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +29,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +30,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +31,ec53a8c4f07baed5d8825072c89799be,29.62851pt,6.83331pt,0.0pt +32,5dbc98dcc983a70728bd082d1a47546e,6.70831pt,6.83331pt,0.0pt +33,d20caec3b48a1eef164cb4ca81ba2587,6.80557pt,6.83331pt,0.0pt +34,5dbc98dcc983a70728bd082d1a47546e,6.70831pt,6.83331pt,0.0pt +35,d20caec3b48a1eef164cb4ca81ba2587,6.80557pt,6.83331pt,0.0pt +36,d33def0eb4933f91b88eb4e784adaf05,10.21071pt,5.80553pt,1.49998pt +37,89ae78be880a004aa5404ac874a01bff,10.21071pt,5.80553pt,1.49998pt +38,d33def0eb4933f91b88eb4e784adaf05,10.21071pt,5.80553pt,1.49998pt +39,89ae78be880a004aa5404ac874a01bff,10.21071pt,5.80553pt,1.49998pt +40,d33def0eb4933f91b88eb4e784adaf05,10.21071pt,5.80553pt,1.49998pt +41,89ae78be880a004aa5404ac874a01bff,10.21071pt,5.80553pt,1.49998pt +42,d20caec3b48a1eef164cb4ca81ba2587,6.80557pt,6.83331pt,0.0pt +43,d20caec3b48a1eef164cb4ca81ba2587,6.80557pt,6.83331pt,0.0pt +44,5dbc98dcc983a70728bd082d1a47546e,6.70831pt,6.83331pt,0.0pt +45,5dbc98dcc983a70728bd082d1a47546e,6.70831pt,6.83331pt,0.0pt +46,d20caec3b48a1eef164cb4ca81ba2587,6.80557pt,6.83331pt,0.0pt +47,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +48,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +49,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +50,2002bba10a26e42e7324f3842669c712,28.1262pt,8.38889pt,1.94444pt +51,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +52,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +53,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +54,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +55,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +56,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt +57,ec53a8c4f07baed5d8825072c89799be,29.62851pt,6.83331pt,0.0pt +58,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt diff --git a/spec/main/P4Runtime-Spec-math-plain.dvi b/spec/main/P4Runtime-Spec-math-plain.dvi new file mode 100644 index 00000000..4def83dd Binary files /dev/null and b/spec/main/P4Runtime-Spec-math-plain.dvi differ diff --git a/spec/main/P4Runtime-Spec-math-plain.final.tex b/spec/main/P4Runtime-Spec-math-plain.final.tex new file mode 100644 index 00000000..673e9aee --- /dev/null +++ b/spec/main/P4Runtime-Spec-math-plain.final.tex @@ -0,0 +1,188 @@ +% MathMode: plain, MathRender: png, MathDpi: 300, MathEmbedLimit: 524288, MathScale: 108, MathBaseline: 0, MathDocClass: [10pt]book, MathImgDir: math, MathLatex: latex, Dvipng: dvipng, Convert: convert, Dvips: dvips, Ps2pdf: ps2pdf +\documentclass[10pt]{book} +% generated by Madoko, version 1.1.4 +%mdk-data-line={1} +\newcommand\mdmathmode{plain} +\newcommand\mdmathrender{png} +\usepackage[heading-base={2},section-num={false},bib-label={true},fontspec={true}]{madoko2} +\usepackage[top=1in, bottom=1.25in, left=1in, right=1in]{geometry} +\usepackage{fancyhdr} +%mdk-data-line={11} + + \setlength{\headheight}{30pt} + \setlength{\emergencystretch}{2em} + +\begin{document} + + +\begin{mdSnippets} +%mdk-data-line={203} +%mdk-data-line={233} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={234} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={240} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={241} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={242} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={244} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={246} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={247} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={249} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={299} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={1570} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={1592} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={1921} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={1942} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={1999} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={2201} +\begin{mdInlineSnippet}[2002bba10a26e42e7324f3842669c712]%mdk +$proto3$\end{mdInlineSnippet}%mdk +%mdk-data-line={2453} +\begin{mdInlineSnippet}[fa3dbcbaeabd35dbb24e3f66f0cbfe14]%mdk +$V > 0$\end{mdInlineSnippet}%mdk +%mdk-data-line={2453} +\begin{mdInlineSnippet}[7fc56270e7a70fa81a5935b72eacbe29]%mdk +$A$\end{mdInlineSnippet}%mdk +%mdk-data-line={2453} +\begin{mdInlineSnippet}[c2043615bebb807e33158410ceb0a1fe]%mdk +$V \leq 2^A -1$\end{mdInlineSnippet}%mdk +%mdk-data-line={2457} +\begin{mdInlineSnippet}[8f21874330b0b0d2f91e831f2f0e7f6a]%mdk +$V \neq 0$\end{mdInlineSnippet}%mdk +%mdk-data-line={2457} +\begin{mdInlineSnippet}[7fc56270e7a70fa81a5935b72eacbe29]%mdk +$A$\end{mdInlineSnippet}%mdk +%mdk-data-line={2458} +\begin{mdInlineSnippet}[323b77d22bf5c16cfde8f2ac3446a479]%mdk +$-2^{A-1} \leq V \leq 2^{A-1} - 1$\end{mdInlineSnippet}%mdk +%mdk-data-line={2460} +\begin{mdInlineSnippet}[67d25a48b1450fb4f887f3329a504ab8]%mdk +$V=0$\end{mdInlineSnippet}%mdk +%mdk-data-line={2460} +\begin{mdInlineSnippet}[a5a2929bc80363d4ffe77ca4cf1911b8]%mdk +$A=1$\end{mdInlineSnippet}%mdk +%mdk-data-line={2463} +\begin{mdInlineSnippet}[5206560a306a2e085a437fd258eb57ce]%mdk +$V$\end{mdInlineSnippet}%mdk +%mdk-data-line={2463} +\begin{mdInlineSnippet}[7fc56270e7a70fa81a5935b72eacbe29]%mdk +$A$\end{mdInlineSnippet}%mdk +%mdk-data-line={2584} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={2824} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={2843} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={3129} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={5014} +\begin{mdInlineSnippet}[ec53a8c4f07baed5d8825072c89799be]%mdk +$Status$\end{mdInlineSnippet}%mdk +%mdk-data-line={5240} +\begin{mdInlineSnippet}[5dbc98dcc983a70728bd082d1a47546e]%mdk +$S$\end{mdInlineSnippet}%mdk +%mdk-data-line={5241} +\begin{mdInlineSnippet}[d20caec3b48a1eef164cb4ca81ba2587]%mdk +$L$\end{mdInlineSnippet}%mdk +%mdk-data-line={5241} +\begin{mdInlineSnippet}[5dbc98dcc983a70728bd082d1a47546e]%mdk +$S$\end{mdInlineSnippet}%mdk +%mdk-data-line={5244} +\begin{mdInlineSnippet}[d20caec3b48a1eef164cb4ca81ba2587]%mdk +$L$\end{mdInlineSnippet}%mdk +%mdk-data-line={5245} +\begin{mdInlineSnippet}[d33def0eb4933f91b88eb4e784adaf05]%mdk +$u_1$\end{mdInlineSnippet}%mdk +%mdk-data-line={5245} +\begin{mdInlineSnippet}[89ae78be880a004aa5404ac874a01bff]%mdk +$u_2$\end{mdInlineSnippet}%mdk +%mdk-data-line={5245} +\begin{mdInlineSnippet}[d33def0eb4933f91b88eb4e784adaf05]%mdk +$u_1$\end{mdInlineSnippet}%mdk +%mdk-data-line={5246} +\begin{mdInlineSnippet}[89ae78be880a004aa5404ac874a01bff]%mdk +$u_2$\end{mdInlineSnippet}%mdk +%mdk-data-line={5246} +\begin{mdInlineSnippet}[d33def0eb4933f91b88eb4e784adaf05]%mdk +$u_1$\end{mdInlineSnippet}%mdk +%mdk-data-line={5247} +\begin{mdInlineSnippet}[89ae78be880a004aa5404ac874a01bff]%mdk +$u_2$\end{mdInlineSnippet}%mdk +%mdk-data-line={5247} +\begin{mdInlineSnippet}[d20caec3b48a1eef164cb4ca81ba2587]%mdk +$L$\end{mdInlineSnippet}%mdk +%mdk-data-line={5248} +\begin{mdInlineSnippet}[d20caec3b48a1eef164cb4ca81ba2587]%mdk +$L$\end{mdInlineSnippet}%mdk +%mdk-data-line={5249} +\begin{mdInlineSnippet}[5dbc98dcc983a70728bd082d1a47546e]%mdk +$S$\end{mdInlineSnippet}%mdk +%mdk-data-line={5250} +\begin{mdInlineSnippet}[5dbc98dcc983a70728bd082d1a47546e]%mdk +$S$\end{mdInlineSnippet}%mdk +%mdk-data-line={5251} +\begin{mdInlineSnippet}[d20caec3b48a1eef164cb4ca81ba2587]%mdk +$L$\end{mdInlineSnippet}%mdk +%mdk-data-line={6504} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={6862;build/P4Runtime-Spec-bib.bbl.mdk:2} +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +\begin{mdInlineSnippet}[2002bba10a26e42e7324f3842669c712]%mdk +$proto3$\end{mdInlineSnippet}%mdk +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +\begin{mdInlineSnippet}[ec53a8c4f07baed5d8825072c89799be]%mdk +$Status$\end{mdInlineSnippet}%mdk +\begin{mdInlineSnippet}[45bea56774116dfcbe5c62b4067ed3dd]%mdk +$P4_{16}$\end{mdInlineSnippet}%mdk +%mdk-data-line={2617} + +\end{mdSnippets} + +\end{document} diff --git a/spec/main/P4Runtime-Spec-math-plain.log b/spec/main/P4Runtime-Spec-math-plain.log new file mode 100644 index 00000000..39903e3c --- /dev/null +++ b/spec/main/P4Runtime-Spec-math-plain.log @@ -0,0 +1,643 @@ +This is pdfTeX, Version 3.14159265-2.6-1.40.16 (TeX Live 2015/Debian) (preloaded format=latex 2018.8.17) 16 SEP 2024 18:50 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**build/P4Runtime-Spec-math-plain.tex +(./build/P4Runtime-Spec-math-plain.tex +LaTeX2e <2016/02/01> +Babel <3.9q> and hyphenation patterns for 81 language(s) loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/book.cls +Document Class: book 2014/09/29 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/bk10.clo +File: bk10.clo 2014/09/29 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@chapter=\count80 +\c@section=\count81 +\c@subsection=\count82 +\c@subsubsection=\count83 +\c@paragraph=\count84 +\c@subparagraph=\count85 +\c@figure=\count86 +\c@table=\count87 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) (build/madoko2.sty (/usr/share/texlive/texmf-dist/tex/latex/colortbl/colortbl.sty +Package: colortbl 2012/02/13 v1.0a Color table columns (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty +Package: array 2014/10/28 v2.4c Tabular extension package (FMi) +\col@sep=\dimen103 +\extrarowheight=\dimen104 +\NC@list=\toks14 +\extratabsurround=\skip43 +\backup@length=\skip44 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty +Package: color 2016/01/03 v1.1b Standard LaTeX Color (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package color Info: Driver file: dvips.def on input line 143. +(/usr/share/texlive/texmf-dist/tex/latex/graphics/dvips.def +File: dvips.def 2015/12/30 v3.0k Driver-dependent file (DPC,SPQR) +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/dvipsnam.def +File: dvipsnam.def 2015/12/30 v3.0k Driver-dependent file (DPC,SPQR) +)) +\everycr=\toks15 +\minrowclearance=\skip45 +) (/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: dvips.def on input line 225. +LaTeX Info: Redefining \color on input line 702. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) (build/options.sty +Package: options 2015/03/01, Daan Leijen, Provides convenient path-value (or key-value) options +(/usr/share/texlive/texmf-dist/tex/latex/etoolbox/etoolbox.sty +Package: etoolbox 2015/08/02 v2.2a e-TeX tools for LaTeX (JAW) +\etb@tempcnta=\count88 +) +\opt@nesting=\count89 +\opt@idx=\count90 +\opt@choiceord=\count91 +) (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty +Package: iftex 2013/04/04 v0.2 Provides if(tex) conditional for PDFTeX, XeTeX, and LuaTeX +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2014/10/28 v1.0g Enhanced LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks16 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2016/01/03 v1.0q Standard LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2016/01/03 v1.10 sin cos tan (DPC) +) (/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg +File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live +) +Package graphics Info: Driver file: dvips.def on input line 95. +) +\Gin@req@height=\dimen105 +\Gin@req@width=\dimen106 +) (build/longfbox.sty +Package: longfbox 2015/12/01, Daan Leijen, Provides long fbox that can break over pages +(build/longbox.sty +Package: longbox 2015/12/01, Daan Leijen, Provides basic longbox that can break over pages +(/usr/share/texlive/texmf-dist/tex/latex/mdwtools/footnote.sty +Package: footnote 1997/01/28 1.13 Save footnotes around boxes +\fn@notes=\box26 +\fn@width=\dimen107 +) +\lb@prevdepth=\skip46 +\lb@freevspace=\skip47 +\lb@headbox=\box27 +\lb@savebox=\box28 +\lb@mainbox=\box29 +\lb@usevbox=\count92 +\lb@width=\skip48 +\lb@height=\skip49 +\lb@skiptop=\skip50 +\lb@skipright=\skip51 +\lb@skipbottom=\skip52 +\lb@skipleft=\skip53 +\lb@skipbreaktop=\skip54 +\lb@skipbreakbottom=\skip55 +\lb@outerwidth=\skip56 +\lb@extrasplit=\skip57 +\lb@textalign=\count93 +\lb@baseline=\count94 +\lb@neededvspace=\skip58 +\lb@splitheight=\skip59 +\lb@insurance=\skip60 +\/longbox/@part-height=\skip61 +\/longbox/@part-width=\skip62 +\/longbox/@part-depth=\skip63 +\/longbox/@content-box-height=\skip64 +\/longbox/@content-box-width=\skip65 +\/longbox/@content-box-depth=\skip66 +\/longbox/@breakat-previous=\skip67 +\/longbox/@lower=\skip68 +\/longbox/split-minimum=\skip69 +\/longbox/split-badness=\skip70 +\/longbox/raise=\skip71 +\/longbox/height=\skip72 +\/longbox/width=\skip73 +\/longbox/outer-height=\skip74 +\/longbox/outer-width=\skip75 +\/longbox/skip-top=\skip76 +\/longbox/skip-right=\skip77 +\/longbox/skip-bottom=\skip78 +\/longbox/skip-left=\skip79 +\/longbox/skip-break-bottom=\skip80 +\/longbox/skip-break-top=\skip81 +) (/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.sty +Package: pict2e 2016/02/05 v0.3b Improved picture commands (HjG,RN,JT) +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.cfg +File: pict2e.cfg 2016/02/05 v0.1u pict2e configuration for teTeX/TeXLive +) +Package pict2e Info: Driver file: dvips.def on input line 119. +Package pict2e Info: Driver file for pict2e: p2e-dvips.def on input line 121. +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/p2e-dvips.def +File: p2e-dvips.def 2016/02/05 v0.1u Driver-dependant file (RN,HjG,JT) +) +\pIIe@GRAPH=\toks17 +\@arclen=\dimen108 +\@arcrad=\dimen109 +\@tempdimd=\dimen110 +) (build/ellipse.sty +Package: ellipse 2004/11/05 v1.0 .dtx ellipse file +) +\fbox@oct=\count95 +\fbox@quad=\count96 +\fbox@diaq=\count97 +\fbox@sign=\count98 +\fbox@anglestart=\skip82 +\fbox@angleend=\skip83 +\fbox@dash=\skip84 +\fbox@dashskip=\skip85 +\fbox@anglecur=\skip86 +\fbox@dashangle=\skip87 +\fbox@dashskipangle=\skip88 +\fbox@delta=\skip89 +\fbox@from=\skip90 +\fbox@to=\skip91 +\/fbox/padding-top=\skip92 +\/fbox/padding-right=\skip93 +\/fbox/padding-bottom=\skip94 +\/fbox/padding-left=\skip95 +\/fbox/padding-break-top=\skip96 +\/fbox/padding-break-bottom=\skip97 +\/fbox/margin-top=\skip98 +\/fbox/margin-right=\skip99 +\/fbox/margin-bottom=\skip100 +\/fbox/margin-left=\skip101 +\/fbox/margin-break-top=\skip102 +\/fbox/margin-break-bottom=\skip103 +\/fbox/border-top-width=\skip104 +\/fbox/border-right-width=\skip105 +\/fbox/border-bottom-width=\skip106 +\/fbox/border-left-width=\skip107 +\/fbox/border-break-top-width=\skip108 +\/fbox/border-break-bottom-width=\skip109 +\/fbox/@lower=\skip110 +\/fbox/@padding-box-height=\skip111 +\/fbox/@padding-box-depth=\skip112 +\/fbox/@padding-box-width=\skip113 +\/fbox/@border-box-width=\skip114 +\/fbox/@border-box-height=\skip115 +\/fbox/@border-box-depth=\skip116 +\/fbox/@border-top-left-radius-x=\skip117 +\/fbox/@border-top-right-radius-x=\skip118 +\/fbox/@border-bottom-left-radius-x=\skip119 +\/fbox/@border-bottom-right-radius-x=\skip120 +\/fbox/@border-top-left-radius-y=\skip121 +\/fbox/@border-top-right-radius-y=\skip122 +\/fbox/@border-bottom-left-radius-y=\skip123 +\/fbox/@border-bottom-right-radius-y=\skip124 +\/fbox/@border-top-left-ix=\skip125 +\/fbox/@border-top-left-iy=\skip126 +\/fbox/@border-top-right-ix=\skip127 +\/fbox/@border-top-right-iy=\skip128 +\/fbox/@border-bottom-left-ix=\skip129 +\/fbox/@border-bottom-left-iy=\skip130 +\/fbox/@border-bottom-right-ix=\skip131 +\/fbox/@border-bottom-right-iy=\skip132 +\/fbox/@border-top-left-phi=\skip133 +\/fbox/@border-top-right-phi=\skip134 +\/fbox/@border-bottom-left-phi=\skip135 +\/fbox/@border-bottom-right-phi=\skip136 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2016/03/03 v2.15a AMS math features +\@mathmargin=\skip137 +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2000/06/29 v2.01 AMS text +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen111 +)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen112 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 1999/12/14 v2.01 operator names +) +\inf@bad=\count99 +LaTeX Info: Redefining \frac on input line 199. +\uproot@=\count100 +\leftroot@=\count101 +LaTeX Info: Redefining \overline on input line 297. +\classnum@=\count102 +\DOTSCASE@=\count103 +LaTeX Info: Redefining \ldots on input line 394. +LaTeX Info: Redefining \dots on input line 397. +LaTeX Info: Redefining \cdots on input line 518. +\Mathstrutbox@=\box30 +\strutbox@=\box31 +\big@size=\dimen113 +LaTeX Font Info: Redeclaring font encoding OML on input line 630. +LaTeX Font Info: Redeclaring font encoding OMS on input line 631. +\macc@depth=\count104 +\c@MaxMatrixCols=\count105 +\dotsspace@=\muskip10 +\c@parentequation=\count106 +\dspbrk@lvl=\count107 +\tag@help=\toks19 +\row@=\count108 +\column@=\count109 +\maxfields@=\count110 +\andhelp@=\toks20 +\eqnshift@=\dimen114 +\alignsep@=\dimen115 +\tagshift@=\dimen116 +\tagwidth@=\dimen117 +\totwidth@=\dimen118 +\lineht@=\dimen119 +\@envbody=\toks21 +\multlinegap=\skip138 +\multlinetaggap=\skip139 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2735. +LaTeX Info: Redefining \] on input line 2736. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +) (/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/stmaryrd.sty +Package: stmaryrd 1994/03/03 St Mary's Road symbol package +\symstmry=\mathgroup6 +LaTeX Font Info: Overwriting symbol font `stmry' in version `bold' +(Font) U/stmry/m/n --> U/stmry/b/n on input line 89. +) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty +Package: textcomp 2005/09/27 v1.99g Standard LaTeX package +Package textcomp Info: Sub-encoding information: +(textcomp) 5 = only ISO-Adobe without \textcurrency +(textcomp) 4 = 5 + \texteuro +(textcomp) 3 = 4 + \textohm +(textcomp) 2 = 3 + \textestimated + \textcurrency +(textcomp) 1 = TS1 - \textcircled - \t +(textcomp) 0 = TS1 (full) +(textcomp) Font families with sub-encoding setting implement +(textcomp) only a restricted character set as indicated. +(textcomp) Family '?' is the default used for unknown fonts. +(textcomp) See the documentation for details. +Package textcomp Info: Setting ? sub-encoding to TS1/1 on input line 79. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +) +LaTeX Info: Redefining \oldstylenums on input line 334. +Package textcomp Info: Setting cmr sub-encoding to TS1/0 on input line 349. +Package textcomp Info: Setting cmss sub-encoding to TS1/0 on input line 350. +Package textcomp Info: Setting cmtt sub-encoding to TS1/0 on input line 351. +Package textcomp Info: Setting cmvtt sub-encoding to TS1/0 on input line 352. +Package textcomp Info: Setting cmbr sub-encoding to TS1/0 on input line 353. +Package textcomp Info: Setting cmtl sub-encoding to TS1/0 on input line 354. +Package textcomp Info: Setting ccr sub-encoding to TS1/0 on input line 355. +Package textcomp Info: Setting ptm sub-encoding to TS1/4 on input line 356. +Package textcomp Info: Setting pcr sub-encoding to TS1/4 on input line 357. +Package textcomp Info: Setting phv sub-encoding to TS1/4 on input line 358. +Package textcomp Info: Setting ppl sub-encoding to TS1/3 on input line 359. +Package textcomp Info: Setting pag sub-encoding to TS1/4 on input line 360. +Package textcomp Info: Setting pbk sub-encoding to TS1/4 on input line 361. +Package textcomp Info: Setting pnc sub-encoding to TS1/4 on input line 362. +Package textcomp Info: Setting pzc sub-encoding to TS1/4 on input line 363. +Package textcomp Info: Setting bch sub-encoding to TS1/4 on input line 364. +Package textcomp Info: Setting put sub-encoding to TS1/5 on input line 365. +Package textcomp Info: Setting uag sub-encoding to TS1/5 on input line 366. +Package textcomp Info: Setting ugq sub-encoding to TS1/5 on input line 367. +Package textcomp Info: Setting ul8 sub-encoding to TS1/4 on input line 368. +Package textcomp Info: Setting ul9 sub-encoding to TS1/4 on input line 369. +Package textcomp Info: Setting augie sub-encoding to TS1/5 on input line 370. +Package textcomp Info: Setting dayrom sub-encoding to TS1/3 on input line 371. +Package textcomp Info: Setting dayroms sub-encoding to TS1/3 on input line 372. +Package textcomp Info: Setting pxr sub-encoding to TS1/0 on input line 373. +Package textcomp Info: Setting pxss sub-encoding to TS1/0 on input line 374. +Package textcomp Info: Setting pxtt sub-encoding to TS1/0 on input line 375. +Package textcomp Info: Setting txr sub-encoding to TS1/0 on input line 376. +Package textcomp Info: Setting txss sub-encoding to TS1/0 on input line 377. +Package textcomp Info: Setting txtt sub-encoding to TS1/0 on input line 378. +Package textcomp Info: Setting lmr sub-encoding to TS1/0 on input line 379. +Package textcomp Info: Setting lmdh sub-encoding to TS1/0 on input line 380. +Package textcomp Info: Setting lmss sub-encoding to TS1/0 on input line 381. +Package textcomp Info: Setting lmssq sub-encoding to TS1/0 on input line 382. +Package textcomp Info: Setting lmvtt sub-encoding to TS1/0 on input line 383. +Package textcomp Info: Setting lmtt sub-encoding to TS1/0 on input line 384. +Package textcomp Info: Setting qhv sub-encoding to TS1/0 on input line 385. +Package textcomp Info: Setting qag sub-encoding to TS1/0 on input line 386. +Package textcomp Info: Setting qbk sub-encoding to TS1/0 on input line 387. +Package textcomp Info: Setting qcr sub-encoding to TS1/0 on input line 388. +Package textcomp Info: Setting qcs sub-encoding to TS1/0 on input line 389. +Package textcomp Info: Setting qpl sub-encoding to TS1/0 on input line 390. +Package textcomp Info: Setting qtm sub-encoding to TS1/0 on input line 391. +Package textcomp Info: Setting qzc sub-encoding to TS1/0 on input line 392. +Package textcomp Info: Setting qhvc sub-encoding to TS1/0 on input line 393. +Package textcomp Info: Setting futs sub-encoding to TS1/4 on input line 394. +Package textcomp Info: Setting futx sub-encoding to TS1/4 on input line 395. +Package textcomp Info: Setting futj sub-encoding to TS1/4 on input line 396. +Package textcomp Info: Setting hlh sub-encoding to TS1/3 on input line 397. +Package textcomp Info: Setting hls sub-encoding to TS1/3 on input line 398. +Package textcomp Info: Setting hlst sub-encoding to TS1/3 on input line 399. +Package textcomp Info: Setting hlct sub-encoding to TS1/5 on input line 400. +Package textcomp Info: Setting hlx sub-encoding to TS1/5 on input line 401. +Package textcomp Info: Setting hlce sub-encoding to TS1/5 on input line 402. +Package textcomp Info: Setting hlcn sub-encoding to TS1/5 on input line 403. +Package textcomp Info: Setting hlcw sub-encoding to TS1/5 on input line 404. +Package textcomp Info: Setting hlcf sub-encoding to TS1/5 on input line 405. +Package textcomp Info: Setting pplx sub-encoding to TS1/3 on input line 406. +Package textcomp Info: Setting pplj sub-encoding to TS1/3 on input line 407. +Package textcomp Info: Setting ptmx sub-encoding to TS1/4 on input line 408. +Package textcomp Info: Setting ptmj sub-encoding to TS1/4 on input line 409. +) (/usr/share/texlive/texmf-dist/tex/latex/psnfss/pifont.sty +Package: pifont 2005/04/12 PSNFSS-v9.2a Pi font support (SPQR) +LaTeX Font Info: Try loading font information for U+pzd on input line 63. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upzd.fd +File: upzd.fd 2001/06/04 font definitions for U/pzd. +) +LaTeX Font Info: Try loading font information for U+psy on input line 64. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upsy.fd +File: upsy.fd 2001/06/04 font definitions for U/psy. +)) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2012/11/06 v6.83m Hypertext links for LaTeX +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO) +Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO) +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO) +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is not detected. +Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) +Package etexcmds Info: Could not find \expanded. +(etexcmds) That can mean that you are not using pdfTeX 1.50 or +(etexcmds) that some package has redefined \expanded. +(etexcmds) In the latter case, load this package earlier. +Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) +Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO) +Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode is ignored in DVI mode. +Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO) +Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO) +Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO) +Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO) +Package: xcolor-patch 2011/01/30 xcolor patch +Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO) +Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO) +Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO) +Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2011/03/04 v1.3 Hooks for auxiliary files (HO) +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) +) +\@linkdim=\dimen120 +\Hy@linkcounter=\count111 +\Hy@pagecounter=\count112 +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count113 +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Hyper figures OFF on input line 4443. +Package hyperref Info: Link nesting OFF on input line 4448. +Package hyperref Info: Hyper index ON on input line 4451. +Package hyperref Info: Plain pages OFF on input line 4458. +Package hyperref Info: Backreferencing OFF on input line 4463. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4688. +\c@Hy@tempcnt=\count114 +(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip11 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 5041. +\XeTeXLinkMargin=\dimen121 +\Fld@menulength=\count115 +\Field@Width=\dimen122 +\Fld@charsize=\dimen123 +Package hyperref Info: Hyper figures OFF on input line 6295. +Package hyperref Info: Link nesting OFF on input line 6300. +Package hyperref Info: Hyper index ON on input line 6303. +Package hyperref Info: backreferencing OFF on input line 6310. +Package hyperref Info: Link coloring OFF on input line 6315. +Package hyperref Info: Link coloring with OCG OFF on input line 6320. +Package hyperref Info: PDF/A mode OFF on input line 6325. +LaTeX Info: Redefining \ref on input line 6365. +LaTeX Info: Redefining \pageref on input line 6369. +\Hy@abspage=\count116 +\c@Item=\count117 +\c@Hfootnote=\count118 +) + +Package hyperref Message: Driver (default): hdvips. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hdvips.def +File: hdvips.def 2012/11/06 v6.83m Hyperref driver for dvips +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pdfmark.def +File: pdfmark.def 2012/11/06 v6.83m Hyperref definitions for pdfmark specials +\pdf@docset=\toks23 +\pdf@box=\box32 +\pdf@toks=\toks24 +\pdf@defaulttoks=\toks25 +\HyField@AnnotCount=\count119 +\Fld@listcount=\count120 +\c@bookmark@seq@number=\count121 +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO) +Package uniquecounter Info: New unique counter `rerunfilecheck' on input line 282. +) +\Hy@SectionHShift=\skip140 +)) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bookmark.sty +Package: bookmark 2011/12/02 v1.24 PDF bookmarks (HO) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bkm-dvips.def +File: bkm-dvips.def 2011/12/02 v1.24 bookmark driver for dvips (HO) +\BKM@id=\count122 +)) +Package hyperref Info: Option `colorlinks' set `true' on input line 87. +\px=\skip141 +\c@md@targetcount=\count123 +\mdcompactskip=\skip142 +\mdcompacttopsep=\skip143 +\dim@rem=\skip144 +\dim@ch=\skip145 +\md@height=\skip146 +\dim@marginbottom=\skip147 +\dim@paddingbottom=\skip148 +\md@interaction=\count124 +\mddefinitionsskip=\skip149 +\md@captionlen=\skip150 +\mdtoclevel=\count125 +\c@mdtoclevelbold=\count126 +\c@mdtocleveldots=\count127 +\mdtocskip=\skip151 +\mdpreskip=\skip152 +\presp=\skip153 +\md@postskip=\skip154 +\ppresp=\skip155 +\md@thmcaption=\box33 +\md@defaultcolwidth=\skip156 +\mdtabularskip=\skip157 +\mdbibindentunit=\skip158 +\c@md@authorcount=\count128 +\c@mdx@authorcount=\count129 +\c@@mdTargetCount=\count130 +\@snippetBox=\box34 +\@snippetWidth=\skip159 +\@snippetHeight=\skip160 +\@snippetDepth=\skip161 +\c@snippets=\count131 +) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty +Package: geometry 2010/09/12 v5.6 Page Geometry +\Gm@cnth=\count132 +\Gm@cntv=\count133 +\c@Gm@tempcnt=\count134 +\Gm@bindingoffset=\dimen124 +\Gm@wd@mp=\dimen125 +\Gm@odd@mp=\dimen126 +\Gm@even@mp=\dimen127 +\Gm@layoutwidth=\dimen128 +\Gm@layoutheight=\dimen129 +\Gm@layouthoffset=\dimen130 +\Gm@layoutvoffset=\dimen131 +\Gm@dimlist=\toks26 +) (/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +\fancy@headwidth=\skip162 +\f@ncyO@elh=\skip163 +\f@ncyO@erh=\skip164 +\f@ncyO@olh=\skip165 +\f@ncyO@orh=\skip166 +\f@ncyO@elf=\skip167 +\f@ncyO@erf=\skip168 +\f@ncyO@olf=\skip169 +\f@ncyO@orf=\skip170 +) (build/P4Runtime-Spec-math-plain.aux) +\openout1 = `P4Runtime-Spec-math-plain.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 15. +LaTeX Font Info: ... okay on input line 15. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 15. +LaTeX Font Info: ... okay on input line 15. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 15. +LaTeX Font Info: ... okay on input line 15. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 15. +LaTeX Font Info: ... okay on input line 15. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 15. +LaTeX Font Info: ... okay on input line 15. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 15. +LaTeX Font Info: ... okay on input line 15. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 15. +LaTeX Font Info: Try loading font information for TS1+cmr on input line 15. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1cmr.fd +File: ts1cmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions +) +LaTeX Font Info: ... okay on input line 15. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 15. +LaTeX Font Info: ... okay on input line 15. +\AtBeginShipoutBox=\box35 +Package hyperref Info: Link coloring ON on input line 15. +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2012/10/27 v2.43 Cross-referencing by name of section +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO) +) +\c@section@level=\count135 +) +LaTeX Info: Redefining \ref on input line 15. +LaTeX Info: Redefining \pageref on input line 15. +LaTeX Info: Redefining \nameref on input line 15. +*geometry* driver: auto-detecting +*geometry* detected driver: dvips +*geometry* verbose mode - [ preamble ] result: +* driver: dvips +* paper: +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: twoside +* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt) +* v-part:(T,H,B)=(72.26999pt, 632.3625pt, 90.3375pt) +* \paperwidth=614.295pt +* \paperheight=794.96999pt +* \textwidth=469.75502pt +* \textheight=632.3625pt +* \oddsidemargin=0.0pt +* \evensidemargin=0.0pt +* \topmargin=-30.06749pt +* \headheight=30.0pt +* \headsep=18.06749pt +* \topskip=10.0pt +* \footskip=25.29494pt +* \marginparwidth=125.0pt +* \marginparsep=7.0pt +* \columnsep=10.0pt +* \skip\footins=9.0pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidetrue +* \@mparswitchtrue +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +\md@dimfile=\write3 +\openout3 = `P4Runtime-Spec-math-plain.dim'. + +LaTeX Font Info: Try loading font information for U+msa on input line 22. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Try loading font information for U+msb on input line 22. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Try loading font information for U+stmry on input line 22. +(/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/Ustmry.fd) [1 + +] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32] [33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47] [48] [49] [50] [51] [52] [53] [54] [55] [56] [57] [58] +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 188. +Package atveryend Info: Executing hook `AfterLastShipout' on input line 188. +\BKM@file=\write4 +\openout4 = `P4Runtime-Spec-math-plain.out.ps'. + +(build/P4Runtime-Spec-math-plain.aux) +Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 188. +Package atveryend Info: Empty hook `AtEndAfterFileList' on input line 188. + ) +Here is how much of TeX's memory you used: + 11194 strings out of 493030 + 205924 string characters out of 6136260 + 297990 words of memory out of 5000000 + 14610 multiletter control sequences out of 15000+600000 + 6809 words of font info for 28 fonts, out of 8000000 for 9000 + 1141 hyphenation exceptions out of 8191 + 48i,5n,52p,909b,373s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on build/P4Runtime-Spec-math-plain.dvi (58 pages, 40784 bytes). diff --git a/spec/main/P4Runtime-Spec-math-plain.out.ps b/spec/main/P4Runtime-Spec-math-plain.out.ps new file mode 100644 index 00000000..65a15b1e Binary files /dev/null and b/spec/main/P4Runtime-Spec-math-plain.out.ps differ diff --git a/spec/main/P4Runtime-Spec.aux b/spec/main/P4Runtime-Spec.aux new file mode 100644 index 00000000..d6b83688 --- /dev/null +++ b/spec/main/P4Runtime-Spec.aux @@ -0,0 +1,468 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument} +\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined +\global\let\oldcontentsline\contentsline +\gdef\contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}} +\global\let\oldnewlabel\newlabel +\gdef\newlabel#1#2{\newlabelxx{#1}#2} +\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}} +\AtEndDocument{\ifx\hyper@anchor\@undefined +\let\contentsline\oldcontentsline +\let\newlabel\oldnewlabel +\fi} +\fi} +\global\let\hyper@last\relax +\gdef\HyperFirstAtBeginDocument#1{#1} +\providecommand*\HyPL@Entry[1]{} +\HyPL@Entry{0<>} +\newlabel{sec-contents}{{}{1}{Contents}{section*.1}{}} +\newlabel{sec-figures}{{}{4}{Figures}{section*.2}{}} +\newlabel{sec-tables}{{}{5}{Tables}{section*.3}{}} +\@writefile{toc}{\contentsline {section}{1.\hspace *{0.5em}Introduction and Scope}{5}{section*.4}} +\newlabel{sec-introduction-and-scope}{{}{5}{\mdline {218}1.\hspace *{0.5em}\mdline {218}Introduction and Scope}{section*.4}{}} +\@writefile{toc}{\contentsline {subsection}{1.1.\hspace *{0.5em}P4 Language Version Applicability}{5}{section*.5}} +\newlabel{sec-p4-language-version-applicability}{{}{5}{\mdline {228}1.1.\hspace *{0.5em}\mdline {228}P4 Language Version Applicability}{section*.5}{}} +\@writefile{toc}{\contentsline {subsection}{1.2.\hspace *{0.5em}In Scope}{5}{section*.6}} +\newlabel{sec-in-scope}{{}{5}{\mdline {252}1.2.\hspace *{0.5em}\mdline {252}In Scope}{section*.6}{}} +\@writefile{toc}{\contentsline {subsection}{1.3.\hspace *{0.5em}Not In Scope}{6}{section*.7}} +\newlabel{sec-not-in-scope}{{}{6}{\mdline {280}1.3.\hspace *{0.5em}\mdline {280}Not In Scope}{section*.7}{}} +\@writefile{toc}{\contentsline {section}{2.\hspace *{0.5em}Terms and Definitions}{6}{section*.8}} +\newlabel{sec-terms-and-definitions}{{}{6}{\mdline {305}2.\hspace *{0.5em}\mdline {305}Terms and Definitions}{section*.8}{}} +\@writefile{toc}{\contentsline {section}{3.\hspace *{0.5em}Reference Architecture}{8}{section*.9}} +\newlabel{sec-reference-architecture}{{}{8}{\mdline {389}3.\hspace *{0.5em}\mdline {389}Reference Architecture}{section*.9}{}} +\@writefile{toc}{\contentsline {subsection}{3.1.\hspace *{0.5em}P4Runtime Service Implementation}{8}{section*.10}} +\newlabel{sec-p4runtime-service-implementation}{{}{8}{\mdline {434}3.1.\hspace *{0.5em}\mdline {434}P4Runtime Service Implementation}{section*.10}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces P4Runtime Reference Architecture.}{}}{9}{section*.9}} +\newlabel{fig-reference-architecture}{{}{9}{\mdline {389}3.\hspace *{0.5em}\mdline {389}Reference Architecture}{section*.9}{}} +\@writefile{toc}{\contentsline {subsubsection}{3.1.1.\hspace *{0.5em}Security concerns}{9}{section*.11}} +\newlabel{sec-security-concerns}{{}{9}{\mdline {444}3.1.1.\hspace *{0.5em}\mdline {444}Security concerns}{section*.11}{}} +\@writefile{toc}{\contentsline {subsection}{3.2.\hspace *{0.5em}Idealized Workflow}{9}{section*.12}} +\newlabel{sec-idealized-workflow}{{}{9}{\mdline {455}3.2.\hspace *{0.5em}\mdline {455}Idealized Workflow}{section*.12}{}} +\@writefile{toc}{\contentsline {subsection}{3.3.\hspace *{0.5em}P4 as a Behavioral Description Language}{10}{section*.13}} +\newlabel{sec-p4-as-behavioral-description-language}{{}{10}{\mdline {481}3.3.\hspace *{0.5em}\mdline {481}P4 as a Behavioral Description Language}{section*.13}{}} +\@writefile{toc}{\contentsline {subsection}{3.4.\hspace *{0.5em}Alternative Workflows}{10}{section*.14}} +\newlabel{sec-alternative-workflows}{{}{10}{\mdline {508}3.4.\hspace *{0.5em}\mdline {508}Alternative Workflows}{section*.14}{}} +\@writefile{toc}{\contentsline {subsubsection}{3.4.1.\hspace *{0.5em}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}{10}{section*.15}} +\newlabel{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{{}{10}{\mdline {514}3.4.1.\hspace *{0.5em}\mdline {514}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}{section*.15}{}} +\@writefile{toc}{\contentsline {subsubsection}{3.4.2.\hspace *{0.5em}No P4 Source Available, P4Info Available}{10}{section*.16}} +\newlabel{sec-no-p4-source-available-p4info-available}{{}{10}{\mdline {523}3.4.2.\hspace *{0.5em}\mdline {523}No P4 Source Available, P4Info Available}{section*.16}{}} +\@writefile{toc}{\contentsline {subsubsection}{3.4.3.\hspace *{0.5em}Partial P4Info and P4 Source are Available}{11}{section*.17}} +\newlabel{sec-partial-p4info-and-p4-source-are-available}{{}{11}{\mdline {539}3.4.3.\hspace *{0.5em}\mdline {539}Partial P4Info and P4 Source are Available}{section*.17}{}} +\@writefile{toc}{\contentsline {subsubsection}{3.4.4.\hspace *{0.5em}P4Info Role-Based Subsets}{11}{section*.18}} +\newlabel{sec-p4info-role-based-subsets}{{}{11}{\mdline {548}3.4.4.\hspace *{0.5em}\mdline {548}P4Info Role-Based Subsets}{section*.18}{}} +\@writefile{toc}{\contentsline {subsection}{3.5.\hspace *{0.5em}P4Runtime State Across Restarts}{11}{section*.19}} +\newlabel{sec-restarts}{{}{11}{\mdline {554}3.5.\hspace *{0.5em}\mdline {554}P4Runtime State Across Restarts}{section*.19}{}} +\@writefile{toc}{\contentsline {section}{4.\hspace *{0.5em}Controller Use-cases}{11}{section*.20}} +\newlabel{sec-controller-use-cases}{{}{11}{\mdline {562}4.\hspace *{0.5em}\mdline {562}Controller Use-cases}{section*.20}{}} +\@writefile{toc}{\contentsline {subsection}{4.1.\hspace *{0.5em}Single Embedded Controller}{11}{section*.21}} +\newlabel{sec-single-embedded-controller}{{}{11}{\mdline {571}4.1.\hspace *{0.5em}\mdline {571}Single Embedded Controller}{section*.21}{}} +\@writefile{toc}{\contentsline {subsection}{4.2.\hspace *{0.5em}Single Remote Controller}{11}{section*.22}} +\newlabel{sec-single-remote-controller}{{}{11}{\mdline {590}4.2.\hspace *{0.5em}\mdline {590}Single Remote Controller}{section*.22}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Use-Case: Single Embedded Controller}{}}{12}{section*.21}} +\newlabel{fig-single-embedded-controller}{{}{12}{\mdline {571}4.1.\hspace *{0.5em}\mdline {571}Single Embedded Controller}{section*.21}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces Use-Case: Single Remote Controller}{}}{12}{section*.22}} +\newlabel{fig-single-remote-controller}{{}{12}{\mdline {590}4.2.\hspace *{0.5em}\mdline {590}Single Remote Controller}{section*.22}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces Use-Case: Embedded Plus Single Remote Controller}{}}{13}{section*.23}} +\newlabel{fig-embedded-plus-single-remote-controller}{{}{13}{\mdline {604}4.3.\hspace *{0.5em}\mdline {604}Embedded\mdline {604} \mdline {604}+ Single Remote Controller}{section*.23}{}} +\@writefile{toc}{\contentsline {subsection}{4.3.\hspace *{0.5em}Embedded + Single Remote Controller}{13}{section*.23}} +\newlabel{sec-embedded-single-remote-controller}{{}{13}{\mdline {604}4.3.\hspace *{0.5em}\mdline {604}Embedded\mdline {604} \mdline {604}+ Single Remote Controller}{section*.23}{}} +\@writefile{toc}{\contentsline {subsection}{4.4.\hspace *{0.5em}Embedded + Two Remote Controllers}{13}{section*.24}} +\newlabel{sec-embedded-two-remote-controllers}{{}{13}{\mdline {625}4.4.\hspace *{0.5em}\mdline {625}Embedded\mdline {625} \mdline {625}+ Two Remote Controllers}{section*.24}{}} +\@writefile{toc}{\contentsline {subsection}{4.5.\hspace *{0.5em}Embedded Controller + Two High-Availability Remote Controllers}{13}{section*.25}} +\newlabel{sec-embedded-controller-two-high-availability-remote-controllers}{{}{13}{\mdline {641}4.5.\hspace *{0.5em}\mdline {641}Embedded Controller\mdline {641} \mdline {641}+ Two High-Availability Remote Controllers}{section*.25}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces Use-Case: Embedded Plus Two Remote Controllers}{}}{14}{section*.24}} +\newlabel{fig-embedded-plus-two-remote-controllers}{{}{14}{\mdline {625}4.4.\hspace *{0.5em}\mdline {625}Embedded\mdline {625} \mdline {625}+ Two Remote Controllers}{section*.24}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces Use-Case: Embedded Plus Two Remote High-Availability Controllers}{}}{14}{section*.25}} +\newlabel{fig-embedded-plus-two-remote-ha-controllers}{{}{14}{\mdline {641}4.5.\hspace *{0.5em}\mdline {641}Embedded Controller\mdline {641} \mdline {641}+ Two High-Availability Remote Controllers}{section*.25}{}} +\@writefile{toc}{\contentsline {section}{5.\hspace *{0.5em}Client Arbitration and Controller Replication}{15}{section*.26}} +\newlabel{sec-client-arbitration-and-controller-replication}{{}{15}{\mdline {659}5.\hspace *{0.5em}\mdline {659}Client Arbitration and Controller Replication}{section*.26}{}} +\@writefile{toc}{\contentsline {subsection}{5.1.\hspace *{0.5em}Default Role}{17}{section*.27}} +\newlabel{sec-default-role}{{}{17}{\mdline {786}5.1.\hspace *{0.5em}\mdline {786}Default Role}{section*.27}{}} +\@writefile{toc}{\contentsline {subsection}{5.2.\hspace *{0.5em}Role Config}{17}{section*.28}} +\newlabel{sec-arbitration-role-config}{{}{17}{\mdline {794}5.2.\hspace *{0.5em}\mdline {794}Role Config}{section*.28}{}} +\@writefile{toc}{\contentsline {subsection}{5.3.\hspace *{0.5em}Rules for Handling \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x MasterArbitrationUpdate}}} Messages Received from Controllers}{17}{section*.29}} +\newlabel{sec-arbitration-updates}{{}{17}{\mdline {821}5.3.\hspace *{0.5em}\mdline {821}Rules for Handling \mdline {821}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}MasterArbitrationUpdate}}}\mdline {821} Messages Received from Controllers}{section*.29}{}} +\@writefile{toc}{\contentsline {subsection}{5.4.\hspace *{0.5em}Client Arbitration Notifications}{19}{section*.30}} +\newlabel{sec-arbitration-notification}{{}{19}{\mdline {923}5.4.\hspace *{0.5em}\mdline {923}Client Arbitration Notifications}{section*.30}{}} +\@writefile{toc}{\contentsline {section}{6.\hspace *{0.5em}The P4Info Message}{19}{section*.31}} +\newlabel{sec-the-p4info-message}{{}{19}{\mdline {963}6.\hspace *{0.5em}\mdline {963}The P4Info Message}{section*.31}{}} +\@writefile{toc}{\contentsline {subsection}{6.1.\hspace *{0.5em}Common Messages}{19}{section*.32}} +\newlabel{sec-common-messages}{{}{19}{\mdline {970}6.1.\hspace *{0.5em}\mdline {970}Common Messages}{section*.32}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.1.1.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Documentation}}} Message}{20}{section*.33}} +\newlabel{sec-documentation-message}{{}{20}{\mdline {974}6.1.1.\hspace *{0.5em}\mdline {974}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Documentation}}}\mdline {974} Message}{section*.33}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.1.2.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Preamble}}} Message}{20}{section*.34}} +\newlabel{sec-preamble-message}{{}{20}{\mdline {990}6.1.2.\hspace *{0.5em}\mdline {990}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Preamble}}}\mdline {990} Message}{section*.34}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.1.3.\hspace *{0.5em}Annotating P4 Entities with \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Documentation}}}}{21}{section*.35}} +\newlabel{sec-annotating-p4-entities-with-documentation}{{}{21}{\mdline {1027}6.1.3.\hspace *{0.5em}\mdline {1027}Annotating P4 Entities with \mdline {1027}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Documentation}}}}{section*.35}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.1.4.\hspace *{0.5em}Structured Annotations}{21}{section*.36}} +\newlabel{sec-structured-annotations}{{}{21}{\mdline {1055}6.1.4.\hspace *{0.5em}\mdline {1055}Structured Annotations}{section*.36}{}} +\newlabel{sec-structured-annotation-examples}{{}{22}{\mdline {1131}6.1.4.1.\hspace *{0.5em}\mdline {1131}Structured Annotation Examples}{section*.37}{}} +\@writefile{toc}{\contentsline {paragraph}{6.1.4.1.\hspace *{0.5em}Structured Annotation Examples}{22}{section*.37}} +\@writefile{toc}{\contentsline {subsubsection}{6.1.5.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x SourceLocation}}} Message}{24}{section*.38}} +\newlabel{sec-sourcelocation-message}{{}{24}{\mdline {1225}6.1.5.\hspace *{0.5em}\mdline {1225}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}SourceLocation}}}\mdline {1225} Message}{section*.38}{}} +\@writefile{toc}{\contentsline {subsection}{6.2.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x PkgInfo}}} Message}{25}{section*.39}} +\newlabel{sec-pkginfo-message}{{}{25}{\mdline {1262}6.2.\hspace *{0.5em}\mdline {1262}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}PkgInfo}}}\mdline {1262} Message}{section*.39}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.2.1.\hspace *{0.5em}Annotating P4 code with PkgInfo}{26}{section*.40}} +\newlabel{sec-annotating-p4-code-with-pkginfo}{{}{26}{\mdline {1319}6.2.1.\hspace *{0.5em}\mdline {1319}Annotating P4 code with PkgInfo}{section*.40}{}} +\@writefile{toc}{\contentsline {subsection}{6.3.\hspace *{0.5em}ID Allocation for P4Info Objects}{27}{section*.41}} +\newlabel{sec-id-allocation}{{}{27}{\mdline {1393}6.3.\hspace *{0.5em}\mdline {1393}ID Allocation for P4Info Objects}{section*.41}{}} +\@writefile{lot}{\contentsline {table}{\numberline {1}{\ignorespaces Mapping of P4Info object type to 8-bit ID prefix value}{}}{28}{section*.41}} +\newlabel{tab-mapping-p4-obj-ids}{{}{28}{\mdline {1393}6.3.\hspace *{0.5em}\mdline {1393}ID Allocation for P4Info Objects}{section*.41}{}} +\@writefile{lot}{\contentsline {table}{\numberline {2}{\ignorespaces Format of P4Info object IDs}{}}{28}{section*.41}} +\newlabel{tab-format-p4-obj-ids}{{}{28}{\mdline {1393}6.3.\hspace *{0.5em}\mdline {1393}ID Allocation for P4Info Objects}{section*.41}{}} +\@writefile{lot}{\contentsline {table}{\numberline {3}{\ignorespaces Example of statically-assigned P4Info object IDs}{}}{28}{section*.41}} +\newlabel{tab-exmpl-p4-obj-ids}{{}{28}{\mdline {1393}6.3.\hspace *{0.5em}\mdline {1393}ID Allocation for P4Info Objects}{section*.41}{}} +\@writefile{toc}{\contentsline {subsection}{6.4.\hspace *{0.5em}P4Info Objects}{29}{section*.42}} +\newlabel{sec-p4info-objects}{{}{29}{\mdline {1483}6.4.\hspace *{0.5em}\mdline {1483}P4Info Objects}{section*.42}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.4.1.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Table}}}}{29}{section*.43}} +\newlabel{sec-table}{{}{29}{\mdline {1485}6.4.1.\hspace *{0.5em}\mdline {1485}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Table}}}}{section*.43}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.4.2.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Action}}}}{30}{section*.44}} +\newlabel{sec-action}{{}{30}{\mdline {1595}6.4.2.\hspace *{0.5em}\mdline {1595}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Action}}}}{section*.44}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.4.3.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x ActionProfile}}}}{31}{section*.45}} +\newlabel{sec-p4info-action-profile}{{}{31}{\mdline {1624}6.4.3.\hspace *{0.5em}\mdline {1624}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}ActionProfile}}}}{section*.45}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.4.4.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Counter}}} \& \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x DirectCounter}}}}{32}{section*.46}} +\newlabel{sec-counter-directcounter}{{}{32}{\mdline {1695}6.4.4.\hspace *{0.5em}\mdline {1695}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Counter}}}\mdline {1695} \mdline {1695}\&\mdline {1695} \mdline {1695}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}DirectCounter}}}}{section*.46}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.4.5.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Meter}}} \& \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x DirectMeter}}}}{33}{section*.47}} +\newlabel{sec-meter-directmeter}{{}{33}{\mdline {1736}6.4.5.\hspace *{0.5em}\mdline {1736}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Meter}}}\mdline {1736} \mdline {1736}\&\mdline {1736} \mdline {1736}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}DirectMeter}}}}{section*.47}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.4.6.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x ControllerPacketMetadata}}}}{34}{section*.48}} +\newlabel{sec-controller-packet-meta}{{}{34}{\mdline {1802}6.4.6.\hspace *{0.5em}\mdline {1802}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}ControllerPacketMetadata}}}}{section*.48}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.4.7.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x ValueSet}}}}{36}{section*.49}} +\newlabel{sec-valueset}{{}{36}{\mdline {1915}6.4.7.\hspace *{0.5em}\mdline {1915}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}ValueSet}}}}{section*.49}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.4.8.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Register}}}}{38}{section*.50}} +\newlabel{sec-register}{{}{38}{\mdline {2050}6.4.8.\hspace *{0.5em}\mdline {2050}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Register}}}}{section*.50}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.4.9.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Digest}}}}{39}{section*.51}} +\newlabel{sec-digest}{{}{39}{\mdline {2076}6.4.9.\hspace *{0.5em}\mdline {2076}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Digest}}}}{section*.51}{}} +\@writefile{toc}{\contentsline {subsubsection}{6.4.10.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Extern}}}}{39}{section*.52}} +\newlabel{sec-p4info-extern}{{}{39}{\mdline {2099}6.4.10.\hspace *{0.5em}\mdline {2099}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Extern}}}}{section*.52}{}} +\@writefile{toc}{\contentsline {subsection}{6.5.\hspace *{0.5em}Support for Arbitrary P4 Types with P4TypeInfo}{40}{section*.53}} +\newlabel{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{{}{40}{\mdline {2134}6.5.\hspace *{0.5em}\mdline {2134}Support for Arbitrary P4 Types with P4TypeInfo}{section*.53}{}} +\@writefile{toc}{\contentsline {section}{7.\hspace *{0.5em}P4 Forwarding-Pipeline Configuration}{40}{section*.54}} +\newlabel{sec-p4-fwd-pipe-config}{{}{40}{\mdline {2139}7.\hspace *{0.5em}\mdline {2139}P4 Forwarding-Pipeline Configuration}{section*.54}{}} +\@writefile{toc}{\contentsline {section}{8.\hspace *{0.5em}General Principles for Message Formatting}{40}{section*.55}} +\newlabel{sec-message-formatting-principles}{{}{40}{\mdline {2174}8.\hspace *{0.5em}\mdline {2174}General Principles for Message Formatting}{section*.55}{}} +\@writefile{toc}{\contentsline {subsection}{8.1.\hspace *{0.5em}Default-valued Fields}{40}{section*.56}} +\newlabel{sec-default-valued-fields}{{}{40}{\mdline {2176}8.1.\hspace *{0.5em}\mdline {2176}Default-valued Fields}{section*.56}{}} +\@writefile{toc}{\contentsline {subsubsection}{8.1.1.\hspace *{0.5em}Set / Unset Scalar Fields}{40}{section*.57}} +\newlabel{sec-set-unset-scalar-fields}{{}{40}{\mdline {2181}8.1.1.\hspace *{0.5em}\mdline {2181}Set / Unset Scalar Fields}{section*.57}{}} +\@writefile{toc}{\contentsline {subsubsection}{8.1.2.\hspace *{0.5em}Set / Unset Message Fields}{41}{section*.58}} +\newlabel{sec-set-unset-message-fields}{{}{41}{\mdline {2198}8.1.2.\hspace *{0.5em}\mdline {2198}Set / Unset Message Fields}{section*.58}{}} +\@writefile{toc}{\contentsline {subsection}{8.2.\hspace *{0.5em}Read-Write Symmetry}{42}{section*.59}} +\newlabel{sec-read-write-symmetry}{{}{42}{\mdline {2262}8.2.\hspace *{0.5em}\mdline {2262}Read-Write Symmetry}{section*.59}{}} +\@writefile{toc}{\contentsline {subsubsection}{8.2.1.\hspace *{0.5em}Data plane volatile objects}{42}{section*.60}} +\newlabel{sec-data-plane-volatile-objects}{{}{42}{\mdline {2301}8.2.1.\hspace *{0.5em}\mdline {2301}Data plane volatile objects}{section*.60}{}} +\newlabel{sec-externentry}{{}{43}{\mdline {2314}8.2.1.1.\hspace *{0.5em}\mdline {2314}ExternEntry}{section*.61}{}} +\@writefile{toc}{\contentsline {paragraph}{8.2.1.1.\hspace *{0.5em}ExternEntry}{43}{section*.61}} +\newlabel{sec-tableentry}{{}{43}{\mdline {2319}8.2.1.2.\hspace *{0.5em}\mdline {2319}TableEntry}{section*.62}{}} +\@writefile{toc}{\contentsline {paragraph}{8.2.1.2.\hspace *{0.5em}TableEntry}{43}{section*.62}} +\newlabel{sec-actionprofilemember}{{}{43}{\mdline {2357}8.2.1.3.\hspace *{0.5em}\mdline {2357}ActionProfileMember}{section*.63}{}} +\@writefile{toc}{\contentsline {paragraph}{8.2.1.3.\hspace *{0.5em}ActionProfileMember}{43}{section*.63}} +\newlabel{sec-actionprofilegroup}{{}{43}{\mdline {2362}8.2.1.4.\hspace *{0.5em}\mdline {2362}ActionProfileGroup}{section*.64}{}} +\@writefile{toc}{\contentsline {paragraph}{8.2.1.4.\hspace *{0.5em}ActionProfileGroup}{43}{section*.64}} +\newlabel{sec-meterentry}{{}{43}{\mdline {2369}8.2.1.5.\hspace *{0.5em}\mdline {2369}MeterEntry}{section*.65}{}} +\@writefile{toc}{\contentsline {paragraph}{8.2.1.5.\hspace *{0.5em}MeterEntry}{43}{section*.65}} +\newlabel{sec-directmeterentry}{{}{43}{\mdline {2374}8.2.1.6.\hspace *{0.5em}\mdline {2374}DirectMeterEntry}{section*.66}{}} +\@writefile{toc}{\contentsline {paragraph}{8.2.1.6.\hspace *{0.5em}DirectMeterEntry}{43}{section*.66}} +\newlabel{sec-counterentry}{{}{43}{\mdline {2379}8.2.1.7.\hspace *{0.5em}\mdline {2379}CounterEntry}{section*.67}{}} +\@writefile{toc}{\contentsline {paragraph}{8.2.1.7.\hspace *{0.5em}CounterEntry}{43}{section*.67}} +\newlabel{sec-directcounterentry}{{}{44}{\mdline {2384}8.2.1.8.\hspace *{0.5em}\mdline {2384}DirectCounterEntry}{section*.68}{}} +\@writefile{toc}{\contentsline {paragraph}{8.2.1.8.\hspace *{0.5em}DirectCounterEntry}{44}{section*.68}} +\newlabel{sec-packetreplicationengineentry}{{}{44}{\mdline {2389}8.2.1.9.\hspace *{0.5em}\mdline {2389}PacketReplicationEngineEntry}{section*.69}{}} +\@writefile{toc}{\contentsline {paragraph}{8.2.1.9.\hspace *{0.5em}PacketReplicationEngineEntry}{44}{section*.69}} +\newlabel{sec-valuesetentry}{{}{44}{\mdline {2394}8.2.1.10.\hspace *{0.5em}\mdline {2394}ValueSetEntry}{section*.70}{}} +\@writefile{toc}{\contentsline {paragraph}{8.2.1.10.\hspace *{0.5em}ValueSetEntry}{44}{section*.70}} +\newlabel{sec-registerentry}{{}{44}{\mdline {2399}8.2.1.11.\hspace *{0.5em}\mdline {2399}RegisterEntry}{section*.71}{}} +\@writefile{toc}{\contentsline {paragraph}{8.2.1.11.\hspace *{0.5em}RegisterEntry}{44}{section*.71}} +\newlabel{sec-digestentry}{{}{44}{\mdline {2404}8.2.1.12.\hspace *{0.5em}\mdline {2404}DigestEntry}{section*.72}{}} +\@writefile{toc}{\contentsline {paragraph}{8.2.1.12.\hspace *{0.5em}DigestEntry}{44}{section*.72}} +\@writefile{toc}{\contentsline {subsection}{8.3.\hspace *{0.5em}Bytestrings}{44}{section*.73}} +\newlabel{sec-bytestrings}{{}{44}{\mdline {2409}8.3.\hspace *{0.5em}\mdline {2409}Bytestrings}{section*.73}{}} +\@writefile{lot}{\contentsline {table}{\numberline {4}{\ignorespaces Examples of Valid Bytestring Encoding}{}}{46}{section*.73}} +\newlabel{tab-valid-bytestring-encoding}{{}{46}{\mdline {2409}8.3.\hspace *{0.5em}\mdline {2409}Bytestrings}{section*.73}{}} +\@writefile{lot}{\contentsline {table}{\numberline {5}{\ignorespaces Examples of Invalid Bytestring Encoding}{}}{46}{section*.73}} +\newlabel{tab-invalid-bytestring-encoding}{{}{46}{\mdline {2409}8.3.\hspace *{0.5em}\mdline {2409}Bytestrings}{section*.73}{}} +\@writefile{lot}{\contentsline {table}{\numberline {6}{\ignorespaces P4 Type Usage}{}}{47}{section*.75}} +\newlabel{tab-p4-type-usage}{{}{47}{\mdline {2581}8.4.1.\hspace *{0.5em}\mdline {2581}Problem Statement}{section*.75}{}} +\@writefile{toc}{\contentsline {subsection}{8.4.\hspace *{0.5em}Representation of Arbitrary P4 Types}{47}{section*.74}} +\newlabel{sec-representation-of-arbitrary-p4-types}{{}{47}{\mdline {2579}8.4.\hspace *{0.5em}\mdline {2579}Representation of Arbitrary P4 Types}{section*.74}{}} +\@writefile{toc}{\contentsline {subsubsection}{8.4.1.\hspace *{0.5em}Problem Statement}{47}{section*.75}} +\newlabel{sec-problem-statement}{{}{47}{\mdline {2581}8.4.1.\hspace *{0.5em}\mdline {2581}Problem Statement}{section*.75}{}} +\@writefile{toc}{\contentsline {subsubsection}{8.4.2.\hspace *{0.5em}P4 Type Specifications in p4info.proto}{48}{section*.76}} +\newlabel{sec-p4-type-specifications-in-p4infoproto}{{}{48}{\mdline {2642}8.4.2.\hspace *{0.5em}\mdline {2642}P4 Type Specifications in p4info.proto}{section*.76}{}} +\@writefile{toc}{\contentsline {subsubsection}{8.4.3.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x P4Data}}} in p4runtime.proto}{49}{section*.77}} +\newlabel{sec-p4data-in-p4runtime-proto}{{}{49}{\mdline {2690}8.4.3.\hspace *{0.5em}\mdline {2690}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}P4Data}}}\mdline {2690} in p4runtime.proto}{section*.77}{}} +\@writefile{toc}{\contentsline {subsubsection}{8.4.4.\hspace *{0.5em}Example}{49}{section*.78}} +\newlabel{sec-example}{{}{49}{\mdline {2723}8.4.4.\hspace *{0.5em}\mdline {2723}Example}{section*.78}{}} +\@writefile{toc}{\contentsline {subsubsection}{8.4.5.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x enum}}}, serializable \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x enum}}} and \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x error}}}}{51}{section*.79}} +\newlabel{sec-enum-serializable-enum-and-error}{{}{51}{\mdline {2820}8.4.5.\hspace *{0.5em}\mdline {2820}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}enum}}}\mdline {2820}, serializable \mdline {2820}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}enum}}}\mdline {2820} and \mdline {2820}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}error}}}}{section*.79}{}} +\@writefile{toc}{\contentsline {subsubsection}{8.4.6.\hspace *{0.5em}User-defined types}{51}{section*.80}} +\newlabel{sec-user-defined-types}{{}{51}{\mdline {2841}8.4.6.\hspace *{0.5em}\mdline {2841}User-defined types}{section*.80}{}} +\@writefile{toc}{\contentsline {subsubsection}{8.4.7.\hspace *{0.5em}Trade-off for v1.x Releases}{53}{section*.81}} +\newlabel{sec-trade-off-for-v1x-releases}{{}{53}{\mdline {2958}8.4.7.\hspace *{0.5em}\mdline {2958}Trade-off for v1.x Releases}{section*.81}{}} +\@writefile{toc}{\contentsline {section}{9.\hspace *{0.5em}P4 Entity Messages}{55}{section*.82}} +\newlabel{sec-p4-entity-msgs}{{}{55}{\mdline {3039}9.\hspace *{0.5em}\mdline {3039}P4 Entity Messages}{section*.82}{}} +\@writefile{toc}{\contentsline {subsection}{9.1.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x TableEntry}}}}{55}{section*.83}} +\newlabel{sec-table-entry}{{}{55}{\mdline {3045}9.1.\hspace *{0.5em}\mdline {3045}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}TableEntry}}}}{section*.83}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.1.1.\hspace *{0.5em}Match Format}{57}{section*.84}} +\newlabel{sec-match-format}{{}{57}{\mdline {3142}9.1.1.\hspace *{0.5em}\mdline {3142}Match Format}{section*.84}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.1.2.\hspace *{0.5em}Action Specification}{59}{section*.85}} +\newlabel{sec-action-specification}{{}{59}{\mdline {3286}9.1.2.\hspace *{0.5em}\mdline {3286}Action Specification}{section*.85}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.1.3.\hspace *{0.5em}Default Entry}{60}{section*.86}} +\newlabel{sec-default-entry}{{}{60}{\mdline {3338}9.1.3.\hspace *{0.5em}\mdline {3338}Default Entry}{section*.86}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.1.4.\hspace *{0.5em}Constant Tables}{60}{section*.87}} +\newlabel{sec-constant-tables}{{}{60}{\mdline {3369}9.1.4.\hspace *{0.5em}\mdline {3369}Constant Tables}{section*.87}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.1.5.\hspace *{0.5em}Preinitialized tables}{61}{section*.88}} +\newlabel{sec-preinitialized-tables}{{}{61}{\mdline {3407}9.1.5.\hspace *{0.5em}\mdline {3407}Preinitialized tables}{section*.88}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.1.6.\hspace *{0.5em}Wildcard Reads}{62}{section*.89}} +\newlabel{sec-table-wildcard-reads}{{}{62}{\mdline {3464}9.1.6.\hspace *{0.5em}\mdline {3464}Wildcard Reads}{section*.89}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.1.7.\hspace *{0.5em}Direct Resources}{64}{section*.90}} +\newlabel{sec-direct-resources}{{}{64}{\mdline {3603}9.1.7.\hspace *{0.5em}\mdline {3603}Direct Resources}{section*.90}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.1.8.\hspace *{0.5em}Idle-timeout}{66}{section*.91}} +\newlabel{sec-idle-timeout}{{}{66}{\mdline {3705}9.1.8.\hspace *{0.5em}\mdline {3705}Idle-timeout}{section*.91}{}} +\@writefile{toc}{\contentsline {subsection}{9.2.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x ActionProfileMember}}} \& \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x ActionProfileGroup}}}}{67}{section*.92}} +\newlabel{sec-action-profile-member-and-group}{{}{67}{\mdline {3758}9.2.\hspace *{0.5em}\mdline {3758}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}ActionProfileMember}}}\mdline {3758} \mdline {3758}\&\mdline {3758} \mdline {3758}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}ActionProfileGroup}}}}{section*.92}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.2.1.\hspace *{0.5em}Action Profile Member Programming}{68}{section*.93}} +\newlabel{sec-action-profile-member-programming}{{}{68}{\mdline {3813}9.2.1.\hspace *{0.5em}\mdline {3813}Action Profile Member Programming}{section*.93}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.2.2.\hspace *{0.5em}Action Profile Group Programming}{69}{section*.94}} +\newlabel{sec-action-profile-group-programming}{{}{69}{\mdline {3866}9.2.2.\hspace *{0.5em}\mdline {3866}Action Profile Group Programming}{section*.94}{}} +\newlabel{sec-max-size-rules}{{}{70}{\mdline {3955}9.2.2.1.\hspace *{0.5em}\mdline {3955}Rules on Setting \mdline {3955}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}max\_size}}}}{section*.95}{}} +\@writefile{toc}{\contentsline {paragraph}{9.2.2.1.\hspace *{0.5em}Rules on Setting \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x max\_size}}}}{70}{section*.95}} +\@writefile{toc}{\contentsline {subsubsection}{9.2.3.\hspace *{0.5em}One Shot Action Selector Programming}{70}{section*.96}} +\newlabel{sec-oneshot}{{}{70}{\mdline {3980}9.2.3.\hspace *{0.5em}\mdline {3980}One Shot Action Selector Programming}{section*.96}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.2.4.\hspace *{0.5em}Constraints on action selector programming}{73}{section*.97}} +\newlabel{action-selector-constraints}{{}{73}{\mdline {4129}9.2.4.\hspace *{0.5em}\mdline {4129}Constraints on action selector programming}{section*.97}{}} +\@writefile{toc}{\contentsline {subsection}{9.3.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x CounterEntry}}} \& \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x DirectCounterEntry}}}}{74}{section*.98}} +\newlabel{sec-counterentry-directcounterentry}{{}{74}{\mdline {4181}9.3.\hspace *{0.5em}\mdline {4181}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}CounterEntry}}}\mdline {4181} \mdline {4181}\&\mdline {4181} \mdline {4181}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}DirectCounterEntry}}}}{section*.98}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.3.1.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x DirectCounterEntry}}}}{74}{section*.99}} +\newlabel{sec-directcounterentry}{{}{74}{\mdline {4204}9.3.1.\hspace *{0.5em}\mdline {4204}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}DirectCounterEntry}}}}{section*.99}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.3.2.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x CounterEntry}}}}{75}{section*.100}} +\newlabel{sec-counterentry}{{}{75}{\mdline {4248}9.3.2.\hspace *{0.5em}\mdline {4248}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}CounterEntry}}}}{section*.100}{}} +\@writefile{toc}{\contentsline {subsection}{9.4.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x MeterEntry}}} \& \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x DirectMeterEntry}}}}{76}{section*.101}} +\newlabel{sec-meterentry-directmeterentry}{{}{76}{\mdline {4297}9.4.\hspace *{0.5em}\mdline {4297}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}MeterEntry}}}\mdline {4297} \mdline {4297}\&\mdline {4297} \mdline {4297}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}DirectMeterEntry}}}}{section*.101}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.4.1.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x DirectMeterEntry}}}}{77}{section*.102}} +\newlabel{sec-directmeterentry}{{}{77}{\mdline {4363}9.4.1.\hspace *{0.5em}\mdline {4363}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}DirectMeterEntry}}}}{section*.102}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.4.2.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x MeterEntry}}}}{78}{section*.103}} +\newlabel{sec-meterentry}{{}{78}{\mdline {4417}9.4.2.\hspace *{0.5em}\mdline {4417}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}MeterEntry}}}}{section*.103}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.4.3.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x MeterCounterData}}}}{78}{section*.104}} +\newlabel{sec-metercounterdata}{{}{78}{\mdline {4474}9.4.3.\hspace *{0.5em}\mdline {4474}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}MeterCounterData}}}}{section*.104}{}} +\@writefile{toc}{\contentsline {subsection}{9.5.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x PacketReplicationEngineEntry}}}}{79}{section*.105}} +\newlabel{sec-packetreplicationengineentry}{{}{79}{\mdline {4494}9.5.\hspace *{0.5em}\mdline {4494}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}PacketReplicationEngineEntry}}}}{section*.105}{}} +\@writefile{toc}{\contentsline {subsubsection}{9.5.1.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x MulticastGroupEntry}}}}{79}{section*.106}} +\newlabel{sec-multicastgroupentry}{{}{79}{\mdline {4502}9.5.1.\hspace *{0.5em}\mdline {4502}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}MulticastGroupEntry}}}}{section*.106}{}} +\newlabel{sec-valid-values-for-mg-id}{{}{80}{\mdline {4584}9.5.1.1.\hspace *{0.5em}\mdline {4584}Valid Values for \mdline {4584}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}multicast\_group\_id}}}}{section*.107}{}} +\@writefile{toc}{\contentsline {paragraph}{9.5.1.1.\hspace *{0.5em}Valid Values for \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x multicast\_group\_id}}}}{80}{section*.107}} +\@writefile{toc}{\contentsline {subsubsection}{9.5.2.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x CloneSessionEntry}}}}{81}{section*.108}} +\newlabel{sec-clonesessionentry}{{}{81}{\mdline {4599}9.5.2.\hspace *{0.5em}\mdline {4599}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}CloneSessionEntry}}}}{section*.108}{}} +\newlabel{sec-valid-values-for-session-id}{{}{82}{\mdline {4700}9.5.2.1.\hspace *{0.5em}\mdline {4700}Valid Values for \mdline {4700}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}session\_id}}}}{section*.109}{}} +\@writefile{toc}{\contentsline {paragraph}{9.5.2.1.\hspace *{0.5em}Valid Values for \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x session\_id}}}}{82}{section*.109}} +\@writefile{toc}{\contentsline {subsection}{9.6.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x ValueSetEntry}}}}{82}{section*.110}} +\newlabel{sec-valuesetentry}{{}{82}{\mdline {4717}9.6.\hspace *{0.5em}\mdline {4717}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}ValueSetEntry}}}}{section*.110}{}} +\@writefile{toc}{\contentsline {subsection}{9.7.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x RegisterEntry}}}}{84}{section*.111}} +\newlabel{sec-registerentry}{{}{84}{\mdline {4815}9.7.\hspace *{0.5em}\mdline {4815}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}RegisterEntry}}}}{section*.111}{}} +\@writefile{toc}{\contentsline {subsection}{9.8.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x DigestEntry}}}}{85}{section*.112}} +\newlabel{sec-digestentry}{{}{85}{\mdline {4842}9.8.\hspace *{0.5em}\mdline {4842}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}DigestEntry}}}}{section*.112}{}} +\@writefile{toc}{\contentsline {subsection}{9.9.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x ExternEntry}}}}{87}{section*.113}} +\newlabel{sec-extern-entry}{{}{87}{\mdline {4982}9.9.\hspace *{0.5em}\mdline {4982}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}ExternEntry}}}}{section*.113}{}} +\@writefile{toc}{\contentsline {section}{10.\hspace *{0.5em}Error Reporting Messages}{87}{section*.114}} +\newlabel{sec-error-reporting-messages}{{}{87}{\mdline {5008}10.\hspace *{0.5em}\mdline {5008}Error Reporting Messages}{section*.114}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces P4Runtime Error Report Message Format}{}}{88}{section*.114}} +\newlabel{fig-error-report}{{}{88}{\mdline {5008}10.\hspace *{0.5em}\mdline {5008}Error Reporting Messages}{section*.114}{}} +\@writefile{toc}{\contentsline {section}{11.\hspace *{0.5em}Atomicity of Individual \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Write}}} and \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Read}}} Operations}{89}{section*.115}} +\newlabel{sec-atomicity-of-individual-write-and-read-operations}{{}{89}{\mdline {5063}11.\hspace *{0.5em}\mdline {5063}Atomicity of Individual \mdline {5063}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Write}}}\mdline {5063} and \mdline {5063}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Read}}}\mdline {5063} Operations}{section*.115}{}} +\@writefile{toc}{\contentsline {section}{12.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Write}}} RPC}{90}{section*.116}} +\newlabel{sec-write-rpc}{{}{90}{\mdline {5145}12.\hspace *{0.5em}\mdline {5145}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Write}}}\mdline {5145} RPC}{section*.116}{}} +\@writefile{toc}{\contentsline {subsection}{12.1.\hspace *{0.5em}Batching and Ordering of Updates}{91}{section*.117}} +\newlabel{sec-batching-and-ordering-of-updates}{{}{91}{\mdline {5229}12.1.\hspace *{0.5em}\mdline {5229}Batching and Ordering of Updates}{section*.117}{}} +\@writefile{toc}{\contentsline {subsection}{12.2.\hspace *{0.5em}Batch Atomicity}{92}{section*.118}} +\newlabel{sec-batch-atomicity}{{}{92}{\mdline {5270}12.2.\hspace *{0.5em}\mdline {5270}Batch Atomicity}{section*.118}{}} +\@writefile{toc}{\contentsline {subsection}{12.3.\hspace *{0.5em}Error Reporting}{93}{section*.119}} +\newlabel{sec-error-reporting}{{}{93}{\mdline {5329}12.3.\hspace *{0.5em}\mdline {5329}Error Reporting}{section*.119}{}} +\@writefile{toc}{\contentsline {section}{13.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Read}}} RPC}{94}{section*.120}} +\newlabel{sec-read-rpc}{{}{94}{\mdline {5382}13.\hspace *{0.5em}\mdline {5382}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Read}}}\mdline {5382} RPC}{section*.120}{}} +\@writefile{toc}{\contentsline {subsection}{13.1.\hspace *{0.5em}Nomenclature}{95}{section*.121}} +\newlabel{sec-nomenclature}{{}{95}{\mdline {5425}13.1.\hspace *{0.5em}\mdline {5425}Nomenclature}{section*.121}{}} +\@writefile{toc}{\contentsline {subsection}{13.2.\hspace *{0.5em}Wildcard Reads}{95}{section*.122}} +\newlabel{sec-wildcard-reads}{{}{95}{\mdline {5437}13.2.\hspace *{0.5em}\mdline {5437}Wildcard Reads}{section*.122}{}} +\@writefile{toc}{\contentsline {subsection}{13.3.\hspace *{0.5em}Batch Processing}{95}{section*.123}} +\newlabel{sec-batch-processing}{{}{95}{\mdline {5473}13.3.\hspace *{0.5em}\mdline {5473}Batch Processing}{section*.123}{}} +\@writefile{toc}{\contentsline {subsubsection}{13.3.1.\hspace *{0.5em}Example}{96}{section*.124}} +\newlabel{sec-example}{{}{96}{\mdline {5509}13.3.1.\hspace *{0.5em}\mdline {5509}Example}{section*.124}{}} +\@writefile{toc}{\contentsline {subsection}{13.4.\hspace *{0.5em}Parallelism of Read and Write Requests}{96}{section*.125}} +\newlabel{sec-parallelism-of-read-and-write-requests}{{}{96}{\mdline {5535}13.4.\hspace *{0.5em}\mdline {5535}Parallelism of Read and Write Requests}{section*.125}{}} +\@writefile{toc}{\contentsline {section}{14.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x SetForwardingPipelineConfig}}} RPC}{97}{section*.126}} +\newlabel{sec-setforwardingpipelineconfig-rpc}{{}{97}{\mdline {5580}14.\hspace *{0.5em}\mdline {5580}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}SetForwardingPipelineConfig}}}\mdline {5580} RPC}{section*.126}{}} +\@writefile{toc}{\contentsline {section}{15.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x GetForwardingPipelineConfig}}} RPC}{98}{section*.127}} +\newlabel{sec-getforwardingpipelineconfig-rpc}{{}{98}{\mdline {5660}15.\hspace *{0.5em}\mdline {5660}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}GetForwardingPipelineConfig}}}\mdline {5660} RPC}{section*.127}{}} +\@writefile{toc}{\contentsline {section}{16.\hspace *{0.5em}P4Runtime Stream Messages}{100}{section*.128}} +\newlabel{sec-p4runtime-stream-messages}{{}{100}{\mdline {5726}16.\hspace *{0.5em}\mdline {5726}P4Runtime Stream Messages}{section*.128}{}} +\@writefile{toc}{\contentsline {subsection}{16.1.\hspace *{0.5em}Packet I/O}{100}{section*.129}} +\newlabel{sec-packet-i_o}{{}{100}{\mdline {5728}16.1.\hspace *{0.5em}\mdline {5728}Packet I/O}{section*.129}{}} +\@writefile{toc}{\contentsline {subsection}{16.2.\hspace *{0.5em}Client Arbitration Update}{101}{section*.130}} +\newlabel{sec-client-arbitration-update}{{}{101}{\mdline {5799}16.2.\hspace *{0.5em}\mdline {5799}Client Arbitration Update}{section*.130}{}} +\@writefile{toc}{\contentsline {subsubsection}{16.2.1.\hspace *{0.5em}Unset Election ID}{102}{section*.131}} +\newlabel{sec-unset-election-id}{{}{102}{\mdline {5870}16.2.1.\hspace *{0.5em}\mdline {5870}Unset Election ID}{section*.131}{}} +\@writefile{toc}{\contentsline {subsection}{16.3.\hspace *{0.5em}Digest Messages}{102}{section*.132}} +\newlabel{sec-digest-messages}{{}{102}{\mdline {5887}16.3.\hspace *{0.5em}\mdline {5887}Digest Messages}{section*.132}{}} +\@writefile{toc}{\contentsline {subsection}{16.4.\hspace *{0.5em}Table Idle Timeout Notification}{102}{section*.133}} +\newlabel{sec-table-idle-timeout-notification}{{}{102}{\mdline {5891}16.4.\hspace *{0.5em}\mdline {5891}Table Idle Timeout Notification}{section*.133}{}} +\@writefile{toc}{\contentsline {subsection}{16.5.\hspace *{0.5em}Architecture-Specific Notifications}{104}{section*.134}} +\newlabel{sec-architecture-specific-notifications}{{}{104}{\mdline {5961}16.5.\hspace *{0.5em}\mdline {5961}Architecture-Specific Notifications}{section*.134}{}} +\@writefile{toc}{\contentsline {subsection}{16.6.\hspace *{0.5em}Stream Error Reporting}{104}{section*.135}} +\newlabel{sec-stream-error-reporting}{{}{104}{\mdline {5971}16.6.\hspace *{0.5em}\mdline {5971}Stream Error Reporting}{section*.135}{}} +\@writefile{toc}{\contentsline {subsubsection}{16.6.1.\hspace *{0.5em}Examples of \texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x StreamError}}} Messages}{105}{section*.136}} +\newlabel{sec-examples-of-streamerror-messages}{{}{105}{\mdline {6021}16.6.1.\hspace *{0.5em}\mdline {6021}Examples of \mdline {6021}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}StreamError}}}\mdline {6021} Messages}{section*.136}{}} +\@writefile{toc}{\contentsline {section}{17.\hspace *{0.5em}\texttt {\hyphenchar \font =-1\relax {\mdfontfamily {LuxiMono}{\fontsize {10.95\dimexpr 0.75 pt\relax }{1.2\dimexpr 10.95\dimexpr 0.75 pt\relax \relax }\selectfont \setbox \@tempboxa \hbox {{ }}\presp \wd \@tempboxa \setbox \@tempboxa \box \voidb@x Capabilities}}} RPC}{105}{section*.137}} +\newlabel{sec-capabilities-rpc}{{}{105}{\mdline {6063}17.\hspace *{0.5em}\mdline {6063}\mdcode {{\mdfontfamily {LuxiMono}{\mdfontsize {\dimfont {0.75}}Capabilities}}}\mdline {6063} RPC}{section*.137}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces P4Runtime Metadata Translation for the Portable Switch Architecture}{}}{106}{section*.139}} +\newlabel{fig-psa-metadata-translation}{{}{106}{\mdline {6090}18.1.\hspace *{0.5em}\mdline {6090}PSA Metadata Translation}{section*.139}{}} +\@writefile{toc}{\contentsline {section}{18.\hspace *{0.5em}Portability Considerations}{106}{section*.138}} +\newlabel{sec-portability-considerations}{{}{106}{\mdline {6088}18.\hspace *{0.5em}\mdline {6088}Portability Considerations}{section*.138}{}} +\@writefile{toc}{\contentsline {subsection}{18.1.\hspace *{0.5em}PSA Metadata Translation}{106}{section*.139}} +\newlabel{sec-psa-metadata-translation}{{}{106}{\mdline {6090}18.1.\hspace *{0.5em}\mdline {6090}PSA Metadata Translation}{section*.139}{}} +\@writefile{toc}{\contentsline {subsubsection}{18.1.1.\hspace *{0.5em}Translation of Port Numbers}{107}{section*.140}} +\newlabel{sec-translation-of-port-numbers}{{}{107}{\mdline {6122}18.1.1.\hspace *{0.5em}\mdline {6122}Translation of Port Numbers}{section*.140}{}} +\@writefile{toc}{\contentsline {subsubsection}{18.1.2.\hspace *{0.5em}Translation of Packet-IO Header Fields}{108}{section*.141}} +\newlabel{sec-translation-of-packet-io-header-fields}{{}{108}{\mdline {6180}18.1.2.\hspace *{0.5em}\mdline {6180}Translation of Packet-IO Header Fields}{section*.141}{}} +\@writefile{toc}{\contentsline {subsubsection}{18.1.3.\hspace *{0.5em}Translation of Match Fields}{108}{section*.142}} +\newlabel{sec-translation-of-match-fields}{{}{108}{\mdline {6221}18.1.3.\hspace *{0.5em}\mdline {6221}Translation of Match Fields}{section*.142}{}} +\@writefile{toc}{\contentsline {subsubsection}{18.1.4.\hspace *{0.5em}Translation of Action Parameters}{109}{section*.143}} +\newlabel{sec-translation-of-action-parameters}{{}{109}{\mdline {6256}18.1.4.\hspace *{0.5em}\mdline {6256}Translation of Action Parameters}{section*.143}{}} +\@writefile{toc}{\contentsline {subsubsection}{18.1.5.\hspace *{0.5em}Port Translation for PSA Extern APIs}{109}{section*.144}} +\newlabel{sec-port-translation-for-psa-extern-apis}{{}{109}{\mdline {6284}18.1.5.\hspace *{0.5em}\mdline {6284}Port Translation for PSA Extern APIs}{section*.144}{}} +\@writefile{toc}{\contentsline {subsubsection}{18.1.6.\hspace *{0.5em}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}{110}{section*.145}} +\newlabel{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{{}{110}{\mdline {6304}18.1.6.\hspace *{0.5em}\mdline {6304}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}{section*.145}{}} +\@writefile{toc}{\contentsline {section}{19.\hspace *{0.5em}P4Runtime Versioning}{110}{section*.146}} +\newlabel{sec-p4runtime-versioning}{{}{110}{\mdline {6342}19.\hspace *{0.5em}\mdline {6342}P4Runtime Versioning}{section*.146}{}} +\@writefile{toc}{\contentsline {section}{20.\hspace *{0.5em}Extending P4Runtime for non-PSA Architectures}{111}{section*.147}} +\newlabel{sec-extending-p4runtime}{{}{111}{\mdline {6381}20.\hspace *{0.5em}\mdline {6381}Extending P4Runtime for non-PSA Architectures}{section*.147}{}} +\@writefile{toc}{\contentsline {subsection}{20.1.\hspace *{0.5em}Extending P4Runtime for Architecture-Specific Externs}{111}{section*.148}} +\newlabel{sec-extending-p4runtime-for-architecture-specific-externs}{{}{111}{\mdline {6404}20.1.\hspace *{0.5em}\mdline {6404}Extending P4Runtime for Architecture-Specific Externs}{section*.148}{}} +\@writefile{toc}{\contentsline {subsubsection}{20.1.1.\hspace *{0.5em}Extending the P4Info message}{112}{section*.149}} +\newlabel{sec-extending-the-p4info-message}{{}{112}{\mdline {6420}20.1.1.\hspace *{0.5em}\mdline {6420}Extending the P4Info message}{section*.149}{}} +\@writefile{toc}{\contentsline {subsubsection}{20.1.2.\hspace *{0.5em}Extending the P4Runtime Service}{112}{section*.150}} +\newlabel{sec-extending-the-p4runtime-service}{{}{112}{\mdline {6452}20.1.2.\hspace *{0.5em}\mdline {6452}Extending the P4Runtime Service}{section*.150}{}} +\@writefile{toc}{\contentsline {subsection}{20.2.\hspace *{0.5em}Architecture-Specific Table Extensions}{113}{section*.151}} +\newlabel{sec-architecture-specific-table-extensions}{{}{113}{\mdline {6480}20.2.\hspace *{0.5em}\mdline {6480}Architecture-Specific Table Extensions}{section*.151}{}} +\@writefile{toc}{\contentsline {subsubsection}{20.2.1.\hspace *{0.5em}New Match Types}{113}{section*.152}} +\newlabel{sec-new-match-types}{{}{113}{\mdline {6482}20.2.1.\hspace *{0.5em}\mdline {6482}New Match Types}{section*.152}{}} +\@writefile{toc}{\contentsline {subsubsection}{20.2.2.\hspace *{0.5em}New Table Properties}{113}{section*.153}} +\newlabel{sec-new-table-properties}{{}{113}{\mdline {6501}20.2.2.\hspace *{0.5em}\mdline {6501}New Table Properties}{section*.153}{}} +\@writefile{toc}{\contentsline {section}{21.\hspace *{0.5em}Known Limitations of Current P4Runtime Version}{113}{section*.154}} +\newlabel{sec-known-limitations-of-current-p4runtime-version}{{}{113}{\mdline {6511}21.\hspace *{0.5em}\mdline {6511}Known Limitations of Current P4Runtime Version}{section*.154}{}} +\@writefile{toc}{\contentsline {section}{A.\hspace *{0.5em}Appendix}{114}{section*.155}} +\newlabel{sec-appendix}{{}{114}{\mdline {6544}A.\hspace *{0.5em}\mdline {6544}Appendix}{section*.155}{}} +\@writefile{toc}{\contentsline {subsection}{A.1.\hspace *{0.5em}Revision History}{114}{section*.156}} +\newlabel{sec-revision-history}{{}{114}{\mdline {6546}A.1.\hspace *{0.5em}\mdline {6546}Revision History}{section*.156}{}} +\@writefile{toc}{\contentsline {subsubsection}{A.1.1.\hspace *{0.5em}Changes in v1.4.0}{114}{section*.157}} +\newlabel{sec-changes-in-v140}{{}{114}{\mdline {6548}A.1.1.\hspace *{0.5em}\mdline {6548}Changes in v1.4.0}{section*.157}{}} +\@writefile{toc}{\contentsline {subsubsection}{A.1.2.\hspace *{0.5em}Changes in v1.3.0}{115}{section*.158}} +\newlabel{sec-changes-in-v130}{{}{115}{\mdline {6585}A.1.2.\hspace *{0.5em}\mdline {6585}Changes in v1.3.0}{section*.158}{}} +\@writefile{toc}{\contentsline {subsubsection}{A.1.3.\hspace *{0.5em}Changes in v1.2.0}{115}{section*.159}} +\newlabel{sec-changes-in-v120}{{}{115}{\mdline {6596}A.1.3.\hspace *{0.5em}\mdline {6596}Changes in v1.2.0}{section*.159}{}} +\@writefile{toc}{\contentsline {subsubsection}{A.1.4.\hspace *{0.5em}Changes in v1.1.0}{115}{section*.160}} +\newlabel{sec-changes-in-v110}{{}{115}{\mdline {6616}A.1.4.\hspace *{0.5em}\mdline {6616}Changes in v1.1.0}{section*.160}{}} +\@writefile{toc}{\contentsline {subsection}{A.2.\hspace *{0.5em}P4 Annotations}{116}{section*.161}} +\newlabel{sec-p4-annotations}{{}{116}{\mdline {6641}A.2.\hspace *{0.5em}\mdline {6641}P4 Annotations}{section*.161}{}} +\@writefile{lot}{\contentsline {table}{\numberline {7}{\ignorespaces P4 annotations introduced by P4Runtime}{}}{116}{section*.161}} +\newlabel{tab-p4-annotations}{{}{116}{\mdline {6641}A.2.\hspace *{0.5em}\mdline {6641}P4 Annotations}{section*.161}{}} +\@writefile{toc}{\contentsline {subsection}{A.3.\hspace *{0.5em}A More Complex Value Set Example}{116}{section*.162}} +\newlabel{sec-value-set-example}{{}{116}{\mdline {6668}A.3.\hspace *{0.5em}\mdline {6668}A More Complex Value Set Example}{section*.162}{}} +\@writefile{toc}{\contentsline {subsection}{A.4.\hspace *{0.5em}Guidelines for Implementations}{118}{section*.163}} +\newlabel{sec-guidelines-for-implementations}{{}{118}{\mdline {6752}A.4.\hspace *{0.5em}\mdline {6752}Guidelines for Implementations}{section*.163}{}} +\@writefile{toc}{\contentsline {subsubsection}{A.4.1.\hspace *{0.5em}gRPC Metadata Maximum Size}{118}{section*.164}} +\newlabel{sec-grpc-metadata-maximum-size}{{}{118}{\mdline {6757}A.4.1.\hspace *{0.5em}\mdline {6757}gRPC Metadata Maximum Size}{section*.164}{}} +\@writefile{toc}{\contentsline {subsubsection}{A.4.2.\hspace *{0.5em}gRPC Server Maximum Receive Message Size}{118}{section*.165}} +\newlabel{sec-grpc-server-maximum-receive-message-size}{{}{118}{\mdline {6784}A.4.2.\hspace *{0.5em}\mdline {6784}gRPC Server Maximum Receive Message Size}{section*.165}{}} +\@writefile{toc}{\contentsline {subsection}{A.5.\hspace *{0.5em}P4Runtime Entries files}{119}{section*.166}} +\newlabel{sec-entries-files}{{}{119}{\mdline {6815}A.5.\hspace *{0.5em}\mdline {6815}P4Runtime Entries files}{section*.166}{}} +\bibcite{p4spec}{1} +\bibcite{rfc2697}{2} +\bibcite{rfc2698}{3} +\bibcite{arenaallocation}{4} +\bibcite{p4complextypes}{5} +\bibcite{protodefaults}{6} +\bibcite{p4enums}{7} +\bibcite{apiversioning}{8} +\bibcite{apiversioningbackwardscompatibility}{9} +\bibcite{grpcauth}{10} +\bibcite{grpc}{11} +\bibcite{grpcstreamc}{12} +\bibcite{p4newtypes}{13} +\bibcite{p4matchtypes}{14} +\bibcite{p4c}{15} +\bibcite{p4ctestprogramforconstentries}{16} +\bibcite{p4annotations}{17} +\bibcite{p4concurrency}{18} +\bibcite{p4runtimerepo}{19} +\bibcite{pirepo}{20} +\bibcite{p4apiwgcharter}{21} +\newlabel{sec-bibliography}{{}{120}{\refname }{section*.167}{}} +\newlabel{p4spec}{{1}{120}{\refname }{section*.167}{}} +\newlabel{rfc2697}{{2}{120}{\refname }{section*.167}{}} +\newlabel{rfc2698}{{3}{120}{\refname }{section*.167}{}} +\newlabel{arenaallocation}{{4}{120}{\refname }{section*.167}{}} +\newlabel{p4complextypes}{{5}{120}{\refname }{section*.167}{}} +\newlabel{protodefaults}{{6}{120}{\refname }{section*.167}{}} +\newlabel{p4enums}{{7}{120}{\refname }{section*.167}{}} +\newlabel{apiversioning}{{8}{120}{\refname }{section*.167}{}} +\newlabel{apiversioningbackwardscompatibility}{{9}{120}{\refname }{section*.167}{}} +\newlabel{grpcauth}{{10}{120}{\refname }{section*.167}{}} +\newlabel{grpc}{{11}{120}{\refname }{section*.167}{}} +\newlabel{grpcstreamc}{{12}{120}{\refname }{section*.167}{}} +\newlabel{p4newtypes}{{13}{120}{\refname }{section*.167}{}} +\newlabel{p4matchtypes}{{14}{120}{\refname }{section*.167}{}} +\newlabel{p4c}{{15}{120}{\refname }{section*.167}{}} +\newlabel{p4ctestprogramforconstentries}{{16}{120}{\refname }{section*.167}{}} +\newlabel{p4annotations}{{17}{120}{\refname }{section*.167}{}} +\newlabel{p4concurrency}{{18}{120}{\refname }{section*.167}{}} +\newlabel{p4runtimerepo}{{19}{120}{\refname }{section*.167}{}} +\bibcite{p4actionannotations}{22} +\bibcite{pna}{23} +\bibcite{psa}{24} +\bibcite{protooneofbackwardscompatibility}{25} +\bibcite{proto}{26} +\bibcite{psaactionselector}{27} +\bibcite{psaatomicityofcontrolplaneops}{28} +\bibcite{psatranslation}{29} +\bibcite{psaemptygroupactionappendix}{30} +\bibcite{p4selectexpr}{31} +\bibcite{semver}{32} +\bibcite{protostatus}{33} +\bibcite{p4revisions122}{34} +\bibcite{p4revisions124}{35} +\bibcite{p4tableproperties}{36} +\bibcite{protoany}{37} +\bibcite{grpcstatus}{38} +\bibcite{grpcerrordetails}{39} +\newlabel{pirepo}{{20}{121}{\refname }{section*.167}{}} +\newlabel{p4apiwgcharter}{{21}{121}{\refname }{section*.167}{}} +\newlabel{p4actionannotations}{{22}{121}{\refname }{section*.167}{}} +\newlabel{pna}{{23}{121}{\refname }{section*.167}{}} +\newlabel{psa}{{24}{121}{\refname }{section*.167}{}} +\newlabel{protooneofbackwardscompatibility}{{25}{121}{\refname }{section*.167}{}} +\newlabel{proto}{{26}{121}{\refname }{section*.167}{}} +\newlabel{psaactionselector}{{27}{121}{\refname }{section*.167}{}} +\newlabel{psaatomicityofcontrolplaneops}{{28}{121}{\refname }{section*.167}{}} +\newlabel{psatranslation}{{29}{121}{\refname }{section*.167}{}} +\newlabel{psaemptygroupactionappendix}{{30}{121}{\refname }{section*.167}{}} +\newlabel{p4selectexpr}{{31}{121}{\refname }{section*.167}{}} +\newlabel{semver}{{32}{121}{\refname }{section*.167}{}} +\newlabel{protostatus}{{33}{121}{\refname }{section*.167}{}} +\newlabel{p4revisions122}{{34}{121}{\refname }{section*.167}{}} +\newlabel{p4revisions124}{{35}{121}{\refname }{section*.167}{}} +\newlabel{p4tableproperties}{{36}{121}{\refname }{section*.167}{}} +\newlabel{protoany}{{37}{121}{\refname }{section*.167}{}} +\bibcite{grpcstatuscodes}{40} +\bibcite{openconfig}{41} +\bibcite{protomessagedifferencer}{42} +\bibcite{stratum}{43} +\bibcite{v1model}{44} +\bibcite{p4valuesets}{45} +\newlabel{grpcstatus}{{38}{122}{\refname }{section*.167}{}} +\newlabel{grpcerrordetails}{{39}{122}{\refname }{section*.167}{}} +\newlabel{grpcstatuscodes}{{40}{122}{\refname }{section*.167}{}} +\newlabel{openconfig}{{41}{122}{\refname }{section*.167}{}} +\newlabel{protomessagedifferencer}{{42}{122}{\refname }{section*.167}{}} +\newlabel{stratum}{{43}{122}{\refname }{section*.167}{}} +\newlabel{v1model}{{44}{122}{\refname }{section*.167}{}} +\newlabel{p4valuesets}{{45}{122}{\refname }{section*.167}{}} diff --git a/spec/main/P4Runtime-Spec.dimx b/spec/main/P4Runtime-Spec.dimx new file mode 100644 index 00000000..849b30e2 --- /dev/null +++ b/spec/main/P4Runtime-Spec.dimx @@ -0,0 +1,60 @@ +\%ordinal,(hash)name,width,(total) height,depth,image width,image height,bbox padding,size,mime,data-url +1,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +2,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +3,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +4,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +5,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +6,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +7,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +8,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +9,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +10,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +11,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +12,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +13,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +14,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +15,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +16,2002bba10a26e42e7324f3842669c712,28.1262pt,8.38889pt,1.94444pt,28.1853pt,8.91330pt,0.00000pt,1782,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHUAAAAlCAYAAAB8iqZLAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAE2UlEQVR42u1b63HcOAz+6EkBmpSg60BOByd3sEkHt+lAnlRwo3Qgd5DIHcgdxHIH2nQQbQfIj4N8MJakSO07Q87szK4EgSA+PEhAa4gIaVzuMMZkAL4AyAEUAN4DeAawAdAS0ZN+5iap7aIBrQH8BJAB+AbgDsDfADoAnwB0xpjBGFO+eS556sUC2rM3/kNEW8v9HMAgLn0moofkqfOKbY0xo/aEE3loBuDeBigAENEGwL241DDQCVSPYksAK1ZuceLp15xDB2NM46HT+fQ+geofdx7lHXtjlCmAXWOjfn9IoPpHKULdy6kmdYXbQNpfCVT/KE7tpXLTA2DLn48er87VpRcAeJewc+bTaXSnnp93sQ8BpBrULnnqheXTBUN68dNUiEjnVPcZsWCvMRcs5wTeFsAtH3MAItr5sFt3AEY+4NYWmjWAXtC0AHIbP8FT0lfqfgagVjQNgMzF0zFPybIMgk+n5xP0AwCK+NTHkiVynS3LM2i9w7PQFX+v+eFWgPMGRAakZ7q1hV/Giyr5d8O0Df8u+H41gchnRALQRShwAqiWC2UDnBRQWIytFJ9KANioe0WIkS2VJXCdhQC0tslje6ielC2YTItcS3AswE10ubrXSAsXgBF/Hx0Lp/+CyexCG5fVOub0RZRa0C1R+sFkEfRT1JQRwxkZbQxGuRi2OgpZqPDWTl0nBVqleJaWRUz3hoAFkzaMmVDbBayBFgB6UFmUw+T4v1NTCZD7nehjCRujulaF5hMJhrLK3pEPyJGvSxa6n/GqNsarFH3moKGYsH9MWQKAlt67doHaaCXHTC6tXOTb1rIpGpZ6gyNEdwsUv3IY03S/OqcsgTxWKuKtXJ6aWcLxbBhUtCQ2RSvJU+XebuFitJUWgc/1NsveJ58eS5YIXci5RyJ6W3wgoidZT+Qy1FRcfowsRP9ino+qRnmIas1azLWJqM0WWr4D1HuPJUvo+C6+Z8aYaq6iFAPAh5kOwiGrNZ/F98fAg3oeIN+Seu+xZAkdg9bvHKh30osjSlYvnm7DXt0PjghSKT9iuy62uY0x0nPac8lijCmNMT2/prIO4LXbfguM131kbK88+WfffFqozUEeedx4LaR4dvn5OWRR+gniadksjTceKyxErngK6GpMtFsi+uog/XSAfPpeWfkm0KOkd9x7otLWxdPyFsKhZclncu+sPgA83wSGiG8RofffwO7H40JQNwty0Rfx/cGh/NJnwBwK8yPLYktZc2nvVv1uQ0NENlOop5AwLUL0uGcxO5iPCml9QBitPHMWJ5BlKv43gUWMQR9pfMTOMp4D/CEC/HZPUOuIunA/J5/KS+VcPfxEsqwDGwf+4oPDcgfXpkYVr7OIqst6T1Az2QXx0LzWoiMMrrTIPZxKFrVpq2dktm5O55gSW0Nv6dx0sn127FqnY1GDbkGxAqeC9xhqQEK+RvBpeO3ZKWURXtiLULxivZeq8jXsGGJEYb5Wzd4mdAsvLH48RIPY06yXjejVAl6VWmN1LllUOG4E36kL1Lr4Wl9nEa9JvBDRbXrB5brGjeN8eg0vXaURCqo6n/5IKvozQL1LnnrdYyeniny6IaK/koqu3FONMavkpdc/3onNUc7HltcWDtc7NwCeY/64k8aZwy8faPsZutd/Kadx+eM3x5VLIWGloTIAAAAASUVORK5CYII= +17,fa3dbcbaeabd35dbb24e3f66f0cbfe14,26.3888pt,7.22429pt,0.39098pt,25.7763pt,7.46790pt,0.00000pt,1402,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGsAAAAfCAYAAADgDDPbAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADu0lEQVRo3u1b0ZGiQBB9bV0ArCFgBrohYAZ4l4FmoCFcaQbshcBloBmcbAaawSkZvPvYxpqjGBwVENidKkqoGoaeftM9r3taIYmv1nwTkRDAAoAPYAjgBGAHICL5XvTOQETWIkLHa+woSHJlnOQTg+SLyAHALwBbABOSLwCmCloiIpHtfQ9ACGAJIAHA3BUBmAMISMLlAjDW8c7GOGcdKwTgu47Vp0v1kunCs/RZap9Dvo9tsOxaPyhc9uGtTbhPBtZB9RFe6Rdrv9gKlnb8z6oeFG4L4PDZQVJdrDOLcegbGBhcPNqgwC2mxr3/gG8O9KPTLzqBzMtASURpI7kzcFhdCEZB3+OjYImIp6a8IHn8Yn4SGo+u5Gqvv4Hqsx6w1OT3JN9qVIAnIvOO4PXDot+yZnq4wAUsiIh/oxIDZY+LmhXwHUAkImcNP7wWgxUY9yfHd0wcpjaw/uSeb7WuRtyfWu1MJ7UEcBaR6NbF1YAL9DQ8KrKYsvbXuH91sqxbwNJg7lin+8sB9pvkRFfeTi36ICKxawDfQBvmnl0tK83Fwk5gjRyBGquyZk1rg+SO5FRl/a2Bd6KZlODJYHlVAT4omHh6p2XFAFbPZH8kjyRnAF4AbDTI34rI4YlkZFgV4AOHzc13sKo1gJTkpg1+h2RKcqWgrVRhGRlZdsSyTkUTs2UeLpkMx3yX3/IMwtxI91DDC6+B74a5rJB373suloUrtPjp7s+VPZIc6Z763mYGWeQ+SaY2sBKXfUvdH9ri/h5kkNuaGGRa1UBOllUElk5s+Qz2VxODDAwGGVb4qVNVgN8NFj4Ozza2U80OgWYyyDfdg2NlkEENljW8F/CBbQJlsZYyKk8ZVy+ahiwrBSxboIsaLMuVHY5cLSu/Il4NoHxlUrO+AKVH7RE+TnDn6lkWanFVLIL0DssyQd1fA8sWa8V9cH/ZvisisVL6ubLEKclRxSmz/R1JBj9P+FzB8vrk/kQkEJGtKiFUgjEhOdGDv6pbfIcbNC1wZw2Kc/UTl+Nl5I6ZO3i0HuYC46iJYF4Byr65dXwn659YazBKIugzHqzJeHL24mzMo5HsRU6GyCUjVKD7wAWsfKXTuWMAeQqKCdLyyfJksswdCo2uVzdZTLcz7k835siQ+4ArpV8NymZWLY0fqhss8ZtRRwooY3NvaOMCUzmzfTMjbNkii1FSZ+lU94cWF2jqajVPCWLbqm3hPprk3HRctsCkq39M0OA81pUKzTys+1z69q3DsgfqOjYAfhaccPeu/QMWuO/UR8JmcAAAAABJRU5ErkJggg== +18,7fc56270e7a70fa81a5935b72eacbe29,7.50002pt,6.83331pt,0.0pt,6.98610pt,6.98610pt,0.00000pt,658,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAYAAABWk2cPAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABj0lEQVRIx7WW/W2DMBDFf4cYgGQEskGaTtCOwAolG3SFKt2AZoIm3aBZodkARqBscP3nIlEL8xVjyQLskx7v7vn5UFVCTiABSqDwxUSEH0cgBXa+gKCgIvIMZPaZeOMsJaFAS2MJgKrKokxF5LUNaGvdbAOKR4HCnreZLimkI/ABnJ31tCs4DiSeZ1VdiYgLkixV0wJ4sfd6DNPoTpYHoFLVL9NH44RsggrJWPwCibNetoR0Di2kAnjrYNcskl4RyYC1qr53bFdDQorvOCJPnr06OFMTz0lVr56QcsiV4omAKZCr6qonrHK+106dJzM9t86kbzRDZzWawDIH6tuZ7Bn1kCvFIwET4AAkIjL1Lkzn1vRghv45Mv6nz5XiESy3ZuibCaWoWgzXc2p6BPYTU9rMFlJLPJeJoNWsmrbE8zDDseo+9UYDaT2pajUDtNeV4p60ZsBqpjc3fa4UeQALz6U8d/zvEi3nO9vYA9vW/sWs7zT0A9YrJcAjkDu1vBqR+iay3Gkbu2Y2oovQkfP7D2+ea93hugWEAAAAAElFTkSuQmCC +19,c2043615bebb807e33158410ceb0a1fe,50.12486pt,9.77197pt,1.35971pt,48.9027pt,10.1178pt,0.00000pt,2078,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMsAAAAqCAYAAAAd468UAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFt0lEQVR42u1d4ZWiSBD+6p4B4ITAZIB3ERyTgfs2gsMM9F0ImoFOBudkoBfBihnIZrCaQe0Pqnd7e0EaRQGteo83A2ID1fVVVX/VjcTMUHkuIaIEwH/MfFJt+MsfqoKnA8oSwBJArNpQsKiUAyUCkMhuqBpRsKiUy9r6/y9Vh4JFpTiqzAF8WIc0sihYVErSr5iZZwAyBYuCRaVc3gH8I/8bsAREFKhqFCwqP6PKFMCWmfdyaK+p2IVgIaI5EbHnFnl2UFrRTvrkBhwT0ZqIjpZOjnJs3OB1QgCfJf0yclCwlKerRLQ5F3EDAGMAUwApAHa2JXK6MWZm+GwAImnvaLVzlLbGAELfth5pE11vXL3K39TRVdzA9TYAIudYbF1n/oz9UKKrqaWXQvssMnJuSpnWDWwABD0y6KXc97rhtg8CiqDk88TR//iKayVF/SfPx7d4vp45rVAc99Jx6uw6mEKwSEO/RJUGPNuhJwoMkdchzLMfypR2YftraTOoOG/u03EexpCe+dy0nT4hUMaOflNxLMdLwGJ/aXPFTcXnQlqHlBdZqZFRXnyDa3gZvuP5LzLoovTL+fxHyvekUSVy7fJSsNi58+GKGzoCSDqstNgByabJSOJcy4T6xCcdtdJArutwCjxn1RbomMUPLEXUcdYAWzIHsGPmVQcZj7GwcRsBzAeAETO/WfRq0xJbY6GvHvUNly0cez5bAOBfAK8V20oZsfoyqAALiChk5qwOLSoe9LVjIEkAzCzjWMkAOLvD5V8c9tGAtEx2zr6vLt8BzKqeyaHuQ6f2olKjKPnF2a/redYAJncyQq+iHBEZ2joEsAAwZOZ73uPunENqKmIiH4RsPU63r68TKpuKLHXAImslsrbTL0lHEklJAgAniSqrlhY8TcSJhHIPVZ7c1fnJ43nnAEYXgFfTsAbB8uppoFHb6ZeVs08tI5sx86JNJUsEG9X4iuvtNx7RfOvrCJj5REQKlmvTsAKF+ypz7ZMv3wgkoUS1owAlk1Rw2DZQLhR7QJ8VpVbyzIasiAG8+EyMlCkdiXUoknYUNB5epqzS7M3zSwqQtlQjsQuJKa6oeneI0j5blMTvMy1+bDULnu6WKHVco85iFbV8O8B0XNhiJbbxQmKLnWbXudZaA+l2naWIPg46mH5l1n1GAN76vj5DGC0zs3vLzJ809+k2dWy8W+W4RZaqoo1xATPvmfkVwCcBzRTAkYiWfcy/Bejvsrtn5jc1z36ApZI+FvZrKsba5pjrQ0Dzhry4lgA4yNqQPoHmf6G5MwB/q2k+EFjECy5uOEWkLmi2zDwSinYrY5qDLOaJutwJwuRFAvZRX19+R0RJjYWEl27rtp5vUGJ4mcXDA07tRJaqBs4KvK6we3sZv0TIay5jACkR7WVste2YgU0lGm4fIPXaIZ9G9HKj9r+huuZ0X+q4gB1InXUfF62zaHGdij2L99AVetli9JbKSPWXDXNTsdBhvzqTfnk4g4yZJwCGyOeFhQDWRHRwinP3jiixpcvJmfPCrqeRzz5mccESdD398gDNSe57iHye2AuApbwoYnpnoISSTiw8dDmDvpe482D5UuAJ58gnBfZWBDQLZh7Ks3wDYN5wM791rUbaTz2BAgB/4gazlFVuF1lM+rXq2gD5SuCsWqjVpKLHmSewDEum0jYZU/b7LJIn28XJk3jjx1XGz+hpxgiNzlgmIsPkzD1OD5HXjsbMTGqqN+/7oxluIKfvf3NQgxqR5eGnXkjUHFm0c5OdsbbGHnXGIJqC3Ufs9LuQ+h6cy+2tWstDpV8eoNk36RyEQLj0TZMKluajSORE8M/OKUuZypXJmBYAMjr3M3mSNoTocVW5gyG+riz6yD52uC/Mm4fqyoT0NyVVnhQwv2RRVecx80nBoqLiKfqTEyoqChYVFQWLySfvMR18qSaiYmTQ43vf4fxbHZuQjZqIipHvzkCV7gP3hdUAAAAASUVORK5CYII= +20,8f21874330b0b0d2f91e831f2f0e7f6a,26.3888pt,8.88887pt,1.94443pt,25.7763pt,9.39510pt,0.00000pt,1410,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGsAAAAnCAYAAAAIJbYbAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADwUlEQVR42u1bS27bMBB9E/gAilF02YW8Lwo1R1Bu4KAnaHIDBz2CcgMlR3BuIK+7qZ0bKIvua3nV7XTRUcIo+oxkS6aYECBkGRRJzeN7HJIjYma8p+dERDGAiJkfbevbyTs8L4BaALgE4A/Q1pyIEiJKiSiTa0xEQd1zEQBW5oCZ0ZQBbBrq2WjqGToDyACkPbfhA0ilrQUAz/h/KfaJK56FB2AuD5YZOZbRFrboUCD1ZUY9mdQ1B+BbCNRC+jnvsY3AsIXX0I+0WKaqsjxHBzJAUtU5S4DyhmC8ANA4IAyGLSvBkoIvWLVn55K+ZeVARsyngnCANlJF2dDAIKwDy5SuZI/O5Q36lgM1FKtaEcDA4QmDMm/QdFn9jp6OJ1S+stEFLqQfcr3u0/MzbjfKx9ZyDcWe/YAllF8z863lrron8+qKmVc9NvWtwr51aWf8DjVggYj8lgYIxXu8GsHSKuqbVaaxJW2Vz5g4nFeB9atw35Zdo5A/GYSXwqqHntnrVTCmLv0xfp+pmNUGLNmqebRd/gps6ptV08K9llkmqB4ATBRgzZRABTJSZ7ajZLDqvk9WmYY+BOCvmMXMu47MWgK4HoH3N+RcVcaszoCfKCY3XzFSIwA7Zr4ZasOViLhrli0vAEgV5ZMjMeuVXE5qwMpBChTytxhY/h4A3Hc0xGcAHwH8BPBXMW8kNkgBEXkTBbNARF6JPB5N/mRNtOrwwoEsSu+Z+cJyqZ4Wp6cqGdxo5i2RPwwlfyObq9q66o1JM2eVgmXI38UYUJL+hgBuB3aCtocCvDNYAO4A3Azg+o6ZVWXMmnYF/KRiTqhda8nxt8fM1yNk1W7g5rcdvcOZllnFEXFWWFBGY5E/QwWOwap83brrwCwT1HWd655LYVAig8tjy59sFl8pR+kHAF8A/AawJKK2zSUHcKDWeN7M1W4y+EWHTwuWZ5n8nRsLW236JLlL2hespQGWVgZNBq5ymjbFTzwdL6Pno+8eTmfzPkeWnEarT99REglWV3heACvDnjEZRzBSHvLlWdCXOLeloqxp+1ADVjHSKRsZUPkLLyyK9cjjKi4VgUbN0U0V1B2V/JmsslSWKwNmoY0b3Dci551V6kDPPH6wKiK3NM6S6j5MkOMBH8DXIywm93HtUwBTZj61uI95nIovKrYTry+uCt4h174iESPE+B8HcuvUuzkIViZLklM4liYOssrDOMLg3jazhFVbZp65CNbEIaAWwqrvcDQ5wyzXWeUMs94Cq5xh1ltgFeDAB+ASS7511QM00z/ydN5HDNwskwAAAABJRU5ErkJggg== +21,7fc56270e7a70fa81a5935b72eacbe29,7.50002pt,6.83331pt,0.0pt,6.98610pt,6.98610pt,0.00000pt,658,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAYAAABWk2cPAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABj0lEQVRIx7WW/W2DMBDFf4cYgGQEskGaTtCOwAolG3SFKt2AZoIm3aBZodkARqBscP3nIlEL8xVjyQLskx7v7vn5UFVCTiABSqDwxUSEH0cgBXa+gKCgIvIMZPaZeOMsJaFAS2MJgKrKokxF5LUNaGvdbAOKR4HCnreZLimkI/ABnJ31tCs4DiSeZ1VdiYgLkixV0wJ4sfd6DNPoTpYHoFLVL9NH44RsggrJWPwCibNetoR0Di2kAnjrYNcskl4RyYC1qr53bFdDQorvOCJPnr06OFMTz0lVr56QcsiV4omAKZCr6qonrHK+106dJzM9t86kbzRDZzWawDIH6tuZ7Bn1kCvFIwET4AAkIjL1Lkzn1vRghv45Mv6nz5XiESy3ZuibCaWoWgzXc2p6BPYTU9rMFlJLPJeJoNWsmrbE8zDDseo+9UYDaT2pajUDtNeV4p60ZsBqpjc3fa4UeQALz6U8d/zvEi3nO9vYA9vW/sWs7zT0A9YrJcAjkDu1vBqR+iay3Gkbu2Y2oovQkfP7D2+ea93hugWEAAAAAElFTkSuQmCC +22,323b77d22bf5c16cfde8f2ac3446a479,103.2221pt,9.77197pt,1.35971pt,101.901pt,10.1178pt,0.00000pt,2714,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAacAAAAqCAYAAAAXtpQqAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAHlElEQVR42u1d7XHiSBB97XIA2BmcnIHYi2AhA1wbwUIGpjaCLZwBOIPDGcBFsIYMrBAWMuj7Ma31WCch8SWN4L0q1dpaLA09/aZ7erpnRFVBOIjIEMA/qrqlNAiCXCWaww1F8EfZpwCmAHotaGssIj32GkGukqs0Tpet7DGAof0ataCtKwBj9hxBrpKrNE6Xjbn3898Be2BTU3aCIFfJVRqnC/fEJgBevVtRYO1biYh6pFxTbQlylVy9dNwyRICeqnZFZGDKHlqo4Ku/6CsicwAxVZcgV8lVzpwuFy8AvtvPif3bEZFOKA1kNhJBkKs0TtfliT0BWKrqOmcKHlE1CIJcJWicUiXsichcRDYionZt7N7ghO+JAHxTVT+L5p0K39rBa+LpS9kVV3zmquQ5qyuXOblKHNu3sYgsima/N4E0siMiCwALAL/hUi/7AEY2hR8ASIlwipqBqRciQCZUAASaBUQU4ieAR9ObvEXomelS3/O+y/DdnueHarb2rEe7rnFAIVeJU82GV3C1ave5H1LVxi/zhFYAOgX/PwSg3jU44l1DAJOc+x3v+fMQ5FLQ/rm1cRFqG0va37EB5yxyhluA9nVlcuTznlJ5F+nnNcmYXL0erp5YHyNzXKYANhkdifP+7iYAC5qmXX4tWlBU1RmAZ+/WvGp4Juv1ARhlQgTpO7YMFZy1nyPr640NOonNeE6KnJnRsQvmfQCJqvZDX/A+t4zJVeKAfhyYPr6bsf6SE5FAcDMnz8uNK1pf39quDnjfYte7zCNUJxZ6Yyfs44Xfb3Apwed8p++ZLY54Ts+eEV27jMlVzpyOmDXFWQ5lOBrkzGlkFvRLWUqoeUsz71Zsi6X7WPAegMKFbng1CWXtsYU8PdE1vUCPqWdrE2lceQmgq6pdVV2e+fXJsZ619f/cvPeEMiZXL5Wr54SqblV1fQiHmi7C7Xnx8YmI/FUSOslmSA0yIYRdA80PAA8lHx3j875duxbPJzZ4HRs22gJ4u7Bp/A9v8HgF8HOPRIRTGaf4yLDPBMCbhakoY3L14rgaOpo2TveZtYEePm9PkkVWMR4qvucFwLjMemfSg3cqfA3ef9uM0tAGjNQYzOAWs5uYdSSZtkX7tMOyzIZ76Nc1yJhcJWpF02G9t12Dygm9zKoKyhTV/eX7JCIb86gj847vVLXJcNivzO/7zp6CCucFImNylbiqmdPIBoIIwKxCWCLKmWaXhQgmALoHEJBZQLvlOoQLv3SsH8bWhyFktCWHGidbU0iaDucFKGNylbge42ReX3ePP8l6SIsKHvCyKplVdSsiVPjdA8gPuNqfdMAZq+pzYE3NGqeHit8vPSvogTImV4lm0ba99fxtUZK86b/VegwsJt0DcF9lc0jbSmPo3YrtOUEovlXmx/hYBP9SV9tMpmnx3JMN/iNVvQvQMOVtwFlVTnNUWO+gjMnVULl6UWhRvnxac1KYG4//7w7w5yp59qTo7+waNvi9pyVtO7qep6S2ZY7P9TODlujLO/aoszEdWDVUo9RKGZOr4XC1hTpSWuck9sE2hJRWnifyqqqPdC3OKu8BPh+aNm5T1pPV//Q8J0xKwnkrAA91zpraLmNylThCRzb4SO3v5q1h3rTkiww8ZV9S2WtBgo+1mxhAP6Szcyq2/1OoJcBwXttlTK4SZ8NNC5S9A1f7AABrVe2z22oJ965V9QFu9+0Ebh1kIyLTlsTPs0WgUYF+Tez7PlPG5CpB47QP/rXpXwLgK7us9gH01QbQPlzoaQjg3c7tCXkALU0nt3DeExo+/qLFMiZXifMZJxEZnnDfqaJrfqAnNrUQwRouLsljkJsbQJeq2oVLJ17CZWO9275lcYBNrlLr9ALgueatlS5JxuRqc/IOdtw+FW7hitlmKDrw6Xj8RnmNQ57wn8yDXDI8EJSRWsOtjcRw9TgDuA06g1rQV9XEq4MBMrVLpl+dvCMZKGNytQUIctw+qV6FmK3nZTHNVHVEPQzag4vweRPOxAbQ1wDa5mcErW1Wkrb5HQVZQpQxuUrUys12ZOvZpptzC7eMdhE29FDHlcykEuunO7g93yK4A+beM4WSTaDo6IxUv9aUMblKhImgjJN5iAtT9rJwyxheHQvR+AC6tT67s765BzAVkY2FfZo2Th3TsWDDeW2SMblKXI1xsjTUVUVlB9xxvwm7MMgB9FlV7+A2C/0Nd/6Pisik5jqeXzme/sTaRRmTqwSNUyWs4OLW44rkSDODiHAH0VnDdTzZATFdG1lSxuQqETaCSIiwrWZgXm0ZIrh6kMGuLWmIAJXtY+aSrj+cdbdtb1uiFFubbVDG5CrRrJ6WJkTcBtDIOT7i0fvEpRkmaJ+XvwTQ9VKk6545PVLG5CoRBPzQc246fKPGyRZxBycaeIj2DKDrOgxF5syf2TUd131qGZOrxJERDH82/S3zkaltI5bArZ8CQNJoWC8ztdsXz23MuCJq17GFEYK7FpCrRP1604E7HmNfjFpzZAZBEATRWgPlz+q3ZZ9T1S2NE0EQBBEcbigCgiAIgsaJIAiCIGiciENQ05b8U8qYMiaIPNxSBEQB3gCce9frBWVMGRNEHv4DYzKY8HzJ0/gAAAAASUVORK5CYII= +23,67d25a48b1450fb4f887f3329a504ab8,26.3888pt,6.83331pt,0.0pt,25.7763pt,6.98610pt,0.00000pt,1138,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGsAAAAdCAYAAACtxJLQAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAC90lEQVRo3u1a7XHaQBB9y1CAQgmiA8UliA7IpAPTgagBd4BTgtyB6CDIHUAHsdXB5gd7+BA6afUR4ZjbmRvQzOqk2af3du9uiZnhbXwjoiWAFYAQwAzAG4AdgC0zv1bdMyGiDRGxckTKF8kb5snvGKSQiA4AfgHIAHxn5m8AFgJaTkRb1/0BgCWABEAOgEtjC+ARQMzM0AwAkcz3bs3zLnMtAYTaub7SkLiYWAQOn0R8DmUf12RmbHq+nHlw5nq5OwPrIPFYNvil4pc6wRLHC1b1fLkMwOHeQZJYbAxjFL6xhcFZ0SYVslhY/8Me2hzLQxe+nIBRGUgRUWvMvLNwWJ8LjArfY1+wiCgQKq+Y+egrP1pal9riai+/scTz34AllN8z87MnFADgpyO+dWYrXKwBC0QUtvyKYqkeVx6jy2CLvSnvsXFYuMD6Xbpuyy4vf9cpIXAwps7+WP8fVMxqA5Ys5o5e/i5sVrrWMqsorYUxVYA1VwIVifzNPT5Xmw6DAD6pKBuLjsxKAay9/DUyqzPgE0VyCxWs2gAomPlppDyQtNjP7DuyGzHrSi6nNWAZkCKF/CUjy98rgJeBJKYpb2SfgZ5EFEwVzAIRBRXyeDP5kxX+Dl/bZuX05JLBXJO3RP4wlvz9p1YMNZEmZ1WCZcnfD49Hu9zTFfDOYOF0ePbkOtX05mTWrCvgE0dOqF1rEVGC0/nU2mPRmlnaomiuZVb5i3iwgApx2qj18qcrhopSLLXMskHd15XuRgqjChlMby1/slm8GqF0B4BsgAJqj4/NXO0mQ1gu+LRgBZ9M/hY49XKMZX3BSi2wtB+YzcCdoWlT/8T5eBmlY2Y/1Ef6gRXHTHmP8c/rjvVdFWEK4FkWpN7a5y1zEhErZN5WjXXTOqsKLDCzP1DsbmtTaBDRY4OvifPLBTmU1PXyN4wc2l1LUa++wRrd3PpgD9roafoHTcFmqj/TL1jZZ0l1ve5yPBDi1OJbeCUbdPlh+lRCUbECH73ulXXBX7w6lfk2P9ENAAAAAElFTkSuQmCC +24,a5a2929bc80363d4ffe77ca4cf1911b8,25.83325pt,6.83331pt,0.0pt,24.8127pt,7.22700pt,0.00000pt,962,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGcAAAAeCAYAAAAxbADwAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACc0lEQVRo3u2a/XHaQBDFf5uhAKCD4A6w0wHugEkqCHRgl5AhHRAqiHEH0ILpAJUA6uDlDy2TixDfkrDD7czNYHSWmH37dt/uySRRpplZE3gD5pKGRDvbPlVwzwnQAR6iew8GctfMZh7Q1YJjZj2g7382o/v3+urJM0wPaBftaZT8zHHwuRMh+CfVt4Eu8Ah8zQVvtczxSOgU/KhbB6YPrIElMPV0/wykB/+3DEHgIKyBX8AguHQnKYmsoQOkoS/MbB0w5l7SoirmTByYae77m09tklJJi3OCtFFCZPSAnqSWmeXBiKLgylJ6DHz3z6vInHcCjpmNgETS64bCuS130cXnW+MCYDpe/D/nLiUBY9rRxddhzhj4UcCWNKa1K4Lj2r0t6WfB5SQKgusyZxKIgLytqmSOmT2ZmWpasw9Vc1wEvBQ1TW7LfBNWkPousQXwWgMrU+DjgLMRAZJae7blm632MaOKE5q6OTCPaW3bpnvSWZEgiKKgDnDMbACsNj3NHlvFKUGNac2HdyOgaWanTkojcyquOSOywebvI/e/xSlBDeCYWZdssHm0k80sTglqYs4EOPVFjcqmBD4FH9ZUy2Y7Gu3rgxOIgFOla0J2JFtFzXnk73sKddj7AycQAfdn3HdVlVqT9Ex2zHvTUnrik4BzjpmXBUBHK4M5ns76QOuC0UdlU4KbbUIdmLGnkLIcGnudbWvmgnebJL7pwR04DAo5ZDOsqae39AgV1QS+kB3ChQ9fOOArspPTxS2h4O1IGKjfcqIm8fqeBPU6wR2pA6sviV3LH6gj12zfvf635UGqM9bAyn6RPdpO5RsqzvTQPknpH42dvQgZUm8UAAAAAElFTkSuQmCC +25,5206560a306a2e085a437fd258eb57ce,8.05556pt,6.83331pt,0.0pt,7.22700pt,6.74520pt,0.00000pt,666,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAcCAYAAAB2+A+pAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABk0lEQVRIx72W0XHCMAyGP+UYIDOkG6QrhA3odQPYAK4jwAbQDcoI6QY92ICskGygvpg71+fEdpyr7vwQWdFv/ZIsAxwBjVy1qhJawC3g5yZACTRABbwDNX/lYhx1qvpNhIhIbXx+GP8AA/AFtMDdPWntnOwYE+FE5HvjpwVKe29ln1RV7yJiq0ryZG2YWrsbK4/xYAFWcxFFpDF0v3gNAoXxmElxCfTAdtTG89PVzvNM4DPQTtn4qO4cyipV7RIp3o5SbKTw6H6c79Q8X4Fd6LBFKOIUYBE5myq+hGxXEcAvCZfGNta+8FT5MDPiK3CIrYdiRN+lAIvIERhU9RRdCSPt0Ma2lHXNViktFxMxIlIuRXGI6ltMng3FJFEcoLpxptRmguJ6zu0WRfVIxJ/ASVXvs6bIRNHYEZ89c/aRNasngHv7qWLpqxyKY4Dt8dg7+qyXyVSO3TyXpor35glzIFci3kvP9az0JjfaENUbB7h3i+w/qH6ys2MhSQF+Y0kJDABvHy+xxACMjbvW9O2rZ05nyS83DMHEM2hQxQAAAABJRU5ErkJggg== +26,7fc56270e7a70fa81a5935b72eacbe29,7.50002pt,6.83331pt,0.0pt,6.98610pt,6.98610pt,0.00000pt,658,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAYAAABWk2cPAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABj0lEQVRIx7WW/W2DMBDFf4cYgGQEskGaTtCOwAolG3SFKt2AZoIm3aBZodkARqBscP3nIlEL8xVjyQLskx7v7vn5UFVCTiABSqDwxUSEH0cgBXa+gKCgIvIMZPaZeOMsJaFAS2MJgKrKokxF5LUNaGvdbAOKR4HCnreZLimkI/ABnJ31tCs4DiSeZ1VdiYgLkixV0wJ4sfd6DNPoTpYHoFLVL9NH44RsggrJWPwCibNetoR0Di2kAnjrYNcskl4RyYC1qr53bFdDQorvOCJPnr06OFMTz0lVr56QcsiV4omAKZCr6qonrHK+106dJzM9t86kbzRDZzWawDIH6tuZ7Bn1kCvFIwET4AAkIjL1Lkzn1vRghv45Mv6nz5XiESy3ZuibCaWoWgzXc2p6BPYTU9rMFlJLPJeJoNWsmrbE8zDDseo+9UYDaT2pajUDtNeV4p60ZsBqpjc3fa4UeQALz6U8d/zvEi3nO9vYA9vW/sWs7zT0A9YrJcAjkDu1vBqR+iay3Gkbu2Y2oovQkfP7D2+ea93hugWEAAAAAElFTkSuQmCC +27,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +28,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +29,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +30,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +31,ec53a8c4f07baed5d8825072c89799be,29.62851pt,6.83331pt,0.0pt,28.9080pt,6.74520pt,0.00000pt,1730,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAAcCAYAAACqAXueAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAEs0lEQVRo3u1b63HcNhD+oArgSQd0B5i4A6oDxumA6oAal0B3QKUCD90BlQoSXge8DjJUB8iPLOS9DUE8SNr0jDjDuTsKCyz2vR8oZa1F7KWU0gBqAPcAfgWgAbwAuAL4AuDJWvvCxlcA7q21D3i7fsh1F6tYpVQHYAbwAGAA8BuA9/TZAfgdwExKhVKqBNADmN7E/AMva+3qDcCQYi2ANjC2onENfVoAJrQG0fa0Thkz/nvcZ+QpeQ8RynWKKiOFUjGaOZKmZDTNSZR7Op5y7rtAvv2Tfj5aa58jI8JXyskA8BwZSO7Z9+eTBLcz8rRrDv6DiqiLtfZz4rxOIEPk+JIZyOUksjkjT/somLy3op9fMuZ9SbR8c0JPMT+796558Ef2/Zox7z8ArtbaIC1V20j0+EOvM/K0t4Lfs+8fMub95S3//jx9cJ0x71/UG7/l3zP2waLVsQBGAMUOrcck5g3dbeS8hgxqor51krQA9JE8kVGMbP0mgm/NaHSiLDXhDY7erTsAqFb7YCJe2txEgqxSGaJ5CxKEuzkg0om/mZg1CIywtLGCPe/omWZAjTmCJ6KZ3PxEFwMMNak4AzOmmZRbcp5oPy2AfhXooNAcsuaRJjOZHt2mIl5iI877Os+YgXiMFmIqT0zYekFxc4B2cGsl7NuBT/2KXNyey9BkdULo6jIUPKZukEUY55VDJBplIyNCEk80vvJEFRugfXWUjDSnQ0YDoEqJ9UOEkvtERdmQkkJKWFOaSDXj3jw5712ZY4qEgbtE+HQOOOXs+M8Jqyag8OpIrFfmyIQ12r15Ik9tVgrUZs/8m3WIs7Eq1qygSPLGnPy7UPyVO+fT1PH/KzaF4eutUWhFwa9F4GEKXso5a2Fpa/4VG5xT2rIjawKPAQ4H5N8iouDViwom4TU7HK3NR+Vf0bO2ewl7a03gKUrrvVLHyvn80j3zdvFOwHPXTLzk7xTsWill2M8+9q0SsuBYjDgJT87haeF6YADSUyQUOiQCUxdr7Tta6ys72HGXvplTWG+ZablFYjHDQ22R2P9FhVBRG5gjeNoQnjelAo/8W+HJ5tWDxenJJuw2EoN2FvziO3Gid8D4VSSecH1ka1zYvIVnvzk85UYMFy0uMoqISOKeN0qpwb3vtuDVV2vtI/57P+5GXndicyZTwY/0+RRzRMiE8ewRZC0UKpV6DYTbgjxKpg8XRs1OPPkM8BJ5FCl5+yTXUEo15J1lKHXQ2zS3MhIhY9oAN06RSJEJ9YlUKJiVIqhPaHfa0NxbeEoN8YK3emF/eqWdGiPTxHRTRYvYnQI6VEuVW8JLeaVHAF0gd6XAk5VQ5LQnT545isg2xwj6wQM9zvIwJWA8JXv2Df5iZX4X8kbhuUVmQVYutBmx8J72CHkS7YoRhVe7J0+eIqv2/H0SmIEWiqw9rdeY0Kp24vlrtWm4lbMjuIYEV9Jnh8j3pCOAkU4gYmOEYTWMN80UdEPPEKUm0niyefJENOmds4smTL41c5Yh4EyTBzkrGe/NAi0GT1iq8O0/E3gT7ZSuN5b2jTigbxKb/Z7Rjx7rb9mYmBCXzZOIBr04hO/EWbVmjjLTeB2xZ/5SAz/g9+rjXzoq3U9t8HhQAAAAAElFTkSuQmCC +32,5dbc98dcc983a70728bd082d1a47546e,6.70831pt,6.83331pt,0.0pt,6.02250pt,6.74520pt,0.00000pt,670,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAcCAYAAACUJBTQAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABlklEQVRIx62W0W2EMAxAXzoBajegGyB1A24D1BEYgc5wI9ANKkbgNmhvBNig4jZwP845uTQEyNWSldzh+MXEMUZE2KpABjRAD0yA6HjW/7OZfQW0e5y36nRQhyWQ61grSIBK15T6u9kCKMyujyu21c3xdRSg2ALwxuXGqCuzZhIR1l6Rj6DZeXaDruvWIJ0anvcAdK0/v1pEeCAgzrlMwwb4YL9cdDwBYQjwauZjAuQbGEVkjEGezfwlAfLko4hBrNQJkE89l6tsSEPRi5bvTQCvTp2GDn4K7HDU19ADJxG5bIorkob1LJqQnoEjUERTeiXft4C8tkmQQOVdA3VJkIV6FoNWd0MinwCv/b9CAnVOgGH+/MGkbeOca0iT1swf5w/tjT8k1imAr1its5DSVM+9Ynd/CkKccyX3Sbnw6n5FctCxSIS86fjuy/ufsmI6jSEhs46mi8kWL+Msz5sdgMr0XnnE7tYfTaZWtUu7WoggX7G93djClA3fbfRaQirdTKX2m/owC+lDPZU67AzQR9uHWtKY/gDdUeDbS+8vYAAAAABJRU5ErkJggg== +33,d20caec3b48a1eef164cb4ca81ba2587,6.80557pt,6.83331pt,0.0pt,6.26340pt,6.74520pt,0.00000pt,518,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAcCAYAAAB/E6/TAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABJUlEQVRIx72W4W2DMBBG36EMgDqCR2AGskGkbsAI3SEjpCswApmlIwQ2uP6oK7nIxj4DPcmSDbY/fzyLO1SVVAM+ADW2IbaX+A2TISKd7zpgXL3+BCZgAV7Aoqpf0Y22HEUczsHJJ8vahsIQEQe0waMRQzSGuf1q/DxL6Br00ywOdmRyUywU4TOdIrSXj0VoF59aR2Y3RUJH8Cl1tJtPqdBuPjWOqtxkhY7iU+LoED4Al7P5+K/SNf/A5w64rSTnSlJ0JlG2fm3bnMxnAJ6qumydZgzczFY3Qeq/qSql9cGjQuT+U5L4cSGfm1Gk9+vGnNCwEmorRBToc0KTlY+/YY/UuktQJL75ydfVjXuJSJ+4Vb+/qHegixSXf6KrKHtzbQZc6OgbuOc0w6KVa18AAAAASUVORK5CYII= +34,5dbc98dcc983a70728bd082d1a47546e,6.70831pt,6.83331pt,0.0pt,6.02250pt,6.74520pt,0.00000pt,670,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAcCAYAAACUJBTQAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABlklEQVRIx62W0W2EMAxAXzoBajegGyB1A24D1BEYgc5wI9ANKkbgNmhvBNig4jZwP845uTQEyNWSldzh+MXEMUZE2KpABjRAD0yA6HjW/7OZfQW0e5y36nRQhyWQ61grSIBK15T6u9kCKMyujyu21c3xdRSg2ALwxuXGqCuzZhIR1l6Rj6DZeXaDruvWIJ0anvcAdK0/v1pEeCAgzrlMwwb4YL9cdDwBYQjwauZjAuQbGEVkjEGezfwlAfLko4hBrNQJkE89l6tsSEPRi5bvTQCvTp2GDn4K7HDU19ADJxG5bIorkob1LJqQnoEjUERTeiXft4C8tkmQQOVdA3VJkIV6FoNWd0MinwCv/b9CAnVOgGH+/MGkbeOca0iT1swf5w/tjT8k1imAr1its5DSVM+9Ynd/CkKccyX3Sbnw6n5FctCxSIS86fjuy/ufsmI6jSEhs46mi8kWL+Msz5sdgMr0XnnE7tYfTaZWtUu7WoggX7G93djClA3fbfRaQirdTKX2m/owC+lDPZU67AzQR9uHWtKY/gDdUeDbS+8vYAAAAABJRU5ErkJggg== +35,d20caec3b48a1eef164cb4ca81ba2587,6.80557pt,6.83331pt,0.0pt,6.26340pt,6.74520pt,0.00000pt,518,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAcCAYAAAB/E6/TAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABJUlEQVRIx72W4W2DMBBG36EMgDqCR2AGskGkbsAI3SEjpCswApmlIwQ2uP6oK7nIxj4DPcmSDbY/fzyLO1SVVAM+ADW2IbaX+A2TISKd7zpgXL3+BCZgAV7Aoqpf0Y22HEUczsHJJ8vahsIQEQe0waMRQzSGuf1q/DxL6Br00ywOdmRyUywU4TOdIrSXj0VoF59aR2Y3RUJH8Cl1tJtPqdBuPjWOqtxkhY7iU+LoED4Al7P5+K/SNf/A5w64rSTnSlJ0JlG2fm3bnMxnAJ6qumydZgzczFY3Qeq/qSql9cGjQuT+U5L4cSGfm1Gk9+vGnNCwEmorRBToc0KTlY+/YY/UuktQJL75ydfVjXuJSJ+4Vb+/qHegixSXf6KrKHtzbQZc6OgbuOc0w6KVa18AAAAASUVORK5CYII= +36,d33def0eb4933f91b88eb4e784adaf05,10.21071pt,5.80553pt,1.49998pt,8.91330pt,5.78160pt,0.00000pt,670,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAYCAYAAAB9ejRwAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABl0lEQVRIx+2W7W2EMAyGX6MOwAyMgLpB6QaoI/Q2QOoINwJdgW4QRii3wd0KdIP0jyO9DeSDK1fdj1qKlC/jx8ZxAmstXAPQAJgAzADOADpeX2sAStIpU/tzGn+8U5Baxz0AC+CYgOp0nwXQ7AalEfrhKRmbE1DGQe0BxFATgNYzNuQYoyhNu0G5KEWMnSPKNe3rrzBer/1yF5HOm2zJWHeLfCKHzBpU658azpPYidLfnty3AtOTngmePu+IBxWuzSdy4KxQU8jGA5byQv0BARGRhoYj0vJkrf0i/UGjtpBiZe7gOtba94iRZ+qbFBEDpaTwvC+JPuV9QwZH7ChFyFCG9w7+5DlWi0i9J1RF/VNmPn16y2/ed34NxXLJzKfJW2szEz8b6pJSEJFKi+YiUiLSAhi3JHUO1BjILz4IBsBHwJFDrIxky0qRc1fM7J4xND+7i1uLoAXwquNjqtgGLvx0RVeFSpVmevD1ACqv8ve0Z9jyyNsM9RctBlXgDuUf6m6hRKTUa8hdRY9a+8Il4YaJzQ+7WDPfq1wmEB5jJZgAAAAASUVORK5CYII= +37,89ae78be880a004aa5404ac874a01bff,10.21071pt,5.80553pt,1.49998pt,9.15420pt,5.78160pt,0.00000pt,786,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAYCAYAAACWTY9zAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB7UlEQVRIx8VW7W2DMBB9jjIATTZgBLIC3YAZ6AZImaBKN6ArMALZoIUN6AYV2eD6o+foxQXbqSg9yYqJz7537z5siAjsAJAD6ACMAAYAFa9PDQAJ7UlC+rGDDVQKJtPvGoAAOAWAVaonAPJFgSlTNx6TwTEArLXAlgLFwDoAhWOwiTFIbHWLArNseQwOns0Z6dVLAtsCeALwDBJjTEGfNeYlp3mDgBhjEgBHdSjVv3sAbwBeReTC+oVbTZw3vkrTFAjqUc52+psrsIJThrvAXPlbxXaJ/LIAPOslnXWaA8ZKpeew3D3MoztGnMdRSr3hCRg7xfQvJwJDgNWro5uJ5Mz08xzI5Wvii8isriZ0H1FIHzRPtp4qawPAMqoqdi5TQD2BOyAsO5oPG2cxpXnvKXt24N1ZPjrnxMoj295EUus7pHPWiog0mJLSppCInH0JmM4kaUo6Yi992t/+4vqxvWyw/dBXQeVMhQ1OU0ycki/vBFUSqNTXYC1r4wQbo73s9aCrA9o+2jtBWVvtj9vHE65GgdhHY33j0Td7Nek09zwUCVTtfSiuOSh85Qwp+RYrizGm1LAfuNc5Vb3/D6aGuYrnR6uxr8UVmKqUqRcAn87yXnN2p4wd1mKqcnqfd4gI/pwxY0yq4YuVi4g8fAFVtZef41puOQAAAABJRU5ErkJggg== +38,d33def0eb4933f91b88eb4e784adaf05,10.21071pt,5.80553pt,1.49998pt,8.91330pt,5.78160pt,0.00000pt,670,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAYCAYAAAB9ejRwAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABl0lEQVRIx+2W7W2EMAyGX6MOwAyMgLpB6QaoI/Q2QOoINwJdgW4QRii3wd0KdIP0jyO9DeSDK1fdj1qKlC/jx8ZxAmstXAPQAJgAzADOADpeX2sAStIpU/tzGn+8U5Baxz0AC+CYgOp0nwXQ7AalEfrhKRmbE1DGQe0BxFATgNYzNuQYoyhNu0G5KEWMnSPKNe3rrzBer/1yF5HOm2zJWHeLfCKHzBpU658azpPYidLfnty3AtOTngmePu+IBxWuzSdy4KxQU8jGA5byQv0BARGRhoYj0vJkrf0i/UGjtpBiZe7gOtba94iRZ+qbFBEDpaTwvC+JPuV9QwZH7ChFyFCG9w7+5DlWi0i9J1RF/VNmPn16y2/ed34NxXLJzKfJW2szEz8b6pJSEJFKi+YiUiLSAhi3JHUO1BjILz4IBsBHwJFDrIxky0qRc1fM7J4xND+7i1uLoAXwquNjqtgGLvx0RVeFSpVmevD1ACqv8ve0Z9jyyNsM9RctBlXgDuUf6m6hRKTUa8hdRY9a+8Il4YaJzQ+7WDPfq1wmEB5jJZgAAAAASUVORK5CYII= +39,89ae78be880a004aa5404ac874a01bff,10.21071pt,5.80553pt,1.49998pt,9.15420pt,5.78160pt,0.00000pt,786,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAYCAYAAACWTY9zAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB7UlEQVRIx8VW7W2DMBB9jjIATTZgBLIC3YAZ6AZImaBKN6ArMALZoIUN6AYV2eD6o+foxQXbqSg9yYqJz7537z5siAjsAJAD6ACMAAYAFa9PDQAJ7UlC+rGDDVQKJtPvGoAAOAWAVaonAPJFgSlTNx6TwTEArLXAlgLFwDoAhWOwiTFIbHWLArNseQwOns0Z6dVLAtsCeALwDBJjTEGfNeYlp3mDgBhjEgBHdSjVv3sAbwBeReTC+oVbTZw3vkrTFAjqUc52+psrsIJThrvAXPlbxXaJ/LIAPOslnXWaA8ZKpeew3D3MoztGnMdRSr3hCRg7xfQvJwJDgNWro5uJ5Mz08xzI5Wvii8isriZ0H1FIHzRPtp4qawPAMqoqdi5TQD2BOyAsO5oPG2cxpXnvKXt24N1ZPjrnxMoj295EUus7pHPWiog0mJLSppCInH0JmM4kaUo6Yi992t/+4vqxvWyw/dBXQeVMhQ1OU0ycki/vBFUSqNTXYC1r4wQbo73s9aCrA9o+2jtBWVvtj9vHE65GgdhHY33j0Td7Nek09zwUCVTtfSiuOSh85Qwp+RYrizGm1LAfuNc5Vb3/D6aGuYrnR6uxr8UVmKqUqRcAn87yXnN2p4wd1mKqcnqfd4gI/pwxY0yq4YuVi4g8fAFVtZef41puOQAAAABJRU5ErkJggg== +40,d33def0eb4933f91b88eb4e784adaf05,10.21071pt,5.80553pt,1.49998pt,8.91330pt,5.78160pt,0.00000pt,670,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAYCAYAAAB9ejRwAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABl0lEQVRIx+2W7W2EMAyGX6MOwAyMgLpB6QaoI/Q2QOoINwJdgW4QRii3wd0KdIP0jyO9DeSDK1fdj1qKlC/jx8ZxAmstXAPQAJgAzADOADpeX2sAStIpU/tzGn+8U5Baxz0AC+CYgOp0nwXQ7AalEfrhKRmbE1DGQe0BxFATgNYzNuQYoyhNu0G5KEWMnSPKNe3rrzBer/1yF5HOm2zJWHeLfCKHzBpU658azpPYidLfnty3AtOTngmePu+IBxWuzSdy4KxQU8jGA5byQv0BARGRhoYj0vJkrf0i/UGjtpBiZe7gOtba94iRZ+qbFBEDpaTwvC+JPuV9QwZH7ChFyFCG9w7+5DlWi0i9J1RF/VNmPn16y2/ed34NxXLJzKfJW2szEz8b6pJSEJFKi+YiUiLSAhi3JHUO1BjILz4IBsBHwJFDrIxky0qRc1fM7J4xND+7i1uLoAXwquNjqtgGLvx0RVeFSpVmevD1ACqv8ve0Z9jyyNsM9RctBlXgDuUf6m6hRKTUa8hdRY9a+8Il4YaJzQ+7WDPfq1wmEB5jJZgAAAAASUVORK5CYII= +41,89ae78be880a004aa5404ac874a01bff,10.21071pt,5.80553pt,1.49998pt,9.15420pt,5.78160pt,0.00000pt,786,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAYCAYAAACWTY9zAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB7UlEQVRIx8VW7W2DMBB9jjIATTZgBLIC3YAZ6AZImaBKN6ArMALZoIUN6AYV2eD6o+foxQXbqSg9yYqJz7537z5siAjsAJAD6ACMAAYAFa9PDQAJ7UlC+rGDDVQKJtPvGoAAOAWAVaonAPJFgSlTNx6TwTEArLXAlgLFwDoAhWOwiTFIbHWLArNseQwOns0Z6dVLAtsCeALwDBJjTEGfNeYlp3mDgBhjEgBHdSjVv3sAbwBeReTC+oVbTZw3vkrTFAjqUc52+psrsIJThrvAXPlbxXaJ/LIAPOslnXWaA8ZKpeew3D3MoztGnMdRSr3hCRg7xfQvJwJDgNWro5uJ5Mz08xzI5Wvii8isriZ0H1FIHzRPtp4qawPAMqoqdi5TQD2BOyAsO5oPG2cxpXnvKXt24N1ZPjrnxMoj295EUus7pHPWiog0mJLSppCInH0JmM4kaUo6Yi992t/+4vqxvWyw/dBXQeVMhQ1OU0ycki/vBFUSqNTXYC1r4wQbo73s9aCrA9o+2jtBWVvtj9vHE65GgdhHY33j0Td7Nek09zwUCVTtfSiuOSh85Qwp+RYrizGm1LAfuNc5Vb3/D6aGuYrnR6uxr8UVmKqUqRcAn87yXnN2p4wd1mKqcnqfd4gI/pwxY0yq4YuVi4g8fAFVtZef41puOQAAAABJRU5ErkJggg== +42,d20caec3b48a1eef164cb4ca81ba2587,6.80557pt,6.83331pt,0.0pt,6.26340pt,6.74520pt,0.00000pt,518,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAcCAYAAAB/E6/TAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABJUlEQVRIx72W4W2DMBBG36EMgDqCR2AGskGkbsAI3SEjpCswApmlIwQ2uP6oK7nIxj4DPcmSDbY/fzyLO1SVVAM+ADW2IbaX+A2TISKd7zpgXL3+BCZgAV7Aoqpf0Y22HEUczsHJJ8vahsIQEQe0waMRQzSGuf1q/DxL6Br00ywOdmRyUywU4TOdIrSXj0VoF59aR2Y3RUJH8Cl1tJtPqdBuPjWOqtxkhY7iU+LoED4Al7P5+K/SNf/A5w64rSTnSlJ0JlG2fm3bnMxnAJ6qumydZgzczFY3Qeq/qSql9cGjQuT+U5L4cSGfm1Gk9+vGnNCwEmorRBToc0KTlY+/YY/UuktQJL75ydfVjXuJSJ+4Vb+/qHegixSXf6KrKHtzbQZc6OgbuOc0w6KVa18AAAAASUVORK5CYII= +43,d20caec3b48a1eef164cb4ca81ba2587,6.80557pt,6.83331pt,0.0pt,6.26340pt,6.74520pt,0.00000pt,518,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAcCAYAAAB/E6/TAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABJUlEQVRIx72W4W2DMBBG36EMgDqCR2AGskGkbsAI3SEjpCswApmlIwQ2uP6oK7nIxj4DPcmSDbY/fzyLO1SVVAM+ADW2IbaX+A2TISKd7zpgXL3+BCZgAV7Aoqpf0Y22HEUczsHJJ8vahsIQEQe0waMRQzSGuf1q/DxL6Br00ywOdmRyUywU4TOdIrSXj0VoF59aR2Y3RUJH8Cl1tJtPqdBuPjWOqtxkhY7iU+LoED4Al7P5+K/SNf/A5w64rSTnSlJ0JlG2fm3bnMxnAJ6qumydZgzczFY3Qeq/qSql9cGjQuT+U5L4cSGfm1Gk9+vGnNCwEmorRBToc0KTlY+/YY/UuktQJL75ydfVjXuJSJ+4Vb+/qHegixSXf6KrKHtzbQZc6OgbuOc0w6KVa18AAAAASUVORK5CYII= +44,5dbc98dcc983a70728bd082d1a47546e,6.70831pt,6.83331pt,0.0pt,6.02250pt,6.74520pt,0.00000pt,670,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAcCAYAAACUJBTQAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABlklEQVRIx62W0W2EMAxAXzoBajegGyB1A24D1BEYgc5wI9ANKkbgNmhvBNig4jZwP845uTQEyNWSldzh+MXEMUZE2KpABjRAD0yA6HjW/7OZfQW0e5y36nRQhyWQ61grSIBK15T6u9kCKMyujyu21c3xdRSg2ALwxuXGqCuzZhIR1l6Rj6DZeXaDruvWIJ0anvcAdK0/v1pEeCAgzrlMwwb4YL9cdDwBYQjwauZjAuQbGEVkjEGezfwlAfLko4hBrNQJkE89l6tsSEPRi5bvTQCvTp2GDn4K7HDU19ADJxG5bIorkob1LJqQnoEjUERTeiXft4C8tkmQQOVdA3VJkIV6FoNWd0MinwCv/b9CAnVOgGH+/MGkbeOca0iT1swf5w/tjT8k1imAr1its5DSVM+9Ynd/CkKccyX3Sbnw6n5FctCxSIS86fjuy/ufsmI6jSEhs46mi8kWL+Msz5sdgMr0XnnE7tYfTaZWtUu7WoggX7G93djClA3fbfRaQirdTKX2m/owC+lDPZU67AzQR9uHWtKY/gDdUeDbS+8vYAAAAABJRU5ErkJggg== +45,5dbc98dcc983a70728bd082d1a47546e,6.70831pt,6.83331pt,0.0pt,6.02250pt,6.74520pt,0.00000pt,670,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAcCAYAAACUJBTQAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABlklEQVRIx62W0W2EMAxAXzoBajegGyB1A24D1BEYgc5wI9ANKkbgNmhvBNig4jZwP845uTQEyNWSldzh+MXEMUZE2KpABjRAD0yA6HjW/7OZfQW0e5y36nRQhyWQ61grSIBK15T6u9kCKMyujyu21c3xdRSg2ALwxuXGqCuzZhIR1l6Rj6DZeXaDruvWIJ0anvcAdK0/v1pEeCAgzrlMwwb4YL9cdDwBYQjwauZjAuQbGEVkjEGezfwlAfLko4hBrNQJkE89l6tsSEPRi5bvTQCvTp2GDn4K7HDU19ADJxG5bIorkob1LJqQnoEjUERTeiXft4C8tkmQQOVdA3VJkIV6FoNWd0MinwCv/b9CAnVOgGH+/MGkbeOca0iT1swf5w/tjT8k1imAr1its5DSVM+9Ynd/CkKccyX3Sbnw6n5FctCxSIS86fjuy/ufsmI6jSEhs46mi8kWL+Msz5sdgMr0XnnE7tYfTaZWtUu7WoggX7G93djClA3fbfRaQirdTKX2m/owC+lDPZU67AzQR9uHWtKY/gDdUeDbS+8vYAAAAABJRU5ErkJggg== +46,d20caec3b48a1eef164cb4ca81ba2587,6.80557pt,6.83331pt,0.0pt,6.26340pt,6.74520pt,0.00000pt,518,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAcCAYAAAB/E6/TAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABJUlEQVRIx72W4W2DMBBG36EMgDqCR2AGskGkbsAI3SEjpCswApmlIwQ2uP6oK7nIxj4DPcmSDbY/fzyLO1SVVAM+ADW2IbaX+A2TISKd7zpgXL3+BCZgAV7Aoqpf0Y22HEUczsHJJ8vahsIQEQe0waMRQzSGuf1q/DxL6Br00ywOdmRyUywU4TOdIrSXj0VoF59aR2Y3RUJH8Cl1tJtPqdBuPjWOqtxkhY7iU+LoED4Al7P5+K/SNf/A5w64rSTnSlJ0JlG2fm3bnMxnAJ6qumydZgzczFY3Qeq/qSql9cGjQuT+U5L4cSGfm1Gk9+vGnNCwEmorRBToc0KTlY+/YY/UuktQJL75ydfVjXuJSJ+4Vb+/qHegixSXf6KrKHtzbQZc6OgbuOc0w6KVa18AAAAASUVORK5CYII= +47,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +48,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +49,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +50,2002bba10a26e42e7324f3842669c712,28.1262pt,8.38889pt,1.94444pt,28.1853pt,8.91330pt,0.00000pt,1782,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHUAAAAlCAYAAAB8iqZLAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAE2UlEQVR42u1b63HcOAz+6EkBmpSg60BOByd3sEkHt+lAnlRwo3Qgd5DIHcgdxHIH2nQQbQfIj4N8MJakSO07Q87szK4EgSA+PEhAa4gIaVzuMMZkAL4AyAEUAN4DeAawAdAS0ZN+5iap7aIBrQH8BJAB+AbgDsDfADoAnwB0xpjBGFO+eS556sUC2rM3/kNEW8v9HMAgLn0moofkqfOKbY0xo/aEE3loBuDeBigAENEGwL241DDQCVSPYksAK1ZuceLp15xDB2NM46HT+fQ+geofdx7lHXtjlCmAXWOjfn9IoPpHKULdy6kmdYXbQNpfCVT/KE7tpXLTA2DLn48er87VpRcAeJewc+bTaXSnnp93sQ8BpBrULnnqheXTBUN68dNUiEjnVPcZsWCvMRcs5wTeFsAtH3MAItr5sFt3AEY+4NYWmjWAXtC0AHIbP8FT0lfqfgagVjQNgMzF0zFPybIMgk+n5xP0AwCK+NTHkiVynS3LM2i9w7PQFX+v+eFWgPMGRAakZ7q1hV/Giyr5d8O0Df8u+H41gchnRALQRShwAqiWC2UDnBRQWIytFJ9KANioe0WIkS2VJXCdhQC0tslje6ielC2YTItcS3AswE10ubrXSAsXgBF/Hx0Lp/+CyexCG5fVOub0RZRa0C1R+sFkEfRT1JQRwxkZbQxGuRi2OgpZqPDWTl0nBVqleJaWRUz3hoAFkzaMmVDbBayBFgB6UFmUw+T4v1NTCZD7nehjCRujulaF5hMJhrLK3pEPyJGvSxa6n/GqNsarFH3moKGYsH9MWQKAlt67doHaaCXHTC6tXOTb1rIpGpZ6gyNEdwsUv3IY03S/OqcsgTxWKuKtXJ6aWcLxbBhUtCQ2RSvJU+XebuFitJUWgc/1NsveJ58eS5YIXci5RyJ6W3wgoidZT+Qy1FRcfowsRP9ino+qRnmIas1azLWJqM0WWr4D1HuPJUvo+C6+Z8aYaq6iFAPAh5kOwiGrNZ/F98fAg3oeIN+Seu+xZAkdg9bvHKh30osjSlYvnm7DXt0PjghSKT9iuy62uY0x0nPac8lijCmNMT2/prIO4LXbfguM131kbK88+WfffFqozUEeedx4LaR4dvn5OWRR+gniadksjTceKyxErngK6GpMtFsi+uog/XSAfPpeWfkm0KOkd9x7otLWxdPyFsKhZclncu+sPgA83wSGiG8RofffwO7H40JQNwty0Rfx/cGh/NJnwBwK8yPLYktZc2nvVv1uQ0NENlOop5AwLUL0uGcxO5iPCml9QBitPHMWJ5BlKv43gUWMQR9pfMTOMp4D/CEC/HZPUOuIunA/J5/KS+VcPfxEsqwDGwf+4oPDcgfXpkYVr7OIqst6T1Az2QXx0LzWoiMMrrTIPZxKFrVpq2dktm5O55gSW0Nv6dx0sn127FqnY1GDbkGxAqeC9xhqQEK+RvBpeO3ZKWURXtiLULxivZeq8jXsGGJEYb5Wzd4mdAsvLH48RIPY06yXjejVAl6VWmN1LllUOG4E36kL1Lr4Wl9nEa9JvBDRbXrB5brGjeN8eg0vXaURCqo6n/5IKvozQL1LnnrdYyeniny6IaK/koqu3FONMavkpdc/3onNUc7HltcWDtc7NwCeY/64k8aZwy8faPsZutd/Kadx+eM3x5VLIWGloTIAAAAASUVORK5CYII= +51,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +52,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +53,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +54,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +55,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +56,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= +57,ec53a8c4f07baed5d8825072c89799be,29.62851pt,6.83331pt,0.0pt,28.9080pt,6.74520pt,0.00000pt,1730,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAAcCAYAAACqAXueAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAEs0lEQVRo3u1b63HcNhD+oArgSQd0B5i4A6oDxumA6oAal0B3QKUCD90BlQoSXge8DjJUB8iPLOS9DUE8SNr0jDjDuTsKCyz2vR8oZa1F7KWU0gBqAPcAfgWgAbwAuAL4AuDJWvvCxlcA7q21D3i7fsh1F6tYpVQHYAbwAGAA8BuA9/TZAfgdwExKhVKqBNADmN7E/AMva+3qDcCQYi2ANjC2onENfVoAJrQG0fa0Thkz/nvcZ+QpeQ8RynWKKiOFUjGaOZKmZDTNSZR7Op5y7rtAvv2Tfj5aa58jI8JXyskA8BwZSO7Z9+eTBLcz8rRrDv6DiqiLtfZz4rxOIEPk+JIZyOUksjkjT/somLy3op9fMuZ9SbR8c0JPMT+796558Ef2/Zox7z8ArtbaIC1V20j0+EOvM/K0t4Lfs+8fMub95S3//jx9cJ0x71/UG7/l3zP2waLVsQBGAMUOrcck5g3dbeS8hgxqor51krQA9JE8kVGMbP0mgm/NaHSiLDXhDY7erTsAqFb7YCJe2txEgqxSGaJ5CxKEuzkg0om/mZg1CIywtLGCPe/omWZAjTmCJ6KZ3PxEFwMMNak4AzOmmZRbcp5oPy2AfhXooNAcsuaRJjOZHt2mIl5iI877Os+YgXiMFmIqT0zYekFxc4B2cGsl7NuBT/2KXNyey9BkdULo6jIUPKZukEUY55VDJBplIyNCEk80vvJEFRugfXWUjDSnQ0YDoEqJ9UOEkvtERdmQkkJKWFOaSDXj3jw5712ZY4qEgbtE+HQOOOXs+M8Jqyag8OpIrFfmyIQ12r15Ik9tVgrUZs/8m3WIs7Eq1qygSPLGnPy7UPyVO+fT1PH/KzaF4eutUWhFwa9F4GEKXso5a2Fpa/4VG5xT2rIjawKPAQ4H5N8iouDViwom4TU7HK3NR+Vf0bO2ewl7a03gKUrrvVLHyvn80j3zdvFOwHPXTLzk7xTsWill2M8+9q0SsuBYjDgJT87haeF6YADSUyQUOiQCUxdr7Tta6ys72HGXvplTWG+ZablFYjHDQ22R2P9FhVBRG5gjeNoQnjelAo/8W+HJ5tWDxenJJuw2EoN2FvziO3Gid8D4VSSecH1ka1zYvIVnvzk85UYMFy0uMoqISOKeN0qpwb3vtuDVV2vtI/57P+5GXndicyZTwY/0+RRzRMiE8ewRZC0UKpV6DYTbgjxKpg8XRs1OPPkM8BJ5FCl5+yTXUEo15J1lKHXQ2zS3MhIhY9oAN06RSJEJ9YlUKJiVIqhPaHfa0NxbeEoN8YK3emF/eqWdGiPTxHRTRYvYnQI6VEuVW8JLeaVHAF0gd6XAk5VQ5LQnT545isg2xwj6wQM9zvIwJWA8JXv2Df5iZX4X8kbhuUVmQVYutBmx8J72CHkS7YoRhVe7J0+eIqv2/H0SmIEWiqw9rdeY0Kp24vlrtWm4lbMjuIYEV9Jnh8j3pCOAkU4gYmOEYTWMN80UdEPPEKUm0niyefJENOmds4smTL41c5Yh4EyTBzkrGe/NAi0GT1iq8O0/E3gT7ZSuN5b2jTigbxKb/Z7Rjx7rb9mYmBCXzZOIBr04hO/EWbVmjjLTeB2xZ/5SAz/g9+rjXzoq3U9t8HhQAAAAAElFTkSuQmCC +58,45bea56774116dfcbe5c62b4067ed3dd,21.28131pt,8.3333pt,1.49998pt,20.2356pt,8.67240pt,0.00000pt,1386,image/png, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAkCAYAAAAXSR0AAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsElEQVRo3u1a7XHaQBB9y6gAQioIJRCngkAHdlKBoQMYV+CROxCpwBEdoBIMHaAOYuhg82fP2blgsXdCRvJ4Z24QQrqPvd23b5cjZkaXhIiGADYAbpi5aNv8eicmPyUirtH2RLQmolQUcQ7JAPQBDFu54VUWSkR9AFeygAGAVK6dLACUAA7eq27B3wBcq/tLZp7VsM5rALl8nTHzsnUaZWZzE1djabnxnb733jpkTK+fvepnGtNP060XqP+Run40btgBwHd1a0xEacTe+97RSukFuNvYu1UEeMEBwFbdmga6+gjADwDLd6NQABN1XYqSQqTUGCtKskoO4LYLLCREoeMY6/QCVUwgmssGrrqg0CQSP9cRY11VWGwV57wD8KUrPLlntJJo/FQYqC20MEJGBuA+Al5a7/J18XN2JGJbOOeQmR+6lMlZXX5cwzr7XlR/MKaMvzy69a4sVOPnJnCMXF2vmHlh2IQMwG9m3nZNoYlhcVH4KQElV5uxsLiv45zM/AkdFIvLa/w8MHNpyP1nKodfiTLLAIu+RUfFotCxR8j3Bp5ZSOFkFaDIN+Gc4gGD2NIfEU0B3KhqVwkgfenPUJBg1Vw+fbTVKSqo4sew4pmsTnFE4CeqQCOGtRcOPvL63ACYMzMsnWiFjpqq0shE5yeeiVKoLDqLrXgJS2EAWZWOLNWmiVfk2Dbkho1wTiLaEBErprGN6GMsm1G8UsudhGBo3fzdKk1xzu86CSGi3KOAIbTvNbp3L3C1rlSoROy6+bvFAjLZrFLGDE0adInwWNmwztymoqzyNe+UMWb6xmu4cf0W+Alg540T21LDWHkIhqq55db1JJfGT6EgA+OzmaIrD57XlGf2nL5HjZzFzvDvP7bC59jJpfEzZKOISH/dNfw3si43/hH8LR0ui8JTADsieskCE8PuNIafLReN5z8lyi987CSiAYCUiA7MvOwZrLPpCN9W0TA0rCjqZO6TiPq9C+PnuSyoaSkqIEv/dpeoypAD2olXv3RgXAJ4RlyBOTYw+PPSMDQjogOAJxc4zjyv54CAd5B5jnV+ezZ6ciFKNT0nbfL0cioldgcw9om4M7UUx75WkfRTxL4u+1Cs4rPVqhO0WE4p6Q2gpxA3HhrxfNvDh5xKJI6xHh/nnTx+KLTaA1YSkKpOurg8fsvMK7TxBFsDwc0VelyQqyxke+8O5fmdX0RXtdCX3967IjMjQ1gblLoRxaYA5pI9/sd6qGtHwi8p4vbuAPIWwJMfGP8CWt67mPyFy/MAAAAASUVORK5CYII= + diff --git a/spec/main/P4Runtime-Spec.html b/spec/main/P4Runtime-Spec.html new file mode 100644 index 00000000..36ac10fa --- /dev/null +++ b/spec/main/P4Runtime-Spec.html @@ -0,0 +1,7606 @@ + + + + + + + + P4Runtime Specification + + + + + + + +
+
+
+
P4Runtime Specification
+
version 1.4.0-dev
+
+
+
The P4.org API Working Group
+
2024-09-16
+
+

Abstract. P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.

+ + +

1. Introduction and Scope

+

This document is published by the P4.org API Working Group, which was +chartered [21] to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called P4Runtime. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +https://github.com/p4lang/p4runtime/tree/main/proto. +

1.1. P4 Language Version Applicability

+

P4Runtime is designed to be implemented in conjunction with the P416 language +version or later. P414 programs should be translated into P416 to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P416 1.0, but were introduced in P416 1.2.4 [35]. For +this version of P4Runtime, we recommend using P416 1.2.4 [35]. +

+

This version of the P4Runtime specification does not yet explicitly +address compatibility with the following P416 language features +introduced in versions 1.2.2 or 1.2.4 of the language specification: +

+
    +
  • Added support for generic structures [34]. +
  • +
  • Added support for additional enumeration types [34]. +
  • +
  • Added support for 0-width bitstrings and varbits [34]. +
  • +
  • Clarified restrictions for parameters with default values +[35]. +
  • +
  • Allow ranges to be specified by serializable enums +[35]. +
  • +
  • Added list type [35]. +
  • +
  • Clarified behavior of table with no key property, or if its list +of keys is empty [35]. +
+

1.2. In Scope

+

This specification document defines the semantics of P4Runtime messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime: +

+
    +
  • Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA) [24] externs (e.g. Counters, Meters, Action +Profiles, ). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0. +
  • +
  • Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism. +
  • +
  • Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy. +
  • +
  • Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities. +
  • +
  • Packet I/O to enable streaming packets to & from the control plane. +
  • +
  • Batching support, with different atomicity guarantees. +
  • +
  • In-the-field device-reconfiguration with a new P4 data plane. +
+ +

The following are in the scope of this specification document: +

+
    +
  • Rationale for the P4Runtime design. +
  • +
  • Reference architecture and use-cases for deploying a P4Runtime service. +
  • +
  • Detailed description of the API semantics. +
  • +
  • Requirements for conformant implementations of the API. +
+

1.3. Not In Scope

+

The following are not in scope of P4Runtime: +

+
    +
  • Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +[41]. An open source implementation of these APIs is also in progress +as part of the Stratum project [43]. +
  • +
  • Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures. +
+ +

The following are not in scope of this specification document: +

+
    +
  • Description of the P4 programming language; it is assumed that the reader is +already familiar with P416 [1]. +
  • +
  • Descriptions of gRPC and Protobuf files in general. +
  • +
  • Controller role definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme. +
+

2. Terms and Definitions

+
+
arbitration
+
Refers to the process through which P4Runtime ensures that at any given +time, there is a single primary controller (i.e. a client with write access) +for a given role. Also referred to as “client arbitration”. +
+
client
+
The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +
+
COS
+
Class of Service. +
+
device
+
Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +
+
entity
+
An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +
+
gRPC
+
gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +[11]. +
+
HA
+
High-Availability. Refers to a redundancy architecture. +
+
Instrumentation
+
The part of the P4Runtime server which implements the calls to the device or +target native “SDK” or backend. +
+
IPC
+
Inter-Process Communication. +
+
P4 Blob
+
A more colloquial term for P4 Device Config (Blob = Binary Large Object). +
+
P4 Device Config
+
The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its “program.” +
+
P4Info
+
Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +
+
P4RT
+
Abbreviation for P4Runtime. +
+
Protobuf (Protocol Buffers)
+
The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See [26]. +
+
PSA
+
Portable Switch Architecture [24]; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +
+
RPC
+
Remote Procedure Call. +
+
RTT
+
Round-trip time. +
+
SDN
+
Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network controller. +
+
SDN port
+
A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +
+
server
+
The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +
+
stream
+
Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (StreamChannel), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and client arbitration, among other things. +
+
switch config
+
Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +
+
target
+
The hardware or software entity which “executes” the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with “device”. +
+
URI
+
Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.

3. Reference Architecture

+

Figure 1 represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. P4Runtime only grants write access to a +single primary controller for each read/write entity. A role defines a grouping +of P4 entities. P4Runtime allows for a primary controller for each role, and a +role-based client arbitration scheme ensures only one controller has +write access to each read/write entity, or the pipeline config itself. Any +controller may perform read access to any entity or the pipeline config. Later +sections describe this in detail. For the sake of brevity, the term controller +may refer to one or more controllers. +

+

The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +[19]. It may be compiled via protoc the Protobuf compiler +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server. +

+

Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository [20]. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, e.g. via callbacks, thus reducing the burden of implementing +P4Runtime. +

+

The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard. +

+

The controller can also set the ForwardingPipelineConfig, which amounts to +installing and running the compiled P4 program output, which is included in the +p4_device_config Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +ForwardingPipelineConfig to retrieve the device config and the P4Info. +

+
+

reference-architecture +

+
+ +
Figure 1. P4Runtime Reference Architecture.

3.1. P4Runtime Service Implementation

+

The P4Runtime API is implemented by a program that runs a gRPC server which +binds an implementation of auto-generated P4Runtime Service interface. This +program is called the “P4Runtime server.” The server must listen on TCP port +9559 by default, which is the port that has been allocated by IANA for the +P4Runtime service. Servers should allow users to override the default port +using a configuration file or flag when starting the server. Uses of other +port numbers as the default should be discontinued. +

3.1.1. Security concerns

+

Appropriate measures and security best practices must be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. Mutual TLS (mTLS) may +be used to facilitate the authentication of the client by the server and +vice-versa. +

3.2. Idealized Workflow

+

In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the ForwardingPipelineConfig +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a SetForwardingPipelineConfig +RPC. Metadata in the P4Info describes both the overall program itself +(PkgInfo) as well as all entity instances derived from the P4 program +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise “handle” used in API +calls. +

+

In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible. +

+

In some use cases, it is expected that a controller will store a +collection of multiple P4 “packages”, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the ForwardingPipelineConfig from the target via the +GetForwardingPipelineRequest RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state. +

3.3. P4 as a Behavioral Description Language

+

P4 can be considered a behavioral description of a switching device which may or +may not execute “P4” natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a SetForwardingPipelineRequest to +change its pipeline “program”, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device. +

+

While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API. +

+

In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the PkgInfo +message as well as the embedded doc fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections. +

3.4. Alternative Workflows

+

Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary. +

3.4.1. P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config

+

In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +p4_device_config. The device's configuration might be derived via some other +means to implement the P4 source code's intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane. +

3.4.2. No P4 Source Available, P4Info Available

+

In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are: +

+
    +
  1. +

    The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security. +

  2. +
  3. +

    The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info. +

+ +

As discussed in Section 3.3, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, e.g. documentation. +

3.4.3. Partial P4Info and P4 Source are Available

+

In this situation, a subset of the target's pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code. +

3.4.4. P4Info Role-Based Subsets

+

In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more. +

3.5. P4Runtime State Across Restarts

+

All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade. +

4. Controller Use-cases

+

P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +section. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime's flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex. +

4.1. Single Embedded Controller

+

Figure 2 shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases. +

+

P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC. +

+
+

single-embedded-controller +

+
+ +
Figure 2. Use-Case: Single Embedded Controller

4.2. Single Remote Controller

+

Figure 3 shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections. +

+
+

single-remote-controller +

+
+ +
Figure 3. Use-Case: Single Remote Controller

4.3. Embedded + Single Remote Controller

+

Figure 4 illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller. +

+

For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables. +

+
+

embedded-plus-single-remote-controller +

+
+ +
Figure 4. Use-Case: Embedded Plus Single Remote Controller

4.4. Embedded + Two Remote Controllers

+

Figure 5 illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +e.g. routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership. +

+
+

embedded-plus-two-remote-controllers +

+
+ +
Figure 5. Use-Case: Embedded Plus Two Remote Controllers

4.5. Embedded Controller + Two High-Availability Remote Controllers

+

Figure 6 illustrates a single +embedded controller plus two remote controllers in an active-standby (i.e. +primary-backup) HA (High-Availability) configuration. Controller #1 is the +active controller and is in charge of some entities. If it fails, Controller #2 +takes over and manages the tables formerly owned by Controller #1. The mechanics +of HA architectures are beyond the scope of this document, but the P4Runtime +role-based client arbitration scheme supports it. +

+
+

embedded-plus-two-remote-ha-controllers +

+
+ +
Figure 6. Use-Case: Embedded Plus Two Remote High-Availability Controllers

5. Client Arbitration and Controller Replication

+

The P4Runtime interface allows multiple clients (i.e. controllers) to be +connected to the P4Runtime server running on the device at the same time for the +following reasons: +

+
    +
  1. +

    Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, “roles” (or “realms”) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +primary and the rest are backups. Role definition, i.e. how P4 entities get +assigned to each role, is out-of-scope of this document. +

  2. +
  3. +

    Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby backup controllers. These can already have a connection +open, which can help them become primary more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved. +

+ +

To support multiple controllers, P4Runtime uses the streaming channel (available +via StreamChannel RPC) for session management. The workflow is described as +follows: +

+
    +
  • +

    Each controller instance (e.g. a controller process) can participate in one or +more roles. For each (device_id, role), the controller receives an +election_id. This election_id can be the same for different roles and/or +devices, as long as the tuple (device_id, role, election_id) is +unique among live controllers, as defined below. For each (device_id, +role) that the controller wishes to control, it establishes a +StreamChannel with the P4Runtime server responsible for that device, and +sends a MasterArbitrationUpdate message containing that tuple of +(device_id, role, election_id) values. The P4Runtime server selects a +primary independently for each (device_id, role) pair. The primary is the +client that has the highest election_id that the device has ever received +for the same (device_id, role) values. A connection between a controller +instance and a device id which involves a persistent StreamChannel +can be referred to as a P4Runtime client. +

    +

    Note that the P4Runtime server does not assign a role or election_id to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the election_id values used for each +StreamChannel. The P4Runtime server only keeps track of the (device_id, +role, election_id) of each StreamChannel that has sent a successful +MasterArbitrationUpdate message, and maintains the invariant that all such +3-tuples are unique among live controllers. A server must use all three of +these values from a WriteRequest message to identify which client is making +the WriteRequest, not only the election_id. This enables controllers to +re-use the same numeric election_id values across different (device_id, +role) pairs. P4Runtime does not require election_id values be reused +across such different (device_id, role) pairs; it allows it. +

  • +
  • +

    To start a controller session, a controller first opens a bidirectional stream +channel to the server via the StreamChannel RPC for each device. This stream +will be used for two purposes: +

    +
      +
    • +

      Session management: As soon as the controller opens the stream +channel, it sends a StreamMessageRequest message to the switch. The +controller populates the MasterArbitrationUpdate field in this message +using its role and election_id, as well as the device_id of the +device. Note that the status field in the MasterArbitrationUpdate is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below. +

    • +
    • +

      Streaming of notifications (e.g. digests) and packet I/O: The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the primary controller can participate in +packet I/O. This feature is explained in more details in the Packet +I/O section. +

    + +

    Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state. +

  • +
  • +

    Note that the stream is opened per device. In case a switching platform has +multiple devices (e.g. multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different primary clients for +different devices. In this case, it is the responsibility of the P4Runtime +server to keep track of the primary for each device (and role). More +specifically, the P4Runtime server will know which stream corresponds to the +primary controller for each pair of (device_id, role) at any point of +time. +

  • +
  • +

    The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered “offline”, +“disconnected”, or “dead” as soon as its stream channel to the switch is +broken. When a primary channel gets broken: +

    +
      +
    1. +

      An advisory message is sent to all other controllers for that device_id +and role, as described in a +later section; and +

    2. +
    3. +

      The P4Runtime server will be without a primary controller, until a client +sends a successful MasterArbitrationUpdate (as per the rules in a +later section). +

    +
  • +
  • +

    The mechanism through which the controller receives the P4Runtime server +details are implementation specific and beyond the scope of this +specification. This includes the device_id, ip and port, as +well as the Forwarding Pipeline Config. Similarly, the mechanism through +which the P4Runtime server receives its switch config (which notably includes +the device_id) is beyond the scope of this specification. Nevertheless, if +the server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks. +

+ +

gRPC enables the server to identify which client originated each message in the +StreamChannel stream. For example, the C++ gRPC library [12] in +synchronous mode enables a server process to cause a function to be called when +a new client creates a StreamChannel stream. This function should not return +until the stream is closed and the server has completed any cleanup required +when a StreamChannel is closed normally (or broken, e.g. because a client +process unexpectedly terminated). Thus the server can easily associate all +StreamChannel messages received from the same client, because they are +processed within the context of the same function call. +

+

A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values device_id, role, and election_id in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods [10] that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server. +

5.1. Default Role

+

A controller can omit the role message in MasterArbitrationUpdate. This +implies the “default role”, which corresponds to “full pipeline access”. +This also implies that a default role has a role_id of "" (default). +If using a default role, all RPCs from the controller (e.g. Write) must +leave the role unset. +

5.2. Role Config

+

The role.config field in the MasterArbitrationUpdate message sent by the +controller describes the role configuration, i.e. which operations are in the +scope of a given role. In particular, the definition of a role may include the +following: +

+
    +
  • A list of P4 entities for which the controller may issue Write updates and +receive notification messages (e.g. DigestList and +IdleTimeoutNotification). +
  • +
  • Whether the controller is able to receive PacketIn messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketIn messages should be sent to the controller. +
  • +
  • Whether the controller is able to send PacketOut messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketOut messages are allowed to be sent by the controller. +
+ +

An unset role.config implies “full pipeline access” (similar to the default +role explained above). In order to support different role definition schemes, +role.config is defined as an Any Protobuf message [37]. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion. +

+

It is the job of the P4Runtime server to remember the role.config for every +device_id and role pair. +

5.3. Rules for Handling MasterArbitrationUpdate Messages Received from Controllers

+
    +
  1. +

    If the MasterArbitrationUpdate message is received for the first time on +this particular channel (i.e. for a newly connected controller): +

    +
      +
    1. +

      If device_id does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +NOT_FOUND error. +

    2. +
    3. +

      If the election_id is set and is already used by another live +controller for the same (device_id, role), the P4Runtime server shall +terminate the stream by returning an INVALID_ARGUMENT error. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the number of open streams for the given (device_id, role) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a RESOURCE_EXHAUSTED error. +

    8. +
    9. +

      Otherwise, the controller is added to a list of live controllers for +the given (device_id, role) and the server remembers the +controllers device_id, role and election_id for this gRPC +channel. See below for the rules to determine if this controller becomes +a primary or backup, and what notifications are sent as a consequence. +

    +
  2. +
  3. +

    Otherwise, if the MasterArbitrationUpdate message is received from an +already live controller: +

    +
      +
    1. +

      If the device_id does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. +

    2. +
    3. +

      If the role does not match the current role assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. If the controller wishes to change its role, +it must close the current stream channel and open a new one. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the election_id is set and is already used by another live +controller (excluding the controller making the request) for the same +(device_id, role), the P4Runtime server shall terminate the stream +by returning an INVALID_ARGUMENT error. +

    8. +
    9. +

      Otherwise, the server updates the election_id it has stored for this +controller. This change might cause a change in the primary client (this +controller might become primary, or the controller might have downgraded +itself to a backup, see below), as well as notifications being sent to +one or more controllers. +

    +
+ +

If the MasterArbitrationUpdate is accepted by either of the two steps above +(cases 1.5. and 2.5. above), then the server determines if there are changes in +the primary client. Let election_id_past be the highest election ID the server +has ever seen for the given device_id and role (including the one of the +current primary if there is one). +

+
    +
  1. +

    If election_id is greater than or equal to election_id_past, then the +controller becomes, or stays, primary. The server updates the role +configuration to role.config for the given role. Furthermore: +

    +
      +
    1. +

      If there was no primary for this device_id and role before and +there are no Write requests still processing from a previous primary, +then the server immediately sends an advisory notification to all +controllers for this device_id and role. See the +following section for the format of the +advisory message. +

    2. +
    3. +

      If there was a previous primary, including this controller, or Write +requests in flight, then the server carries out the following steps +(in this order): +

      +
        +
      1. +

        The server stops accepting Write requests from the previous primary +(if there is one). At this point, the server will reject all Write +requests with PERMISSION_DENIED. +

      2. +
      3. +

        The server notifies all controllers other than the new primary client +of the change by sending the advisory notification described in +the following section. +

      4. +
      5. +

        The server will finish processing any Write requests that have +already started. If there are errors, they are reported as usual to +the previous primary. If the previous primary has already +disconnected, any possible errors are dropped and not reported. +

      6. +
      7. +

        The server now accepts the current controller as the new primary, +thus accepting Write requests from this controller. The server +updates the highest election ID (i.e. election_id_past) it has seen +for this device_id and role to election_id. +

      8. +
      9. +

        The server notifies the new primary by sending the advisory message +described in the following section. +

      +
    +
  2. +
  3. +

    Otherwise, the controller becomes a backup. If the controller was previously +a primary (and downgraded itself), then an advisory message is sent to all +controllers for this device_id and role. Otherwise, the advisory +message is only sent to the controller that sent the initial +MasterArbitrationUpdate. See the +following section for the format of the +advisory message. +

+

5.4. Client Arbitration Notifications

+

For any given device_id and role, any time a new primary is chosen, a +primary downgrades its status to a backup, a primary disconnects, or the +role.config is updated by the primary, all controllers for that +(device_id, role) are informed of this by sending a +StreamMessageResponse. The MasterArbitrationUpdate is populated as follows: +

+
    +
  • +

    device_id and role as given. +

  • +
  • +

    role.config is set to the role configuration the server received most +recently in a MasterArbitrationUpdate from a primary. +

  • +
  • +

    election_id is populated as follows: +

    +
      +
    • +

      If there has not been any primary at all, the election_id is left unset. +

    • +
    • +

      Otherwise, election_id is set to the highest election ID that the server +has seen for this device_id and role (which is the election_id of +the current primary if there is any). +

    +
  • +
  • +

    status is set differently based on whether the notification is sent to the +primary or a backup controller: +

    +
      +
    • +

      If there is a primary: +

      +
        +
      • +

        For the primary, status is OK (with status.code set to +google.rpc.OK). +

      • +
      • +

        For all backup controllers, status is set to non-OK (with +status.code set to google.rpc.ALREADY_EXISTS). +

      +
    • +
    • +

      Otherwise, if there is no primary currently, for all backup controllers, +status is set to non-OK (with status.code set to +google.rpc.NOT_FOUND). +

    +
+ +

Note that on primary client changes with outstanding Write request, some +notifications might be delayed, see the +previous section for details. +

6. The P4Info Message

+

The purpose of P4Info was described under +Reference Architecture. +Here we describe the various +components. +

6.1. Common Messages

+

These messages appear nested within many other messages. +

6.1.1. Documentation Message

+

Documentation is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers. +

+
+
+
message Documentation {
+  // A brief description of something, e.g. one sentence
+  string brief = 1;
+  // A more verbose description of something.
+  // Multiline is accepted. Markup format (if any) is TBD.
+  string description = 2;
+}

6.1.2. Preamble Message

+

The preamble serves as the “descriptor” for each entity and contains the unique +instance ID, name, alias, annotations and documentation. +

+
+
+
message Preamble {
+  // ids share the same number-space; e.g. table ids cannot overlap with counter
+  // ids. Even though this is irrelevant to this proto definition, the ids are
+  // allocated in such a way that it is possible based on an id to deduce the
+  // resource type (e.g. table, action, counter, ...). This means that code
+  // using these ids can detect if the wrong resource type is used
+  // somewhere. This also means that ids of different types can be mixed
+  // (e.g. direct resource list for a table) without ambiguity. Note that id 0
+  // is reserved and means "invalid id".
+  uint32 id = 1;
+  // fully qualified name of the P4 object, e.g. c1.c2.ipv4_lpm
+  string name = 2;
+  // an alias (alternative name) for the P4 object, probably shorter than its
+  // fully qualified name. The only constraint is for it to be unique with
+  // respect to other P4 objects of the same type. By default, the compiler uses
+  // the shortest suffix of the name that uniquely identifies the object. For
+  // example if the P4 program contains two tables with names s.c1.t and s.c2.t,
+  // the default aliases will respectively be c1.t and c2.t. In the future, the
+  // P4 programmer may also be able to override the default alias for any P4
+  // object (TBD).
+  string alias = 3;
+  repeated string annotations = 4;
+  // Optional. If present, the location of `annotations[i]` is given by
+ // `annotation_locations[i]`.
+  repeated SourceLocation annotation_locations = 7;
+  // Documentation of the entity
+  Documentation doc = 5;
+  repeated StructuredAnnotation structured_annotations = 6;
+}

6.1.3. Annotating P4 Entities with Documentation

+

P4 entities may be annotated using the following annotations: +

+
+
+
@brief(string...)
+@description(string...)
+

Attaching either or both of these annotations to an entity will generate a +P4Info Documentation Message, which in turn will +appear in the Preamble Message for the entity. +

+

The P4 compiler should not emit annotation messages in the P4Info for these +specific cases; instead, it should generate the Documentation messages as +described. +

+

The following example shows documentation annotations for a table entity: +

+
+
+
@brief("Match IPv4 addresses to next-hop MAC and port")
+@description("Match IPv4 addresses to next-hop MAC and port. \
+Uses LPM match type.")
+table my_ipv4_lkup {
+  ...
+}

6.1.4. Structured Annotations

+

P4 supports both unstructured and structured annotations [17]. +Unstructured annotations of the form MyAnno1 or MyAnno2(body-content) can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +MyAnno3[] or MyAnno4[kvList|expressionList] have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this. +

+

The annotations described up to this point, e.g. @brief(), have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as repeated string annotations fields in the various messages. +Similarly, structured annotations are represented in repeated +StructuredAnnotation structured_annotations fields which are siblings to the +unstructured annotations. The structured_annotations contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations. +

+

The structured annotation messages are defined in p4types.proto. +

+
+
+
message KeyValuePair {
+  string key = 1;
+  Expression value = 2;
+}
+
+message KeyValuePairList {
+  repeated KeyValuePair kv_pairs = 1;
+}
+
+message Expression {
+  oneof value {
+    string string_value = 1;
+    int64 int64_value = 2;
+    bool bool_value = 3;
+  }
+}
+
+message ExpressionList {
+  repeated Expression expressions = 1;
+}
+
+message StructuredAnnotation {
+  string name = 1;
+  oneof body {
+    ExpressionList expression_list = 2;
+    KeyValuePairList kv_pair_list = 3;
+  }
+  // Optional. Location of the '@' symbol of this annotation in the source code.
+  SourceLocation source_location = 4;
+}
+

The StructuredAnnotation message can represent either a KeyValuePairList +or an ExpressionList. +

+

The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The p4c +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don't match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler may print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions. +

+

The following invariants hold: +

+
    +
  1. +

    For any P4 entity, there are no two StructuredAnnotations that have the +same name. +

  2. +
  3. +

    Within a KeyValuePairList, there are no two KeyValuePairs that have the +same key. +

+
6.1.4.1. Structured Annotation Examples
+

We omit the source_location field in the following examples. +

+

Empty Expression List +

+
+
+
@Empty[]
+table t {
+    ...
+}
+

The generated P4Info will contain the following. +

+
+
+
structured_annotations {
+  name: "Empty"
+}
+

Mixed Expression List +

+
+
+
#define TEXT_CONST "hello"
+#define NUM_CONST 6
+@MixedExprList[1,TEXT_CONST,true,1==2,5+NUM_CONST]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedExprList"
+  expression_list {
+    expressions {
+      int64_value: 1
+    }
+    expressions {
+      string_value: "hello"
+    }
+    expressions {
+      bool_value: true
+    }
+    expressions {
+      bool_value: false
+    }
+    expressions {
+      int64_value: 11
+    }
+  }
+}
+

kvList of Mixed Expressions +

+
+
+
@MixedKV[label="text", my_bool=true, int_val=2*3]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedKV"
+  kv_pair_list {
+    kv_pairs {
+      key: "label"
+      value {
+        string_value: "text"
+      }
+    }
+    kv_pairs {
+      key: "my_bool"
+      value {
+        bool_value: true
+      }
+    }
+    kv_pairs {
+      key: "int_val"
+      value {
+        int64_value: 6
+      }
+    }
+  }
+}

6.1.5. SourceLocation Message

+

A source location describes a location within a .p4-source file. The +SourceLocation message is defined in p4types.proto as follows: +

+
+
+
// Location of code relative to a given source file.
+message SourceLocation {
+  // Path to the source file (absolute or relative to the working directory).
+  string file = 1;
+  // Line and column numbers within the source file, 1-based.
+  int32 line = 2;
+  int32 column = 3;
+}
+

We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations. +

+

The SourceLocation message associated with an annotation holds the location of +the @ symbol introducing the annotation in the P4 source code; the message can +be found in the following place: +

+
    +
  • +

    For unstructured annotations, every message containing a field +repeated string annotations also contains a field +repeated SourceLocation annotation_locations. The field must either be empty + or match the size of annotations. In the latter case, the i-th member of +annotation_locations is the source location of the i-th member of +annotations. +

  • +
  • +

    For structured annotations, every StructuredAnnotation message contains +an optional field SourceLocation source_location holding its source +location, if present. +

+

6.2. PkgInfo Message

+

The PkgInfo message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. PkgInfo can be extracted +and used to facilitate “browsing” of available P4 programs from a +library. Although all fields are technically “optional,” every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included. +

+
+
+
// Can be used to manage multiple P4 packages.
+message PkgInfo {
+  // a definitive name for this configuration, e.g. switch.p4_v1.0
+  string name = 1;
+  // configuration version, free-format string
+  string version = 2;
+  // brief and detailed descriptions
+  Documentation doc = 3;
+  // Miscellaneous metadata, free-form; a way to extend PkgInfo
+  repeated string annotations = 4;
+  // Optional. If present, the location of `annotations[i]` is given by
+  // `annotation_locations[i]`.
+  repeated SourceLocation annotation_locations = 10;
+  // the target architecture, e.g. "psa"
+  string arch = 5;
+  // organization which produced the configuration, e.g. "p4.org"
+  string organization = 6;
+  // contact info for support,e.g. "tech-support@acme.org"
+  string contact = 7;
+  // url for more information, e.g. "http://support.p4.org/ref/p4/switch.p4_v1.0"
+  string url = 8;
+  // Miscellaneous metadata, structured; a way to extend PkgInfo
+  repeated StructuredAnnotation structured_annotations = 9;
+  // If set, specifies the properties that the underlying platform should have.
+  // If the platform does not conform to these properties, the server should
+  // reject the P4Info when used with a SetForwardingPipelineConfigRequest.
+  PlatformProperties platform_properties = 11;
+}
+

where the PlatformProperties message looks as follows: +

+
+
+
// Used to describe the required properties of the underlying platform.
+message PlatformProperties {
+  // The minimum number of multicast entries (i.e. multicast groups) that the
+  // platform is required to support. If 0, there are no requirements.
+  int32 multicast_group_table_size = 1;
+  // The minimum number of replicas that the platform is required to support
+  // across all  groups. If 0, there are no requirements.
+  int32 multicast_group_table_total_replicas = 2;
+  // The number of replicas that the platform is required to support per
+  // group/entry. If 0, `multicast_group_table_total_replicas` should be used.
+  // Must be no larger than `multicast_group_table_total_replicas`.
+  int32 multicast_group_table_max_replicas_per_entry = 3;
+}

6.2.1. Annotating P4 code with PkgInfo

+

A P4 program's PkgInfo may be declared using one or more of the following +annotations, attached to the main block only: +

+
+
+
@pkginfo(key=value)
+@pkginfo(key=value[,key=value,...])
+@brief("A brief description")
+@description("A longer\
+description")
+@custom_annotation(...)
+@another_custom_annotation(...)
+@platform_property(key=value)
+@platform_property(key=value[,key=value,...])
+

Above we see several different types of annotations: +

+
    +
  • +

    @pkginfo - This is used to populate a specific field within the PkgInfo +message. Multiple @pkginfo annotations are allowed. For compactness, +multiple key-value pairs can appear in a single @pkginfo annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The keys must be from +among the message fields inside PkgInfo, for example, name, version, +etc. Each key-value pair assigns a value to the corresponding field inside the +single PkgInfo message for the program's P4Info. One exception is that the +Documentation field of PkgInfo must be expressed as individual +@description and @brief annotations, see next bullets. The key arch will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself. +

  • +
  • +

    @brief - This will populate the PkgInfo.doc.brief message field. +

  • +
  • +

    @description - This will populate the PkgInfo.doc.description message +field +

  • +
  • +

    @platform_property - This is used to populate a specific field within the +PlatformProperty message in PkgInfo.platform_property. Multiple +@platform_property annotations are allowed. For compactness, +multiple key-value pairs can appear in a single @platform_property +annotation, separated by commas. Each key must only appear once and the +compiler must reject the program if one appears multiple times. The keys +must be from among the message fields inside PlatformProperty, for example, +multicast_group_table_size or multicast_group_table_total_replicas. Each +key-value pair assigns a value to the corresponding field inside the single +PlatformProperty message inside the program's P4Info. +

  • +
  • +

    @<anything else> - This will create a PkgInfo.annotation entry +

+ +

Declaring one or more of these annotations on main will +generate a single corresponding PkgInfo message in the P4Info as described in +PkgInfo Message. +

+

The following example shows @pkginfo annotations using a mixture of single and +multiple key-value pairs. It also shows @brief and @description annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the PkgInfo message. The custom annotations will +be appended to the PkgInfo.annotations list. +

+
+
+
@pkginfo(name="switch.p4",version="2")
+@pkginfo(organization="p4.org")
+@pkginfo(contact="info@p4.org")
+@pkginfo(url="www.p4.org")
+@brief("L2/L3 switch")
+@description("L2/L3 switch.\
+Built for data-center profile.")
+@my_annotation1(...) // Not well-known, this will appear in PkgInfo annotations
+@my_annotation2(...) // Not well-known, this will appear in PkgInfo annotations
+PSA_Switch(IgPipeline, PacketReplicationEngine(), EgPipeline,
+           BufferingQueueingEngine()) main;

6.3. ID Allocation for P4Info Objects

+

P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(e.g. table, action, counter, ). The most significant 8 bits of the ID +encodes the object type (as per Table 1). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (p4.config.v1.P4Ids.Prefix). These values must +be used (e.g. by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table 2 shows the ID +layout. +

+
+ + + + + + + + + + + + + + + + + + + + + +
8-bit prefix value P4 object type
0x00 Reserved (unspecified)
0x01 Action
0x02 Table
0x03 Value-set
0x04 Controller header (header type with @controller_header annotation)
0x050x0f Reserved (for future P4 built-in objects)
0x10 Reserved (start of PSA extern types)
0x11 PSA Action profiles / selectors
0x12 PSA Counter
0x13 PSA Direct counter
0x14 PSA Meter
0x15 PSA Direct meter
0x16 PSA Register
0x17 PSA Digest
0x180x7f Reserved (for future PSA extern types)
0x80 Reserved (start of vendor-specific extern types)
0x810xfe Vendor-specific extern types
0xff Reserved (max prefix value)
+
+ +
Table 1. Mapping of P4Info object type to 8-bit ID prefix value
+
+ + + + +
MSB bit 31 .. bit 24 bit 23 .. bit 0 LSB
Object type prefix Generated suffix (e.g. by the compiler)
+
+ +
Table 2. Format of P4Info object IDs
+

It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with @id (see Table +3). The compiler must honor the @id annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (i.e. if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same @id value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct. +

+
+ + + + + + + + + + +
P4 declaration(s) Compiler-allocated ID(s)
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) table tA... Error(same ID suffixes for 2 objects of the same type)
@id(0x12ab34) table tB...
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) action act1... 0x0112ab34
+
+ +
Table 3. Example of statically-assigned P4Info object IDs
+

The @id annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively). +

6.4. P4Info Objects

6.4.1. Table

+

Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this table. +

  • +
  • +

    match_fields, a repeated field of type MatchField representing the data to +be used to construct the lookup key matched in this table. Each MatchField +message is defined with the following fields: +

    +
      +
    • +

      id, the uint32 identifier of this MatchField, unique in the scope of +this table. No rules are prescribed on the way MatchField IDs should be +allocated, as long as two MatchField of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the @id annotation, or let the compiler +choose them. +

    • +
    • +

      name, the string representing the name of this MatchField. +

    • +
    • +

      annotations, a repeated field of strings, each one representing a P4 +annotation associated to this match field. +

    • +
    • +

      bitwidth, an int32 value set to the size in bits of this match field. +

    • +
    • +

      match, a oneof describing the match behavior for this field; it can be +either: +

      +
        +
      • match_type, an enum field of type MatchType, which includes all +possible PSA match kinds. +
      • +
      • other_match_type, a string field which can be used to encode any +architecture-specific match type. +
      +
    • +
    • +

      doc, a Documentation message describing this match field. +

    • +
    • +

      type_name, which indicates whether the match field has a user-defined +type; this is useful for +translation. +

    +
  • +
  • +

    action_refs, a repeated ActionRef field representing the set of possible +actions for this table. The ActionRef message is used to reference an action +specified in the same P4Info message and it includes the following fields: +

    +
      +
    • id, the uint32 identifier of the action. +
    • +
    • scope, an enum value which can take one of three values: + TABLE_AND_DEFAULT, TABLE_ONLY and DEFAULT_ONLY. The scope of the + action is determined by the use of the P4 standard annotations + @tableonly and @defaultonly [22]. TABLE_ONLY + (@tableonly annotation) means that the action can only appear within + the table, and never as the default action. DEFAULT_ONLY + (@defaultonly annotation) means that the action can only be used as the + default action. TABLE_AND_DEFAULT is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action. +
    • +
    • annotations, a repeated string field, each one representing a P4 +annotation associated to the action reference in this table. +
    +
  • +
  • +

    const_default_action_id, if this table has a constant default action, this +field will carry the uint32 identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action's +arguments. +

  • +
  • +

    initial_default_action, the default action that is executed with the + specified arguments when the table does not match. If no explicit + default action is set, the identifier of this field will default to + the id of the NoAction action. +

  • +
  • +

    implementation_id, the uint32 identifier of the “implementation” of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (e.g. a PSA ActionProfile or ActionSelector +instance). The table is then referred to as an indirect match table. +

  • +
  • +

    direct_resource_ids, repeated uint32 identifiers for all the direct +resources attached to this table, such as DirectMeter and DirectCounter +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2. +

  • +
  • +

    size, an int64 describing the desired number of table entries that the +target should support for the table. See the “Size” subsection within the +“Table Properties” section of the P416 language specification for details +[36]. +

  • +
  • +

    idle_timeout_behavior, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +Idle-Timeout section). Value can be any of the +IdleTimeoutBehavior enum: +

    +
      +
    • NO_TIMEOUT (default value), which means that idle timeout is not +supported for this table. +
    • +
    • NOTIFY_CONTROL, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +Table Idle Timeout Notifications). +
    +
  • +
  • +

    is_const_table, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime. +

  • +
  • +

    has_initial_entries, a boolean flag indicating that the table has +entries populated into it when the P4 program is loaded, which is +true for tables in the P4 source code with either the entries or +const entries properties, and there is at least one entry in the +list. +

  • +
  • +

    other_properties, an Any Protobuf message [37] to embed +architecture-specific table properties [36] which are not part +of the core P4 language or of the PSA architecture. +

+

6.4.2. Action

+

Action messages are used to specify all possible actions of all match-action +tables. +

+

The Action message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this action +

  • +
  • +

    params, a repeated field of Param messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each Param message contains the +following fields: +

    +
      +
    • id, the uint32 identifier of this parameter. No rules are prescribed +on the way Param IDs should be allocated, as long as two Param of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the @id +annotation, or let the compiler choose them. +
    • +
    • name, the string representing the name of this parameter. +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this parameter. +
    • +
    • bitwidth, an int32 value set to the size in bits of this parameter. +
    • +
    • doc, which describes this parameter using a Documentation message. +
    • +
    • type_name, which indicates whether the action parameter has a +user-defined type; this is useful for +translation. +
    +
+

6.4.3. ActionProfile

+

ActionProfile messages are used to specify all available instances of Action +Profile and Action Selector PSA externs. +

+

PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile member, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime. +

+

PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into groups. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime. +

+

While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same ActionProfile message to describe both. +

+

The ActionProfile message includes the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Action +Profile or Selector. +

  • +
  • +

    table_ids, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector. +

  • +
  • +

    with_selector, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern. +

  • +
  • +

    size, an int64 representing the maximum number of member entries that the +Action Profile can hold. For Action Selectors, its semantics is specified by +the selector_size_semantics value as described below. +

  • +
  • +

    max_group_size, an int32 which is 0 for an Action Profile, or, for an +Action Selector, its semantics is specified by the selector_size_semantics +value as described below. +The max_group_size must be no larger than size. PSA programs can use the +@max_group_size annotation to provide this value for Action Selectors. +If the annotation is omitted, the P4Info field will default to 0. +

  • +
  • +

    selector_size_semantics, a oneof for Action Selectors that +specifies how size and max_group_size are interpreted. It can be either: +

    +
      +
    • sum_of_weights, indicating that size and max_group_size represent +the maximum sum of weights that can be present across all selector groups +and within a single selector group respectively. +
    • +
    • sum_of_members, indicating that size and max_group_size represent +the maximum number of members that can be present across all selector +groups and within a single selector group respectively, irrespective of +their weight. The SumOfMembers message used to represent this value also +contains an optional int32 max_member_weight, which indicates the +maximum weight of each individual member. If unset, any 32-bit integer is +allowed for weight. +
    +
+ +

PSA programs can use the @selector_size_semantics annotation with one of + sum_of_weights or sum_of_members to specify this value for Action + Selectors. In the sum_of_members case, the @max_member_weight annotation + can be used to specify max_member_weight. Unless otherwise specified, the + value of selector_size_semantics should default to sum_of_weights. + However, an unset selector_size_semantics should also be treated as + sum_of_weights for backwards compatibility in Action Selectors. In Action + Profiles, this value must be unset. +

6.4.4. Counter & DirectCounter

+

Counter and DirectCounter messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is: +

+
    +
  • +

    Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index. +

  • +
  • +

    Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table. +

+ +

Both Counter and DirectCounter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this counter +extern instance. +

  • +
  • +

    spec, a message of of type CounterSpec used to describe the compile-time +configuration of this counter. Currently, the CounterSpec message is used to +carry only the counter unit, which can be any of the CounterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES: byte counter. +
    • +
    • PACKETS: packet counter. +
    • +
    • BOTH: combination of both byte and packet counter. +
    +
+ +

For indexed counters, the Counter message contains also a size field, an +int64 representing the maximum number of independent values that can be held +by this counter array. Conversely, the DirectCounter message contains a +direct_table_id field that carries the unit32 identifier of the table to +which this direct counter is attached. +

+

For indexed counters, the Counter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.5. Meter & DirectMeter

+

Meter and DirectMeter messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is: +

+
    +
  • +

    Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +e.g. to set the rate threshold. +

  • +
  • +

    Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table. +

+ +

Both Meter and DirectMeter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this meter +extern instance. +

  • +
  • +

    spec, a message of type MeterSpec used to describe the capabilities of +this meter extern instance. The MeterSpec message is used to describe the +meter unit and the meter type. The meter unit can be any of the +MeterSpec.Unit enum values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES, which signifies that this meter can be configured with rates +expressed in bytes/second. +
    • +
    • PACKETS, for rates expressed in packets/second. +
    + +

    The meter type can be any of the MeterSpec.Type enum values: +

    +
      +
    • TWO_RATE_THREE_COLOR: This is the Two Rate Three Color Marker (trTCM) +defined in RFC 2698 [3]. This is the standard P4Runtime meter type +and allows meters to use two rates to split packets into three potential +colors: GREEN, YELLOW, or RED. This mode is the default, but can also be +set explicitly in a P4 program by adding the @two_rate_three_color +annotation to the meter definition. +For example, in a V1Model P4 program, we might define a trTCM direct meter +as follows: + +
      +
      +
      @two_rate_three_color
      +direct_meter<color_type>(MeterType.bytes) my_meter;
    • +
    • SINGLE_RATE_THREE_COLOR: This is the Single Rate Three Color Marker +(srTCM) defined in RFC 2697 [2]. This allows meters to use one rate +and an Excess Burst Size (EBS) to split packets into three potential +colors: GREEN, YELLOW, or RED. In a P4 program, this mode can be set by +adding the @single_rate_three_color annotation to the meter definition. +
    • +
    • SINGLE_RATE_TWO_COLOR: This is a simplified version of RFC 2697 +[2], and the SINGLE_RATE_THREE_COLOR mode above. +SINGLE_RATE_TWO_COLOR restricts meters to use only a single rate +specified by the Committed Information Rate (CIR) and Committed Burst Size +(CBS) to mark packets GREEN or RED. In a P4 program, this mode can be set +by adding the @single_rate_two_color annotation to the meter definition. +
    +
+ +

For indexed meters, the Meter message contains also a size field, an int64 +representing the maximum number of independent cells that can be held by this +meter. Conversely, the DirectMeter message contains a direct_table_id field +that carries the uint32 identifier of the table to which this direct meter is +attached. +

+

For indexed meters, the Meter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.6. ControllerPacketMetadata

+

ControllerPacketMetadata messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server. +

+

When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet. +

+

Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +@controller_header("packet_in") and @controller_header("packet_out"), +respectively. ControllerPacketMetadata messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages). +

+

A P4Info message can contain at most two ControllerPacketMetadata messages, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message where preamble.name is set to "packet_in" +and "packet_out" for packet-in and packet-out metadata, respectively. +

  • +
  • +

    metadata, a repeated field of type Metadata, where each Metadata message +includes the following fields: +

    +
      +
    • id, a uint32 identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two Metadata of the +same ControllerPacketMetadata message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the @id annotation, or let the compiler choose them. +
    • +
    • name, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below). +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this metadata. +
    • +
    • bitwidth, an int32 representing the size in bits of this metadata. +
    • +
    • type_name, which indicates whether the metadata field has a +user-defined type; this is useful for +translation. +
    +
+ +

As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding ControllerPacketMetadata +messages. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  bit<9> egress_port; /* suggested port where the packet
+                         should be sent */
+  bit<8> queue_id;    /* suggested queue ID */
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  bit<9> ingress_port; /* data plane port ID where
+                          the original packet was received */
+  bit<1> is_clone;     /* 1 if this is a clone of the
+                          original packet */
+}
+
+
+
controller_packet_metadata {
+  preamble {
+    id: 2868916615
+    name: "packet_out"
+    annotations: "@controller_header(\"packet_out\")"
+  }
+  metadata {
+    id: 1
+    name: "egress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "queue_id"
+    bitwidth: 8
+  }
+}
+
+controller_packet_metadata {
+  preamble {
+    id: 2868941301
+    name: "packet_in"
+    annotations: "@controller_header(\"packet_in\")"
+  }
+  metadata {
+    id: 1
+    name: "ingress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "is_clone"
+    bitwidth: 1
+  }
+}
+

Note that the use of @controller_header is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages. +

6.4.7. ValueSet

+

ValueSet messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P416 +specification [45]. +

+

The ValueSet message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Value +Set. +

  • +
  • +

    match, a repeated field of MatchField messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the match_fields repeated field in the +Table message. +

  • +
  • +

    size, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +value_set constructor call. +

+ +

According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of bit<W>, +tuple, or struct [31]. The rest of this section looks at all 3 of +these cases and gives an example ValueSet message when appropriate. +

+
    +
  1. +

    If the type parameter is bit<W>, match will include exactly one +MatchField message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used): +

    +
      +
    • id: set to 1 +
    • +
    • bitwidth: set to the value of W +
    • +
    • match_type: set to EXACT +
    +
+ +
+
+
@id(1) value_set<bit<8> >(4) pvs;
+select (hdr.f8) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    bitwidth: 8
+    match_type: EXACT
+  }
+  size: 4
+}
+
    +
  1. +

    If the type parameter is a tuple, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program. +

  2. +
  3. +

    If the type parameter is a struct, this version of P4Runtime requires that +all the fields of the struct be of type bit<W> (where W can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +match field will include one MatchField message for each field in the +struct, with the following fields: +

    +
      +
    • id: must be unique with respect to the other match entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +@id annotation, or let the compiler choose them. +
    • +
    • name: set to the name of the corresponding struct field. +
    • +
    • annotations: set to the list of P4 annotations associated with the struct +field, except for the @match annotation, if present (see the match field +below). +
    • +
    • bitwidth: set to the value of W for the corresponding struct field. +
    • +
    • type_name, which indicates whether the struct field has a user-defined +type; this is useful for +translation. +
    • +
    • match: by default match_type is set to EXACT; the P4 programmer can +specify a different match type by using the @match annotation +[31]. +
    • +
    • doc: documentation associated with the struct field. +
    +
+ +
+
+
struct match_t {
+  @id(1) bit<8> f8;
+  @id(2) @match(ternary) bit<16> f16;
+  @id(3) @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

In the above example, the @id annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs. +

+

Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a user-defined +type that resolves to a bit<W>, or a struct where +one or more fields is a user-defined type that +resolves to a bit<W>. For each MatchField that corresponds to a user-defined +type, the type_name field must be set to the appropriate value (i.e. the name +of the type). +

6.4.8. Register

+

Register messages are used to specify all possible instances of Register PSA +externs. +

+

Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime. +

+

The Register message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this register +instance. +

  • +
  • +

    type_spec, which specifies the data type stored by this register, expressed +using a P4DataTypeSpec message (see section on Representation of Arbitrary +P4 Types). +

  • +
  • +

    size, an int32 value representing the total number of independent register +cells available. +

  • +
  • +

    index_type_name, which indicates whether the register index has a +user-defined type. This is useful for +translation. The underlying built-in type +must be a fixed-width unsigned bitstring (bit<W>). +

+

6.4.9. Digest

+

Digest messages are used to specify all possible instances of Packet Digest +PSA externs. +

+

A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages. +

+

The Digest message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this digest +instance. +

  • +
  • +

    type_spec, which specifies the data type of an individual digest +notification using a P4DataTypeSpec message (see section on Representation +of Arbitrary P4 Types). +

+

6.4.10. Extern

+

Extern messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one Extern message instance in P4Info. The Extern message defines +the following fields: +

+
    +
  • +

    extern_type_id, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the reserved +range [0x81, 0xfe]. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture. +

  • +
  • +

    extern_type_name, which specifies the fully-qualified P4 name of the extern +type. +

  • +
  • +

    instances, a repeated field of ExternInstance Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +ExternInstance in turn defines the following fields: +

    +
      +
    • preamble, a Preamble message with the ID, name, and alias of this digest +instance. +
    • +
    • info, an Any Protobuf message [37] which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for info should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on Extending +P4Runtime for non-PSA Architectures for more +information. +
    +
+ +

If the P4 program does not include any instance of a given extern type, the +Extern message instance for that type should be omitted from the P4Info. +

6.5. Support for Arbitrary P4 Types with P4TypeInfo

+

See section on Representation of Arbitrary P4 +Types. +

7. P4 Forwarding-Pipeline Configuration

+

The ForwardingPipelineConfig captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the “Device Configuration” and sometimes also referred to as +the “P4 Blob”. It is defined as: +

+
+
+
message ForwardingPipelineConfig {
+  config.P4Info p4info = 1;
+  bytes p4_device_config = 2;
+  message Cookie {
+    uint64 cookie = 1;
+  }
+  Cookie cookie = 3;
+}
+

The p4info field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic. +

+

The p4_device_config is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new ForwardingPipelineConfig on that target. +

+

The cookie field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a GetForwardingPipelineConfig RPC. +When writing the config via a SetForwardingPipelineConfig RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present. +

8. General Principles for Message Formatting

8.1. Default-valued Fields

+

There is a subtle distinction between the treatment of default-valued scalar +fields vs default-valued message fields in P4Runtime. +

8.1.1. Set / Unset Scalar Fields

+

In Protobuf version 3 (proto3), the default value of scalar fields is 0 for +numeric types such as int32, and the empty string "" for string types +(string and bytes). An application, such as the P4Runtime client or +server, is unable to distinguish between an unset scalar field and a scalar +field set to its default value. Therefore, we usually reserve the default +values 0 and “” of scalar fields to mean “unset”. +

+

In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +server, such as in a WriteRequest or a SetForwardingPipelineConfigRequest. +

+

In contrast to scalar fields, note that for message fields, we often do make +a distinction between an unset message field vs a message field set to its +default value, see the next section. +

8.1.2. Set / Unset Message Fields

+

In Protobuf version 3 (proto3), the default value for a message field is +“unset” [6]. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +CounterEntry message, an “unset” index field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the index message field is +set, a single entry will be read. +

+

Let's look at the counter example in more details. Based on this specification +document, the C++ server code which processes CounterEntry messages may look +like this: +

+
+
+
auto *counter_entry = ...
+if (counter_entry->has_index()) {
+  auto index = counter_entry->index().index();
+  read_one_entry(counter_entry->id(), index);
+} else {
+  read_all_entries(counter_entry->id());
+}
+
    +
  1. +

    Reading a single counter entry at index 0 in the counter array with id +<id>: +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
      +entry.mutable_index();
      +// The above line sets the index field; it is equivalent to:
      +// auto *index = entry.mutable_index();
      +// index->set_index(0);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
      +index {}
    • +
    • Expected behavior: Counter entry at index 0 is read. Notice that the +index subfield is missing under the index field message of +CounterEntry in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages. +
    +
  2. +
  3. +

    Reading all counter entries by leaving the index field unset +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
    • +
    • Expected behavior: All counter entries for the provided counter +instance are read. Notice that the index message field is unset (default +value) and is therefore omitted from the textual representation of the +message. +
    +
+

8.2. Read-Write Symmetry

+

The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully (with the exception of parts +of the response known to be data plane volatile, as explained in section +8.2.1). Consider the following pseudocode as an +example: +

+
+
+
intended_value = value
+
+status = server.write(intended_value, p4_entity)
+observed_value = server.read(p4_entity)
+
+assert(intended_value == observed_value)
+

To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If Read RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol's complexities to the client implementations. +

+

In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the match fields in a TableEntry message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +MessageDifferencer class [42] included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance. +

8.2.1. Data plane volatile objects

+

An exception to read-write symmetry are objects whose contents or +fields can change by the action of the data plane alone, even if no +controller modifies them. These objects are called data plane +volatile. +

+

The following sections describe all possible values of an Entity +message, since these are the messages that a controller can use to +modify objects in the data plane via an Update message. For each, a +description is given of the parts of that entity that are data plane +volatile. +

8.2.1.1. ExternEntry
+

Data plane volatility depends upon the definition of the extern and +its control plane API. +

8.2.1.2. TableEntry
+

For a table with a direct counter associated with it, the counter_data +field of a TableEntry can be modified by the data plane when packets +match the entry. +

+

For a table with a direct meter associated with it, the +meter_counter_data field of a TableEntry can be modified by the data +plane when packets match the entry. +

+

For a PSA [24] table with property psa_idle_timeout equal to +PSA_IdleTimeout_t.NOTIFY_CONTROL, the data plane can modify the +elapsed_ns field of a TableEntry when no packets match the entry +for an implementation-specific amount of time. +

+

For a PNA [23] table with property pna_idle_timeout equal to +PNA_IdleTimeout_t.NOTIFY_CONTROL or PNA_IdleTimeout_t.AUTO_DELETE +the data plane can modify the elapsed_ns field of a TableEntry +when no packets cause the extern function restart_expire_timer to +be called for an implementation-specific amount of time (nor any other +extern function defined to also have the same effect as +restart_expire_timer). +

+

Similarly, for a table in PNA with any of the values of +pna_idle_timeout listed above, the data plane can modify the +idle_timeout_ns field of a TableEntry when packets match the entry +and the action calls the set_entry_expire_time extern function (or any +of the other extern functions defined to have an effect similar to +calling set_entry_expire_time). +

+

For a PNA [23] table with the property add_on_miss equal to true +the data plane can insert new entries into the table without any +controller's involvement. +

+

For a PNA [23] table with the property pna_idle_timeout equal to +PNA_IdleTimeout_t.AUTO_DELETE, the data plane can delete existing +entries from the table without any controller's involvement. +

8.2.1.3. ActionProfileMember
+

Not data plane volatile in any architectures defined by P4.org +specifications. +

8.2.1.4. ActionProfileGroup
+

Not data plane volatile in any architectures defined by P4.org +specifications. The watch_port feature does affect how action +selectors behave while processing packets, but this feature does not +affect what a P4Runtime client sees when it reads the configuration. +

8.2.1.5. MeterEntry
+

The field counter_data is modified by the data plane when the +corresponding meter is updated in the data plane. +

8.2.1.6. DirectMeterEntry
+

The field counter_data is modified by the data plane when the +corresponding meter is updated in the data plane. +

8.2.1.7. CounterEntry
+

The field data is modified by the data plane when the corresponding +counter is updated in the data plane. +

8.2.1.8. DirectCounterEntry
+

The field data is modified by the data plane when the corresponding +counter is updated in the data plane. +

8.2.1.9. PacketReplicationEngineEntry
+

Not data plane volatile in any architectures defined by P4.org +specifications. +

8.2.1.10. ValueSetEntry
+

Not data plane volatile in any architectures defined by P4.org +specifications. +

8.2.1.11. RegisterEntry
+

The field data can be modified by the data plane when the +corresponding register entry is updated in the data plane. +

8.2.1.12. DigestEntry
+

Not data plane volatile in any architectures defined by P4.org +specifications. +

8.3. Bytestrings

+

P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (bit<W>) or signed (int<W>), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +bytes Protobuf type. The correct bitwidth as per the P4 program of +each integer variable exposed through P4Runtime is specified in the P4Info +message. +

+

The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals: +

+
    +
  • +

    It ensures that a properly encoded binary string's integer value conforms +to the P4Info-specified bitwidth. +

  • +
  • +

    It supports read-write symmetry. +

  • +
  • +

    It helps facilitate non-disruptive P4 program updates. +

+ +

In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type bit<W> and/or int<W>. +

+

Note that this representation does not make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range. +

+

In the P4Runtime API version 1.0 (including minor version revisions), values +of table key fields, action parameters, and fields in packet-in and packet-out +headers between a device and the controller (see 6.4.6), +may not be of type int<W>. The rules for encoding signed values thus only +apply to messages of type P4Data (see 8.4.3). +

+

For a value of type bit<W>, the fewest number of bits required to represent +the integer value $V > 0$ is the smallest integer $A$ such that $V \leq 2^A -1$. +

+

For a value of type int<W>, the fewest number of bits required to represent +the integer value $V \neq 0$ in 2's complement form is the smallest integer $A$ +such that $-2^{A-1} \leq V \leq 2^{A-1} - 1$. +

+

As a special case, define that the value $V=0$ requires at least $A=1$ bit to +represent, regardless of whether it is signed or unsigned. +

+

The shortest possible binary string for an integer $V$ that needs $A$ bits to +represent it is computed as: +

+
+
+
minimum_string_size = floor((A + 7) / 8)
+

Binary strings with the byte length computed as minimum_string_size promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies. +

+

Any additional bits in the bytes sent for an unsigned integer value (type +bit<W>) must be 0. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with 0. +

+

Any additional bits in the bytes sent for a signed integer value (type int<W>) +must be copies of the sign bit, i.e. 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with copies of the +sign bit, i.e. 0 for non-negative values, or 0xff for negative values. In 2's +complement representation, this is called “sign extension”, and leaves the +numeric value represented unchanged. +

+

Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the maximum length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value. +

+

For a received bitstring expected to fit within a bit<W> type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring's width is W bits or less. +

+

For a received bitstring expected to fit within an int<W> type, the value it +represents is in range if, after “undoing sign extension”, the remaining bit +string's width is W bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other. +

+

If the string's byte length is zero, the server always rejects the string. +

+

When the server rejects a binary string due to any of the previous criteria, +it returns an OUT_OF_RANGE error. +

+

For all binary strings, P4Runtime uses big-endian (i.e. network) byte-order. +For signed integer values (int<W> P4 type), P4Runtime uses the same two's +complement bitwise representation as P4. Table 4 +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above. +

+
+ + + + + + + + + + + + + + + + + +
P4 type Integer value P4Runtime binary string Read-write symmetry
bit<8> 99 (0x63) \x63 yes
bit<16> 99 (0x63) \x00\x63 no
bit<16> 99 (0x63) \x63 yes
bit<16> 12388 (0x3064) \x30\x64 yes
bit<16> 12388 (0x3064) \x00\x30\x64 no
bit<12> 99 (0x63) \x00\x63 no
bit<12> 99 (0x63) \x63 yes
bit<12> 99 (0x63) \x00\x00\x63 no
int<8> 99 (0x63) \x63 yes
int<8> -99 (-0x63) \x9d yes
int<8> -99 (-0x63) \xff\x9d no
int<12> -739 (-0x2e3) \xfd\x1d yes
int<16> 0 (0x0) \x00\x00 no
int<16> 0 (0x0) \x00 yes
+
+ +
Table 4. Examples of Valid Bytestring Encoding
+

Table 5 shows some examples of invalid +P4Runtime binary strings: +

+
+ + + + + + + + + + + + +
P4 type P4Runtime binary string
bit<8> \x01\x63
bit<8> empty string
bit<16> \x01\x00\x63
bit<12> \x10\x63
bit<12> \x01\x00\x63
bit<12> \x00\x40\x63
int<8> \x00\x9d
int<12> \x8d\x1d
int<16> empty string
+
+ +
Table 5. Examples of Invalid Bytestring Encoding
+

As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from bit<8> to bit<9>, a server +running the bit<9> version of the P4 program will accept requests from +clients that remain on the bit<8> P4Runtime version. +

+

Despite the server's binary string flexibility for P4 program update support, +the client and server must both remain aware of the +read-write symmetry +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values. +

+

Representation of variable-length integer values (varbit<W> P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the dynamic-length of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an OUT_OF_RANGE error code otherwise. +

8.4. Representation of Arbitrary P4 Types

8.4.1. Problem Statement

+

The P416 language includes more complex types than just binary strings +[5]. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table 6 shows the different +P416 types and how they are allowed to be used, as per the P416 +specification. +

+
+ + + + + + + + + + + + + + + + + + + +
Container type
Element type header header_union struct or tuple
bit<W> allowed error allowed
int<W> allowed error allowed
varbit<W> allowed error allowed
int error error error
void error error error
error error error allowed
match_kind error error error
bool error error allowed
enum allowed1 error allowed
header error allowed allowed
header stack error error allowed
header_union error error allowed
struct error error allowed
tuple error error allowed
+
+ +
Table 6. P4 Type Usage
+

For example, the following P416 objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects. +

+
+
+
Digest<tuple<bit<4>, bit<8> > >() digest_complex;
+digest_complex.pack({ hdr.ipv4.version, hdr.ipv4.protocol });
+// ...
+header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

One solution would be to use only binary string (bytes type) in +p4runtime.proto and to define a custom serialization format for complex P416 +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P416 types. +

8.4.2. P4 Type Specifications in p4info.proto

+

In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type ip_t, which is a header union with 2 possible headers: +ipv4 with type ipv4_t and ipv6 with type ipv6_t. Similarly, they need to +know the field layout for both of these header types. +

+

To achieve this we introduce 2 main Protobuf messages: P4TypeInfo and +P4DataTypeSpec. +

+

P4TypeInfo is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P416 program. These +named types are struct, header, header_union, enum and +serializable_enum; for each of these we have a type specification message, +respectively P4StructTypeSpec, P4HeaderTypeSpec, P4HeaderUnionTypeSpec, +P4EnumTypeSpec and P4SerializableEnumTypeSpec. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. P4TypeInfo also includes the list of parser errors for the program, as +a P4ErrorTypeSpec message. +

+

P4DataTypeSpec is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each P4DataTypeSpec message corresponds to a compile-time type in the +original P416 program (e.g. the type parameter of an extern). This +compile-time type is represented as a Protobuf oneof, which can be: +

+
    +
  • +

    a string representing the name of the type in case of a named type (struct, +header, header_union, enum, serializable_enum or user-defined “new” +type), +

  • +
  • +

    an empty Protobuf message for bool and error, or +

  • +
  • +

    a Protobuf message for other anonymous types (bit<W>, int<W>, varbit<W>, +tuple or stack). The “binary string” types (bit<W>, int<W>, and +varbit<W>) are grouped together in the P4BitstringLikeTypeSpec message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf bytes +type). +

+ +

For all P416 compound types (tuple, struct, header, and header_union), +the order of members in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P416 declaration. The same goes for the order of members of an enum +(serializable or not) or members of error. +

8.4.3. P4Data in p4runtime.proto

+

P4Runtime uses the P4Data message to represent values of arbitrary types. The +P4Runtime client must generate correct P4Data messages based on the type +specification information included in P4Info. The P4Data message was designed +to introduce little overhead compared to using binary strings in the most common +case (P416 bit<W> type). +

+

Just like its P4Info counterpart - P4DataTypeSpec -, P4Data uses a Protobuf +oneof to represent all possible values. +

+

We define a canonical representation for P4Data messages therefore +guaranteeing read-write symmetry by introducing the following requirements: +

+
    +
  • +

    The order of members in P4StructLike and the order of bitstrings in +P4Header must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P416 type +declaration. +

  • +
  • +

    An invalid header is represented by a P4Header message where the is_valid +field is false and the bitstrings repeated field is empty. +

  • +
  • +

    An invalid header union (i.e. all headers in the union are invalid) is +represented by a P4HeaderUnion message where the valid_header_name is the +empty string (default value for the field) and the valid_header is unset. +

  • +
  • +

    The order of entries in P4HeaderStack and P4HeaderUnionStack is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the entries field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding P4HeaderStackTypeSpec or +P4HeaderUnionStackTypeSpec message. +

+

8.4.4. Example

+

Let's look at the Register example again: +

+
+
+
header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

Here's the corresponding entry in the P4Info message: +

+
+
+
registers {
+  preamble {
+    id: 369119267
+    name: "register_ip"
+    alias: "register_ip"
+  }
+  type_spec {
+    header_union {
+      name: "ip_t"
+    }
+  }
+  size: 128
+}
+type_info {
+  headers {
+    key: "ipv4_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  headers {
+    key: "ipv6_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  header_unions {
+    key: "ip_t"
+    value {
+      members {
+        name: "ipv4"
+        header {
+          name: "ipv4_t"
+        }
+      }
+      members {
+        name: "ipv6"
+        header {
+          name: "ipv6_t"
+        }
+      }
+    }
+  }
+}
+

Here's a p4.WriteRequest to set the value of register_ip[12]: +

+
+
+
update {
+  type: INSERT
+  entity {
+    register_entry {
+      register_id: 369119267
+      index {
+        index: 12
+      }
+      data {
+        header_union {
+          valid_header_name: "ipv4"
+          valid_header {
+            is_valid: true
+            bitstrings: "\x04"
+            bitstrings: # ...
+          }
+        }
+      }
+    }
+  }
+}

8.4.5. enum, serializable enum and error

+

P416 supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or “unsafe” enum) +[7]. For enum types with no underlying type as well as error +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in P4Data to represent enum and +error values. +

+

Serializable enum types have an underlying fixed-width unsigned integer +representation (bit<W>). All named enum members must be assigned an integer +value by the P4 programmer, but not all valid numeric values for the +underlying type need to have a corresponding name. P4TypeInfo includes the +mapping between entry name and entry value. When providing serializable enum +values through P4Data, one must use the assigned integer value (enum_value +bytestring field). P4Runtime does not provide a way for the client to use the +name even when the enum member has one instead of the value, as it makes +it easier for the server to respect the read-write +symmetry principle. +

8.4.6. User-defined types

+

P416 enables programmers to introduce new types [13]. While similar +to typedef, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +translation. When introducing a new type, the +declaration can be annotated with @p4runtime_translation to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for port numbers, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. The @p4runtime_translation annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (bit<W>). The type exposed to the control plane (referred to as the +controller_type) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a URI (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the controller_type of the values exposed to the control plane. The +controller_type can be either bit<W> where W is any positive integer, or +string, or a positive integer W which has the same meaning as bit<W>. +Specifying just an integer is deprecated. +

+

It is recommended that the URI includes at least the P4 architecture name and +the type name. +

+

A @p4runtime_translation annotation need not have any effect if it is used to +annotate anything in a P4 program other than a type declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect. +

+

User-defined types are specified using the P4NewTypeSpec message, which has +the following fields: +

+
    +
  • +

    representation, a Protobuf oneof specifying how values of this type are +exchanged between client and server; it can be either: +

    +
      +
    • +

      original_type, if and only if no @p4runtime_translation annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 type declaration is itself a +user-defined type, original_type is obtained by “walking” the chain of +type declarations recursively until a built-in type (e.g. bit<W>) is +found. +

    • +
    • +

      translated_type, if and only if the P4 type declaration was annotated +with @p4runtime_translation. It is of type P4NewTypeTranslation, +which itself has two fields uri and either sdn_string or +sdn_bitwidth , which map to the two input parameters to the +annotation. +

    +
  • +
  • +

    annotations, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration. +

+ +

For example, an architecture in this case PSA may introduce a new type +for port numbers: +

+
+
+
// Controller refers to ports as a string, e.g. "eth0".
+@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+// Controller refers to ports as a 32-bit integer, e.g. 0xffffffff.
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+// Same as above.
+@p4runtime_translation("p4.org/psa/v1/PortId_32_t", 32)
+type bit<9> PortId_32_t;
+

In this case, the P4Info message would include the following P4TypeInfo +messages: +

+
+
+
type_info {
+  new_types {
+    key: "PortId_String_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_String_t"
+        sdn_string: {}
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_Bit32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_Bit32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+

Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (e.g. through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over @p4runtime_translation to enable users +to overwrite annotations included as part of the P4 architecture definition. +

8.4.7. Trade-off for v1.x Releases

+

For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +bytes with P4Data in the p4.v1.FieldMatch message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +bytes to provide action parameter values and controller metadata +values. However P4Data is used whenever appropriate for PSA externs and we +encourage the use of P4Data in architecture-specific extensions. +

+

In order to support translation for action +parameters and match fields, we include a type_name field in +p4.config.v1.MatchField, p4.config.v1.Action.Param and +p4.config.v1.ControllerPacketMetadata.Metadata. In addition, the bitwidth +field for all of these message types must abide by the following rule when +type_name names a translated user-defined type: +

+
    +
  • +

    If the controller_type is a fixed-width unsigned bitstring, the bitwidth +field must be set to the bitwidth of the controller_type. This information +is redundant with the one included in the P4TypeInfo entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent. +

  • +
  • +

    Otherwise (i.e., if the controller_type is a string), the bitwidth must +be “unset”, which, in Protobuf version 3, is the same as setting the field to +0. +

+ +

For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types: +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+@name(".t")
+table t {
+  key = {
+    meta.port1: exact;  // meta.port1 has type PortId_String_t
+    meta.port2: exact;  // meta.port2 has type PortId_Bit32_t
+  }
+  actions = {
+    drop;
+  }
+}
+

This table would have the following representation in the generated P4Info +message: +

+
+
+
tables {
+  preamble {
+    id: 34728461
+    name: "t"
+    alias: "t"
+  }
+  match_fields {
+    id: 1
+    name: "meta.port1"
+    # notice that bitwidth is unset
+    match_type: EXACT
+    type_name {
+      name: "PortId_String_t"
+    }
+  }
+  match_fields {
+    id: 2
+    name: "meta.port2"
+    bitwidth: 32
+    match_type: EXACT
+    type_name {
+      name: "PortId_Bit32_t"
+    }
+  }
+  # ...
+}

9. P4 Entity Messages

+

P4Runtime covers P4 entities that are either part of the P416 language, or +defined as PSA externs. The sections below describe the messages for each +supported entity. +

9.1. TableEntry

+

The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action's +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification. +

+

P4Runtime supports inserting, modifying, deleting and reading table entries with +the TableEntry entity, which has the following fields: +

+
    +
  • +

    table_id, which identifies the table instance; the table_id is determined +by the P4Info message. +

  • +
  • +

    match, a repeated field of FieldMatch messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration. +

  • +
  • +

    action, which indicates which of the table's actions to execute in case of +match and with which argument values. +

  • +
  • +

    priority, a 32-bit integer used to order entries when the table's match key +includes an optional, ternary or range match. +

  • +
  • +

    controller_metadata, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +metadata field. +

  • +
  • +

    metadata, an arbitrary bytes value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. +

  • +
  • +

    meter_config, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    counter_data, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    meter_counter_data, which is used to read and write the per-color counter +values for the direct meter entry attached to this table entry, if any. +See Direct resources section for more information. +

  • +
  • +

    is_default_action, a boolean flag which indicates whether the table entry is +the default entry for the table. See Default entry +section for more information. +

  • +
  • +

    idle_timeout_ns and time_since_last_hit, which are two fields used to +implement idle-timeout support for the table, if applicable. See +Idle-timeout section for more information. +

  • +
  • +

    is_const, a boolean value that is true if and only if the entry +cannot be modified or deleted by the client. +

+ +

The priority field must be set to a non-zero value if the match key includes a +ternary match (i.e. in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an OPTIONAL, TERNARY or +RANGE match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches. +

+

The match and priority fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for MODIFY and DELETE updates. When deleting +an entry, these key fields (along with is_default_action) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a keyless +table (the table has an empty match key), the server must reject all attempts to +INSERT a match entry and return an INVALID_ARGUMENT error. +

+

The number of match entries that a table should support is indicated in P4Info +(size field of Table message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P416 specification for the +size property [36]. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +RESOURCE_EXHAUSTED when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached. +

+

The is_const field must be false in any INSERT, MODIFY, or +DELETE write request of a table entry. If it is true, the server +must reject the operation and return an INVALID_ARGUMENT error. +

9.1.1. Match Format

+

The bytes fields in the FieldMatch message follow the format described in +Bytestrings. +

+

For “don't care” matches, the P4Runtime client must omit the field's entire +FieldMatch entry when building the match repeated field of the TableEntry +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for “don't care” matches, which is needed +to ensure read-write symmetry. For PSA match types, +a “don't care” match for a specific match key field is defined as follows: +

+
    +
  • +

    For a TERNARY match, it is logically equivalent to a mask of zeros. +

  • +
  • +

    For a OPTIONAL match, it is logically equivalent to a wildcard match. +

  • +
  • +

    For an LPM match, it is logically equivalent to a prefix_len of zero. +

  • +
  • +

    For a RANGE match, it is logically equivalent to a range which includes all +possible values for the field. +

+ +

Note that there is no “don't care” value for EXACT matches and therefore exact +match fields can never be omitted from the TableEntry message. +

+

The following example shows a P4Runtime message that treats a TERNARY field +as a “don't care” match. The P4 program defines table t with TERNARY +and EXACT fields in its match key: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: ternary;
+    istd.ingress_port: exact;
+  }
+  actions = {
+    drop;
+  }
+}
+

In this P4Runtime request, the client omits the table's TERNARY field +from the repeated match field to indicate a “don't care” match. As shown +below, the match specifies only the EXACT field given by field_id: 2. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 33554439  # Table t's ID.
+    match {
+      # field_id 1 is not present to use the don't care ternary value.
+      field_id: 2
+      exact {
+        value: "\x20"
+      }
+    }
+    action {
+      # Action selection goes here.
+    }
+  }
+}
+

For every member of the TableEntry repeated match field, field_id must be +a valid id for the table, as per the P4Info, and one of the fields in +field_match_type must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an INVALID_ARGUMENT error code. +

+
    +
  • EXACT match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.exact().value()))
+
    +
  • LPM match + +
      +
    • The binary string encoding of the value (when present) must conform to the +Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • “Don't care” bits must be 0 in value. +
+ +
+
+
assert(BytestringValid(match.lpm().value()))
+
+pLen = match.lpm().prefix_len()
+assert(pLen > 0)
+
+trailing_zeros = countTrailingZeros(match.lpm().value())
+assert(trailing_zeros >= field_bits - pLen)
+
    +
  • TERNARY match + +
      +
    • The binary string encoding of the value (when present) and mask (when +present) must conform to the Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • Masked bits must be 0 in value. This constraint taken together +with the Bytestrings requirements means that the +value's binary string is never longer than the mask's binary string. +When the value's string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask. +
+ +
+
+
assert(BytestringValid(match.ternary().value()))
+assert(BytestringValid(match.ternary().mask()))
+assert(match.ternary().value().size() <= match.ternary().mask().size());
+
+value = parseInteger(match.ternary().value())
+mask = parseInteger(match.ternary().mask())
+
+assert(mask != 0)
+
+assert(value & mask == value)
+
    +
  • RANGE match + +
      +
    • The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the Bytestrings +requirements. +
    • +
    • Low bound must be less than or equal to the high bound. +
    • +
    • “Don't care” match must be omitted. +
+ +
+
+
assert(BytestringValid(match.range().low()))
+assert(BytestringValid(match.range().high()))
+
+low = parseInteger(match.range().low())
+high = parseInteger(match.range().high())
+
+assert(low <= high)
+
+assert(low != min_field_value || high != max_field_value)
+
    +
  • OPTIONAL match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.optional().value()))

9.1.2. Action Specification

+

The TableEntry action field must be set for every INSERT update but may be +left unset for MODIFY updates, in which case the action specification for the +table entry will not be modified (if a MODIFY update has an unset action field +and does not modify any direct resource attached to the table then the MODIFY +update is a no-op). Based on the implementation property value of the P4 table, +the oneof in the TableAction message will either be: +

+
    +
  • +

    an Action specification for direct tables (with no P4 implementation +property) +

  • +
  • +

    an action profile member id for indirect tables for which the implementation +property is an action profile with no selector. +

  • +
  • +

    an action profile member id or group id for indirect tables for which the +implementation property is an action profile with selector. +

  • +
  • +

    an ActionProfileActionSet specification for indirect tables for +which the implementation property is an action profile with +selector. This usage is described in One Shot Action Selector +Programming +

+ +

If the oneof does not match the table description in the P4Info (e.g. the +oneof is action_profile_member_id for a direct table), the server must +return an INVALID_ARGUMENT error code. +

+

The Action Protobuf message has the following fields: +

+
    +
  • +

    action_id, which identifies the action instance; the action_id is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an INVALID_ARGUMENT error +code. If the client uses a valid action_id for the table but does not +respect the action scope specified in P4Info (e.g. tries to set a TABLE_ONLY +action as the default action), the server must return a PERMISSION_DENIED +error code. +

  • +
  • +

    params: a repeated Protobuf field of action parameter values, each encoded +as a Param message. For each parameter, param_id must be valid for the +action (as per the P4Info) and value must follow the format described in +Bytestrings. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an INVALID_ARGUMENT error code +if a parameter id is missing, if an extra parameter id not found in the +P4Info was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +Bytestrings format. +

+ +

For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a NOT_FOUND error code. +

9.1.3. Default Entry

+

According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer or defaults to NoAction +(which is a no-op) otherwise and assuming it is not declared as const, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow INSERT and DELETE updates on the default entry and the +P4Runtime server must return an INVALID_ARGUMENT error code if the client +attempts one. +

+

The default entry is identified by setting the is_default_action boolean field +to true. When this flag is set to true, the repeated match field must be empty +and the priority field must be set to zero, otherwise the P4Runtime server +must return an INVALID_ARGUMENT error code. When performing a MODIFY update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its controller_metadata and metadata value as well as the +configurations for its direct resources will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a PERMISSION_DENIED +error code if the client attempts to modify it. +

+

Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to direct resources. +

+

In this P4Runtime release, we have decided to restrict the default entry for +indirect tables tables with an ActionProfile or ActionSelector +implementation property to a constant NoAction action entry, with the +hope that it would simplify the implementation of the P4Runtime service. +

9.1.4. Constant Tables

+

Constant tables are defined as tables whose match entries are +immutable. They are identified by the table property const entries +in the P416 source code. In the P4Info, such tables have +is_const_table equal to true, and if the list of entries in the +source code has at least one entry in it, they also have +has_initial_entries flag equal to true. For tables declared with +the entries property, without const before entries see Section +9.1.5. +

+

The only write updates which are allowed for constant tables are MODIFY +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +PERMISSION_DENIED error. Just like any table entry MODIFY request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a PERMISSION_DENIED error. +

+

The contents of const tables can be queried by the client through a +ReadRequest. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: table_id, match, action, +is_default_action, and priority (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. +

+

When a priority value is required (e.g. for tables including RANGE, +TERNARY or OPTIONAL matches), it is inferred based on the order in +which entries appear in the table declaration. As of August 2023, the +open source p4c compiler always assigns entry priority values in a +constant table with N entries starting at N for the first entry +and decrementing the value by 1 for each successive entry. The P416 +language specification does not preclude the P4 developer from +explicitly specifying priorities for entries in constant tables, but +p4c does not yet support this. +

9.1.5. Preinitialized tables

+

Preinitialized tables are those defined with an entries table +property in the P416 source code, with no const qualifier before +entries, and at least one entry in that list. In the P4Info, such +tables have has_initial_entries flag equal to true, but +is_const_table is false. For tables declared with const entries, +see Section 9.1.4. +

+

Every P4 table falls into one of three categories: +

+
    +
  • Normal table: Neither entries nor const entries are declared +in the source code, and thus is_const_table and +has_initial_entries will both be false. A corner case is that if +it has entries = { } with no const before entries, i.e. an +empty list of entries, that is also a normal table. +
  • +
  • Constant table: The table has const entries declared, and thus a +separate entries property is not permitted by the language. Such +a table will have is_const_table true. Such a table will have +has_initial_entries true if there is at least one entry in the +source code, or false if the list is empty. +
  • +
  • Preinitialized table: The table has entries declared, and thus a +separate const entries property is not permitted by the language. +It also has at least one entry in the list. Such a table will have +is_const_table false and has_initial_entries true. +
+ +

A preinitialized table is allowed to have a mix of some entries marked +const, and other entries not marked const. +

+

Entries not marked const may be modified or deleted, just as a +client may do for any entry in a normal table. +

+

Entries marked const behave like entries in a constant table, +i.e. only MODIFY operations on direct resources are allowed. +

+

Unlike a table with is_const_table = true, a client may insert +entries into a table with has_initial_entries = true and +is_const_table = false, subject to capacity constraints on the +number of entries supported by the target for the table. +

+

The contents of preinitialized tables can be queried by the client +through a ReadRequest. The server fills in the same fields in the +response as it does for constant tables, as described in Section +9.1.4, and with the same restrictions on table +features supported. +

+

If the table requires a priority value for entries, the priorities of +the initial entries are determined according to the P416 language +specification. After the P4 program is initially loaded, the entries +not marked const can be modified at run time just as table entries +in a normal table can. +

+

The contents of all table entries within the entries table +properties in a P4 program can be written to a separate output file by +the open source p4c compiler. See Section A.5 for +details. +

9.1.6. Wildcard Reads

+

When performing a ReadRequest, the P4Runtime client can select all entries +from one or all tables on the target and use several of the TableEntry fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as priority and “unset” for message fields such as match. The following +fields may be used to select and filter results: +

+
    +
  • table_id: If default (0), entries from all tables including constant +tables will be selected and no other filter can be used. Otherwise only +the specified table will be considered. +
  • +
  • match: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned. +
  • +
  • action: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an action_id (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id. +
  • +
  • priority: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value. +
  • +
  • controller_metadata: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +controller_metadata value. +
  • +
  • metadata: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided metadata value. +
  • +
  • is_default_action: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered. +
  • +
  • role: If default (unset), all table entries will be considered. Otherwise, +table entries will be filtered based on the provided role value. +
+ +

For example, in order to read all entries from all tables from device 3, the +client can use the following ReadRequest message. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0
+    priority: 0
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following ReadRequest +message: +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+    priority: 11
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

The canonical representation of “don't care” matches, combined with the ability +to do a wildcard read on all table entries by leaving the match field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single “don't care” entry or to do a wildcard +read. If a table has no fields with match kind EXACT, it is possible via +P4Runtime to add an entry that is “don't care” for all fields (i.e. has an empty +match field) but is not the default entry (i.e. is_default_action is +false). When reading this entry from the table, there is no way to read only +that entry from the table, because it would require providing an unset match +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single LPM match: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: lpm;
+  }
+  actions = {
+    drop; fwd;
+  }
+}
+

The following WriteRequest message can be used to add 2 entries: +

+
+
+
device_id: 3
+entities {
+  table_entry { # don't care entry
+    table_id: 0x0212ab34
+    # ...
+  }
+  table entry {
+    table_id: 0x0212ab34
+    match {
+      field_id: 1
+      lpm {
+        value: 0x0a000000
+        prefix_len: 8
+      }
+    # ...
+  }
+}
+

The first entry is a “don't care” entry, while the second one matches all +10.0.0.0/8 addresses. The second entry has higher priority than the first one. +

+

The following ReadRequest message will return all entries in the table, not +just the “don't care” entry. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+  }
+}
+

This issue also exists for tables with TERNARY, RANGE, and OPTIONAL +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the “don't care” entry will be returned to the +client. If the client uses distinct priority values for all entries which is +strongly recommended to achieve deterministic behavior , +then there is no ambiguity because the wildcard read will actually return a +single entry (the “don't care” entry) as long as the priority field is set to +the correct value. +

9.1.7. Direct Resources

+

In addition to the DirectCounterEntry and DirectMeterEntry entities, +P4Runtime support reading and writing direct resources as part of the +TableEntry message. This is convenient for two reasons: +

+
    +
  • +

    A table entry and its direct resources can be read with a single entity when +doing a Read RPC call +

  • +
  • +

    The initial configuration for an entry's direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can “hit” the table entry without +executing the appropriate meter entry. +

+ +

Once the table entry has been inserted, the P4Runtime client is free to use the +DirectCounterEntry and DirectMeterEntry messages for read and write +operations on DirectCounter and DirectMeter instances. For example, it is +usually more convenient as well as more efficient to use DirectCounterEntry to +query a counter entry value rather than use TableEntry, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry. +

+

The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does not need to be “executed” in +every action bound to the table. It is an error to provide a direct resource +configuration in a TableEntry message when programming an action that does not +execute the direct resource, and the server must return an INVALID_ARGUMENT +error code. +

+

We leverage Protobuf's ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the TableEntry message. The list below describes how +the server must handle the meter_config, counter_data and +meter_counter_data fields for read and write requests, based on whether the +fields are set or not. We do not cover error cases in the list, i.e. we assume +that we are dealing with a table which is assigned a direct counter / a direct +meter, and that the action being used for the table entry “executes” the direct +resource appropriately. +

+
    +
  • +

    meter_config field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets). +
      • +
      • if set: The initial configuration for the meter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The meter entry's configuration is reset to the default +(meter returns GREEN for all packets). +
      • +
      • if set: The value provided by the client is used to re-configure +the meter entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the meter entry's +configuration (meter_config is unset in the response). +
      • +
      • if set: If the meter entry's configuration is the default +configuration, meter_config is unset in the response. Otherwise, the +response includes the meter entry's configuration that was written by +the client earlier. This respects the “read-write symmetry” principle. +
    +
  • +
  • +

    counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for the counter entry is the default +(0). +
      • +
      • if set: The initial value for the counter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The counter entry's value is not changed. +
      • +
      • if set: The value provided by the client is written to the counter +entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the counter entry's value +(counter_data is unset in the response). +
      • +
      • if set: The response includes the counter entry's value read from +the target. +
    +
  • +
  • +

    meter_counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for all 3 counter entries is the +default (0). +
      • +
      • if set: The initial value for all 3 counter entries is the +default (0). Sub-field, if any, can only have zero (0) as its value. +INVALID_ARGUMENT error is returned for any non-zero sub-field value. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: All the 3 counter entries are unchanged. +
      • +
      • if set: All the 3 counters are reset to 0. Sub-field, if any, can +only have zero (0) as its value. INVALID_ARGUMENT error is returned +for any non-zero sub-field value. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include counter values +(meter_counter_data is unset in the response). +
      • +
      • if set: The response includes all the 3 counter values read from +the target. +
    +
+ +

In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +meter_config field unset when inserting or modifying a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the TableEntry message +(i.e. the meter_config field must be set to match the existing configuration). +

9.1.8. Idle-timeout

+

P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not “hit” (i.e. not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification using the +IdleTimeoutNotification message to the primary client, which can then take +action, such as remove the idle table entry. +

+

Two fields of the TableEntry Protobuf message are used to implement idle +timeout: +

+
    +
  • +

    idle_timeout_ns: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, i.e. no +IdleTimeoutNotification message will ever be generated for this entry. When +a client reads a TableEntry, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry. +

  • +
  • +

    time_since_last_hit: a Protobuf message with a single field (elapsed_ns) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The time_since_last_hit field must be unset for a +TableEntry write. When reading a table entry, time_since_last_hit must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0. +

+ +

These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an INVALID_ARGUMENT error code if at least one of these +conditions is met: +

+
    +
  • idle_timeout_ns is set to a non-zero value, or +
  • +
  • time_since_last_hit is set +
+ +

The target should do its best to approximate the idle_timeout_ns value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the TableEntry write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for time_since_last_hit. +

+

P4Runtime does not support idle timeout for default entries. When the +is_default_action flag is set in a TableEntry message, idle_timeout_ns +must be set to 0 (default) and time_since_last_hit must be unset. If the +server receives a TableEntry message which violates this, it must return an +INVALID_ARGUMENT error. +

+

For more information about idle timeout, in particular regarding +IdleTimeoutNotification, please refer to the Table idle timeout +notifications section. +

9.2. ActionProfileMember & ActionProfileGroup

+

P4Runtime defines an API for programming a PSA ActionProfile extern using +ActionProfileMember messages. A PSA ActionSelector extern can be programmed +using both ActionProfileMember and ActionProfileGroup messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table t for L3 routing, implemented with an action +selector as. +

+
+
+
ActionSelector(HashAlgorithm.crc32,
+               /*size = */ 32w1024,
+               /*output_width = */ 32w10) as;
+
+action set_nhop(PortId_t p, EthAddr smac, EthAddr dmac) {
+  istd.egress_port = p;
+  hdr.ethernet.smac = smac;
+  hdr.ethernet.dmac = dmac;
+}
+
+table t {
+  key = {
+    hdr.ipv4.dip: lpm;  // LPM on destination IP address
+  }
+  actions = {
+    set_nhop;
+  }
+  implementation = as;
+}
+

When programming table t in the example above, a P4Runtime client should +specify the TableAction in the TableEntry to be a reference to either an +action profile member or group. The reference is a non-zero uint32 identifier +that uniquely identifies a member or group programmed in the action selector +as. +

+

If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata. +

+

If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata. +

9.2.1. Action Profile Member Programming

+

Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a uint32 identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the actions +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the actions attributes of the +tables must have an identical list of P4 actions. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector. +

+

An ActionProfileMember entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info. +

  • +
  • +

    member_id is the non-zero uint32 identifier of the action profile member +entry being updated. +

  • +
  • +

    action is the specification of the P4 action instance bound to the action +profile member entry. +

+ +

An action profile member may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an ALREADY_EXISTS error +code. The action specification must be provided, or the server must return +INVALID_ARGUMENT. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return RESOURCE_EXHAUSTED. +
  • +
  • MODIFY: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return NOT_FOUND, +and the action specification must be provided, or the server must return +INVALID_ARGUMENT. +
  • +
  • DELETE: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a NOT_FOUND error code. The member +must not be part of an action profile group, or the server must return +FAILED_PRECONDITION. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return FAILED_PRECONDITION. action_profile_id and member_id are the only +fields that are considered when performing a DELETE and every other field +will be ignored. +
+ +

When reading, an ActionProfileMember message with action_profile_id and +member_id equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with action_profile_id equal to the id of +an existing ActionProfile or ActionSelector object, and a member_id equal to +0, will read all members of that specified object. +

9.2.2. Action Profile Group Programming

+

Action profile groups are entries in an ActionSelector and are referenced by a +uint32 identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type. +

+

Within a single ActionSelector object, the uint32 values used to identify its +members are in a separate ‘scope’ from the uint32 values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5. +

+

There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it. +

+

An ActionProfileGroup entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionSelector +extern instance, as defined in P4Info. +

  • +
  • +

    group_id is the non-zero uint32 identifier of the action profile group +entry being updated. +

  • +
  • +

    members is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields: +

    +
      +
    • member_id for looking up the member table in the selector. +
    • +
    • weight specifying the probability of the member's selection at +runtime. 0 is not a valid weight value and the server must return +INVALID_ARGUMENT if the client attempts to use it. +
    • +
    • watch_port is the controller-defined port that the member's +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +9.2.4 for notes on the behavior if all members in +a group are excluded for this reason. If watch_port is empty, then the +member is always included in the selection, regardless of the status of +any port of the device. The value must be empty or the SDN port of an +existing port on the device, otherwise the server must return +INVALID_ARGUMENT. If the target does not support using the SDN port as a +watch port (e.g. on some targets LAGs cannot be used for this purpose), +the server must return UNIMPLEMENTED. +
    +
  • +
  • +

    max_size is the maximum sum of all members or member weights (as per the +selector_size_semantics) for the group. This field is defined when the group +is inserted, and must not be changed in a MODIFY update, otherwise an +INVALID_ARGUMENT error is returned. See the subsection below for the +rules on setting max_size. +

+ +

An action profile group may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new group entry bound to a set of existing action profile +members. The group_id must be different from ids of already programmed +groups for that selector, or the server must return an ALREADY_EXISTS error +code. All members specified in the group must exist in the selector, or the +server must return NOT_FOUND. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target. +
  • +
  • MODIFY: Modify the member set specification of an existing group entry. An +entry with the group_id must exist, or the server must return +NOT_FOUND. All members specified in the group entry must exist in the +selector, or the server must return NOT_FOUND. The value of max_size must +be identical to the value used when inserting the group, otherwise an +INVALID_ARGUMENT error is returned. +
  • +
  • DELETE: Delete the group entry and deallocate the group_id. The group must +not be referenced in the table action of any table entry, or the server must +return a FAILED_PRECONDITION error code. If the group_id is invalid, the +server must return NOT_FOUND. action_profile_id and group_id are the +only fields that are considered when performing a DELETE and every other +field will be ignored. +
+ +

When setting the group membership with INSERT or MODIFY, the members +repeated field must not include duplicates, i.e. members with the same +member_id. The weight field is used instead to logically “repeat” the member +inside the group. +

+

It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation “stores” the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made. +

+

When reading, an ActionProfileGroup message with action_profile_id and +group_id equal to 0 will read all groups of all ActionSelector objects. A +message with action_profile_id equal to the id of an existing ActionSelector +object, and a group_id equal to 0, will read all groups of that one specified +object. +

9.2.2.1. Rules on Setting max_size
+

The valid values for max_size depend on the static max_group_size included +in the P4Info message: +

+
    +
  • +

    If max_group_size is greater than 0, then max_size must be greater than 0, +and less than or equal to max_group_size. We assume that the target can +support selector groups for which the size of the members (as defined by +selector_size_semantics) is up to max_group_size, or the P4Runtime server +would have rejected the Forwarding Pipeline Config. If max_size is greater +than max_group_size, the server must return INVALID_ARGUMENT. +

  • +
  • +

    Otherwise (i.e. if max_group_size is 0), the P4Runtime client can set +max_size to any value greater than or equal to 0. +

    +
      +
    • +

      A max_size of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (INSERT or MODIFY), the target must return a +RESOURCE_EXHAUSTED error. +

    • +
    • +

      If max_size is greater than 0 and the value is not supported by the +target, the server must return a RESOURCE_EXHAUSTED error at +group-creation time. +

    +
+

9.2.3. One Shot Action Selector Programming

+

P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids. +

+

One shots are programmed by choosing the ActionProfileActionSet message as the +TableAction. The ActionProfileActionSet message consists of a set of +ActionProfileAction messages. This set should have cardinality no greater than +max_group_size (if max_group_size is nonzero) if selector_size_semantics +is sum_of_members, or else the server must return INVALID_ARGUMENT. Each +ActionProfileAction message has the following fields: +

+
    +
  • +

    action is one of the actions specified by the table that is being +programmed. +

  • +
  • +

    weight specifying the probability of the action's selection at runtime. 0 is +not a valid weight value and the server must return INVALID_ARGUMENT if +the client attempts to use it. If selector_size_semantics is +sum_of_weights, then the sum of all weights across all ActionProfileAction +messages for that ActionProfileActionSet message must not exceed the +max_group_size specified in the P4Info (if greater than 0), or the server +must return INVALID_ARGUMENT. If selector_size_semantics is +sum_of_members, the individual weight of each member must not exceed +max_member_weight (if greater than 0), or the server must return +INVALID_ARGUMENT. +

  • +
  • +

    watch_port is the controller-defined port that the action's liveness depends +on. At runtime, the action must be excluded from selection if the watch port +is down. See Section 9.2.2 for more details +on the watch_port field, which also apply for one shot action selector +programming. +

+ +

Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics. +

+

To preserve read-write symmetry, an implementation must answer ReadRequests +with the original one shot messages. It may not return a desugared version of +the one shot message. +

+

For example, consider the action selector table defined +here. This table could be programmed +with the following one shot update: +

+
+
+
table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action {
+    action_profile_action_set {
+      action_profile_actions {
+        action { /* set nexthop 1 */ }
+        weight: 1
+        watch_port: "\x01"
+      }
+      action_profile_actions {
+        action { /* set nexthop 2 */ }
+        weight: 2
+        watch_port: "\x02"
+      }
+      action_profile_actions {
+        action { /* set nexthop 3 */ }
+        weight: 3
+        watch_port: "\x03"
+      }
+    }
+  }
+}
+

Which would be equivalent to the following updates, where GROUP_ID, +MEMBER_ID_1, MEMBER_ID_2, and MEMBER_ID_3 are unused ids: +

+
+
+
action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_1
+  action { /* set nexthop 1 */ }
+}
+action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_2
+  action { /* set nexthop 2 */ }
+}
+action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_3
+  action {  /* set nexthop 3 */ }
+}
+action_profile_group {
+  action_profile_id: 0x11ab12cd
+  group_id: GROUP_ID
+  members {
+    member_id: MEMBER_ID_1
+    weight: 1
+    watch_port: "\x01"
+  }
+  members {
+    member_id: MEMBER_ID_2
+    weight: 2
+    watch_port: "\x02"
+  }
+  members {
+    member_id: MEMBER_ID_3
+    weight: 3
+    watch_port: "\x03"
+  }
+}
+table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action { action_profile_group_id: GROUP_ID }
+}
+

Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure correct ordering between the dependent +updates. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct WriteRequest batches are required. +

+

It is possible to include several ActionProfileAction messages with the same +exact action specification in one ActionProfileActionSet message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the weight field. Note that to preserve read-write symmetry, the server +must not coalesce multiple ActionProfileAction messages with the same action +specification into one. Additionally, each action specification would count as +a separate member for the purposes of e.g. the sum_of_members group size +calculation for Action Selectors. +

+

All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with ActionProfileMember and +ActionProfileGroup messages. Programming some entries with one shots, and +other entries with ActionProfileMember and ActionProfileGroup messages is +not allowed, and the server must return the error code INVALID_ARGUMENT in +that case. +

+

A P4Runtime server must support the one shot style of programming tables with +an action selector implementation. Support for the ActionProfileMember and +ActionProfileGroup style is optional. If ActionProfileMember and +ActionProfileGroup are not supported by a server, it must return an +UNIMPLEMENTED error for every ActionProfileMember or ActionProfileGroup +message that it receives. +

9.2.4. Constraints on action selector programming

+

The PSA specification states that the following features are optional in +action selector implementations [27]: +

+
    +
  1. Support for non-empty groups where in the same group, different members are +bound to different actions. +
  2. +
  3. Predictable data plane behavior when a matched table entry points to an empty +group. +
+ +

For 1., if a client tries to INSERT or MODIFY a group with members bound to +different actions, the server should return UNIMPLEMENTED if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return UNIMPLEMENTED (modifying the action parameter values must be +supported, however). +

+

PSA 1.1 introduces the psa_empty_group_action table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. psa_empty_group_action is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of psa_empty_group_action at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +NoAction. Even when psa_empty_group_action is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of psa_empty_group_action mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming. +

+

The PSA specification includes a discussion on how to implement +psa_empty_group_action in software in the P4Runtime server +[30]. +

+

If a P4Runtime implementation does support psa_empty_group_action, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down. +

+

If a P4Runtime implementation does not support psa_empty_group_action, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down. +

9.3. CounterEntry & DirectCounterEntry

+

PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The CounterData +P4Runtime message can be used for all three types of PSA counters PACKETS, +BYTES and PACKETS_AND_BYTES and consists of the following fields: +

+
    +
  • byte_count is an int64, corresponding to the number of octets. +
  • +
  • packet_count is an int64, corresponding to the number of packets. +
+ +
+
+
message CounterData {
+  int64 byte_count = 1;
+  int64 packet_count = 2;
+}
+

P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of byte_count and packet_count fields, which +is equivalent to specifying the counter type PACKETS_AND_BYTES. Counters may +be defined as direct or indirect (indexed) instances. +

9.3.1. DirectCounterEntry

+

A direct counter is a direct resource associated with a TableEntry (see +Direct Resources). The counter_data field of the +TableEntry message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +DirectCounterEntry message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed. +

+
+
+
message DirectCounterEntry {
+  TableEntry table_entry = 1;
+  CounterData data = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectCounterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match TableEntry.match of the table entry +to which this direct counter entry is associated. If a matching TableEntry +is not found, the server returns the error code NOT_FOUND. +

  • +
  • +

    data is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified. +

+ +

Specifying DirectCounterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read the contents of a +DirectCounter: +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the counter value in the counter_data field of the TableEntry message +(see Direct resources). +

  • +
  • +

    Explicitly request the counter value by including the DirectCounterEntry in +the ReadRequest. The table_entry.match field must match the TableEntry +whose counter is being read. If no such entry is found, the server returns the +error code NOT_FOUND. +

+

9.3.2. CounterEntry

+

An indirect or indexed counter is not associated with a specific TableEntry +and may be updated independently of any action. It may be read or written using +the P4Runtime CounterEntry message whose fields are defined as follows: +

+
    +
  • +

    counter_id is a uint32, the unique identifier for the counter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +the counter array. +

  • +
  • +

    data is a Protobuf message of type CounterData, which represents the +counter value. +

+ +
+
+
message CounterEntry {
+  uint32 counter_id = 1;
+  Index index = 2;
+  CounterData data = 3;
+}
+

The CounterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the counter entries in the +array have default value 0. +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect counter instance whose unique id is counter_id +and array index is specified by index. The counter value is set to the value +specified by the client in the data field. Note that the counter value is +not modified if this Protobuf field is not set. If index is omitted all +counter values in the array will be set to the value provided by the +client. The server must return INVALID_ARGUMENT for a negative index value +and OUT_OF_RANGE if the index value exceeds the size of the counter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a ReadRequest by including a CounterEntry +entity for each of the instances, specifying the counter_id and +index. Wildcard reads are also supported as follows: +

+
    +
  • +

    If the counter_id field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the ReadResponse. +

  • +
  • +

    Otherwise, if the index field is not set, the server returns the counter +values for all indirect counters in the array identified by the unique id +counter_id. +

+

9.4. MeterEntry & DirectMeterEntry

+

Meters are an advanced mechanism for keeping statistics, involving stateful +“marking” and usually “throttling” of packets based on configured rates of +traffic. The PSA metering function is based on the Two Rate Three Color Marker +(trTCM) defined in RFC 2698 [3]. P4Runtime clients may additionally +restrict meter usage on a table to RFC 2697's [2] Single Rate Three +Color Marker (srTCM) or a simplified version of it that we call Single Rate +Two Color Marker. The type of a table's meter is set by the MeterSpec.Type as +described in the Meter & DirectMeter section. +

+

The trTCM meters an arbitrary packet stream using two configured rates +the Peak Information Rate (PIR) and Committed Information Rate (CIR), and their +associated burst sizes and “marks” its packets as GREEN, YELLOW or RED based +on the observed rate. +

+

The srTCM meters an arbitrary packet stream using a single configured rate +the Committed Information Rate (CIR) and its associated burst size as well +as the Excess Burst Size (EBS) and “marks” its packets as GREEN, YELLOW or RED +based on the observed rate. +

+

The Single Rate Two Color Marker meters an arbitary packet stream using a +single configured rate the Committed Information Rate (CIR) and its +associated burst size and “marks” its packets as GREEN or RED based on the +observed rate. +

+

MeterEntry & DirectMeterEntry have an additional field counter_data that +may hold per color counter data for targets that support it, and that must +always be unset for targets that do not support it. If set in a request and +unsupported by a target, an UNIMPLEMENTED error code should be returned. +These counters provide a granular list of the counters applicable to the +possible meter colors GREEN, YELLOW and RED. The counter associated with a +specific color is incremented when a packet is “marked” with that color. The +primary purpose of the color counters is for debugging purposes. +

+

A meter may be configured as a direct or indirect instance, similar to a +counter. The MeterConfig P4Runtime message represents meter configuration. +

+
+
+
message MeterConfig {
+  int64 cir = 1;  // Committed Information Rate
+  int64 cburst = 2;  // Committed Burst Size
+  int64 pir = 3;  // Peak Information Rate
+  int64 pburst = 4;  // Peak Burst Size
+  int64 eburst = 5; // Excess burst size (only used for srTCM)
+}
+

A MeterConfig for a trTCM typed meter must only be accepted if eburst is +unset. Otherwise, the server should return an INVALID_ARGUMENT error. +

+

A MeterConfig for a srTCM typed meter must only be accepted if pir and +pburst are equal to cir and cburst respectively. Otherwise, the server +should return an INVALID_ARGUMENT error. +

+

A MeterConfig for a Single Rate Two Color Marker typed meter must only be +accepted if pir and pburst are equal to cir and cburst respectively and +eburst is unset. Otherwise, the server should return an INVALID_ARGUMENT +error. +

+

Note: Any acceptable MeterConfig for a Single Rate Two Color Marker typed +meter is also acceptable for either of the other two meter types and will mark +packets identically in all three cases. Thus, changing the meter type from +Single Rate Two Color Marker to Single Rate Three Color Marker or +Two Rate Three Color Marker is a non-breaking change. +

9.4.1. DirectMeterEntry

+

A direct meter is a direct resource associated with a TableEntry (see Direct +resources). The meter_config field of the TableEntry +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +DirectMeterEntry message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed. +

+
+
+
message DirectMeterEntry {
+  TableEntry table_entry = 1;
+  MeterConfig config = 2;
+  MeterCounterData counter_data = 3;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectMeterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match the match key of the TableEntry +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching TableEntry is not found, +the server returns the error code NOT_FOUND. +

  • +
  • +

    config is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets). +

  • +
  • +

    counter_data is used to set the per color counter values to the default +value of (0), which is essentially clearing the counters. If the field is +unset, the counter values are left untouched. If the field is set, targets +supporting these counters should reset all the color counters to (0), if any +of the sub-fields are set to a non-zero value, then an INVALID_ARGUMENT +error should be returned. +

+ +

Specifying DirectMeterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read a DirectMeter config. +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the meter config in the meter_config field of the TableEntry +message (see Direct resources). +

  • +
  • +

    Explicitly request the meter configuration by including the DirectMeterEntry +in the ReadRequest. The table_entry.match field must match the +TableEntry whose meter config is being read. If no such entry is found, the +server returns the error code NOT_FOUND. Read responses also include the +per color counter data for the meter entry, if supported and specified in +the request message. +

+

9.4.2. MeterEntry

+

An indirect or indexed meter is not associated with a specific TableEntry and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime MeterEntry message whose fields are defined as +follows: +

+
    +
  • +

    meter_id is a uint32, the unique identifier for the meter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +a meter array. +

  • +
  • +

    config is a Protobuf message of type MeterConfig, which represents the +meter configuration. +

  • +
  • +

    counter_data is a Protobuf message of type MeterCounterData, which +represents the per color counter values associated with the corresponding +meter. +

+ +
+
+
message MeterEntry {
+  uint32 meter_id = 1;
+  Index index = 2;
+  MeterConfig config = 3;
+  MeterCounterData counter_data = 4;
+}
+

The MeterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the meter entries in the +array have a default configuration (GREEN for all packets). +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect meter instance whose unique id is meter_id and +array index is specified by index. The meter is reconfigured using the +config field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the index field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if config is unset). The server must return INVALID_ARGUMENT for a +negative index value and OUT_OF_RANGE if the index value exceeds the size of +the meter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a ReadRequest by including a MeterEntry entity for each +of the instances, specifying the meter_id and index. Wildcard reads are also +supported as follows: +

+
    +
  • +

    If the meter_id field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the ReadResponse. +

  • +
  • +

    Otherwise, if the index field is not set, the server returns the +configuration for all indirect meters in the array identified by the unique id +meter_id. +

+

9.4.3. MeterCounterData

+

The MeterCounterData P4Runtime message represents the per color counters +associated with a meter entry. Whenever a meter is executed and returns +a color, the corresponding color counter GREEN, YELLOW or RED is updated. +

+

As seen above, these counters can be associated with a DirectMeterEntry or +MeterEntry. Targets not capable of supporting these counters should return +UNIMPLEMENTED if a MeterCounterData field was set in a read or write +request. +

+
+
+
message MeterCounterData {
+  CounterData green = 1;
+  CounterData yellow = 2;
+  CounterData red = 3;
+}

9.5. PacketReplicationEngineEntry

+

The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets. +

9.5.1. MulticastGroupEntry

+

Multicasting is achieved in PSA programs by setting the multicast_group +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the MulticastGroupEntry API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example. +

+
+
+
control arp_multicast(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ethernet.isValid() &&
+        hdr.ethernet.eth_type == ETH_TYPE_ARP) {
+      smeta.multicast_group = (MulticastGroup_t) 1;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    multicast_group_entry {
+      multicast_group_id: 1
+      replicas { port: "\x05" instance: 1 }
+      replicas { port: "\x0c" instance: 2 }
+      replicas { port: "\x12" instance: 3 }
+      replicas { port: "\x18" instance: 4 }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +PSA Metadata Translation section. +

+

The egress packets may be distinguished for further processing in the egress +using the instance metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 multicast_group metadata is set to a value that is not +programmed in the PRE, then the packet is dropped. +

+

A multicast group may be inserted, modified or deleted as per the following +semantics. +

+
    +
  • INSERT: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The multicast_group_id field is a uint32 and must be greater +than 0 (see explanation below), or the +P4Runtime server must return an INVALID_ARGUMENT error. The replica +instance ID is also a uint32, and its value may not exceed the maximum +allowed by the target for the EgressInstance_t type (0 is allowed), or the +server must return an INVALID_ARGUMENT error. The egress port (port field) +must be an SDN port and must refer to a singleton port. No two replicas may +have identical values of both port and instance, or the server must +return INVALID_ARGUMENT. The metadata field is an arbitrary bytes value +which is opaque to the target. There is no requirement of where this is +stored, but it must be returned by the server along with the rest of the entry +when the client performs a read on the entry. +
  • +
  • MODIFY: Modify the set of replicas and metadata for a given multicast group +entry, indexed by the given multicast_group_id. Same restrictions as +INSERT apply here. +
  • +
  • DELETE: Delete the multicast group indexed by the given +multicast_group_id. The replicas and metadata fields need not be +provided for this operation. Any packets with their multicast_group +metadata in the data plane set to the deleted multicast_group_id will be +dropped. +
+ +

When reading a multicast group, only multicast_group_id is considered. All +other fields in MulticastGroupEntry are ignored. To perform a wildcard +Read on all configured multicast group entries, the multicast_group_id field +must be set to 0, its default value. +

9.5.1.1. Valid Values for multicast_group_id
+

The PSA specification states that the valid data plane values for multicast +group ids (MulticastGroup_t) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target [29]. This means that, in the absence of +translation, the client must set the multicast_group_id field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special wildcard value which is used to read all the multicast groups +configured in the target, the multicast_group_id field must never be set to 0 +when performing a Write RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value. +

9.5.2. CloneSessionEntry

+

PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +clone_session_id identifier and a boolean flag clone in the packet +metadata. The clone_session_id serves as a handle to the clone attributes, +namely a set replicas of (egress port, instance) pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +CloneSessionEntry API. +

+

The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the clone_low_ttl control block is applied in the ingress +pipeline to create an ingress-to-egress clone. +

+
+
+
control clone_low_ttl(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ipv4.isValid() &&
+        hdr.ipv4.ttl <= LOW_TTL_THRESHOLD) {
+      smeta.clone_session_id = 10w100;
+      smeta.clone = true;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    clone_session_entry {
+      session_id: 100
+      replicas { port: "\xff\xff\xff\xfd" instance: 1 } # to CPU
+      class_of_service: 2
+      packet_length_bytes: 4096
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type CloneSessionId_t [29]). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes. +

+

The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port 0xfffffffd; see +Translation of Port Numbers). Note that the +egress port (port field) must be an SDN port and must refer to a singleton +port. +

+

If the clone_session_id data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created. +

+

A clone session may be inserted, modified or deleted as per the following +semantics: +

+
    +
  • INSERT: Add a new clone session entry bound to a set of egress ports and +replica IDs. The session_id is a uint32 and must be greater than 0 (see +explanation below), or the P4Runtime +server must return an INVALID_ARGUMENT error. The replica instance ID is +also a uint32, and its value may not exceed the maximum allowed by the +target for the EgressInstance_t type (0 is allowed), or the server must also +return an INVALID_ARGUMENT error. The egress port (port field) in the +replica must be an SDN port and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (class_of_service field). This value must be a valid +value for the PSA ClassOfService_t type, which supports runtime translation +by default [29], or the server must return +INVALID_ARGUMENT. See PSA Metadata +Translation for more information. The +packet_length_bytes field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +packet_length_bytes field is 0 (default), no truncation on the clone will be +performed. +
  • +
  • MODIFY: Modify the attributes of a given clone session entry, indexed by the +given clone_session_id. Same restrictions as INSERT apply here. +
  • +
  • DELETE: Delete the clone session indexed by the given +clone_session_id. Other fields need not be provided for this operation. Any +packet with their clone_session_id metadata in the data plane set to the +deleted session_id will no longer be cloned. +
+ +

When reading a clone session, only session_id is considered. All other fields +in CloneSessionEntry are ignored. To perform a wildcard Read on all +configured clone session entries, the session_id field must be set to 0, its +default value. The session_id field can never be equal to 0 in a Write +RPC. If it does, the server must return an INVALID_ARGUMENT error. +

9.5.2.1. Valid Values for session_id
+

The PSA specification states that the valid data plane values for clone +session ids (CloneSessionId_t) range from 0 to the maximum value supported by +the target [29]. Note that unlike for multicast group +ids, 0 is a valid data plane value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special wildcard value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a session_id +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is not enabled, we effectively +“lose” one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (e.g. because the target supports a very +limited number of clone sessions), one can enable translation on +CloneSessionId_t and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id. +

9.6. ValueSetEntry

+

Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the parse_trill_types state. +

+
+
+
state parse_l2 {
+  @id(1) value_set<ETH_TYPE_BITWIDTH>(MAX_TRILL_TYPES) trill_types;
+  extract(hdr.ethernet);
+  select (hdr.ethernet.eth_type) {
+    ETH_TYPE_IPV4: parse_ipv4;
+    ETH_TYPE_IPV6: parse_ipv6;
+    trill_types:   parse_trill_types;
+    _:             reject;
+  }
+}
+

The corresponding entry in the P4Info for this Value Set is: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "trill_types"
+  }
+  match {
+    id: 1
+    bitwidth: <ETH_TYPE_BITWIDTH>
+    match_type: EXACT
+  }
+  size: <MAX_TRILL_TYPES>
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0x22f3 }
+      }
+      match {
+        field_id: 1
+        exact { value: 0x893b }
+      }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the parse_trill_types state. +

+

A ValueSetEntry entity update message has the following fields: +

+
    +
  • +

    value_set_id is the uint32 identifier of the Value Set instance, as +defined in P4Info. +

  • +
  • +

    members is a repeated field of type ValueSetMember. When “selecting” +against a Value Set, every member will be considered and if at least one +“matches”, the corresponding parser transition will be taken. Each +ValueSetMember contains a repeated field of FieldMatch messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a ValueSetMember if and only if +it matches all its FieldMatch messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. FieldMatch messages in a ValueSetEntry follow +the same rules as in a TableEntry. +

+ +

A ValueSetEntry may only be modified. If the update type is INSERT or +DELETE, the server must return an INVALID_ARGUMENT error. If the update type +is MODIFY, the server writes the members given in the repeated field to the +Value Set entry indexed by the given value_set_id. The maximum number of +matches must not exceed the maximum size given by the size field in P4Info of +the Value Set, otherwise the server must return a RESOURCE_EXHAUSTED error. To +empty a Value Set (i.e. restore it to its initial state), the P4Runtime client +can perform a MODIFY update with an empty members repeated field. +

+

To facilitate read-write symmetry, the server must +return an ALREADY_EXISTS error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set. +

+

See Appendix A.3 for a more complex Value Set example. +

9.7. RegisterEntry

+

The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The RegisterEntry P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations. +

+

RegisterEntry has the following fields: +

+
    +
  • +

    register_id, which identifies the PSA Register extern instance which is +being accessed by the client; the register_id is specified by the P4Info +message. +

  • +
  • +

    index, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the RegisterEntry message +used for the request. When an index is provided , the server must validate +its value, and return INVALID_ARGUMENT for a negative index or +OUT_OF_RANGE if the index exceeds the size of the register array. +

  • +
  • +

    data: the data to be written to the array (if RegisterEntry is part of a +WriteRequest message) or the data read from the array (if RegisterEntry is +part of a ReadResponse message). The data field is a P4Data message and +must match the format described by the type_spec field of the corresponding +Register entry in the P4Info, or the server must return an INVALID_ARGUMENT +error. +

+

9.8. DigestEntry

+

A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly. +

+

The DigestEntry P4Runtime entity is used to configure how the device must +generate digest messages. The DigestEntry Protobuf message is not used to +carry digest data, which is done on the StreamChannel bidirectional stream +using the DigestList (digest data sent by the target to the client) and +DigestListAck (digest data acknowledgments sent by the client to the target) +Protobuf messages. +

+

In this section, we refer to the data learned by a single data plane call to +Digest<T>::pack as a “digest message” and we use “digest list” to designate +the list of digest messages bundled by the P4Runtime service in a single +DigestList stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are “duplicate” if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are “distinct” +if they are not duplicate. +

+

DigestEntry has the following fields: +

+
    +
  • +

    digest_id, which identifies the PSA Digest extern instance which emitted the +data; the digest_id is determined by the P4Info message. +

  • +
  • +

    config, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +digest_id; these parameters are: +

    +
      +
    • max_timeout_ns: the maximum server buffering delay in nanoseconds for an +outstanding digest message. +
    • +
    • max_list_size: the maximum digest list size in number of digest +messages sent by the server to the client as a single DigestList +Protobuf message. +
    • +
    • ack_timeout_ns: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data. +
    +
+ +

Here is the significance of the different Update types for DigestEntry: +

+
    +
  • INSERT: Enable server generation of DigestList messages for given digest +instance and use provided configuration parameters. +
  • +
  • MODIFY: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance. +
  • +
  • DELETE: Disable server generation of DigestList messages for given digest +instance. +
+ +

A server should buffer digest messages until either: +

+
    +
  • max_timeout_ns time has passed since the first digest message was added to +the empty buffer, or +
  • +
  • max_list_size distinct digest messages have been received from the +data plane and added to the buffer +
+ +

At which point the server should, with best effort, generate a DigestList +stream message with the buffer contents and send it to the primary client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software. +

+

To avoid sending duplicate digest messages across different DigestList +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the primary client indicates that it has received the +digest list and acted on it. The server must keep a “cache” containing the set +of all digest messages that have been sent, but not acknowledged yet by the +primary client, up-to ack_timeout_ns in the past. The server must delete all +cache entries for a given digest list when they are at least ack_timeout_ns +old or when a matching DigestListAck message (i.e. with the same digest_id +and list_id fields as the DigestList message) is received. +

+

The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged DigestList messages. +

+

When max_timeout_ns is set to 0 and / or max_list_size is set to 1, the +server should, with best effort, generate a DigestList message for every +digest message generated by the data plane which is not already in the cache. If +ack_timeout_ns is set to 0, the cache must always be an empty set. If +max_list_size is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +max_timeout_ns configuration parameter. +

+

The P4Runtime server may empty the digest message cache in case of a client +status change. +

+

Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server: +

+
+
+
DigestStream stream;
+DigestCache cache;
+DigestBuffer buffers;
+
+// sends digest list when it is ready
+send_buffer(Id digest_id) {
+  buffer = buffers[digest_id];
+  stream.write(DigestList(buffer));
+  cache.merge(buffer);  // updates cache with new digest list
+  buffer.clear();
+}
+
+// callback which handles data plane digest messages from device
+handle_dataplane_digest(Digest msg) {
+  digest_id = msg.digest_id();
+  buffer = buffers[digest_id];
+  if (msg in cache OR msg in buffer) return;
+  buffer.enqueue(msg);
+  if (buffer.length() < max_list_size(digest_id)) return;
+  send_buffer(digest_id);
+}
+
+// callback which handles ack messages received on the stream
+handle_stream_ack(DigestListAck ack) {
+  // clear all cache entries matching the tuple (digest_id, list_id)
+  cache.erase( (ack.digest_id(), ack.list_id() )
+}
+
+// loop to enforce timeouts
+while (true) {
+  now = now();
+  // check for buffers that need to be sent
+  for ((digest_id, buffer) in buffers) {
+    if (now - buffer.first_enq_time() >= max_timeout_ns(digest_id))
+      send_buffer(buffer_id);
+  }
+  // check for expired entries in cache
+  for ((digest_id, list_id, sent_time) in cache) {
+    if (now - sent_time >= ack_timeout_ns(digest_id))
+      cache.erase( (digest_id, list_id) );
+  }
+  sleep(X);
+}

9.9. ExternEntry

+

This is used to support a P4 extern entity that is not part of PSA. It is +defined as: +

+
+
+
message ExternEntry {
+  uint32 extern_type_id = 1;
+  uint32 extern_id = 2;
+  google.protobuf.Any entry = 3;
+}
+

Each ExternEntry entity maps to an Extern message in the +P4Info and an ExternInstance message within that +message. The extern_type_id field must be equal to the one in +ExternEntry. The extern_id field must be equal to the ID included in the +preamble of the corresponding ExternInstance message. +

+

entry itself is embedded as an Any Protobuf message [37] to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on Extending P4Runtime for non-PSA +Architectures for more information. +

10. Error Reporting Messages

+

P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case. +

+

gRPC uses grpc::Status [38] to represent the status returned by an +RPC. It has 3 attributes: +

+
+
+
StatusCode code_;
+grpc::string error_message_;
+grpc::string binary_error_details_;
+

The code_ represents a canonical error [40] and describes the +overall RPC status. The error_message_ is a developer-facing error message, +which should be in English. The binary_error_details_ carries a serialized +google.rpc.Status message [33] message, which has 3 fields: +

+
+
+
int32 code = 1;  // see code.proto
+string message = 2;
+repeated google.protobuf.Any details = 3;
+

The code and message fields must be the same as code_ and error_message_ +fields from grpc::Status above. The details field is a list that consists of +p4.Error messages that carry error details for individual elements inside +batch-request RPCs (e.g. Write and Read). p4.Error includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices [40]. +

+

Figure 7 illustrates how these messages fit together. +

+
+

error-report +

+
+ +
Figure 7. P4Runtime Error Report Message Format
+

gRPC provides utility functions ExtractErrorDetails() and SetErrorDetails() +[39] to easily convert between grpc::Status and +google.rpc.Status. +

+

Please see sections on individual P4Runtime RPCs for details on how +grpc::Status is populated for reporting errors. +

+

Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on Stream Error +Reporting for more information. +

11. Atomicity of Individual Write and Read Operations

+

Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane apply +operation, and every single Write operation on a table that inserts, deletes, +or modifies one table entry, the apply operation should behave as if that +Write operation has not yet occurred, or as if the Write operation is +complete. The P4 program should never behave as if the Write operation is +partially complete. These guarantees also apply to extern instances: Read and +Write operations on extern entities must execute atomically relative to extern +data plane methods. +

+

The atomicity guarantees provided by P4Runtime for individual Read and Write +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification [28]. +

+

The P416 language introduces an @atomic annotation [18], to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the @atomic annotation for Write +operations, as well as non-wildcard Read operations, +relative to data plane execution. Consider the following P4 example written for +PSA: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024) r1;
+
+  apply {
+    // ...
+    @atomic {
+        Value_t v = r1.read((Index_t)1);
+        v = v + 1;
+        r1.write((Index_t)1, v);
+    }
+  }
+}
+

If a P4Runtime server is processing messages which write to Register r1 at +index 1, these writes must not happen between the data plane read and +write. +

+

Now let's consider the following example: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024, (Value_t)0 /* initial value */) r1;
+
+  apply {
+    @atomic {
+        r1.write((Index_t)1, (Value_t)100);
+        r1.write((Index_t)2, (Value_t)100);
+    }
+    @atomic {
+        r1.write((Index_t)1, (Value_t)200);
+        r1.write((Index_t)2, (Value_t)200);
+    }
+  }
+}
+

If a P4Runtime client issues a wildcard Read on Register r1, there is no +guarantee that r1[1] == r1[2] in the response, as the read for r1[1] may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for r1[2] may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read r1[1] and r1[2] separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +ReadRequest message) of individual read requests. Similar to a batch +ReadRequest, a wildcard read of a register can execute the reads of the +register array elements (r1[1], r1[2], ) in an arbitrary order relative +to each other. +

+

If the @atomic annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program. +

12. Write RPC

+

The Write RPC updates one or more P4 entities on the target. The request is +defined as follows: +

+
+
+
message WriteRequest {
+  uint64 device_id = 1;
+  string role = 6;
+  Uint128 election_id = 3;
+  repeated Update updates = 4;
+  enum Atomicity {
+    CONTINUE_ON_ERROR = 0;
+    ROLLBACK_ON_ERROR = 1;
+    DATAPLANE_ATOMIC = 2;
+  }
+  Atomicity atomicity = 5;
+}
+

The device_id uniquely identifies the target P4 device. The role and +election_id define the client role and election-id as described in the +Primary-Backup Arbitration and Controller +Replication +section. The server is expected to perform the following checks (in this order) +before processing the updates list: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the primary for (device_id, role) according to +the election_id value, the server must return a PERMISSION_DENIED error. +

  4. +
  5. +

    If the Write is attempted before a ForwardingPipelineConfig has been set, +the server must return a FAILED_PRECONDITION error. +

+ +

The updates field is a list of P4 entity updates to be applied. Each update is +defined as: +

+
+
+
message Update {
+  enum Type {
+    UNSPECIFIED = 0;
+    INSERT = 1;
+    MODIFY = 2;
+    DELETE = 3;
+  }
+  Type type = 1;
+  Entity entity = 2;
+}
+

This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a logical table (e.g. +CounterEntry) or an actual table (e.g. TableEntry) in the P4 data +plane. Each entity in the container is uniquely identified by its key. Please +refer to the P4 Entity Messages section for details on +what parts of the entity specification make up the key for each P4 entity. +

+

An update can be one of the following types: +

+
    +
  • +

    INSERT: Inserts the given P4 entity in the entity container. +The entity field always specifies the full state of the P4 entity. +If the entity already exists, an ALREADY_EXISTS error is returned, and +the existing entity remains unchanged. If the entity is malformed, an +INVALID_ARGUMENT error is usually returned (unless a more specific error +code applies [40]). If the entity cannot be inserted because the +container is already full, a RESOURCE_EXHAUSTED error is returned. +

  • +
  • +

    MODIFY: Modifies the P4 entity to its new specified state. This uses +assign or full-snapshot semantics, i.e. the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an INVALID_ARGUMENT error is usually returned (unless a +more specific error code applies [40]). If the entity does not +exist, a NOT_FOUND error is returned. +

  • +
  • +

    DELETE: Deletes the specified P4 entity. If the entity does not exist, a +NOT_FOUND error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored. +

+ +

If an update is not allowed under the given controller role, the server must +return a PERMISSION_DENIED error for this update. +

12.1. Batching and Ordering of Updates

+

P4Runtime supports batching of Write operations. The list of updates in a +WriteRequest is referred to as a batch. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of TableEntry entities). +

+

The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +WriteRequests can also be processed interleaved and/or in parallel. +However, the processing of requests must be strictly serializable. That +is, given a history $S$ of WriteRequests including the responses to those +requests, there must exist an order $L$ for all updates in $S$, such that: +

+
    +
  1. All updates from the same write request must appear as a contiguous +subsequence in $L$, but the order within that subsequence can be arbitrary. +
  2. +
  3. For two updates $u_1$ and $u_2$, if the write request containing $u_1$ +completed before the write request of $u_2$ was sent, then $u_1$ must appear +before $u_2$ in $L$. +
  4. +
  5. Executing all updates in $L$ sequentially must yield the same response for +every update as in $S$. +
  6. +
  7. The observable state of the switch after $S$ (e.g., through the Read RPC) +is identical to the one obtained by sequentially executing $L$. +
+ +

The Write RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the Write RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (e.g. inserting an ActionProfileMember +followed by pointing a TableEntry to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding Write RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate Write calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each Write call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one. +

12.2. Batch Atomicity

+

A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the Atomicity +enum. A P4Runtime server is required to support only the modes marked as +Required below: +

+
    +
  • +

    Required: CONTINUE_ON_ERROR: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that see each of +these intermediate stages. +

  • +
  • +

    Optional: ROLLBACK_ON_ERROR: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is all-or-none, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that see each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure. +

    +

    If a P4Runtime server does not support this option at all, an +UNIMPLEMENTED error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (e.g. it is +more straightforward to implement batches that contain only INSERT +operations, vs. those that contain DELETE operations), an +UNIMPLEMENTED error is returned when the batch cannot be executed +in a data plane-atomic way. +

  • +
  • +

    Optional: DATAPLANE_ATOMIC: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +transaction. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane's table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table. +

    +

    If a P4Runtime server does not support this option at all, an UNIMPLEMENTED +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an UNIMPLEMENTED error is returned when the batch +cannot be executed in a data plane-atomic way. +

+ +

There is no expectation that a given client must always use the same Atomicity +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use DATAPLANE_ATOMIC at one time and default behavior +(CONTINUE_ON_ERROR) at other times. +

12.3. Error Reporting

+

Please see section Error Reporting Messages for +information on error reporting messages and guidelines. P4Runtime server will +populate grpc::Status as follows: +

+
    +
  1. +

    If all batch updates succeeded, set grpc::Status::code_ to OK and do not +populate any other field. +

  2. +
  3. +

    If an error is encountered before even trying to attempt individual batch +updates, set grpc::Status::code_ that best describes that RPC-wide +error. For example, use UNAVAILABLE if the P4Runtime service is not yet +ready to handle requests. Set error_message_ to describe the issue. Do not +set error_details in this case. +

  4. +
  5. +

    Otherwise, if one or more updates in the batch (WriteRequest.updates) +failed, set grpc::Status::code_ to UNKNOWN. For example, one update in +the batch may fail with RESOURCE_EXHAUSTED and another with +INVALID_ARGUMENT. A p4.Error message is used to capture the status of +each and every update in the batch. The number of p4.Error messages packed +into google.rpc.Status.details field should therefore always match the +number of updates in the WriteRequest, and the order of +p4.Error messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +p4.Error should set the code to OK and omit other fields. +

+ +
+
+
# Example of a grpc::Status returned for a Write RPC with a batch of 3 updates.
+# The first and third updates encountered an error, while the second update
+# succeeded.
+code_ = 2  # UNKNOWN
+error_message_ = "Write failure."
+binary_error_details {
+  code: 2  # UNKNOWN
+  message: "Write failure."
+  details {
+    canonical_code: 8  # RESOURCE_EXHAUSTED
+    message: "Table is full."
+    space: "targetX-psa-vendorY"
+    code: 500  # ERR_TABLE_FULL
+  }
+  details {
+    canonical_code: 0  # OK
+  }
+  details {
+    canonical_code: 6  # ALREADY_EXISTS
+    message: "Entity already exists."
+    space: "targetX-psa-vendorY"
+    code: 600  # ERR_ENTITY_ALREADY_EXISTS
+  }
+}

13. Read RPC

+

The Read RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as: +

+
+
+
message ReadRequest {
+  uint64 device_id = 1;
+  string role = 3;
+  repeated Entity entities = 2;
+}
+

The device_id uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +NOT_FOUND error. +If the Read is attempted before ForwardingPipelineConfig has been set, the +server must return a FAILED_PRECONDITION error. +The role field acts as a filter, restricting the reported entities based on +the role to which the entity belongs. +The entities repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server. +

+

Since ReadRequests do not mutate any state on the switch, they do not +require an election_id, and they do not require the presence of an open +StreamChannel between the server and client. +

+

The Read response consists of a sequence of messages (a gRPC stream) with +each message defined as: +

+
+
+
message ReadResponse {
+  repeated Entity entities = 1;
+}
+

The entities repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the Finish() method on the stream object +[12]). +

13.1. Nomenclature

+
+
request
+
An element of the p4.ReadRequest.entities repeated field. +
+
batch
+
Refers to the p4.ReadRequest.entities repeated field.
+

Each request acts as a query filter for that entity type. If a request fully +specifies the entity key, the Read operation should retrieve a single P4 +entity. Please refer to the P4 Entity Messages section +for details on what parts of the entity specification make up the entity key. +

13.2. Wildcard Reads

+

P4Runtime allows wildcard read of P4 entities. A request may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the P4 Entity Messages section for details on +what parts of the entity can be wildcarded in a given request. +

+

For example, in a request of type CounterEntry: +

+
    +
  • A default counter_id (0) implies a request to read all counter-entries for +all indirect counters. +
  • +
  • A particular (non-default) counter_id in conjunction with index unset +implies a request to read all counter-entries for the given indirect counter +ID. +
+ +

To read the entire forwarding state for a given device, the P4Runtime client can +generate the following ReadRequest: +

+
+
+
device_id: <ID>
+entities {
+  extern_entry { }  # read all extern instances for all supported extern types
+  table_entry { }  # read all table entries for all tables
+  action_profile_member { }  # read all members for all action profiles
+  action_profile_group { }  # read all groups for all action profiles
+  ...
+}
+

The entity oneof field in the Entity message must always be set, or the +server must return an INVALID_ARGUMENT error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty Entity message in the ReadRequest. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the entity oneof [25]. +

13.3. Batch Processing

+

A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type request +appears only once in the batch. +

+

A P4Runtime server will process the batch as follows: +

+
    +
  1. +

    Lock state (preventing new writes) and validate each request in the batch: +

    +
      +
    1. +

      If it is a valid request, perform the read; +

      +
        +
      1. If the read was successful, return the entities read in +ReadResponse stream. +
      2. +
      3. If the read failed (exception / critical-error), prepare a p4.Error +with code set to INTERNAL. +
      +
    2. +
    3. +

      If the request is invalid (invalid-argument, not-supported, etc.), +prepare a p4.Error with relevant canonical code to capture the error. +

    +
  2. +
  3. +

    Unlock the state (allowing new writes); +

  4. +
  5. +

    Close the ReadResponse stream and return a grpc::Status as follows: +

    +
      +
    1. +

      If no errors were encountered, set code to OK and do not populate any +other field. +

    2. +
    3. +

      Otherwise, the overall code should be set to UNKNOWN. See section +Error Reporting Messages for information +on error reporting messages and guidelines. Assemble a list of p4.Error +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +google.rpc.Status.details field. This behavior also matches Write +RPC. +

    +
+

13.3.1. Example

+

If a client asked to read {a,b,c,d} and b and d requests didn't +validate, the server will return entities corresponding to a and c, followed +by a status {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} in the +details field. +

+

The P4Runtime server is not required to perform any optimization (e.g. merge two +requests in the batch if one is a subset of other). As a result of this, it +is possible for the ReadResponse to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging. +

+

There is no requirement that each request in the batch will correspond to one +ReadResponse message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit. +

+

A P4Runtime server must be prepared to handle multiple concurrent Read RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (e.g. in a single-threaded architecture), it may choose to serialize +Read RPC processing. +

13.4. Parallelism of Read and Write Requests

+

A P4Runtime server may be implemented to serve at most one +ReadRequest or WriteRequest message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so. +

+

For example, imagine a client that wanted to use WriteRequest +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +WriteRequest messages with only a few updates to an ActionSelector +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +WriteRequest batch currently being processed, but it will not +complete for a significant amount of time. +

+

The restrictions on which a client may rely are: +

+
    +
  • The processing of any two WriteRequest messages W1 and W2 must +result in the same state as if one of them was completed before the +other began. +
  • +
  • For any WriteRequest W and any ReadRequest R, R must +return results consistent with a state where W has completed +processing, or W has not yet begun processing. +
+ +

For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a WriteRequest message it acquired a write lock for each stateful +object affected by the WriteRequest, and before starting the +processing of a ReadRequest message it acquired a read lock for each +stateful object accessed by the ReadRequest, such an implementation +meets all of the requirements above. +

+

It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, e.g. if the server somehow determined that two +WriteRequest messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly. +

14. SetForwardingPipelineConfig RPC

+

A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the SetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message SetForwardingPipelineConfigRequest {
+  enum Action {
+    UNSPECIFIED = 0;
+    VERIFY = 1;
+    VERIFY_AND_SAVE = 2;
+    VERIFY_AND_COMMIT = 3;
+    COMMIT = 4;
+    RECONCILE_AND_COMMIT = 5;
+  }
+  uint64 device_id = 1;
+  string role = 6;
+  Uint128 election_id = 3;
+  Action action = 4;
+  ForwardingPipelineConfig config = 5;
+}
+

The server is expected to perform the following checks (in this order) +before performing the required action: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the primary for (device_id, role) according to +the election_id value, the server must return a PERMISSION_DENIED error. +

+ +

The action is the type of configuration action requested, it can be one of: +

+
    +
  • +

    VERIFY: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an INVALID_ARGUMENT +error if config is not provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_SAVE: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent Read / Write requests must refer to fields in the new +config. Returns an INVALID_ARGUMENT error if the forwarding config is not +provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_COMMIT: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an INVALID_ARGUMENT error if the forwarding config is not provided or if the +provided config cannot be realized. +

  • +
  • +

    COMMIT: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a NOT_FOUND error if no saved config +is found, i.e. if no VERIFY_AND_SAVE action preceded this one. Returns an +INVALID_ARGUMENT error if a config is provided with this message. +

  • +
  • +

    RECONCILE_AND_COMMIT: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an UNIMPLEMENTED error. For targets that support this option, an +INVALID_ARGUMENT error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target. +

+ +

The config field is a message of type ForwardingPipelineConfig that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(e.g. generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the Forwarding-Pipeline +Configuration section for details. +

+

A P4Runtime server running on a non-programmable device may not +support SetForwardingPipelineConfig (e.g. the forwarding-pipeline +config is part of the device's software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +UNIMPLEMENTED error. +

15. GetForwardingPipelineConfig RPC

+

The forwarding-pipeline configuration of the target can be retrieved by invoking +the GetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message GetForwardingPipelineConfigRequest {
+  enum ResponseType {
+    ALL = 0;
+    COOKIE_ONLY = 1;
+    P4INFO_AND_COOKIE = 2;
+    DEVICE_CONFIG_AND_COOKIE = 3;
+  }
+  uint64 device_id = 1;
+  ResponseType response_type = 2;
+}
+

The device_id uniquely identifies the target P4 device. A NOT_FOUND error is +returned if the device_id is not recognized by the P4Runtime server. +

+

The response_type is used to specify which fields to populate in the response, +its value can be one of: +

+
    +
  • +

    ALL: returns a ForwardingPipelineConfig with all fields +set as stored by the target. This is the default behaviour if the +response_type field is not set. +

  • +
  • +

    COOKIE_ONLY: reply by setting only the cookie field in the +ForwardingPipelineConfig, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message. +

  • +
  • +

    P4INFO_AND_COOKIE: reply by setting the p4info and cookie fields. +

  • +
  • +

    DEVICE_CONFIG_AND_COOKIE: reply by setting the p4_device_config and +cookie fields. +

+ +

The response contains the ForwardingPipelineConfig for the specified device: +

+
+
+
message GetForwardingPipelineConfigResponse {
+  ForwardingPipelineConfig config = 1;
+}
+

If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level config field will be unset in the response. Examples are +(i) a server that only allows configuration via SetForwardingPipelineConfig +but this RPC hasn't been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn't yet occurred. +

+

Once a forwarding-pipeline config is installed on the device (either via +SetForwardingPipelineConfig or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +config.p4_device_config will be empty / unset in the response, even if +response_type in the request was set to ALL. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the SetForwardingPipelineConfig RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +SetForwardingPipelineConfig, the value of config.cookie will be unset. +

+

If a P4Runtime server supports both SetForwardingPipelineConfig as well as +returning the p4_device_config, there should be read-write symmetry between +SetForwardingPipelineConfig and GetForwardingPipelineConfig RPCs. +

16. P4Runtime Stream Messages

16.1. Packet I/O

+

P4Runtime supports controller packet-in and packet-out by means of PacketIn +and PacketOut stream messages, respectively. +

+

PacketIn messages are sent by the P4Runtime server to the client. Conversely, +PacketOut messages are sent by the client to the server. Any PacketOut +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a StreamMessageResponse message with the error field set to +report the error to the client. See the section on Stream Error +Reporting for more information on error. +

+

As introduced in the ControllerPacketMetadata +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with @controller_header. The expected metadata is described +in the P4Info using the ControllerPacketMetadata messages. +

+

Both PacketIn and PacketOut stream messages share the same fields and are +defined as follows: +

+
+
+
// Packet sent from the controller to the switch.
+message PacketOut {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+// Packet sent from the switch to the controller.
+message PacketIn {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+message PacketMetadata {
+  // This refers to Metadata.id coming from P4Info ControllerPacketMetadata.
+  uint32 metadata_id = 1;
+  bytes value = 2;
+}
+
    +
  • +

    payload is used to carry the full packet content, including the headers. +

  • +
  • +

    metadata is a repeated field of PacketMetadata messages used to carry the +arbitrary controller metadata. When a P4Runtime client (or server) +generates a PacketOut (or PacketIn) message, it must populate precisely +one metadata field for each metadata field in the +ControllerPacketMetadata for packet-out (or packet-in) in the P4Info, such +that the two metadata.id fields match. +The size and value of each PacketIn/PacketOut metadata entry needs +to be consistent with what is specified in the corresponding P4Info +ControllerPacketMetadata.Metadata message with the same id, in the +following sense: +

    +
      +
    • If ControllerPacketMetadata.Metadata.bitwidth is set, or if +ControllerPacketMetadata.Metadata.type_name is set and +P4NewTypeSpec.translated_type.sdn_bitwidth is set in the P4NewTypeSpec +for the type name, then PacketMetadata.value must be a binary string of +the specified bit width conforming to the Bytestrings +requirements. +
    • +
    • If ControllerPacketMetadata.Metadata.type_name is set and +P4NewTypeSpec.translated_type.sdn_string is set in the +P4NewTypeSpec message for the specified type name, then +PacketMetadata.value can be an arbitrary SDN string subject to the +@p4runtime_translation. +If a metadata field +does not match the P4Info specification, the server must drop the PacketOut +message and may generate a StreamMessageResponse message with the error +field set to report the error to the client which issued the PacketOut. See +the section on Stream Error Reporting for more +information on error. +
    +
+

16.2. Client Arbitration Update

+

P4Runtime's client arbitration mechanism ensures that only the current primary +can modify state on the switch, and that the election_id is monotonically +increasing. For example, the switch must finish all previous write operations +before before selecting a different primary, and must only accept write requests +from the current primary. +

+

As explained earlier in this document, the controller uses the StreamChannel +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via Write RPC), +it needs to start a controller session and become a “primary”. To do so, the +controller first opens a bidirectional stream channel to the server via +StreamChannel for each device and sends a StreamMessageRequest message. The +controller populates the MasterArbitrationUpdate field in this message using +its role and election_id and the device_id of the device, as explained +in detail in the Client Arbitration and Controller +Replication +section. For any given (device_id, role), the P4Runtime server keeps track +of the highest election_id that it has ever received. If a controller's +election_id is equal to the highest election_id that the server has ever +received, that controller is the primary. All other controllers are backups. +Note that it is possible that all controllers are backups, and that there is no +primary. There can be at most one primary, because for any given +(device_id, role), each connected controller has a unique election_id. +

+

This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest election_id after such a restart. +However, across a full restart, the election_id must be +reset. In fact, a full restart is the only way to reset the election_id. +

+

The MasterArbitrationUpdate message is defined as follows: +

+
+
+
message MasterArbitrationUpdate {
+  uint64 device_id = 1;
+  // The role for which the primary client is being arbitrated. For use-cases
+  // where multiple roles are not needed, the controller can leave this unset,
+  // implying default role and full pipeline access.
+  Role role = 2;
+  // The stream RPC with the highest election_id is the primary. The 'primary'
+  // controller instance populates this with its latest election_id. Switch
+  // populates with the highest election ID it has received from all connected
+  // controllers.
+  Uint128 election_id = 3;
+  // Switch populates this with OK for the client that is the primary, and
+  // with an error status for all other connected clients (at every primary
+  // client change). The controller does not populate this field.
+  .google.rpc.Status status = 4;
+}
+
+message Role {
+  // Uniquely identifies this role.
+  string name = 3;
+  // Describes the role configuration, i.e. what operations, P4 entities,
+  // behaviors, etc. are in the scope of a given role. If config is not set
+  // (default case), it implies all P4 objects and control behaviors are in
+  // scope, i.e. full pipeline access. The format of this message is
+  // out-of-scope of P4Runtime.
+  .google.protobuf.Any config = 2;
+}
+

Note that the status field in the MasterArbitrationUpdate message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a StreamMessageResponse message back to the controller, in which +it populates the MasterArbitrationUpdate message using the device_id, +role, and election_id it previously received from the controller. The server +also populates the status field in the MasterArbitrationUpdate according to +the rules in an earlier section. +

16.2.1. Unset Election ID

+

The sender need not specify an election_id. If the election_id is +unset, the sender's election_id is considered lower than any +election_id, and the sender will thus never become primary. This way, a +controller can choose to be a standby controller, in order to avoid primary +“flapping” (if a standby controller connects to the switch shortly before the +actual primary controller, therefore becoming primary temporarily). +

+

Note that +

+
election_id : { high: 0 low: 0 }
+

is different from an unset election_id, see +the section on default-valued fields. +

16.3. Digest Messages

+

See the DigestEntry section. +

16.4. Table Idle Timeout Notification

+

When a table supports idle timeout (as per the P4Info message), the primary +client can specify a TTL value for each entry in the table (see +Idle-timeout section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an IdleTimeoutNotification message on the +StreamChannel bidirectional stream to the primary client. The primary client +can then take the action of its choice, most likely remove the idle entry. +

+

The IdleTimeoutNotification Protobuf message has the following fields: +

+
    +
  • +

    timestamp: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server's local clock. +

  • +
  • +

    table_entry: a repeated field of entries which have expired. Each individual +entry is identified by a single TableEntry message. For each TableEntry, +the key fields (table_id, match and priority) must be set, along with +the controller_metadata field, the metadata field, and the +idle_timeout_ns field. Other fields may be set by the server but should be +ignored by the client. +

+ +

Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +IdleTimeoutNotification message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an IdleTimeoutNotification +message with an empty table_entry repeated field. +

+

After generating an idle notification, the P4Runtime server must “reset” the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the primary client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle. +

+

Here is a reasonable pseudo-code implementation for idle timeout for table +entries: +

+
+
+
IdleTimeoutStream stream;
+
+scanning_interval = 10ms;
+
+while (true) {
+  // iterate over all tables which support idle timeout
+  for (table in tables) {
+    if (!table.idle_timeout_supported) continue;
+    // we coalesce all idle notifications for the same table in one
+    // message
+    IdleTimeoutNotification msg;
+    // read time_since_last_hit from device
+    entries = device.load_table_entries_from_hw(table);
+    for (entry in entries) {
+      if (entry.idle_timeout == 0) continue;  // no TTL
+      if (entry.time_since_last_hit < entry.idle_timeout) continue;
+      msg.table_entry_add(entry);
+      entry.reset_time_since_last_hit();
+    }
+    if (msg.table_entry_size() == 0) continue;  // no notifications
+    msg.set_timestamp(now());
+    stream.write(msg);
+  }
+  sleep(scanning_interval);
+}

16.5. Architecture-Specific Notifications

+

P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on StreamChannel, by including an Any Protobuf field [37] +named other in both StreamMessageRequest and StreamMessageResponse. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the PSA Digest +extern. See section on Extending P4Runtime for non-PSA +Architectures for more information. +

16.6. Stream Error Reporting

+

The P4Runtime server can asynchronously report errors which occur when +processing StreamMessageRequest messages, using the error message field (of +type StreamError) in StreamMessageResponse. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature. +

+

The StreamError message has the following fields: +

+
    +
  • canonical_code, which must be set to the appropriate canonical error code +[40]. +
  • +
  • message, an optional developer-facing error message describing the error. +
  • +
  • space and code, which are optional and can be used by vendors to provide +additional details on the error. code is a numeric error code drawn from a +vendor's chosen error space. +
  • +
  • details, which is a Protobuf oneof used to help the client identify which +StreamMessageRequest triggered the error. The server is required to set the +appropriate field in the oneof so that the client can identify which type +of stream message is responsible for the error (packet_out, +digest_list_ack or other), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid PacketOut message from the +client, the packet_out field (of type PacketOutError) should be set in +the details oneof, and the server may additionally set the packet_out +field in the PacketOutError sub-message (by copying it from the invalid +PacketOut message received on the stream channel) so that the client can +know exactly what packet-out triggered the error. +
+ +

The appropriate canonical error code [40] should be used when +populating the canonical_code field. For example: +

+
    +
  • if a controller is not allowed to send a PacketOut message under its +current role definition, the code should be set to PERMISSION_DENIED. +
  • +
  • if the metadata repeated field in PacketOut does not match the P4Info +definition, the code should be set to INVALID_ARGUMENT. It may be useful +for the server to set the packet_out field in this case, so that the client +can find out which set of metadata fields triggered the error. +
  • +
  • if the digest_id field in DigestListAck does not match any Digest entry +in P4Info, the code should be set to INVALID_ARGUMENT. +
+ +

The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, e.g. because of a +burst of PacketIn messages. +

+

Note that client arbitration errors are never reported using the StreamError +message. Invalid MasterArbitrationUpdate messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section 5.3. +

16.6.1. Examples of StreamError Messages

+
    +
  • +

    Malformed packet-out metadata. If the server receives a PacketOut +message with a metadata field with id 7 which is not included in the P4Info +ControllerPacketMetadata message for “packet_out”, the server may send the +following StreamMessageResponse back to the client: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Unknown metadata field id 7."
    + packet_out {
    +   # copied from the PacketOut message received from the client
    +   packet_out {
    +     payload: ...
    +     metadata {
    +       id: 7
    +       name: "I_should_not_be_here"
    +       bitwidth: 32
    +     }
    +     # more metadata
    +   }
    + }
    +}
  • +
  • +

    Packet-out which exceeds the MTU. If the server receives a PacketOut +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following StreamMessageResponse: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Packet exceeds the MTU for port."
    + space: "targetX-psa-vendor1"
    + code: 123  # MTU_EXCEEDED
    + packet_out {
    +   # we do not set the packet_out field as it does not provide any
    +   # extra information to the client
    + }
    +}
+

17. Capabilities RPC

+

The Capabilities RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the CapabilitiesRequest message is empty and the CapabilitiesResponse +message only includes the p4runtime_api_version string field. This field must +be set to the full semantic version string [32] corresponding to the +version of the P4Runtime API implemented by the server, e.g. “1.1.0-rc.1”. +

+

Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three atomicity +modes for WriteRequest batches, two of them being +optional. In the future we may decide to leverage the CapabilitiesResponse +message to enable the server to report to the client which subset of these +atomicity modes is supported. +

+

The semantic version string included in CapabilitiesResponse can be used by +the client to determine which exact feature set is implemented by the server, +since minor releases may introduce new +functionality. However, because the Capabilities RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (i.e. an UNIMPLEMENTED error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0). +

18. Portability Considerations

18.1. PSA Metadata Translation

+

The Portable Switch Architecture (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +[29]. For such metadata, a translation between the controller's +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the @p4runtime_translation annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture. +

+
+

psa-metadata-translation +

+
+ +
Figure 8. P4Runtime Metadata Translation for the Portable Switch Architecture
+

Figure 8 illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller's 32 bit port +numbers to a target's 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch. +

18.1.1. Translation of Port Numbers

+

In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller's space and the PSA device's space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +user-defined P4 types, namely PortId_t and +PortIdInHeader_t, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in psa.p4 for +the PSA device in Switch 1. +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type bit<9> PortId_t;
+@p4runtime_translation("p4.org/psa/v1/PortIdInHeader_t", 32)
+type bit<32> PortIdInHeader_t;
+

The first argument to the @p4runtime_translation annotation is a URI that +indicates to the P4Runtime server which numerical mapping provided by the +out-of-band switch configuration mechanism to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports). +

+

An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows: +

+
+
+
enum SdnPort {
+  SDN_PORT_UNKNOWN = 0;
+
+  // SDN ports are numbered starting from 1.
+  SDN_PORT_MIN = 1;
+
+  // The maximum value of an SDN port (physical or logical).
+  SDN_PORT_MAX = 0xfffffeff;
+
+  // Reserved SDN port numbers (0xfffffff0 - 0xffffffff)
+
+  SDN_PORT_RECIRCULATE = 0xfffffffa;
+  SDN_PORT_CPU = 0xfffffffd;
+}
+

The switch config will map SDN_PORT_RECIRCULATE and SDN_PORT_CPU as well +as any SDN port number corresponding to a “regular” front-panel port to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation. +

+

The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs. +

18.1.2. Translation of Packet-IO Header Fields

+

Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  PortIdInHeader_t egress_port;
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  PortIdInHeader_t ingress_port;
+}
+

The header-level annotation @controller_header is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (egress_port) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI first argument to the @p4runtime_translation +annotation). Any subsequent reference to the egress_port field in the +data plane will use the translated value. PortIdInHeader_t is used in the +header definition instead of PortId_t to guarantee byte-aligned headers in +case this is required by the target. +

+

A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target's PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the ingress_port field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller. +

18.1.3. Translation of Match Fields

+

Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table's match key as shown in the example below: +

+
+
+
table t {
+  key = {
+    istd.ingress_port: exact;  // PSA standard metadata ingress port
+  }
+  actions = {
+    drop;
+  }
+}
+

Table t has an exact match on PSA standard metadata ingress port +(istd.ingress_port). Since the field is of type PortId_t, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in t from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table t is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values. +

+

Note that it may be infeasible to translate the value-mask pair for ternary +matches: LPM, TERNARY or RANGE match kinds. The P4Runtime server may +require that for these match kinds the port match be either de facto “exact” +(0xffffffff mask for TERNARY, prefix-length of 32 for LPM, or same low and +high bounds for RANGE) or “don't care”. +

18.1.4. Translation of Action Parameters

+

PortId_t type parameters can be part of a P4 action definition as shown in the +example below: +

+
+
+
action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+}
+
+table t {
+  key = {
+    hdr.h.f: exact;
+  }
+  actions = {
+    a;
+  }
+}
+

The controller may write entries in table t with action a to set the egress +port as shown in the P4 code above. The action parameter p is of type +PortId_t, which leads to a 32-bit bitwidth for p being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device. +

18.1.5. Port Translation for PSA Extern APIs

+

The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch_port +field is of type bytes to carry the SDN representation of the port being +watched. The P4Runtime server will translate the given watch port into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device. +

+

The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type bytes to carry the SDN +representation of the port(s). The P4Runtime server will translate these SDN +ports to device-specific port numbers for multicasting and cloning in the data +plane. +

18.1.6. Using Port as an Index to a Register, Indirect Counter or Indirect Meter

+

P4Runtime supports using a translated value (PortId_t or any other translated +type for which the underlying built-in type is bit<W>) as an index to a +register, indirect counter, or indirect meter. +

+
+
+
Counter<bit<32> /* counter entry type */, PortId_t /* index type */>(
+  32w1024, PSA_CounterType_t.PACKETS) counter;
+action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+  counter.count(p);
+}
+

This P4 Counter declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
counters {
+  preamble {
+    id: 0x12000001
+    name: "counter"
+  }
+  spec {
+    unit: PACKETS
+  }
+  index_type_name {
+    name: "PortId_t"
+  }
+}
+

The controller may read and write counter values from indexed counter counter +using SDN port numbers as indices, and not device-specific port numbers. The +index_type_name field in the P4Info message is a signal to the P4Runtime +server that translation is required. +

19. P4Runtime Versioning

+

P4Runtime follows the Google guidelines for versioning cloud APIs +[8]. We use a MAJOR.MINOR.PATCH style version number scheme and +we increment the: +

+
    +
  • MAJOR version when we make incompatible API changes, +
  • +
  • MINOR version when we add functionality in a backwards-compatible manner, +
  • +
  • PATCH version when we make backwards-compatible bug fixes. +
+ +

The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is p4.v1 and the package +name for P4Info is p4.config.v1. Even though p4 and p4.config are two +different Protobuf packages, p4 depends on p4.config and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence. +

+

As recommended in [8], we may consider using pre-GA release +suffixes (such as alpha or beta) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1). +

+

Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner. [9] describes +what constitute a backwards-compatible change. We expect MAJOR version bumps +to be a rare event. +

+

Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor + patch version numbers in future releases. +

+

All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository [19] and the version label follows +semantic versioning rules [32]. +

20. Extending P4Runtime for non-PSA Architectures

+

P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place. +

+

When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names: +

+
    +
  • p4/[organization]/arch/config/<major version>/p4info.proto +
  • +
  • p4/[organization]/arch/<major version>/p4runtime.proto +
+ +

We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they “extend”. +

+

For the remainder of this section, we will refer to these two files as +p4info-ext and p4runtime-ext respectively. +

20.1. Extending P4Runtime for Architecture-Specific Externs

+

Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both p4info-ext and +p4runtime-ext. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example: +

+
+
+
// T must be a bit<W> type, it indicates the width of each counter cell
+extern MyNewPacketCounter<T> {
+  counter(bit<32> size);
+  increment(in bit<32> index);
+}

20.1.1. Extending the P4Info message

+
    +
  • Id prefixes 0x81 through 0xfe are reserved for architecture-specific +externs. It is recommended that p4info-ext include a P4Ids message based +on the one in p4info.proto that the P4 compiler can refer to when assigning +IDs to each extern instance. +
+ +
+
+
message P4Ids {
+  enum Prefix {
+    UNSPECIFIED = 0;
+    MY_NEW_PACKET_COUNTER = 0x81;
+  }
+}
+
    +
  • p4info-ext should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +p4.config.v1.ExternInstance message as the info +field, which is of type Any [37]. +
+ +
+
+
message MyNewPacketCounter {
+  // corresponds to the T type parameter in the P4 extern definition
+  p4.config.v1.P4DataTypeSpec type_spec = 1;
+  // constructor argument
+  int64 size = 2;
+}

20.1.2. Extending the P4Runtime Service

+

Just like p4info-ext, p4runtime-ext should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an ExternEntry message generated by the +P4Runtime client. +

+

Here is a possible Protobuf message for our MyNewPacketCounter P4 extern: +

+
+
+
// This message enables reading / writing data to the counter at the provided
+// index
+message MyNewPacketCounter {
+  int64 index = 1;
+  p4.v1.P4Data data = 2;
+}
+

P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an Any Protobuf field [37] named other +in both p4.v1.StreamMessageRequest and +p4.v1.StreamMessageResponse. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in p4runtime-ext and embed instances of these messages in +p4.v1.StreamMessageRequest and p4.v1.StreamMessageResponse as appropriate. +

20.2. Architecture-Specific Table Extensions

20.2.1. New Match Types

+

An architecture may introduce new table match types [14]. P4Runtime +accounts for this by providing the following hooks: +

+
    +
  • +

    The match field in p4.config.v1.MatchField (p4info.proto) is a oneof +which can be either one of the default match types (EXACT, LPM, TERNARY, +RANGE, or OPTIONAL) or an architecture-specific match type encoded as a +string. +

  • +
  • +

    The field_match_type field in p4.v1.FieldMatch (p4runtime.proto) is a +oneof which includes an Any Protobuf message [37] field +(other). p4info-ext should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in p4.v1.FieldMatch as the +other field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info. +

+

20.2.2. New Table Properties

+

An architecture may introduce additional table properties +[36]. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +p4.config.v1.Table message includes the other_properties Any Protobuf +field [37]. At the moment, there is not any mechanism to extend the +p4.v1.TableEntry message based on the value of architecture-specific table +properties, but we may include on in future versions of the API. +

21. Known Limitations of Current P4Runtime Version

+
    +
  • +

    FieldMatch, action Param, and controller packet metadata fields only +support unsigned bitstrings, i.e. values of one of the following types (not +the more general P4Data): +

    +
      +
    • bit<W> +
    • +
    • bool. Note that as far as the P4Info message contents and +thus controller software is concerned, such fields of type bool +will be indistinguishable from those that have been declared with +type bit<1>. P4Runtime server software will automatically +perform any conversion needed between the type bit<1> values in +P4Runtime messages and the data plane representation. +
    • +
    • an enum with underlying type bit<W> +
    • +
    • a type or typedef with an underlying type that is one of the above (or +in general a “chain” of type and/or typedef that eventually ends with +one of the types above) +
    +
  • +
  • +

    Support for PSA Random & Timestamp externs is postponed to a future minor +version update. +

  • +
  • +

    P4Info does not include information about which of a table's actions execute +which direct resource(s). +

  • +
  • +

    The default action for indirect match tables is restricted to a const +NoAction known at compile-time. +

  • +
  • +

    There is no mechanism for changing the value of the psa_empty_group_action +table property at runtime. +

  • +
  • +

    There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor + +patch version numbers. +

+

A. Appendix

A.1. Revision History

A.1.1. Changes in v1.4.0

+
    +
  • Add a Type field to the MeterSpec message allowing users to restrict the +type of meters that can be used for a table and a new eburst field to the +MeterConfig message for use with one of the new MeterSpec types. +
  • +
  • Add a PlatformProperties message specifying desired underlying platform +properties to the PkgInfo message. +
  • +
  • Add a metadata field to the MulticastGroupEntry message. +
  • +
  • Clarify that the limitation on supported types for FieldMatch, action +Param, and Packet IO metadata fields (no support for signed integers, with +type int<W>) apply to all minor revisions of P4Runtime v1, not just to +P4Runtime v1.0. +
  • +
  • Fix invalid action_profile_id in the One Shot Action Selector Programming +example. +
  • +
  • Specify Read behavior in the absence of a P4Info (ForwardingPipelineConfig +not set yet). +
  • +
  • Clarify that for updates of type INSERT, error codes other than +INVALID_ARGUMENT can be returned when applicable. +
  • +
  • Enable C++ Arena Allocation [4] by default in p4runtime.proto. +
  • +
  • Add support for string role identifiers and deprecate integer role +identifiers. +
  • +
  • Add support for specifying a role in ReadRequest messages: if present, only +entities belonging to this specific role are returned. +
  • +
  • Specify that max_group_size must be less than or equal to size for Action +Selectors. +
  • +
  • Simplify specification for arbitration updates for which there is no change to +the controller's election_id; in particular, a “no-op” arbitration update +from a primary controller (the controller already was, and remains, the +primary controller) is essentially treated the same way as an arbitration +update which leads to the election of a new primary controller. +
  • +
  • Enable P4Runtime servers to provide per-color counter values when direct or +indirect meter entries are read. +
  • +
  • Clarify that the (device_id, role, election_id) 3-tuples are only unique +for live controllers. +
  • +
  • Add a selector_size_semantics field to the ActionProfile message +in P4Info. +
+

A.1.2. Changes in v1.3.0

+
    +
  • Add IANA assigned TCP port, 9559, to P4Runtime server discussion. +
  • +
  • Move “Security considerations” section to P4Runtime server discussion. +
  • +
  • Deprecate watch field (int32) in favor of watch_port (bytes). This allows +using the watch port feature with the p4runtime_translation feature. +
  • +
  • Replace master, slave, master arbitration with more inclusive language: +primary, backup, and client arbitration +
  • +
  • Clarify that source locations for annotations are optional in the P4Info +message. +
+

A.1.3. Changes in v1.2.0

+
    +
  • Add new OPTIONAL match kind. At the moment, OPTIONAL is only supported by +the v1model architecture [44], and not by PSA. It will eventually be +included in the core P4 language. +
  • +
  • Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists. +
  • +
  • Add a new metadata field of type bytes to TableEntry. This is more +flexible than the now deprecated controller_metadata field. +
  • +
  • Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +@id annotation. +
  • +
  • Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature. +
  • +
  • Support using string as the controller type in the @p4runtime_translation +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type. +
  • +
  • Add optional P4 source locations to both structured and unstructured +annotations. +
+

A.1.4. Changes in v1.1.0

+
    +
  • Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously. +
  • +
  • Add error field to stream messages sent by the server. +
  • +
  • Add Capabilities RPC to query the P4Runtime API version implemented by the +server. +
  • +
  • Support wildcard reads for multicast groups and clone sessions. +
  • +
  • Support for modifying direct resources of const tables. +
  • +
  • Support P4 user-defined types for Packet IO metadata fields. +
  • +
  • Clarify consistency requirements for Write and Read RPCs. +
  • +
  • Add Appendix providing implementation advice for avoiding common pitfalls: + +
      +
    • advice on setting gRPC Metadata Maximum Size +
    • +
    • advice on setting gRPC Server Maximum Receive Message Size +
  • +
  • Clarify limitations on supported types for FieldMatch, action Param, and +Packet IO metadata fields. +
  • +
  • Clarify that reading entire forwarding state with empty entity is not +supported. +
  • +
  • Document that @p4runtime_translation need only be supported when applied to +type declarations in P4. +
+

A.2. P4 Annotations

+

Table 7 lists P416 annotations introduced primarily for +the purpose of adding features for the P4Runtime API. +

+
+ + + + + + + + + + + + + + + + +
Annotation Description
@brief See section 6.1.3
@controller_header See section 6.4.6
@description See section 6.1.3
@id See section 6.3
@max_group_size See sections 6.4.3, 9.2.2
@selector_size_semantics See section 6.4.3
@max_member_weight See section 6.4.3
@two_rate_three_color See section 6.4.5
@single_rate_three_color See section 6.4.5
@single_rate_two_color See section 6.4.5
@pkginfo See section 6.2.1
@platform_property See section 6.2.1
@p4runtime_translation See sections 8.4.6, 18.1.1
+
+ +
Table 7. P4 annotations introduced by P4Runtime

A.3. A More Complex Value Set Example

+

This section includes a more complex Value Set example, with multiple matches of +different kinds. +

+
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+

This P4 Value Set declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

A P4Runtime client can set the membership for this Value Set with WriteRequest +messages similar to this one: +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xac }
+      }
+      # match for field_id 2 is missing => don't care match
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xdc }
+      }
+      match {
+        field_id: 2
+        ternary { value: 0x88 mask: 8f }
+      }
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+  }
+}

A.4. Guidelines for Implementations

+

This section contains practical advice for implementing P4Runtime clients and +servers. +

A.4.1. gRPC Metadata Maximum Size

+

In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the grpc.max_metadata_size gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the Write P4Runtime RPC. The Write RPC +returns an individual error for every item in a batch (see Section +12), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +RESOURCE_EXHAUSTED error, without any of the individual errors. +

+

To fix this problem, one can set the grpc.max_metadata_size option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it's +limit, as only the receiving side's limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every p4.Error, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +8192 + MAX_UPDATES_PER_WRITE * 100 bytes of metadata. +

+

For example, in C++, one can create a client channel as follows: +

+
+
+
const int MAX_UPDATES_PER_WRITE = 100;
+::grpc::ChannelArguments arguments;
+arguments.SetInt(GRPC_ARG_MAX_METADATA_SIZE, 8192 + MAX_UPDATES_PER_WRITE*100);
+return grpc::CreateCustomChannel(address, credentials, arguments);

A.4.2. gRPC Server Maximum Receive Message Size

+

At the time of writing, the default maximum receive message size in gRPC is 4MB + while the default maximum send message size is unlimited. This can be a +problem for the SetForwardingPipelineConfig RPC, since for some targets the +binary p4_device_config can exceed 4MB, in which case by default the P4Runtime +server would return an INVALID_ARGUMENT error. To a lesser extent, this may +affect the Write RPC as well, in case of extremely large batches. +

+

To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of p4_device_config for their target(s). This can be done by +setting the grpc.max_receive_message_length when building the gRPC server. +

+

For example, in C++, one can set the maximum receive message size as follows: +

+
+
+
const int MAX_RECEIVE_MESSAGE_SIZE = 128 * 1024 * 1024;  // 128MB
+::grpc::ServerBuilder server_builder;
+builder.AddListeningPort(/*...*/);
+builder.RegisterService(/*...*/);  // register P4Runtime service
+builder.SetMaxReceiveMessageSize(MAX_RECEIVE_MESSAGE_SIZE);
+builder.BuildAndStart();
+

On the client side, we recommend that P4Runtime clients do not use Write +batches larger than the default maximum receive message size (4MB) in case +the server did not deem necessary to increase the default value , unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB). +

A.5. P4Runtime Entries files

+

The open source P4 compiler p4c [15] implements an option to +generate an “entries file”, i.e. a file that contains all table +entries declared via the entries table property within the program. +

+

An example P416 program that can be used to demonstrate this +capability is table-entries-ternary-bmv2.p4 [16]: +

+
git clone https://github.com/p4lang/p4c
+cd p4c/testdata/p4_16_samples
+mkdir tmp
+p4test --arch v1model \
+    --p4runtime-files tmp/p4info.txt \
+    --p4runtime-entries-files tmp/entries.txt \
+    table-entries-ternary-bmv2.p4
+

You can replace the .txt suffix of the file name tmp/entries.txt +in the example command above with .json or .bin. The .bin +format is a binary P4Runtime API protobuf message format. The .txt +format is the text encoding of the same Protobuf messages. +

+

Target devices are not required to use this file. For example, if a +target has a P4 compiler back end that encodes all of the necessary +details from the P4 source program, including the entries of tables, +in a target-specific binary format, then that target might have no +reason to generate these entries files. +

+

Some target devices might choose to generate entries files, and also +to require doing so in order to have a correct implementation. For +example, a target runtime implementation might take a target-specific +binary format for the compiled P4 program that does not contain any +data describing the entries of tables, plus the entries file +generated by p4c, and use the entries file to load the initial +entries of tables into the device. +

+

The format of the entries file is a single WriteRequest message +containing one Update sub-message per entry in the P4 source program +defined via an entries table property. All Update sub-messages +have type equal to INSERT, and entity is a TableEntry message +containing the data for one table entry. +

+

Note that if a P4Runtime client attempted to send a WriteRequest to +a P4Runtime server with the contents of the entries file, the server +must return an error for each entry that has is_const true, as +described in Section 9.1. +

+

References

+
+ +
[2]“A Single Rate Three Color Marker.” https://​tools.​ietf.​org/​html/​rfc2697.
+
[3]“A Two Rate Three Color Marker.” https://​tools.​ietf.​org/​html/​rfc2698.
+ + + + + +
[9]“Google Cloud APIs Versioning - Backwards-Compatibility.” https://​cloud.​google.​com/​apis/​design/​versioning#​backwards_​compatibility.
+ +
[11]“gRPC Main Site.” https://​grpc.​io.
+ + + +
[15]“P4_16 Reference Compiler.” https://​github.​com/​p4lang/​p4c.
+ + + +
[19]“p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” https://​github.​com/​p4lang/​p4runtime.
+
[20]“p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.” https://​github.​com/​p4lang/​PI.
+ + +
[23]“Portable NIC Architecture Specification (v0.7).” https://​p4.​org/​p4-​spec/​docs/​PNA-​v0.​7.​html.
+
[24]“Portable Switch Architecture Specification (v1.1.0).” https://​p4.​org/​p4-​spec/​docs/​PSA-​v1.​1.​0.​html.
+ + + + + + + +
[32]“Semantic Versioning.” https://​semver.​org/​.
+ + + + + + + + +
[41]“The OpenConfig Project.” http://​openconfig.​net.
+ +
[43]“The Stratum Project.” https://​stratumproject.​org/​.
+ +
+
+
+ +
+

1.an enum type used as a field in a header must specify a +underlying type and representation for enum elements. +

+ + + diff --git a/spec/main/P4Runtime-Spec.log b/spec/main/P4Runtime-Spec.log new file mode 100644 index 00000000..22b79fef --- /dev/null +++ b/spec/main/P4Runtime-Spec.log @@ -0,0 +1,16059 @@ +This is XeTeX, Version 3.14159265-2.6-0.99992 (TeX Live 2015/Debian) (preloaded format=xelatex 2018.8.17) 16 SEP 2024 18:50 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**build/P4Runtime-Spec.tex +(./build/P4Runtime-Spec.tex +LaTeX2e <2016/02/01> +Babel <3.9q> and hyphenation patterns for 81 language(s) loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2014/09/29 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo +File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@section=\count80 +\c@subsection=\count81 +\c@subsubsection=\count82 +\c@paragraph=\count83 +\c@subparagraph=\count84 +\c@figure=\count85 +\c@table=\count86 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) (build/madoko2.sty (/usr/share/texlive/texmf-dist/tex/latex/colortbl/colortbl.sty +Package: colortbl 2012/02/13 v1.0a Color table columns (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty +Package: array 2014/10/28 v2.4c Tabular extension package (FMi) +\col@sep=\dimen103 +\extrarowheight=\dimen104 +\NC@list=\toks14 +\extratabsurround=\skip43 +\backup@length=\skip44 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty +Package: color 2016/01/03 v1.1b Standard LaTeX Color (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package color Info: Driver file: xetex.def on input line 143. +(/usr/share/texlive/texmf-dist/tex/xelatex/xetex-def/xetex.def +File: xetex.def 2015/09/11 v4.06 LaTeX color/graphics driver for XeTeX (TeX Live/RRM/JK) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +))) +\everycr=\toks15 +\minrowclearance=\skip45 +) (/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: xetex.def on input line 225. +LaTeX Info: Redefining \color on input line 702. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) (build/options.sty +Package: options 2015/03/01, Daan Leijen, Provides convenient path-value (or key-value) options +(/usr/share/texlive/texmf-dist/tex/latex/etoolbox/etoolbox.sty +Package: etoolbox 2015/08/02 v2.2a e-TeX tools for LaTeX (JAW) +\etb@tempcnta=\count87 +) +\opt@nesting=\count88 +\opt@idx=\count89 +\opt@choiceord=\count90 +) (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty +Package: iftex 2013/04/04 v0.2 Provides if(tex) conditional for PDFTeX, XeTeX, and LuaTeX +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2014/10/28 v1.0g Enhanced LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks16 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2016/01/03 v1.0q Standard LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2016/01/03 v1.10 sin cos tan (DPC) +) (/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg +File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live +) +Package graphics Info: Driver file: xetex.def on input line 95. +) +\Gin@req@height=\dimen105 +\Gin@req@width=\dimen106 +) (build/longfbox.sty +Package: longfbox 2015/12/01, Daan Leijen, Provides long fbox that can break over pages +(build/longbox.sty +Package: longbox 2015/12/01, Daan Leijen, Provides basic longbox that can break over pages +(/usr/share/texlive/texmf-dist/tex/latex/mdwtools/footnote.sty +Package: footnote 1997/01/28 1.13 Save footnotes around boxes +\fn@notes=\box26 +\fn@width=\dimen107 +) +\lb@prevdepth=\skip46 +\lb@freevspace=\skip47 +\lb@headbox=\box27 +\lb@savebox=\box28 +\lb@mainbox=\box29 +\lb@usevbox=\count91 +\lb@width=\skip48 +\lb@height=\skip49 +\lb@skiptop=\skip50 +\lb@skipright=\skip51 +\lb@skipbottom=\skip52 +\lb@skipleft=\skip53 +\lb@skipbreaktop=\skip54 +\lb@skipbreakbottom=\skip55 +\lb@outerwidth=\skip56 +\lb@extrasplit=\skip57 +\lb@textalign=\count92 +\lb@baseline=\count93 +\lb@neededvspace=\skip58 +\lb@splitheight=\skip59 +\lb@insurance=\skip60 +\/longbox/@part-height=\skip61 +\/longbox/@part-width=\skip62 +\/longbox/@part-depth=\skip63 +\/longbox/@content-box-height=\skip64 +\/longbox/@content-box-width=\skip65 +\/longbox/@content-box-depth=\skip66 +\/longbox/@breakat-previous=\skip67 +\/longbox/@lower=\skip68 +\/longbox/split-minimum=\skip69 +\/longbox/split-badness=\skip70 +\/longbox/raise=\skip71 +\/longbox/height=\skip72 +\/longbox/width=\skip73 +\/longbox/outer-height=\skip74 +\/longbox/outer-width=\skip75 +\/longbox/skip-top=\skip76 +\/longbox/skip-right=\skip77 +\/longbox/skip-bottom=\skip78 +\/longbox/skip-left=\skip79 +\/longbox/skip-break-bottom=\skip80 +\/longbox/skip-break-top=\skip81 +) (/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.sty +Package: pict2e 2016/02/05 v0.3b Improved picture commands (HjG,RN,JT) +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.cfg +File: pict2e.cfg 2016/02/05 v0.1u pict2e configuration for teTeX/TeXLive +) +Package pict2e Info: Driver file: xetex.def on input line 119. +Package pict2e Info: Driver file for pict2e: p2e-xetex.def on input line 121. +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/p2e-xetex.def +File: p2e-xetex.def 2016/02/05 v0.1u Driver-dependant file (RN,HjG,JT) +) +\pIIe@GRAPH=\toks17 +\@arclen=\dimen108 +\@arcrad=\dimen109 +\@tempdimd=\dimen110 +) (build/ellipse.sty +Package: ellipse 2004/11/05 v1.0 .dtx ellipse file +) +\fbox@oct=\count94 +\fbox@quad=\count95 +\fbox@diaq=\count96 +\fbox@sign=\count97 +\fbox@anglestart=\skip82 +\fbox@angleend=\skip83 +\fbox@dash=\skip84 +\fbox@dashskip=\skip85 +\fbox@anglecur=\skip86 +\fbox@dashangle=\skip87 +\fbox@dashskipangle=\skip88 +\fbox@delta=\skip89 +\fbox@from=\skip90 +\fbox@to=\skip91 +\/fbox/padding-top=\skip92 +\/fbox/padding-right=\skip93 +\/fbox/padding-bottom=\skip94 +\/fbox/padding-left=\skip95 +\/fbox/padding-break-top=\skip96 +\/fbox/padding-break-bottom=\skip97 +\/fbox/margin-top=\skip98 +\/fbox/margin-right=\skip99 +\/fbox/margin-bottom=\skip100 +\/fbox/margin-left=\skip101 +\/fbox/margin-break-top=\skip102 +\/fbox/margin-break-bottom=\skip103 +\/fbox/border-top-width=\skip104 +\/fbox/border-right-width=\skip105 +\/fbox/border-bottom-width=\skip106 +\/fbox/border-left-width=\skip107 +\/fbox/border-break-top-width=\skip108 +\/fbox/border-break-bottom-width=\skip109 +\/fbox/@lower=\skip110 +\/fbox/@padding-box-height=\skip111 +\/fbox/@padding-box-depth=\skip112 +\/fbox/@padding-box-width=\skip113 +\/fbox/@border-box-width=\skip114 +\/fbox/@border-box-height=\skip115 +\/fbox/@border-box-depth=\skip116 +\/fbox/@border-top-left-radius-x=\skip117 +\/fbox/@border-top-right-radius-x=\skip118 +\/fbox/@border-bottom-left-radius-x=\skip119 +\/fbox/@border-bottom-right-radius-x=\skip120 +\/fbox/@border-top-left-radius-y=\skip121 +\/fbox/@border-top-right-radius-y=\skip122 +\/fbox/@border-bottom-left-radius-y=\skip123 +\/fbox/@border-bottom-right-radius-y=\skip124 +\/fbox/@border-top-left-ix=\skip125 +\/fbox/@border-top-left-iy=\skip126 +\/fbox/@border-top-right-ix=\skip127 +\/fbox/@border-top-right-iy=\skip128 +\/fbox/@border-bottom-left-ix=\skip129 +\/fbox/@border-bottom-left-iy=\skip130 +\/fbox/@border-bottom-right-ix=\skip131 +\/fbox/@border-bottom-right-iy=\skip132 +\/fbox/@border-top-left-phi=\skip133 +\/fbox/@border-top-right-phi=\skip134 +\/fbox/@border-bottom-left-phi=\skip135 +\/fbox/@border-bottom-right-phi=\skip136 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2016/03/03 v2.15a AMS math features +\@mathmargin=\skip137 +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2000/06/29 v2.01 AMS text +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen111 +)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen112 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 1999/12/14 v2.01 operator names +) +\inf@bad=\count98 +LaTeX Info: Redefining \frac on input line 199. +\uproot@=\count99 +\leftroot@=\count100 +LaTeX Info: Redefining \overline on input line 297. +\classnum@=\count101 +\DOTSCASE@=\count102 +LaTeX Info: Redefining \ldots on input line 394. +LaTeX Info: Redefining \dots on input line 397. +LaTeX Info: Redefining \cdots on input line 518. +\Mathstrutbox@=\box30 +\strutbox@=\box31 +\big@size=\dimen113 +LaTeX Font Info: Redeclaring font encoding OML on input line 630. +LaTeX Font Info: Redeclaring font encoding OMS on input line 631. +\macc@depth=\count103 +\c@MaxMatrixCols=\count104 +\dotsspace@=\muskip10 +\c@parentequation=\count105 +\dspbrk@lvl=\count106 +\tag@help=\toks19 +\row@=\count107 +\column@=\count108 +\maxfields@=\count109 +\andhelp@=\toks20 +\eqnshift@=\dimen114 +\alignsep@=\dimen115 +\tagshift@=\dimen116 +\tagwidth@=\dimen117 +\totwidth@=\dimen118 +\lineht@=\dimen119 +\@envbody=\toks21 +\multlinegap=\skip138 +\multlinetaggap=\skip139 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2735. +LaTeX Info: Redefining \] on input line 2736. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +) (/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/stmaryrd.sty +Package: stmaryrd 1994/03/03 St Mary's Road symbol package +\symstmry=\mathgroup6 +LaTeX Font Info: Overwriting symbol font `stmry' in version `bold' +(Font) U/stmry/m/n --> U/stmry/b/n on input line 89. +) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty +Package: textcomp 2005/09/27 v1.99g Standard LaTeX package +Package textcomp Info: Sub-encoding information: +(textcomp) 5 = only ISO-Adobe without \textcurrency +(textcomp) 4 = 5 + \texteuro +(textcomp) 3 = 4 + \textohm +(textcomp) 2 = 3 + \textestimated + \textcurrency +(textcomp) 1 = TS1 - \textcircled - \t +(textcomp) 0 = TS1 (full) +(textcomp) Font families with sub-encoding setting implement +(textcomp) only a restricted character set as indicated. +(textcomp) Family '?' is the default used for unknown fonts. +(textcomp) See the documentation for details. +Package textcomp Info: Setting ? sub-encoding to TS1/1 on input line 79. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +) +LaTeX Info: Redefining \oldstylenums on input line 334. +Package textcomp Info: Setting cmr sub-encoding to TS1/0 on input line 349. +Package textcomp Info: Setting cmss sub-encoding to TS1/0 on input line 350. +Package textcomp Info: Setting cmtt sub-encoding to TS1/0 on input line 351. +Package textcomp Info: Setting cmvtt sub-encoding to TS1/0 on input line 352. +Package textcomp Info: Setting cmbr sub-encoding to TS1/0 on input line 353. +Package textcomp Info: Setting cmtl sub-encoding to TS1/0 on input line 354. +Package textcomp Info: Setting ccr sub-encoding to TS1/0 on input line 355. +Package textcomp Info: Setting ptm sub-encoding to TS1/4 on input line 356. +Package textcomp Info: Setting pcr sub-encoding to TS1/4 on input line 357. +Package textcomp Info: Setting phv sub-encoding to TS1/4 on input line 358. +Package textcomp Info: Setting ppl sub-encoding to TS1/3 on input line 359. +Package textcomp Info: Setting pag sub-encoding to TS1/4 on input line 360. +Package textcomp Info: Setting pbk sub-encoding to TS1/4 on input line 361. +Package textcomp Info: Setting pnc sub-encoding to TS1/4 on input line 362. +Package textcomp Info: Setting pzc sub-encoding to TS1/4 on input line 363. +Package textcomp Info: Setting bch sub-encoding to TS1/4 on input line 364. +Package textcomp Info: Setting put sub-encoding to TS1/5 on input line 365. +Package textcomp Info: Setting uag sub-encoding to TS1/5 on input line 366. +Package textcomp Info: Setting ugq sub-encoding to TS1/5 on input line 367. +Package textcomp Info: Setting ul8 sub-encoding to TS1/4 on input line 368. +Package textcomp Info: Setting ul9 sub-encoding to TS1/4 on input line 369. +Package textcomp Info: Setting augie sub-encoding to TS1/5 on input line 370. +Package textcomp Info: Setting dayrom sub-encoding to TS1/3 on input line 371. +Package textcomp Info: Setting dayroms sub-encoding to TS1/3 on input line 372. +Package textcomp Info: Setting pxr sub-encoding to TS1/0 on input line 373. +Package textcomp Info: Setting pxss sub-encoding to TS1/0 on input line 374. +Package textcomp Info: Setting pxtt sub-encoding to TS1/0 on input line 375. +Package textcomp Info: Setting txr sub-encoding to TS1/0 on input line 376. +Package textcomp Info: Setting txss sub-encoding to TS1/0 on input line 377. +Package textcomp Info: Setting txtt sub-encoding to TS1/0 on input line 378. +Package textcomp Info: Setting lmr sub-encoding to TS1/0 on input line 379. +Package textcomp Info: Setting lmdh sub-encoding to TS1/0 on input line 380. +Package textcomp Info: Setting lmss sub-encoding to TS1/0 on input line 381. +Package textcomp Info: Setting lmssq sub-encoding to TS1/0 on input line 382. +Package textcomp Info: Setting lmvtt sub-encoding to TS1/0 on input line 383. +Package textcomp Info: Setting lmtt sub-encoding to TS1/0 on input line 384. +Package textcomp Info: Setting qhv sub-encoding to TS1/0 on input line 385. +Package textcomp Info: Setting qag sub-encoding to TS1/0 on input line 386. +Package textcomp Info: Setting qbk sub-encoding to TS1/0 on input line 387. +Package textcomp Info: Setting qcr sub-encoding to TS1/0 on input line 388. +Package textcomp Info: Setting qcs sub-encoding to TS1/0 on input line 389. +Package textcomp Info: Setting qpl sub-encoding to TS1/0 on input line 390. +Package textcomp Info: Setting qtm sub-encoding to TS1/0 on input line 391. +Package textcomp Info: Setting qzc sub-encoding to TS1/0 on input line 392. +Package textcomp Info: Setting qhvc sub-encoding to TS1/0 on input line 393. +Package textcomp Info: Setting futs sub-encoding to TS1/4 on input line 394. +Package textcomp Info: Setting futx sub-encoding to TS1/4 on input line 395. +Package textcomp Info: Setting futj sub-encoding to TS1/4 on input line 396. +Package textcomp Info: Setting hlh sub-encoding to TS1/3 on input line 397. +Package textcomp Info: Setting hls sub-encoding to TS1/3 on input line 398. +Package textcomp Info: Setting hlst sub-encoding to TS1/3 on input line 399. +Package textcomp Info: Setting hlct sub-encoding to TS1/5 on input line 400. +Package textcomp Info: Setting hlx sub-encoding to TS1/5 on input line 401. +Package textcomp Info: Setting hlce sub-encoding to TS1/5 on input line 402. +Package textcomp Info: Setting hlcn sub-encoding to TS1/5 on input line 403. +Package textcomp Info: Setting hlcw sub-encoding to TS1/5 on input line 404. +Package textcomp Info: Setting hlcf sub-encoding to TS1/5 on input line 405. +Package textcomp Info: Setting pplx sub-encoding to TS1/3 on input line 406. +Package textcomp Info: Setting pplj sub-encoding to TS1/3 on input line 407. +Package textcomp Info: Setting ptmx sub-encoding to TS1/4 on input line 408. +Package textcomp Info: Setting ptmj sub-encoding to TS1/4 on input line 409. +) (/usr/share/texlive/texmf-dist/tex/latex/psnfss/pifont.sty +Package: pifont 2005/04/12 PSNFSS-v9.2a Pi font support (SPQR) +LaTeX Font Info: Try loading font information for U+pzd on input line 63. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upzd.fd +File: upzd.fd 2001/06/04 font definitions for U/pzd. +) +LaTeX Font Info: Try loading font information for U+psy on input line 64. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upsy.fd +File: upsy.fd 2001/06/04 font definitions for U/psy. +)) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2012/11/06 v6.83m Hypertext links for LaTeX +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO) +Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO) +Package hobsub Info: Skipping package `infwarerr' (already loaded). +Package hobsub Info: Skipping package `ltxcmds' (already loaded). +Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO) +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is not detected. +Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) +Package etexcmds Info: Could not find \expanded. +(etexcmds) That can mean that you are not using pdfTeX 1.50 or +(etexcmds) that some package has redefined \expanded. +(etexcmds) In the latter case, load this package earlier. +Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) +Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO) +Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: pdfTeX >= 1.30 not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode not found. +Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO) +Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO) +Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO) +Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO) +Package: xcolor-patch 2011/01/30 xcolor patch +Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO) +Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO) +Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO) +Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2011/03/04 v1.3 Hooks for auxiliary files (HO) +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) +) +\@linkdim=\dimen120 +\Hy@linkcounter=\count110 +\Hy@pagecounter=\count111 +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count112 +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Hyper figures OFF on input line 4443. +Package hyperref Info: Link nesting OFF on input line 4448. +Package hyperref Info: Hyper index ON on input line 4451. +Package hyperref Info: Plain pages OFF on input line 4458. +Package hyperref Info: Backreferencing OFF on input line 4463. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4688. +\c@Hy@tempcnt=\count113 +(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip11 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 5041. +\XeTeXLinkMargin=\dimen121 +\Fld@menulength=\count114 +\Field@Width=\dimen122 +\Fld@charsize=\dimen123 +Package hyperref Info: Hyper figures OFF on input line 6295. +Package hyperref Info: Link nesting OFF on input line 6300. +Package hyperref Info: Hyper index ON on input line 6303. +Package hyperref Info: backreferencing OFF on input line 6310. +Package hyperref Info: Link coloring OFF on input line 6315. +Package hyperref Info: Link coloring with OCG OFF on input line 6320. +Package hyperref Info: PDF/A mode OFF on input line 6325. +LaTeX Info: Redefining \ref on input line 6365. +LaTeX Info: Redefining \pageref on input line 6369. +\Hy@abspage=\count115 +\c@Item=\count116 +\c@Hfootnote=\count117 +) + +Package hyperref Message: Driver (autodetected): hxetex. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hxetex.def +File: hxetex.def 2012/11/06 v6.83m Hyperref driver for XeTeX +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def +File: puenc.def 2012/11/06 v6.83m Hyperref: PDF Unicode definition (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/stringenc.sty +Package: stringenc 2011/12/02 v1.10 Convert strings between diff. encodings (HO) +) +\pdfm@box=\box32 +\c@Hy@AnnotLevel=\count118 +\HyField@AnnotCount=\count119 +\Fld@listcount=\count120 +\c@bookmark@seq@number=\count121 +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO) +Package rerunfilecheck Info: Feature \pdfmdfivesum is not available +(rerunfilecheck) (e.g. pdfTeX or LuaTeX with package `pdftexcmds'). +(rerunfilecheck) Therefore file contents cannot be checked efficiently +(rerunfilecheck) and the loading of the package is aborted. +) +\Hy@SectionHShift=\skip140 +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bookmark.sty +Package: bookmark 2011/12/02 v1.24 PDF bookmarks (HO) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bkm-dvipdfm.def +File: bkm-dvipdfm.def 2011/12/02 v1.24 bookmark driver for dvipdfm (HO) +\BKM@id=\count122 +)) (/usr/share/texlive/texmf-dist/tex/latex/booktabs/booktabs.sty +Package: booktabs 2005/04/14 v1.61803 publication quality tables +\heavyrulewidth=\dimen124 +\lightrulewidth=\dimen125 +\cmidrulewidth=\dimen126 +\belowrulesep=\dimen127 +\belowbottomsep=\dimen128 +\aboverulesep=\dimen129 +\abovetopsep=\dimen130 +\cmidrulesep=\dimen131 +\cmidrulekern=\dimen132 +\defaultaddspace=\dimen133 +\@cmidla=\count123 +\@cmidlb=\count124 +\@aboverulesep=\dimen134 +\@belowrulesep=\dimen135 +\@thisruleclass=\count125 +\@lastruleclass=\count126 +\@thisrulewidth=\dimen136 +) (/usr/share/texlive/texmf-dist/tex/latex/tools/longtable.sty +Package: longtable 2014/10/28 v4.11 Multi-page Table package (DPC) +\LTleft=\skip141 +\LTright=\skip142 +\LTpre=\skip143 +\LTpost=\skip144 +\LTchunksize=\count127 +\LTcapwidth=\dimen137 +\LT@head=\box33 +\LT@firsthead=\box34 +\LT@foot=\box35 +\LT@lastfoot=\box36 +\LT@cols=\count128 +\LT@rows=\count129 +\c@LT@tables=\count130 +\c@LT@chunks=\count131 +\LT@p@ftn=\toks23 +) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Package: anyfontsize 2007/11/22 anyfontsize.sty by pts +) (/usr/share/texlive/texmf-dist/tex/latex/enumitem/enumitem.sty +Package: enumitem 2011/09/28 v3.5.2 Customized lists +\labelindent=\skip145 +\enit@outerparindent=\dimen138 +\enit@toks=\toks24 +\enit@inbox=\box37 +\enitdp@description=\count132 +) (/usr/share/texlive/texmf-dist/tex/latex/wrapfig/wrapfig.sty +\wrapoverhang=\dimen139 +\WF@size=\dimen140 +\c@WF@wrappedlines=\count133 +\WF@box=\box38 +\WF@everypar=\toks25 +Package: wrapfig 2003/01/31 v 3.6 +) (/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.sty (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty +Package: expl3 2016/01/19 v6377 L3 programming layer (loader) +(/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3-code.tex +Package: expl3 2016/01/19 v6377 L3 programming layer (code) +L3 Module: l3bootstrap 2016/01/01 v6339 L3 Bootstrap code +L3 Module: l3names 2015/12/21 v6328 L3 Namespace for primitives +L3 Module: l3basics 2015/11/22 v6315 L3 Basic definitions +L3 Module: l3expan 2015/09/10 v5983 L3 Argument expansion +L3 Module: l3tl 2015/09/29 v6121 L3 Token lists +L3 Module: l3str 2016/01/03 v6357 L3 Strings +L3 Module: l3seq 2015/08/05 v5777 L3 Sequences and stacks +L3 Module: l3int 2016/01/05 v6366 L3 Integers +\c_max_int=\count134 +\l_tmpa_int=\count135 +\l_tmpb_int=\count136 +\g_tmpa_int=\count137 +\g_tmpb_int=\count138 +L3 Module: l3quark 2015/08/17 v5855 L3 Quarks +L3 Module: l3prg 2015/11/01 v6216 L3 Control structures +\g__prg_map_int=\count139 +L3 Module: l3clist 2015/09/02 v5901 L3 Comma separated lists +L3 Module: l3token 2015/11/11 v6249 L3 Experimental token manipulation +L3 Module: l3prop 2016/01/05 v6366 L3 Property lists +L3 Module: l3msg 2015/09/28 v6113 L3 Messages +L3 Module: l3file 2015/12/03 v6317 L3 File and I/O operations +\l_iow_line_count_int=\count140 +\l__iow_target_count_int=\count141 +\l__iow_current_line_int=\count142 +\l__iow_current_word_int=\count143 +\l__iow_current_indentation_int=\count144 +L3 Module: l3skip 2016/01/05 v6366 L3 Dimensions and skips +\c_zero_dim=\dimen141 +\c_max_dim=\dimen142 +\l_tmpa_dim=\dimen143 +\l_tmpb_dim=\dimen144 +\g_tmpa_dim=\dimen145 +\g_tmpb_dim=\dimen146 +\c_zero_skip=\skip146 +\c_max_skip=\skip147 +\l_tmpa_skip=\skip148 +\l_tmpb_skip=\skip149 +\g_tmpa_skip=\skip150 +\g_tmpb_skip=\skip151 +\c_zero_muskip=\muskip12 +\c_max_muskip=\muskip13 +\l_tmpa_muskip=\muskip14 +\l_tmpb_muskip=\muskip15 +\g_tmpa_muskip=\muskip16 +\g_tmpb_muskip=\muskip17 +L3 Module: l3keys 2015/11/17 v6284 L3 Key-value interfaces +\g__keyval_level_int=\count145 +\l_keys_choice_int=\count146 +L3 Module: l3fp 2015/08/25 v5890 L3 Floating points +\c__fp_leading_shift_int=\count147 +\c__fp_middle_shift_int=\count148 +\c__fp_trailing_shift_int=\count149 +\c__fp_big_leading_shift_int=\count150 +\c__fp_big_middle_shift_int=\count151 +\c__fp_big_trailing_shift_int=\count152 +\c__fp_Bigg_leading_shift_int=\count153 +\c__fp_Bigg_middle_shift_int=\count154 +\c__fp_Bigg_trailing_shift_int=\count155 +L3 Module: l3box 2015/08/09 v5822 L3 Experimental boxes +\c_empty_box=\box39 +\l_tmpa_box=\box40 +\l_tmpb_box=\box41 +\g_tmpa_box=\box42 +\g_tmpb_box=\box43 +L3 Module: l3coffins 2015/08/06 v5789 L3 Coffin code layer +\l__coffin_internal_box=\box44 +\l__coffin_internal_dim=\dimen147 +\l__coffin_offset_x_dim=\dimen148 +\l__coffin_offset_y_dim=\dimen149 +\l__coffin_x_dim=\dimen150 +\l__coffin_y_dim=\dimen151 +\l__coffin_x_prime_dim=\dimen152 +\l__coffin_y_prime_dim=\dimen153 +\c_empty_coffin=\box45 +\l__coffin_aligned_coffin=\box46 +\l__coffin_aligned_internal_coffin=\box47 +\l_tmpa_coffin=\box48 +\l_tmpb_coffin=\box49 +\l__coffin_display_coffin=\box50 +\l__coffin_display_coord_coffin=\box51 +\l__coffin_display_pole_coffin=\box52 +\l__coffin_display_offset_dim=\dimen154 +\l__coffin_display_x_dim=\dimen155 +\l__coffin_display_y_dim=\dimen156 +L3 Module: l3color 2014/08/23 v5354 L3 Experimental color support +L3 Module: l3sys 2015/09/25 v6087 L3 Experimental system/runtime functions +L3 Module: l3candidates 2016/01/14 v6376 L3 Experimental additions to l3kernel +\l__box_top_dim=\dimen157 +\l__box_bottom_dim=\dimen158 +\l__box_left_dim=\dimen159 +\l__box_right_dim=\dimen160 +\l__box_top_new_dim=\dimen161 +\l__box_bottom_new_dim=\dimen162 +\l__box_left_new_dim=\dimen163 +\l__box_right_new_dim=\dimen164 +\l__box_internal_box=\box53 +\l__coffin_bounding_shift_dim=\dimen165 +\l__coffin_left_corner_dim=\dimen166 +\l__coffin_right_corner_dim=\dimen167 +\l__coffin_bottom_corner_dim=\dimen168 +\l__coffin_top_corner_dim=\dimen169 +\l__coffin_scaled_total_height_dim=\dimen170 +\l__coffin_scaled_width_dim=\dimen171 +L3 Module: l3luatex 2015/11/11 v6250 L3 Experimental LuaTeX-specific functions +) (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def +File: l3xdvidpfmx.def 2015/11/11 v6250 L3 Experimental driver: xdvipdfmx +)) (/usr/share/texlive/texmf-dist/tex/latex/l3packages/xparse/xparse.sty +Package: xparse 2016/01/19 v6377 L3 Experimental document command parser +\l__xparse_current_arg_int=\count156 +\l__xparse_m_args_int=\count157 +\l__xparse_mandatory_args_int=\count158 +\l__xparse_processor_int=\count159 +\l__xparse_v_nesting_int=\count160 +) +Package: fontspec 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec-xetex.sty +Package: fontspec-xetex 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +\l_fontspec_script_int=\count161 +\l_fontspec_language_int=\count162 +\l_fontspec_strnum_int=\count163 +\l__fontspec_tmpa_dim=\dimen172 +\l__fontspec_tmpb_dim=\dimen173 +\l__fontspec_tmpc_dim=\dimen174 +\g__file_internal_ior=\read1 +(/usr/share/texlive/texmf-dist/tex/latex/base/fontenc.sty +Package: fontenc 2005/09/27 v1.99g Standard LaTeX package +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1enc.def +File: eu1enc.def 2010/05/27 v0.1h Experimental Unicode font encodings +) +LaTeX Font Info: Try loading font information for EU1+lmr on input line 105. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmr.fd +File: eu1lmr.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) (/usr/share/texlive/texmf-dist/tex/xelatex/xunicode/xunicode.sty +File: xunicode.sty 2011/09/09 v0.981 provides access to latin accents and many other characters in Unicode lower plane +(/usr/share/texmf/tex/latex/tipa/t3enc.def +File: t3enc.def 2001/12/31 T3 encoding +LaTeX Font Info: Try loading font information for EU1+lmss on input line 357. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmss.fd +File: eu1lmss.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) +\tipaTiiicode=\count164 +\tipasavetokens=\toks26 +\tipachecktokens=\toks27 +) +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \__fontspec_post_arg:w with sig. 'mmO{}' on line 353. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \fontspec with sig. 'om' on line 355. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmainfont with sig. 'om' on line 365. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setsansfont with sig. 'om' on line 375. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmonofont with sig. 'om' on line 385. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathrm with sig. 'om' on line 399. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setboldmathrm with sig. 'om' on line 407. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathsf with sig. 'om' on line 415. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathtt with sig. 'om' on line 423. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfamily with sig. 'mom' on line 437. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontface with sig. 'mom' on line 453. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \defaultfontfeatures with sig. 't+om' on line 467. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \addfontfeatures with sig. 'm' on line 529. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfeature with sig. 'mm' on line 540. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newAATfeature with sig. 'mmmm' on line 548. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newopentypefeature with sig. 'mmm' on line 556. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeature with sig. 'mm' on line 577. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeatureoption with sig. 'mmm' on line 586. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontscript with sig. 'mm' on line 590. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontlanguage with sig. 'mm' on line 594. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \DeclareFontsExtensions with sig. 'm' on line 599. +................................................. +\l__fontspec_tmp_int=\count165 +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.cfg) +LaTeX Info: Redefining \itshape on input line 2705. +LaTeX Info: Redefining \slshape on input line 2710. +LaTeX Info: Redefining \scshape on input line 2715. +LaTeX Info: Redefining \upshape on input line 2720. +\l__fontspec_em_int=\count166 +\l__fontspec_emdef_int=\count167 +LaTeX Info: Redefining \em on input line 2736. +LaTeX Info: Redefining \emph on input line 2742. +LaTeX Info: Redefining \- on input line 2746. +................................................. +. LaTeX info: "xparse/redefine-command" +. +. Redefining command \oldstylenums with sig. 'm' on line 2841. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \liningnums with sig. 'm' on line 2845. +................................................. +)) +Package hyperref Info: Option `colorlinks' set `true' on input line 87. +\px=\skip152 +\c@md@targetcount=\count168 +\mdcompactskip=\skip153 +\mdcompacttopsep=\skip154 +\dim@rem=\skip155 +\dim@ch=\skip156 +\md@height=\skip157 +\dim@marginbottom=\skip158 +\dim@paddingbottom=\skip159 +\md@interaction=\count169 +\mddefinitionsskip=\skip160 +\md@captionlen=\skip161 +\mdtoclevel=\count170 +\c@mdtoclevelbold=\count171 +\c@mdtocleveldots=\count172 +\mdtocskip=\skip162 +\mdpreskip=\skip163 +\presp=\skip164 +LaTeX Font Info: Try loading font information for EU1+lmtt on input line 801. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmtt.fd +File: eu1lmtt.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +\md@postskip=\skip165 +\ppresp=\skip166 +\md@thmcaption=\box54 +\md@defaultcolwidth=\skip167 +\mdtabularskip=\skip168 +\mdbibindentunit=\skip169 +\c@md@authorcount=\count173 +\c@mdx@authorcount=\count174 +\c@@mdTargetCount=\count175 +\@snippetBox=\box55 +\@snippetWidth=\skip170 +\@snippetHeight=\skip171 +\@snippetDepth=\skip172 +\c@snippets=\count176 +) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty +Package: geometry 2010/09/12 v5.6 Page Geometry +\Gm@cnth=\count177 +\Gm@cntv=\count178 +\c@Gm@tempcnt=\count179 +\Gm@bindingoffset=\dimen175 +\Gm@wd@mp=\dimen176 +\Gm@odd@mp=\dimen177 +\Gm@even@mp=\dimen178 +\Gm@layoutwidth=\dimen179 +\Gm@layoutheight=\dimen180 +\Gm@layouthoffset=\dimen181 +\Gm@layoutvoffset=\dimen182 +\Gm@dimlist=\toks28 +) (/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +\fancy@headwidth=\skip173 +\f@ncyO@elh=\skip174 +\f@ncyO@erh=\skip175 +\f@ncyO@olh=\skip176 +\f@ncyO@orh=\skip177 +\f@ncyO@elf=\skip178 +\f@ncyO@erf=\skip179 +\f@ncyO@olf=\skip180 +\f@ncyO@orf=\skip181 +) (build/P4Runtime-Spec.aux + +LaTeX Warning: Label `sec-directcounterentry' multiply defined. + + +LaTeX Warning: Label `sec-counterentry' multiply defined. + + +LaTeX Warning: Label `sec-directmeterentry' multiply defined. + + +LaTeX Warning: Label `sec-meterentry' multiply defined. + + +LaTeX Warning: Label `sec-packetreplicationengineentry' multiply defined. + + +LaTeX Warning: Label `sec-valuesetentry' multiply defined. + + +LaTeX Warning: Label `sec-registerentry' multiply defined. + + +LaTeX Warning: Label `sec-digestentry' multiply defined. + + +LaTeX Warning: Label `sec-example' multiply defined. + +) +\openout1 = `P4Runtime-Spec.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for TS1+cmr on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1cmr.fd +File: ts1cmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions +) +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for EU1/lmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T3/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for T3+cmr on input line 14. +(/usr/share/texmf/tex/latex/tipa/t3cmr.fd +File: t3cmr.fd 2001/12/31 TIPA font definitions +) +LaTeX Font Info: ... okay on input line 14. +\AtBeginShipoutBox=\box56 +Package hyperref Info: Link coloring ON on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2012/10/27 v2.43 Cross-referencing by name of section +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO) +) +\c@section@level=\count180 +) +LaTeX Info: Redefining \ref on input line 14. +LaTeX Info: Redefining \pageref on input line 14. +LaTeX Info: Redefining \nameref on input line 14. +................................................. +. fontspec info: "setup-math" +. +. Adjusting the maths setup (use [no-math] to avoid this). +................................................. +\symlegacymaths=\mathgroup7 +LaTeX Font Info: Overwriting symbol font `legacymaths' in version `bold' +(Font) OT1/cmr/m/n --> OT1/cmr/bx/n on input line 14. +LaTeX Font Info: Redeclaring math accent \acute on input line 14. +LaTeX Font Info: Redeclaring math accent \grave on input line 14. +LaTeX Font Info: Redeclaring math accent \ddot on input line 14. +LaTeX Font Info: Redeclaring math accent \tilde on input line 14. +LaTeX Font Info: Redeclaring math accent \bar on input line 14. +LaTeX Font Info: Redeclaring math accent \breve on input line 14. +LaTeX Font Info: Redeclaring math accent \check on input line 14. +LaTeX Font Info: Redeclaring math accent \hat on input line 14. +LaTeX Font Info: Redeclaring math accent \dot on input line 14. +LaTeX Font Info: Redeclaring math accent \mathring on input line 14. +LaTeX Font Info: Redeclaring math symbol \Gamma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Delta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Theta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Lambda on input line 14. +LaTeX Font Info: Redeclaring math symbol \Xi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Pi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Sigma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Upsilon on input line 14. +LaTeX Font Info: Redeclaring math symbol \Phi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Psi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Omega on input line 14. +LaTeX Font Info: Redeclaring math symbol \mathdollar on input line 14. +LaTeX Font Info: Redeclaring symbol font `operators' on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `normal' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/cmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `bold' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/cmr/bx/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) EU1/lmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/cmr/m/it --> EU1/lmr/m/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/cmr/bx/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/cmss/m/n --> EU1/lmss/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/cmtt/m/n --> EU1/lmtt/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) EU1/lmr/m/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' +(Font) OT1/cmr/bx/it --> EU1/lmr/bx/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/cmss/bx/n --> EU1/lmss/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/cmtt/m/n --> EU1/lmtt/bx/n on input line 14. +*geometry* driver: auto-detecting +*geometry* detected driver: xetex +*geometry* verbose mode - [ preamble ] result: +* driver: xetex +* paper: +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: +* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt) +* v-part:(T,H,B)=(72.26999pt, 632.3625pt, 90.3375pt) +* \paperwidth=614.295pt +* \paperheight=794.96999pt +* \textwidth=469.75502pt +* \textheight=632.3625pt +* \oddsidemargin=0.0pt +* \evensidemargin=0.0pt +* \topmargin=-37.0pt +* \headheight=30.0pt +* \headsep=25.0pt +* \topskip=11.0pt +* \footskip=30.0pt +* \marginparwidth=59.0pt +* \marginparsep=10.0pt +* \columnsep=10.0pt +* \skip\footins=10.0pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +resolve font stack: UtopiaStd-Regular + +\g__fontspec_family_UtopiaStd-Regular_int=\count181 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'UtopiaStd-Regular(0)' created for font 'UtopiaStd-Regular' with +. options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;" +. - 'small caps' (m/sc) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;+smcp;" +................................................. + +resolved font stack 'UtopiaStd-Regular' to: UtopiaStd-Regular +LaTeX Font Info: Try loading font information for U+msa on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Try loading font information for U+msb on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Try loading font information for U+stmry on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/Ustmry.fd) + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/bx/n' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 35. + +resolve font stack: LuxiMono + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +\g__fontspec_family_LuxiMono_int=\count182 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'LuxiMono(0)' created for font 'LuxiMono' with options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: <->"LuxiMono/OT:" +. - 'small caps' (m/sc) with NFSS spec.: +................................................. + +resolved font stack 'LuxiMono' to: LuxiMono +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/se-ascii-print.def +File: se-ascii-print.def 2011/12/02 v1.10 stringenc: Printable ASCII characters +) [1 + +] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[2] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <10.95> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 323. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Font Warning: Font shape `EU1/LuxiMono(0)/bx/n' undefined +(Font) using `EU1/LuxiMono(0)/m/n' instead on input line 323. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[3] [4] + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/m/it' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 543. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[5] [6] [7] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/reference-architecture.png Graphic file (type QTm) + [8] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[9] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[10] +File: build/single-embedded-controller.png Graphic file (type QTm) + +File: build/single-remote-controller.png Graphic file (type QTm) + [11] [12] +File: build/embedded-plus-single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-controllers.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-ha-controllers.png Graphic file (type QTm) + [13] [14] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[15] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[16] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <12> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 1602. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1602. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[17] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[18] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (65.03293pt too wide) in paragraph at lines 1870--1873 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For all backup controllers, \EU1/LuxiMono(0)/bx/n/8.2125 status \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set to non-OK (with \EU1/LuxiMono(0)/bx/n/8.2125 status.code \EU1/UtopiaStd-Regular(0)/m/it/10.95 set to \EU1/LuxiMono(0)/bx/n/8.2125 google.rpc.ALREADY_EXISTS\EU1/UtopiaStd-Regular(0)/m/it/10.95 ). + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1907. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[19] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1931. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[20] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1976. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[21] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[22] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[23] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2259. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[24] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1057) in paragraph at lines 2309--2313 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For structured annotations, every \EU1/LuxiMono(0)/bx/n/8.2125 StructuredAnnotation \EU1/UtopiaStd-Regular(0)/m/it/10.95 message contains an optional field + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2316. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[25] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1442) in paragraph at lines 2449--2459 +\EU1/LuxiMono(0)/bx/n/8.2125 Property\EU1/UtopiaStd-Regular(0)/m/it/10.95 , for example, \EU1/LuxiMono(0)/bx/n/8.2125 multicast_group_table_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 or \EU1/LuxiMono(0)/bx/n/8.2125 multicast_group_table_total_replicas\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +[26] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: `!h' float specifier changed to `!ht'. + + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (12.45624pt too wide) in paragraph at lines 2595--2608 + [] + [] + + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[27] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2631. + +[28] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[29] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2839. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[30] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2899. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[31] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1546) in paragraph at lines 2998--3006 + \EU1/UtopiaStd-Regular(0)/m/it/10.95 PSA programs can use the \EU1/LuxiMono(0)/bx/n/8.2125 @selector_size_semantics \EU1/UtopiaStd-Regular(0)/m/it/10.95 annotation with one of \EU1/LuxiMono(0)/bx/n/8.2125 sum_of_weights \EU1/UtopiaStd-Regular(0)/m/it/10.95 or + [] + + +Overfull \hbox (13.9818pt too wide) in paragraph at lines 2998--3006 +\EU1/LuxiMono(0)/bx/n/8.2125 sum_of_members \EU1/UtopiaStd-Regular(0)/m/it/10.95 to specify this value for Action Selectors. In the \EU1/LuxiMono(0)/bx/n/8.2125 sum_of_members \EU1/UtopiaStd-Regular(0)/m/it/10.95 case, the \EU1/LuxiMono(0)/bx/n/8.2125 @max_member_weight + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3008. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[32] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3089. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.59204pt too wide) in paragraph at lines 3143--3145 +[]\EU1/LuxiMono(0)/bx/n/8.2125 BYTES\EU1/UtopiaStd-Regular(0)/m/it/10.95 , which signifies that this meter can be configured with rates expressed in bytes/second. + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (32.19182pt too wide) in paragraph at lines 3186--3193 +[]\EU1/LuxiMono(0)/bx/n/8.2125 SINGLE_RATE_TWO_COLOR\EU1/UtopiaStd-Regular(0)/m/it/10.95 : This is a simplified version of RFC 2697 [[][]2[][]], and the \EU1/LuxiMono(0)/bx/n/8.2125 SINGLE_RATE_THREE_COLOR + [] + +[33] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3212. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (18.74199pt too wide) in paragraph at lines 3229--3236 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 carrying P4 standard annotations \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_in") \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_out")\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[34] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[35] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3371. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[36] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[37] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3599. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[38] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3646. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3684. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[39] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[40] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[41] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[42] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[43] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[44] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[45] [46] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1629) in paragraph at lines 4449--4451 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For example, the following P4$[]$ objects involve complex types that need to be exposed in + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[47] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1454) in paragraph at lines 4497--4506 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 ification for all the named types in the P4$[]$ program. These named types are \EU1/LuxiMono(0)/bx/n/8.2125 struct\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 header\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + + +Underfull \hbox (badness 1831) in paragraph at lines 4497--4506 +\EU1/LuxiMono(0)/bx/n/8.2125 header_union\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 enum \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 serializable_enum\EU1/UtopiaStd-Regular(0)/m/it/10.95 ; for each of these we have a type specification mes- + [] + + +Underfull \hbox (badness 1845) in paragraph at lines 4497--4506 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 sage, respectively \EU1/LuxiMono(0)/bx/n/8.2125 P4StructTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnionTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4EnumTypeSpec \EU1/UtopiaStd-Regular(0)/m/it/10.95 and + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (33.06564pt too wide) in paragraph at lines 4532--4539 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 “binary string” types (\EU1/LuxiMono(0)/bx/n/8.2125 bit\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 int\EU1/UtopiaStd-Regular(0)/m/it/10.95 , and \EU1/LuxiMono(0)/bx/n/8.2125 varbit\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) are grouped together in the \EU1/LuxiMono(0)/bx/n/8.2125 P4BitstringLikeTypeSpec + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4549. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[48] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.46094pt too wide) in paragraph at lines 4586--4589 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 An invalid header union (i.e. all headers in the union are invalid) is represented by a \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnion + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[49] [50] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4723. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[51] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (24.68944pt too wide) in paragraph at lines 4811--4817 +[]\EU1/LuxiMono(0)/bx/n/8.2125 translated_type\EU1/UtopiaStd-Regular(0)/m/it/10.95 , if and only if the P4 \EU1/LuxiMono(0)/bx/n/8.2125 type \EU1/UtopiaStd-Regular(0)/m/it/10.95 declaration was annotated with \EU1/LuxiMono(0)/bx/n/8.2125 @p4runtime_translation\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[52] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[53] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (32.59732pt too wide) in paragraph at lines 4919--4925 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 in \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.MatchField\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.Action.Param \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.ControllerPacketMetadata.Metadata\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[54] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5026. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[55] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[56] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[57] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[58] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.53593pt too wide) in paragraph at lines 5500--5503 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 If the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 does not match the table description in the P4Info (e.g. the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 is \EU1/LuxiMono(0)/bx/n/8.2125 action_profile_member_id + [] + +[59] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[60] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (54.86232pt too wide) in paragraph at lines 5673--5677 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 Unlike a table with \EU1/LuxiMono(0)/bx/n/8.2125 is_const_table = true\EU1/UtopiaStd-Regular(0)/m/it/10.95 , a client may insert entries into a table with \EU1/LuxiMono(0)/bx/n/8.2125 has_initial_entries = true + [] + +[61] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[62] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[63] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[64] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[65] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[66] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6225. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[67] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[68] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (21.53802pt too wide) in paragraph at lines 6448--6454 +[]\EU1/LuxiMono(0)/bx/n/8.2125 max_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 is the maximum sum of all members or member weights (as per the \EU1/LuxiMono(0)/bx/n/8.2125 selector_size_semantics\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[69] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (9.29865pt too wide) in paragraph at lines 6512--6514 + []\EU1/lmr/bx/n/10.95 9.2.2.1.| Rules on Setting \EU1/LuxiMono(0)/bx/n/8.2125 max_size[] \EU1/UtopiaStd-Regular(0)/m/it/10.95 The valid values for \EU1/LuxiMono(0)/bx/n/8.2125 max_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 depend on the static \EU1/LuxiMono(0)/bx/n/8.2125 max_group_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[70] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[71] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[72] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[73] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6809. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6849. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1331) in paragraph at lines 6852--6859 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 A direct counter is a direct resource associated with a \EU1/LuxiMono(0)/bx/n/8.2125 TableEntry \EU1/UtopiaStd-Regular(0)/m/it/10.95 (see [][]Direct Resources[][]). The + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[74] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6926. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[75] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7020. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[76] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7103. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7193. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[77] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7298. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[78] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7326. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7336. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[79] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7464. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[80] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[81] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.93839pt too wide) in paragraph at lines 7576--7578 +[]\EU1/LuxiMono(0)/bx/n/8.2125 MODIFY\EU1/UtopiaStd-Regular(0)/m/it/10.95 : Modify the attributes of a given clone session entry, indexed by the given \EU1/LuxiMono(0)/bx/n/8.2125 clone_session_id\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7614. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[82] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[83] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7750. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7794. + +[84] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[85] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[86] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7992. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[87] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/error-report.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <14.4> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 8116. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8116. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[88] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[89] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8218. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[90] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[91] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[92] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (34.34796pt too wide) in paragraph at lines 8502--8507 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If an error is encountered before even trying to attempt individual batch updates, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.66206pt too wide) in paragraph at lines 8511--8522 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 Otherwise, if one or more updates in the batch (\EU1/LuxiMono(0)/bx/n/8.2125 WriteRequest.updates\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) failed, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[93] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8558. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[94] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[95] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.4752pt too wide) in paragraph at lines 8793--8797 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 responding to \EU1/LuxiMono(0)/bx/n/8.2125 a \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 c\EU1/UtopiaStd-Regular(0)/m/it/10.95 , followed by a status \EU1/LuxiMono(0)/bx/n/8.2125 {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[96] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8879. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[97] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 9002. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[98] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 9100--9103 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If a P4Runtime server supports both \EU1/LuxiMono(0)/bx/n/8.2125 SetForwardingPipelineConfig \EU1/UtopiaStd-Regular(0)/m/it/10.95 as well as returning the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[99] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (57.64021pt too wide) in paragraph at lines 9185--9191 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If \EU1/LuxiMono(0)/bx/n/8.2125 ControllerPacketMetadata.Metadata.bitwidth \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set, or if \EU1/LuxiMono(0)/bx/n/8.2125 ControllerPacketMetadata.Metadata.type_name + [] + +[100] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (44.6621pt too wide) in paragraph at lines 9193--9205 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If \EU1/LuxiMono(0)/bx/n/8.2125 ControllerPacketMetadata.Metadata.type_name \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set and \EU1/LuxiMono(0)/bx/n/8.2125 P4NewTypeSpec.translated_type.sdn_string + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[101] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[102] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[103] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 9500. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[104] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 9568. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[105] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/psa-metadata-translation.png Graphic file (type QTm) + [106] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[107] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[108] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[109] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[110] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[111] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 10079--10086 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 p4info-ext should include a Protobuf message definition for every extern type that can + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 10130. + + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 10130. + +[112] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 4036) in paragraph at lines 10134--10141 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 P4Runtime also supports streaming arbitrary Protobuf messages between the server and the + [] + + +Underfull \hbox (badness 1629) in paragraph at lines 10134--10141 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 client, by including an \EU1/LuxiMono(0)/bx/n/8.2125 Any \EU1/UtopiaStd-Regular(0)/m/it/10.95 Protobuf field [[][]37[][]] named \EU1/LuxiMono(0)/bx/n/8.2125 other \EU1/UtopiaStd-Regular(0)/m/it/10.95 in both \EU1/LuxiMono(0)/bx/n/8.2125 p4.v1.StreamMessageRequest + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[113] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[114] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[115] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1997) in paragraph at lines 10467--10469 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 Table [][]7[][] lists P4$[]$ annotations introduced primarily for the purpose of adding features for the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[116] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[117] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.61781pt too wide) in paragraph at lines 10620--10627 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 In gRPC, the status of a RPC request is sent as metadata, whose size is limited by the \EU1/LuxiMono(0)/bx/n/8.2125 grpc.max_metadata_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[118] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[119] +Underfull \hbox (badness 10000) in paragraph at lines 10770--10771 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Complex Types in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- p4- + [] + + +Underfull \hbox (badness 4001) in paragraph at lines 10782--10783 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Google Cloud APIs Versioning - Backwards-Compatibility.” [][]\EU1/lmtt/m/n/10.95 https:// cloud. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10791--10792 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “gRPC Streaming RPCs in C++.” [][]\EU1/lmtt/m/n/10.95 https:// grpc. io/ docs/ tutorials/ basic/ c. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10809--10810 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “P4 Concurrency Model.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10812--10813 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” + [] + +[120] +Underfull \hbox (badness 10000) in paragraph at lines 10830--10831 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Protobuf OneOf Backwards-Compatibility Issues.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10836--10837 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Action Selector.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# sec- action- + [] + + +Underfull \hbox (badness 2409) in paragraph at lines 10845--10846 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Empty Group Action Appendix.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10848--10849 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Select Expressions in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 1668) in paragraph at lines 10866--10867 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Any Protobuf Message.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ protocol- buffers/ docs/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10872--10873 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC C++ Error Details Library.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ grpc/ grpc/ blob/ master/ + [] + +[121] +Underfull \hbox (badness 10000) in paragraph at lines 10875--10876 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC Canonical Status Codes.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ maps- booking/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10881--10882 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Protobuf MessageDifferencer in the C++ API.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10887--10888 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “v1model Architecture Definition.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ p4lang/ p4c/ blob/ master/ + [] + +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 10896. +[122] +Package atveryend Info: Empty hook `AfterLastShipout' on input line 10896. +(build/P4Runtime-Spec.aux) +Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 10896. +Package atveryend Info: Empty hook `AtEndAfterFileList' on input line 10896. + +LaTeX Font Warning: Some font shapes were not available, defaults substituted. + + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 27580 strings out of 493638 + 518353 string characters out of 6146796 + 568918 words of memory out of 5000000 + 30682 multiletter control sequences out of 15000+600000 + 14633 words of font info for 98 fonts, out of 8000000 for 9000 + 1328 hyphenation exceptions out of 8191 + 48i,19n,81p,10429b,768s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on build/P4Runtime-Spec.pdf (122 pages). diff --git a/spec/main/P4Runtime-Spec.pdf b/spec/main/P4Runtime-Spec.pdf new file mode 100644 index 00000000..a6486ec1 Binary files /dev/null and b/spec/main/P4Runtime-Spec.pdf differ diff --git a/spec/main/P4Runtime-Spec.tex b/spec/main/P4Runtime-Spec.tex new file mode 100644 index 00000000..8969d700 --- /dev/null +++ b/spec/main/P4Runtime-Spec.tex @@ -0,0 +1,10896 @@ +\documentclass[11pt]{article} +% generated by Madoko, version 1.1.4 +%mdk-data-line={1} + + +\usepackage[heading-base={2},section-num={False},bib-label={hide},fontspec={True}]{madoko2} +\usepackage[top=1in, bottom=1.25in, left=1in, right=1in]{geometry} +\usepackage{fancyhdr} +%mdk-data-line={11} + + \setlength{\headheight}{30pt} + \setlength{\emergencystretch}{2em} + +\begin{document} + + + +{\mdfontfamily{UtopiaStd-Regular} +%mdk-data-line={203} +\mdxtitleblockstart{} +%mdk-data-line={203} +\mdxtitle{{\sffamily{\bfseries\mdline{203}P4Runtime Specification}}}%mdk + +%mdk-data-line={206} +\mdxtitlenote{{\sffamily{\bfseries\mdline{206}version 1.4.0-dev}}}%mdk +\mdxauthorstart{} +%mdk-data-line={211} +\mdxauthorname{\mdline{211}The P4.org API Working Group}%mdk +\mdxauthorend +%mdk-data-line={220} +\mdxtitlefooter{{\sffamily{\bfseries\mdline{220}2024-09-16}}}%mdk +\mdtitleauthorrunning{}{}\mdxtitleblockend%mdk + +%mdk-data-line={205} +\begin{abstract}%mdk + +%mdk-data-line={206} +\noindent\mdline{206}P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.%mdk +%mdk +\end{abstract}%mdk +\mdline{214} +\begin{mdtoc}%mdk + +\section*{Contents}\label{sec-contents}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-introduction-and-scope}{\mdref{sec-introduction-and-scope}{1.\hspace*{0.5em}Introduction and Scope}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-language-version-applicability}{\mdref{sec-p4-language-version-applicability}{1.1.\hspace*{0.5em}P4 Language Version Applicability}}%mdk + +\mdtocitemx{sec-in-scope}{\mdref{sec-in-scope}{1.2.\hspace*{0.5em}In Scope}}%mdk + +\mdtocitemx{sec-not-in-scope}{\mdref{sec-not-in-scope}{1.3.\hspace*{0.5em}Not In Scope}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-terms-and-definitions}{\mdref{sec-terms-and-definitions}{2.\hspace*{0.5em}Terms and Definitions}}%mdk + +\mdtocitemx{sec-reference-architecture}{\mdref{sec-reference-architecture}{3.\hspace*{0.5em}Reference Architecture}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-service-implementation}{\mdref{sec-p4runtime-service-implementation}{3.1.\hspace*{0.5em}P4Runtime Service Implementation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-security-concerns}{\mdref{sec-security-concerns}{3.1.1.\hspace*{0.5em}Security concerns}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-idealized-workflow}{\mdref{sec-idealized-workflow}{3.2.\hspace*{0.5em}Idealized Workflow}}%mdk + +\mdtocitemx{sec-p4-as-behavioral-description-language}{\mdref{sec-p4-as-behavioral-description-language}{3.3.\hspace*{0.5em}P4 as a Behavioral Description Language}}%mdk + +\mdtocitemx{sec-alternative-workflows}{\mdref{sec-alternative-workflows}{3.4.\hspace*{0.5em}Alternative Workflows}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{\mdref{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{3.4.1.\hspace*{0.5em}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}}%mdk + +\mdtocitemx{sec-no-p4-source-available-p4info-available}{\mdref{sec-no-p4-source-available-p4info-available}{3.4.2.\hspace*{0.5em}No P4 Source Available, P4Info Available}}%mdk + +\mdtocitemx{sec-partial-p4info-and-p4-source-are-available}{\mdref{sec-partial-p4info-and-p4-source-are-available}{3.4.3.\hspace*{0.5em}Partial P4Info and P4 Source are Available}}%mdk + +\mdtocitemx{sec-p4info-role-based-subsets}{\mdref{sec-p4info-role-based-subsets}{3.4.4.\hspace*{0.5em}P4Info Role-Based Subsets}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-restarts}{\mdref{sec-restarts}{3.5.\hspace*{0.5em}P4Runtime State Across Restarts}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-controller-use-cases}{\mdref{sec-controller-use-cases}{4.\hspace*{0.5em}Controller Use-cases}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-single-embedded-controller}{\mdref{sec-single-embedded-controller}{4.1.\hspace*{0.5em}Single Embedded Controller}}%mdk + +\mdtocitemx{sec-single-remote-controller}{\mdref{sec-single-remote-controller}{4.2.\hspace*{0.5em}Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-single-remote-controller}{\mdref{sec-embedded-single-remote-controller}{4.3.\hspace*{0.5em}Embedded + Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-two-remote-controllers}{\mdref{sec-embedded-two-remote-controllers}{4.4.\hspace*{0.5em}Embedded + Two Remote Controllers}}%mdk + +\mdtocitemx{sec-embedded-controller-two-high-availability-remote-controllers}{\mdref{sec-embedded-controller-two-high-availability-remote-controllers}{4.5.\hspace*{0.5em}Embedded Controller + Two High-Availability Remote Controllers}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-client-arbitration-and-controller-replication}{\mdref{sec-client-arbitration-and-controller-replication}{5.\hspace*{0.5em}Client Arbitration and Controller Replication}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-default-role}{\mdref{sec-default-role}{5.1.\hspace*{0.5em}Default Role}}%mdk + +\mdtocitemx{sec-arbitration-role-config}{\mdref{sec-arbitration-role-config}{5.2.\hspace*{0.5em}Role Config}}%mdk + +\mdtocitemx{sec-arbitration-updates}{\mdref{sec-arbitration-updates}{5.3.\hspace*{0.5em}Rules for Handling \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}} Messages Received from Controllers}}%mdk + +\mdtocitemx{sec-arbitration-notification}{\mdref{sec-arbitration-notification}{5.4.\hspace*{0.5em}Client Arbitration Notifications}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-the-p4info-message}{\mdref{sec-the-p4info-message}{6.\hspace*{0.5em}The P4Info Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-common-messages}{\mdref{sec-common-messages}{6.1.\hspace*{0.5em}Common Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-documentation-message}{\mdref{sec-documentation-message}{6.1.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}} Message}}%mdk + +\mdtocitemx{sec-preamble-message}{\mdref{sec-preamble-message}{6.1.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}} Message}}%mdk + +\mdtocitemx{sec-annotating-p4-entities-with-documentation}{\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3.\hspace*{0.5em}Annotating P4 Entities with \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}}%mdk + +\mdtocitemx{sec-structured-annotations}{\mdref{sec-structured-annotations}{6.1.4.\hspace*{0.5em}Structured Annotations}}%mdk + +\mdtocitemx{sec-sourcelocation-message}{\mdref{sec-sourcelocation-message}{6.1.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}} Message}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-pkginfo-message}{\mdref{sec-pkginfo-message}{6.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}} Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-annotating-p4-code-with-pkginfo}{\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1.\hspace*{0.5em}Annotating P4 code with PkgInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-id-allocation}{\mdref{sec-id-allocation}{6.3.\hspace*{0.5em}ID Allocation for P4Info Objects}}%mdk + +\mdtocitemx{sec-p4info-objects}{\mdref{sec-p4info-objects}{6.4.\hspace*{0.5em}P4Info Objects}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table}{\mdref{sec-table}{6.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}}%mdk + +\mdtocitemx{sec-action}{\mdref{sec-action}{6.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}}%mdk + +\mdtocitemx{sec-p4info-action-profile}{\mdref{sec-p4info-action-profile}{6.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}}%mdk + +\mdtocitemx{sec-counter-directcounter}{\mdref{sec-counter-directcounter}{6.4.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}}%mdk + +\mdtocitemx{sec-meter-directmeter}{\mdref{sec-meter-directmeter}{6.4.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}}%mdk + +\mdtocitemx{sec-controller-packet-meta}{\mdref{sec-controller-packet-meta}{6.4.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}}%mdk + +\mdtocitemx{sec-valueset}{\mdref{sec-valueset}{6.4.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}}%mdk + +\mdtocitemx{sec-register}{\mdref{sec-register}{6.4.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}}%mdk + +\mdtocitemx{sec-digest}{\mdref{sec-digest}{6.4.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}}%mdk + +\mdtocitemx{sec-p4info-extern}{\mdref{sec-p4info-extern}{6.4.10.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{\mdref{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{6.5.\hspace*{0.5em}Support for Arbitrary P4 Types with P4TypeInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-fwd-pipe-config}{\mdref{sec-p4-fwd-pipe-config}{7.\hspace*{0.5em}P4 Forwarding-Pipeline Configuration}}%mdk + +\mdtocitemx{sec-message-formatting-principles}{\mdref{sec-message-formatting-principles}{8.\hspace*{0.5em}General Principles for Message Formatting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-default-valued-fields}{\mdref{sec-default-valued-fields}{8.1.\hspace*{0.5em}Default-valued Fields}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-set-unset-scalar-fields}{\mdref{sec-set-unset-scalar-fields}{8.1.1.\hspace*{0.5em}Set / Unset Scalar Fields}}%mdk + +\mdtocitemx{sec-set-unset-message-fields}{\mdref{sec-set-unset-message-fields}{8.1.2.\hspace*{0.5em}Set / Unset Message Fields}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-read-write-symmetry}{\mdref{sec-read-write-symmetry}{8.2.\hspace*{0.5em}Read-Write Symmetry}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-data-plane-volatile-objects}{\mdref{sec-data-plane-volatile-objects}{8.2.1.\hspace*{0.5em}Data plane volatile objects}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-bytestrings}{\mdref{sec-bytestrings}{8.3.\hspace*{0.5em}Bytestrings}}%mdk + +\mdtocitemx{sec-representation-of-arbitrary-p4-types}{\mdref{sec-representation-of-arbitrary-p4-types}{8.4.\hspace*{0.5em}Representation of Arbitrary P4 Types}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-problem-statement}{\mdref{sec-problem-statement}{8.4.1.\hspace*{0.5em}Problem Statement}}%mdk + +\mdtocitemx{sec-p4-type-specifications-in-p4infoproto}{\mdref{sec-p4-type-specifications-in-p4infoproto}{8.4.2.\hspace*{0.5em}P4 Type Specifications in p4info.proto}}%mdk + +\mdtocitemx{sec-p4data-in-p4runtime-proto}{\mdref{sec-p4data-in-p4runtime-proto}{8.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}} in p4runtime.proto}}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{8.4.4.\hspace*{0.5em}Example}}%mdk + +\mdtocitemx{sec-enum-serializable-enum-and-error}{\mdref{sec-enum-serializable-enum-and-error}{8.4.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}, serializable \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}}%mdk + +\mdtocitemx{sec-user-defined-types}{\mdref{sec-user-defined-types}{8.4.6.\hspace*{0.5em}User-defined types}}%mdk + +\mdtocitemx{sec-trade-off-for-v1x-releases}{\mdref{sec-trade-off-for-v1x-releases}{8.4.7.\hspace*{0.5em}Trade-off for v1.x Releases}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-entity-msgs}{\mdref{sec-p4-entity-msgs}{9.\hspace*{0.5em}P4 Entity Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table-entry}{\mdref{sec-table-entry}{9.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-match-format}{\mdref{sec-match-format}{9.1.1.\hspace*{0.5em}Match Format}}%mdk + +\mdtocitemx{sec-action-specification}{\mdref{sec-action-specification}{9.1.2.\hspace*{0.5em}Action Specification}}%mdk + +\mdtocitemx{sec-default-entry}{\mdref{sec-default-entry}{9.1.3.\hspace*{0.5em}Default Entry}}%mdk + +\mdtocitemx{sec-constant-tables}{\mdref{sec-constant-tables}{9.1.4.\hspace*{0.5em}Constant Tables}}%mdk + +\mdtocitemx{sec-preinitialized-tables}{\mdref{sec-preinitialized-tables}{9.1.5.\hspace*{0.5em}Preinitialized tables}}%mdk + +\mdtocitemx{sec-table-wildcard-reads}{\mdref{sec-table-wildcard-reads}{9.1.6.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-direct-resources}{\mdref{sec-direct-resources}{9.1.7.\hspace*{0.5em}Direct Resources}}%mdk + +\mdtocitemx{sec-idle-timeout}{\mdref{sec-idle-timeout}{9.1.8.\hspace*{0.5em}Idle-timeout}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-and-group}{\mdref{sec-action-profile-member-and-group}{9.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-programming}{\mdref{sec-action-profile-member-programming}{9.2.1.\hspace*{0.5em}Action Profile Member Programming}}%mdk + +\mdtocitemx{sec-action-profile-group-programming}{\mdref{sec-action-profile-group-programming}{9.2.2.\hspace*{0.5em}Action Profile Group Programming}}%mdk + +\mdtocitemx{sec-oneshot}{\mdref{sec-oneshot}{9.2.3.\hspace*{0.5em}One Shot Action Selector Programming}}%mdk + +\mdtocitemx{action-selector-constraints}{\mdref{action-selector-constraints}{9.2.4.\hspace*{0.5em}Constraints on action selector programming}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-counterentry-directcounterentry}{\mdref{sec-counterentry-directcounterentry}{9.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directcounterentry}{\mdref{sec-directcounterentry}{9.3.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\mdtocitemx{sec-counterentry}{\mdref{sec-counterentry}{9.3.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-meterentry-directmeterentry}{\mdref{sec-meterentry-directmeterentry}{9.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directmeterentry}{\mdref{sec-directmeterentry}{9.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\mdtocitemx{sec-meterentry}{\mdref{sec-meterentry}{9.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}}%mdk + +\mdtocitemx{sec-metercounterdata}{\mdref{sec-metercounterdata}{9.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-packetreplicationengineentry}{\mdref{sec-packetreplicationengineentry}{9.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-multicastgroupentry}{\mdref{sec-multicastgroupentry}{9.5.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}}%mdk + +\mdtocitemx{sec-clonesessionentry}{\mdref{sec-clonesessionentry}{9.5.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-valuesetentry}{\mdref{sec-valuesetentry}{9.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}}%mdk + +\mdtocitemx{sec-registerentry}{\mdref{sec-registerentry}{9.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}}%mdk + +\mdtocitemx{sec-digestentry}{\mdref{sec-digestentry}{9.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}}%mdk + +\mdtocitemx{sec-extern-entry}{\mdref{sec-extern-entry}{9.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-error-reporting-messages}{\mdref{sec-error-reporting-messages}{10.\hspace*{0.5em}Error Reporting Messages}}%mdk + +\mdtocitemx{sec-atomicity-of-individual-write-and-read-operations}{\mdref{sec-atomicity-of-individual-write-and-read-operations}{11.\hspace*{0.5em}Atomicity of Individual \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} Operations}}%mdk + +\mdtocitemx{sec-write-rpc}{\mdref{sec-write-rpc}{12.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-batching-and-ordering-of-updates}{\mdref{sec-batching-and-ordering-of-updates}{12.1.\hspace*{0.5em}Batching and Ordering of Updates}}%mdk + +\mdtocitemx{sec-batch-atomicity}{\mdref{sec-batch-atomicity}{12.2.\hspace*{0.5em}Batch Atomicity}}%mdk + +\mdtocitemx{sec-error-reporting}{\mdref{sec-error-reporting}{12.3.\hspace*{0.5em}Error Reporting}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-read-rpc}{\mdref{sec-read-rpc}{13.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-nomenclature}{\mdref{sec-nomenclature}{13.1.\hspace*{0.5em}Nomenclature}}%mdk + +\mdtocitemx{sec-wildcard-reads}{\mdref{sec-wildcard-reads}{13.2.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-batch-processing}{\mdref{sec-batch-processing}{13.3.\hspace*{0.5em}Batch Processing}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{13.3.1.\hspace*{0.5em}Example}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-parallelism-of-read-and-write-requests}{\mdref{sec-parallelism-of-read-and-write-requests}{13.4.\hspace*{0.5em}Parallelism of Read and Write Requests}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-setforwardingpipelineconfig-rpc}{\mdref{sec-setforwardingpipelineconfig-rpc}{14.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-getforwardingpipelineconfig-rpc}{\mdref{sec-getforwardingpipelineconfig-rpc}{15.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-p4runtime-stream-messages}{\mdref{sec-p4runtime-stream-messages}{16.\hspace*{0.5em}P4Runtime Stream Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-packet-i_o}{\mdref{sec-packet-i_o}{16.1.\hspace*{0.5em}Packet I/O}}%mdk + +\mdtocitemx{sec-client-arbitration-update}{\mdref{sec-client-arbitration-update}{16.2.\hspace*{0.5em}Client Arbitration Update}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-unset-election-id}{\mdref{sec-unset-election-id}{16.2.1.\hspace*{0.5em}Unset Election ID}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-digest-messages}{\mdref{sec-digest-messages}{16.3.\hspace*{0.5em}Digest Messages}}%mdk + +\mdtocitemx{sec-table-idle-timeout-notification}{\mdref{sec-table-idle-timeout-notification}{16.4.\hspace*{0.5em}Table Idle Timeout Notification}}%mdk + +\mdtocitemx{sec-architecture-specific-notifications}{\mdref{sec-architecture-specific-notifications}{16.5.\hspace*{0.5em}Architecture-Specific Notifications}}%mdk + +\mdtocitemx{sec-stream-error-reporting}{\mdref{sec-stream-error-reporting}{16.6.\hspace*{0.5em}Stream Error Reporting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-examples-of-streamerror-messages}{\mdref{sec-examples-of-streamerror-messages}{16.6.1.\hspace*{0.5em}Examples of \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}} Messages}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-capabilities-rpc}{\mdref{sec-capabilities-rpc}{17.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}} RPC}}%mdk + +\mdtocitemx{sec-portability-considerations}{\mdref{sec-portability-considerations}{18.\hspace*{0.5em}Portability Considerations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-psa-metadata-translation}{\mdref{sec-psa-metadata-translation}{18.1.\hspace*{0.5em}PSA Metadata Translation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-translation-of-port-numbers}{\mdref{sec-translation-of-port-numbers}{18.1.1.\hspace*{0.5em}Translation of Port Numbers}}%mdk + +\mdtocitemx{sec-translation-of-packet-io-header-fields}{\mdref{sec-translation-of-packet-io-header-fields}{18.1.2.\hspace*{0.5em}Translation of Packet-IO Header Fields}}%mdk + +\mdtocitemx{sec-translation-of-match-fields}{\mdref{sec-translation-of-match-fields}{18.1.3.\hspace*{0.5em}Translation of Match Fields}}%mdk + +\mdtocitemx{sec-translation-of-action-parameters}{\mdref{sec-translation-of-action-parameters}{18.1.4.\hspace*{0.5em}Translation of Action Parameters}}%mdk + +\mdtocitemx{sec-port-translation-for-psa-extern-apis}{\mdref{sec-port-translation-for-psa-extern-apis}{18.1.5.\hspace*{0.5em}Port Translation for PSA Extern APIs}}%mdk + +\mdtocitemx{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{\mdref{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{18.1.6.\hspace*{0.5em}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-versioning}{\mdref{sec-p4runtime-versioning}{19.\hspace*{0.5em}P4Runtime Versioning}}%mdk + +\mdtocitemx{sec-extending-p4runtime}{\mdref{sec-extending-p4runtime}{20.\hspace*{0.5em}Extending P4Runtime for non-PSA Architectures}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-p4runtime-for-architecture-specific-externs}{\mdref{sec-extending-p4runtime-for-architecture-specific-externs}{20.1.\hspace*{0.5em}Extending P4Runtime for Architecture-Specific Externs}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-the-p4info-message}{\mdref{sec-extending-the-p4info-message}{20.1.1.\hspace*{0.5em}Extending the P4Info message}}%mdk + +\mdtocitemx{sec-extending-the-p4runtime-service}{\mdref{sec-extending-the-p4runtime-service}{20.1.2.\hspace*{0.5em}Extending the P4Runtime Service}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-architecture-specific-table-extensions}{\mdref{sec-architecture-specific-table-extensions}{20.2.\hspace*{0.5em}Architecture-Specific Table Extensions}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-new-match-types}{\mdref{sec-new-match-types}{20.2.1.\hspace*{0.5em}New Match Types}}%mdk + +\mdtocitemx{sec-new-table-properties}{\mdref{sec-new-table-properties}{20.2.2.\hspace*{0.5em}New Table Properties}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-known-limitations-of-current-p4runtime-version}{\mdref{sec-known-limitations-of-current-p4runtime-version}{21.\hspace*{0.5em}Known Limitations of Current P4Runtime Version}}%mdk + +\mdtocitemx{sec-appendix}{\mdref{sec-appendix}{A.\hspace*{0.5em}Appendix}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-revision-history}{\mdref{sec-revision-history}{A.1.\hspace*{0.5em}Revision History}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-changes-in-v140}{\mdref{sec-changes-in-v140}{A.1.1.\hspace*{0.5em}Changes in v1.4.0}}%mdk + +\mdtocitemx{sec-changes-in-v130}{\mdref{sec-changes-in-v130}{A.1.2.\hspace*{0.5em}Changes in v1.3.0}}%mdk + +\mdtocitemx{sec-changes-in-v120}{\mdref{sec-changes-in-v120}{A.1.3.\hspace*{0.5em}Changes in v1.2.0}}%mdk + +\mdtocitemx{sec-changes-in-v110}{\mdref{sec-changes-in-v110}{A.1.4.\hspace*{0.5em}Changes in v1.1.0}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-annotations}{\mdref{sec-p4-annotations}{A.2.\hspace*{0.5em}P4 Annotations}}%mdk + +\mdtocitemx{sec-value-set-example}{\mdref{sec-value-set-example}{A.3.\hspace*{0.5em}A More Complex Value Set Example}}%mdk + +\mdtocitemx{sec-guidelines-for-implementations}{\mdref{sec-guidelines-for-implementations}{A.4.\hspace*{0.5em}Guidelines for Implementations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-grpc-metadata-maximum-size}{\mdref{sec-grpc-metadata-maximum-size}{A.4.1.\hspace*{0.5em}gRPC Metadata Maximum Size}}%mdk + +\mdtocitemx{sec-grpc-server-maximum-receive-message-size}{\mdref{sec-grpc-server-maximum-receive-message-size}{A.4.2.\hspace*{0.5em}gRPC Server Maximum Receive Message Size}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-entries-files}{\mdref{sec-entries-files}{A.5.\hspace*{0.5em}P4Runtime Entries files}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-bibliography}{\mdref{sec-bibliography}{References}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{215} +\begin{mdtoc}%mdk + +\section*{Figures}\label{sec-figures}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{fig-reference-architecture}{\mdref{fig-reference-architecture}{\mdcaptionlabel{1}. P4Runtime Reference Architecture.}}%mdk + +\mdtocitemx{fig-single-embedded-controller}{\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}. Use-Case: Single Embedded Controller}}%mdk + +\mdtocitemx{fig-single-remote-controller}{\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}. Use-Case: Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-single-remote-controller}{\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}. Use-Case: Embedded Plus Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-controllers}{\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}. Use-Case: Embedded Plus Two Remote Controllers}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-ha-controllers}{\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}. Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk + +\mdtocitemx{fig-error-report}{\mdref{fig-error-report}{\mdcaptionlabel{7}. P4Runtime Error Report Message Format}}%mdk + +\mdtocitemx{fig-psa-metadata-translation}{\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}. P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{216} +\begin{mdtoc}%mdk + +\section*{Tables}\label{sec-tables}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{tab-mapping-p4-obj-ids}{\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}. Mapping of P4Info object type to 8-bit ID prefix value}}%mdk + +\mdtocitemx{tab-format-p4-obj-ids}{\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}. Format of P4Info object IDs}}%mdk + +\mdtocitemx{tab-exmpl-p4-obj-ids}{\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}. Example of statically-assigned P4Info object IDs}}%mdk + +\mdtocitemx{tab-valid-bytestring-encoding}{\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}. Examples of Valid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-invalid-bytestring-encoding}{\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}. Examples of Invalid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-p4-type-usage}{\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}. P4 Type Usage}}%mdk + +\mdtocitemx{tab-p4-annotations}{\mdref{tab-p4-annotations}{\mdcaptionlabel{7}. P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk + +%mdk-data-line={218} +\section{\mdline{218}1.\hspace*{0.5em}\mdline{218}Introduction and Scope}\label{sec-introduction-and-scope}%mdk%mdk + +%mdk-data-line={220} +\noindent\mdline{220}This document is published by the \mdline{220}\emph{P4.org API Working Group}\mdline{220}, which was +chartered\mdline{221}~[\mdcite{p4apiwgcharter}{21}]\mdline{221} to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called \mdline{223}\emph{P4Runtime}\mdline{223}. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +\mdline{226}\href{https://github.com/p4lang/p4runtime/tree/main/proto}{https://github.com/p4lang/p4runtime/tree/main/proto}\mdline{226}.%mdk + +%mdk-data-line={228} +\subsection{\mdline{228}1.1.\hspace*{0.5em}\mdline{228}P4 Language Version Applicability}\label{sec-p4-language-version-applicability}%mdk%mdk + +%mdk-data-line={230} +\noindent\mdline{230}P4Runtime is designed to be implemented in conjunction with the P4\mdline{230}\mdsub{16}\mdline{230} language +version or later. P4\mdline{231}\mdsub{14}\mdline{231} programs should be translated into P4\mdline{231}\mdsub{16}\mdline{231} to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P4\mdline{233}\mdsub{16}\mdline{233} 1.0, but were introduced in P4\mdline{233}\mdsub{16}\mdline{233} 1.2.4\mdline{233}~[\mdcite{p4revisions124}{35}]\mdline{233}. For +this version of P4Runtime, we recommend using P4\mdline{234}\mdsub{16}\mdline{234} 1.2.4\mdline{234}~[\mdcite{p4revisions124}{35}]\mdline{234}.%mdk + +%mdk-data-line={236} +\mdline{236}This version of the P4Runtime specification does not yet explicitly +address compatibility with the following P4\mdline{237}\mdsub{16}\mdline{237} language features +introduced in versions 1.2.2 or 1.2.4 of the language specification:%mdk + +%mdk-data-line={240} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={240} +\item\mdline{240}Added support for generic structures\mdline{240}~[\mdcite{p4revisions122}{34}]\mdline{240}.%mdk + +%mdk-data-line={241} +\item\mdline{241}Added support for additional enumeration types\mdline{241}~[\mdcite{p4revisions122}{34}]\mdline{241}.%mdk + +%mdk-data-line={242} +\item\mdline{242}Added support for 0-width bitstrings and varbits\mdline{242}~[\mdcite{p4revisions122}{34}]\mdline{242}.%mdk + +%mdk-data-line={243} +\item\mdline{243}Clarified restrictions for parameters with default values +\mdline{244}[\mdcite{p4revisions124}{35}]\mdline{244}.%mdk + +%mdk-data-line={245} +\item\mdline{245}Allow ranges to be specified by serializable enums +\mdline{246}[\mdcite{p4revisions124}{35}]\mdline{246}.%mdk + +%mdk-data-line={247} +\item\mdline{247}Added \mdline{247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}list}}}\mdline{247} type\mdline{247}~[\mdcite{p4revisions124}{35}]\mdline{247}.%mdk + +%mdk-data-line={248} +\item\mdline{248}Clarified behavior of table with no \mdline{248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{248} property, or if its list +of keys is empty\mdline{249}~[\mdcite{p4revisions124}{35}]\mdline{249}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={252} +\subsection{\mdline{252}1.2.\hspace*{0.5em}\mdline{252}In Scope}\label{sec-in-scope}%mdk%mdk + +%mdk-data-line={254} +\noindent\mdline{254}This specification document defines the \mdline{254}\emph{semantics}\mdline{254} of \mdline{254}\emph{P4Runtime}\mdline{254} messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime:%mdk + +%mdk-data-line={258} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={258} +\item\mdline{258}Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA)\mdline{259}~[\mdcite{psa}{24}]\mdline{259} externs (\mdline{259}e.g.\mdline{259} Counters, Meters, Action +Profiles, \mdline{260}\dots{}\mdline{260}). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0.%mdk + +%mdk-data-line={262} +\item\mdline{262}Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism.%mdk + +%mdk-data-line={264} +\item\mdline{264}Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy.%mdk + +%mdk-data-line={267} +\item\mdline{267}Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities.%mdk + +%mdk-data-line={269} +\item\mdline{269}Packet I/O to enable streaming packets to \mdline{269}\&\mdline{269} from the control plane.%mdk + +%mdk-data-line={270} +\item\mdline{270}Batching support, with different atomicity guarantees.%mdk + +%mdk-data-line={271} +\item\mdline{271}In-the-field device-reconfiguration with a new P4 data plane.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={273} +\noindent\mdline{273}The following are in the scope of this specification document:%mdk + +%mdk-data-line={275} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={275} +\item\mdline{275}Rationale for the P4Runtime design.%mdk + +%mdk-data-line={276} +\item\mdline{276}Reference architecture and use-cases for deploying a P4Runtime service.%mdk + +%mdk-data-line={277} +\item\mdline{277}Detailed description of the API semantics.%mdk + +%mdk-data-line={278} +\item\mdline{278}Requirements for conformant implementations of the API.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={280} +\subsection{\mdline{280}1.3.\hspace*{0.5em}\mdline{280}Not In Scope}\label{sec-not-in-scope}%mdk%mdk + +%mdk-data-line={282} +\noindent\mdline{282}The following are not in scope of P4Runtime:%mdk + +%mdk-data-line={284} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={284} +\item\mdline{284}Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +\mdline{289}[\mdcite{openconfig}{41}]\mdline{289}. An open source implementation of these APIs is also in progress +as part of the Stratum project\mdline{290}~[\mdcite{stratum}{43}]\mdline{290}.%mdk + +%mdk-data-line={291} +\item\mdline{291}Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={296} +\noindent\mdline{296}The following are not in scope of this specification document:%mdk + +%mdk-data-line={298} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={298} +\item\mdline{298}Description of the P4 programming language; it is assumed that the reader is +already familiar with P4\mdline{299}\mdsub{16}\mdline{299}~[\mdcite{p4spec}{1}]\mdline{299}.%mdk + +%mdk-data-line={300} +\item\mdline{300}Descriptions of gRPC and Protobuf files in general.%mdk + +%mdk-data-line={301} +\item\mdline{301}Controller\mdline{301}~\mdref{sec-arbitration-role-config}{role}\mdline{301} definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={305} +\section{\mdline{305}2.\hspace*{0.5em}\mdline{305}Terms and Definitions}\label{sec-terms-and-definitions}%mdk%mdk + +%mdk-data-line={307} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries arbitration}}%mdk + +%mdk-data-line={307} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{307}Refers to the process through which P4Runtime ensures that at any given +time, there is a single primary controller (\mdline{308}i.e.\mdline{308} a client with write access) +for a given role. Also referred to as \mdline{309}\textquotedblleft{}client arbitration\textquotedblright{}\mdline{309}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries client}}%mdk + +%mdk-data-line={311} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{311}The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries COS}}%mdk + +%mdk-data-line={315} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{315}Class of Service. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries device}}%mdk + +%mdk-data-line={317} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{317}Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries entity}}%mdk + +%mdk-data-line={321} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{321}An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries gRPC}}%mdk + +%mdk-data-line={324} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{324}gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +\mdline{325}[\mdcite{grpc}{11}]\mdline{325}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries HA}}%mdk + +%mdk-data-line={327} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{327}High-Availability. Refers to a redundancy architecture. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Instrumentation}}%mdk + +%mdk-data-line={329} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{329}The part of the P4Runtime server which implements the calls to the device or +target native \mdline{330}\textquotedblleft{}SDK\textquotedblright{}\mdline{330} or backend. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries IPC}}%mdk + +%mdk-data-line={332} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{332}Inter-Process Communication. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Blob}}%mdk + +%mdk-data-line={334} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{334}A more colloquial term for P4 Device Config (Blob = Binary Large Object). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Device Config}}%mdk + +%mdk-data-line={336} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{336}The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its \mdline{338}\textquotedblleft{}program.\textquotedblright{}\mdline{338} +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4Info}}%mdk + +%mdk-data-line={340} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{340}Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4RT}}%mdk + +%mdk-data-line={344} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{344}Abbreviation for P4Runtime. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Protobuf (Protocol Buffers)}}%mdk + +%mdk-data-line={346} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{346}The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See\mdline{347}~[\mdcite{proto}{26}]\mdline{347}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries PSA}}%mdk + +%mdk-data-line={349} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{349}Portable Switch Architecture\mdline{349}~[\mdcite{psa}{24}]\mdline{349}; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RPC}}%mdk + +%mdk-data-line={353} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{353}Remote Procedure Call. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RTT}}%mdk + +%mdk-data-line={355} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{355}Round-trip time. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN}}%mdk + +%mdk-data-line={357} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{357}Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network \mdline{362}\emph{controller}\mdline{362}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN port}}%mdk + +%mdk-data-line={364} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{364}A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries server}}%mdk + +%mdk-data-line={368} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{368}The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries stream}}%mdk + +%mdk-data-line={372} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{372}Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (\mdline{373}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{373}), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and client arbitration, among other things. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries switch config}}%mdk + +%mdk-data-line={377} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{377}Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries target}}%mdk + +%mdk-data-line={382} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{382}The hardware or software entity which \mdline{382}\textquotedblleft{}executes\textquotedblright{}\mdline{382} the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with \mdline{383}\textquotedblleft{}device\textquotedblright{}\mdline{383}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries URI}}%mdk + +%mdk-data-line={385} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{385}Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={389} +\section{\mdline{389}3.\hspace*{0.5em}\mdline{389}Reference Architecture}\label{sec-reference-architecture}%mdk%mdk + +%mdk-data-line={391} +\noindent\mdline{391}Figure\mdline{391}~\mdref{fig-reference-architecture}{\mdcaptionlabel{1}}\mdline{391} represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. P4Runtime only grants write access to a +single primary controller for each read/write entity. A role defines a grouping +of P4 entities. P4Runtime allows for a primary controller for each role, and a +role-based client arbitration scheme ensures only one controller has +write access to each read/write entity, or the pipeline config itself. Any +controller may perform read access to any entity or the pipeline config. Later +sections describe this in detail. For the sake of brevity, the term controller +may refer to one or more controllers.%mdk + +%mdk-data-line={402} +\mdline{402}The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +\mdline{405}[\mdcite{p4runtimerepo}{19}]\mdline{405}. It may be compiled via protoc\mdline{405} \mdline{405}\textemdash{}\mdline{405} the Protobuf compiler\mdline{405} \mdline{405}\textemdash{}\mdline{405} +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server.%mdk + +%mdk-data-line={410} +\mdline{410}Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository\mdline{411}~[\mdcite{pirepo}{20}]\mdline{411}. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, \mdline{413}e.g.\mdline{413} via callbacks, thus reducing the burden of implementing +P4Runtime.%mdk + +%mdk-data-line={416} +\mdline{416}The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard.%mdk + +%mdk-data-line={420} +\mdline{420}The controller can also set the \mdline{420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{420}, which amounts to +installing and running the compiled P4 program output, which is included in the +\mdline{422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{422} Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +\mdline{424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{424} to retrieve the device config and the P4Info.%mdk + +%mdk-data-line={427} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={428} +\noindent\mdline{428}\includegraphics[keepaspectratio=true,height=7cm]{build/reference-architecture}{}\mdline{428}%mdk + +%mdk-data-line={429} +\mdhr{}%mdk + +%mdk-data-line={430} +\noindent\mdline{430}\mdcaption{\textbf{Figure~\mdcaptionlabel{1}.}~\mdcaptiontext{P4Runtime Reference Architecture.}}%mdk +%mdk +\end{mdcenter}\label{fig-reference-architecture}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={434} +\subsection{\mdline{434}3.1.\hspace*{0.5em}\mdline{434}P4Runtime Service Implementation}\label{sec-p4runtime-service-implementation}%mdk%mdk + +%mdk-data-line={436} +\noindent\mdline{436}The P4Runtime API is implemented by a program that runs a gRPC server which +binds an implementation of auto-generated P4Runtime Service interface. This +program is called the \mdline{438}\textquotedblleft{}P4Runtime server.\textquotedblright{}\mdline{438} The server must listen on TCP port +9559 by default, which is the port that has been allocated by IANA for the +P4Runtime service. Servers should allow users to override the default port +using a configuration file or flag when starting the server. Uses of other +port numbers as the default should be discontinued.%mdk + +%mdk-data-line={444} +\subsubsection{\mdline{444}3.1.1.\hspace*{0.5em}\mdline{444}Security concerns}\label{sec-security-concerns}%mdk%mdk + +%mdk-data-line={446} +\noindent\mdline{446}Appropriate measures and security best practices must be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. Mutual TLS (mTLS) may +be used to facilitate the authentication of the client by the server and +vice-versa.%mdk + +%mdk-data-line={455} +\subsection{\mdline{455}3.2.\hspace*{0.5em}\mdline{455}Idealized Workflow}\label{sec-idealized-workflow}%mdk%mdk + +%mdk-data-line={457} +\noindent\mdline{457}In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the \mdline{458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{458} +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a \mdline{460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{460} +RPC. Metadata in the P4Info describes both the overall program itself +(\mdline{462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{462}) as well as all entity instances derived from the P4 program\mdline{462} \mdline{462}\textemdash{}\mdline{462} +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise \mdline{464}\textquotedblleft{}handle\textquotedblright{}\mdline{464} used in API +calls.%mdk + +%mdk-data-line={467} +\mdline{467}In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible.%mdk + +%mdk-data-line={473} +\mdline{473}In some use cases, it is expected that a controller will store a +collection of multiple P4 \mdline{474}\textquotedblleft{}packages\textquotedblright{}\mdline{474}, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the \mdline{476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{476} from the target via the +\mdline{477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineRequest}}}\mdline{477} RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state.%mdk + +%mdk-data-line={481} +\subsection{\mdline{481}3.3.\hspace*{0.5em}\mdline{481}P4 as a Behavioral Description Language}\label{sec-p4-as-behavioral-description-language}%mdk%mdk + +%mdk-data-line={483} +\noindent\mdline{483}P4 can be considered a behavioral description of a switching device which may or +may not execute \mdline{484}\textquotedblleft{}P4\textquotedblright{}\mdline{484} natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a \mdline{486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineRequest}}}\mdline{486} to +change its pipeline \mdline{487}\textquotedblleft{}program\textquotedblright{}\mdline{487}, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device.%mdk + +%mdk-data-line={493} +\mdline{493}While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API.%mdk + +%mdk-data-line={502} +\mdline{502}In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the \mdline{503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{503} +message as well as the embedded \mdline{504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{504} fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections.%mdk + +%mdk-data-line={508} +\subsection{\mdline{508}3.4.\hspace*{0.5em}\mdline{508}Alternative Workflows}\label{sec-alternative-workflows}%mdk%mdk + +%mdk-data-line={510} +\noindent\mdline{510}Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary.%mdk + +%mdk-data-line={514} +\subsubsection{\mdline{514}3.4.1.\hspace*{0.5em}\mdline{514}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}\label{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}%mdk%mdk + +%mdk-data-line={516} +\noindent\mdline{516}In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +\mdline{518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{518}. The device\mdline{518}'\mdline{518}s configuration might be derived via some other +means to implement the P4 source code\mdline{519}'\mdline{519}s intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane.%mdk + +%mdk-data-line={523} +\subsubsection{\mdline{523}3.4.2.\hspace*{0.5em}\mdline{523}No P4 Source Available, P4Info Available}\label{sec-no-p4-source-available-p4info-available}%mdk%mdk + +%mdk-data-line={525} +\noindent\mdline{525}In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are:%mdk + +%mdk-data-line={528} +\begin{enumerate}%mdk + +%mdk-data-line={528} +\item{} +%mdk-data-line={528} +\mdline{528}The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security.%mdk%mdk + +%mdk-data-line={531} +\item{} +%mdk-data-line={531} +\mdline{531}The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={534} +\noindent\mdline{534}As discussed in Section\mdline{534}~\mdref{sec-p4-as-behavioral-description-language}{3.3}\mdline{534}, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, \mdline{537}e.g.\mdline{537} documentation.%mdk + +%mdk-data-line={539} +\subsubsection{\mdline{539}3.4.3.\hspace*{0.5em}\mdline{539}Partial P4Info and P4 Source are Available}\label{sec-partial-p4info-and-p4-source-are-available}%mdk%mdk + +%mdk-data-line={541} +\noindent\mdline{541}In this situation, a subset of the target\mdline{541}'\mdline{541}s pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code.%mdk + +%mdk-data-line={548} +\subsubsection{\mdline{548}3.4.4.\hspace*{0.5em}\mdline{548}P4Info Role-Based Subsets}\label{sec-p4info-role-based-subsets}%mdk%mdk + +%mdk-data-line={550} +\noindent\mdline{550}In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more.%mdk + +%mdk-data-line={554} +\subsection{\mdline{554}3.5.\hspace*{0.5em}\mdline{554}P4Runtime State Across Restarts}\label{sec-restarts}%mdk%mdk + +%mdk-data-line={556} +\noindent\mdline{556}All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade.%mdk + +%mdk-data-line={562} +\section{\mdline{562}4.\hspace*{0.5em}\mdline{562}Controller Use-cases}\label{sec-controller-use-cases}%mdk%mdk + +%mdk-data-line={564} +\noindent\mdline{564}P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +\mdline{566}\mdref{sec-client-arbitration-and-controller-replication}{section}\mdline{566}. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime\mdline{568}'\mdline{568}s flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex.%mdk + +%mdk-data-line={571} +\subsection{\mdline{571}4.1.\hspace*{0.5em}\mdline{571}Single Embedded Controller}\label{sec-single-embedded-controller}%mdk%mdk + +%mdk-data-line={573} +\noindent\mdline{573}Figure\mdline{573}~\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}}\mdline{573} shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases.%mdk + +%mdk-data-line={578} +\mdline{578}P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC.%mdk + +%mdk-data-line={583} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={584} +\noindent\mdline{584}\includegraphics[keepaspectratio=true,height=6cm]{build/single-embedded-controller}{}\mdline{584}%mdk + +%mdk-data-line={585} +\mdhr{}%mdk + +%mdk-data-line={586} +\noindent\mdline{586}\mdcaption{\textbf{Figure~\mdcaptionlabel{2}.}~\mdcaptiontext{Use-Case: Single Embedded Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-embedded-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={590} +\subsection{\mdline{590}4.2.\hspace*{0.5em}\mdline{590}Single Remote Controller}\label{sec-single-remote-controller}%mdk%mdk + +%mdk-data-line={592} +\noindent\mdline{592}Figure\mdline{592}~\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}}\mdline{592} shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections.%mdk + +%mdk-data-line={597} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={598} +\noindent\mdline{598}\includegraphics[keepaspectratio=true,height=7cm]{build/single-remote-controller}{}\mdline{598}%mdk + +%mdk-data-line={599} +\mdhr{}%mdk + +%mdk-data-line={600} +\noindent\mdline{600}\mdcaption{\textbf{Figure~\mdcaptionlabel{3}.}~\mdcaptiontext{Use-Case: Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={604} +\subsection{\mdline{604}4.3.\hspace*{0.5em}\mdline{604}Embedded\mdline{604} \mdline{604}+ Single Remote Controller}\label{sec-embedded-single-remote-controller}%mdk%mdk + +%mdk-data-line={606} +\noindent\mdline{606}Figure\mdline{606}~\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}}\mdline{606} illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller.%mdk + +%mdk-data-line={613} +\mdline{613}For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables.%mdk + +%mdk-data-line={617} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={618} +\noindent\mdline{618}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-single-remote-controller}{}\mdline{618}%mdk + +%mdk-data-line={619} +\mdhr{}%mdk + +%mdk-data-line={620} +\noindent\mdline{620}\mdcaption{\textbf{Figure~\mdcaptionlabel{4}.}~\mdcaptiontext{Use-Case: Embedded Plus Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={625} +\subsection{\mdline{625}4.4.\hspace*{0.5em}\mdline{625}Embedded\mdline{625} \mdline{625}+ Two Remote Controllers}\label{sec-embedded-two-remote-controllers}%mdk%mdk + +%mdk-data-line={627} +\noindent\mdline{627}Figure\mdline{627}~\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}}\mdline{627} illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +\mdline{630}e.g.\mdline{630} routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership.%mdk + +%mdk-data-line={633} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={634} +\noindent\mdline{634}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-controllers}{}\mdline{634}%mdk + +%mdk-data-line={635} +\mdhr{}%mdk + +%mdk-data-line={636} +\noindent\mdline{636}\mdcaption{\textbf{Figure~\mdcaptionlabel{5}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={641} +\subsection{\mdline{641}4.5.\hspace*{0.5em}\mdline{641}Embedded Controller\mdline{641} \mdline{641}+ Two High-Availability Remote Controllers}\label{sec-embedded-controller-two-high-availability-remote-controllers}%mdk%mdk + +%mdk-data-line={643} +\noindent\mdline{643}Figure\mdline{643}~\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}}\mdline{643} illustrates a single +embedded controller plus two remote controllers in an active-standby (\mdline{644}i.e.\mdline{644} +primary-backup) HA (High-Availability) configuration. Controller \mdline{645}\#\mdline{645}1 is the +active controller and is in charge of some entities. If it fails, Controller \mdline{646}\#\mdline{646}2 +takes over and manages the tables formerly owned by Controller \mdline{647}\#\mdline{647}1. The mechanics +of HA architectures are beyond the scope of this document, but the P4Runtime +role-based client arbitration scheme supports it.%mdk + +%mdk-data-line={651} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={652} +\noindent\mdline{652}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-ha-controllers}{}\mdline{652}%mdk + +%mdk-data-line={653} +\mdhr{}%mdk + +%mdk-data-line={654} +\noindent\mdline{654}\mdcaption{\textbf{Figure~\mdcaptionlabel{6}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-ha-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={659} +\section{\mdline{659}5.\hspace*{0.5em}\mdline{659}Client Arbitration and Controller Replication}\label{sec-client-arbitration-and-controller-replication}%mdk%mdk + +%mdk-data-line={662} +\noindent\mdline{662}The P4Runtime interface allows multiple clients (\mdline{662}i.e.\mdline{662} controllers) to be +connected to the P4Runtime server running on the device at the same time for the +following reasons:%mdk + +%mdk-data-line={666} +\begin{enumerate}%mdk + +%mdk-data-line={666} +\item{} +%mdk-data-line={666} +\mdline{666}Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, \mdline{667}\textquotedblleft{}roles\textquotedblright{}\mdline{667} (or \mdline{667}\textquotedblleft{}realms\textquotedblright{}\mdline{667}) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +primary and the rest are backups. Role definition, \mdline{670}i.e.\mdline{670} how P4 entities get +assigned to each role, is \mdline{671}\textbf{out-of-scope}\mdline{671} of this document.%mdk%mdk + +%mdk-data-line={673} +\item{} +%mdk-data-line={673} +\mdline{673}Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby backup controllers. These can already have a connection +open, which can help them become primary more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={679} +\noindent\mdline{679}To support multiple controllers, P4Runtime uses the streaming channel (available +via \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{680} RPC) for session management. The workflow is described as +follows:%mdk + +%mdk-data-line={683} +\begin{itemize}%mdk + +%mdk-data-line={683} +\item{} +%mdk-data-line={683} +\mdline{683}Each controller instance (\mdline{683}e.g.\mdline{683} a controller process) can participate in one or +more roles. For each (\mdline{684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{684}, \mdline{684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{684}), the controller receives an +\mdline{685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{685}. This \mdline{685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{685} can be the same for different roles and/or +devices, as long as the tuple (\mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{686}, \mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{686}, \mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{686}) is +unique among live controllers, as defined below. For each (\mdline{687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{687}, +\mdline{688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{688}) that the controller wishes to control, it establishes a +\mdline{689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{689} with the P4Runtime server responsible for that device, and +sends a \mdline{690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{690} message containing that tuple of +(\mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{691}, \mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{691}, \mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{691}) values. The P4Runtime server selects a +primary independently for each (\mdline{692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{692}, \mdline{692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{692}) pair. The primary is the +client that has the highest \mdline{693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{693} that the device has ever received +for the same (\mdline{694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{694}, \mdline{694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{694}) values. A connection between a controller +instance and a device id\mdline{695} \mdline{695}\textemdash{}\mdline{695} which involves a persistent \mdline{695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{695} \mdline{695}\textemdash{}\mdline{695} +can be referred to as a P4Runtime client.%mdk + +%mdk-data-line={698} +\mdline{698}Note that the P4Runtime server does not assign a \mdline{698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{698} or \mdline{698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{698} to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the \mdline{700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{700} values used for each +\mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{701}. The P4Runtime server only keeps track of the (\mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{701}, +\mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{702}, \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{702}) of each \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{702} that has sent a successful +\mdline{703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{703} message, and maintains the invariant that all such +3-tuples are unique among live controllers. A server must use all three of +these values from a \mdline{705}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{705} message to identify which client is making +the \mdline{706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{706}, not only the \mdline{706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{706}. This enables controllers to +re-use the same numeric \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{707} values across different (\mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{707}, +\mdline{708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{708}) pairs. P4Runtime does not require \mdline{708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{708} values be reused +across such different (\mdline{709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{709}, \mdline{709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{709}) pairs; it allows it.%mdk%mdk + +%mdk-data-line={711} +\item{} +%mdk-data-line={711} +\mdline{711}To start a controller session, a controller first opens a bidirectional stream +channel to the server via the \mdline{712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{712} RPC for each device. This stream +will be used for two purposes:%mdk + +%mdk-data-line={715} +\begin{itemize}%mdk + +%mdk-data-line={715} +\item{} +%mdk-data-line={715} +\mdline{715}\textbf{Session management:}\mdline{715} As soon as the controller opens the stream +channel, it sends a \mdline{716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{716} message to the switch. The +controller populates the \mdline{717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{717} field in this message +using its \mdline{718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{718} and \mdline{718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{718}, as well as the \mdline{718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{718} of the +device. Note that the \mdline{719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{719} field in the \mdline{719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{719} is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below.%mdk%mdk + +%mdk-data-line={723} +\item{} +%mdk-data-line={723} +\mdline{723}\textbf{Streaming of notifications (e.g. digests) and packet I/O:}\mdline{723} The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the primary controller can participate in +packet I/O. This feature is explained in more details in the\mdline{727}~\mdref{sec-packet-i_o}{Packet +I/O}\mdline{728} section.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={730} +\mdline{730}Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state.%mdk%mdk + +%mdk-data-line={733} +\item{} +%mdk-data-line={733} +\mdline{733}Note that the stream is opened per device. In case a switching platform has +multiple devices (\mdline{734}e.g.\mdline{734} multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different primary clients for +different devices. In this case, it is the responsibility of the P4Runtime +server to keep track of the primary for each device (and role). More +specifically, the P4Runtime server will know which stream corresponds to the +primary controller for each pair of (\mdline{739}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{739}, \mdline{739}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{739}) at any point of +time.%mdk%mdk + +%mdk-data-line={742} +\item{} +%mdk-data-line={742} +\mdline{742}The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered \mdline{743}\textquotedblleft{}offline\textquotedblright{}\mdline{743}, +\mdline{744}\textquotedblleft{}disconnected\textquotedblright{}\mdline{744}, or \mdline{744}\textquotedblleft{}dead\textquotedblright{}\mdline{744} as soon as its stream channel to the switch is +broken. When a primary channel gets broken:%mdk + +%mdk-data-line={747} +\begin{enumerate}%mdk + +%mdk-data-line={747} +\item{} +%mdk-data-line={747} +\mdline{747}An advisory message is sent to all other controllers for that \mdline{747}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{747} +and \mdline{748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{748}, as described in a +\mdline{749}\mdref{sec-arbitration-notification}{later section}\mdline{749}; and%mdk%mdk + +%mdk-data-line={751} +\item{} +%mdk-data-line={751} +\mdline{751}The P4Runtime server will be without a primary controller, until a client +sends a successful \mdline{752}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{752} (as per the rules in a +\mdline{753}\mdref{sec-arbitration-updates}{later section}\mdline{753}).%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={755} +\item{} +%mdk-data-line={755} +\mdline{755}The mechanism through which the controller receives the P4Runtime server +details are implementation specific and beyond the scope of this +specification. This includes the \mdline{757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{757}, \mdline{757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip}}}\mdline{757} and \mdline{757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{757}, as +well as the Forwarding Pipeline Config. Similarly, the mechanism through +which the P4Runtime server receives its switch config (which notably includes +the \mdline{760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{760}) is beyond the scope of this specification. Nevertheless, if +the server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={765} +\noindent\mdline{765}gRPC enables the server to identify which client originated each message in the +\mdline{766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{766} stream. For example, the C++ gRPC library\mdline{766}~[\mdcite{grpcstreamc}{12}]\mdline{766} in +synchronous mode enables a server process to cause a function to be called when +a new client creates a \mdline{768}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{768} stream. This function should not return +until the stream is closed and the server has completed any cleanup required +when a \mdline{770}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{770} is closed normally (or broken, \mdline{770}e.g.\mdline{770} because a client +process unexpectedly terminated). Thus the server can easily associate all +\mdline{772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{772} messages received from the same client, because they are +processed within the context of the same function call.%mdk + +%mdk-data-line={775} +\mdline{775}A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values \mdline{780}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{780}, \mdline{780}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{780}, and \mdline{780}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{780} in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods\mdline{782}~[\mdcite{grpcauth}{10}]\mdline{782} that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server.%mdk + +%mdk-data-line={786} +\subsection{\mdline{786}5.1.\hspace*{0.5em}\mdline{786}Default Role}\label{sec-default-role}%mdk%mdk + +%mdk-data-line={788} +\noindent\mdline{788}A controller can omit the role message in \mdline{788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{788}. This +implies the \mdline{789}\textquotedblleft{}default role\textquotedblright{}\mdline{789}, which corresponds to \mdline{789}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{789}. +This also implies that a default role has a \mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{790} of \mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}""}}}\mdline{790} (default). +If using a default role, all RPCs from the controller (\mdline{791}e.g.\mdline{791} \mdline{791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{791}) must +leave the \mdline{792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{792} unset.%mdk + +%mdk-data-line={794} +\subsection{\mdline{794}5.2.\hspace*{0.5em}\mdline{794}Role Config}\label{sec-arbitration-role-config}%mdk%mdk + +%mdk-data-line={796} +\noindent\mdline{796}The \mdline{796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{796} field in the \mdline{796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{796} message sent by the +controller describes the role configuration, \mdline{797}i.e.\mdline{797} which operations are in the +scope of a given role. In particular, the definition of a role may include the +following:%mdk + +%mdk-data-line={801} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={801} +\item\mdline{801}A list of P4 entities for which the controller may issue \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{801} updates and +receive notification messages (\mdline{802}e.g.\mdline{802} \mdline{802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{802} and +\mdline{803}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{803}).%mdk + +%mdk-data-line={804} +\item\mdline{804}Whether the controller is able to receive \mdline{804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{804} messages, along with a +filtering mechanism based on the values of the \mdline{805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{805} fields to +select which \mdline{806}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{806} messages should be sent to the controller.%mdk + +%mdk-data-line={807} +\item\mdline{807}Whether the controller is able to send \mdline{807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{807} messages, along with a +filtering mechanism based on the values of the \mdline{808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{808} fields to +select which \mdline{809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{809} messages are allowed to be sent by the controller.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={811} +\noindent\mdline{811}An unset \mdline{811}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{811} implies \mdline{811}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{811} (similar to the default +role explained above). In order to support different role definition schemes, +\mdline{813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{813} is defined as an \mdline{813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{813} Protobuf message\mdline{813}~[\mdcite{protoany}{37}]\mdline{813}. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion.%mdk + +%mdk-data-line={818} +\mdline{818}It is the job of the P4Runtime server to remember the \mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{818} for every +\mdline{819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{819} and \mdline{819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{819} pair.%mdk + +%mdk-data-line={821} +\subsection{\mdline{821}5.3.\hspace*{0.5em}\mdline{821}Rules for Handling \mdline{821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{821} Messages Received from Controllers}\label{sec-arbitration-updates}%mdk%mdk + +%mdk-data-line={823} +\begin{enumerate}%mdk + +%mdk-data-line={823} +\item{} +%mdk-data-line={823} +\mdline{823}If the \mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{823} message is received for the first time on +this particular channel (\mdline{824}i.e.\mdline{824} for a newly connected controller):%mdk + +%mdk-data-line={826} +\begin{enumerate}%mdk + +%mdk-data-line={826} +\item{} +%mdk-data-line={826} +\mdline{826}If \mdline{826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{826} does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +\mdline{828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{828} error.%mdk%mdk + +%mdk-data-line={830} +\item{} +%mdk-data-line={830} +\mdline{830}If the \mdline{830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{830} is set and is already used by another live +controller for the same (\mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{831}, \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{831}), the P4Runtime server shall +terminate the stream by returning an \mdline{832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{832} error.%mdk%mdk + +%mdk-data-line={834} +\item{} +%mdk-data-line={834} +\mdline{834}If \mdline{834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{834} does not match the \mdline{834}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{834} scheme previously +agreed upon, the server must return an \mdline{835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{835} error.%mdk%mdk + +%mdk-data-line={837} +\item{} +%mdk-data-line={837} +\mdline{837}If the number of open streams for the given (\mdline{837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{837}, \mdline{837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{837}) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a \mdline{839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{839} error.%mdk%mdk + +%mdk-data-line={841} +\item{} +%mdk-data-line={841} +\mdline{841}Otherwise, the controller is added to a list of live controllers for +the given (\mdline{842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{842}, \mdline{842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{842}) and the server remembers the +controllers \mdline{843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{843}, \mdline{843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{843} and \mdline{843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{843} for this gRPC +channel. See below for the rules to determine if this controller becomes +a primary or backup, and what notifications are sent as a consequence.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={847} +\item{} +%mdk-data-line={847} +\mdline{847}Otherwise, if the \mdline{847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{847} message is received from an +already live controller:%mdk + +%mdk-data-line={850} +\begin{enumerate}%mdk + +%mdk-data-line={850} +\item{} +%mdk-data-line={850} +\mdline{850}If the \mdline{850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{850} does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{852} error.%mdk%mdk + +%mdk-data-line={854} +\item{} +%mdk-data-line={854} +\mdline{854}If the \mdline{854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{854} does not match the current \mdline{854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{854} assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{856} error. If the controller wishes to change its role, +it must close the current stream channel and open a new one.%mdk%mdk + +%mdk-data-line={859} +\item{} +%mdk-data-line={859} +\mdline{859}If \mdline{859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{859} does not match the \mdline{859}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{859} scheme previously +agreed upon, the server must return an \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{860} error.%mdk%mdk + +%mdk-data-line={862} +\item{} +%mdk-data-line={862} +\mdline{862}If the \mdline{862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{862} is set and is already used by another live +controller (excluding the controller making the request) for the same +(\mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{864}, \mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{864}), the P4Runtime server shall terminate the stream +by returning an \mdline{865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{865} error.%mdk%mdk + +%mdk-data-line={867} +\item{} +%mdk-data-line={867} +\mdline{867}Otherwise, the server updates the \mdline{867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{867} it has stored for this +controller. This change might cause a change in the primary client (this +controller might become primary, or the controller might have downgraded +itself to a backup, see below), as well as notifications being sent to +one or more controllers.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={873} +\noindent\mdline{873}If the \mdline{873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{873} is accepted by either of the two steps above +(cases 1.5. and 2.5. above), then the server determines if there are changes in +the primary client. Let \mdline{875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{875} be the highest election ID the server +has ever seen for the given \mdline{876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{876} and \mdline{876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{876} (including the one of the +current primary if there is one).%mdk + +%mdk-data-line={879} +\begin{enumerate}%mdk + +%mdk-data-line={879} +\item{} +%mdk-data-line={879} +\mdline{879}If \mdline{879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{879} is greater than or equal to \mdline{879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{879}, then the +controller becomes, or stays, primary. The server updates the role +configuration to \mdline{881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{881} for the given \mdline{881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{881}. Furthermore:%mdk + +%mdk-data-line={883} +\begin{enumerate}%mdk + +%mdk-data-line={883} +\item{} +%mdk-data-line={883} +\mdline{883}If there was no primary for this \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{883} and \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{883} before and +there are no \mdline{884}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{884} requests still processing from a previous primary, +then the server immediately sends an advisory notification to all +controllers for this \mdline{886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{886} and \mdline{886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{886}. See the +\mdline{887}\mdref{sec-arbitration-notification}{following section}\mdline{887} for the format of the +advisory message.%mdk%mdk + +%mdk-data-line={890} +\item{} +%mdk-data-line={890} +\mdline{890}If there was a previous primary, including this controller, or \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{890} +requests in flight, then the server carries out the following steps +(in this order):%mdk + +%mdk-data-line={894} +\begin{enumerate}%mdk + +%mdk-data-line={894} +\item{} +%mdk-data-line={894} +\mdline{894}The server stops accepting \mdline{894}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{894} requests from the previous primary +(if there is one). At this point, the server will reject all \mdline{895}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{895} +requests with \mdline{896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{896}.%mdk%mdk + +%mdk-data-line={898} +\item{} +%mdk-data-line={898} +\mdline{898}The server notifies all controllers other than the new primary client +of the change by sending the advisory notification described in +the\mdline{900}~\mdref{sec-arbitration-notification}{following section}\mdline{900}.%mdk%mdk + +%mdk-data-line={902} +\item{} +%mdk-data-line={902} +\mdline{902}The server will finish processing any \mdline{902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{902} requests that have +already started. If there are errors, they are reported as usual to +the previous primary. If the previous primary has already +disconnected, any possible errors are dropped and not reported.%mdk%mdk + +%mdk-data-line={907} +\item{} +%mdk-data-line={907} +\mdline{907}The server now accepts the current controller as the new primary, +thus accepting \mdline{908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{908} requests from this controller. The server +updates the highest election ID (\mdline{909}i.e.\mdline{909} \mdline{909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{909}) it has seen +for this \mdline{910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{910} and \mdline{910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{910} to \mdline{910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{910}.%mdk%mdk + +%mdk-data-line={912} +\item{} +%mdk-data-line={912} +\mdline{912}The server notifies the new primary by sending the advisory message +described in the\mdline{913}~\mdref{sec-arbitration-notification}{following section}\mdline{913}.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={915} +\item{} +%mdk-data-line={915} +\mdline{915}Otherwise, the controller becomes a backup. If the controller was previously +a primary (and downgraded itself), then an advisory message is sent to all +controllers for this \mdline{917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{917} and \mdline{917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{917}. Otherwise, the advisory +message is only sent to the controller that sent the initial +\mdline{919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{919}. See the +\mdline{920}\mdref{sec-arbitration-notification}{following section}\mdline{920} for the format of the +advisory message.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={923} +\subsection{\mdline{923}5.4.\hspace*{0.5em}\mdline{923}Client Arbitration Notifications}\label{sec-arbitration-notification}%mdk%mdk + +%mdk-data-line={925} +\noindent\mdline{925}For any given \mdline{925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{925} and \mdline{925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{925}, any time a new primary is chosen, a +primary downgrades its status to a backup, a primary disconnects, or the +\mdline{927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{927} is updated by the primary, all controllers for that +(\mdline{928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{928}, \mdline{928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{928}) are informed of this by sending a +\mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{929}. The \mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{929} is populated as follows:%mdk + +%mdk-data-line={931} +\begin{itemize}%mdk + +%mdk-data-line={931} +\item{} +%mdk-data-line={931} +\mdline{931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{931} and \mdline{931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{931} as given.%mdk%mdk + +%mdk-data-line={933} +\item{} +%mdk-data-line={933} +\mdline{933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{933} is set to the role configuration the server received most +recently in a \mdline{934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{934} from a primary.%mdk%mdk + +%mdk-data-line={936} +\item{} +%mdk-data-line={936} +\mdline{936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{936} is populated as follows:%mdk + +%mdk-data-line={938} +\begin{itemize}%mdk + +%mdk-data-line={938} +\item{} +%mdk-data-line={938} +\mdline{938}If there has not been any primary at all, the election\mdline{938}\_\mdline{938}id is left unset.%mdk%mdk + +%mdk-data-line={940} +\item{} +%mdk-data-line={940} +\mdline{940}Otherwise, \mdline{940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{940} is set to the highest election ID that the server +has seen for this \mdline{941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{941} and \mdline{941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{941} (which is the \mdline{941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{941} of +the current primary if there is any).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={944} +\item{} +%mdk-data-line={944} +\mdline{944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{944} is set differently based on whether the notification is sent to the +primary or a backup controller:%mdk + +%mdk-data-line={947} +\begin{itemize}%mdk + +%mdk-data-line={947} +\item{} +%mdk-data-line={947} +\mdline{947}If there is a primary:%mdk + +%mdk-data-line={949} +\begin{itemize}%mdk + +%mdk-data-line={949} +\item{} +%mdk-data-line={949} +\mdline{949}For the primary, \mdline{949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{949} is OK (with \mdline{949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{949} set to +\mdline{950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.OK}}}\mdline{950}).%mdk%mdk + +%mdk-data-line={952} +\item{} +%mdk-data-line={952} +\mdline{952}For all backup controllers, \mdline{952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{952} is set to non-OK (with +\mdline{953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{953} set to \mdline{953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.ALREADY\_EXISTS}}}\mdline{953}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={955} +\item{} +%mdk-data-line={955} +\mdline{955}Otherwise, if there is no primary currently, for all backup controllers, +\mdline{956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{956} is set to non-OK (with \mdline{956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{956} set to +\mdline{957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.NOT\_FOUND}}}\mdline{957}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={959} +\noindent\mdline{959}Note that on primary client changes with outstanding \mdline{959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{959} request, some +notifications might be delayed, see the +\mdline{961}\mdref{sec-arbitration-updates}{previous section}\mdline{961} for details.%mdk + +%mdk-data-line={963} +\section{\mdline{963}6.\hspace*{0.5em}\mdline{963}The P4Info Message}\label{sec-the-p4info-message}%mdk%mdk + +%mdk-data-line={965} +\noindent\mdline{965}The purpose of P4Info was described under +\mdline{966}\mdref{sec-reference-architecture}{Reference Architecture}\mdline{966}. +Here we describe the various +components.%mdk + +%mdk-data-line={970} +\subsection{\mdline{970}6.1.\hspace*{0.5em}\mdline{970}Common Messages}\label{sec-common-messages}%mdk%mdk + +%mdk-data-line={972} +\noindent\mdline{972}These messages appear nested within many other messages.%mdk + +%mdk-data-line={974} +\subsubsection{\mdline{974}6.1.1.\hspace*{0.5em}\mdline{974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{974} Message}\label{sec-documentation-message}%mdk%mdk + +%mdk-data-line={976} +\noindent\mdline{976}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{976} is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers.%mdk + +%mdk-data-line={980} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={981} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Documentation~\{\\ +~~{\mdcolor{darkgreen}//~A~brief~description~of~something,~e.g.~one~sentence}\\ +~~{\bfseries{\mdcolor{navy}string}}~brief~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~A~more~verbose~description~of~something.}\\ +~~{\mdcolor{darkgreen}//~Multiline~is~accepted.~Markup~format~(if~any)~is~TBD.}\\ +~~{\bfseries{\mdcolor{navy}string}}~description~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={990} +\subsubsection{\mdline{990}6.1.2.\hspace*{0.5em}\mdline{990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{990} Message}\label{sec-preamble-message}%mdk%mdk + +%mdk-data-line={992} +\noindent\mdline{992}The preamble serves as the \mdline{992}\textquotedblleft{}descriptor\textquotedblright{}\mdline{992} for each entity and contains the unique +instance ID, name, alias, annotations and documentation.%mdk + +%mdk-data-line={995} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={996} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Preamble~\{\\ +~~{\mdcolor{darkgreen}//~ids~share~the~same~number-space;~e.g.~table~ids~cannot~overlap~with~counter}\\ +~~{\mdcolor{darkgreen}//~ids.~Even~though~this~is~irrelevant~to~this~proto~definition,~the~ids~are}\\ +~~{\mdcolor{darkgreen}//~allocated~in~such~a~way~that~it~is~possible~based~on~an~id~to~deduce~the}\\ +~~{\mdcolor{darkgreen}//~resource~type~(e.g.~table,~action,~counter,~...).~This~means~that~code}\\ +~~{\mdcolor{darkgreen}//~using~these~ids~can~detect~if~the~wrong~resource~type~is~used}\\ +~~{\mdcolor{darkgreen}//~somewhere.~This~also~means~that~ids~of~different~types~can~be~mixed}\\ +~~{\mdcolor{darkgreen}//~(e.g.~direct~resource~list~for~a~table)~without~ambiguity.~Note~that~id~0}\\ +~~{\mdcolor{darkgreen}//~is~reserved~and~means~"invalid~id".}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name~of~the~P4~object,~e.g.~c1.c2.ipv4\_lpm}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~an~alias~(alternative~name)~for~the~P4~object,~probably~shorter~than~its}\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name.~The~only~constraint~is~for~it~to~be~unique~with}\\ +~~{\mdcolor{darkgreen}//~respect~to~other~P4~objects~of~the~same~type.~By~default,~the~compiler~uses}\\ +~~{\mdcolor{darkgreen}//~the~shortest~suffix~of~the~name~that~uniquely~identifies~the~object.~For}\\ +~~{\mdcolor{darkgreen}//~example~if~the~P4~program~contains~two~tables~with~names~s.c1.t~and~s.c2.t,}\\ +~~{\mdcolor{darkgreen}//~the~default~aliases~will~respectively~be~c1.t~and~c2.t.~In~the~future,~the}\\ +~~{\mdcolor{darkgreen}//~P4~programmer~may~also~be~able~to~override~the~default~alias~for~any~P4}\\ +~~{\mdcolor{darkgreen}//~object~(TBD).}\\ +~~{\bfseries{\mdcolor{navy}string}}~alias~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~Optional.~If~present,~the~location~of~`annotations{}[i]`~is~given~by}\\ +~{\mdcolor{darkgreen}//~`annotation\_locations{}[i]`.}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~SourceLocation~annotation\_locations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~Documentation~of~the~entity}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1027} +\subsubsection{\mdline{1027}6.1.3.\hspace*{0.5em}\mdline{1027}Annotating P4 Entities with \mdline{1027}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}\label{sec-annotating-p4-entities-with-documentation}%mdk%mdk + +%mdk-data-line={1029} +\noindent\mdline{1029}P4 entities may be annotated using the following annotations:%mdk + +%mdk-data-line={1031} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1032} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}(string...)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}(string...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1036} +\noindent\mdline{1036}Attaching either or both of these annotations to an entity will generate a +P4Info\mdline{1037}~\mdref{sec-documentation-message}{Documentation Message}\mdline{1037}, which in turn will +appear in the\mdline{1038}~\mdref{sec-preamble-message}{Preamble Message}\mdline{1038} for the entity.%mdk + +%mdk-data-line={1040} +\mdline{1040}The P4 compiler should not emit \mdline{1040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation}}}\mdline{1040} messages in the P4Info for these +specific cases; instead, it should generate the \mdline{1041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1041} messages as +described.%mdk + +%mdk-data-line={1044} +\mdline{1044}The following example shows documentation annotations for a \mdline{1044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table}}}\mdline{1044} entity:%mdk + +%mdk-data-line={1046} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1047} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port.~\textbackslash{}}\\ +Uses~LPM~match~{\bfseries{\mdcolor{navy}type}}.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}table~my\_ipv4\_lkup~\{}\\ +{\mdcolor{maroon}~~...}\\ +{\mdcolor{maroon}\}}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1055} +\subsubsection{\mdline{1055}6.1.4.\hspace*{0.5em}\mdline{1055}Structured Annotations}\label{sec-structured-annotations}%mdk%mdk + +%mdk-data-line={1057} +\noindent\mdline{1057}P4 supports both unstructured and structured annotations\mdline{1057}~[\mdcite{p4annotations}{17}]\mdline{1057}. +Unstructured annotations of the form \mdline{1058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno1}}}\mdline{1058} or \mdline{1058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno2(body-content)}}}\mdline{1058} can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +\mdline{1061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno3{}[]}}}\mdline{1061} or \mdline{1061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno4{}[kvList\textbar{}expressionList]}}}\mdline{1061} have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this.%mdk + +%mdk-data-line={1066} +\mdline{1066}The annotations described up to this point, \mdline{1066}e.g.\mdline{1066} \mdline{1066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief()}}}\mdline{1066}, have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as \mdline{1068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1068} fields in the various \mdline{1068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{1068}s. +Similarly, structured annotations are represented in \mdline{1069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated\\ +StructuredAnnotation~structured\_annotations}}}\mdline{1070} fields which are siblings to the +unstructured \mdline{1071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1071}. The \mdline{1071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations}}}\mdline{1071} contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations.%mdk + +%mdk-data-line={1076} +\mdline{1076}The structured annotation messages are defined in p4types.proto.%mdk + +%mdk-data-line={1078} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1079} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~KeyValuePair~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~key~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Expression~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~KeyValuePairList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~KeyValuePair~kv\_pairs~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Expression~\{\\ +~~{\bfseries{\mdcolor{navy}oneof}}~value~\{\\ +~~~~{\bfseries{\mdcolor{navy}string}}~string\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~{\bfseries{\mdcolor{navy}int64}}~int64\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~{\bfseries{\mdcolor{navy}bool}}~bool\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~ExpressionList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Expression~expressions~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~StructuredAnnotation~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}oneof}}~body~\{\\ +~~~~ExpressionList~expression\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~KeyValuePairList~kv\_pair\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~Optional.~Location~of~the~'@'~symbol~of~this~annotation~in~the~source~code.}\\ +~~SourceLocation~source\_location~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1111} +\noindent\mdline{1111}The \mdline{1111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1111} message can represent either a \mdline{1111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1111} +or an \mdline{1112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExpressionList}}}\mdline{1112}.%mdk + +%mdk-data-line={1114} +\mdline{1114}The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The \mdline{1115}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{1115} +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don\mdline{1117}'\mdline{1117}t match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler \mdline{1119}\emph{may}\mdline{1119} print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions.%mdk + +%mdk-data-line={1123} +\mdline{1123}The following invariants hold:%mdk + +%mdk-data-line={1125} +\begin{enumerate}%mdk + +%mdk-data-line={1125} +\item{} +%mdk-data-line={1125} +\mdline{1125}For any P4 entity, there are no two \mdline{1125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1125}s that have the +same name.%mdk%mdk + +%mdk-data-line={1128} +\item{} +%mdk-data-line={1128} +\mdline{1128}Within a \mdline{1128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1128}, there are no two \mdline{1128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePair}}}\mdline{1128}s that have the +same \mdline{1129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key.}}}\mdline{1129}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1131} +\paragraph{\mdline{1131}6.1.4.1.\hspace*{0.5em}\mdline{1131}Structured Annotation Examples}\label{sec-structured-annotation-examples}%mdk%mdk + +%mdk-data-line={1133} +\noindent\mdline{1133}We omit the \mdline{1133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}source\_location}}}\mdline{1133} field in the following examples.%mdk + +%mdk-data-line={1135} +\mdline{1135}\textbf{Empty Expression List}\mdline{1135}%mdk + +%mdk-data-line={1137} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1138} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}Empty}{\mdcolor{maroon}{}[]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1144} +\noindent\mdline{1144}The generated P4Info will contain the following.%mdk + +%mdk-data-line={1146} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1147} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}Empty}{\mdcolor{maroon}"}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1152} +\noindent\mdline{1152}\textbf{Mixed Expression List}\mdline{1152}%mdk + +%mdk-data-line={1154} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1155} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~TEXT\_CONST~"hello"}\\ +{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~NUM\_CONST~6}\\ +{\mdcolor{gray}@}{\mdcolor{gray}MixedExprList}{\mdcolor{maroon}{}[1,TEXT\_CONST,true,1==2,5+NUM\_CONST]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1163} +\noindent\mdline{1163}The generated P4Info will contain:%mdk + +%mdk-data-line={1165} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1166} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedExprList}{\mdcolor{maroon}"}\\ +~~expression\_list~\{\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}1}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}hello}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~true\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~false\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}11}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1188} +\noindent\mdline{1188}\textbf{kvList of Mixed Expressions}\mdline{1188}%mdk + +%mdk-data-line={1190} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1191} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}MixedKV}{\mdcolor{maroon}{}[label="text",~my\_bool=true,~int\_val=2*3]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1197} +\noindent\mdline{1197}The generated P4Info will contain:%mdk + +%mdk-data-line={1199} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1200} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedKV}{\mdcolor{maroon}"}\\ +~~kv\_pair\_list~\{\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}label}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}text}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}my\_bool}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~bool\_value:~true\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}int\_val}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~int64\_value:~{\mdcolor{purple}6}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1225} +\subsubsection{\mdline{1225}6.1.5.\hspace*{0.5em}\mdline{1225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1225} Message}\label{sec-sourcelocation-message}%mdk%mdk + +%mdk-data-line={1227} +\noindent\mdline{1227}A source location describes a location within a \mdline{1227}\emph{.p4}\mdline{1227}-source file. The +\mdline{1228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1228} message is defined in p4types.proto as follows:%mdk + +%mdk-data-line={1230} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1231} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Location~of~code~relative~to~a~given~source~file.}\\ +{\bfseries{\mdcolor{navy}message}}~SourceLocation~\{\\ +~~{\mdcolor{darkgreen}//~Path~to~the~source~file~(absolute~or~relative~to~the~working~directory).}\\ +~~{\bfseries{\mdcolor{navy}string}}~file~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Line~and~column~numbers~within~the~source~file,~1-based.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~line~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}int32}}~column~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1241} +\noindent\mdline{1241}We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations.%mdk + +%mdk-data-line={1246} +\mdline{1246}The \mdline{1246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1246} message associated with an annotation holds the location of +the \mdline{1247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@}}}\mdline{1247} symbol introducing the annotation in the P4 source code; the message can +be found in the following place:%mdk + +%mdk-data-line={1250} +\begin{itemize}%mdk + +%mdk-data-line={1250} +\item{} +%mdk-data-line={1250} +\mdline{1250}For \mdline{1250}\textbf{unstructured annotations}\mdline{1250}, every message containing a field +\mdline{1251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1251} also contains a field +\mdline{1252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~SourceLocation~annotation\_locations}}}\mdline{1252}. The field must either be empty + or match the size of \mdline{1253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1253}. In the latter case, the i-th member of +\mdline{1254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation\_locations}}}\mdline{1254} is the source location of the i-th member of +\mdline{1255}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1255}.%mdk%mdk + +%mdk-data-line={1257} +\item{} +%mdk-data-line={1257} +\mdline{1257}For \mdline{1257}\textbf{structured annotations}\mdline{1257}, every \mdline{1257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1257} message contains +an optional field \mdline{1258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation~source\_location}}}\mdline{1258} holding its source +location, if present.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1262} +\subsection{\mdline{1262}6.2.\hspace*{0.5em}\mdline{1262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1262} Message}\label{sec-pkginfo-message}%mdk%mdk + +%mdk-data-line={1264} +\noindent\mdline{1264}The \mdline{1264}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1264} message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. \mdline{1265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1265} can be extracted +and used to facilitate \mdline{1266}\textquotedblleft{}browsing\textquotedblright{}\mdline{1266} of available P4 programs from a +library. Although all fields are technically \mdline{1267}\textquotedblleft{}optional,\textquotedblright{}\mdline{1267} every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included.%mdk + +%mdk-data-line={1271} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1272} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Can~be~used~to~manage~multiple~P4~packages.}\\ +{\bfseries{\mdcolor{navy}message}}~PkgInfo~\{\\ +~~{\mdcolor{darkgreen}//~a~definitive~name~for~this~configuration,~e.g.~switch.p4\_v1.0}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~configuration~version,~free-format~string}\\ +~~{\bfseries{\mdcolor{navy}string}}~version~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~brief~and~detailed~descriptions}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~free-form;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~Optional.~If~present,~the~location~of~`annotations{}[i]`~is~given~by}\\ +~~{\mdcolor{darkgreen}//~`annotation\_locations{}[i]`.}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~SourceLocation~annotation\_locations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}10};\\ +~~{\mdcolor{darkgreen}//~the~target~architecture,~e.g.~"psa"}\\ +~~{\bfseries{\mdcolor{navy}string}}~arch~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\mdcolor{darkgreen}//~organization~which~produced~the~configuration,~e.g.~"p4.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~organization~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~{\mdcolor{darkgreen}//~contact~info~for~support,e.g.~"tech-support@acme.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~contact~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~url~for~more~information,~e.g.~"http://support.p4.org/ref/p4/switch.p4\_v1.0"}\\ +~~{\bfseries{\mdcolor{navy}string}}~url~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}8};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~structured;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}9};\\ +~~{\mdcolor{darkgreen}//~If~set,~specifies~the~properties~that~the~underlying~platform~should~have.}\\ +~~{\mdcolor{darkgreen}//~If~the~platform~does~not~conform~to~these~properties,~the~server~should}\\ +~~{\mdcolor{darkgreen}//~reject~the~P4Info~when~used~with~a~SetForwardingPipelineConfigRequest.}\\ +~~PlatformProperties~platform\_properties~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}11};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1302} +\noindent\mdline{1302}where the \mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PlatformProperties}}}\mdline{1302} message looks as follows:%mdk + +%mdk-data-line={1303} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1304} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Used~to~describe~the~required~properties~of~the~underlying~platform.}\\ +{\bfseries{\mdcolor{navy}message}}~PlatformProperties~\{\\ +~~{\mdcolor{darkgreen}//~The~minimum~number~of~multicast~entries~(i.e.~multicast~groups)~that~the}\\ +~~{\mdcolor{darkgreen}//~platform~is~required~to~support.~If~0,~there~are~no~requirements.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~multicast\_group\_table\_size~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~The~minimum~number~of~replicas~that~the~platform~is~required~to~support}\\ +~~{\mdcolor{darkgreen}//~across~all~~groups.~If~0,~there~are~no~requirements.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~multicast\_group\_table\_total\_replicas~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~The~number~of~replicas~that~the~platform~is~required~to~support~per}\\ +~~{\mdcolor{darkgreen}//~group/entry.~If~0,~`multicast\_group\_table\_total\_replicas`~should~be~used.}\\ +~~{\mdcolor{darkgreen}//~Must~be~no~larger~than~`multicast\_group\_table\_total\_replicas`.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~multicast\_group\_table\_max\_replicas\_per\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1319} +\subsubsection{\mdline{1319}6.2.1.\hspace*{0.5em}\mdline{1319}Annotating P4 code with PkgInfo}\label{sec-annotating-p4-code-with-pkginfo}%mdk%mdk + +%mdk-data-line={1321} +\noindent\mdline{1321}A P4 program\mdline{1321}'\mdline{1321}s \mdline{1321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1321} may be declared using one or more of the following +annotations, attached to the \mdline{1322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1322} block only:%mdk + +%mdk-data-line={1324} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1325} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value{}[,key=value,...])}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("A~brief~description")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("A~longer\textbackslash{}}\\ +description{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@custom\_annotation(...)}\\ +{\mdcolor{maroon}@another\_custom\_annotation(...)}\\ +{\mdcolor{maroon}@platform\_property(key=value)}\\ +{\mdcolor{maroon}@platform\_property(key=value{}[,key=value,...])}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1336} +\noindent\mdline{1336}Above we see several different types of annotations:%mdk + +%mdk-data-line={1338} +\begin{itemize}%mdk + +%mdk-data-line={1338} +\item{} +%mdk-data-line={1338} +\mdline{1338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1338} \mdline{1338}- This is used to populate a specific field within the \mdline{1338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1338} +message. Multiple \mdline{1339}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1339} annotations are allowed. For compactness, +multiple key-value pairs can appear in a single \mdline{1340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1340} annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The \mdline{1342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{1342}s must be from +among the message fields inside \mdline{1343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1343}, for example, \mdline{1343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1343}, \mdline{1343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}version}}}\mdline{1343}, +etc. Each key-value pair assigns a value to the corresponding field inside the +single \mdline{1345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1345} message for the program\mdline{1345}'\mdline{1345}s P4Info. One exception is that the +\mdline{1346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1346} field of \mdline{1346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1346} must be expressed as individual +\mdline{1347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1347} and \mdline{1347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1347} annotations, see next bullets. The key \mdline{1347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}arch}}}\mdline{1347} will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself.%mdk%mdk + +%mdk-data-line={1351} +\item{} +%mdk-data-line={1351} +\mdline{1351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1351} \mdline{1351}- This will populate the \mdline{1351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.brief}}}\mdline{1351} message field.%mdk%mdk + +%mdk-data-line={1353} +\item{} +%mdk-data-line={1353} +\mdline{1353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1353} \mdline{1353}- This will populate the \mdline{1353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.description}}}\mdline{1353} message +field%mdk%mdk + +%mdk-data-line={1356} +\item{} +%mdk-data-line={1356} +\mdline{1356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@platform\_property}}}\mdline{1356} \mdline{1356}- This is used to populate a specific field within the +\mdline{1357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PlatformProperty}}}\mdline{1357} message in \mdline{1357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.platform\_property}}}\mdline{1357}. Multiple +\mdline{1358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@platform\_property}}}\mdline{1358} annotations are allowed. For compactness, +multiple key-value pairs can appear in a single \mdline{1359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@platform\_property}}}\mdline{1359} +annotation, separated by commas. Each key must only appear once and the +compiler must reject the program if one appears multiple times. The \mdline{1361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{1361}s +must be from among the message fields inside \mdline{1362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PlatformProperty}}}\mdline{1362}, for example, +\mdline{1363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_table\_size}}}\mdline{1363} or \mdline{1363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_table\_total\_replicas}}}\mdline{1363}. Each +key-value pair assigns a value to the corresponding field inside the single +\mdline{1365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PlatformProperty}}}\mdline{1365} message inside the program\mdline{1365}'\mdline{1365}s P4Info.%mdk%mdk + +%mdk-data-line={1367} +\item{} +%mdk-data-line={1367} +\mdline{1367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@\textless{}anything~else\textgreater{}}}}\mdline{1367} \mdline{1367}- This will create a \mdline{1367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotation}}}\mdline{1367} entry%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1369} +\noindent\mdline{1369}Declaring one or more of these annotations on \mdline{1369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1369} will +generate a single corresponding \mdline{1370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1370} message in the P4Info as described in +\mdline{1371}\mdref{sec-pkginfo-message}{PkgInfo Message}\mdline{1371}.%mdk + +%mdk-data-line={1373} +\mdline{1373}The following example shows \mdline{1373}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1373} annotations using a mixture of single and +multiple key-value pairs. It also shows \mdline{1374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1374} and \mdline{1374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1374} annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the \mdline{1376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1376} message. The custom annotations will +be appended to the \mdline{1377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotations}}}\mdline{1377} list.%mdk + +%mdk-data-line={1379} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1380} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(name="switch.p4",version="2")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(organization="p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(contact="info@p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(url="www.p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("L2/L3~switch")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("L2/L3~switch.\textbackslash{}}\\ +Built~for~data-center~profile.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@my\_annotation1(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}@my\_annotation2(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}PSA\_Switch(IgPipeline,~PacketReplicationEngine(),~EgPipeline,}\\ +{\mdcolor{maroon}~~~~~~~~~~~BufferingQueueingEngine())~main;}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1393} +\subsection{\mdline{1393}6.3.\hspace*{0.5em}\mdline{1393}ID Allocation for P4Info Objects}\label{sec-id-allocation}%mdk%mdk + +%mdk-data-line={1395} +\noindent\mdline{1395}P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(\mdline{1399}e.g.\mdline{1399} table, action, counter, \mdline{1399}\dots{}\mdline{1399}). The most significant 8 bits of the ID +encodes the object type (as per Table\mdline{1400}~\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}}\mdline{1400}). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (\mdline{1402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.P4Ids.Prefix}}}\mdline{1402}). These values must +be used (\mdline{1403}e.g.\mdline{1403} by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table\mdline{1405}~\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}}\mdline{1405} shows the ID +layout.%mdk + +%mdk-data-line={1408} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1410} 8-bit prefix value}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1410} P4 object type}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{1412} 0x00}&\multicolumn{1}{|l|}{\mdline{1412} Reserved (unspecified)}\\ +\multicolumn{1}{|l}{\mdline{1413} 0x01}&\multicolumn{1}{|l|}{\mdline{1413} Action}\\ +\multicolumn{1}{|l}{\mdline{1414} 0x02}&\multicolumn{1}{|l|}{\mdline{1414} Table}\\ +\multicolumn{1}{|l}{\mdline{1415} 0x03}&\multicolumn{1}{|l|}{\mdline{1415} Value-set}\\ +\multicolumn{1}{|l}{\mdline{1416} 0x04}&\multicolumn{1}{|l|}{\mdline{1416} Controller header (header type with \mdline{1416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1416} annotation)}\\ +\multicolumn{1}{|l}{\mdline{1417} 0x05\mdline{1417}\dots{}\mdline{1417}0x0f}&\multicolumn{1}{|l|}{\mdline{1417} Reserved (for future P4 built-in objects)}\\ +\multicolumn{1}{|l}{\mdline{1418} 0x10}&\multicolumn{1}{|l|}{\mdline{1418} Reserved (start of PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1419} 0x11}&\multicolumn{1}{|l|}{\mdline{1419} PSA Action profiles / selectors}\\ +\multicolumn{1}{|l}{\mdline{1420} 0x12}&\multicolumn{1}{|l|}{\mdline{1420} PSA Counter}\\ +\multicolumn{1}{|l}{\mdline{1421} 0x13}&\multicolumn{1}{|l|}{\mdline{1421} PSA Direct counter}\\ +\multicolumn{1}{|l}{\mdline{1422} 0x14}&\multicolumn{1}{|l|}{\mdline{1422} PSA Meter}\\ +\multicolumn{1}{|l}{\mdline{1423} 0x15}&\multicolumn{1}{|l|}{\mdline{1423} PSA Direct meter}\\ +\multicolumn{1}{|l}{\mdline{1424} 0x16}&\multicolumn{1}{|l|}{\mdline{1424} PSA Register}\\ +\multicolumn{1}{|l}{\mdline{1425} 0x17}&\multicolumn{1}{|l|}{\mdline{1425} PSA Digest}\\ +\multicolumn{1}{|l}{\mdline{1426} 0x18\mdline{1426}\dots{}\mdline{1426}0x7f}&\multicolumn{1}{|l|}{\mdline{1426} Reserved (for future PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1427} 0x80}&\multicolumn{1}{|l|}{\mdline{1427} Reserved (start of vendor-specific extern types)}\\ +\multicolumn{1}{|l}{\mdline{1428} 0x81\mdline{1428}\dots{}\mdline{1428}0xfe}&\multicolumn{1}{|l|}{\mdline{1428} Vendor-specific extern types}\\ +\multicolumn{1}{|l}{\mdline{1429} 0xff}&\multicolumn{1}{|l|}{\mdline{1429} Reserved (max prefix value)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1431} +\mdhr{}%mdk + +%mdk-data-line={1432} +\noindent\mdline{1432}\mdcaption{\textbf{Table~\mdcaptionlabel{1}.}~\mdcaptiontext{Mapping of P4Info object type to 8-bit ID prefix value}}%mdk +%mdk +\end{mdcenter}\label{tab-mapping-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1435} +\begin{table}[h!]%mdk +\begin{mdblock}{text-align=center,breakable=true}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{cc}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1437} MSB bit 31 \mdline{1437}\dots{}\mdline{1437}\dots{}\mdline{1437}.. bit 24}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1437} bit 23 \mdline{1437}\dots{}\mdline{1437}\dots{}\mdline{1437}\dots{}\mdline{1437}\dots{}\mdline{1437}\dots{}\mdline{1437}\dots{}\mdline{1437}\dots{}\mdline{1437}.. bit 0 LSB}}\\ + +\midrule +\multicolumn{1}{|c}{\mdline{1439} Object type prefix}&\multicolumn{1}{|c|}{\mdline{1439} Generated suffix (\mdline{1439}e.g.\mdline{1439} by the compiler)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1441} +\mdhr{}%mdk + +%mdk-data-line={1442} +\noindent\mdline{1442}\mdcaption{\textbf{Table~\mdcaptionlabel{2}.}~\mdcaptiontext{Format of P4Info object IDs}}%mdk%mdk +\end{mdblock}\label{tab-format-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1446} +\mdline{1446}It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with \mdline{1447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1447} (see Table +\mdline{1448}\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}}\mdline{1448}). The compiler must honor the \mdline{1448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1448} annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (\mdline{1450}i.e.\mdline{1450} if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same \mdline{1452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1452} value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct.%mdk + +%mdk-data-line={1461} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth-7cm)/1}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{\mdinline{width=7cm}{{\bfseries\mdline{1463} P4 declaration(s)}}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1463} Compiler-allocated ID(s)}}\\ + +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1465} \mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1465}}}&\multicolumn{1}{|l|}{\mdline{1465} 0x0212ab34}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1467} \mdline{1467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1467}}}&\multicolumn{1}{|l|}{\mdline{1467} \mdline{1467}\textbf{Error}\mdline{1467}(same ID suffixes for 2 objects of the same type)}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1468} \mdline{1468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tB...}}}\mdline{1468}}}&\multicolumn{1}{|l|}{\mdline{1468}}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1470} \mdline{1470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1470}}}&\multicolumn{1}{|l|}{\mdline{1470} 0x0212ab34}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1471} \mdline{1471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~action~act1...}}}\mdline{1471}}}&\multicolumn{1}{|l|}{\mdline{1471} 0x0112ab34}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1473} +\mdhr{}%mdk + +%mdk-data-line={1474} +\noindent\mdline{1474}\mdcaption{\textbf{Table~\mdcaptionlabel{3}.}~\mdcaptiontext{Example of statically-assigned P4Info object IDs}}%mdk +%mdk +\end{mdcenter}\label{tab-exmpl-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1477} +\mdline{1477}The \mdline{1477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1477} annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively).%mdk + +%mdk-data-line={1483} +\subsection{\mdline{1483}6.4.\hspace*{0.5em}\mdline{1483}P4Info Objects}\label{sec-p4info-objects}%mdk%mdk + +%mdk-data-line={1485} +\subsubsection{\mdline{1485}6.4.1.\hspace*{0.5em}\mdline{1485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}\label{sec-table}%mdk%mdk + +%mdk-data-line={1487} +\noindent\mdline{1487}Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields:%mdk + +%mdk-data-line={1490} +\begin{itemize}%mdk + +%mdk-data-line={1490} +\item{} +%mdk-data-line={1490} +\mdline{1490}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1490}, a \mdline{1490}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1490} message with the ID, name, and alias of this table.%mdk%mdk + +%mdk-data-line={1492} +\item{} +%mdk-data-line={1492} +\mdline{1492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1492}, a repeated field of type \mdline{1492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1492} representing the data to +be used to construct the lookup key matched in this table. Each \mdline{1493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1493} +message is defined with the following fields:%mdk + +%mdk-data-line={1496} +\begin{itemize}%mdk + +%mdk-data-line={1496} +\item{} +%mdk-data-line={1496} +\mdline{1496}id, the \mdline{1496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1496} identifier of this \mdline{1496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1496}, unique in the scope of +this table. No rules are prescribed on the way \mdline{1497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1497} IDs should be +allocated, as long as two \mdline{1498}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1498} of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the \mdline{1502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1502} annotation, or let the compiler +choose them.%mdk%mdk + +%mdk-data-line={1505} +\item{} +%mdk-data-line={1505} +\mdline{1505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1505}, the string representing the name of this \mdline{1505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1505}.%mdk%mdk + +%mdk-data-line={1507} +\item{} +%mdk-data-line={1507} +\mdline{1507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1507}, a repeated field of strings, each one representing a P4 +annotation associated to this match field.%mdk%mdk + +%mdk-data-line={1510} +\item{} +%mdk-data-line={1510} +\mdline{1510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1510}, an \mdline{1510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1510} value set to the size in bits of this match field.%mdk%mdk + +%mdk-data-line={1512} +\item{} +%mdk-data-line={1512} +\mdline{1512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1512}, a \mdline{1512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{1512} describing the match behavior for this field; it can be +either:%mdk + +%mdk-data-line={1514} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1514} +\item\mdline{1514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1514}, an enum field of type \mdline{1514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchType}}}\mdline{1514}, which includes all +possible PSA match kinds.%mdk + +%mdk-data-line={1516} +\item\mdline{1516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_match\_type}}}\mdline{1516}, a string field which can be used to encode any +architecture-specific match type.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1519} +\item{} +%mdk-data-line={1519} +\mdline{1519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1519}, a \mdline{1519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1519} message describing this match field.%mdk%mdk + +%mdk-data-line={1521} +\item{} +%mdk-data-line={1521} +\mdline{1521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1521}, which indicates whether the match field has a\mdline{1521}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1522}; this is useful for +\mdline{1523}\mdref{sec-psa-metadata-translation}{translation}\mdline{1523}.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1525} +\item{} +%mdk-data-line={1525} +\mdline{1525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_refs}}}\mdline{1525}, a repeated \mdline{1525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1525} field representing the set of possible +actions for this table. The \mdline{1526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1526} message is used to reference an action +specified in the same P4Info message and it includes the following fields:%mdk + +%mdk-data-line={1528} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1528} +\item\mdline{1528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1528}, the \mdline{1528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1528} identifier of the action.%mdk + +%mdk-data-line={1529} +\item\mdline{1529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1529}, an enum value which can take one of three values: + \mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1530}, \mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1530} and \mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1530}. The \mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1530} of the + action is determined by the use of the P4 standard annotations + \mdline{1532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1532} and \mdline{1532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1532}~[\mdcite{p4actionannotations}{22}]\mdline{1532}. \mdline{1532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1532} + (\mdline{1533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1533} annotation) means that the action can only appear within + the table, and never as the default action. \mdline{1534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1534} + (\mdline{1535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1535} annotation) means that the action can only be used as the + default action. \mdline{1536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1536} is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action.%mdk + +%mdk-data-line={1539} +\item\mdline{1539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1539}, a repeated string field, each one representing a P4 +annotation associated to the action \mdline{1540}\emph{reference}\mdline{1540} in this table.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1542} +\item{} +%mdk-data-line={1542} +\mdline{1542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\_default\_action\_id}}}\mdline{1542}, if this table has a constant default action, this +field will carry the \mdline{1543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1543} identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action\mdline{1546}'\mdline{1546}s +arguments.%mdk%mdk + +%mdk-data-line={1549} +\item{} +%mdk-data-line={1549} +\mdline{1549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}initial\_default\_action}}}\mdline{1549}, the default action that is executed with the + specified arguments when the table does not match. If no explicit + default action is set, the identifier of this field will default to + the id of the \mdline{1552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{1552} action.%mdk%mdk + +%mdk-data-line={1554} +\item{} +%mdk-data-line={1554} +\mdline{1554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation\_id}}}\mdline{1554}, the \mdline{1554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1554} identifier of the \mdline{1554}\textquotedblleft{}implementation\textquotedblright{}\mdline{1554} of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (\mdline{1557}e.g.\mdline{1557} a PSA \mdline{1557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1557} or \mdline{1557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{1557} +instance). The table is then referred to as an indirect match table.%mdk%mdk + +%mdk-data-line={1560} +\item{} +%mdk-data-line={1560} +\mdline{1560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_resource\_ids}}}\mdline{1560}, repeated \mdline{1560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1560} identifiers for all the direct +resources attached to this table, such as \mdline{1561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1561} and \mdline{1561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1561} +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2.%mdk%mdk + +%mdk-data-line={1567} +\item{} +%mdk-data-line={1567} +\mdline{1567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1567}, an \mdline{1567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1567} describing the desired number of table entries that the +target should support for the table. See the \mdline{1568}\textquotedblleft{}Size\textquotedblright{}\mdline{1568} subsection within the +\mdline{1569}\textquotedblleft{}Table Properties\textquotedblright{}\mdline{1569} section of the P4\mdline{1569}\mdsub{16}\mdline{1569} language specification for details +\mdline{1570}[\mdcite{p4tableproperties}{36}]\mdline{1570}.%mdk%mdk + +%mdk-data-line={1572} +\item{} +%mdk-data-line={1572} +\mdline{1572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_behavior}}}\mdline{1572}, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +\mdline{1574}\mdref{sec-idle-timeout}{Idle-Timeout}\mdline{1574} section). Value can be any of the +\mdline{1575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutBehavior}}}\mdline{1575} enum:%mdk + +%mdk-data-line={1576} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1576} +\item\mdline{1576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NO\_TIMEOUT}}}\mdline{1576} (default value), which means that idle timeout is not +supported for this table.%mdk + +%mdk-data-line={1578} +\item\mdline{1578}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOTIFY\_CONTROL}}}\mdline{1578}, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +\mdline{1580}\mdref{sec-table-idle-timeout-notification}{Table Idle Timeout Notifications}\mdline{1580}).%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1582} +\item{} +%mdk-data-line={1582} +\mdline{1582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{1582}, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime.%mdk%mdk + +%mdk-data-line={1585} +\item{} +%mdk-data-line={1585} +\mdline{1585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}has\_initial\_entries}}}\mdline{1585}, a boolean flag indicating that the table has +entries populated into it when the P4 program is loaded, which is +true for tables in the P4 source code with either the \mdline{1587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{1587} or +\mdline{1588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const~entries}}}\mdline{1588} properties, and there is at least one entry in the +list.%mdk%mdk + +%mdk-data-line={1591} +\item{} +%mdk-data-line={1591} +\mdline{1591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{1591}, an \mdline{1591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1591} Protobuf message\mdline{1591}~[\mdcite{protoany}{37}]\mdline{1591} to embed +architecture-specific table properties\mdline{1592}~[\mdcite{p4tableproperties}{36}]\mdline{1592} which are not part +of the core P4 language or of the PSA architecture.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1595} +\subsubsection{\mdline{1595}6.4.2.\hspace*{0.5em}\mdline{1595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}\label{sec-action}%mdk%mdk + +%mdk-data-line={1597} +\noindent\mdline{1597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1597} messages are used to specify all possible actions of all match-action +tables.%mdk + +%mdk-data-line={1600} +\mdline{1600}The \mdline{1600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1600} message defines the following fields:%mdk + +%mdk-data-line={1602} +\begin{itemize}%mdk + +%mdk-data-line={1602} +\item{} +%mdk-data-line={1602} +\mdline{1602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1602}, a \mdline{1602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1602} message with the ID, name, and alias of this action%mdk%mdk + +%mdk-data-line={1604} +\item{} +%mdk-data-line={1604} +\mdline{1604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{1604}, a repeated field of \mdline{1604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1604} messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each \mdline{1606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1606} message contains the +following fields:%mdk + +%mdk-data-line={1608} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1608} +\item\mdline{1608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1608}, the \mdline{1608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1608} identifier of this parameter. No rules are prescribed +on the way \mdline{1609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1609} IDs should be allocated, as long as two \mdline{1609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1609} of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the \mdline{1613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1613} +annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1615} +\item\mdline{1615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1615}, the string representing the name of this parameter.%mdk + +%mdk-data-line={1616} +\item\mdline{1616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1616}, a repeated field of strings, each one representing a P4 +annotation associated to this parameter.%mdk + +%mdk-data-line={1618} +\item\mdline{1618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1618}, an \mdline{1618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1618} value set to the size in bits of this parameter.%mdk + +%mdk-data-line={1619} +\item\mdline{1619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1619}, which describes this parameter using a \mdline{1619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1619} message.%mdk + +%mdk-data-line={1620} +\item\mdline{1620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1620}, which indicates whether the action parameter has a +\mdline{1621}\mdref{sec-user-defined-types}{user-defined type}\mdline{1621}; this is useful for +\mdline{1622}\mdref{sec-psa-metadata-translation}{translation}\mdline{1622}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1624} +\subsubsection{\mdline{1624}6.4.3.\hspace*{0.5em}\mdline{1624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}\label{sec-p4info-action-profile}%mdk%mdk + +%mdk-data-line={1626} +\noindent\mdline{1626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1626} messages are used to specify all available instances of Action +Profile and Action Selector PSA externs.%mdk + +%mdk-data-line={1629} +\mdline{1629}PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile \mdline{1633}\emph{member}\mdline{1633}, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime.%mdk + +%mdk-data-line={1637} +\mdline{1637}PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into \mdline{1638}\emph{groups}\mdline{1638}. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime.%mdk + +%mdk-data-line={1647} +\mdline{1647}While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same \mdline{1648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1648} message to describe both.%mdk + +%mdk-data-line={1650} +\mdline{1650}The \mdline{1650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1650} message includes the following fields:%mdk + +%mdk-data-line={1652} +\begin{itemize}%mdk + +%mdk-data-line={1652} +\item{} +%mdk-data-line={1652} +\mdline{1652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1652}, a \mdline{1652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1652} message with the ID, name, and alias of this Action +Profile or Selector.%mdk%mdk + +%mdk-data-line={1655} +\item{} +%mdk-data-line={1655} +\mdline{1655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_ids}}}\mdline{1655}, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector.%mdk%mdk + +%mdk-data-line={1658} +\item{} +%mdk-data-line={1658} +\mdline{1658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}with\_selector}}}\mdline{1658}, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern.%mdk%mdk + +%mdk-data-line={1661} +\item{} +%mdk-data-line={1661} +\mdline{1661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1661}, an \mdline{1661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1661} representing the maximum number of member entries that the +Action Profile can hold. For Action Selectors, its semantics is specified by +the \mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{1663} value as described below.%mdk%mdk + +%mdk-data-line={1665} +\item{} +%mdk-data-line={1665} +\mdline{1665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1665}, an \mdline{1665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1665} which is 0 for an Action Profile, or, for an +Action Selector, its semantics is specified by the \mdline{1666}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{1666} +value as described below. +The \mdline{1668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1668} must be no larger than \mdline{1668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1668}. PSA programs can use the +\mdline{1669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{1669} annotation to provide this value for Action Selectors. +If the annotation is omitted, the P4Info field will default to 0.%mdk%mdk + +%mdk-data-line={1672} +\item{} +%mdk-data-line={1672} +\mdline{1672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{1672}, a oneof for Action Selectors that +specifies how \mdline{1673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1673} and \mdline{1673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1673} are interpreted. It can be either:%mdk + +%mdk-data-line={1674} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1674} +\item\mdline{1674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_weights}}}\mdline{1674}, indicating that \mdline{1674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1674} and \mdline{1674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1674} represent +the maximum sum of weights that can be present across all selector groups +and within a single selector group respectively.%mdk + +%mdk-data-line={1677} +\item\mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_members}}}\mdline{1677}, indicating that \mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1677} and \mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1677} represent +the maximum number of members that can be present across all selector +groups and within a single selector group respectively, irrespective of +their weight. The \mdline{1680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SumOfMembers}}}\mdline{1680} message used to represent this value also +contains an optional int32 \mdline{1681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_member\_weight}}}\mdline{1681}, which indicates the +maximum weight of each individual member. If unset, any 32-bit integer is +allowed for weight.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1686} +\noindent\mdline{1686} PSA programs can use the \mdline{1686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@selector\_size\_semantics}}}\mdline{1686} annotation with one of + \mdline{1687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_weights}}}\mdline{1687} or \mdline{1687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_members}}}\mdline{1687} to specify this value for Action + Selectors. In the \mdline{1688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_members}}}\mdline{1688} case, the \mdline{1688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_member\_weight}}}\mdline{1688} annotation + can be used to specify \mdline{1689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_member\_weight}}}\mdline{1689}. Unless otherwise specified, the + value of \mdline{1690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{1690} should default to \mdline{1690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_weights}}}\mdline{1690}. + However, an unset \mdline{1691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{1691} should also be treated as + \mdline{1692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_weights}}}\mdline{1692} for backwards compatibility in Action Selectors. In Action + Profiles, this value must be unset.%mdk + +%mdk-data-line={1695} +\subsubsection{\mdline{1695}6.4.4.\hspace*{0.5em}\mdline{1695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1695} \mdline{1695}\&\mdline{1695} \mdline{1695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}\label{sec-counter-directcounter}%mdk%mdk + +%mdk-data-line={1697} +\noindent\mdline{1697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1697} and \mdline{1697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1697} messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is:%mdk + +%mdk-data-line={1703} +\begin{itemize}%mdk + +%mdk-data-line={1703} +\item{} +%mdk-data-line={1703} +\mdline{1703}Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index.%mdk%mdk + +%mdk-data-line={1707} +\item{} +%mdk-data-line={1707} +\mdline{1707}Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1710} +\noindent\mdline{1710}Both \mdline{1710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1710} and \mdline{1710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1710} messages share the following fields:%mdk + +%mdk-data-line={1712} +\begin{itemize}%mdk + +%mdk-data-line={1712} +\item{} +%mdk-data-line={1712} +\mdline{1712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1712}, a \mdline{1712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1712} message with the ID, name, and alias of this counter +extern instance.%mdk%mdk + +%mdk-data-line={1715} +\item{} +%mdk-data-line={1715} +\mdline{1715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1715}, a message of of type \mdline{1715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1715} used to describe the compile-time +configuration of this counter. Currently, the \mdline{1716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1716} message is used to +carry only the counter unit, which can be any of the \mdline{1717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec.Unit}}}\mdline{1717} enum +values:%mdk + +%mdk-data-line={1719} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1719} +\item\mdline{1719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1719}: reserved value.%mdk + +%mdk-data-line={1720} +\item\mdline{1720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1720}: byte counter.%mdk + +%mdk-data-line={1721} +\item\mdline{1721}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1721}: packet counter.%mdk + +%mdk-data-line={1722} +\item\mdline{1722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BOTH}}}\mdline{1722}: combination of both byte and packet counter.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1724} +\noindent\mdline{1724}For indexed counters, the \mdline{1724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1724} message contains also a \mdline{1724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1724} field, an +\mdline{1725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1725} representing the maximum number of independent values that can be held +by this counter array. Conversely, the \mdline{1726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1726} message contains a +\mdline{1727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1727} field that carries the \mdline{1727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}unit32}}}\mdline{1727} identifier of the table to +which this direct counter is attached.%mdk + +%mdk-data-line={1730} +\mdline{1730}For indexed counters, the \mdline{1730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1730} message contains also an \mdline{1730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1730} +field, which indicates whether the index has a\mdline{1731}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1732}. This is useful for +\mdline{1733}\mdref{sec-psa-metadata-translation}{translation}\mdline{1733}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1734}).%mdk + +%mdk-data-line={1736} +\subsubsection{\mdline{1736}6.4.5.\hspace*{0.5em}\mdline{1736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1736} \mdline{1736}\&\mdline{1736} \mdline{1736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}\label{sec-meter-directmeter}%mdk%mdk + +%mdk-data-line={1738} +\noindent\mdline{1738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1738} and \mdline{1738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1738} messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is:%mdk + +%mdk-data-line={1744} +\begin{itemize}%mdk + +%mdk-data-line={1744} +\item{} +%mdk-data-line={1744} +\mdline{1744}Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +\mdline{1746}e.g.\mdline{1746} to set the rate threshold.%mdk%mdk + +%mdk-data-line={1748} +\item{} +%mdk-data-line={1748} +\mdline{1748}Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1751} +\noindent\mdline{1751}Both \mdline{1751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1751} and \mdline{1751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1751} messages share the following fields:%mdk + +%mdk-data-line={1753} +\begin{itemize}%mdk + +%mdk-data-line={1753} +\item{} +%mdk-data-line={1753} +\mdline{1753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1753}, a \mdline{1753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1753} message with the ID, name, and alias of this meter +extern instance.%mdk%mdk + +%mdk-data-line={1756} +\item{} +%mdk-data-line={1756} +\mdline{1756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1756}, a message of type \mdline{1756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1756} used to describe the capabilities of +this meter extern instance. The \mdline{1757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1757} message is used to describe the +meter unit and the meter type. The meter unit can be any of the +\mdline{1759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Unit}}}\mdline{1759} enum values:%mdk + +%mdk-data-line={1760} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1760} +\item\mdline{1760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1760}: reserved value.%mdk + +%mdk-data-line={1761} +\item\mdline{1761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1761}, which signifies that this meter can be configured with rates +expressed in bytes/second.%mdk + +%mdk-data-line={1763} +\item\mdline{1763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1763}, for rates expressed in packets/second.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1765} +\mdline{1765}The meter type can be any of the \mdline{1765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Type}}}\mdline{1765} enum values:%mdk + +%mdk-data-line={1766} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1766} +\item\mdline{1766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TWO\_RATE\_THREE\_COLOR}}}\mdline{1766}: This is the \mdline{1766}\emph{Two Rate Three Color Marker}\mdline{1766} (trTCM) +defined in RFC 2698\mdline{1767}~[\mdcite{rfc2698}{3}]\mdline{1767}. This is the standard P4Runtime meter type +and allows meters to use two rates to split packets into three potential +colors: GREEN, YELLOW, or RED. This mode is the default, but can also be +set explicitly in a P4 program by adding the \mdline{1770}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@two\_rate\_three\_color}}}\mdline{1770} +annotation to the meter definition. +For example, in a V1Model P4 program, we might define a trTCM direct meter +as follows: + +%mdk-data-line={1774} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1775} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}two\_rate\_three\_color}\\ +direct\_meter\textless{}color\_type\textgreater{}(MeterType.bytes)~my\_meter;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={1778} +\item\mdline{1778}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SINGLE\_RATE\_THREE\_COLOR}}}\mdline{1778}: This is the \mdline{1778}\emph{Single Rate Three Color Marker}\mdline{1778} +(srTCM) defined in RFC 2697\mdline{1779}~[\mdcite{rfc2697}{2}]\mdline{1779}. This allows meters to use one rate +and an Excess Burst Size (EBS) to split packets into three potential +colors: GREEN, YELLOW, or RED. In a P4 program, this mode can be set by +adding the \mdline{1782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@single\_rate\_three\_color}}}\mdline{1782} annotation to the meter definition.%mdk + +%mdk-data-line={1783} +\item\mdline{1783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SINGLE\_RATE\_TWO\_COLOR}}}\mdline{1783}: This is a simplified version of RFC 2697 +\mdline{1784}[\mdcite{rfc2697}{2}]\mdline{1784}, and the \mdline{1784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SINGLE\_RATE\_THREE\_COLOR}}}\mdline{1784} mode above. +\mdline{1785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SINGLE\_RATE\_TWO\_COLOR}}}\mdline{1785} restricts meters to use only a single rate +specified by the Committed Information Rate (CIR) and Committed Burst Size +(CBS) to mark packets GREEN or RED. In a P4 program, this mode can be set +by adding the \mdline{1788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@single\_rate\_two\_color}}}\mdline{1788} annotation to the meter definition.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1790} +\noindent\mdline{1790}For indexed meters, the \mdline{1790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1790} message contains also a \mdline{1790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1790} field, an \mdline{1790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1790} +representing the maximum number of independent cells that can be held by this +meter. Conversely, the \mdline{1792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1792} message contains a \mdline{1792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1792} field +that carries the \mdline{1793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1793} identifier of the table to which this direct meter is +attached.%mdk + +%mdk-data-line={1796} +\mdline{1796}For indexed meters, the \mdline{1796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1796} message contains also an \mdline{1796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1796} +field, which indicates whether the index has a\mdline{1797}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1798}. This is useful for +\mdline{1799}\mdref{sec-psa-metadata-translation}{translation}\mdline{1799}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1800}).%mdk + +%mdk-data-line={1802} +\subsubsection{\mdline{1802}6.4.6.\hspace*{0.5em}\mdline{1802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\label{sec-controller-packet-meta}%mdk%mdk + +%mdk-data-line={1804} +\noindent\mdline{1804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1804} messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server.%mdk + +%mdk-data-line={1810} +\mdline{1810}When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet.%mdk + +%mdk-data-line={1816} +\mdline{1816}Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +\mdline{1818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_in")}}}\mdline{1818} and \mdline{1818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_out")}}}\mdline{1818}, +respectively. \mdline{1819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1819} messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages).%mdk + +%mdk-data-line={1824} +\mdline{1824}A P4Info message can contain at most two \mdline{1824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata~messages}}}\mdline{1824}, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields:%mdk + +%mdk-data-line={1828} +\begin{itemize}%mdk + +%mdk-data-line={1828} +\item{} +%mdk-data-line={1828} +\mdline{1828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1828}, a \mdline{1828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1828} message where \mdline{1828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble.name}}}\mdline{1828} is set to \mdline{1828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_in"}}}\mdline{1828} +and \mdline{1829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_out"}}}\mdline{1829} for packet-in and packet-out metadata, respectively.%mdk%mdk + +%mdk-data-line={1831} +\item{} +%mdk-data-line={1831} +\mdline{1831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{1831}, a repeated field of type \mdline{1831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1831}, where each \mdline{1831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1831} message +includes the following fields:%mdk + +%mdk-data-line={1833} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1833} +\item\mdline{1833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1833}, a \mdline{1833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1833} identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two \mdline{1834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1834} of the +same \mdline{1835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1835} message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the \mdline{1839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1839} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1840} +\item\mdline{1840}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1840}, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below).%mdk + +%mdk-data-line={1844} +\item\mdline{1844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1844}, a repeated field of strings, each one representing a P4 +annotation associated to this metadata.%mdk + +%mdk-data-line={1846} +\item\mdline{1846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1846}, an \mdline{1846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1846} representing the size in bits of this metadata.%mdk + +%mdk-data-line={1847} +\item\mdline{1847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1847}, which indicates whether the metadata field has a +\mdline{1848}\mdref{sec-user-defined-types}{user-defined type}\mdline{1848}; this is useful for +\mdline{1849}\mdref{sec-psa-metadata-translation}{translation}\mdline{1849}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1851} +\noindent\mdline{1851}As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding \mdline{1852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1852} +messages.%mdk + +%mdk-data-line={1855} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1856} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~egress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~port~where~the~packet}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~should~be~sent~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~queue\_id;~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~queue~ID~}{\mdcolor{darkgreen}*/}\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~ingress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~data~plane~port~ID~where}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~the~original~packet~was~received~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}1}\textgreater{}~is\_clone;~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~1~if~this~is~a~clone~of~the}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~original~packet~}{\mdcolor{darkgreen}*/}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1871} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1872} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868916615}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_out}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_out}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}egress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}queue\_id}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~\}\\ +\}\\ +\\ +controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868941301}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_in}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_in}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ingress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}is\_clone}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}1}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1909} +\noindent\mdline{1909}Note that the use of \mdline{1909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1909} is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages.%mdk + +%mdk-data-line={1915} +\subsubsection{\mdline{1915}6.4.7.\hspace*{0.5em}\mdline{1915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}\label{sec-valueset}%mdk%mdk + +%mdk-data-line={1917} +\noindent\mdline{1917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1917} messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P4\mdline{1920}\mdsub{16}\mdline{1920} +specification\mdline{1921}~[\mdcite{p4valuesets}{45}]\mdline{1921}.%mdk + +%mdk-data-line={1923} +\mdline{1923}The \mdline{1923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1923} message defines the following fields:%mdk + +%mdk-data-line={1925} +\begin{itemize}%mdk + +%mdk-data-line={1925} +\item{} +%mdk-data-line={1925} +\mdline{1925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1925}, a \mdline{1925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1925} message with the ID, name, and alias of this Value +Set.%mdk%mdk + +%mdk-data-line={1928} +\item{} +%mdk-data-line={1928} +\mdline{1928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1928}, a repeated field of \mdline{1928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1928} messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the \mdline{1931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1931} repeated field in the +\mdline{1932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{1932} message.%mdk%mdk + +%mdk-data-line={1934} +\item{} +%mdk-data-line={1934} +\mdline{1934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1934}, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +\mdline{1936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set}}}\mdline{1936} constructor call.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1938} +\noindent\mdline{1938}According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of \mdline{1941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1941}, +\mdline{1942}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1942}, or \mdline{1942}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1942}~[\mdcite{p4selectexpr}{31}]\mdline{1942}. The rest of this section looks at all 3 of +these cases and gives an example \mdline{1943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1943} message when appropriate.%mdk + +%mdk-data-line={1945} +\begin{enumerate}%mdk + +%mdk-data-line={1945} +\item{} +%mdk-data-line={1945} +\mdline{1945}If the type parameter is \mdline{1945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1945}, \mdline{1945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1945} will include exactly one +\mdline{1946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1946} message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used):%mdk + +%mdk-data-line={1949} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1949} +\item\mdline{1949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1949}: set to 1%mdk + +%mdk-data-line={1950} +\item\mdline{1950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1950}: set to the value of \mdline{1950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1950}%mdk + +%mdk-data-line={1951} +\item\mdline{1951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1951}: set to \mdline{1951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1951}%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1953} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1954} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}bit\textless{}8\textgreater{}~\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(hdr.f8)~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1957} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1958} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1972} +\begin{enumerate}[,start=2]%mdk + +%mdk-data-line={1972} +\item{} +%mdk-data-line={1972} +\mdline{1972}If the type parameter is a \mdline{1972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1972}, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program.%mdk%mdk + +%mdk-data-line={1977} +\item{} +%mdk-data-line={1977} +\mdline{1977}If the type parameter is a \mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1977}, this version of P4Runtime requires that +all the fields of the struct be of type \mdline{1978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1978} (where \mdline{1978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1978} can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +\mdline{1981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1981} field will include one \mdline{1981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1981} message for each field in the +struct, with the following fields:%mdk + +%mdk-data-line={1984} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1984} +\item\mdline{1984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1984}: must be unique with respect to the other \mdline{1984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1984} entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +\mdline{1988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1988} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1989} +\item\mdline{1989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1989}: set to the name of the corresponding struct field.%mdk + +%mdk-data-line={1990} +\item\mdline{1990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1990}: set to the list of P4 annotations associated with the struct +field, except for the \mdline{1991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1991} annotation, if present (see the \mdline{1991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1991} field +below).%mdk + +%mdk-data-line={1993} +\item\mdline{1993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1993}: set to the value of \mdline{1993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1993} for the corresponding struct field.%mdk + +%mdk-data-line={1994} +\item\mdline{1994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1994}, which indicates whether the struct field has a\mdline{1994}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1995}; this is useful for +\mdline{1996}\mdref{sec-psa-metadata-translation}{translation}\mdline{1996}.%mdk + +%mdk-data-line={1997} +\item\mdline{1997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1997}: by default \mdline{1997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1997} is set to \mdline{1997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1997}; the P4 programmer can +specify a different match type by using the \mdline{1998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1998} annotation +\mdline{1999}[\mdcite{p4selectexpr}{31}]\mdline{1999}.%mdk + +%mdk-data-line={2000} +\item\mdline{2000}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{2000}: documentation associated with the struct field.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={2002} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2003} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~bit\textless{}8\textgreater{}~f8;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(2)~@match(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(3)~@match(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2011} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2012} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2039} +\noindent\mdline{2039}In the above example, the \mdline{2039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{2039} annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs.%mdk + +%mdk-data-line={2042} +\mdline{2042}Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a\mdline{2043}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{2044} that resolves to a \mdline{2044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2044}, or a \mdline{2044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2044} where +one or more fields is a\mdline{2045}~\mdref{sec-user-defined-types}{user-defined type}\mdline{2045} that +resolves to a \mdline{2046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2046}. For each \mdline{2046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{2046} that corresponds to a user-defined +type, the \mdline{2047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2047} field must be set to the appropriate value (\mdline{2047}i.e.\mdline{2047} the name +of the type).%mdk + +%mdk-data-line={2050} +\subsubsection{\mdline{2050}6.4.8.\hspace*{0.5em}\mdline{2050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}\label{sec-register}%mdk%mdk + +%mdk-data-line={2052} +\noindent\mdline{2052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{2052} messages are used to specify all possible instances of Register PSA +externs.%mdk + +%mdk-data-line={2055} +\mdline{2055}Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime.%mdk + +%mdk-data-line={2059} +\mdline{2059}The \mdline{2059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{2059} message defines the following fields:%mdk + +%mdk-data-line={2061} +\begin{itemize}%mdk + +%mdk-data-line={2061} +\item{} +%mdk-data-line={2061} +\mdline{2061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{2061}, a \mdline{2061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{2061} message with the ID, name, and alias of this register +instance.%mdk%mdk + +%mdk-data-line={2064} +\item{} +%mdk-data-line={2064} +\mdline{2064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{2064}, which specifies the data type stored by this register, expressed +using a \mdline{2065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2065} message (see section on\mdline{2065}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary +P4 Types}\mdline{2066}).%mdk%mdk + +%mdk-data-line={2068} +\item{} +%mdk-data-line={2068} +\mdline{2068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2068}, an \mdline{2068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{2068} value representing the total number of independent register +cells available.%mdk%mdk + +%mdk-data-line={2071} +\item{} +%mdk-data-line={2071} +\mdline{2071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{2071}, which indicates whether the register index has a +\mdline{2072}\mdref{sec-user-defined-types}{user-defined type}\mdline{2072}. This is useful for +\mdline{2073}\mdref{sec-psa-metadata-translation}{translation}\mdline{2073}. The underlying built-in type +must be a fixed-width unsigned bitstring (\mdline{2074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2074}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2076} +\subsubsection{\mdline{2076}6.4.9.\hspace*{0.5em}\mdline{2076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}\label{sec-digest}%mdk%mdk + +%mdk-data-line={2078} +\noindent\mdline{2078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{2078} messages are used to specify all possible instances of Packet Digest +PSA externs.%mdk + +%mdk-data-line={2081} +\mdline{2081}A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages.%mdk + +%mdk-data-line={2090} +\mdline{2090}The \mdline{2090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{2090} message defines the following fields:%mdk + +%mdk-data-line={2092} +\begin{itemize}%mdk + +%mdk-data-line={2092} +\item{} +%mdk-data-line={2092} +\mdline{2092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{2092}, a \mdline{2092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{2092} message with the ID, name, and alias of this digest +instance.%mdk%mdk + +%mdk-data-line={2095} +\item{} +%mdk-data-line={2095} +\mdline{2095}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{2095}, which specifies the data type of an individual digest +notification using a \mdline{2096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2096} message (see section on\mdline{2096}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation +of Arbitrary P4 Types}\mdline{2097}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2099} +\subsubsection{\mdline{2099}6.4.10.\hspace*{0.5em}\mdline{2099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}\label{sec-p4info-extern}%mdk%mdk + +%mdk-data-line={2101} +\noindent\mdline{2101}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2101} messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one \mdline{2104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2104} message instance in P4Info. The \mdline{2104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2104} message defines +the following fields:%mdk + +%mdk-data-line={2107} +\begin{itemize}%mdk + +%mdk-data-line={2107} +\item{} +%mdk-data-line={2107} +\mdline{2107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{2107}, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the\mdline{2108}~\mdref{sec-id-allocation}{reserved +range}\mdline{2109} \mdline{2109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{}[0x81,~0xfe]}}}\mdline{2109}. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture.%mdk%mdk + +%mdk-data-line={2114} +\item{} +%mdk-data-line={2114} +\mdline{2114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_name}}}\mdline{2114}, which specifies the fully-qualified P4 name of the extern +type.%mdk%mdk + +%mdk-data-line={2117} +\item{} +%mdk-data-line={2117} +\mdline{2117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instances}}}\mdline{2117}, a repeated field of \mdline{2117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{2117} Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +\mdline{2119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{2119} in turn defines the following fields:%mdk + +%mdk-data-line={2121} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2121} +\item\mdline{2121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{2121}, a \mdline{2121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{2121} message with the ID, name, and alias of this digest +instance.%mdk + +%mdk-data-line={2123} +\item\mdline{2123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{2123}, an \mdline{2123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{2123} Protobuf message\mdline{2123}~[\mdcite{protoany}{37}]\mdline{2123} which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for \mdline{2125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{2125} should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on\mdline{2127}~\mdref{sec-extending-p4runtime}{Extending +P4Runtime for non-PSA Architectures}\mdline{2128} for more +information.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2131} +\noindent\mdline{2131}If the P4 program does not include any instance of a given extern type, the +\mdline{2132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2132} message instance for that type should be omitted from the P4Info.%mdk + +%mdk-data-line={2134} +\subsection{\mdline{2134}6.5.\hspace*{0.5em}\mdline{2134}Support for Arbitrary P4 Types with P4TypeInfo}\label{sec-support-for-arbitrary-p4-types-with-p4typeinfo}%mdk%mdk + +%mdk-data-line={2136} +\noindent\mdline{2136}See section on\mdline{2136}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary P4 +Types}\mdline{2137}.%mdk + +%mdk-data-line={2139} +\section{\mdline{2139}7.\hspace*{0.5em}\mdline{2139}P4 Forwarding-Pipeline Configuration}\label{sec-p4-fwd-pipe-config}%mdk%mdk + +%mdk-data-line={2141} +\noindent\mdline{2141}The \mdline{2141}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2141} captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the \mdline{2143}\textquotedblleft{}Device Configuration\textquotedblright{}\mdline{2143} and sometimes also referred to as +the \mdline{2144}\textquotedblleft{}P4 Blob\textquotedblright{}\mdline{2144}. It is defined as:%mdk + +%mdk-data-line={2146} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2147} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ForwardingPipelineConfig~\{\\ +~~config.P{\mdcolor{purple}4}Info~p4info~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~p4\_device\_config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}message}}~Cookie~\{\\ +~~~~{\bfseries{\mdcolor{navy}uint64}}~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~\}\\ +~~Cookie~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2157} +\noindent\mdline{2157}The \mdline{2157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{2157} field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic.%mdk + +%mdk-data-line={2160} +\mdline{2160}The \mdline{2160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{2160} is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new \mdline{2162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2162} on that target.%mdk + +%mdk-data-line={2164} +\mdline{2164}The \mdline{2164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{2164} field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a \mdline{2169}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{2169} RPC. +When writing the config via a \mdline{2170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{2170} RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present.%mdk + +%mdk-data-line={2174} +\section{\mdline{2174}8.\hspace*{0.5em}\mdline{2174}General Principles for Message Formatting}\label{sec-message-formatting-principles}%mdk%mdk + +%mdk-data-line={2176} +\subsection{\mdline{2176}8.1.\hspace*{0.5em}\mdline{2176}Default-valued Fields}\label{sec-default-valued-fields}%mdk%mdk + +%mdk-data-line={2178} +\noindent\mdline{2178}There is a subtle distinction between the treatment of default-valued scalar +fields vs default-valued message fields in P4Runtime.%mdk + +%mdk-data-line={2181} +\subsubsection{\mdline{2181}8.1.1.\hspace*{0.5em}\mdline{2181}Set / Unset Scalar Fields}\label{sec-set-unset-scalar-fields}%mdk%mdk + +%mdk-data-line={2183} +\noindent\mdline{2183}In Protobuf version 3 (\mdline{2183}\emph{proto3}\mdline{2183}), the default value of scalar fields is \mdline{2183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0}}}\mdline{2183} for +numeric types such as \mdline{2184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{2184}, and the empty string \mdline{2184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}""}}}\mdline{2184} for string types +(\mdline{2185}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{2185} and \mdline{2185}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2185}). An application, such as the P4Runtime client or +server, is \mdline{2186}\textbf{unable to distinguish}\mdline{2186} between an unset scalar field and a scalar +field set to its default value. Therefore, we usually reserve the default +values 0 and \mdline{2188}\textquotedblleft{}\textquotedblright{}\mdline{2188} of scalar fields to mean \mdline{2188}\textquotedblleft{}unset\textquotedblright{}\mdline{2188}.%mdk + +%mdk-data-line={2190} +\mdline{2190}In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +server, such as in a \mdline{2192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{2192} or a \mdline{2192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfigRequest}}}\mdline{2192}.%mdk + +%mdk-data-line={2194} +\mdline{2194}In contrast to scalar fields, note that for message fields, we often do make +a distinction between an unset message field vs a message field set to its +default value, see the next section.%mdk + +%mdk-data-line={2198} +\subsubsection{\mdline{2198}8.1.2.\hspace*{0.5em}\mdline{2198}Set / Unset Message Fields}\label{sec-set-unset-message-fields}%mdk%mdk + +%mdk-data-line={2200} +\noindent\mdline{2200}In Protobuf version 3 (\mdline{2200}\emph{proto3}\mdline{2200}), the default value for a message field is +\mdline{2201}\textquotedblleft{}unset\textquotedblright{}\mdline{2201}~[\mdcite{protodefaults}{6}]\mdline{2201}. An application, such as the P4Runtime client or +server, is \mdline{2202}\textbf{able to distinguish}\mdline{2202} between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +\mdline{2206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2206} message, an \mdline{2206}\textquotedblleft{}unset\textquotedblright{}\mdline{2206} \mdline{2206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2206} field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the \mdline{2208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2208} message field is +set, a single entry will be read.%mdk + +%mdk-data-line={2211} +\mdline{2211}Let\mdline{2211}'\mdline{2211}s look at the counter example in more details. Based on this specification +document, the C++ server code which processes \mdline{2212}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2212} messages may look +like this:%mdk + +%mdk-data-line={2214} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2215} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}auto}}~*counter\_entry~=~...\\ +{\bfseries{\mdcolor{navy}if}}~(counter\_entry-\textgreater{}has\_index())~\{\\ +~~{\bfseries{\mdcolor{navy}auto}}~index~=~counter\_entry-\textgreater{}index().index();\\ +~~read\_one\_entry(counter\_entry-\textgreater{}id(),~index);\\ +\}~{\bfseries{\mdcolor{navy}else}}~\{\\ +~~read\_all\_entries(counter\_entry-\textgreater{}id());\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2224} +\begin{enumerate}%mdk + +%mdk-data-line={2224} +\item{} +%mdk-data-line={2224} +\mdline{2224}Reading a single counter entry at index 0 in the counter array with id +\mdline{2225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textless{}id\textgreater{}}}}\mdline{2225}:%mdk + +%mdk-data-line={2226} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2226} +\item\mdline{2226}Here is the C++ client code: + +%mdk-data-line={2227} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2228} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});\\ +entry.mutable\_index();\\ +{\mdcolor{darkgreen}//~The~above~line~sets~the~index~field;~it~is~equivalent~to:}\\ +{\mdcolor{darkgreen}//~auto~*index~=~entry.mutable\_index();}\\ +{\mdcolor{darkgreen}//~index-\textgreater{}set\_index(0);}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2235} +\item\mdline{2235}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2236} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2237} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}\\ +index~\{\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2240} +\item\mdline{2240}\textbf{Expected behavior}\mdline{2240}: Counter entry at index 0 is read. Notice that the +\mdline{2241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2241} subfield is missing under the \mdline{2241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2241} field message of +\mdline{2242}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2242} in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2247} +\item{} +%mdk-data-line={2247} +\mdline{2247}Reading all counter entries by leaving the \mdline{2247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2247} field unset%mdk + +%mdk-data-line={2248} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2248} +\item\mdline{2248}Here is the C++ client code: + +%mdk-data-line={2249} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2250} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2253} +\item\mdline{2253}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2254} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2255} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2257} +\item\mdline{2257}\textbf{Expected behavior}\mdline{2257}: All counter entries for the provided counter +instance are read. Notice that the \mdline{2258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2258} message field is unset (default +value) and is therefore omitted from the textual representation of the +message.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={2262} +\subsection{\mdline{2262}8.2.\hspace*{0.5em}\mdline{2262}Read-Write Symmetry}\label{sec-read-write-symmetry}%mdk%mdk + +%mdk-data-line={2264} +\noindent\mdline{2264}The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully (with the exception of parts +of the response known to be data plane volatile, as explained in section +\mdline{2269}\mdref{sec-data-plane-volatile-objects}{8.2.1}\mdline{2269}). Consider the following pseudocode as an +example:%mdk + +%mdk-data-line={2272} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2273} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}intended\_value~=~value\\ +\\ +status~=~server.write(intended\_value,~p4\_entity)\\ +observed\_value~=~server.read(p4\_entity)\\ +\\ +assert(intended\_value~==~observed\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2281} +\noindent\mdline{2281}To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If \mdline{2285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{2285} RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol\mdline{2288}'\mdline{2288}s complexities to the client implementations.%mdk + +%mdk-data-line={2290} +\mdline{2290}In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the \mdline{2293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2293} fields in a \mdline{2293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2293} message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +\mdline{2296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MessageDifferencer}}}\mdline{2296} class\mdline{2296}~[\mdcite{protomessagedifferencer}{42}]\mdline{2296} included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance.%mdk + +%mdk-data-line={2301} +\subsubsection{\mdline{2301}8.2.1.\hspace*{0.5em}\mdline{2301}Data plane volatile objects}\label{sec-data-plane-volatile-objects}%mdk%mdk + +%mdk-data-line={2303} +\noindent\mdline{2303}An exception to read-write symmetry are objects whose contents or +fields can change by the action of the data plane alone, even if no +controller modifies them. These objects are called data plane +volatile.%mdk + +%mdk-data-line={2308} +\mdline{2308}The following sections describe all possible values of an \mdline{2308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{2308} +message, since these are the messages that a controller can use to +modify objects in the data plane via an \mdline{2310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{2310} message. For each, a +description is given of the parts of that entity that are data plane +volatile.%mdk + +%mdk-data-line={2314} +\paragraph{\mdline{2314}8.2.1.1.\hspace*{0.5em}\mdline{2314}ExternEntry}\label{sec-externentry}%mdk%mdk + +%mdk-data-line={2316} +\noindent\mdline{2316}Data plane volatility depends upon the definition of the extern and +its control plane API.%mdk + +%mdk-data-line={2319} +\paragraph{\mdline{2319}8.2.1.2.\hspace*{0.5em}\mdline{2319}TableEntry}\label{sec-tableentry}%mdk%mdk + +%mdk-data-line={2321} +\noindent\mdline{2321}For a table with a direct counter associated with it, the \mdline{2321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2321} +field of a \mdline{2322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2322} can be modified by the data plane when packets +match the entry.%mdk + +%mdk-data-line={2325} +\mdline{2325}For a table with a direct meter associated with it, the +\mdline{2326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{2326} field of a \mdline{2326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2326} can be modified by the data +plane when packets match the entry.%mdk + +%mdk-data-line={2329} +\mdline{2329}For a PSA\mdline{2329}~[\mdcite{psa}{24}]\mdline{2329} table with property \mdline{2329}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_idle\_timeout}}}\mdline{2329} equal to +\mdline{2330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PSA\_IdleTimeout\_t.NOTIFY\_CONTROL}}}\mdline{2330}, the data plane can modify the +\mdline{2331}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{2331} field of a \mdline{2331}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2331} when \mdline{2331}\emph{no}\mdline{2331} packets match the entry +for an implementation-specific amount of time.%mdk + +%mdk-data-line={2334} +\mdline{2334}For a PNA\mdline{2334}~[\mdcite{pna}{23}]\mdline{2334} table with property \mdline{2334}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}pna\_idle\_timeout}}}\mdline{2334} equal to +\mdline{2335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PNA\_IdleTimeout\_t.NOTIFY\_CONTROL}}}\mdline{2335} or \mdline{2335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PNA\_IdleTimeout\_t.AUTO\_DELETE}}}\mdline{2335} +the data plane can modify the \mdline{2336}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{2336} field of a \mdline{2336}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2336} +when \mdline{2337}\emph{no}\mdline{2337} packets cause the extern function \mdline{2337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}restart\_expire\_timer}}}\mdline{2337} to +be called for an implementation-specific amount of time (nor any other +extern function defined to also have the same effect as +\mdline{2340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}restart\_expire\_timer}}}\mdline{2340}).%mdk + +%mdk-data-line={2342} +\mdline{2342}Similarly, for a table in PNA with any of the values of +\mdline{2343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}pna\_idle\_timeout}}}\mdline{2343} listed above, the data plane can modify the +\mdline{2344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2344} field of a \mdline{2344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2344} when packets match the entry +and the action calls the \mdline{2345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}set\_entry\_expire\_time}}}\mdline{2345} extern function (or any +of the other extern functions defined to have an effect similar to +calling \mdline{2347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}set\_entry\_expire\_time}}}\mdline{2347}).%mdk + +%mdk-data-line={2349} +\mdline{2349}For a PNA\mdline{2349}~[\mdcite{pna}{23}]\mdline{2349} table with the property \mdline{2349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}add\_on\_miss}}}\mdline{2349} equal to \mdline{2349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}true}}}\mdline{2349} +the data plane can insert new entries into the table without any +controller\mdline{2351}'\mdline{2351}s involvement.%mdk + +%mdk-data-line={2353} +\mdline{2353}For a PNA\mdline{2353}~[\mdcite{pna}{23}]\mdline{2353} table with the property \mdline{2353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}pna\_idle\_timeout}}}\mdline{2353} equal to +\mdline{2354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PNA\_IdleTimeout\_t.AUTO\_DELETE}}}\mdline{2354}, the data plane can delete existing +entries from the table without any controller\mdline{2355}'\mdline{2355}s involvement.%mdk + +%mdk-data-line={2357} +\paragraph{\mdline{2357}8.2.1.3.\hspace*{0.5em}\mdline{2357}ActionProfileMember}\label{sec-actionprofilemember}%mdk%mdk + +%mdk-data-line={2359} +\noindent\mdline{2359}Not data plane volatile in any architectures defined by P4.org +specifications.%mdk + +%mdk-data-line={2362} +\paragraph{\mdline{2362}8.2.1.4.\hspace*{0.5em}\mdline{2362}ActionProfileGroup}\label{sec-actionprofilegroup}%mdk%mdk + +%mdk-data-line={2364} +\noindent\mdline{2364}Not data plane volatile in any architectures defined by P4.org +specifications. The \mdline{2365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{2365} feature does affect how action +selectors behave while processing packets, but this feature does not +affect what a P4Runtime client sees when it reads the configuration.%mdk + +%mdk-data-line={2369} +\paragraph{\mdline{2369}8.2.1.5.\hspace*{0.5em}\mdline{2369}MeterEntry}\label{sec-meterentry}%mdk%mdk + +%mdk-data-line={2371} +\noindent\mdline{2371}The field \mdline{2371}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2371} is modified by the data plane when the +corresponding meter is updated in the data plane.%mdk + +%mdk-data-line={2374} +\paragraph{\mdline{2374}8.2.1.6.\hspace*{0.5em}\mdline{2374}DirectMeterEntry}\label{sec-directmeterentry}%mdk%mdk + +%mdk-data-line={2376} +\noindent\mdline{2376}The field \mdline{2376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2376} is modified by the data plane when the +corresponding meter is updated in the data plane.%mdk + +%mdk-data-line={2379} +\paragraph{\mdline{2379}8.2.1.7.\hspace*{0.5em}\mdline{2379}CounterEntry}\label{sec-counterentry}%mdk%mdk + +%mdk-data-line={2381} +\noindent\mdline{2381}The field \mdline{2381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{2381} is modified by the data plane when the corresponding +counter is updated in the data plane.%mdk + +%mdk-data-line={2384} +\paragraph{\mdline{2384}8.2.1.8.\hspace*{0.5em}\mdline{2384}DirectCounterEntry}\label{sec-directcounterentry}%mdk%mdk + +%mdk-data-line={2386} +\noindent\mdline{2386}The field \mdline{2386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{2386} is modified by the data plane when the corresponding +counter is updated in the data plane.%mdk + +%mdk-data-line={2389} +\paragraph{\mdline{2389}8.2.1.9.\hspace*{0.5em}\mdline{2389}PacketReplicationEngineEntry}\label{sec-packetreplicationengineentry}%mdk%mdk + +%mdk-data-line={2391} +\noindent\mdline{2391}Not data plane volatile in any architectures defined by P4.org +specifications.%mdk + +%mdk-data-line={2394} +\paragraph{\mdline{2394}8.2.1.10.\hspace*{0.5em}\mdline{2394}ValueSetEntry}\label{sec-valuesetentry}%mdk%mdk + +%mdk-data-line={2396} +\noindent\mdline{2396}Not data plane volatile in any architectures defined by P4.org +specifications.%mdk + +%mdk-data-line={2399} +\paragraph{\mdline{2399}8.2.1.11.\hspace*{0.5em}\mdline{2399}RegisterEntry}\label{sec-registerentry}%mdk%mdk + +%mdk-data-line={2401} +\noindent\mdline{2401}The field \mdline{2401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{2401} can be modified by the data plane when the +corresponding register entry is updated in the data plane.%mdk + +%mdk-data-line={2404} +\paragraph{\mdline{2404}8.2.1.12.\hspace*{0.5em}\mdline{2404}DigestEntry}\label{sec-digestentry}%mdk%mdk + +%mdk-data-line={2406} +\noindent\mdline{2406}Not data plane volatile in any architectures defined by P4.org +specifications.%mdk + +%mdk-data-line={2409} +\subsection{\mdline{2409}8.3.\hspace*{0.5em}\mdline{2409}Bytestrings}\label{sec-bytestrings}%mdk%mdk + +%mdk-data-line={2411} +\noindent\mdline{2411}P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (\mdline{2413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2413}) or signed (\mdline{2413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2413}), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +\mdline{2416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2416} Protobuf type. The correct bitwidth\mdline{2416} \mdline{2416}\textemdash{}\mdline{2416} as per the P4 program\mdline{2416} \mdline{2416}\textemdash{}\mdline{2416} of +each integer variable exposed through P4Runtime is specified in the P4Info +message.%mdk + +%mdk-data-line={2420} +\mdline{2420}The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals:%mdk + +%mdk-data-line={2423} +\begin{itemize}%mdk + +%mdk-data-line={2423} +\item{} +%mdk-data-line={2423} +\mdline{2423}It ensures that a properly encoded binary string\mdline{2423}'\mdline{2423}s integer value conforms +to the P4Info-specified bitwidth.%mdk%mdk + +%mdk-data-line={2426} +\item{} +%mdk-data-line={2426} +\mdline{2426}It supports\mdline{2426}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2426}.%mdk%mdk + +%mdk-data-line={2428} +\item{} +%mdk-data-line={2428} +\mdline{2428}It helps facilitate non-disruptive P4 program updates.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2430} +\noindent\mdline{2430}In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type \mdline{2435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2435} and/or \mdline{2435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2435}.%mdk + +%mdk-data-line={2437} +\mdline{2437}Note that this representation does \mdline{2437}\emph{not}\mdline{2437} make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range.%mdk + +%mdk-data-line={2446} +\mdline{2446}In the P4Runtime API version 1.0 (including minor version revisions), values +of table key fields, action parameters, and fields in packet-in and packet-out +headers between a device and the controller (see\mdline{2448}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{2448}), +may not be of type \mdline{2449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2449}. The rules for encoding signed values thus only +apply to messages of type \mdline{2450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2450} (see\mdline{2450}~\mdref{sec-p4data-in-p4runtime-proto}{8.4.3}\mdline{2450}).%mdk + +%mdk-data-line={2452} +\mdline{2452}For a value of type \mdline{2452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2452}, the fewest number of bits required to represent +the integer value \mdline{2453}$V > 0$\mdline{2453} is the smallest integer \mdline{2453}$A$\mdline{2453} such that \mdline{2453}$V \leq 2^A -1$\mdline{2454}.%mdk + +%mdk-data-line={2456} +\mdline{2456}For a value of type \mdline{2456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2456}, the fewest number of bits required to represent +the integer value \mdline{2457}$V \neq 0$\mdline{2457} in 2\mdline{2457}'\mdline{2457}s complement form is the smallest integer \mdline{2457}$A$\mdline{2457} +such that \mdline{2458}$-2^{A-1} \leq V \leq 2^{A-1} - 1$\mdline{2458}.%mdk + +%mdk-data-line={2460} +\mdline{2460}As a special case, define that the value \mdline{2460}$V=0$\mdline{2460} requires at least \mdline{2460}$A=1$\mdline{2460} bit to +represent, regardless of whether it is signed or unsigned.%mdk + +%mdk-data-line={2463} +\mdline{2463}The shortest possible binary string for an integer \mdline{2463}$V$\mdline{2463} that needs \mdline{2463}$A$\mdline{2463} bits to +represent it is computed as:%mdk + +%mdk-data-line={2465} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2466} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size~=~floor(({\mdcolor{teal}A}~+~{\mdcolor{purple}7})~/~{\mdcolor{purple}8})}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2469} +\noindent\mdline{2469}Binary strings with the byte length computed as \mdline{2469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2469} promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies.%mdk + +%mdk-data-line={2473} +\mdline{2473}Any additional bits in the bytes sent for an unsigned integer value (type +\mdline{2474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2474}) must be 0. If additional bytes are transmitted above the +\mdline{2475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2475} minimum required, they must be filled with 0.%mdk + +%mdk-data-line={2477} +\mdline{2477}Any additional bits in the bytes sent for a signed integer value (type \mdline{2477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2477}) +must be copies of the sign bit, \mdline{2478}i.e.\mdline{2478} 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +\mdline{2480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2480} minimum required, they must be filled with copies of the +sign bit, \mdline{2481}i.e.\mdline{2481} 0 for non-negative values, or 0xff for negative values. In 2\mdline{2481}'\mdline{2481}s +complement representation, this is called \mdline{2482}\textquotedblleft{}sign extension\textquotedblright{}\mdline{2482}, and leaves the +numeric value represented unchanged.%mdk + +%mdk-data-line={2485} +\mdline{2485}Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the maximum length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value.%mdk + +%mdk-data-line={2491} +\mdline{2491}For a received bitstring expected to fit within a \mdline{2491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2491} type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring\mdline{2493}'\mdline{2493}s width is \mdline{2493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2493} bits or less.%mdk + +%mdk-data-line={2495} +\mdline{2495}For a received bitstring expected to fit within an \mdline{2495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2495} type, the value it +represents is in range if, after \mdline{2496}\textquotedblleft{}undoing sign extension\textquotedblright{}\mdline{2496}, the remaining bit +string\mdline{2497}'\mdline{2497}s width is \mdline{2497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2497} bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other.%mdk + +%mdk-data-line={2503} +\mdline{2503}If the string\mdline{2503}'\mdline{2503}s byte length is zero, the server always rejects the string.%mdk + +%mdk-data-line={2505} +\mdline{2505}When the server rejects a binary string due to any of the previous criteria, +it returns an \mdline{2506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2506} error.%mdk + +%mdk-data-line={2508} +\mdline{2508}For all binary strings, P4Runtime uses big-endian (\mdline{2508}i.e.\mdline{2508} network) byte-order. +For signed integer values (\mdline{2509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2509} P4 type), P4Runtime uses the same two\mdline{2509}'\mdline{2509}s +complement bitwise representation as P4. Table\mdline{2510}~\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}}\mdline{2510} +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above.%mdk + +%mdk-data-line={2514} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2516} P4 type}}&\multicolumn{1}{|c}{{\bfseries\mdline{2516} Integer value}}&\multicolumn{1}{|c}{{\bfseries\mdline{2516} P4Runtime binary string}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2516} Read-write symmetry}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2518} \mdline{2518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2518}}&\multicolumn{1}{|l}{\mdline{2518} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2518} \mdline{2518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2518}}&\multicolumn{1}{|l|}{\mdline{2518} yes}\\ +\multicolumn{1}{|l}{\mdline{2519} \mdline{2519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2519}}&\multicolumn{1}{|l}{\mdline{2519} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2519} \mdline{2519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2519}}&\multicolumn{1}{|l|}{\mdline{2519} no}\\ +\multicolumn{1}{|l}{\mdline{2520} \mdline{2520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2520}}&\multicolumn{1}{|l}{\mdline{2520} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2520} \mdline{2520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2520}}&\multicolumn{1}{|l|}{\mdline{2520} yes}\\ +\multicolumn{1}{|l}{\mdline{2521} \mdline{2521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2521}}&\multicolumn{1}{|l}{\mdline{2521} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2521} \mdline{2521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x30\textbackslash{}x64}}}\mdline{2521}}&\multicolumn{1}{|l|}{\mdline{2521} yes}\\ +\multicolumn{1}{|l}{\mdline{2522} \mdline{2522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2522}}&\multicolumn{1}{|l}{\mdline{2522} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2522} \mdline{2522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x30\textbackslash{}x64}}}\mdline{2522}}&\multicolumn{1}{|l|}{\mdline{2522} no}\\ +\multicolumn{1}{|l}{\mdline{2523} \mdline{2523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2523}}&\multicolumn{1}{|l}{\mdline{2523} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2523} \mdline{2523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2523}}&\multicolumn{1}{|l|}{\mdline{2523} no}\\ +\multicolumn{1}{|l}{\mdline{2524} \mdline{2524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2524}}&\multicolumn{1}{|l}{\mdline{2524} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2524} \mdline{2524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2524}}&\multicolumn{1}{|l|}{\mdline{2524} yes}\\ +\multicolumn{1}{|l}{\mdline{2525} \mdline{2525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2525}}&\multicolumn{1}{|l}{\mdline{2525} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2525} \mdline{2525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00\textbackslash{}x63}}}\mdline{2525}}&\multicolumn{1}{|l|}{\mdline{2525} no}\\ +\multicolumn{1}{|l}{\mdline{2526} \mdline{2526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2526}}&\multicolumn{1}{|l}{\mdline{2526} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2526} \mdline{2526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2526}}&\multicolumn{1}{|l|}{\mdline{2526} yes}\\ +\multicolumn{1}{|l}{\mdline{2527} \mdline{2527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2527}}&\multicolumn{1}{|l}{\mdline{2527} \mdline{2527}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2527} \mdline{2527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x9d}}}\mdline{2527}}&\multicolumn{1}{|l|}{\mdline{2527} yes}\\ +\multicolumn{1}{|l}{\mdline{2528} \mdline{2528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2528}}&\multicolumn{1}{|l}{\mdline{2528} \mdline{2528}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2528} \mdline{2528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xff\textbackslash{}x9d}}}\mdline{2528}}&\multicolumn{1}{|l|}{\mdline{2528} no}\\ +\multicolumn{1}{|l}{\mdline{2529} \mdline{2529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2529}}&\multicolumn{1}{|l}{\mdline{2529} \mdline{2529}-739 (-0x2e3)}&\multicolumn{1}{|l}{\mdline{2529} \mdline{2529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xfd\textbackslash{}x1d}}}\mdline{2529}}&\multicolumn{1}{|l|}{\mdline{2529} yes}\\ +\multicolumn{1}{|l}{\mdline{2530} \mdline{2530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2530}}&\multicolumn{1}{|l}{\mdline{2530} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2530} \mdline{2530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00}}}\mdline{2530}}&\multicolumn{1}{|l|}{\mdline{2530} no}\\ +\multicolumn{1}{|l}{\mdline{2531} \mdline{2531}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2531}}&\multicolumn{1}{|l}{\mdline{2531} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2531} \mdline{2531}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00}}}\mdline{2531}}&\multicolumn{1}{|l|}{\mdline{2531} yes}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2533} +\mdhr{}%mdk + +%mdk-data-line={2534} +\noindent\mdline{2534}\mdcaption{\textbf{Table~\mdcaptionlabel{4}.}~\mdcaptiontext{Examples of Valid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-valid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2536} +\mdline{2536}Table\mdline{2536}~\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}}\mdline{2536} shows some examples of invalid +P4Runtime binary strings:%mdk + +%mdk-data-line={2539} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2541} P4 type}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2541} P4Runtime binary string}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2543} \mdline{2543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2543}}&\multicolumn{1}{|l|}{\mdline{2543} \mdline{2543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x63}}}\mdline{2543}}\\ +\multicolumn{1}{|l}{\mdline{2544} \mdline{2544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2544}}&\multicolumn{1}{|l|}{\mdline{2544} \mdline{2544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2544}}\\ +\multicolumn{1}{|l}{\mdline{2545} \mdline{2545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2545}}&\multicolumn{1}{|l|}{\mdline{2545} \mdline{2545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2545}}\\ +\multicolumn{1}{|l}{\mdline{2546} \mdline{2546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2546}}&\multicolumn{1}{|l|}{\mdline{2546} \mdline{2546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x10\textbackslash{}x63}}}\mdline{2546}}\\ +\multicolumn{1}{|l}{\mdline{2547} \mdline{2547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2547}}&\multicolumn{1}{|l|}{\mdline{2547} \mdline{2547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2547}}\\ +\multicolumn{1}{|l}{\mdline{2548} \mdline{2548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2548}}&\multicolumn{1}{|l|}{\mdline{2548} \mdline{2548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x40\textbackslash{}x63}}}\mdline{2548}}\\ +\multicolumn{1}{|l}{\mdline{2549} \mdline{2549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2549}}&\multicolumn{1}{|l|}{\mdline{2549} \mdline{2549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x9d}}}\mdline{2549}}\\ +\multicolumn{1}{|l}{\mdline{2550} \mdline{2550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2550}}&\multicolumn{1}{|l|}{\mdline{2550} \mdline{2550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x8d\textbackslash{}x1d}}}\mdline{2550}}\\ +\multicolumn{1}{|l}{\mdline{2551} \mdline{2551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2551}}&\multicolumn{1}{|l|}{\mdline{2551} \mdline{2551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2551}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2553} +\mdhr{}%mdk + +%mdk-data-line={2554} +\noindent\mdline{2554}\mdcaption{\textbf{Table~\mdcaptionlabel{5}.}~\mdcaptiontext{Examples of Invalid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-invalid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2556} +\mdline{2556}As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from \mdline{2561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2561} to \mdline{2561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2561}, a server +running the \mdline{2562}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2562} version of the P4 program will accept requests from +clients that remain on the \mdline{2563}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2563} P4Runtime version.%mdk + +%mdk-data-line={2565} +\mdline{2565}Despite the server\mdline{2565}'\mdline{2565}s binary string flexibility for P4 program update support, +the client and server must both remain aware of the +\mdline{2567}\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2567} +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values.%mdk + +%mdk-data-line={2572} +\mdline{2572}Representation of variable-length integer values (\mdline{2572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2572} P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the \mdline{2574}\emph{dynamic-length}\mdline{2574} of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an \mdline{2577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2577} error code otherwise.%mdk + +%mdk-data-line={2579} +\subsection{\mdline{2579}8.4.\hspace*{0.5em}\mdline{2579}Representation of Arbitrary P4 Types}\label{sec-representation-of-arbitrary-p4-types}%mdk%mdk + +%mdk-data-line={2581} +\subsubsection{\mdline{2581}8.4.1.\hspace*{0.5em}\mdline{2581}Problem Statement}\label{sec-problem-statement}%mdk%mdk + +%mdk-data-line={2583} +\noindent\mdline{2583}The P4\mdline{2583}\mdsub{16}\mdline{2583} language includes more complex types than just binary strings +\mdline{2584}[\mdcite{p4complextypes}{5}]\mdline{2584}. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table\mdline{2587}~\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}}\mdline{2587} shows the different +P4\mdline{2588}\mdsub{16}\mdline{2588} types and how they are allowed to be used, as per the P4\mdline{2588}\mdsub{16}\mdline{2588} +specification.%mdk + +%mdk-data-line={2591} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|l}{{\bfseries\mdline{2593}}}&\multicolumn{3}{|c|}{{\bfseries\mdline{2593} Container type}}\\ +\cmidrule{2-2}\cmidrule{3-3}\cmidrule{4-4} +\multicolumn{1}{|l}{{\bfseries\mdline{2595} Element type}}&\multicolumn{1}{|l}{{\bfseries\mdline{2595} header}}&\multicolumn{1}{|l}{{\bfseries\mdline{2595} header\mdline{2595}\_\mdline{2595}union}}&\multicolumn{1}{|l|}{{\bfseries\mdline{2595} struct or tuple}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2597} \mdline{2597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2597}}&\multicolumn{1}{|l}{\mdline{2597} allowed}&\multicolumn{1}{|l}{\mdline{2597} error}&\multicolumn{1}{|l|}{\mdline{2597} allowed}\\ +\multicolumn{1}{|l}{\mdline{2598} \mdline{2598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2598}}&\multicolumn{1}{|l}{\mdline{2598} allowed}&\multicolumn{1}{|l}{\mdline{2598} error}&\multicolumn{1}{|l|}{\mdline{2598} allowed}\\ +\multicolumn{1}{|l}{\mdline{2599} \mdline{2599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2599}}&\multicolumn{1}{|l}{\mdline{2599} allowed}&\multicolumn{1}{|l}{\mdline{2599} error}&\multicolumn{1}{|l|}{\mdline{2599} allowed}\\ +\multicolumn{1}{|l}{\mdline{2600} \mdline{2600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int}}}\mdline{2600}}&\multicolumn{1}{|l}{\mdline{2600} error}&\multicolumn{1}{|l}{\mdline{2600} error}&\multicolumn{1}{|l|}{\mdline{2600} error}\\ +\multicolumn{1}{|l}{\mdline{2601} \mdline{2601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}void}}}\mdline{2601}}&\multicolumn{1}{|l}{\mdline{2601} error}&\multicolumn{1}{|l}{\mdline{2601} error}&\multicolumn{1}{|l|}{\mdline{2601} error}\\ +\multicolumn{1}{|l}{\mdline{2602} \mdline{2602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2602}}&\multicolumn{1}{|l}{\mdline{2602} error}&\multicolumn{1}{|l}{\mdline{2602} error}&\multicolumn{1}{|l|}{\mdline{2602} allowed}\\ +\multicolumn{1}{|l}{\mdline{2603} \mdline{2603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_kind}}}\mdline{2603}}&\multicolumn{1}{|l}{\mdline{2603} error}&\multicolumn{1}{|l}{\mdline{2603} error}&\multicolumn{1}{|l|}{\mdline{2603} error}\\ +\multicolumn{1}{|l}{\mdline{2604} \mdline{2604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2604}}&\multicolumn{1}{|l}{\mdline{2604} error}&\multicolumn{1}{|l}{\mdline{2604} error}&\multicolumn{1}{|l|}{\mdline{2604} allowed}\\ +\multicolumn{1}{|l}{\mdline{2605} \mdline{2605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2605}}&\multicolumn{1}{|l}{\mdline{2605} allowed\mdline{2605}\mdfootnote{1}{%mdk-data-line={2615} +%mdk-data-line={2615} +\noindent\mdline{2615}an \mdline{2615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2615} type used as a field in a \mdline{2615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2615} must specify a +underlying type and representation for \mdline{2616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2616} elements.%mdk +\label{fn-enum_header}%mdk%mdk +}\mdline{2605}}&\multicolumn{1}{|l}{\mdline{2605} error}&\multicolumn{1}{|l|}{\mdline{2605} allowed}\\ +\multicolumn{1}{|l}{\mdline{2606} \mdline{2606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2606}}&\multicolumn{1}{|l}{\mdline{2606} error}&\multicolumn{1}{|l}{\mdline{2606} allowed}&\multicolumn{1}{|l|}{\mdline{2606} allowed}\\ +\multicolumn{1}{|l}{\mdline{2607} header stack}&\multicolumn{1}{|l}{\mdline{2607} error}&\multicolumn{1}{|l}{\mdline{2607} error}&\multicolumn{1}{|l|}{\mdline{2607} allowed}\\ +\multicolumn{1}{|l}{\mdline{2608} \mdline{2608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2608}}&\multicolumn{1}{|l}{\mdline{2608} error}&\multicolumn{1}{|l}{\mdline{2608} error}&\multicolumn{1}{|l|}{\mdline{2608} allowed}\\ +\multicolumn{1}{|l}{\mdline{2609} \mdline{2609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2609}}&\multicolumn{1}{|l}{\mdline{2609} error}&\multicolumn{1}{|l}{\mdline{2609} error}&\multicolumn{1}{|l|}{\mdline{2609} allowed}\\ +\multicolumn{1}{|l}{\mdline{2610} \mdline{2610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2610}}&\multicolumn{1}{|l}{\mdline{2610} error}&\multicolumn{1}{|l}{\mdline{2610} error}&\multicolumn{1}{|l|}{\mdline{2610} allowed}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2612} +\mdhr{}%mdk + +%mdk-data-line={2613} +\noindent\mdline{2613}\mdcaption{\textbf{Table~\mdcaptionlabel{6}.}~\mdcaptiontext{P4 Type Usage}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-type-usage}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2618} +\mdline{2618}For example, the following P4\mdline{2618}\mdsub{16}\mdline{2618} objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects.%mdk + +%mdk-data-line={2621} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2622} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}{\bfseries{\mdcolor{navy}tuple}}\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}4}\textgreater{},~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~\textgreater{}~\textgreater{}()~digest\_complex;\\ +digest\_complex.pack(\{~hdr.ipv4.version,~hdr.ipv4.protocol~\});\\ +{\mdcolor{darkgreen}//~...}\\ +{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2632} +\noindent\mdline{2632}One solution would be to use only binary string (\mdline{2632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2632} type) in +p4runtime.proto and to define a custom serialization format for complex P4\mdline{2633}\mdsub{16}\mdline{2633} +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P4\mdline{2640}\mdsub{16}\mdline{2640} types.%mdk + +%mdk-data-line={2642} +\subsubsection{\mdline{2642}8.4.2.\hspace*{0.5em}\mdline{2642}P4 Type Specifications in p4info.proto}\label{sec-p4-type-specifications-in-p4infoproto}%mdk%mdk + +%mdk-data-line={2644} +\noindent\mdline{2644}In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type \mdline{2648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip\_t}}}\mdline{2648}, which is a header union with 2 possible headers: +\mdline{2649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4}}}\mdline{2649} with type \mdline{2649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4\_t}}}\mdline{2649} and \mdline{2649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6}}}\mdline{2649} with type \mdline{2649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6\_t}}}\mdline{2649}. Similarly, they need to +know the field layout for both of these header types.%mdk + +%mdk-data-line={2652} +\mdline{2652}To achieve this we introduce 2 main Protobuf messages: \mdline{2652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2652} and +\mdline{2653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2653}.%mdk + +%mdk-data-line={2655} +\mdline{2655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2655} is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P4\mdline{2656}\mdsub{16}\mdline{2656} program. These +named types are \mdline{2657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2657}, \mdline{2657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2657}, \mdline{2657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2657}, \mdline{2657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2657} and +\mdline{2658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2658}; for each of these we have a type specification message, +respectively \mdline{2659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructTypeSpec}}}\mdline{2659}, \mdline{2659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderTypeSpec}}}\mdline{2659}, \mdline{2659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionTypeSpec}}}\mdline{2659}, +\mdline{2660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4EnumTypeSpec}}}\mdline{2660} and \mdline{2660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4SerializableEnumTypeSpec}}}\mdline{2660}. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. \mdline{2662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2662} also includes the list of parser errors for the program, as +a \mdline{2663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4ErrorTypeSpec}}}\mdline{2663} message.%mdk + +%mdk-data-line={2665} +\mdline{2665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2665} is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each \mdline{2667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2667} message corresponds to a compile-time type in the +original P4\mdline{2668}\mdsub{16}\mdline{2668} program (\mdline{2668}e.g.\mdline{2668} the type parameter of an extern). This +compile-time type is represented as a Protobuf \mdline{2669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2669}, which can be:%mdk + +%mdk-data-line={2671} +\begin{itemize}%mdk + +%mdk-data-line={2671} +\item{} +%mdk-data-line={2671} +\mdline{2671}a string representing the name of the type in case of a named type (\mdline{2671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2671}, +\mdline{2672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2672}, \mdline{2672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2672}, \mdline{2672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2672}, \mdline{2672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2672} or user-defined \mdline{2672}\textquotedblleft{}new\textquotedblright{}\mdline{2672} +\mdline{2673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2673}),%mdk%mdk + +%mdk-data-line={2675} +\item{} +%mdk-data-line={2675} +\mdline{2675}an empty Protobuf message for \mdline{2675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2675} and \mdline{2675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2675}, or%mdk%mdk + +%mdk-data-line={2677} +\item{} +%mdk-data-line={2677} +\mdline{2677}a Protobuf message for other anonymous types (\mdline{2677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2677}, \mdline{2677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2677}, \mdline{2677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2677}, +\mdline{2678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2678} or stack). The \mdline{2678}\textquotedblleft{}binary string\textquotedblright{}\mdline{2678} types (\mdline{2678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2678}, \mdline{2678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2678}, and +\mdline{2679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2679}) are grouped together in the \mdline{2679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4BitstringLikeTypeSpec}}}\mdline{2679} message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf \mdline{2681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2681} +type).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2684} +\noindent\mdline{2684}For all P4\mdline{2684}\mdsub{16}\mdline{2684} compound types (\mdline{2684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2684}, \mdline{2684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2684}, \mdline{2684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2684}, and \mdline{2684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2684}), +the order of \mdline{2685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2685} in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P4\mdline{2687}\mdsub{16}\mdline{2687} declaration. The same goes for the order of members of an \mdline{2687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2687} +(serializable or not) or members of \mdline{2688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2688}.%mdk + +%mdk-data-line={2690} +\subsubsection{\mdline{2690}8.4.3.\hspace*{0.5em}\mdline{2690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2690} in p4runtime.proto}\label{sec-p4data-in-p4runtime-proto}%mdk%mdk + +%mdk-data-line={2692} +\noindent\mdline{2692}P4Runtime uses the \mdline{2692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2692} message to represent values of arbitrary types. The +P4Runtime client must generate correct \mdline{2693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2693} messages based on the type +specification information included in P4Info. The \mdline{2694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2694} message was designed +to introduce little overhead compared to using binary strings in the most common +case (P4\mdline{2696}\mdsub{16}\mdline{2696} \mdline{2696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2696} type).%mdk + +%mdk-data-line={2698} +\mdline{2698}Just like its P4Info counterpart\mdline{2698} \mdline{2698}- \mdline{2698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2698} \mdline{2698}-, \mdline{2698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2698} uses a Protobuf +\mdline{2699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2699} to represent all possible values.%mdk + +%mdk-data-line={2701} +\mdline{2701}We define a canonical representation for \mdline{2701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2701} messages\mdline{2701} \mdline{2701}\textemdash{}\mdline{2701} therefore +guaranteeing read-write symmetry\mdline{2702} \mdline{2702}\textemdash{}\mdline{2702} by introducing the following requirements:%mdk + +%mdk-data-line={2704} +\begin{itemize}%mdk + +%mdk-data-line={2704} +\item{} +%mdk-data-line={2704} +\mdline{2704}The order of \mdline{2704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2704} in \mdline{2704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructLike}}}\mdline{2704} and the order of \mdline{2704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2704} in +\mdline{2705}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2705} must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P4\mdline{2706}\mdsub{16}\mdline{2706} type +declaration.%mdk%mdk + +%mdk-data-line={2709} +\item{} +%mdk-data-line={2709} +\mdline{2709}An invalid header is represented by a \mdline{2709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2709} message where the \mdline{2709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_valid}}}\mdline{2709} +field is false and the \mdline{2710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2710} repeated field is empty.%mdk%mdk + +%mdk-data-line={2712} +\item{} +%mdk-data-line={2712} +\mdline{2712}An invalid header union (\mdline{2712}i.e.\mdline{2712} all headers in the union are invalid) is +represented by a \mdline{2713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnion}}}\mdline{2713} message where the \mdline{2713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header\_name}}}\mdline{2713} is the +empty string (default value for the field) and the \mdline{2714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header}}}\mdline{2714} is unset.%mdk%mdk + +%mdk-data-line={2716} +\item{} +%mdk-data-line={2716} +\mdline{2716}The order of \mdline{2716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2716} in \mdline{2716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStack}}}\mdline{2716} and \mdline{2716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStack}}}\mdline{2716} is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the \mdline{2718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2718} field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding \mdline{2720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStackTypeSpec}}}\mdline{2720} or +\mdline{2721}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStackTypeSpec}}}\mdline{2721} message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2723} +\subsubsection{\mdline{2723}8.4.4.\hspace*{0.5em}\mdline{2723}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={2725} +\noindent\mdline{2725}Let\mdline{2725}'\mdline{2725}s look at the Register example again:%mdk + +%mdk-data-line={2727} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2728} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2735} +\noindent\mdline{2735}Here\mdline{2735}'\mdline{2735}s the corresponding entry in the P4Info message:%mdk + +%mdk-data-line={2737} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2738} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}registers~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}369119267}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~\}\\ +~~type\_spec~\{\\ +~~~~header\_union~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~size:~{\mdcolor{purple}128}\\ +\}\\ +type\_info~\{\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~header\_unions~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2794} +\noindent\mdline{2794}Here\mdline{2794}'\mdline{2794}s a \mdline{2794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.WriteRequest}}}\mdline{2794} to set the value of \mdline{2794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_ip{}[12]}}}\mdline{2794}:%mdk + +%mdk-data-line={2796} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2797} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}update~\{\\ +~~type:~INSERT\\ +~~entity~\{\\ +~~~~register\_entry~\{\\ +~~~~~~register\_id:~{\mdcolor{purple}369119267}\\ +~~~~~~index~\{\\ +~~~~~~~~index:~{\mdcolor{purple}12}\\ +~~~~~~\}\\ +~~~~~~data~\{\\ +~~~~~~~~header\_union~\{\\ +~~~~~~~~~~valid\_header\_name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~~~valid\_header~\{\\ +~~~~~~~~~~~~is\_valid:~true\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x04}{\mdcolor{maroon}"}\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{darkgreen}\#~...}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2820} +\subsubsection{\mdline{2820}8.4.5.\hspace*{0.5em}\mdline{2820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2820}, serializable \mdline{2820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2820} and \mdline{2820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}\label{sec-enum-serializable-enum-and-error}%mdk%mdk + +%mdk-data-line={2822} +\noindent\mdline{2822}P4\mdline{2822}\mdsub{16}\mdline{2822} supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or \mdline{2823}\textquotedblleft{}unsafe\textquotedblright{}\mdline{2823} enum) +\mdline{2824}[\mdcite{p4enums}{7}]\mdline{2824}. For \mdline{2824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2824} types with no underlying type\mdline{2824} \mdline{2824}\textemdash{}\mdline{2824} as well as \mdline{2824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2824} \mdline{2824}\textemdash{}\mdline{2824} +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in \mdline{2827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2827} to represent \mdline{2827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2827} and +\mdline{2828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2828} values.%mdk + +%mdk-data-line={2830} +\mdline{2830}Serializable \mdline{2830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2830} types have an underlying fixed-width unsigned integer +representation (\mdline{2831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2831}). All named enum members must be assigned an integer +value by the P4 programmer, but \mdline{2832}\emph{not all}\mdline{2832} valid numeric values for the +underlying type need to have a corresponding name. \mdline{2833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2833} includes the +mapping between entry name and entry value. When providing serializable enum +values through \mdline{2835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2835}, one must use the assigned integer value (\mdline{2835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum\_value}}}\mdline{2835} +bytestring field). P4Runtime does not provide a way for the client to use the +name\mdline{2837} \mdline{2837}\textemdash{}\mdline{2837} even when the enum member has one\mdline{2837} \mdline{2837}\textemdash{}\mdline{2837} instead of the value, as it makes +it easier for the server to respect the\mdline{2838}~\mdref{sec-read-write-symmetry}{read-write +symmetry}\mdline{2839} principle.%mdk + +%mdk-data-line={2841} +\subsubsection{\mdline{2841}8.4.6.\hspace*{0.5em}\mdline{2841}User-defined types}\label{sec-user-defined-types}%mdk%mdk + +%mdk-data-line={2843} +\noindent\mdline{2843}P4\mdline{2843}\mdsub{16}\mdline{2843} enables programmers to introduce new types\mdline{2843}~[\mdcite{p4newtypes}{13}]\mdline{2843}. While similar +to \mdline{2844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{2844}, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +\mdline{2847}\mdref{sec-psa-metadata-translation}{translation}\mdline{2847}. When introducing a new type, the +declaration can be annotated with \mdline{2848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2848} to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for\mdline{2850}~\mdref{sec-translation-of-port-numbers}{port numbers}\mdline{2850}, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. \mdline{2853}\textbf{The \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}} annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}})}\mdline{2855}. The type exposed to the control plane (referred to as the +\mdline{2856}\emph{controller\_type}\mdline{2856}) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a \mdline{2858}\emph{URI}\mdline{2858} (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the \mdline{2860}\emph{controller\_type}\mdline{2860} of the values exposed to the control plane. The +\mdline{2861}\emph{controller\_type}\mdline{2861} can be either \mdline{2861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2861} where \mdline{2861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2861} is any positive integer, or +\mdline{2862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{2862}, or a positive integer \mdline{2862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2862} which has the same meaning as \mdline{2862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2862}. +Specifying just an integer is deprecated.%mdk + +%mdk-data-line={2865} +\mdline{2865}It is recommended that the URI includes at least the P4 architecture name and +the type name.%mdk + +%mdk-data-line={2868} +\mdline{2868}A \mdline{2868}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2868} annotation need not have any effect if it is used to +annotate anything in a P4 program other than a \mdline{2869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2869} declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect.%mdk + +%mdk-data-line={2873} +\mdline{2873}User-defined types are specified using the \mdline{2873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{2873} message, which has +the following fields:%mdk + +%mdk-data-line={2876} +\begin{itemize}%mdk + +%mdk-data-line={2876} +\item{} +%mdk-data-line={2876} +\mdline{2876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}representation}}}\mdline{2876}, a Protobuf \mdline{2876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2876} specifying how values of this type are +exchanged between client and server; it can be either:%mdk + +%mdk-data-line={2879} +\begin{itemize}%mdk + +%mdk-data-line={2879} +\item{} +%mdk-data-line={2879} +\mdline{2879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2879}, if and only if no \mdline{2879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2879} annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 \mdline{2881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2881} declaration is itself a +user-defined type, \mdline{2882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2882} is obtained by \mdline{2882}\textquotedblleft{}walking\textquotedblright{}\mdline{2882} the chain of +\mdline{2883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2883} declarations recursively until a built-in type (\mdline{2883}e.g.\mdline{2883} \mdline{2883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2883}) is +found.%mdk%mdk + +%mdk-data-line={2886} +\item{} +%mdk-data-line={2886} +\mdline{2886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}translated\_type}}}\mdline{2886}, if and only if the P4 \mdline{2886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2886} declaration was annotated +with \mdline{2887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2887}. It is of type \mdline{2887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeTranslation}}}\mdline{2887}, +which itself has two fields\mdline{2888} \mdline{2888}\textemdash{}\mdline{2888} \mdline{2888}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uri}}}\mdline{2888} and either \mdline{2888}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_string}}}\mdline{2888} or +\mdline{2889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_bitwidth}}}\mdline{2889} \mdline{2889}\textemdash{}\mdline{2889}, which map to the two input parameters to the +annotation.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2892} +\item{} +%mdk-data-line={2892} +\mdline{2892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{2892}, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2895} +\noindent\mdline{2895}For example, an architecture\mdline{2895} \mdline{2895}\textemdash{}\mdline{2895} in this case PSA\mdline{2895} \mdline{2895}\textemdash{}\mdline{2895} may introduce a new type +for port numbers:%mdk + +%mdk-data-line={2897} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2898} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~string,~e.g.~"eth0".}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~32-bit~integer,~e.g.~0xffffffff.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{darkgreen}//~Same~as~above.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_32\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_32\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2911} +\noindent\mdline{2911}In this case, the P4Info message would include the following \mdline{2911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2911} +messages:%mdk + +%mdk-data-line={2914} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2915} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_string:~\{\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2952} +\noindent\mdline{2952}Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (\mdline{2953}e.g.\mdline{2953} through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over \mdline{2955}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2955} to enable users +to overwrite annotations included as part of the P4 architecture definition.%mdk + +%mdk-data-line={2958} +\subsubsection{\mdline{2958}8.4.7.\hspace*{0.5em}\mdline{2958}Trade-off for v1.x Releases}\label{sec-trade-off-for-v1x-releases}%mdk%mdk + +%mdk-data-line={2960} +\noindent\mdline{2960}For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +\mdline{2961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2961} with \mdline{2961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2961} in the \mdline{2961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{2961} message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +\mdline{2964}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2964} to provide action parameter values and controller metadata +values. However \mdline{2965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2965} is used whenever appropriate for PSA externs and we +encourage the use of \mdline{2966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2966} in architecture-specific extensions.%mdk + +%mdk-data-line={2968} +\mdline{2968}In order to support\mdline{2968}~\mdref{sec-psa-metadata-translation}{translation}\mdline{2968} for action +parameters and match fields, we include a \mdline{2969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2969} field in +\mdline{2970}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{2970}, \mdline{2970}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Action.Param}}}\mdline{2970} and +\mdline{2971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ControllerPacketMetadata.Metadata}}}\mdline{2971}. In addition, the \mdline{2971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2971} +field for all of these message types must abide by the following rule when +\mdline{2973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2973} names a translated user-defined type:%mdk + +%mdk-data-line={2975} +\begin{itemize}%mdk + +%mdk-data-line={2975} +\item{} +%mdk-data-line={2975} +\mdline{2975}If the \mdline{2975}\emph{controller\_type}\mdline{2975} is a fixed-width unsigned bitstring, the \mdline{2975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2975} +field must be set to the bitwidth of the \mdline{2976}\emph{controller\_type}\mdline{2976}. This information +is redundant with the one included in the \mdline{2977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2977} entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent.%mdk%mdk + +%mdk-data-line={2983} +\item{} +%mdk-data-line={2983} +\mdline{2983}Otherwise (\mdline{2983}i.e.\mdline{2983}, if the \mdline{2983}\emph{controller\_type}\mdline{2983} is a string), the \mdline{2983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2983} must +be \mdline{2984}\textquotedblleft{}unset\textquotedblright{}\mdline{2984}, which, in Protobuf version 3, is the same as setting the field to +0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2987} +\noindent\mdline{2987}For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types:%mdk + +%mdk-data-line={2989} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2990} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{navy}@}{\mdcolor{navy}name}{\mdcolor{maroon}(".t")}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~meta.port1:~exact;~~{\mdcolor{darkgreen}//~meta.port1~has~type~PortId\_String\_t}\\ +~~~~meta.port2:~exact;~~{\mdcolor{darkgreen}//~meta.port2~has~type~PortId\_Bit32\_t}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3008} +\noindent\mdline{3008}This table would have the following representation in the generated P4Info +message:%mdk + +%mdk-data-line={3010} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3011} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tables~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}34728461}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port1}{\mdcolor{maroon}"}\\ +~~~~{\mdcolor{darkgreen}\#~notice~that~bitwidth~is~unset}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port2}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~{\mdcolor{darkgreen}\#~...}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3039} +\section{\mdline{3039}9.\hspace*{0.5em}\mdline{3039}P4 Entity Messages}\label{sec-p4-entity-msgs}%mdk%mdk + +%mdk-data-line={3041} +\noindent\mdline{3041}P4Runtime covers P4 entities that are either part of the P4\mdline{3041}\mdsub{16}\mdline{3041} language, or +defined as PSA externs. The sections below describe the messages for each +supported entity.%mdk + +%mdk-data-line={3045} +\subsection{\mdline{3045}9.1.\hspace*{0.5em}\mdline{3045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}\label{sec-table-entry}%mdk%mdk + +%mdk-data-line={3047} +\noindent\mdline{3047}The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action\mdline{3049}'\mdline{3049}s +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification.%mdk + +%mdk-data-line={3055} +\mdline{3055}P4Runtime supports inserting, modifying, deleting and reading table entries with +the \mdline{3056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3056} entity, which has the following fields:%mdk + +%mdk-data-line={3058} +\begin{itemize}%mdk + +%mdk-data-line={3058} +\item{} +%mdk-data-line={3058} +\mdline{3058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3058}, which identifies the table instance; the \mdline{3058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3058} is determined +by the P4Info message.%mdk%mdk + +%mdk-data-line={3061} +\item{} +%mdk-data-line={3061} +\mdline{3061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3061}, a repeated field of \mdline{3061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3061} messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration.%mdk%mdk + +%mdk-data-line={3065} +\item{} +%mdk-data-line={3065} +\mdline{3065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3065}, which indicates which of the table\mdline{3065}'\mdline{3065}s actions to execute in case of +match and with which argument values.%mdk%mdk + +%mdk-data-line={3068} +\item{} +%mdk-data-line={3068} +\mdline{3068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3068}, a 32-bit integer used to order entries when the table\mdline{3068}'\mdline{3068}s match key +includes an optional, ternary or range match.%mdk%mdk + +%mdk-data-line={3071} +\item{} +%mdk-data-line={3071} +\mdline{3071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3071}, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +\mdline{3075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3075} field.%mdk%mdk + +%mdk-data-line={3077} +\item{} +%mdk-data-line={3077} +\mdline{3077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3077}, an arbitrary \mdline{3077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{3077} value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry.%mdk%mdk + +%mdk-data-line={3082} +\item{} +%mdk-data-line={3082} +\mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3082}, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See\mdline{3083}~\mdref{sec-direct-resources}{Direct +resources}\mdline{3084} section for more information.%mdk%mdk + +%mdk-data-line={3086} +\item{} +%mdk-data-line={3086} +\mdline{3086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3086}, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See\mdline{3087}~\mdref{sec-direct-resources}{Direct +resources}\mdline{3088} section for more information.%mdk%mdk + +%mdk-data-line={3090} +\item{} +%mdk-data-line={3090} +\mdline{3090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3090}, which is used to read and write the per-color counter +values for the direct meter entry attached to this table entry, if any. +See\mdline{3092}~\mdref{sec-direct-resources}{Direct resources}\mdline{3092} section for more information.%mdk%mdk + +%mdk-data-line={3094} +\item{} +%mdk-data-line={3094} +\mdline{3094}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3094}, a boolean flag which indicates whether the table entry is +the default entry for the table. See\mdline{3095}~\mdref{sec-default-entry}{Default entry}\mdline{3095} +section for more information.%mdk%mdk + +%mdk-data-line={3098} +\item{} +%mdk-data-line={3098} +\mdline{3098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3098} and \mdline{3098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3098}, which are two fields used to +implement idle-timeout support for the table, if applicable. See +\mdline{3100}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{3100} section for more information.%mdk%mdk + +%mdk-data-line={3102} +\item{} +%mdk-data-line={3102} +\mdline{3102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const}}}\mdline{3102}, a boolean value that is \mdline{3102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}true}}}\mdline{3102} if and only if the entry +cannot be modified or deleted by the client.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3105} +\noindent\mdline{3105}The \mdline{3105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3105} field must be set to a non-zero value if the match key includes a +ternary match (\mdline{3106}i.e.\mdline{3106} in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an \mdline{3107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3107}, \mdline{3107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3107} or +\mdline{3108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3108} match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches.%mdk + +%mdk-data-line={3117} +\mdline{3117}The \mdline{3117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3117} and \mdline{3117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3117} fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for \mdline{3119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3119} and \mdline{3119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3119} updates. When deleting +an entry, these key fields (along with \mdline{3120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3120}) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a \mdline{3122}\emph{keyless}\mdline{3122} +table (the table has an empty match key), the server must reject all attempts to +\mdline{3124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3124} a match entry and return an \mdline{3124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3124} error.%mdk + +%mdk-data-line={3126} +\mdline{3126}The number of match entries that a table \mdline{3126}\emph{should}\mdline{3126} support is indicated in P4Info +(\mdline{3127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{3127} field of \mdline{3127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{3127} message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P4\mdline{3128}\mdsub{16}\mdline{3128} specification for the +\mdline{3129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{3129} property\mdline{3129}~[\mdcite{p4tableproperties}{36}]\mdline{3129}. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +\mdline{3133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3133} when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached.%mdk + +%mdk-data-line={3138} +\mdline{3138}The \mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const}}}\mdline{3138} field must be \mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}false}}}\mdline{3138} in any \mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3138}, \mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3138}, or +\mdline{3139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3139} write request of a table entry. If it is true, the server +must reject the operation and return an \mdline{3140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3140} error.%mdk + +%mdk-data-line={3142} +\subsubsection{\mdline{3142}9.1.1.\hspace*{0.5em}\mdline{3142}Match Format}\label{sec-match-format}%mdk%mdk + +%mdk-data-line={3144} +\noindent\mdline{3144}The bytes fields in the \mdline{3144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3144} message follow the format described in +\mdline{3145}\mdref{sec-bytestrings}{Bytestrings}\mdline{3145}.%mdk + +%mdk-data-line={3147} +\mdline{3147}For \mdline{3147}\textquotedblleft{}don't care\textquotedblright{}\mdline{3147} matches, the P4Runtime client must omit the field\mdline{3147}'\mdline{3147}s entire +\mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3148} entry when building the \mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3148} repeated field of the \mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3148} +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for \mdline{3150}\textquotedblleft{}don't care\textquotedblright{}\mdline{3150} matches, which is needed +to ensure\mdline{3151}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{3151}. For PSA match types, +a \mdline{3152}\textquotedblleft{}don't care\textquotedblright{}\mdline{3152} match for a specific match key field is defined as follows:%mdk + +%mdk-data-line={3154} +\begin{itemize}%mdk + +%mdk-data-line={3154} +\item{} +%mdk-data-line={3154} +\mdline{3154}For a \mdline{3154}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3154} match, it is logically equivalent to a mask of zeros.%mdk%mdk + +%mdk-data-line={3156} +\item{} +%mdk-data-line={3156} +\mdline{3156}For a \mdline{3156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3156} match, it is logically equivalent to a wildcard match.%mdk%mdk + +%mdk-data-line={3158} +\item{} +%mdk-data-line={3158} +\mdline{3158}For an \mdline{3158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{3158} match, it is logically equivalent to a prefix\mdline{3158}\_\mdline{3158}len of zero.%mdk%mdk + +%mdk-data-line={3160} +\item{} +%mdk-data-line={3160} +\mdline{3160}For a \mdline{3160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3160} match, it is logically equivalent to a range which includes all +possible values for the field.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3163} +\noindent\mdline{3163}Note that there is no \mdline{3163}\textquotedblleft{}don't care\textquotedblright{}\mdline{3163} value for \mdline{3163}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3163} matches and therefore exact +match fields can never be omitted from the \mdline{3164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3164} message.%mdk + +%mdk-data-line={3166} +\mdline{3166}The following example shows a P4Runtime message that treats a \mdline{3166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3166} field +as a \mdline{3167}\textquotedblleft{}don't care\textquotedblright{}\mdline{3167} match. The P4 program defines table \mdline{3167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3167} with \mdline{3167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3167} +and \mdline{3168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3168} fields in its match key:%mdk + +%mdk-data-line={3170} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3171} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~ternary;\\ +~~~~istd.ingress\_port:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3182} +\noindent\mdline{3182}In this P4Runtime request, the client omits the table\mdline{3182}'\mdline{3182}s \mdline{3182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3182} field +from the repeated \mdline{3183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3183} field to indicate a \mdline{3183}\textquotedblleft{}don't care\textquotedblright{}\mdline{3183} match. As shown +below, the \mdline{3184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3184} specifies only the \mdline{3184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3184} field given by \mdline{3184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id:~2}}}\mdline{3184}.%mdk + +%mdk-data-line={3186} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3187} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}33554439}~~{\mdcolor{darkgreen}\#~Table~t's~ID.}\\ +~~~~match~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~field\_id~1~is~not~present~to~use~the~don't~care~ternary~value.}\\ +~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~exact~\{\\ +~~~~~~~~value:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x20}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~action~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~Action~selection~goes~here.}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3205} +\noindent\mdline{3205}For every member of the \mdline{3205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3205} repeated \mdline{3205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3205} field, \mdline{3205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id}}}\mdline{3205} must be +a valid id for the table, as per the P4Info, and one of the fields in +\mdline{3207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{3207} must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an \mdline{3209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3209} error code.%mdk + +%mdk-data-line={3211} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3211} +\item\mdline{3211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3211} match + +%mdk-data-line={3212} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3212} +\item\mdline{3212}The binary string encoding of the value must conform to the +\mdline{3213}\mdref{sec-bytestrings}{Bytestrings}\mdline{3213} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3215} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3216} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.exact().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3219} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3219} +\item\mdline{3219}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{3219} match + +%mdk-data-line={3220} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3220} +\item\mdline{3220}The binary string encoding of the value (when present) must conform to the +\mdline{3221}\mdref{sec-bytestrings}{Bytestrings}\mdline{3221} requirements.%mdk + +%mdk-data-line={3222} +\item\mdline{3222}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3222} match must be omitted.%mdk + +%mdk-data-line={3223} +\item\mdline{3223}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3223} bits must be 0 in value.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3225} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3226} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.lpm().value()))\\ +\\ +pLen~=~match.lpm().prefix\_len()\\ +assert(pLen~\textgreater{}~0)\\ +\\ +trailing\_zeros~=~countTrailingZeros(match.lpm().value())\\ +assert(trailing\_zeros~\textgreater{}=~field\_bits~-~pLen)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3235} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3235} +\item\mdline{3235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3235} match + +%mdk-data-line={3236} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3236} +\item\mdline{3236}The binary string encoding of the value (when present) and mask (when +present) must conform to the\mdline{3237}~\mdref{sec-bytestrings}{Bytestrings}\mdline{3237} requirements.%mdk + +%mdk-data-line={3238} +\item\mdline{3238}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3238} match must be omitted.%mdk + +%mdk-data-line={3239} +\item\mdline{3239}Masked bits must be 0 in value. This constraint taken together +with the\mdline{3240}~\mdref{sec-bytestrings}{Bytestrings}\mdline{3240} requirements means that the +value\mdline{3241}'\mdline{3241}s binary string is never longer than the mask\mdline{3241}'\mdline{3241}s binary string. +When the value\mdline{3242}'\mdline{3242}s string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3246} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3247} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.ternary().value()))\\ +assert(BytestringValid(match.ternary().mask()))\\ +assert(match.ternary().value().size()~\textless{}=~match.ternary().mask().size());\\ +\\ +value~=~parseInteger(match.ternary().value())\\ +mask~=~parseInteger(match.ternary().mask())\\ +\\ +assert(mask~!=~0)\\ +\\ +assert(value~\&~mask~==~value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3259} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3259} +\item\mdline{3259}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3259} match + +%mdk-data-line={3260} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3260} +\item\mdline{3260}The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the\mdline{3261}~\mdref{sec-bytestrings}{Bytestrings}\mdline{3261} +requirements.%mdk + +%mdk-data-line={3263} +\item\mdline{3263}Low bound must be less than or equal to the high bound.%mdk + +%mdk-data-line={3264} +\item\mdline{3264}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3264} match must be omitted.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3266} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3267} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.range().low()))\\ +assert(BytestringValid(match.range().high()))\\ +\\ +low~=~parseInteger(match.range().low())\\ +high~=~parseInteger(match.range().high())\\ +\\ +assert(low~\textless{}=~high)\\ +\\ +assert(low~!=~min\_field\_value~\textbar{}\textbar{}~high~!=~max\_field\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3278} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3278} +\item\mdline{3278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3278} match + +%mdk-data-line={3279} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3279} +\item\mdline{3279}The binary string encoding of the value must conform to the +\mdline{3280}\mdref{sec-bytestrings}{Bytestrings}\mdline{3280} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3282} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3283} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.optional().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3286} +\subsubsection{\mdline{3286}9.1.2.\hspace*{0.5em}\mdline{3286}Action Specification}\label{sec-action-specification}%mdk%mdk + +%mdk-data-line={3288} +\noindent\mdline{3288}The \mdline{3288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3288} \mdline{3288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3288} field must be set for every \mdline{3288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3288} update but may be +left unset for \mdline{3289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3289} updates, in which case the action specification for the +table entry will not be modified (if a \mdline{3290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3290} update has an unset action field +and does not modify any direct resource attached to the table then the \mdline{3291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3291} +update is a no-op). Based on the implementation property value of the P4 table, +the \mdline{3293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3293} in the \mdline{3293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3293} message will either be:%mdk + +%mdk-data-line={3295} +\begin{itemize}%mdk + +%mdk-data-line={3295} +\item{} +%mdk-data-line={3295} +\mdline{3295}an \mdline{3295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3295} specification for direct tables (with no P4 \mdline{3295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3295} +property)%mdk%mdk + +%mdk-data-line={3298} +\item{} +%mdk-data-line={3298} +\mdline{3298}an action profile member id for indirect tables for which the \mdline{3298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3298} +property is an action profile with no selector.%mdk%mdk + +%mdk-data-line={3301} +\item{} +%mdk-data-line={3301} +\mdline{3301}an action profile member id or group id for indirect tables for which the +\mdline{3302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3302} property is an action profile with selector.%mdk%mdk + +%mdk-data-line={3304} +\item{} +%mdk-data-line={3304} +\mdline{3304}an \mdline{3304}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3304} specification for indirect tables for +which the \mdline{3305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3305} property is an action profile with +selector. This usage is described in\mdline{3306}~\mdref{sec-oneshot}{One Shot Action Selector +Programming}\mdline{3307}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3309} +\noindent\mdline{3309}If the \mdline{3309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3309} does not match the table description in the P4Info (\mdline{3309}e.g.\mdline{3309} the +\mdline{3310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3310} is \mdline{3310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member\_id}}}\mdline{3310} for a direct table), the server must +return an \mdline{3311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3311} error code.%mdk + +%mdk-data-line={3313} +\mdline{3313}The \mdline{3313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3313} Protobuf message has the following fields:%mdk + +%mdk-data-line={3315} +\begin{itemize}%mdk + +%mdk-data-line={3315} +\item{} +%mdk-data-line={3315} +\mdline{3315}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3315}, which identifies the action instance; the \mdline{3315}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3315} is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an \mdline{3317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3317} error +code. If the client uses a valid \mdline{3318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3318} for the table but does not +respect the action scope specified in P4Info (\mdline{3319}e.g.\mdline{3319} tries to set a \mdline{3319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{3319} +action as the default action), the server must return a \mdline{3320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3320} +error code.%mdk%mdk + +%mdk-data-line={3323} +\item{} +%mdk-data-line={3323} +\mdline{3323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{3323}: a repeated Protobuf field of action parameter values, each encoded +as a \mdline{3324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{3324} message. For each parameter, \mdline{3324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}param\_id}}}\mdline{3324} must be valid for the +action (as per the P4Info) and value must follow the format described in +\mdline{3326}\mdref{sec-bytestrings}{Bytestrings}\mdline{3326}. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an \mdline{3328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3328} error code +if a parameter id is missing, if an extra parameter\mdline{3329} \mdline{3329}\textemdash{}\mdline{3329} id not found in the +P4Info\mdline{3330} \mdline{3330}\textemdash{}\mdline{3330} was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +\mdline{3332}\mdref{sec-bytestrings}{Bytestrings}\mdline{3332} format.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3334} +\noindent\mdline{3334}For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a \mdline{3336}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3336} error code.%mdk + +%mdk-data-line={3338} +\subsubsection{\mdline{3338}9.1.3.\hspace*{0.5em}\mdline{3338}Default Entry}\label{sec-default-entry}%mdk%mdk + +%mdk-data-line={3340} +\noindent\mdline{3340}According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer\mdline{3341} \mdline{3341}\textemdash{}\mdline{3341} or defaults to \mdline{3341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3341} +(which is a no-op) otherwise\mdline{3342} \mdline{3342}\textemdash{}\mdline{3342} and assuming it is not declared as \mdline{3342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3342}, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow \mdline{3344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3344} and \mdline{3344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3344} updates on the default entry and the +P4Runtime server must return an \mdline{3345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3345} error code if the client +attempts one.%mdk + +%mdk-data-line={3348} +\mdline{3348}The default entry is identified by setting the \mdline{3348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3348} boolean field +to true. When this flag is set to true, the repeated \mdline{3349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3349} field must be empty +and the \mdline{3350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3350} field must be set to zero, otherwise the P4Runtime server +must return an \mdline{3351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3351} error code. When performing a \mdline{3351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3351} update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its \mdline{3355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3355} and \mdline{3355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3355} value as well as the +configurations for its\mdline{3356}~\mdref{sec-direct-resources}{direct resources}\mdline{3356} will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a \mdline{3358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3358} +error code if the client attempts to modify it.%mdk + +%mdk-data-line={3361} +\mdline{3361}Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to\mdline{3362}~\mdref{sec-direct-resources}{direct resources}\mdline{3362}.%mdk + +%mdk-data-line={3364} +\mdline{3364}In this P4Runtime release, we have decided to restrict the default entry for +indirect tables\mdline{3365} \mdline{3365}\textemdash{}\mdline{3365} tables with an ActionProfile or ActionSelector +\mdline{3366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3366} property\mdline{3366} \mdline{3366}\textemdash{}\mdline{3366} to a constant \mdline{3366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3366} action entry, with the +hope that it would simplify the implementation of the P4Runtime service.%mdk + +%mdk-data-line={3369} +\subsubsection{\mdline{3369}9.1.4.\hspace*{0.5em}\mdline{3369}Constant Tables}\label{sec-constant-tables}%mdk%mdk + +%mdk-data-line={3371} +\noindent\mdline{3371}Constant tables are defined as tables whose match entries are +immutable. They are identified by the table property \mdline{3372}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const~entries}}}\mdline{3372} +in the P4\mdline{3373}\mdsub{16}\mdline{3373} source code. In the P4Info, such tables have +\mdline{3374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3374} equal to true, and if the list of entries in the +source code has at least one entry in it, they also have +\mdline{3376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}has\_initial\_entries}}}\mdline{3376} flag equal to true. For tables declared with +the \mdline{3377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3377} property, without \mdline{3377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3377} before \mdline{3377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3377} see Section +\mdline{3378}\mdref{sec-preinitialized-tables}{9.1.5}\mdline{3378}.%mdk + +%mdk-data-line={3380} +\mdline{3380}The only write updates which are allowed for constant tables are \mdline{3380}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3380} +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +\mdline{3384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3384} error. Just like any table entry \mdline{3384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3384} request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a \mdline{3388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3388} error.%mdk + +%mdk-data-line={3390} +\mdline{3390}The contents of const tables can be queried by the client through a +\mdline{3391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3391}. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: \mdline{3392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3392}, \mdline{3392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3392}, \mdline{3392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3392}, +\mdline{3393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3393}, and \mdline{3393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3393} (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries.%mdk + +%mdk-data-line={3397} +\mdline{3397}When a priority value is required (\mdline{3397}e.g.\mdline{3397} for tables including \mdline{3397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3397}, +\mdline{3398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3398} or \mdline{3398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3398} matches), it is inferred based on the order in +which entries appear in the table declaration. As of August 2023, the +open source \mdline{3400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{3400} compiler always assigns entry priority values in a +constant table with \mdline{3401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}N}}}\mdline{3401} entries starting at \mdline{3401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}N}}}\mdline{3401} for the first entry +and decrementing the value by 1 for each successive entry. The P4\mdline{3402}\mdsub{16}\mdline{3402} +language specification does not preclude the P4 developer from +explicitly specifying priorities for entries in constant tables, but +\mdline{3405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{3405} does not yet support this.%mdk + +%mdk-data-line={3407} +\subsubsection{\mdline{3407}9.1.5.\hspace*{0.5em}\mdline{3407}Preinitialized tables}\label{sec-preinitialized-tables}%mdk%mdk + +%mdk-data-line={3409} +\noindent\mdline{3409}Preinitialized tables are those defined with an \mdline{3409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3409} table +property in the P4\mdline{3410}\mdsub{16}\mdline{3410} source code, with no \mdline{3410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3410} qualifier before +\mdline{3411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3411}, and at least one entry in that list. In the P4Info, such +tables have \mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}has\_initial\_entries}}}\mdline{3412} flag equal to true, but +\mdline{3413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3413} is false. For tables declared with \mdline{3413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const~entries}}}\mdline{3413}, +see Section\mdline{3414}~\mdref{sec-constant-tables}{9.1.4}\mdline{3414}.%mdk + +%mdk-data-line={3416} +\mdline{3416}Every P4 table falls into one of three categories:%mdk + +%mdk-data-line={3418} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3418} +\item\mdline{3418}\emph{Normal table}\mdline{3418}: Neither \mdline{3418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3418} nor \mdline{3418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const~entries}}}\mdline{3418} are declared +in the source code, and thus \mdline{3419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3419} and +\mdline{3420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}has\_initial\_entries}}}\mdline{3420} will both be false. A corner case is that if +it has \mdline{3421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries~=~\{~\}}}}\mdline{3421} with no \mdline{3421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3421} before \mdline{3421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3421}, \mdline{3421}i.e.\mdline{3421} an +empty list of entries, that is also a normal table.%mdk + +%mdk-data-line={3423} +\item\mdline{3423}\emph{Constant table}\mdline{3423}: The table has \mdline{3423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const~entries}}}\mdline{3423} declared, and thus a +separate \mdline{3424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3424} property is not permitted by the language. Such +a table will have \mdline{3425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3425} true. Such a table will have +\mdline{3426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}has\_initial\_entries}}}\mdline{3426} true if there is at least one entry in the +source code, or false if the list is empty.%mdk + +%mdk-data-line={3428} +\item\mdline{3428}\emph{Preinitialized table}\mdline{3428}: The table has \mdline{3428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3428} declared, and thus a +separate \mdline{3429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const~entries}}}\mdline{3429} property is not permitted by the language. +It also has at least one entry in the list. Such a table will have +\mdline{3431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3431} false and \mdline{3431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}has\_initial\_entries}}}\mdline{3431} true.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3433} +\noindent\mdline{3433}A preinitialized table is allowed to have a mix of some entries marked +\mdline{3434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3434}, and other entries not marked \mdline{3434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3434}.%mdk + +%mdk-data-line={3436} +\mdline{3436}Entries not marked \mdline{3436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3436} may be modified or deleted, just as a +client may do for any entry in a normal table.%mdk + +%mdk-data-line={3439} +\mdline{3439}Entries marked \mdline{3439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3439} behave like entries in a constant table, +\mdline{3440}i.e.\mdline{3440} only \mdline{3440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3440} operations on direct resources are allowed.%mdk + +%mdk-data-line={3442} +\mdline{3442}Unlike a table with \mdline{3442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table~=~true}}}\mdline{3442}, a client may insert +entries into a table with \mdline{3443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}has\_initial\_entries~=~true}}}\mdline{3443} and +\mdline{3444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table~=~false}}}\mdline{3444}, subject to capacity constraints on the +number of entries supported by the target for the table.%mdk + +%mdk-data-line={3447} +\mdline{3447}The contents of preinitialized tables can be queried by the client +through a \mdline{3448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3448}. The server fills in the same fields in the +response as it does for constant tables, as described in Section +\mdline{3450}\mdref{sec-constant-tables}{9.1.4}\mdline{3450}, and with the same restrictions on table +features supported.%mdk + +%mdk-data-line={3453} +\mdline{3453}If the table requires a priority value for entries, the priorities of +the initial entries are determined according to the P4\mdline{3454}\mdsub{16}\mdline{3454} language +specification. After the P4 program is initially loaded, the entries +not marked \mdline{3456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3456} can be modified at run time just as table entries +in a normal table can.%mdk + +%mdk-data-line={3459} +\mdline{3459}The contents of all table entries within the \mdline{3459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3459} table +properties in a P4 program can be written to a separate output file by +the open source \mdline{3461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{3461} compiler. See Section\mdline{3461}~\mdref{sec-entries-files}{A.5}\mdline{3461} for +details.%mdk + +%mdk-data-line={3464} +\subsubsection{\mdline{3464}9.1.6.\hspace*{0.5em}\mdline{3464}Wildcard Reads}\label{sec-table-wildcard-reads}%mdk%mdk + +%mdk-data-line={3466} +\noindent\mdline{3466}When performing a \mdline{3466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3466}, the P4Runtime client can select all entries +from one or all tables on the target and use several of the \mdline{3467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3467} fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as \mdline{3471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3471} and \mdline{3471}\textquotedblleft{}unset\textquotedblright{}\mdline{3471} for message fields such as \mdline{3471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3471}. The following +fields may be used to select and filter results:%mdk + +%mdk-data-line={3474} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3474} +\item\mdline{3474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3474}: If default (0), entries from all tables\mdline{3474} \mdline{3474}\textemdash{}\mdline{3474} including constant +tables\mdline{3475} \mdline{3475}\textemdash{}\mdline{3475} will be selected and no other filter can be used. Otherwise only +the specified table will be considered.%mdk + +%mdk-data-line={3477} +\item\mdline{3477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3477}: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned.%mdk + +%mdk-data-line={3481} +\item\mdline{3481}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3481}: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an \mdline{3482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3482} (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id.%mdk + +%mdk-data-line={3488} +\item\mdline{3488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3488}: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value.%mdk + +%mdk-data-line={3491} +\item\mdline{3491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3491}: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +\mdline{3493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3493} value.%mdk + +%mdk-data-line={3494} +\item\mdline{3494}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3494}: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided \mdline{3496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3496} value.%mdk + +%mdk-data-line={3497} +\item\mdline{3497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3497}: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered.%mdk + +%mdk-data-line={3500} +\item\mdline{3500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{3500}: If default (unset), all table entries will be considered. Otherwise, +table entries will be filtered based on the provided role value.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3503} +\noindent\mdline{3503}For example, in order to read all entries from all tables from device 3, the +client can use the following \mdline{3504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3504} message.%mdk + +%mdk-data-line={3506} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3507} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0}\\ +~~~~priority:~{\mdcolor{purple}0}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3518} +\noindent\mdline{3518}In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following \mdline{3519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3519} +message:%mdk + +%mdk-data-line={3522} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3523} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~priority:~{\mdcolor{purple}11}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3534} +\noindent\mdline{3534}The canonical representation of \mdline{3534}\textquotedblleft{}don't care\textquotedblright{}\mdline{3534} matches, combined with the ability +to do a wildcard read on all table entries by leaving the \mdline{3535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3535} field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single \mdline{3537}\textquotedblleft{}don't care\textquotedblright{}\mdline{3537} entry or to do a wildcard +read. If a table has no fields with match kind \mdline{3538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3538}, it is possible via +P4Runtime to add an entry that is \mdline{3539}\textquotedblleft{}don't care\textquotedblright{}\mdline{3539} for all fields (\mdline{3539}i.e.\mdline{3539} has an empty +\mdline{3540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3540} field) but is not the default entry (\mdline{3540}i.e.\mdline{3540} \mdline{3540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3540} is +false). When reading this entry from the table, there is no way to read \mdline{3541}\emph{only}\mdline{3541} +that entry from the table, because it would require providing an unset \mdline{3542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3542} +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single \mdline{3545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{3545} match:%mdk + +%mdk-data-line={3547} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3548} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;~fwd;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3558} +\noindent\mdline{3558}The following \mdline{3558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3558} message can be used to add 2 entries:%mdk + +%mdk-data-line={3559} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3560} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{~{\mdcolor{darkgreen}\#~don't~care~entry}\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +~~table~entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~match~\{\\ +~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~lpm~\{\\ +~~~~~~~~value:~{\mdcolor{purple}0x0a000000}\\ +~~~~~~~~prefix\_len:~{\mdcolor{purple}8}\\ +~~~~~~\}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3579} +\noindent\mdline{3579}The first entry is a \mdline{3579}\textquotedblleft{}don't care\textquotedblright{}\mdline{3579} entry, while the second one matches all +\mdline{3580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}10.0.0.0/8}}}\mdline{3580} addresses. The second entry has higher priority than the first one.%mdk + +%mdk-data-line={3582} +\mdline{3582}The following \mdline{3582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3582} message will return \mdline{3582}\emph{all}\mdline{3582} entries in the table, not +just the \mdline{3583}\textquotedblleft{}don't care\textquotedblright{}\mdline{3583} entry.%mdk + +%mdk-data-line={3584} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3585} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3593} +\noindent\mdline{3593}This issue also exists for tables with \mdline{3593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3593}, \mdline{3593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3593}, and \mdline{3593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3593} +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the \mdline{3596}\textquotedblleft{}don't care\textquotedblright{}\mdline{3596} entry will be returned to the +client. If the client uses distinct priority values for all entries\mdline{3597} \mdline{3597}\textemdash{}\mdline{3597} which is +strongly recommended to achieve\mdline{3598}~\mdref{sec-table-entry}{deterministic behavior}\mdline{3598} \mdline{3598}\textemdash{}\mdline{3598}, +then there is no ambiguity because the wildcard read will actually return a +single entry (the \mdline{3600}\textquotedblleft{}don't care\textquotedblright{}\mdline{3600} entry) as long as the \mdline{3600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3600} field is set to +the correct value.%mdk + +%mdk-data-line={3603} +\subsubsection{\mdline{3603}9.1.7.\hspace*{0.5em}\mdline{3603}Direct Resources}\label{sec-direct-resources}%mdk%mdk + +%mdk-data-line={3605} +\noindent\mdline{3605}In addition to the \mdline{3605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3605} and \mdline{3605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3605} entities, +P4Runtime support reading and writing direct resources as part of the +\mdline{3607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3607} message. This is convenient for two reasons:%mdk + +%mdk-data-line={3609} +\begin{itemize}%mdk + +%mdk-data-line={3609} +\item{} +%mdk-data-line={3609} +\mdline{3609}A table entry and its direct resources can be read with a single entity when +doing a \mdline{3610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{3610} RPC call%mdk%mdk + +%mdk-data-line={3612} +\item{} +%mdk-data-line={3612} +\mdline{3612}The initial configuration for an entry\mdline{3612}'\mdline{3612}s direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can \mdline{3617}\textquotedblleft{}hit\textquotedblright{}\mdline{3617} the table entry without +executing the appropriate meter entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3620} +\noindent\mdline{3620}Once the table entry has been inserted, the P4Runtime client is free to use the +\mdline{3621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3621} and \mdline{3621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3621} messages for read and write +operations on \mdline{3622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3622} and \mdline{3622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3622} instances. For example, it is +usually more convenient as well as more efficient to use \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3623} to +query a counter entry value rather than use \mdline{3624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3624}, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry.%mdk + +%mdk-data-line={3628} +\mdline{3628}The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does \mdline{3629}\emph{not}\mdline{3629} need to be \mdline{3629}\textquotedblleft{}executed\textquotedblright{}\mdline{3629} in +every action bound to the table. It is an error to provide a direct resource +configuration in a \mdline{3631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3631} message when programming an action that does not +execute the direct resource, and the server must return an \mdline{3632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3632} +error code.%mdk + +%mdk-data-line={3635} +\mdline{3635}We leverage Protobuf\mdline{3635}'\mdline{3635}s ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the \mdline{3637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3637} message. The list below describes how +the server must handle the \mdline{3638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3638}, \mdline{3638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3638} and +\mdline{3639}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3639} fields for read and write requests, based on whether the +fields are set or not. We do not cover error cases in the list, \mdline{3640}i.e.\mdline{3640} we assume +that we are dealing with a table which is assigned a direct counter / a direct +meter, and that the action being used for the table entry \mdline{3642}\textquotedblleft{}executes\textquotedblright{}\mdline{3642} the direct +resource appropriately.%mdk + +%mdk-data-line={3645} +\begin{itemize}%mdk + +%mdk-data-line={3645} +\item{} +%mdk-data-line={3645} +\mdline{3645}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3645} field%mdk + +%mdk-data-line={3646} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3646} +\item\mdline{3646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3646} + +%mdk-data-line={3647} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3647} +\item\mdline{3647}if \mdline{3647}\textbf{unset}\mdline{3647}: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets).%mdk + +%mdk-data-line={3649} +\item\mdline{3649}if \mdline{3649}\textbf{set}\mdline{3649}: The initial configuration for the meter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3651} +\item\mdline{3651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3651} + +%mdk-data-line={3652} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3652} +\item\mdline{3652}if \mdline{3652}\textbf{unset}\mdline{3652}: The meter entry\mdline{3652}'\mdline{3652}s configuration is reset to the default +(meter returns GREEN for all packets).%mdk + +%mdk-data-line={3654} +\item\mdline{3654}if \mdline{3654}\textbf{set}\mdline{3654}: The value provided by the client is used to re-configure +the meter entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3656} +\item\mdline{3656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3656} + +%mdk-data-line={3657} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3657} +\item\mdline{3657}if \mdline{3657}\textbf{unset}\mdline{3657}: The response does not include the meter entry\mdline{3657}'\mdline{3657}s +configuration (\mdline{3658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3658} is unset in the response).%mdk + +%mdk-data-line={3659} +\item\mdline{3659}if \mdline{3659}\textbf{set}\mdline{3659}: If the meter entry\mdline{3659}'\mdline{3659}s configuration is the default +configuration, \mdline{3660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3660} is unset in the response. Otherwise, the +response includes the meter entry\mdline{3661}'\mdline{3661}s configuration that was written by +the client earlier. This respects the \mdline{3662}\textquotedblleft{}read-write symmetry\textquotedblright{}\mdline{3662} principle.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3664} +\item{} +%mdk-data-line={3664} +\mdline{3664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3664} field%mdk + +%mdk-data-line={3665} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3665} +\item\mdline{3665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3665} + +%mdk-data-line={3666} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3666} +\item\mdline{3666}if \mdline{3666}\textbf{unset}\mdline{3666}: The initial value for the counter entry is the default +(0).%mdk + +%mdk-data-line={3668} +\item\mdline{3668}if \mdline{3668}\textbf{set}\mdline{3668}: The initial value for the counter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3670} +\item\mdline{3670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3670} + +%mdk-data-line={3671} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3671} +\item\mdline{3671}if \mdline{3671}\textbf{unset}\mdline{3671}: The counter entry\mdline{3671}'\mdline{3671}s value is not changed.%mdk + +%mdk-data-line={3672} +\item\mdline{3672}if \mdline{3672}\textbf{set}\mdline{3672}: The value provided by the client is written to the counter +entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3674} +\item\mdline{3674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3674} + +%mdk-data-line={3675} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3675} +\item\mdline{3675}if \mdline{3675}\textbf{unset}\mdline{3675}: The response does not include the counter entry\mdline{3675}'\mdline{3675}s value +(\mdline{3676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3676} is unset in the response).%mdk + +%mdk-data-line={3677} +\item\mdline{3677}if \mdline{3677}\textbf{set}\mdline{3677}: The response includes the counter entry\mdline{3677}'\mdline{3677}s value read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3680} +\item{} +%mdk-data-line={3680} +\mdline{3680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3680} field%mdk + +%mdk-data-line={3681} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3681} +\item\mdline{3681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3681} + +%mdk-data-line={3682} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3682} +\item\mdline{3682}if \mdline{3682}\textbf{unset}\mdline{3682}: The initial value for all 3 counter entries is the +default (0).%mdk + +%mdk-data-line={3684} +\item\mdline{3684}if \mdline{3684}\textbf{set}\mdline{3684}: The initial value for all 3 counter entries is the +default (0). Sub-field, if any, can only have zero (0) as its value. +\mdline{3686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3686} error is returned for any non-zero sub-field value.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3687} +\item\mdline{3687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3687} + +%mdk-data-line={3688} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3688} +\item\mdline{3688}if \mdline{3688}\textbf{unset}\mdline{3688}: All the 3 counter entries are unchanged.%mdk + +%mdk-data-line={3689} +\item\mdline{3689}if \mdline{3689}\textbf{set}\mdline{3689}: All the 3 counters are reset to 0. Sub-field, if any, can +only have zero (0) as its value. \mdline{3690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3690} error is returned +for any non-zero sub-field value.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3692} +\item\mdline{3692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3692} + +%mdk-data-line={3693} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3693} +\item\mdline{3693}if \mdline{3693}\textbf{unset}\mdline{3693}: The response does not include counter values +(\mdline{3694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3694} is unset in the response).%mdk + +%mdk-data-line={3695} +\item\mdline{3695}if \mdline{3695}\textbf{set}\mdline{3695}: The response includes all the 3 counter values read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3698} +\noindent\mdline{3698}In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +\mdline{3700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3700} field unset when inserting \mdline{3700}\textbf{or modifying}\mdline{3700} a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the \mdline{3702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3702} message +(\mdline{3703}i.e.\mdline{3703} the \mdline{3703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3703} field must be set to match the existing configuration).%mdk + +%mdk-data-line={3705} +\subsubsection{\mdline{3705}9.1.8.\hspace*{0.5em}\mdline{3705}Idle-timeout}\label{sec-idle-timeout}%mdk%mdk + +%mdk-data-line={3707} +\noindent\mdline{3707}P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not \mdline{3709}\textquotedblleft{}hit\textquotedblright{}\mdline{3709} (\mdline{3709}i.e.\mdline{3709} not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification\mdline{3711} \mdline{3711}\textemdash{}\mdline{3711} using the +\mdline{3712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3712} message\mdline{3712} \mdline{3712}\textemdash{}\mdline{3712} to the primary client, which can then take +action, such as remove the idle table entry.%mdk + +%mdk-data-line={3715} +\mdline{3715}Two fields of the \mdline{3715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3715} Protobuf message are used to implement idle +timeout:%mdk + +%mdk-data-line={3718} +\begin{itemize}%mdk + +%mdk-data-line={3718} +\item{} +%mdk-data-line={3718} +\mdline{3718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3718}: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, \mdline{3719}i.e.\mdline{3719} no +\mdline{3720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3720} message will ever be generated for this entry. When +a client reads a \mdline{3721}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3721}, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry.%mdk%mdk + +%mdk-data-line={3725} +\item{} +%mdk-data-line={3725} +\mdline{3725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3725}: a Protobuf message with a single field (\mdline{3725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{3725}) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The \mdline{3727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3727} field must be unset for a +\mdline{3728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3728} write. When reading a table entry, \mdline{3728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3728} must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3733} +\noindent\mdline{3733}These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an \mdline{3735}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3735} error code if at least one of these +conditions is met:%mdk + +%mdk-data-line={3738} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3738} +\item\mdline{3738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3738} is set to a non-zero value, or%mdk + +%mdk-data-line={3739} +\item\mdline{3739}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3739} is set%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3741} +\noindent\mdline{3741}The target should do its best to approximate the \mdline{3741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3741} value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the \mdline{3744}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3744} write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for \mdline{3746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3746}.%mdk + +%mdk-data-line={3748} +\mdline{3748}P4Runtime does not support idle timeout for default entries. When the +\mdline{3749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3749} flag is set in a \mdline{3749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3749} message, \mdline{3749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3749} +must be set to 0 (default) and \mdline{3750}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3750} must be unset. If the +server receives a \mdline{3751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3751} message which violates this, it must return an +\mdline{3752}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3752} error.%mdk + +%mdk-data-line={3754} +\mdline{3754}For more information about idle timeout, in particular regarding +\mdline{3755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3755}, please refer to the\mdline{3755}~\mdref{sec-table-idle-timeout-notification}{Table idle timeout +notifications}\mdline{3756} section.%mdk + +%mdk-data-line={3758} +\subsection{\mdline{3758}9.2.\hspace*{0.5em}\mdline{3758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3758} \mdline{3758}\&\mdline{3758} \mdline{3758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}\label{sec-action-profile-member-and-group}%mdk%mdk + +%mdk-data-line={3760} +\noindent\mdline{3760}P4Runtime defines an API for programming a PSA ActionProfile extern using +\mdline{3761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3761} messages. A PSA ActionSelector extern can be programmed +using both \mdline{3762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3762} and \mdline{3762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3762} messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table \mdline{3766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3766} for L3 routing, implemented with an action +selector \mdline{3767}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3767}.%mdk + +%mdk-data-line={3769} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3770} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector(HashAlgorithm.crc32,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}size~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w1024,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}output\_width~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w10)~as;\\ +\\ +{\bfseries{\mdcolor{navy}action}}~set\_nhop(PortId\_t~p,~EthAddr~smac,~EthAddr~dmac)~\{\\ +~~istd.egress\_port~=~p;\\ +~~hdr.ethernet.smac~=~smac;\\ +~~hdr.ethernet.dmac~=~dmac;\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;~~{\mdcolor{darkgreen}//~LPM~on~destination~IP~address}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~set\_nhop;\\ +~~\}\\ +~~implementation~=~as;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3791} +\noindent\mdline{3791}When programming table \mdline{3791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3791} in the example above, a P4Runtime client should +specify the \mdline{3792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3792} in the \mdline{3792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3792} to be a reference to either an +action profile member or group. The reference is a non-zero \mdline{3793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3793} identifier +that uniquely identifies a member or group programmed in the action selector +\mdline{3795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3795}.%mdk + +%mdk-data-line={3797} +\mdline{3797}If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata.%mdk + +%mdk-data-line={3802} +\mdline{3802}If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata.%mdk + +%mdk-data-line={3813} +\subsubsection{\mdline{3813}9.2.1.\hspace*{0.5em}\mdline{3813}Action Profile Member Programming}\label{sec-action-profile-member-programming}%mdk%mdk + +%mdk-data-line={3815} +\noindent\mdline{3815}Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a \mdline{3816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3816} identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the \mdline{3818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3818} +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the \mdline{3820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3820} attributes of the +tables \mdline{3821}\emph{must have an identical list of P4 actions}\mdline{3821}. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector.%mdk + +%mdk-data-line={3825} +\mdline{3825}An \mdline{3825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3825} entity update message has the following fields:%mdk + +%mdk-data-line={3827} +\begin{itemize}%mdk + +%mdk-data-line={3827} +\item{} +%mdk-data-line={3827} +\mdline{3827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3827} is the \mdline{3827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3827} identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3830} +\item{} +%mdk-data-line={3830} +\mdline{3830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3830} is the non-zero \mdline{3830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3830} identifier of the action profile member +entry being updated.%mdk%mdk + +%mdk-data-line={3833} +\item{} +%mdk-data-line={3833} +\mdline{3833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3833} is the specification of the P4 action instance bound to the action +profile member entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3836} +\noindent\mdline{3836}An action profile member may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3839} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3839} +\item\mdline{3839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3839}: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an \mdline{3841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3841} error +code. The action specification must be provided, or the server must return +\mdline{3843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3843}. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return \mdline{3845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3845}.%mdk + +%mdk-data-line={3846} +\item\mdline{3846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3846}: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return \mdline{3847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3847}, +and the action specification must be provided, or the server must return +\mdline{3849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3849}.%mdk + +%mdk-data-line={3850} +\item\mdline{3850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3850}: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a \mdline{3851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3851} error code. The member +must not be part of an action profile group, or the server must return +\mdline{3853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3853}. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return \mdline{3856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3856}. \mdline{3856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3856} and \mdline{3856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3856} are the only +fields that are considered when performing a \mdline{3857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3857} and every other field +will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3860} +\noindent\mdline{3860}When reading, an \mdline{3860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3860} message with \mdline{3860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3860} and +\mdline{3861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3861} equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with \mdline{3862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3862} equal to the id of +an existing ActionProfile or ActionSelector object, and a \mdline{3863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3863} equal to +0, will read all members of that specified object.%mdk + +%mdk-data-line={3866} +\subsubsection{\mdline{3866}9.2.2.\hspace*{0.5em}\mdline{3866}Action Profile Group Programming}\label{sec-action-profile-group-programming}%mdk%mdk + +%mdk-data-line={3868} +\noindent\mdline{3868}Action profile groups are entries in an ActionSelector and are referenced by a +\mdline{3869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3869} identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type.%mdk + +%mdk-data-line={3873} +\mdline{3873}Within a single ActionSelector object, the \mdline{3873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3873} values used to identify its +members are in a separate \mdline{3874}\textquoteleft{}scope\textquoteright{}\mdline{3874} from the \mdline{3874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3874} values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5.%mdk + +%mdk-data-line={3878} +\mdline{3878}There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it.%mdk + +%mdk-data-line={3884} +\mdline{3884}An \mdline{3884}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3884} entity update message has the following fields:%mdk + +%mdk-data-line={3886} +\begin{itemize}%mdk + +%mdk-data-line={3886} +\item{} +%mdk-data-line={3886} +\mdline{3886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3886} is the \mdline{3886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3886} identifier of the PSA ActionSelector +extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3889} +\item{} +%mdk-data-line={3889} +\mdline{3889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3889} is the non-zero \mdline{3889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3889} identifier of the action profile group +entry being updated.%mdk%mdk + +%mdk-data-line={3892} +\item{} +%mdk-data-line={3892} +\mdline{3892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3892} is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields:%mdk + +%mdk-data-line={3895} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3895} +\item\mdline{3895}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3895} for looking up the member table in the selector.%mdk + +%mdk-data-line={3896} +\item\mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3896} specifying the probability of the member\mdline{3896}'\mdline{3896}s selection at +runtime. 0 is not a valid \mdline{3897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3897} value and the server must return +\mdline{3898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3898} if the client attempts to use it.%mdk + +%mdk-data-line={3899} +\item\mdline{3899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3899} is the controller-defined port that the member\mdline{3899}'\mdline{3899}s +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +\mdline{3902}\mdref{action-selector-constraints}{9.2.4}\mdline{3902} for notes on the behavior if all members in +a group are excluded for this reason. If \mdline{3903}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3903} is empty, then the +member is always included in the selection, regardless of the status of +any port of the device. The value must be empty or the SDN port of an +existing port on the device, otherwise the server must return +\mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3907}. If the target does not support using the SDN port as a +watch port (\mdline{3908}e.g.\mdline{3908} on some targets LAGs cannot be used for this purpose), +the server must return \mdline{3909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3909}.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3911} +\item{} +%mdk-data-line={3911} +\mdline{3911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3911} is the maximum sum of all members or member weights (as per the +\mdline{3912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{3912}) for the group. This field is defined when the group +is inserted, and must not be changed in a \mdline{3913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3913} update, otherwise an +\mdline{3914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3914} error is returned. See the subsection below for the +\mdline{3915}\mdref{sec-max-size-rules}{rules on setting \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\mdline{3915}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3917} +\noindent\mdline{3917}An action profile group may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3920} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3920} +\item\mdline{3920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3920}: Add a new group entry bound to a set of existing action profile +members. \mdline{3921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}The~group\_id}}}\mdline{3921} must be different from ids of already programmed +groups for that selector, or the server must return an \mdline{3922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3922} error +code. All members specified in the group must exist in the selector, or the +server must return \mdline{3924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3924}. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target.%mdk + +%mdk-data-line={3926} +\item\mdline{3926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3926}: Modify the member set specification of an existing group entry. An +entry with the \mdline{3927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3927} must exist, or the server must return +\mdline{3928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3928}. All members specified in the group entry must exist in the +selector, or the server must return \mdline{3929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3929}. The value of \mdline{3929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3929} must +be identical to the value used when inserting the group, otherwise an +\mdline{3931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3931} error is returned.%mdk + +%mdk-data-line={3932} +\item\mdline{3932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3932}: Delete the group entry and deallocate the \mdline{3932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3932}. The group must +not be referenced in the table action of any table entry, or the server must +return a \mdline{3934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3934} error code. If the \mdline{3934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3934} is invalid, the +server must return \mdline{3935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3935}. \mdline{3935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3935} and \mdline{3935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3935} are the +only fields that are considered when performing a \mdline{3936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3936} and every other +field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3939} +\noindent\mdline{3939}When setting the group membership with \mdline{3939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3939} or \mdline{3939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3939}, the \mdline{3939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3939} +repeated field must not include duplicates, \mdline{3940}i.e.\mdline{3940} members with the same +\mdline{3941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3941}. The \mdline{3941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3941} field is used instead to logically \mdline{3941}\textquotedblleft{}repeat\textquotedblright{}\mdline{3941} the member +inside the group.%mdk + +%mdk-data-line={3944} +\mdline{3944}It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation \mdline{3945}\textquotedblleft{}stores\textquotedblright{}\mdline{3945} the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made.%mdk + +%mdk-data-line={3949} +\mdline{3949}When reading, an \mdline{3949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3949} message with \mdline{3949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3949} and +\mdline{3950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3950} equal to 0 will read all groups of all ActionSelector objects. A +message with \mdline{3951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3951} equal to the id of an existing ActionSelector +object, and a \mdline{3952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3952} equal to 0, will read all groups of that one specified +object.%mdk + +%mdk-data-line={3955} +\paragraph{\mdline{3955}9.2.2.1.\hspace*{0.5em}\mdline{3955}Rules on Setting \mdline{3955}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\label{sec-max-size-rules}%mdk%mdk + +%mdk-data-line={3957} +\noindent\mdline{3957}The valid values for \mdline{3957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3957} depend on the static \mdline{3957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3957} included +in the P4Info message:%mdk + +%mdk-data-line={3960} +\begin{itemize}%mdk + +%mdk-data-line={3960} +\item{} +%mdk-data-line={3960} +\mdline{3960}If \mdline{3960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3960} is greater than 0, then \mdline{3960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3960} must be greater than 0, +and less than or equal to \mdline{3961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3961}. We assume that the target can +support selector groups for which the size of the members (as defined by +\mdline{3963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{3963}) is up to \mdline{3963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3963}, or the P4Runtime server +would have rejected the Forwarding Pipeline Config. If \mdline{3964}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3964} is greater +than \mdline{3965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3965}, the server must return \mdline{3965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3965}.%mdk%mdk + +%mdk-data-line={3967} +\item{} +%mdk-data-line={3967} +\mdline{3967}Otherwise (\mdline{3967}i.e.\mdline{3967} if \mdline{3967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3967} is 0), the P4Runtime client can set +\mdline{3968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3968} to any value greater than or equal to 0.%mdk + +%mdk-data-line={3970} +\begin{itemize}%mdk + +%mdk-data-line={3970} +\item{} +%mdk-data-line={3970} +\mdline{3970}A \mdline{3970}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3970} of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (\mdline{3973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3973} or \mdline{3973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3973}), the target must return a +\mdline{3974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3974} error.%mdk%mdk + +%mdk-data-line={3976} +\item{} +%mdk-data-line={3976} +\mdline{3976}If \mdline{3976}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3976} is greater than 0 and the value is not supported by the +target, the server must return a \mdline{3977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3977} error at +group-creation time.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3980} +\subsubsection{\mdline{3980}9.2.3.\hspace*{0.5em}\mdline{3980}One Shot Action Selector Programming}\label{sec-oneshot}%mdk%mdk + +%mdk-data-line={3982} +\noindent\mdline{3982}P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids.%mdk + +%mdk-data-line={3988} +\mdline{3988}One shots are programmed by choosing the \mdline{3988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3988} message as the +\mdline{3989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3989}. The \mdline{3989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3989} message consists of a set of +\mdline{3990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3990} messages. This set should have cardinality no greater than +\mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3991} (if \mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3991} is nonzero) if \mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{3991} +is \mdline{3992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_members}}}\mdline{3992}, or else the server must return \mdline{3992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3992}. Each +\mdline{3993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3993} message has the following fields:%mdk + +%mdk-data-line={3995} +\begin{itemize}%mdk + +%mdk-data-line={3995} +\item{} +%mdk-data-line={3995} +\mdline{3995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3995} is one of the actions specified by the table that is being +programmed.%mdk%mdk + +%mdk-data-line={3998} +\item{} +%mdk-data-line={3998} +\mdline{3998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3998} specifying the probability of the action\mdline{3998}'\mdline{3998}s selection at runtime. 0 is +not a valid \mdline{3999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3999} value and the server must return \mdline{3999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3999} if +the client attempts to use it. If \mdline{4000}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{4000} is +\mdline{4001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_weights}}}\mdline{4001}, then the sum of all weights across all \mdline{4001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{4001} +messages for that \mdline{4002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{4002} message must not exceed the +\mdline{4003}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{4003} specified in the P4Info (if greater than 0), or the server +must return \mdline{4004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4004}. If \mdline{4004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{4004} is +\mdline{4005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_members}}}\mdline{4005}, the individual weight of each member must not exceed +\mdline{4006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_member\_weight}}}\mdline{4006} (if greater than 0), or the server must return +\mdline{4007}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4007}.%mdk%mdk + +%mdk-data-line={4009} +\item{} +%mdk-data-line={4009} +\mdline{4009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{4009} is the controller-defined port that the action\mdline{4009}'\mdline{4009}s liveness depends +on. At runtime, the action must be excluded from selection if the watch port +is down. See Section\mdline{4011}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{4011} for more details +on the \mdline{4012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{4012} field, which also apply for one shot action selector +programming.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4016} +\noindent\mdline{4016}Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics.%mdk + +%mdk-data-line={4021} +\mdline{4021}To preserve read-write symmetry, an implementation must answer \mdline{4021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4021}s +with the original one shot messages. It may not return a desugared version of +the one shot message.%mdk + +%mdk-data-line={4025} +\mdline{4025}For example, consider the action selector table defined +\mdline{4026}\mdref{sec-action-profile-member-and-group}{here}\mdline{4026}. This table could be programmed +with the following one shot update:%mdk + +%mdk-data-line={4029} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4030} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{\\ +~~~~action\_profile\_action\_set~\{\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}1}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x01}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}2}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x02}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}3}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x03}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4055} +\noindent\mdline{4055}Which would be equivalent to the following updates, where \mdline{4055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GROUP\_ID}}}\mdline{4055}, +\mdline{4056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_1}}}\mdline{4056}, \mdline{4056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_2}}}\mdline{4056}, and \mdline{4056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_3}}}\mdline{4056} are unused ids:%mdk + +%mdk-data-line={4058} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4059} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_1\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_2\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_3\\ +~~action~\{~~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +\}\\ +action\_profile\_group~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~group\_id:~GROUP\_ID\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_1\\ +~~~~weight:~{\mdcolor{purple}1}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x01}{\mdcolor{maroon}"}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_2\\ +~~~~weight:~{\mdcolor{purple}2}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x02}{\mdcolor{maroon}"}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_3\\ +~~~~weight:~{\mdcolor{purple}3}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x03}{\mdcolor{maroon}"}\\ +~~\}\\ +\}\\ +table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{~action\_profile\_group\_id:~GROUP\_ID~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4100} +\noindent\mdline{4100}Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure\mdline{4101}~\mdref{sec-batching-and-ordering-of-updates}{correct ordering between the dependent +updates}\mdline{4102}. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct \mdline{4104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4104} batches are required.%mdk + +%mdk-data-line={4106} +\mdline{4106}It is possible to include several \mdline{4106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{4106} messages with the same +exact \mdline{4107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{4107} specification in one \mdline{4107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{4107} message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the \mdline{4109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{4109} field. Note that to preserve read-write symmetry, the server +must not coalesce multiple \mdline{4110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{4110} messages with the same \mdline{4110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{4110} +specification into one. Additionally, each \mdline{4111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{4111} specification would count as +a separate member for the purposes of \mdline{4112}e.g.\mdline{4112} the \mdline{4112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_members}}}\mdline{4112} group size +calculation for Action Selectors.%mdk + +%mdk-data-line={4115} +\mdline{4115}All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with \mdline{4116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4116} and +\mdline{4117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{4117} messages. Programming some entries with one shots, and +other entries with \mdline{4118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4118} and \mdline{4118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{4118} messages is +not allowed, and the server must return the error code \mdline{4119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4119} in +that case.%mdk + +%mdk-data-line={4122} +\mdline{4122}A P4Runtime server \mdline{4122}\emph{must}\mdline{4122} support the one shot style of programming tables with +an action selector implementation. Support for the \mdline{4123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4123} and +\mdline{4124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{4124} style is \mdline{4124}\emph{optional}\mdline{4124}. If \mdline{4124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4124} and +\mdline{4125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{4125} are not supported by a server, it must return an +\mdline{4126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4126} error for every \mdline{4126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4126} or \mdline{4126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{4126} +message that it receives.%mdk + +%mdk-data-line={4129} +\subsubsection{\mdline{4129}9.2.4.\hspace*{0.5em}\mdline{4129}Constraints on action selector programming}\label{action-selector-constraints}%mdk%mdk + +%mdk-data-line={4131} +\noindent\mdline{4131}The PSA specification states that the following features are \mdline{4131}\emph{optional}\mdline{4131} in +action selector implementations\mdline{4132}~[\mdcite{psaactionselector}{27}]\mdline{4132}:%mdk + +%mdk-data-line={4134} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4134} +\item\mdline{4134}Support for non-empty groups where in the same group, different members are +bound to different actions.%mdk + +%mdk-data-line={4136} +\item\mdline{4136}Predictable data plane behavior when a matched table entry points to an empty +group.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4139} +\noindent\mdline{4139}For 1., if a client tries to \mdline{4139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4139} or \mdline{4139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4139} a group with members bound to +different actions, the server should return \mdline{4140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4140} if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return \mdline{4146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4146} (modifying the action parameter values must be +supported, however).%mdk + +%mdk-data-line={4149} +\mdline{4149}PSA 1.1 introduces the \mdline{4149}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4149} table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. \mdline{4153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4153} is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of \mdline{4156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4156} at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +\mdline{4158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{4158}. Even when \mdline{4158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4158} is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of \mdline{4162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4162} mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming.%mdk + +%mdk-data-line={4167} +\mdline{4167}The PSA specification includes a discussion on how to implement +\mdline{4168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4168} in software in the P4Runtime server +\mdline{4169}[\mdcite{psaemptygroupactionappendix}{30}]\mdline{4169}.%mdk + +%mdk-data-line={4171} +\mdline{4171}If a P4Runtime implementation does support \mdline{4171}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4171}, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down.%mdk + +%mdk-data-line={4175} +\mdline{4175}If a P4Runtime implementation does not support \mdline{4175}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4175}, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down.%mdk + +%mdk-data-line={4181} +\subsection{\mdline{4181}9.3.\hspace*{0.5em}\mdline{4181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4181} \mdline{4181}\&\mdline{4181} \mdline{4181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-counterentry-directcounterentry}%mdk%mdk + +%mdk-data-line={4183} +\noindent\mdline{4183}PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The \mdline{4185}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{4185} +P4Runtime message can be used for all three types of PSA counters\mdline{4186} \mdline{4186}\textemdash{}\mdline{4186} \mdline{4186}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{4186}, +\mdline{4187}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{4187} and \mdline{4187}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{4187} \mdline{4187}\textemdash{}\mdline{4187} and consists of the following fields:%mdk + +%mdk-data-line={4189} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4189} +\item\mdline{4189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{4189} is an \mdline{4189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4189}, corresponding to the number of octets.%mdk + +%mdk-data-line={4190} +\item\mdline{4190}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{4190} is an \mdline{4190}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4190}, corresponding to the number of packets.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4192} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4193} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterData~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~byte\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}int64}}~packet\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4199} +\noindent\mdline{4199}P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of \mdline{4200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{4200} and \mdline{4200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{4200} fields, which +is equivalent to specifying the counter type \mdline{4201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{4201}. Counters may +be defined as direct or indirect (indexed) instances.%mdk + +%mdk-data-line={4204} +\subsubsection{\mdline{4204}9.3.1.\hspace*{0.5em}\mdline{4204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-directcounterentry}%mdk%mdk + +%mdk-data-line={4206} +\noindent\mdline{4206}A direct counter is a direct resource associated with a \mdline{4206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4206} (see +\mdline{4207}\mdref{sec-direct-resources}{Direct Resources}\mdline{4207}). The \mdline{4207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4207} field of the +\mdline{4208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4208} message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +\mdline{4211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{4211} message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed.%mdk + +%mdk-data-line={4214} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4215} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectCounterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4221} +\noindent\mdline{4221}A \mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4221} may only include an \mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4221} message of type \mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4221} with a +\mdline{4222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{4222}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={4224} +\begin{itemize}%mdk + +%mdk-data-line={4224} +\item{} +%mdk-data-line={4224} +\mdline{4224}the \mdline{4224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4224} field must match \mdline{4224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry.match}}}\mdline{4224} of the table entry +to which this direct counter entry is associated. If a matching \mdline{4225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4225} +is not found, the server returns the error code \mdline{4226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4226}.%mdk%mdk + +%mdk-data-line={4228} +\item{} +%mdk-data-line={4228} +\mdline{4228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4228} is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4232} +\noindent\mdline{4232}Specifying \mdline{4232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{4232} in an \mdline{4232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4232} message of type \mdline{4232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4232} or +\mdline{4233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4233} is not allowed, and the server must return the error code +\mdline{4234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4234} in that case.%mdk + +%mdk-data-line={4236} +\mdline{4236}A client may use \mdline{4236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4236} in two ways to read the contents of a +\mdline{4237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{4237}:%mdk + +%mdk-data-line={4239} +\begin{itemize}%mdk + +%mdk-data-line={4239} +\item{} +%mdk-data-line={4239} +\mdline{4239}As a direct resource associated with a table entry, request the server to +return the counter value in the \mdline{4240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4240} field of the \mdline{4240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4240} message +(see\mdline{4241}~\mdref{sec-direct-resources}{Direct resources}\mdline{4241}).%mdk%mdk + +%mdk-data-line={4243} +\item{} +%mdk-data-line={4243} +\mdline{4243}Explicitly request the counter value by including the \mdline{4243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{4243} in +the \mdline{4244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4244}. The \mdline{4244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4244} field must match the \mdline{4244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4244} +whose counter is being read. If no such entry is found, the server returns the +error code \mdline{4246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4246}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4248} +\subsubsection{\mdline{4248}9.3.2.\hspace*{0.5em}\mdline{4248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}\label{sec-counterentry}%mdk%mdk + +%mdk-data-line={4250} +\noindent\mdline{4250}An indirect or indexed counter is not associated with a specific \mdline{4250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4250} +and may be updated independently of any action. It may be read or written using +the P4Runtime \mdline{4252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4252} message whose fields are defined as follows:%mdk + +%mdk-data-line={4254} +\begin{itemize}%mdk + +%mdk-data-line={4254} +\item{} +%mdk-data-line={4254} +\mdline{4254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4254} is a \mdline{4254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4254}, the unique identifier for the counter.%mdk%mdk + +%mdk-data-line={4256} +\item{} +%mdk-data-line={4256} +\mdline{4256}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4256} is a Protobuf message that encapsulates an \mdline{4256}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4256}, used to index into +the counter array.%mdk%mdk + +%mdk-data-line={4259} +\item{} +%mdk-data-line={4259} +\mdline{4259}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4259} is a Protobuf message of type \mdline{4259}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{4259}, which represents the +counter value.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4262} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4263} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~counter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4270} +\noindent\mdline{4270}The \mdline{4270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4270} can only be used in a \mdline{4270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4270} with the \mdline{4270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4270} update +type. The P4Runtime server must return an \mdline{4271}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4271} error code for +update types \mdline{4272}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4272} and \mdline{4272}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4272}. By default all the counter entries in the +array have default value 0.%mdk + +%mdk-data-line={4275} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4275} +\item\mdline{4275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4275}: Server returns the error code \mdline{4275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4275}.%mdk + +%mdk-data-line={4276} +\item\mdline{4276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4276}: Modify an indirect counter instance whose unique id is \mdline{4276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4276} +and array index is specified by \mdline{4277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4277}. The counter value is set to the value +specified by the client in the \mdline{4278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4278} field. Note that the counter value is +not modified if this Protobuf field is not set. If \mdline{4279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4279} is omitted all +counter values in the array will be set to the value provided by the +client. The server must return \mdline{4281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4281} for a negative index value +and \mdline{4282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4282} if the index value exceeds the size of the counter array.%mdk + +%mdk-data-line={4283} +\item\mdline{4283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4283}: Server returns the error code \mdline{4283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4283}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4285} +\noindent\mdline{4285}A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a \mdline{4286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4286} by including a \mdline{4286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4286} +entity for each of the instances, specifying the \mdline{4287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4287} and +\mdline{4288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4288}. Wildcard reads are also supported as follows:%mdk + +%mdk-data-line={4290} +\begin{itemize}%mdk + +%mdk-data-line={4290} +\item{} +%mdk-data-line={4290} +\mdline{4290}If the \mdline{4290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4290} field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the \mdline{4291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4291}.%mdk%mdk + +%mdk-data-line={4293} +\item{} +%mdk-data-line={4293} +\mdline{4293}Otherwise, if the \mdline{4293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4293} field is not set, the server returns the counter +values for all indirect counters in the array identified by the unique id +\mdline{4295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4295}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4297} +\subsection{\mdline{4297}9.4.\hspace*{0.5em}\mdline{4297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4297} \mdline{4297}\&\mdline{4297} \mdline{4297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-meterentry-directmeterentry}%mdk%mdk + +%mdk-data-line={4299} +\noindent\mdline{4299}Meters are an advanced mechanism for keeping statistics, involving stateful +\mdline{4300}\textquotedblleft{}marking\textquotedblright{}\mdline{4300} and usually \mdline{4300}\textquotedblleft{}throttling\textquotedblright{}\mdline{4300} of packets based on configured rates of +traffic. The PSA metering function is based on the \mdline{4301}\emph{Two Rate Three Color Marker}\mdline{4301} +(trTCM) defined in RFC 2698\mdline{4302}~[\mdcite{rfc2698}{3}]\mdline{4302}. P4Runtime clients may additionally +restrict meter usage on a table to RFC 2697\mdline{4303}'\mdline{4303}s\mdline{4303}~[\mdcite{rfc2697}{2}]\mdline{4303} \mdline{4303}\emph{Single Rate Three +Color Marker}\mdline{4304} (srTCM) or a simplified version of it that we call \mdline{4304}\emph{Single Rate +Two Color Marker}\mdline{4305}. The type of a table\mdline{4305}'\mdline{4305}s meter is set by the \mdline{4305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Type}}}\mdline{4305} as +described in the\mdline{4306}~\mdref{sec-meter-directmeter}{Meter \& DirectMeter section}\mdline{4306}.%mdk + +%mdk-data-line={4308} +\mdline{4308}The trTCM meters an arbitrary packet stream using two configured rates\mdline{4308} \mdline{4308}\textemdash{}\mdline{4308} +the Peak Information Rate (PIR) and Committed Information Rate (CIR), and their +associated burst sizes\mdline{4310} \mdline{4310}\textemdash{}\mdline{4310} and \mdline{4310}\textquotedblleft{}marks\textquotedblright{}\mdline{4310} its packets as GREEN, YELLOW or RED based +on the observed rate.%mdk + +%mdk-data-line={4313} +\mdline{4313}The srTCM meters an arbitrary packet stream using a single configured rate\mdline{4313} \mdline{4313}\textemdash{}\mdline{4313} +the Committed Information Rate (CIR) and its associated burst size\mdline{4314} \mdline{4314}\textemdash{}\mdline{4314} as well +as the Excess Burst Size (EBS) and \mdline{4315}\textquotedblleft{}marks\textquotedblright{}\mdline{4315} its packets as GREEN, YELLOW or RED +based on the observed rate.%mdk + +%mdk-data-line={4318} +\mdline{4318}The \mdline{4318}\emph{Single Rate Two Color Marker}\mdline{4318} meters an arbitary packet stream using a +single configured rate\mdline{4319} \mdline{4319}\textemdash{}\mdline{4319} the Committed Information Rate (CIR) and its +associated burst size\mdline{4320} \mdline{4320}\textemdash{}\mdline{4320} and \mdline{4320}\textquotedblleft{}marks\textquotedblright{}\mdline{4320} its packets as GREEN or RED based on the +observed rate.%mdk + +%mdk-data-line={4323} +\mdline{4323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4323} \mdline{4323}\&\mdline{4323} \mdline{4323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4323} have an additional field \mdline{4323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4323} that +may hold per color counter data for targets that support it, and that must +always be unset for targets that do not support it. If set in a request and +unsupported by a target, an \mdline{4326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4326} error code should be returned. +These counters provide a granular list of the counters applicable to the +possible meter colors GREEN, YELLOW and RED. The counter associated with a +specific color is incremented when a packet is \mdline{4329}\textquotedblleft{}marked\textquotedblright{}\mdline{4329} with that color. The +primary purpose of the color counters is for debugging purposes.%mdk + +%mdk-data-line={4332} +\mdline{4332}A meter may be configured as a direct or indirect instance, similar to a +counter. The \mdline{4333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{4333} P4Runtime message represents meter configuration.%mdk + +%mdk-data-line={4335} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4336} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterConfig~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~cir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~Committed~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~cburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};~~{\mdcolor{darkgreen}//~Committed~Burst~Size}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};~~{\mdcolor{darkgreen}//~Peak~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};~~{\mdcolor{darkgreen}//~Peak~Burst~Size}\\ +~~{\bfseries{\mdcolor{navy}int64}}~eburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};~{\mdcolor{darkgreen}//~Excess~burst~size~(only~used~for~srTCM)}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4345} +\noindent\mdline{4345}A MeterConfig for a trTCM typed meter must only be accepted if \mdline{4345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}eburst}}}\mdline{4345} is +unset. Otherwise, the server should return an \mdline{4346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4346} error.%mdk + +%mdk-data-line={4348} +\mdline{4348}A MeterConfig for a srTCM typed meter must only be accepted if \mdline{4348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}pir}}}\mdline{4348} and +\mdline{4349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}pburst}}}\mdline{4349} are equal to \mdline{4349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cir}}}\mdline{4349} and \mdline{4349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cburst}}}\mdline{4349} respectively. Otherwise, the server +should return an \mdline{4350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4350} error.%mdk + +%mdk-data-line={4352} +\mdline{4352}A MeterConfig for a \mdline{4352}\emph{Single Rate Two Color Marker}\mdline{4352} typed meter must only be +accepted if \mdline{4353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}pir}}}\mdline{4353} and \mdline{4353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}pburst}}}\mdline{4353} are equal to \mdline{4353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cir}}}\mdline{4353} and \mdline{4353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cburst}}}\mdline{4353} respectively and +\mdline{4354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}eburst}}}\mdline{4354} is unset. Otherwise, the server should return an \mdline{4354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4354} +error.%mdk + +%mdk-data-line={4357} +\mdline{4357}Note: Any acceptable MeterConfig for a \mdline{4357}\emph{Single Rate Two Color Marker}\mdline{4357} typed +meter is also acceptable for either of the other two meter types and will mark +packets identically in all three cases. Thus, changing the meter type from +\mdline{4360}\emph{Single Rate Two Color Marker}\mdline{4360} to \mdline{4360}\emph{Single Rate Three Color Marker}\mdline{4360} or +\mdline{4361}\emph{Two Rate Three Color Marker}\mdline{4361} is a non-breaking change.%mdk + +%mdk-data-line={4363} +\subsubsection{\mdline{4363}9.4.1.\hspace*{0.5em}\mdline{4363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-directmeterentry}%mdk%mdk + +%mdk-data-line={4365} +\noindent\mdline{4365}A direct meter is a direct resource associated with a \mdline{4365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4365} (see\mdline{4365}~\mdref{sec-direct-resources}{Direct +resources}\mdline{4366}). The \mdline{4366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{4366} field of the \mdline{4366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4366} +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +\mdline{4370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4370} message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed.%mdk + +%mdk-data-line={4373} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4374} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectMeterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterCounterData~counter\_data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4381} +\noindent\mdline{4381}A \mdline{4381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4381} may only include an \mdline{4381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4381} message of type \mdline{4381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4381} with a +\mdline{4382}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4382}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={4384} +\begin{itemize}%mdk + +%mdk-data-line={4384} +\item{} +%mdk-data-line={4384} +\mdline{4384}the \mdline{4384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4384} field must match the match key of the \mdline{4384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4384} +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching \mdline{4386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4386} is not found, +the server returns the error code \mdline{4387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4387}.%mdk%mdk + +%mdk-data-line={4389} +\item{} +%mdk-data-line={4389} +\mdline{4389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4389} is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets).%mdk%mdk + +%mdk-data-line={4393} +\item{} +%mdk-data-line={4393} +\mdline{4393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4393} is used to set the per color counter values to the default +value of (0), which is essentially clearing the counters. If the field is +unset, the counter values are left untouched. If the field is set, targets +supporting these counters should reset all the color counters to (0), if any +of the sub-fields are set to a non-zero value, then an \mdline{4397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4397} +error should be returned.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4400} +\noindent\mdline{4400}Specifying \mdline{4400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4400} in an \mdline{4400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4400} message of type \mdline{4400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4400} or +\mdline{4401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4401} is not allowed, and the server must return the error code +\mdline{4402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4402} in that case.%mdk + +%mdk-data-line={4404} +\mdline{4404}A client may use \mdline{4404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4404} in two ways to read a \mdline{4404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{4404} config.%mdk + +%mdk-data-line={4406} +\begin{itemize}%mdk + +%mdk-data-line={4406} +\item{} +%mdk-data-line={4406} +\mdline{4406}As a direct resource associated with a table entry, request the server to +return the meter config in the \mdline{4407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{4407} field of the \mdline{4407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4407} +message (see\mdline{4408}~\mdref{sec-direct-resources}{Direct resources}\mdline{4408}).%mdk%mdk + +%mdk-data-line={4410} +\item{} +%mdk-data-line={4410} +\mdline{4410}Explicitly request the meter configuration by including the \mdline{4410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4410} +in the \mdline{4411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4411}. The \mdline{4411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4411} field must match the +\mdline{4412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4412} whose meter config is being read. If no such entry is found, the +server returns the error code \mdline{4413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4413}. Read responses also include the +per color counter data for the meter entry, if supported and specified in +the request message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4417} +\subsubsection{\mdline{4417}9.4.2.\hspace*{0.5em}\mdline{4417}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}\label{sec-meterentry}%mdk%mdk + +%mdk-data-line={4419} +\noindent\mdline{4419}An indirect or indexed meter is not associated with a specific \mdline{4419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4419} and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime \mdline{4421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4421} message whose fields are defined as +follows:%mdk + +%mdk-data-line={4424} +\begin{itemize}%mdk + +%mdk-data-line={4424} +\item{} +%mdk-data-line={4424} +\mdline{4424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4424} is a \mdline{4424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4424}, the unique identifier for the meter.%mdk%mdk + +%mdk-data-line={4426} +\item{} +%mdk-data-line={4426} +\mdline{4426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4426} is a Protobuf message that encapsulates an \mdline{4426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4426}, used to index into +a meter array.%mdk%mdk + +%mdk-data-line={4429} +\item{} +%mdk-data-line={4429} +\mdline{4429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4429} is a Protobuf message of type \mdline{4429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{4429}, which represents the +meter configuration.%mdk%mdk + +%mdk-data-line={4432} +\item{} +%mdk-data-line={4432} +\mdline{4432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4432} is a Protobuf message of type \mdline{4432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4432}, which +represents the per color counter values associated with the corresponding +meter.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4436} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4437} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~meter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~MeterCounterData~counter\_data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4445} +\noindent\mdline{4445}The \mdline{4445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4445} can only be used in a \mdline{4445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4445} with the \mdline{4445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4445} update +type. The P4Runtime server must return an \mdline{4446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4446} error code for +update types \mdline{4447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4447} and \mdline{4447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4447}. By default all the meter entries in the +array have a default configuration (GREEN for all packets).%mdk + +%mdk-data-line={4450} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4450} +\item\mdline{4450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4450}: Server returns the error code \mdline{4450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4450}.%mdk + +%mdk-data-line={4451} +\item\mdline{4451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4451}: Modify an indirect meter instance whose unique id is \mdline{4451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4451} and +array index is specified by \mdline{4452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4452}. The meter is reconfigured using the +\mdline{4453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4453} field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the \mdline{4455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4455} field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if \mdline{4457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4457} is unset). The server must return \mdline{4457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4457} for a +negative index value and \mdline{4458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4458} if the index value exceeds the size of +the meter array.%mdk + +%mdk-data-line={4460} +\item\mdline{4460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4460}: Server returns the error code \mdline{4460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4460}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4462} +\noindent\mdline{4462}A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4463} by including a \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4463} entity for each +of the instances, specifying the \mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4464} and \mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4464}. Wildcard reads are also +supported as follows:%mdk + +%mdk-data-line={4467} +\begin{itemize}%mdk + +%mdk-data-line={4467} +\item{} +%mdk-data-line={4467} +\mdline{4467}If the \mdline{4467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4467} field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the \mdline{4468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4468}.%mdk%mdk + +%mdk-data-line={4470} +\item{} +%mdk-data-line={4470} +\mdline{4470}Otherwise, if the \mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4470} field is not set, the server returns the +configuration for all indirect meters in the array identified by the unique id +\mdline{4472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4472}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4474} +\subsubsection{\mdline{4474}9.4.3.\hspace*{0.5em}\mdline{4474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}}\label{sec-metercounterdata}%mdk%mdk + +%mdk-data-line={4476} +\noindent\mdline{4476}The \mdline{4476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4476} P4Runtime message represents the per color counters +associated with a meter entry. Whenever a meter is executed and returns +a color, the corresponding color counter GREEN, YELLOW or RED is updated.%mdk + +%mdk-data-line={4480} +\mdline{4480}As seen above, these counters can be associated with a \mdline{4480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4480} or +\mdline{4481}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4481}. Targets not capable of supporting these counters should return +\mdline{4482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4482} if a \mdline{4482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4482} field was set in a read or write +request.%mdk + +%mdk-data-line={4485} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4486} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterCounterData~\{\\ +~~CounterData~green~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~yellow~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~red~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4494} +\subsection{\mdline{4494}9.5.\hspace*{0.5em}\mdline{4494}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}\label{sec-packetreplicationengineentry}%mdk%mdk + +%mdk-data-line={4496} +\noindent\mdline{4496}The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets.%mdk + +%mdk-data-line={4502} +\subsubsection{\mdline{4502}9.5.1.\hspace*{0.5em}\mdline{4502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}\label{sec-multicastgroupentry}%mdk%mdk + +%mdk-data-line={4504} +\noindent\mdline{4504}Multicasting is achieved in PSA programs by setting the \mdline{4504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4504} +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the \mdline{4507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4507} API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example.%mdk + +%mdk-data-line={4512} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4513} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~arp\_multicast({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ethernet.isValid()~\&\&\\ +~~~~~~~~hdr.ethernet.eth\_type~==~ETH\_TYPE\_ARP)~\{\\ +~~~~~~smeta.multicast\_group~=~(MulticastGroup\_t)~{\mdcolor{purple}1};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4523} +\noindent\mdline{4523}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4526} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4527} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~multicast\_group\_entry~\{\\ +~~~~~~multicast\_group\_id:~{\mdcolor{purple}1}\\ +~~~~~~replicas~\{~port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x05}{\mdcolor{maroon}"}~instance:~{\mdcolor{purple}1}~\}\\ +~~~~~~replicas~\{~port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x0c}{\mdcolor{maroon}"}~instance:~{\mdcolor{purple}2}~\}\\ +~~~~~~replicas~\{~port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x12}{\mdcolor{maroon}"}~instance:~{\mdcolor{purple}3}~\}\\ +~~~~~~replicas~\{~port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x18}{\mdcolor{maroon}"}~instance:~{\mdcolor{purple}4}~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4541} +\noindent\mdline{4541}As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +\mdline{4546}\mdref{sec-translation-of-port-numbers}{PSA Metadata Translation}\mdline{4546} section.%mdk + +%mdk-data-line={4548} +\mdline{4548}The egress packets may be distinguished for further processing in the egress +using the \mdline{4549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4549} metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 \mdline{4551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4551} metadata is set to a value that is not +programmed in the PRE, then the packet is dropped.%mdk + +%mdk-data-line={4554} +\mdline{4554}A multicast group may be inserted, modified or deleted as per the following +semantics.%mdk + +%mdk-data-line={4557} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4557} +\item\mdline{4557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4557}: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The \mdline{4558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4558} field is a \mdline{4558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4558} and must be greater +than 0 (see explanation\mdline{4559}~\mdref{sec-valid-values-for-mg-id}{below}\mdline{4559}), or the +P4Runtime server must return an \mdline{4560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4560} error. The replica +\mdline{4561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4561} ID is also a \mdline{4561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4561}, and its value may not exceed the maximum +allowed by the target for the \mdline{4562}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4562} type (0 is allowed), or the +server must return an \mdline{4563}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4563} error. The egress port (\mdline{4563}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{4563} field) +must be an SDN port and must refer to a singleton port. No two replicas may +have identical values of \mdline{4565}\emph{both}\mdline{4565} \mdline{4565}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{4565} and \mdline{4565}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4565}, or the server must +return \mdline{4566}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4566}. The \mdline{4566}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{4566} field is an arbitrary \mdline{4566}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{4566} value +which is opaque to the target. There is no requirement of where this is +stored, but it must be returned by the server along with the rest of the entry +when the client performs a read on the entry.%mdk + +%mdk-data-line={4570} +\item\mdline{4570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4570}: Modify the set of replicas and metadata for a given multicast group +entry, indexed by the given \mdline{4571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4571}. Same restrictions as +\mdline{4572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4572} apply here.%mdk + +%mdk-data-line={4573} +\item\mdline{4573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4573}: Delete the multicast group indexed by the given +\mdline{4574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4574}. The \mdline{4574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}replicas}}}\mdline{4574} and \mdline{4574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{4574} fields need not be +provided for this operation. Any packets with their \mdline{4575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4575} +metadata in the data plane set to the deleted \mdline{4576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4576} will be +dropped.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4579} +\noindent\mdline{4579}When reading a multicast group, only \mdline{4579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4579} is considered. All +other fields in \mdline{4580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4580} are ignored. To perform a \mdline{4580}\emph{wildcard}\mdline{4580} +\mdline{4581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4581} on all configured multicast group entries, the \mdline{4581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4581} field +must be set to 0, its default value.%mdk + +%mdk-data-line={4584} +\paragraph{\mdline{4584}9.5.1.1.\hspace*{0.5em}\mdline{4584}Valid Values for \mdline{4584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}}\label{sec-valid-values-for-mg-id}%mdk%mdk + +%mdk-data-line={4586} +\noindent\mdline{4586}The PSA specification states that the valid \mdline{4586}\emph{data plane}\mdline{4586} values for multicast +group ids (\mdline{4587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroup\_t}}}\mdline{4587}) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target\mdline{4589}~[\mdcite{psatranslation}{29}]\mdline{4589}. This means that, in the absence of +translation, the client must set the \mdline{4590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4590} field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special \mdline{4592}\emph{wildcard}\mdline{4592} value which is used to read all the multicast groups +configured in the target, the \mdline{4593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4593} field must never be set to 0 +when performing a \mdline{4594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4594} RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value.%mdk + +%mdk-data-line={4599} +\subsubsection{\mdline{4599}9.5.2.\hspace*{0.5em}\mdline{4599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}\label{sec-clonesessionentry}%mdk%mdk + +%mdk-data-line={4601} +\noindent\mdline{4601}PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +\mdline{4605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4605} identifier and a boolean flag \mdline{4605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone}}}\mdline{4605} in the packet +metadata. The \mdline{4606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4606} serves as a handle to the clone attributes, +namely a set \mdline{4607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}replicas}}}\mdline{4607} of \mdline{4607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(egress~port,~instance)}}}\mdline{4607} pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +\mdline{4610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4610} API.%mdk + +%mdk-data-line={4612} +\mdline{4612}The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the \mdline{4615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_low\_ttl}}}\mdline{4615} control block is applied in the ingress +pipeline to create an ingress-to-egress clone.%mdk + +%mdk-data-line={4618} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4619} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~clone\_low\_ttl({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ipv4.isValid()~\&\&\\ +~~~~~~~~hdr.ipv4.ttl~\textless{}=~LOW\_TTL\_THRESHOLD)~\{\\ +~~~~~~smeta.clone\_session\_id~=~{\mdcolor{purple}10}w100;\\ +~~~~~~smeta.clone~=~{\bfseries{\mdcolor{navy}true}};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4631} +\noindent\mdline{4631}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4634} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4635} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~clone\_session\_entry~\{\\ +~~~~~~session\_id:~{\mdcolor{purple}100}\\ +~~~~~~replicas~\{~port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}xff}{\mdcolor{gray}\textbackslash{}xff}{\mdcolor{gray}\textbackslash{}xff}{\mdcolor{gray}\textbackslash{}xfd}{\mdcolor{maroon}"}~instance:~{\mdcolor{purple}1}~\}~{\mdcolor{darkgreen}\#~to~CPU}\\ +~~~~~~class\_of\_service:~{\mdcolor{purple}2}\\ +~~~~~~packet\_length\_bytes:~{\mdcolor{purple}4096}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4648} +\noindent\mdline{4648}As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type \mdline{4652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4652}~[\mdcite{psatranslation}{29}]\mdline{4652}). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes.%mdk + +%mdk-data-line={4657} +\mdline{4657}The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port \mdline{4658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfffffffd}}}\mdline{4658}; see +\mdline{4659}\mdref{sec-translation-of-port-numbers}{Translation of Port Numbers}\mdline{4659}). Note that the +egress port (\mdline{4660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{4660} field) must be an SDN port and must refer to a singleton +port.%mdk + +%mdk-data-line={4663} +\mdline{4663}If the \mdline{4663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4663} data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created.%mdk + +%mdk-data-line={4666} +\mdline{4666}A clone session may be inserted, modified or deleted as per the following +semantics:%mdk + +%mdk-data-line={4669} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4669} +\item\mdline{4669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4669}: Add a new clone session entry bound to a set of egress ports and +replica IDs. The \mdline{4670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4670} is a \mdline{4670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4670} and must be greater than 0 (see +explanation\mdline{4671}~\mdref{sec-valid-values-for-session-id}{below}\mdline{4671}), or the P4Runtime +server must return an \mdline{4672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4672} error. The replica \mdline{4672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4672} ID is +also a \mdline{4673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4673}, and its value may not exceed the maximum allowed by the +target for the \mdline{4674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4674} type (0 is allowed), or the server must also +return an \mdline{4675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4675} error. The egress port (\mdline{4675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{4675} field) in the +replica must be an SDN port and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (\mdline{4678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}class\_of\_service}}}\mdline{4678} field). This value must be a valid +value for the PSA \mdline{4679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ClassOfService\_t}}}\mdline{4679} type, which supports runtime translation +by default\mdline{4680}~[\mdcite{psatranslation}{29}]\mdline{4680}, or the server must return +\mdline{4681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4681}. See\mdline{4681}~\mdref{sec-translation-of-port-numbers}{PSA Metadata +Translation}\mdline{4682} for more information. The +\mdline{4683}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4683} field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +\mdline{4685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4685} field is 0 (default), no truncation on the clone will be +performed.%mdk + +%mdk-data-line={4687} +\item\mdline{4687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4687}: Modify the attributes of a given clone session entry, indexed by the +given \mdline{4688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4688}. Same restrictions as \mdline{4688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4688} apply here.%mdk + +%mdk-data-line={4689} +\item\mdline{4689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4689}: Delete the clone session indexed by the given +\mdline{4690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4690}. Other fields need not be provided for this operation. Any +packet with their \mdline{4691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4691} metadata in the data plane set to the +deleted \mdline{4692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4692} will no longer be cloned.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4694} +\noindent\mdline{4694}When reading a clone session, only \mdline{4694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4694} is considered. All other fields +in \mdline{4695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4695} are ignored. To perform a \mdline{4695}\emph{wildcard}\mdline{4695} \mdline{4695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4695} on all +configured clone session entries, the \mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4696} field must be set to 0, its +default value. The \mdline{4697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4697} field can never be equal to 0 in a \mdline{4697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4697} +RPC. If it does, the server must return an \mdline{4698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4698} error.%mdk + +%mdk-data-line={4700} +\paragraph{\mdline{4700}9.5.2.1.\hspace*{0.5em}\mdline{4700}Valid Values for \mdline{4700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}}\label{sec-valid-values-for-session-id}%mdk%mdk + +%mdk-data-line={4702} +\noindent\mdline{4702}The PSA specification states that the valid \mdline{4702}\emph{data plane}\mdline{4702} values for clone +session ids (\mdline{4703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4703}) range from 0 to the maximum value supported by +the target\mdline{4704}~[\mdcite{psatranslation}{29}]\mdline{4704}. Note that unlike for\mdline{4704}~\mdref{sec-valid-values-for-mg-id}{multicast group +ids}\mdline{4705}, 0 is a valid \mdline{4705}\emph{data plane}\mdline{4705} value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special \mdline{4707}\emph{wildcard}\mdline{4707} value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a \mdline{4708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4708} +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is \mdline{4710}\emph{not}\mdline{4710} enabled, we effectively +\mdline{4711}\textquotedblleft{}lose\textquotedblright{}\mdline{4711} one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (\mdline{4712}e.g.\mdline{4712} because the target supports a very +limited number of clone sessions), one can enable translation on +\mdline{4714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4714} and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id.%mdk + +%mdk-data-line={4717} +\subsection{\mdline{4717}9.6.\hspace*{0.5em}\mdline{4717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}\label{sec-valuesetentry}%mdk%mdk + +%mdk-data-line={4719} +\noindent\mdline{4719}Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the \mdline{4723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4723} state.%mdk + +%mdk-data-line={4725} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4726} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}state}}~parse\_l2~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}(MAX\_TRILL\_TYPES)~trill\_types;}\\ +~~extract(hdr.ethernet);\\ +~~{\bfseries{\mdcolor{navy}select}}~(hdr.ethernet.eth\_type)~\{\\ +~~~~ETH\_TYPE\_IPV4:~parse\_ipv4;\\ +~~~~ETH\_TYPE\_IPV6:~parse\_ipv6;\\ +~~~~trill\_types:~~~parse\_trill\_types;\\ +~~~~\_:~~~~~~~~~~~~~reject;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4738} +\noindent\mdline{4738}The corresponding entry in the P4Info for this Value Set is:%mdk + +%mdk-data-line={4740} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4741} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}trill\_types}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~\textless{}MAX\_TRILL\_TYPES\textgreater{}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4755} +\noindent\mdline{4755}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4758} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4759} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x22f3}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x893b}~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4777} +\noindent\mdline{4777}As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the \mdline{4779}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4779} state.%mdk + +%mdk-data-line={4781} +\mdline{4781}A \mdline{4781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4781} entity update message has the following fields:%mdk + +%mdk-data-line={4783} +\begin{itemize}%mdk + +%mdk-data-line={4783} +\item{} +%mdk-data-line={4783} +\mdline{4783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4783} is the \mdline{4783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4783} identifier of the Value Set instance, as +defined in P4Info.%mdk%mdk + +%mdk-data-line={4786} +\item{} +%mdk-data-line={4786} +\mdline{4786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4786} is a repeated field of type \mdline{4786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4786}. When \mdline{4786}\textquotedblleft{}selecting\textquotedblright{}\mdline{4786} +against a Value Set, every member will be considered and if at least one +\mdline{4788}\textquotedblleft{}matches\textquotedblright{}\mdline{4788}, the corresponding parser transition will be taken. Each +\mdline{4789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4789} contains a repeated field of \mdline{4789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4789} messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a \mdline{4791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4791} if and only if +it matches all its \mdline{4792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4792} messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. \mdline{4794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4794} messages in a \mdline{4794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4794} follow +the\mdline{4795}~\mdref{sec-match-format}{same rules}\mdline{4795} as in a \mdline{4795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4795}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4797} +\noindent\mdline{4797}A \mdline{4797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4797} may only be modified. If the update type is \mdline{4797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4797} or +\mdline{4798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4798}, the server must return an \mdline{4798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4798} error. If the update type +is \mdline{4799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4799}, the server writes the members given in the repeated field to the +Value Set entry indexed by the given \mdline{4800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4800}. The maximum number of +matches must not exceed the maximum size given by the \mdline{4801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{4801} field in P4Info of +the Value Set, otherwise the server must return a \mdline{4802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4802} error. To +empty a Value Set (\mdline{4803}i.e.\mdline{4803} restore it to its initial state), the P4Runtime client +can perform a \mdline{4804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4804} update with an empty \mdline{4804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4804} repeated field.%mdk + +%mdk-data-line={4806} +\mdline{4806}To facilitate\mdline{4806}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{4806}, the server must +return an \mdline{4807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4807} error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set.%mdk + +%mdk-data-line={4813} +\mdline{4813}See Appendix\mdline{4813}~\mdref{sec-value-set-example}{A.3}\mdline{4813} for a more complex Value Set example.%mdk + +%mdk-data-line={4815} +\subsection{\mdline{4815}9.7.\hspace*{0.5em}\mdline{4815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}\label{sec-registerentry}%mdk%mdk + +%mdk-data-line={4817} +\noindent\mdline{4817}The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The \mdline{4818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4818} P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations.%mdk + +%mdk-data-line={4822} +\mdline{4822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4822} has the following fields:%mdk + +%mdk-data-line={4824} +\begin{itemize}%mdk + +%mdk-data-line={4824} +\item{} +%mdk-data-line={4824} +\mdline{4824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4824}, which identifies the PSA Register extern instance which is +being accessed by the client; the \mdline{4825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4825} is specified by the P4Info +message.%mdk%mdk + +%mdk-data-line={4828} +\item{} +%mdk-data-line={4828} +\mdline{4828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4828}, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the \mdline{4830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4830} message +used for the request. When an \mdline{4831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4831} is provided , the server must validate +its value, and return \mdline{4832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4832} for a negative index or +\mdline{4833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4833} if the index exceeds the size of the register array.%mdk%mdk + +%mdk-data-line={4835} +\item{} +%mdk-data-line={4835} +\mdline{4835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4835}: the data to be written to the array (if \mdline{4835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4835} is part of a +\mdline{4836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4836} message) or the data read from the array (if \mdline{4836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4836} is +part of a \mdline{4837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4837} message). The \mdline{4837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4837} field is a \mdline{4837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{4837} message and +must match the format described by the \mdline{4838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{4838} field of the corresponding +Register entry in the P4Info, or the server must return an \mdline{4839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4839} +error.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4842} +\subsection{\mdline{4842}9.8.\hspace*{0.5em}\mdline{4842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}\label{sec-digestentry}%mdk%mdk + +%mdk-data-line={4844} +\noindent\mdline{4844}A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly.%mdk + +%mdk-data-line={4849} +\mdline{4849}The \mdline{4849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4849} P4Runtime entity is used to \mdline{4849}\textbf{configure}\mdline{4849} how the device must +generate digest messages. The \mdline{4850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4850} Protobuf message is not used to +carry digest data, which is done on the \mdline{4851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4851} bidirectional stream +using the \mdline{4852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4852} (digest data sent by the target to the client) and +\mdline{4853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4853} (digest data acknowledgments sent by the client to the target) +Protobuf messages.%mdk + +%mdk-data-line={4856} +\mdline{4856}In this section, we refer to the data learned by a single data plane call to +\mdline{4857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}T\textgreater{}::pack}}}\mdline{4857} as a \mdline{4857}\textquotedblleft{}digest message\textquotedblright{}\mdline{4857} and we use \mdline{4857}\textquotedblleft{}digest list\textquotedblright{}\mdline{4857} to designate +the list of digest messages bundled by the P4Runtime service in a single +\mdline{4859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4859} stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are \mdline{4861}\textquotedblleft{}duplicate\textquotedblright{}\mdline{4861} if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are \mdline{4862}\textquotedblleft{}distinct\textquotedblright{}\mdline{4862} +if they are not duplicate.%mdk + +%mdk-data-line={4865} +\mdline{4865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4865} has the following fields:%mdk + +%mdk-data-line={4867} +\begin{itemize}%mdk + +%mdk-data-line={4867} +\item{} +%mdk-data-line={4867} +\mdline{4867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4867}, which identifies the PSA Digest extern instance which emitted the +data; the \mdline{4868}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4868} is determined by the P4Info message.%mdk%mdk + +%mdk-data-line={4870} +\item{} +%mdk-data-line={4870} +\mdline{4870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4870}, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +\mdline{4872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4872}; these parameters are:%mdk + +%mdk-data-line={4874} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4874} +\item\mdline{4874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4874}: the maximum server buffering delay in nanoseconds for an +outstanding digest message.%mdk + +%mdk-data-line={4876} +\item\mdline{4876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4876}: the maximum digest list size\mdline{4876} \mdline{4876}\textemdash{}\mdline{4876} in number of digest +messages\mdline{4877} \mdline{4877}\textemdash{}\mdline{4877} sent by the server to the client as a single \mdline{4877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4877} +Protobuf message.%mdk + +%mdk-data-line={4879} +\item\mdline{4879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4879}: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4883} +\noindent\mdline{4883}Here is the significance of the different \mdline{4883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4883} types for \mdline{4883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4883}:%mdk + +%mdk-data-line={4885} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4885} +\item\mdline{4885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4885}: Enable server generation of \mdline{4885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4885} messages for given digest +instance and use provided configuration parameters.%mdk + +%mdk-data-line={4887} +\item\mdline{4887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4887}: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance.%mdk + +%mdk-data-line={4889} +\item\mdline{4889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4889}: Disable server generation of \mdline{4889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4889} messages for given digest +instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4892} +\noindent\mdline{4892}A server should buffer digest messages until either:%mdk + +%mdk-data-line={4894} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4894} +\item\mdline{4894}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4894} time has passed since the first digest message was added to +the empty buffer, or%mdk + +%mdk-data-line={4896} +\item\mdline{4896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4896} \mdline{4896}\emph{distinct}\mdline{4896} digest messages have been received from the +data plane and added to the buffer%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4899} +\noindent\mdline{4899}At which point the server should, with best effort, generate a \mdline{4899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4899} +stream message with the buffer contents and send it to the primary client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software.%mdk + +%mdk-data-line={4905} +\mdline{4905}To avoid sending duplicate digest messages across different \mdline{4905}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4905} +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the primary client indicates that it has received the +digest list and acted on it. The server must keep a \mdline{4908}\textquotedblleft{}cache\textquotedblright{}\mdline{4908} containing the set +of all digest messages that have been sent, but not acknowledged yet by the +primary client, up-to \mdline{4910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4910} in the past. The server must delete all +cache entries for a given digest list when they are at least \mdline{4911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4911} +old or when a matching \mdline{4912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4912} message (\mdline{4912}i.e.\mdline{4912} with the same \mdline{4912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4912} +and \mdline{4913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}list\_id}}}\mdline{4913} fields as the \mdline{4913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4913} message) is received.%mdk + +%mdk-data-line={4915} +\mdline{4915}The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged \mdline{4920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4920} messages.%mdk + +%mdk-data-line={4922} +\mdline{4922}When \mdline{4922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4922} is set to 0 and / or \mdline{4922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4922} is set to 1, the +server should, with best effort, generate a \mdline{4923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4923} message for every +digest message generated by the data plane which is not already in the cache. If +\mdline{4925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4925} is set to 0, the cache must always be an empty set. If +\mdline{4926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4926} is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +\mdline{4928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4928} configuration parameter.%mdk + +%mdk-data-line={4930} +\mdline{4930}The P4Runtime server may empty the digest message cache in case of a client +status change.%mdk + +%mdk-data-line={4933} +\mdline{4933}Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server:%mdk + +%mdk-data-line={4936} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4937} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestStream~stream;\\ +DigestCache~cache;\\ +DigestBuffer~buffers;\\ +\\ +{\mdcolor{darkgreen}//~sends~digest~list~when~it~is~ready}\\ +send\_buffer(Id~digest\_id)~\{\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~stream.write(DigestList(buffer));\\ +~~cache.merge(buffer);~~{\mdcolor{darkgreen}//~updates~cache~with~new~digest~list}\\ +~~buffer.clear();\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~data~plane~digest~messages~from~device}\\ +handle\_dataplane\_digest(Digest~msg)~\{\\ +~~digest\_id~=~msg.digest\_id();\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~{\bfseries{\mdcolor{navy}if}}~(msg~in~cache~{\mdcolor{teal}OR}~msg~in~buffer)~{\bfseries{\mdcolor{navy}return}};\\ +~~buffer.enqueue(msg);\\ +~~{\bfseries{\mdcolor{navy}if}}~(buffer.length()~\textless{}~max\_list\_size(digest\_id))~{\bfseries{\mdcolor{navy}return}};\\ +~~send\_buffer(digest\_id);\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~ack~messages~received~on~the~stream}\\ +handle\_stream\_ack(DigestListAck~ack)~\{\\ +~~{\mdcolor{darkgreen}//~clear~all~cache~entries~matching~the~tuple~(digest\_id,~list\_id)}\\ +~~cache.erase(~(ack.digest\_id(),~ack.list\_id()~)\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~loop~to~enforce~timeouts}\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~now~=~now();\\ +~~{\mdcolor{darkgreen}//~check~for~buffers~that~need~to~be~sent}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~buffer)~in~buffers)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~buffer.first\_enq\_time()~\textgreater{}=~max\_timeout\_ns(digest\_id))\\ +~~~~~~send\_buffer(buffer\_id);\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~check~for~expired~entries~in~cache}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~list\_id,~sent\_time)~in~cache)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~sent\_time~\textgreater{}=~ack\_timeout\_ns(digest\_id))\\ +~~~~~~cache.erase(~(digest\_id,~list\_id)~);\\ +~~\}\\ +~~sleep({\mdcolor{teal}X});\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4982} +\subsection{\mdline{4982}9.9.\hspace*{0.5em}\mdline{4982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\label{sec-extern-entry}%mdk%mdk + +%mdk-data-line={4984} +\noindent\mdline{4984}This is used to support a P4 extern entity that is not part of PSA. It is +defined as:%mdk + +%mdk-data-line={4987} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4988} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ExternEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_type\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~google.protobuf.Any~entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4995} +\noindent\mdline{4995}Each \mdline{4995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4995} entity maps to an \mdline{4995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{4995} message in the +\mdline{4996}\mdref{sec-p4info-extern}{P4Info}\mdline{4996} and an \mdline{4996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4996} message within that +message. The \mdline{4997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{4997} field must be equal to the one in +\mdline{4998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4998}. The \mdline{4998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_id}}}\mdline{4998} field must be equal to the ID included in the +\mdline{4999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{4999} of the corresponding \mdline{4999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4999} message.%mdk + +%mdk-data-line={5001} +\mdline{5001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entry}}}\mdline{5001} itself is embedded as an \mdline{5001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5001} Protobuf message\mdline{5001}~[\mdcite{protoany}{37}]\mdline{5001} to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on\mdline{5005}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{5006} for more information.%mdk + +%mdk-data-line={5008} +\section{\mdline{5008}10.\hspace*{0.5em}\mdline{5008}Error Reporting Messages}\label{sec-error-reporting-messages}%mdk%mdk + +%mdk-data-line={5010} +\noindent\mdline{5010}P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case.%mdk + +%mdk-data-line={5014} +\mdline{5014}gRPC uses \mdline{5014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5014}~[\mdcite{grpcstatus}{38}]\mdline{5014} to represent the status returned by an +RPC. It has 3 attributes:%mdk + +%mdk-data-line={5017} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5018} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StatusCode~code\_;\\ +{\mdcolor{navy}grpc::}string~error\_message\_;\\ +{\mdcolor{navy}grpc::}string~binary\_error\_details\_;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5023} +\noindent\mdline{5023}The \mdline{5023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{5023} represents a canonical error\mdline{5023}~[\mdcite{grpcstatuscodes}{40}]\mdline{5023} and describes the +overall RPC status. The \mdline{5024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{5024} is a developer-facing error message, +which should be in English. The \mdline{5025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}binary\_error\_details\_}}}\mdline{5025} carries a serialized +\mdline{5026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{5026} message\mdline{5026}~[\mdcite{protostatus}{33}]\mdline{5026} message, which has 3 fields:%mdk + +%mdk-data-line={5028} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5029} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}int32}}~code~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~see~code.proto}\\ +{\bfseries{\mdcolor{navy}string}}~{\bfseries{\mdcolor{navy}message}}~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +{\bfseries{\mdcolor{navy}repeated}}~google.protobuf.Any~details~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5034} +\noindent\mdline{5034}The code and message fields must be the same as \mdline{5034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{5034} and \mdline{5034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{5034} +fields from \mdline{5035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5035} above. The \mdline{5035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5035} field is a list that consists of +\mdline{5036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5036} messages that carry error details for individual elements inside +batch-request RPCs (\mdline{5037}e.g.\mdline{5037} \mdline{5037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5037} and \mdline{5037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5037}). \mdline{5037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5037} includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices\mdline{5041}~[\mdcite{grpcstatuscodes}{40}]\mdline{5041}.%mdk + +%mdk-data-line={5043} +\mdline{5043}Figure\mdline{5043}~\mdref{fig-error-report}{\mdcaptionlabel{7}}\mdline{5043} illustrates how these messages fit together.%mdk + +%mdk-data-line={5045} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={5046} +\noindent\mdline{5046}\includegraphics[keepaspectratio=true,width=\dimwidth{0.70}]{build/error-report}{}\mdline{5046}%mdk + +%mdk-data-line={5047} +\mdhr{}%mdk + +%mdk-data-line={5048} +\noindent\mdline{5048}\mdcaption{\textbf{Figure~\mdcaptionlabel{7}.}~\mdcaptiontext{P4Runtime Error Report Message Format}}%mdk +%mdk +\end{mdcenter}\label{fig-error-report}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={5050} +\noindent\mdline{5050}gRPC provides utility functions \mdline{5050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExtractErrorDetails()}}}\mdline{5050} and \mdline{5050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetErrorDetails()}}}\mdline{5050} +\mdline{5051}[\mdcite{grpcerrordetails}{39}]\mdline{5051} to easily convert between \mdline{5051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5051} and +\mdline{5052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{5052}.%mdk + +%mdk-data-line={5054} +\mdline{5054}Please see sections on individual P4Runtime RPCs for details on how +\mdline{5055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5055} is populated for reporting errors.%mdk + +%mdk-data-line={5057} +\mdline{5057}Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on\mdline{5060}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{5061} for more information.%mdk + +%mdk-data-line={5063} +\section{\mdline{5063}11.\hspace*{0.5em}\mdline{5063}Atomicity of Individual \mdline{5063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5063} and \mdline{5063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5063} Operations}\label{sec-atomicity-of-individual-write-and-read-operations}%mdk%mdk + +%mdk-data-line={5065} +\noindent\mdline{5065}Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane \mdline{5066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{5066} +operation, and every single \mdline{5067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5067} operation on a table that inserts, deletes, +or modifies one table entry, the \mdline{5068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{5068} operation should behave as if that +\mdline{5069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5069} operation has not yet occurred, or as if the \mdline{5069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5069} operation is +complete. The P4 program should never behave as if the \mdline{5070}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5070} operation is +partially complete. These guarantees also apply to extern instances: \mdline{5071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5071} and +\mdline{5072}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5072} operations on extern entities must execute atomically relative to extern +data plane methods.%mdk + +%mdk-data-line={5075} +\mdline{5075}The atomicity guarantees provided by P4Runtime for individual \mdline{5075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5075} and \mdline{5075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5075} +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification\mdline{5077}~[\mdcite{psaatomicityofcontrolplaneops}{28}]\mdline{5077}.%mdk + +%mdk-data-line={5079} +\mdline{5079}The P4\mdline{5079}\mdsub{16}\mdline{5079} language introduces an \mdline{5079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{5079} annotation\mdline{5079}~[\mdcite{p4concurrency}{18}]\mdline{5079}, to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the \mdline{5081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{5081} annotation for \mdline{5081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5081} +operations, as well as\mdline{5082}~\mdref{sec-wildcard-reads}{non-wildcard \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} operations}\mdline{5082}, +relative to data plane execution. Consider the following P4 example written for +PSA:%mdk + +%mdk-data-line={5086} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5087} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024)~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\mdcolor{darkgreen}//~...}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~Value\_t~v~=~r1.read((Index\_t){\mdcolor{purple}1});\\ +~~~~~~~~v~=~v~+~{\mdcolor{purple}1};\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~v);\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5103} +\noindent\mdline{5103}If a P4Runtime server is processing messages which write to Register \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{5103} at +index \mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}1}}}\mdline{5104}, these writes must not happen between the data plane \mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}read}}}\mdline{5104} and +\mdline{5105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}write}}}\mdline{5105}.%mdk + +%mdk-data-line={5107} +\mdline{5107}Now let\mdline{5107}'\mdline{5107}s consider the following example:%mdk + +%mdk-data-line={5109} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5110} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024,~(Value\_t){\mdcolor{purple}0}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~initial~value~}{\mdcolor{darkgreen}*/})~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}100});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}100});\\ +~~~~\}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}200});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}200});\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5128} +\noindent\mdline{5128}If a P4Runtime client issues a \mdline{5128}\emph{wildcard}\mdline{5128} \mdline{5128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5128} on Register \mdline{5128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{5128}, there is no +guarantee that \mdline{5129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]~==~r1{}[2]}}}\mdline{5129} in the response, as the read for \mdline{5129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{5129} may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for \mdline{5131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{5131} may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read \mdline{5133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{5133} and \mdline{5133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{5133} separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +\mdline{5136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5136} message) of individual read requests. Similar to a batch +\mdline{5137}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5137}, a wildcard read of a register can execute the reads of the +register array elements (\mdline{5138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{5138}, \mdline{5138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{5138}, \mdline{5138}\dots{}\mdline{5138}) in an arbitrary order relative +to each other.%mdk + +%mdk-data-line={5141} +\mdline{5141}If the \mdline{5141}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{5141} annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program.%mdk + +%mdk-data-line={5145} +\section{\mdline{5145}12.\hspace*{0.5em}\mdline{5145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5145} RPC}\label{sec-write-rpc}%mdk%mdk + +%mdk-data-line={5147} +\noindent\mdline{5147}The \mdline{5147}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5147} RPC updates one or more P4 entities on the target. The request is +defined as follows:%mdk + +%mdk-data-line={5150} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5151} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~WriteRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Update~updates~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\bfseries{\mdcolor{navy}enum}}~Atomicity~\{\\ +~~~~CONTINUE\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~ROLLBACK\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~DATAPLANE\_ATOMIC~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~\}\\ +~~Atomicity~atomicity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5165} +\noindent\mdline{5165}The \mdline{5165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5165} uniquely identifies the target P4 device. The \mdline{5165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5165} and +\mdline{5166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5166} define the client role and election-id as described in the +\mdline{5167}\mdref{sec-client-arbitration-and-controller-replication}{Primary-Backup Arbitration and Controller +Replication}\mdline{5168} +section. The server is expected to perform the following checks (in this order) +before processing the \mdline{5170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}updates}}}\mdline{5170} list:%mdk + +%mdk-data-line={5172} +\begin{enumerate}%mdk + +%mdk-data-line={5172} +\item{} +%mdk-data-line={5172} +\mdline{5172}If \mdline{5172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5172} does not match any of the devices known to the P4Runtime +server or if \mdline{5173}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5173} does not match any of the roles for the device, the +server must return a \mdline{5174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5174} error.%mdk%mdk + +%mdk-data-line={5176} +\item{} +%mdk-data-line={5176} +\mdline{5176}If the client is not the primary for (\mdline{5176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5176}, \mdline{5176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5176}) according to +the \mdline{5177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5177} value, the server must return a \mdline{5177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5177} error.%mdk%mdk + +%mdk-data-line={5179} +\item{} +%mdk-data-line={5179} +\mdline{5179}If the \mdline{5179}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5179} is attempted before a \mdline{5179}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5179} has been set, +the server must return a \mdline{5180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{5180} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5182} +\noindent\mdline{5182}The updates field is a list of P4 entity updates to be applied. Each update is +defined as:%mdk + +%mdk-data-line={5185} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5186} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Update~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Type~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~INSERT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~MODIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DELETE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~Type~type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Entity~entity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5198} +\noindent\mdline{5198}This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a \mdline{5199}\emph{logical}\mdline{5199} table (\mdline{5199}e.g.\mdline{5199} +\mdline{5200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{5200}) or an actual table (\mdline{5200}e.g.\mdline{5200} \mdline{5200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5200}) in the P4 data +plane. Each entity in the container is uniquely identified by its \mdline{5201}\emph{key}\mdline{5201}. Please +refer to the\mdline{5202}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{5202} section for details on +what parts of the entity specification make up the \mdline{5203}\emph{key}\mdline{5203} for each P4 entity.%mdk + +%mdk-data-line={5205} +\mdline{5205}An update can be one of the following types:%mdk + +%mdk-data-line={5207} +\begin{itemize}%mdk + +%mdk-data-line={5207} +\item{} +%mdk-data-line={5207} +\mdline{5207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{5207}: Inserts the given P4 entity in the entity container. +The \mdline{5208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5208} field always specifies the full state of the P4 entity. +If the entity already exists, an \mdline{5209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{5209} error is returned, and +the existing entity remains unchanged. If the entity is malformed, an +\mdline{5211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5211} error is usually returned (unless a more specific error +code applies\mdline{5212}~[\mdcite{grpcstatuscodes}{40}]\mdline{5212}). If the entity cannot be inserted because the +container is already full, a \mdline{5213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{5213} error is returned.%mdk%mdk + +%mdk-data-line={5215} +\item{} +%mdk-data-line={5215} +\mdline{5215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{5215}: Modifies the P4 entity to its new specified state. This uses +\mdline{5216}\emph{assign}\mdline{5216} or \mdline{5216}\emph{full-snapshot}\mdline{5216} semantics, \mdline{5216}i.e.\mdline{5216} the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an \mdline{5218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5218} error is usually returned (unless a +more specific error code applies\mdline{5219}~[\mdcite{grpcstatuscodes}{40}]\mdline{5219}). If the entity does not +exist, a \mdline{5220}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5220} error is returned.%mdk%mdk + +%mdk-data-line={5222} +\item{} +%mdk-data-line={5222} +\mdline{5222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{5222}: Deletes the specified P4 entity. If the entity does not exist, a +\mdline{5223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5223} error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5226} +\noindent\mdline{5226}If an update is not allowed under the given controller role, the server must +return a \mdline{5227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5227} error for this update.%mdk + +%mdk-data-line={5229} +\subsection{\mdline{5229}12.1.\hspace*{0.5em}\mdline{5229}Batching and Ordering of Updates}\label{sec-batching-and-ordering-of-updates}%mdk%mdk + +%mdk-data-line={5231} +\noindent\mdline{5231}P4Runtime supports batching of \mdline{5231}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5231} operations. The list of updates in a +\mdline{5232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5232} is referred to as a \mdline{5232}\emph{batch}\mdline{5232}. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of \mdline{5234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5234} entities).%mdk + +%mdk-data-line={5236} +\mdline{5236}The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +\mdline{5238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5238}s can also be processed interleaved and/or in parallel. +However, \mdline{5239}\textbf{the processing of requests must be strictly serializable}\mdline{5239}. That +is, given a history \mdline{5240}$S$\mdline{5240} of \mdline{5240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5240}s including the responses to those +requests, there must exist an order \mdline{5241}$L$\mdline{5241} for all updates in \mdline{5241}$S$\mdline{5241}, such that:%mdk + +%mdk-data-line={5243} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5243} +\item\mdline{5243}All updates from the same write request must appear as a contiguous +subsequence in \mdline{5244}$L$\mdline{5244}, but the order within that subsequence can be arbitrary.%mdk + +%mdk-data-line={5245} +\item\mdline{5245}For two updates \mdline{5245}$u_1$\mdline{5245} and \mdline{5245}$u_2$\mdline{5245}, if the write request containing \mdline{5245}$u_1$\mdline{5245} +completed before the write request of \mdline{5246}$u_2$\mdline{5246} was sent, then \mdline{5246}$u_1$\mdline{5246} must appear +before \mdline{5247}$u_2$\mdline{5247} in \mdline{5247}$L$\mdline{5247}.%mdk + +%mdk-data-line={5248} +\item\mdline{5248}Executing all updates in \mdline{5248}$L$\mdline{5248} sequentially must yield the same response for +every update as in \mdline{5249}$S$\mdline{5249}.%mdk + +%mdk-data-line={5250} +\item\mdline{5250}The observable state of the switch after \mdline{5250}$S$\mdline{5250} (\mdline{5250}e.g.\mdline{5250}, through the \mdline{5250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5250} RPC) +is identical to the one obtained by sequentially executing \mdline{5251}$L$\mdline{5251}.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5253} +\noindent\mdline{5253}The \mdline{5253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5253} RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the \mdline{5254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5254} RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (\mdline{5257}e.g.\mdline{5257} inserting an \mdline{5257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{5257} +followed by pointing a \mdline{5258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5258} to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding \mdline{5260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5260} RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate \mdline{5264}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5264} calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each \mdline{5265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5265} call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one.%mdk + +%mdk-data-line={5270} +\subsection{\mdline{5270}12.2.\hspace*{0.5em}\mdline{5270}Batch Atomicity}\label{sec-batch-atomicity}%mdk%mdk + +%mdk-data-line={5272} +\noindent\mdline{5272}A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the \mdline{5273}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{5273} +enum. A P4Runtime server is required to support only the modes marked as +\mdline{5275}\emph{Required}\mdline{5275} below:%mdk + +%mdk-data-line={5277} +\begin{itemize}%mdk + +%mdk-data-line={5277} +\item{} +%mdk-data-line={5277} +\mdline{5277}\emph{Required}\mdline{5277}: \mdline{5277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{5277}: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that \mdline{5281}\emph{see}\mdline{5281} each of +these intermediate stages.%mdk%mdk + +%mdk-data-line={5284} +\item{} +%mdk-data-line={5284} +\mdline{5284}\emph{Optional}\mdline{5284}: \mdline{5284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ROLLBACK\_ON\_ERROR}}}\mdline{5284}: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is \mdline{5288}\emph{all-or-none}\mdline{5288}, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that \mdline{5292}\emph{see}\mdline{5292} each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure.%mdk + +%mdk-data-line={5297} +\mdline{5297}If a P4Runtime server does not support this option at all, an +\mdline{5298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5298} error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (\mdline{5299}e.g.\mdline{5299} it is +more straightforward to implement batches that contain only \mdline{5300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{5300} +operations, vs. those that contain \mdline{5301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{5301} operations), an +\mdline{5302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5302} error is returned when the batch cannot be executed +in a data plane-atomic way.%mdk%mdk + +%mdk-data-line={5305} +\item{} +%mdk-data-line={5305} +\mdline{5305}\emph{Optional}\mdline{5305}: \mdline{5305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{5305}: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +\mdline{5309}\emph{transaction}\mdline{5309}. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane\mdline{5311}'\mdline{5311}s table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table.%mdk + +%mdk-data-line={5318} +\mdline{5318}If a P4Runtime server does not support this option at all, an \mdline{5318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5318} +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an \mdline{5320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5320} error is returned when the batch +cannot be executed in a data plane-atomic way.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5323} +\noindent\mdline{5323}There is no expectation that a given client must always use the same \mdline{5323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{5323} +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use \mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{5326} at one time and default behavior +(\mdline{5327}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{5327}) at other times.%mdk + +%mdk-data-line={5329} +\subsection{\mdline{5329}12.3.\hspace*{0.5em}\mdline{5329}Error Reporting}\label{sec-error-reporting}%mdk%mdk + +%mdk-data-line={5331} +\noindent\mdline{5331}Please see section\mdline{5331}~\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{5331} for +information on error reporting messages and guidelines. P4Runtime server will +populate \mdline{5333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5333} as follows:%mdk + +%mdk-data-line={5335} +\begin{enumerate}%mdk + +%mdk-data-line={5335} +\item{} +%mdk-data-line={5335} +\mdline{5335}If all batch updates succeeded, set \mdline{5335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{5335} to \mdline{5335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{5335} and do not +populate any other field.%mdk%mdk + +%mdk-data-line={5338} +\item{} +%mdk-data-line={5338} +\mdline{5338}If an error is encountered before even trying to attempt individual batch +updates, set \mdline{5339}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{5339} that best describes that RPC-wide +error. For example, use \mdline{5340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNAVAILABLE}}}\mdline{5340} if the P4Runtime service is not yet +ready to handle requests. Set \mdline{5341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{5341} to describe the issue. Do not +set \mdline{5342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_details}}}\mdline{5342} in this case.%mdk%mdk + +%mdk-data-line={5344} +\item{} +%mdk-data-line={5344} +\mdline{5344}Otherwise, if one or more updates in the batch (\mdline{5344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest.updates}}}\mdline{5344}) +failed, set \mdline{5345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{5345} to \mdline{5345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{5345}. For example, one update in +the batch may fail with \mdline{5346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{5346} and another with +\mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5347}. A \mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5347} message is used to capture the status of +each and every update in the batch. The number of \mdline{5348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5348} messages packed +into \mdline{5349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{5349} field should therefore always match the +number of updates in the \mdline{5350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5350}, and the order of +\mdline{5351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5351} messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +\mdline{5353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5353} should set the code to \mdline{5353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{5353} and omit other fields.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5355} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5356} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}\#~Example~of~a~grpc::Status~returned~for~a~Write~RPC~with~a~batch~of~3~updates.}\\ +{\mdcolor{darkgreen}\#~The~first~and~third~updates~encountered~an~error,~while~the~second~update}\\ +{\mdcolor{darkgreen}\#~succeeded.}\\ +code\_~=~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +error\_message\_~=~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +binary\_error\_details~\{\\ +~~code:~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}8}~~{\mdcolor{darkgreen}\#~RESOURCE\_EXHAUSTED}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Table~is~full.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}500}~~{\mdcolor{darkgreen}\#~ERR\_TABLE\_FULL}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}0}~~{\mdcolor{darkgreen}\#~OK}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}6}~~{\mdcolor{darkgreen}\#~ALREADY\_EXISTS}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Entity~already~exists.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}600}~~{\mdcolor{darkgreen}\#~ERR\_ENTITY\_ALREADY\_EXISTS}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5382} +\section{\mdline{5382}13.\hspace*{0.5em}\mdline{5382}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5382} RPC}\label{sec-read-rpc}%mdk%mdk + +%mdk-data-line={5384} +\noindent\mdline{5384}The \mdline{5384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5384} RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as:%mdk + +%mdk-data-line={5387} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5388} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5395} +\noindent\mdline{5395}The \mdline{5395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5395} uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +\mdline{5397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5397} error. +If the \mdline{5398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5398} is attempted before \mdline{5398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5398} has been set, the +server must return a \mdline{5399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{5399} error. +The \mdline{5400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5400} field acts as a filter, restricting the reported entities based on +the role to which the entity belongs. +The \mdline{5402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{5402} repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server.%mdk + +%mdk-data-line={5405} +\mdline{5405}Since \mdline{5405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5405}s do not mutate any state on the switch, they do not +require an \mdline{5406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5406}, and they do not require the presence of an open +\mdline{5407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5407} between the server and client.%mdk + +%mdk-data-line={5409} +\mdline{5409}The \mdline{5409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read~}}}\mdline{5409}response consists of a sequence of messages (a gRPC \mdline{5409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}stream}}}\mdline{5409}) with +each message defined as:%mdk + +%mdk-data-line={5412} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5413} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadResponse~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5418} +\noindent\mdline{5418}The \mdline{5418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{5418} repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the \mdline{5422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Finish()}}}\mdline{5422} method on the stream object +\mdline{5423}[\mdcite{grpcstreamc}{12}]\mdline{5423}).%mdk + +%mdk-data-line={5425} +\subsection{\mdline{5425}13.1.\hspace*{0.5em}\mdline{5425}Nomenclature}\label{sec-nomenclature}%mdk%mdk + +%mdk-data-line={5427} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries request}}%mdk + +%mdk-data-line={5427} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{5427}An element of the \mdline{5427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{5427} repeated field. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries batch}}%mdk + +%mdk-data-line={5429} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{5429}Refers to the \mdline{5429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{5429} repeated field.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={5432} +\noindent\mdline{5432}Each \mdline{5432}\emph{request}\mdline{5432} acts as a query filter for that entity type. If a \mdline{5432}\emph{request}\mdline{5432} fully +specifies the entity key, the \mdline{5433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5433} operation should retrieve a single P4 +entity. Please refer to the\mdline{5434}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{5434} section +for details on what parts of the entity specification make up the entity \mdline{5435}\emph{key}\mdline{5435}.%mdk + +%mdk-data-line={5437} +\subsection{\mdline{5437}13.2.\hspace*{0.5em}\mdline{5437}Wildcard Reads}\label{sec-wildcard-reads}%mdk%mdk + +%mdk-data-line={5439} +\noindent\mdline{5439}P4Runtime allows wildcard read of P4 entities. A \mdline{5439}\emph{request}\mdline{5439} may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the\mdline{5441}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{5441} section for details on +what parts of the entity can be wildcarded in a given \mdline{5442}\emph{request}\mdline{5442}.%mdk + +%mdk-data-line={5444} +\mdline{5444}For example, in a \mdline{5444}\emph{request}\mdline{5444} of type \mdline{5444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{5444}:%mdk + +%mdk-data-line={5446} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5446} +\item\mdline{5446}A default \mdline{5446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{5446} (0) implies a request to read all counter-entries for +all indirect counters.%mdk + +%mdk-data-line={5448} +\item\mdline{5448}A particular (non-default) \mdline{5448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{5448} in conjunction with \mdline{5448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{5448} unset +implies a request to read all counter-entries for the given indirect counter +ID.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5452} +\noindent\mdline{5452}To read the entire forwarding state for a given device, the P4Runtime client can +generate the following \mdline{5453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5453}:%mdk + +%mdk-data-line={5455} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5456} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~\textless{}ID\textgreater{}\\ +entities~\{\\ +~~extern\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~extern~instances~for~all~supported~extern~types}\\ +~~table\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~table~entries~for~all~tables}\\ +~~action\_profile\_member~\{~\}~~{\mdcolor{darkgreen}\#~read~all~members~for~all~action~profiles}\\ +~~action\_profile\_group~\{~\}~~{\mdcolor{darkgreen}\#~read~all~groups~for~all~action~profiles}\\ +~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5466} +\noindent\mdline{5466}The \mdline{5466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5466} oneof field in the \mdline{5466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5466} message must always be set, or the +server must return an \mdline{5467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5467} error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty \mdline{5469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5469} message in the \mdline{5469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5469}. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the \mdline{5471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5471} oneof\mdline{5471}~[\mdcite{protooneofbackwardscompatibility}{25}]\mdline{5471}.%mdk + +%mdk-data-line={5473} +\subsection{\mdline{5473}13.3.\hspace*{0.5em}\mdline{5473}Batch Processing}\label{sec-batch-processing}%mdk%mdk + +%mdk-data-line={5475} +\noindent\mdline{5475}A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type \mdline{5476}\emph{request}\mdline{5476} +appears only once in the batch.%mdk + +%mdk-data-line={5479} +\mdline{5479}A P4Runtime server will process the batch as follows:%mdk + +%mdk-data-line={5481} +\begin{enumerate}%mdk + +%mdk-data-line={5481} +\item{} +%mdk-data-line={5481} +\mdline{5481}Lock state (preventing new writes) and validate each \mdline{5481}\emph{request}\mdline{5481} in the batch:%mdk + +%mdk-data-line={5483} +\begin{enumerate}%mdk + +%mdk-data-line={5483} +\item{} +%mdk-data-line={5483} +\mdline{5483}If it is a valid \mdline{5483}\emph{request}\mdline{5483}, perform the read;%mdk + +%mdk-data-line={5485} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5485} +\item\mdline{5485}If the read was successful, return the entities read in +\mdline{5486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5486} stream.%mdk + +%mdk-data-line={5487} +\item\mdline{5487}If the read failed (exception / critical-error), prepare a \mdline{5487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5487} +with code set to \mdline{5488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INTERNAL}}}\mdline{5488}.%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5490} +\item{} +%mdk-data-line={5490} +\mdline{5490}If the \mdline{5490}\emph{request}\mdline{5490} is invalid (invalid-argument, not-supported, etc.), +prepare a \mdline{5491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5491} with relevant canonical code to capture the error.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5493} +\item{} +%mdk-data-line={5493} +\mdline{5493}Unlock the state (allowing new writes);%mdk%mdk + +%mdk-data-line={5495} +\item{} +%mdk-data-line={5495} +\mdline{5495}Close the \mdline{5495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5495} stream and return a \mdline{5495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5495} as follows:%mdk + +%mdk-data-line={5497} +\begin{enumerate}%mdk + +%mdk-data-line={5497} +\item{} +%mdk-data-line={5497} +\mdline{5497}If no errors were encountered, set code to \mdline{5497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{5497} and do not populate any +other field.%mdk%mdk + +%mdk-data-line={5500} +\item{} +%mdk-data-line={5500} +\mdline{5500}Otherwise, the overall code should be set to \mdline{5500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{5500}. See section +\mdline{5501}\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{5501} for information +on error reporting messages and guidelines. Assemble a list of \mdline{5502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5502} +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +\mdline{5506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{5506} field. This behavior also matches \mdline{5506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5506} +RPC.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5509} +\subsubsection{\mdline{5509}13.3.1.\hspace*{0.5em}\mdline{5509}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={5511} +\noindent\mdline{5511}If a client asked to read \mdline{5511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{a,b,c,d\}}}}\mdline{5511} and \mdline{5511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}b}}}\mdline{5511} and \mdline{5511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}d}}}\mdline{5511} \mdline{5511}\emph{requests}\mdline{5511} didn\mdline{5511}'\mdline{5511}t +validate, the server will return entities corresponding to \mdline{5512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5512} and \mdline{5512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}c}}}\mdline{5512}, followed +by a status \mdline{5513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{p4.Error(OK),~p4.Error(xxx),~p4.Error(yyy),~p4.Error(OK)\}}}}\mdline{5513} in the +\mdline{5514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5514} field.%mdk + +%mdk-data-line={5516} +\mdline{5516}The P4Runtime server is not required to perform any optimization (\mdline{5516}e.g.\mdline{5516} merge two +\mdline{5517}\emph{requests}\mdline{5517} in the \mdline{5517}\emph{batch}\mdline{5517} if one is a subset of other). As a result of this, it +is possible for the \mdline{5518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5518} to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging.%mdk + +%mdk-data-line={5521} +\mdline{5521}There is no requirement that each request in the batch will correspond to one +\mdline{5522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5522} message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit.%mdk + +%mdk-data-line={5527} +\mdline{5527}A P4Runtime server must be prepared to handle multiple concurrent \mdline{5527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5527} RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (\mdline{5532}e.g.\mdline{5532} in a single-threaded architecture), it may choose to serialize +\mdline{5533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5533} RPC processing.%mdk + +%mdk-data-line={5535} +\subsection{\mdline{5535}13.4.\hspace*{0.5em}\mdline{5535}Parallelism of Read and Write Requests}\label{sec-parallelism-of-read-and-write-requests}%mdk%mdk + +%mdk-data-line={5537} +\noindent\mdline{5537}A P4Runtime server may be implemented to serve at most one +\mdline{5538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5538} or \mdline{5538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5538} message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so.%mdk + +%mdk-data-line={5543} +\mdline{5543}For example, imagine a client that wanted to use \mdline{5543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5543} +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +\mdline{5547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5547} messages with only a few updates to an \mdline{5547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{5547} +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +\mdline{5550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5550} batch currently being processed, but it will not +complete for a significant amount of time.%mdk + +%mdk-data-line={5553} +\mdline{5553}The restrictions on which a client may rely are:%mdk + +%mdk-data-line={5555} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5555} +\item\mdline{5555}The processing of any two \mdline{5555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5555} messages \mdline{5555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W1}}}\mdline{5555} and \mdline{5555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W2}}}\mdline{5555} must +result in the same state as if one of them was completed before the +other began.%mdk + +%mdk-data-line={5558} +\item\mdline{5558}For any \mdline{5558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5558} \mdline{5558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5558} and any \mdline{5558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5558} \mdline{5558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5558}, \mdline{5558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5558} must +return results consistent with a state where \mdline{5559}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5559} has completed +processing, or \mdline{5560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5560} has not yet begun processing.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5562} +\noindent\mdline{5562}For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a \mdline{5565}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5565} message it acquired a write lock for each stateful +object affected by the \mdline{5566}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5566}, and before starting the +processing of a \mdline{5567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5567} message it acquired a read lock for each +stateful object accessed by the \mdline{5568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5568}, such an implementation +meets all of the requirements above.%mdk + +%mdk-data-line={5571} +\mdline{5571}It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, \mdline{5573}e.g.\mdline{5573} if the server somehow determined that two +\mdline{5574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5574} messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly.%mdk + +%mdk-data-line={5580} +\section{\mdline{5580}14.\hspace*{0.5em}\mdline{5580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5580} RPC}\label{sec-setforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5582} +\noindent\mdline{5582}A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the \mdline{5583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig~RPC}}}\mdline{5583}. The request is defined as:%mdk + +%mdk-data-line={5585} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5586} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~SetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Action~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~VERIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~VERIFY\_AND\_SAVE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~VERIFY\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~~~COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~~~RECONCILE\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~Action~action~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5603} +\noindent\mdline{5603}The server is expected to perform the following checks (in this order) +before performing the required \mdline{5604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{5604}:%mdk + +%mdk-data-line={5606} +\begin{enumerate}%mdk + +%mdk-data-line={5606} +\item{} +%mdk-data-line={5606} +\mdline{5606}If \mdline{5606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5606} does not match any of the devices known to the P4Runtime +server or if \mdline{5607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5607} does not match any of the roles for the device, the +server must return a \mdline{5608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5608} error.%mdk%mdk + +%mdk-data-line={5610} +\item{} +%mdk-data-line={5610} +\mdline{5610}If the client is not the primary for (\mdline{5610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5610}, \mdline{5610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5610}) according to +the \mdline{5611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5611} value, the server must return a \mdline{5611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5611} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5613} +\noindent\mdline{5613}The action is the type of configuration action requested, it can be one of:%mdk + +%mdk-data-line={5615} +\begin{itemize}%mdk + +%mdk-data-line={5615} +\item{} +%mdk-data-line={5615} +\mdline{5615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY}}}\mdline{5615}: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an \mdline{5616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5616} +error if config is not provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5619} +\item{} +%mdk-data-line={5619} +\mdline{5619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5619}: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent \mdline{5621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5621} / \mdline{5621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5621} requests must refer to fields in the new +config. Returns an \mdline{5622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5622} error if the forwarding config is not +provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5625} +\item{} +%mdk-data-line={5625} +\mdline{5625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_COMMIT}}}\mdline{5625}: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an \mdline{5627}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5627} error if the forwarding config is not provided or if the +provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5630} +\item{} +%mdk-data-line={5630} +\mdline{5630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COMMIT}}}\mdline{5630}: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a \mdline{5633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5633} error if no saved config +is found, \mdline{5634}i.e.\mdline{5634} if no \mdline{5634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5634} action preceded this one. Returns an +\mdline{5635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5635} error if a config is provided with this message.%mdk%mdk + +%mdk-data-line={5637} +\item{} +%mdk-data-line={5637} +\mdline{5637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RECONCILE\_AND\_COMMIT}}}\mdline{5637}: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an \mdline{5643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5643} error. For targets that support this option, an +\mdline{5644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5644} error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5648} +\noindent\mdline{5648}The \mdline{5648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5648} field is a message of type \mdline{5648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5648} that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(\mdline{5650}e.g.\mdline{5650} generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the\mdline{5651}~\mdref{sec-p4-fwd-pipe-config}{Forwarding-Pipeline +Configuration}\mdline{5652} section for details.%mdk + +%mdk-data-line={5654} +\mdline{5654}A P4Runtime server running on a non-programmable device may not +support \mdline{5655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5655} (\mdline{5655}e.g.\mdline{5655} the forwarding-pipeline +config is part of the device\mdline{5656}'\mdline{5656}s software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +\mdline{5658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5658} error.%mdk + +%mdk-data-line={5660} +\section{\mdline{5660}15.\hspace*{0.5em}\mdline{5660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5660} RPC}\label{sec-getforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5662} +\noindent\mdline{5662}The forwarding-pipeline configuration of the target can be retrieved by invoking +the \mdline{5663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig~RPC}}}\mdline{5663}. The request is defined as:%mdk + +%mdk-data-line={5665} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5666} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~ResponseType~\{\\ +~~~~ALL~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~COOKIE\_ONLY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~P{\mdcolor{purple}4}INFO\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DEVICE\_CONFIG\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~ResponseType~response\_type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5678} +\noindent\mdline{5678}The \mdline{5678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5678} uniquely identifies the target P4 device. A \mdline{5678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5678} error is +returned if the \mdline{5679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5679} is not recognized by the P4Runtime server.%mdk + +%mdk-data-line={5681} +\mdline{5681}The \mdline{5681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5681} is used to specify which fields to populate in the response, +its value can be one of:%mdk + +%mdk-data-line={5684} +\begin{itemize}%mdk + +%mdk-data-line={5684} +\item{} +%mdk-data-line={5684} +\mdline{5684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5684}: returns a \mdline{5684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5684} with all fields +set as stored by the target. This is the default behaviour if the +\mdline{5686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5686} field is not set.%mdk%mdk + +%mdk-data-line={5688} +\item{} +%mdk-data-line={5688} +\mdline{5688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COOKIE\_ONLY}}}\mdline{5688}: reply by setting only the \mdline{5688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5688} field in the +\mdline{5689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5689}, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message.%mdk%mdk + +%mdk-data-line={5693} +\item{} +%mdk-data-line={5693} +\mdline{5693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4INFO\_AND\_COOKIE}}}\mdline{5693}: reply by setting the \mdline{5693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{5693} and \mdline{5693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5693} fields.%mdk%mdk + +%mdk-data-line={5695} +\item{} +%mdk-data-line={5695} +\mdline{5695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEVICE\_CONFIG\_AND\_COOKIE}}}\mdline{5695}: reply by setting the \mdline{5695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5695} and +\mdline{5696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5696} fields.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5698} +\noindent\mdline{5698}The response contains the \mdline{5698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5698} for the specified device:%mdk + +%mdk-data-line={5700} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5701} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigResponse~\{\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5706} +\noindent\mdline{5706}If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level \mdline{5707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5707} field will be unset in the response. Examples are +(i) a server that only allows configuration via \mdline{5708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5708} +but this RPC hasn\mdline{5709}'\mdline{5709}t been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn\mdline{5710}'\mdline{5710}t yet occurred.%mdk + +%mdk-data-line={5712} +\mdline{5712}Once a forwarding-pipeline config is installed on the device (either via +\mdline{5713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5713} or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +\mdline{5715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.p4\_device\_config}}}\mdline{5715} will be empty / unset in the response, even if +\mdline{5716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5716} in the request was set to \mdline{5716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5716}. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the \mdline{5718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5718} RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +\mdline{5720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5720}, the value of \mdline{5720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.cookie}}}\mdline{5720} will be unset.%mdk + +%mdk-data-line={5722} +\mdline{5722}If a P4Runtime server supports both \mdline{5722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5722} as well as +returning the \mdline{5723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5723}, there should be read-write symmetry between +\mdline{5724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5724} and \mdline{5724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5724} RPCs.%mdk + +%mdk-data-line={5726} +\section{\mdline{5726}16.\hspace*{0.5em}\mdline{5726}P4Runtime Stream Messages}\label{sec-p4runtime-stream-messages}%mdk%mdk + +%mdk-data-line={5728} +\subsection{\mdline{5728}16.1.\hspace*{0.5em}\mdline{5728}Packet I/O}\label{sec-packet-i_o}%mdk%mdk + +%mdk-data-line={5730} +\noindent\mdline{5730}P4Runtime supports controller packet-in and packet-out by means of \mdline{5730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5730} +and \mdline{5731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5731} stream messages, respectively.%mdk + +%mdk-data-line={5733} +\mdline{5733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5733} messages are sent by the P4Runtime server to the client. Conversely, +\mdline{5734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5734} messages are sent by the client to the server. Any \mdline{5734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5734} +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a \mdline{5737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5737} message with the \mdline{5737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5737} field set to +report the error to the client. See the section on\mdline{5738}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{5739} for more information on \mdline{5739}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5739}.%mdk + +%mdk-data-line={5741} +\mdline{5741}As introduced in the\mdline{5741}~\mdref{sec-controller-packet-meta}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\mdline{5741} +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with \mdline{5743}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5743}. The expected metadata is described +in the P4Info using the \mdline{5744}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5744} messages.%mdk + +%mdk-data-line={5746} +\mdline{5746}Both \mdline{5746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5746} and \mdline{5746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5746} stream messages share the same fields and are +defined as follows:%mdk + +%mdk-data-line={5749} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5750} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Packet~sent~from~the~controller~to~the~switch.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketOut~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~Packet~sent~from~the~switch~to~the~controller.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketIn~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~PacketMetadata~\{\\ +~~{\mdcolor{darkgreen}//~This~refers~to~Metadata.id~coming~from~P4Info~ControllerPacketMetadata.}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~metadata\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5769} +\begin{itemize}%mdk + +%mdk-data-line={5769} +\item{} +%mdk-data-line={5769} +\mdline{5769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}payload}}}\mdline{5769} is used to carry the full packet content, including the headers.%mdk%mdk + +%mdk-data-line={5771} +\item{} +%mdk-data-line={5771} +\mdline{5771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5771} is a repeated field of \mdline{5771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{5771} messages used to carry the +arbitrary controller metadata. When a P4Runtime client (or server) +generates a \mdline{5773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5773} (or \mdline{5773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5773}) message, it must populate precisely +one \mdline{5774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5774} field for each \mdline{5774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5774} field in the +\mdline{5775}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5775} for packet-out (or packet-in) in the P4Info, such +that the two \mdline{5776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata.id}}}\mdline{5776} fields match. +The size and value of each \mdline{5777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5777}/\mdline{5777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5777} metadata entry needs +to be consistent with what is specified in the corresponding P4Info +\mdline{5779}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.Metadata}}}\mdline{5779} message with the same \mdline{5779}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{5779}, in the +following sense:%mdk + +%mdk-data-line={5781} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5781} +\item\mdline{5781}If \mdline{5781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.Metadata.bitwidth}}}\mdline{5781} is set, or if +\mdline{5782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.Metadata.type\_name}}}\mdline{5782} is set and +\mdline{5783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec.translated\_type.sdn\_bitwidth}}}\mdline{5783} is set in the \mdline{5783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{5783} +for the type name, then \mdline{5784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata.value}}}\mdline{5784} must be a binary string of +the specified bit width conforming to the\mdline{5785}~\mdref{sec-bytestrings}{Bytestrings}\mdline{5785} +requirements.%mdk + +%mdk-data-line={5787} +\item\mdline{5787}If \mdline{5787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.Metadata.type\_name}}}\mdline{5787} is set and +\mdline{5788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec.translated\_type.sdn\_string}}}\mdline{5788} is set in the +\mdline{5789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{5789} message for the specified type name, then +\mdline{5790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata.value}}}\mdline{5790} can be an arbitrary SDN string subject to the +\mdline{5791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5791}. +If a \mdline{5792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5792} field +does not match the P4Info specification, the server must drop the \mdline{5793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5793} +message and may generate a \mdline{5794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5794} message with the \mdline{5794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5794} +field set to report the error to the client which issued the \mdline{5795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5795}. See +the section on\mdline{5796}~\mdref{sec-stream-error-reporting}{Stream Error Reporting}\mdline{5796} for more +information on \mdline{5797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5797}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5799} +\subsection{\mdline{5799}16.2.\hspace*{0.5em}\mdline{5799}Client Arbitration Update}\label{sec-client-arbitration-update}%mdk%mdk + +%mdk-data-line={5801} +\noindent\mdline{5801}P4Runtime\mdline{5801}'\mdline{5801}s client arbitration mechanism ensures that only the current primary +can modify state on the switch, and that the \mdline{5802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5802} is monotonically +increasing. For example, the switch must finish all previous write operations +before before selecting a different primary, and must only accept write requests +from the current primary.%mdk + +%mdk-data-line={5807} +\mdline{5807}As explained earlier in this document, the controller uses the \mdline{5807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5807} +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via \mdline{5809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5809} RPC), +it needs to start a controller session and become a \mdline{5810}\textquotedblleft{}primary\textquotedblright{}\mdline{5810}. To do so, the +controller first opens a bidirectional stream channel to the server via +\mdline{5812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5812} for each device and sends a \mdline{5812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5812} message. The +controller populates the \mdline{5813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5813} field in this message using +its \mdline{5814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5814} and \mdline{5814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5814} and the \mdline{5814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5814} of the device, as explained +in detail in the\mdline{5815}~\mdref{sec-client-arbitration-and-controller-replication}{Client Arbitration and Controller +Replication}\mdline{5816} +section. For any given \mdline{5817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role)}}}\mdline{5817}, the P4Runtime server keeps track +of the highest \mdline{5818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5818} that it has ever received. If a controller\mdline{5818}'\mdline{5818}s +\mdline{5819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5819} is equal to the highest \mdline{5819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5819} that the server has ever +received, that controller is the primary. All other controllers are backups. +Note that it is possible that all controllers are backups, and that there is no +primary. There can be at most one primary, because for any given +\mdline{5823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role)}}}\mdline{5823}, each connected controller has a unique \mdline{5823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5823}.%mdk + +%mdk-data-line={5825} +\mdline{5825}This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest \mdline{5826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5826} after such a restart. +However, across a\mdline{5827}~\mdref{sec-restarts}{full restart}\mdline{5827}, the \mdline{5827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5827} must be +reset. In fact, a full restart is the only way to reset the \mdline{5828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5828}.%mdk + +%mdk-data-line={5830} +\mdline{5830}The \mdline{5830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5830} message is defined as follows:%mdk + +%mdk-data-line={5832} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5833} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MasterArbitrationUpdate~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~The~role~for~which~the~primary~client~is~being~arbitrated.~For~use-cases}\\ +~~{\mdcolor{darkgreen}//~where~multiple~roles~are~not~needed,~the~controller~can~leave~this~unset,}\\ +~~{\mdcolor{darkgreen}//~implying~default~role~and~full~pipeline~access.}\\ +~~Role~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~The~stream~RPC~with~the~highest~election\_id~is~the~primary.~The~'primary'}\\ +~~{\mdcolor{darkgreen}//~controller~instance~populates~this~with~its~latest~election\_id.~Switch}\\ +~~{\mdcolor{darkgreen}//~populates~with~the~highest~election~ID~it~has~received~from~all~connected}\\ +~~{\mdcolor{darkgreen}//~controllers.}\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Switch~populates~this~with~OK~for~the~client~that~is~the~primary,~and}\\ +~~{\mdcolor{darkgreen}//~with~an~error~status~for~all~other~connected~clients~(at~every~primary}\\ +~~{\mdcolor{darkgreen}//~client~change).~The~controller~does~not~populate~this~field.}\\ +~~.google.{\bfseries{\mdcolor{navy}rpc}}.Status~status~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Role~\{\\ +~~{\mdcolor{darkgreen}//~Uniquely~identifies~this~role.}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Describes~the~role~configuration,~i.e.~what~operations,~P4~entities,}\\ +~~{\mdcolor{darkgreen}//~behaviors,~etc.~are~in~the~scope~of~a~given~role.~If~config~is~not~set}\\ +~~{\mdcolor{darkgreen}//~(default~case),~it~implies~all~P4~objects~and~control~behaviors~are~in}\\ +~~{\mdcolor{darkgreen}//~scope,~i.e.~full~pipeline~access.~The~format~of~this~message~is}\\ +~~{\mdcolor{darkgreen}//~out-of-scope~of~P4Runtime.}\\ +~~.google.protobuf.Any~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5862} +\noindent\mdline{5862}Note that the \mdline{5862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5862} field in the \mdline{5862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5862} message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a \mdline{5864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5864} message back to the controller, in which +it populates the \mdline{5865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5865} message using the \mdline{5865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5865}, +\mdline{5866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5866}, and \mdline{5866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5866} it previously received from the controller. The server +also populates the \mdline{5867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5867} field in the \mdline{5867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5867} according to +the rules in an\mdline{5868}~\mdref{sec-arbitration-updates}{earlier section}\mdline{5868}.%mdk + +%mdk-data-line={5870} +\subsubsection{\mdline{5870}16.2.1.\hspace*{0.5em}\mdline{5870}Unset Election ID}\label{sec-unset-election-id}%mdk%mdk + +%mdk-data-line={5872} +\noindent\mdline{5872}The sender need not specify an \mdline{5872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5872}. If the \mdline{5872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5872} is +unset, the sender\mdline{5873}'\mdline{5873}s \mdline{5873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5873} is considered lower than any +\mdline{5874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5874}, and the sender will thus never become primary. This way, a +controller can choose to be a standby controller, in order to avoid primary +\mdline{5876}\textquotedblleft{}flapping\textquotedblright{}\mdline{5876} (if a standby controller connects to the switch shortly before the +actual primary controller, therefore becoming primary temporarily).%mdk + +%mdk-data-line={5879} +\mdline{5879}Note that%mdk +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id~:~\{~high:~0~low:~0~\}}}%mdk +\end{mdpre}\noindent\mdline{5883}is different from an unset \mdline{5883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5883}, see +\mdline{5884}\mdref{sec-default-valued-fields}{the section on default-valued fields}\mdline{5884}. + +%mdk-data-line={5887} +\subsection{\mdline{5887}16.3.\hspace*{0.5em}\mdline{5887}Digest Messages}\label{sec-digest-messages}%mdk%mdk + +%mdk-data-line={5889} +\noindent\mdline{5889}See the\mdline{5889}~\mdref{sec-digestentry}{DigestEntry}\mdline{5889} section.%mdk + +%mdk-data-line={5891} +\subsection{\mdline{5891}16.4.\hspace*{0.5em}\mdline{5891}Table Idle Timeout Notification}\label{sec-table-idle-timeout-notification}%mdk%mdk + +%mdk-data-line={5893} +\noindent\mdline{5893}When a table supports idle timeout (as per the P4Info message), the primary +client can specify a TTL value for each entry in the table (see +\mdline{5895}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{5895} section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an \mdline{5897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5897} message on the +\mdline{5898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5898} bidirectional stream to the primary client. The primary client +can then take the action of its choice, most likely remove the idle entry.%mdk + +%mdk-data-line={5901} +\mdline{5901}The \mdline{5901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5901} Protobuf message has the following fields:%mdk + +%mdk-data-line={5903} +\begin{itemize}%mdk + +%mdk-data-line={5903} +\item{} +%mdk-data-line={5903} +\mdline{5903}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}timestamp}}}\mdline{5903}: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server\mdline{5904}'\mdline{5904}s local clock.%mdk%mdk + +%mdk-data-line={5906} +\item{} +%mdk-data-line={5906} +\mdline{5906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5906}: a repeated field of entries which have expired. Each individual +entry is identified by a single \mdline{5907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5907} message. For each \mdline{5907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5907}, +the \mdline{5908}\emph{key}\mdline{5908} fields (\mdline{5908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{5908}, \mdline{5908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{5908} and \mdline{5908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{5908}) must be set, along with +the \mdline{5909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{5909} field, the \mdline{5909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5909} field, and the +\mdline{5910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{5910} field. Other fields may be set by the server but should be +ignored by the client.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5913} +\noindent\mdline{5913}Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +\mdline{5915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5915} message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an \mdline{5920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5920} +message with an empty \mdline{5921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5921} repeated field.%mdk + +%mdk-data-line={5923} +\mdline{5923}After generating an idle notification, the P4Runtime server must \mdline{5923}\textquotedblleft{}reset\textquotedblright{}\mdline{5923} the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the primary client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle.%mdk + +%mdk-data-line={5930} +\mdline{5930}Here is a reasonable pseudo-code implementation for idle timeout for table +entries:%mdk + +%mdk-data-line={5933} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5934} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutStream~stream;\\ +\\ +scanning\_interval~=~{\mdcolor{purple}10}ms;\\ +\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~{\mdcolor{darkgreen}//~iterate~over~all~tables~which~support~idle~timeout}\\ +~~{\bfseries{\mdcolor{navy}for}}~(table~in~tables)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(!table.idle\_timeout\_supported)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~{\mdcolor{darkgreen}//~we~coalesce~all~idle~notifications~for~the~same~table~in~one}\\ +~~~~{\mdcolor{darkgreen}//~message}\\ +~~~~IdleTimeoutNotification~msg;\\ +~~~~{\mdcolor{darkgreen}//~read~time\_since\_last\_hit~from~device}\\ +~~~~entries~=~device.load\_table\_entries\_from\_hw(table);\\ +~~~~{\bfseries{\mdcolor{navy}for}}~(entry~in~entries)~\{\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.idle\_timeout~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~TTL}\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.time\_since\_last\_hit~\textless{}~entry.idle\_timeout)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~~~msg.table\_entry\_add(entry);\\ +~~~~~~entry.reset\_time\_since\_last\_hit();\\ +~~~~\}\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(msg.table\_entry\_size()~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~notifications}\\ +~~~~msg.set\_timestamp(now());\\ +~~~~stream.write(msg);\\ +~~\}\\ +~~sleep(scanning\_interval);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5961} +\subsection{\mdline{5961}16.5.\hspace*{0.5em}\mdline{5961}Architecture-Specific Notifications}\label{sec-architecture-specific-notifications}%mdk%mdk + +%mdk-data-line={5963} +\noindent\mdline{5963}P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on \mdline{5964}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5964}, by including an \mdline{5964}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5964} Protobuf field\mdline{5964}~[\mdcite{protoany}{37}]\mdline{5964} +named \mdline{5965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5965} in both \mdline{5965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5965} and \mdline{5965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5965}. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the\mdline{5967}~\mdref{sec-digestentry}{PSA \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}} +extern}\mdline{5968}. See section on\mdline{5968}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{5969} for more information.%mdk + +%mdk-data-line={5971} +\subsection{\mdline{5971}16.6.\hspace*{0.5em}\mdline{5971}Stream Error Reporting}\label{sec-stream-error-reporting}%mdk%mdk + +%mdk-data-line={5973} +\noindent\mdline{5973}The P4Runtime server can asynchronously report errors which occur when +processing \mdline{5974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5974} messages, using the \mdline{5974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5974} message field (of +type \mdline{5975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5975}) in \mdline{5975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5975}. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature.%mdk + +%mdk-data-line={5979} +\mdline{5979}The \mdline{5979}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5979} message has the following fields:%mdk + +%mdk-data-line={5981} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5981} +\item\mdline{5981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5981}, which must be set to the appropriate canonical error code +\mdline{5982}[\mdcite{grpcstatuscodes}{40}]\mdline{5982}.%mdk + +%mdk-data-line={5983} +\item\mdline{5983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{5983}, an optional developer-facing error message describing the error.%mdk + +%mdk-data-line={5984} +\item\mdline{5984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5984} and \mdline{5984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5984}, which are optional and can be used by vendors to provide +additional details on the error. \mdline{5985}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5985} is a numeric error code drawn from a +vendor\mdline{5986}'\mdline{5986}s chosen error \mdline{5986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5986}.%mdk + +%mdk-data-line={5987} +\item\mdline{5987}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5987}, which is a Protobuf \mdline{5987}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5987} used to help the client identify which +\mdline{5988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5988} triggered the error. The server is required to set the +appropriate field in the \mdline{5989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5989} so that the client can identify which type +of stream message is responsible for the error (\mdline{5990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5990}, +\mdline{5991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_list\_ack}}}\mdline{5991} or \mdline{5991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5991}), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid \mdline{5993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5993} message from the +client, the \mdline{5994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5994} field (of type \mdline{5994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError)}}}\mdline{5994} should be set in +the \mdline{5995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5995} \mdline{5995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5995}, and the server may additionally set the \mdline{5995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5995} +field in the \mdline{5996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError}}}\mdline{5996} sub-message (by copying it from the invalid +\mdline{5997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5997} message received on the stream channel) so that the client can +know exactly what packet-out triggered the error.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6000} +\noindent\mdline{6000}The appropriate canonical error code\mdline{6000}~[\mdcite{grpcstatuscodes}{40}]\mdline{6000} should be used when +populating the \mdline{6001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{6001} field. For example:%mdk + +%mdk-data-line={6003} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6003} +\item\mdline{6003}if a controller is not allowed to send a \mdline{6003}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{6003} message under its +current role definition, the code should be set to \mdline{6004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{6004}.%mdk + +%mdk-data-line={6005} +\item\mdline{6005}if the \mdline{6005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6005} repeated field in \mdline{6005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{6005} does not match the P4Info +definition, the code should be set to \mdline{6006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6006}. It may be useful +for the server to set the \mdline{6007}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{6007} field in this case, so that the client +can find out which set of metadata fields triggered the error.%mdk + +%mdk-data-line={6009} +\item\mdline{6009}if the \mdline{6009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{6009} field in \mdline{6009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{6009} does not match any \mdline{6009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{6009} entry +in P4Info, the code should be set to \mdline{6010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6010}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6012} +\noindent\mdline{6012}The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, \mdline{6013}e.g.\mdline{6013} because of a +burst of \mdline{6014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{6014} messages.%mdk + +%mdk-data-line={6016} +\mdline{6016}Note that client arbitration errors are never reported using the \mdline{6016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{6016} +message. Invalid \mdline{6017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{6017} messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section\mdline{6019}~\mdref{sec-arbitration-updates}{5.3}\mdline{6019}.%mdk + +%mdk-data-line={6021} +\subsubsection{\mdline{6021}16.6.1.\hspace*{0.5em}\mdline{6021}Examples of \mdline{6021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{6021} Messages}\label{sec-examples-of-streamerror-messages}%mdk%mdk + +%mdk-data-line={6023} +\begin{itemize}%mdk + +%mdk-data-line={6023} +\item{} +%mdk-data-line={6023} +\mdline{6023}\textbf{Malformed packet-out metadata.}\mdline{6023} If the server receives a \mdline{6023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{6023} +message with a \mdline{6024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6024} field with id 7 which is not included in the P4Info +\mdline{6025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{6025} message for \mdline{6025}\textquotedblleft{}packet\_out\textquotedblright{}\mdline{6025}, the server may send the +following \mdline{6026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{6026} back to the client:%mdk + +%mdk-data-line={6027} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6028} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Unknown~metadata~field~id~7.}{\mdcolor{maroon}"}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~copied~from~the~PacketOut~message~received~from~the~client}\\ +~~~packet\_out~\{\\ +~~~~~payload:~...\\ +~~~~~metadata~\{\\ +~~~~~~~id:~{\mdcolor{purple}7}\\ +~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}I\_should\_not\_be\_here}{\mdcolor{maroon}"}\\ +~~~~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~~\}\\ +~~~~~{\mdcolor{darkgreen}\#~more~metadata}\\ +~~~\}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={6046} +\item{} +%mdk-data-line={6046} +\mdline{6046}\textbf{Packet-out which exceeds the MTU.}\mdline{6046} If the server receives a \mdline{6046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{6046} +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following \mdline{6049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{6049}:%mdk + +%mdk-data-line={6050} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6051} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Packet~exceeds~the~MTU~for~port.}{\mdcolor{maroon}"}\\ +~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendor1}{\mdcolor{maroon}"}\\ +~code:~{\mdcolor{purple}123}~~{\mdcolor{darkgreen}\#~MTU\_EXCEEDED}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~we~do~not~set~the~packet\_out~field~as~it~does~not~provide~any}\\ +~~~{\mdcolor{darkgreen}\#~extra~information~to~the~client}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6063} +\section{\mdline{6063}17.\hspace*{0.5em}\mdline{6063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6063} RPC}\label{sec-capabilities-rpc}%mdk%mdk + +%mdk-data-line={6065} +\noindent\mdline{6065}The \mdline{6065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6065} RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the \mdline{6067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesRequest}}}\mdline{6067} message is empty and the \mdline{6067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{6067} +message only includes the \mdline{6068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_api\_version}}}\mdline{6068} string field. This field must +be set to the full semantic version string\mdline{6069}~[\mdcite{semver}{32}]\mdline{6069} corresponding to the +version of the P4Runtime API implemented by the server, \mdline{6070}e.g.\mdline{6070} \mdline{6070}\textquotedblleft{}1.1.0-rc.1\textquotedblright{}\mdline{6070}.%mdk + +%mdk-data-line={6072} +\mdline{6072}Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three\mdline{6073}~\mdref{sec-batch-atomicity}{atomicity +modes}\mdline{6074} for \mdline{6074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6074} batches, two of them being +optional. In the future we may decide to leverage the \mdline{6075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{6075} +message to enable the server to report to the client which subset of these +atomicity modes is supported.%mdk + +%mdk-data-line={6079} +\mdline{6079}The semantic version string included in \mdline{6079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{6079} can be used by +the client to determine which exact feature set is implemented by the server, +since\mdline{6081}~\mdref{sec-p4runtime-versioning}{minor releases}\mdline{6081} may introduce new +functionality. However, because the \mdline{6082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6082} RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (\mdline{6084}i.e.\mdline{6084} an \mdline{6084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{6084} error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0).%mdk + +%mdk-data-line={6088} +\section{\mdline{6088}18.\hspace*{0.5em}\mdline{6088}Portability Considerations}\label{sec-portability-considerations}%mdk%mdk + +%mdk-data-line={6090} +\subsection{\mdline{6090}18.1.\hspace*{0.5em}\mdline{6090}PSA Metadata Translation}\label{sec-psa-metadata-translation}%mdk%mdk + +%mdk-data-line={6092} +\noindent\mdline{6092}The \mdline{6092}\emph{Portable Switch Architecture}\mdline{6092} (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +\mdline{6096}[\mdcite{psatranslation}{29}]\mdline{6096}. For such metadata, a translation between the controller\mdline{6096}'\mdline{6096}s +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the \mdline{6100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6100} annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture.%mdk + +%mdk-data-line={6104} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={6105} +\noindent\mdline{6105}\includegraphics[keepaspectratio=true,height=7cm]{build/psa-metadata-translation}{}\mdline{6105}%mdk + +%mdk-data-line={6106} +\mdhr{}%mdk + +%mdk-data-line={6107} +\noindent\mdline{6107}\mdcaption{\textbf{Figure~\mdcaptionlabel{8}.}~\mdcaptiontext{P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdcenter}\label{fig-psa-metadata-translation}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={6111} +\noindent\mdline{6111}Figure\mdline{6111}~\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}}\mdline{6111} illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller\mdline{6117}'\mdline{6117}s 32 bit port +numbers to a target\mdline{6118}'\mdline{6118}s 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch.%mdk + +%mdk-data-line={6122} +\subsubsection{\mdline{6122}18.1.1.\hspace*{0.5em}\mdline{6122}Translation of Port Numbers}\label{sec-translation-of-port-numbers}%mdk%mdk + +%mdk-data-line={6124} +\noindent\mdline{6124}In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller\mdline{6125}'\mdline{6125}s space and the PSA device\mdline{6125}'\mdline{6125}s space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +\mdline{6129}\mdref{sec-user-defined-types}{user-defined P4 types}\mdline{6129}, namely \mdline{6129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{6129} and +\mdline{6130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{6130}, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in \mdline{6133}\emph{psa.p4}\mdline{6133} for +the PSA device in Switch 1.%mdk + +%mdk-data-line={6136} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6137} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_t;\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortIdInHeader\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~PortIdInHeader\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6143} +\noindent\mdline{6143}The first argument to the \mdline{6143}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6143} annotation is a URI that +indicates to the P4Runtime server which numerical mapping\mdline{6144} \mdline{6144}\textemdash{}\mdline{6144} provided by the +out-of-band switch configuration mechanism\mdline{6145} \mdline{6145}\textemdash{}\mdline{6145} to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports).%mdk + +%mdk-data-line={6149} +\mdline{6149}An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows:%mdk + +%mdk-data-line={6155} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6156} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}enum}}~SdnPort~\{\\ +~~SDN\_PORT\_UNKNOWN~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +\\ +~~{\mdcolor{darkgreen}//~SDN~ports~are~numbered~starting~from~1.}\\ +~~SDN\_PORT\_MIN~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\\ +~~{\mdcolor{darkgreen}//~The~maximum~value~of~an~SDN~port~(physical~or~logical).}\\ +~~SDN\_PORT\_MAX~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffeff};\\ +\\ +~~{\mdcolor{darkgreen}//~Reserved~SDN~port~numbers~(0xfffffff0~-~0xffffffff)}\\ +\\ +~~SDN\_PORT\_RECIRCULATE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffa};\\ +~~SDN\_PORT\_CPU~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffd};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6172} +\noindent\mdline{6172}The switch config will map \mdline{6172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_RECIRCULATE}}}\mdline{6172} and \mdline{6172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_CPU}}}\mdline{6172} \mdline{6172}\textemdash{}\mdline{6172} as well +as any SDN port number corresponding to a \mdline{6173}\textquotedblleft{}regular\textquotedblright{}\mdline{6173} front-panel port\mdline{6173} \mdline{6173}\textemdash{}\mdline{6173} to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation.%mdk + +%mdk-data-line={6177} +\mdline{6177}The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs.%mdk + +%mdk-data-line={6180} +\subsubsection{\mdline{6180}18.1.2.\hspace*{0.5em}\mdline{6180}Translation of Packet-IO Header Fields}\label{sec-translation-of-packet-io-header-fields}%mdk%mdk + +%mdk-data-line={6182} +\noindent\mdline{6182}Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:.%mdk + +%mdk-data-line={6185} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6186} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~PortIdInHeader\_t~egress\_port;\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~PortIdInHeader\_t~ingress\_port;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6197} +\noindent\mdline{6197}The header-level annotation \mdline{6197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{6197} is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (\mdline{6201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{6201}) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI\mdline{6205} \mdline{6205}\textemdash{}\mdline{6205} first argument to the \mdline{6205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6205} +annotation). Any subsequent reference to the \mdline{6206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{6206} field in the +data plane will use the translated value. \mdline{6207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{6207} is used in the +header definition instead of \mdline{6208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{6208} to guarantee byte-aligned headers in +case this is required by the target.%mdk + +%mdk-data-line={6211} +\mdline{6211}A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target\mdline{6213}'\mdline{6213}s PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the \mdline{6215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ingress\_port}}}\mdline{6215} field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller.%mdk + +%mdk-data-line={6221} +\subsubsection{\mdline{6221}18.1.3.\hspace*{0.5em}\mdline{6221}Translation of Match Fields}\label{sec-translation-of-match-fields}%mdk%mdk + +%mdk-data-line={6223} +\noindent\mdline{6223}Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table\mdline{6224}'\mdline{6224}s match key as shown in the example below:%mdk + +%mdk-data-line={6226} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6227} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~istd.ingress\_port:~exact;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~ingress~port}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6237} +\noindent\mdline{6237}Table \mdline{6237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{6237} has an exact match on PSA standard metadata ingress port +(\mdline{6238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}istd.ingress\_port}}}\mdline{6238}). Since the field is of type \mdline{6238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{6238}, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in \mdline{6241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{6241} from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table \mdline{6246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{6246} is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values.%mdk + +%mdk-data-line={6250} +\mdline{6250}Note that it may be infeasible to translate the value-mask pair for ternary +matches: \mdline{6251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{6251}, \mdline{6251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{6251} or \mdline{6251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{6251} match kinds. The P4Runtime server may +require that for these match kinds the port match be either \mdline{6252}\emph{de facto}\mdline{6252} \mdline{6252}\textquotedblleft{}exact\textquotedblright{}\mdline{6252} +(0xffffffff mask for \mdline{6253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{6253}, prefix-length of 32 for \mdline{6253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{6253}, or same low and +high bounds for \mdline{6254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{6254}) or \mdline{6254}\textquotedblleft{}don't care\textquotedblright{}\mdline{6254}.%mdk + +%mdk-data-line={6256} +\subsubsection{\mdline{6256}18.1.4.\hspace*{0.5em}\mdline{6256}Translation of Action Parameters}\label{sec-translation-of-action-parameters}%mdk%mdk + +%mdk-data-line={6258} +\noindent\mdline{6258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{6258} type parameters can be part of a P4 action definition as shown in the +example below:%mdk + +%mdk-data-line={6261} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6262} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.h.f:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~a;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6276} +\noindent\mdline{6276}The controller may write entries in table \mdline{6276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{6276} with action \mdline{6276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{6276} to set the egress +port as shown in the P4 code above. The action parameter \mdline{6277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{6277} is of type +\mdline{6278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{6278}, which leads to a 32-bit bitwidth for \mdline{6278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{6278} being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device.%mdk + +%mdk-data-line={6284} +\subsubsection{\mdline{6284}18.1.5.\hspace*{0.5em}\mdline{6284}Port Translation for PSA Extern APIs}\label{sec-port-translation-for-psa-extern-apis}%mdk%mdk + +%mdk-data-line={6286} +\noindent\mdline{6286}The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The \mdline{6291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{6291} +field is of type \mdline{6292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{6292} to carry the SDN representation of the port being +watched. The P4Runtime server will translate the given watch port into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device.%mdk + +%mdk-data-line={6297} +\mdline{6297}The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress \mdline{6298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{6298} fields defined in the PRE +multicast entry and clone session entry are of type \mdline{6299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{6299} to carry the SDN +representation of the port(s). The P4Runtime server will translate these SDN +ports to device-specific port numbers for multicasting and cloning in the data +plane.%mdk + +%mdk-data-line={6304} +\subsubsection{\mdline{6304}18.1.6.\hspace*{0.5em}\mdline{6304}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}\label{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}%mdk%mdk + +%mdk-data-line={6306} +\noindent\mdline{6306}P4Runtime supports using a translated value (\mdline{6306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{6306} or any other translated +type for which the underlying built-in type is \mdline{6307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6307}) as an index to a +register, indirect counter, or indirect meter.%mdk + +%mdk-data-line={6310} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6311} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~counter~entry~type~}{\mdcolor{darkgreen}*/},~PortId\_t~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~index~type~}{\mdcolor{darkgreen}*/}\textgreater{}(\\ +~~{\mdcolor{purple}32}w1024,~PSA\_CounterType\_t.PACKETS)~counter;\\ +{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +~~counter.count(p);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6319} +\noindent\mdline{6319}This P4 Counter declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={6322} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6323} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counters~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x12000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}counter}{\mdcolor{maroon}"}\\ +~~\}\\ +~~spec~\{\\ +~~~~unit:~PACKETS\\ +~~\}\\ +~~index\_type\_name~\{\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6337} +\noindent\mdline{6337}The controller may read and write counter values from indexed counter \mdline{6337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter}}}\mdline{6337} +using SDN port numbers as indices, and not device-specific port numbers. The +\mdline{6339}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{6339} field in the P4Info message is a signal to the P4Runtime +server that translation is required.%mdk + +%mdk-data-line={6342} +\section{\mdline{6342}19.\hspace*{0.5em}\mdline{6342}P4Runtime Versioning}\label{sec-p4runtime-versioning}%mdk%mdk + +%mdk-data-line={6344} +\noindent\mdline{6344}P4Runtime follows the Google guidelines for versioning cloud APIs +\mdline{6345}[\mdcite{apiversioning}{8}]\mdline{6345}. We use a \mdline{6345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR.MINOR.PATCH}}}\mdline{6345} style version number scheme and +we increment the:%mdk + +%mdk-data-line={6348} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6348} +\item\mdline{6348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{6348} version when we make incompatible API changes,%mdk + +%mdk-data-line={6349} +\item\mdline{6349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MINOR}}}\mdline{6349} version when we add functionality in a backwards-compatible manner,%mdk + +%mdk-data-line={6350} +\item\mdline{6350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PATCH}}}\mdline{6350} version when we make backwards-compatible bug fixes.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6352} +\noindent\mdline{6352}The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is \mdline{6354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1}}}\mdline{6354} and the package +name for P4Info is \mdline{6355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1}}}\mdline{6355}. Even though \mdline{6355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{6355} and \mdline{6355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{6355} are two +different Protobuf packages, \mdline{6356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{6356} depends on \mdline{6356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{6356} and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence.%mdk + +%mdk-data-line={6360} +\mdline{6360}As recommended in\mdline{6360}~[\mdcite{apiversioning}{8}]\mdline{6360}, we may consider using pre-GA release +suffixes (such as \mdline{6361}\emph{alpha}\mdline{6361} or \mdline{6361}\emph{beta}\mdline{6361}) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1).%mdk + +%mdk-data-line={6365} +\mdline{6365}Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner.\mdline{6366}~[\mdcite{apiversioningbackwardscompatibility}{9}]\mdline{6366} describes +what constitute a backwards-compatible change. We expect \mdline{6367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{6367} version bumps +to be a \mdline{6368}\textbf{rare}\mdline{6368} event.%mdk + +%mdk-data-line={6370} +\mdline{6370}Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor\mdline{6375} \mdline{6375}+ patch version numbers in future releases.%mdk + +%mdk-data-line={6377} +\mdline{6377}All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository\mdline{6378}~[\mdcite{p4runtimerepo}{19}]\mdline{6378} and the version label follows +semantic versioning rules\mdline{6379}~[\mdcite{semver}{32}]\mdline{6379}.%mdk + +%mdk-data-line={6381} +\section{\mdline{6381}20.\hspace*{0.5em}\mdline{6381}Extending P4Runtime for non-PSA Architectures}\label{sec-extending-p4runtime}%mdk%mdk + +%mdk-data-line={6383} +\noindent\mdline{6383}P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place.%mdk + +%mdk-data-line={6391} +\mdline{6391}When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names:%mdk + +%mdk-data-line={6395} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6395} +\item\mdline{6395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/config/\textless{}major~version\textgreater{}/p4info.proto}}}\mdline{6395}%mdk + +%mdk-data-line={6396} +\item\mdline{6396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/\textless{}major~version\textgreater{}/p4runtime.proto}}}\mdline{6396}%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6398} +\noindent\mdline{6398}We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they \mdline{6399}\textquotedblleft{}extend\textquotedblright{}\mdline{6399}.%mdk + +%mdk-data-line={6401} +\mdline{6401}For the remainder of this section, we will refer to these two files as +\mdline{6402}\emph{p4info-ext}\mdline{6402} and \mdline{6402}\emph{p4runtime-ext}\mdline{6402} respectively.%mdk + +%mdk-data-line={6404} +\subsection{\mdline{6404}20.1.\hspace*{0.5em}\mdline{6404}Extending P4Runtime for Architecture-Specific Externs}\label{sec-extending-p4runtime-for-architecture-specific-externs}%mdk%mdk + +%mdk-data-line={6406} +\noindent\mdline{6406}Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both \mdline{6407}\emph{p4info-ext}\mdline{6407} and +\mdline{6408}\emph{p4runtime-ext}\mdline{6408}. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example:%mdk + +%mdk-data-line={6412} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6413} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~T~must~be~a~bit\textless{}W\textgreater{}~type,~it~indicates~the~width~of~each~counter~cell}\\ +{\bfseries{\mdcolor{navy}extern}}~MyNewPacketCounter\textless{}T\textgreater{}~\{\\ +~~counter({\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~size);\\ +~~increment({\bfseries{\mdcolor{navy}in}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~index);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6420} +\subsubsection{\mdline{6420}20.1.1.\hspace*{0.5em}\mdline{6420}Extending the P4Info message}\label{sec-extending-the-p4info-message}%mdk%mdk + +%mdk-data-line={6422} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6422} +\item\mdline{6422}Id prefixes \mdline{6422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0x81}}}\mdline{6422} through \mdline{6422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfe}}}\mdline{6422} are reserved for architecture-specific +externs. It is recommended that \mdline{6423}\emph{p4info-ext}\mdline{6423} include a \mdline{6423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Ids}}}\mdline{6423} message based +on the one in p4info.proto that the P4 compiler can refer to when\mdline{6424}~\mdref{sec-id-allocation}{assigning +IDs}\mdline{6425} to each extern instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6427} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6428} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~P{\mdcolor{purple}4}Ids~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Prefix~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~MY\_NEW\_PACKET\_COUNTER~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0x81};\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6436} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6436} +\item\mdline{6436}\emph{p4info-ext}\mdline{6436} should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +\mdline{6440}\mdref{sec-p4info-extern}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ExternInstance}}}}\mdline{6440} message as the \mdline{6440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{6440} +field, which is of type \mdline{6441}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6441}~[\mdcite{protoany}{37}]\mdline{6441}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6443} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6444} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\mdcolor{darkgreen}//~corresponds~to~the~T~type~parameter~in~the~P4~extern~definition}\\ +~~p4.config.v1.P{\mdcolor{purple}4}DataTypeSpec~type\_spec~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~constructor~argument}\\ +~~{\bfseries{\mdcolor{navy}int64}}~size~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6452} +\subsubsection{\mdline{6452}20.1.2.\hspace*{0.5em}\mdline{6452}Extending the P4Runtime Service}\label{sec-extending-the-p4runtime-service}%mdk%mdk + +%mdk-data-line={6454} +\noindent\mdline{6454}Just like \mdline{6454}\emph{p4info-ext}\mdline{6454}, \mdline{6454}\emph{p4runtime-ext}\mdline{6454} should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an\mdline{6459}~\mdref{sec-extern-entry}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\mdline{6459} message generated by the +P4Runtime client.%mdk + +%mdk-data-line={6462} +\mdline{6462}Here is a possible Protobuf message for our \mdline{6462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyNewPacketCounter}}}\mdline{6462} P4 extern:%mdk + +%mdk-data-line={6463} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6464} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~This~message~enables~reading~/~writing~data~to~the~counter~at~the~provided}\\ +{\mdcolor{darkgreen}//~index}\\ +{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~p4.v1.P{\mdcolor{purple}4}Data~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6472} +\noindent\mdline{6472}P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an \mdline{6473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6473} Protobuf field\mdline{6473}~[\mdcite{protoany}{37}]\mdline{6473} named \mdline{6473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6473} +in both \mdline{6474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{6474} and +\mdline{6475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{6475}. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in \mdline{6477}\emph{p4runtime-ext}\mdline{6477} and embed instances of these messages in +\mdline{6478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{6478} and \mdline{6478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{6478} as appropriate.%mdk + +%mdk-data-line={6480} +\subsection{\mdline{6480}20.2.\hspace*{0.5em}\mdline{6480}Architecture-Specific Table Extensions}\label{sec-architecture-specific-table-extensions}%mdk%mdk + +%mdk-data-line={6482} +\subsubsection{\mdline{6482}20.2.1.\hspace*{0.5em}\mdline{6482}New Match Types}\label{sec-new-match-types}%mdk%mdk + +%mdk-data-line={6484} +\noindent\mdline{6484}An architecture may introduce new table match types\mdline{6484}~[\mdcite{p4matchtypes}{14}]\mdline{6484}. P4Runtime +accounts for this by providing the following hooks:%mdk + +%mdk-data-line={6487} +\begin{itemize}%mdk + +%mdk-data-line={6487} +\item{} +%mdk-data-line={6487} +\mdline{6487}The \mdline{6487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{6487} field in \mdline{6487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{6487} (p4info.proto) is a \mdline{6487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6487} +which can be either one of the default match types (\mdline{6488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{6488}, \mdline{6488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{6488}, \mdline{6488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{6488}, +\mdline{6489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{6489}, or \mdline{6489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6489}) or an architecture-specific match type encoded as a +string.%mdk%mdk + +%mdk-data-line={6492} +\item{} +%mdk-data-line={6492} +\mdline{6492}The \mdline{6492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{6492} field in \mdline{6492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6492} (p4runtime.proto) is a +\mdline{6493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6493} which includes an \mdline{6493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6493} Protobuf message\mdline{6493}~[\mdcite{protoany}{37}]\mdline{6493} field +(\mdline{6494}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6494}). \mdline{6494}\emph{p4info-ext}\mdline{6494} should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in \mdline{6497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6497} as the +\mdline{6498}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6498} field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6501} +\subsubsection{\mdline{6501}20.2.2.\hspace*{0.5em}\mdline{6501}New Table Properties}\label{sec-new-table-properties}%mdk%mdk + +%mdk-data-line={6503} +\noindent\mdline{6503}An architecture may introduce additional table properties +\mdline{6504}[\mdcite{p4tableproperties}{36}]\mdline{6504}. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +\mdline{6506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Table}}}\mdline{6506} message includes the \mdline{6506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{6506} \mdline{6506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6506} Protobuf +field\mdline{6507}~[\mdcite{protoany}{37}]\mdline{6507}. At the moment, there is not any mechanism to extend the +\mdline{6508}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.TableEntry}}}\mdline{6508} message based on the value of architecture-specific table +properties, but we may include on in future versions of the API.%mdk + +%mdk-data-line={6511} +\section{\mdline{6511}21.\hspace*{0.5em}\mdline{6511}Known Limitations of Current P4Runtime Version}\label{sec-known-limitations-of-current-p4runtime-version}%mdk%mdk + +%mdk-data-line={6513} +\begin{itemize}%mdk + +%mdk-data-line={6513} +\item{} +%mdk-data-line={6513} +\mdline{6513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6513}, action \mdline{6513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6513}, and controller packet metadata fields only +support unsigned bitstrings, \mdline{6514}i.e.\mdline{6514} values of one of the following types (not +the more general \mdline{6515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{6515}):%mdk + +%mdk-data-line={6516} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6516} +\item\mdline{6516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6516}%mdk + +%mdk-data-line={6517} +\item\mdline{6517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6517}. Note that as far as the \mdline{6517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Info}}}\mdline{6517} message contents and +thus controller software is concerned, such fields of type \mdline{6518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6518} +will be indistinguishable from those that have been declared with +type \mdline{6520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6520}. P4Runtime server software will automatically +perform any conversion needed between the type \mdline{6521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6521} values in +P4Runtime messages and the data plane representation.%mdk + +%mdk-data-line={6523} +\item\mdline{6523}an \mdline{6523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{6523} with underlying type \mdline{6523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6523}%mdk + +%mdk-data-line={6524} +\item\mdline{6524}a \mdline{6524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6524} or \mdline{6524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6524} with an underlying type that is one of the above (or +in general a \mdline{6525}\textquotedblleft{}chain\textquotedblright{}\mdline{6525} of \mdline{6525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6525} and/or \mdline{6525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6525} that eventually ends with +one of the types above)%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6528} +\item{} +%mdk-data-line={6528} +\mdline{6528}Support for PSA Random \mdline{6528}\&\mdline{6528} Timestamp externs is postponed to a future minor +version update.%mdk%mdk + +%mdk-data-line={6531} +\item{} +%mdk-data-line={6531} +\mdline{6531}P4Info does not include information about which of a table\mdline{6531}'\mdline{6531}s actions execute +which direct resource(s).%mdk%mdk + +%mdk-data-line={6534} +\item{} +%mdk-data-line={6534} +\mdline{6534}The default action for indirect match tables is restricted to a \mdline{6534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\\ +NoAction}}}\mdline{6535} known at compile-time.%mdk%mdk + +%mdk-data-line={6537} +\item{} +%mdk-data-line={6537} +\mdline{6537}There is no mechanism for changing the value of the \mdline{6537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{6537} +table property at runtime.%mdk%mdk + +%mdk-data-line={6540} +\item{} +%mdk-data-line={6540} +\mdline{6540}There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor\mdline{6541} \mdline{6541}+ +patch version numbers.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6544} +\section{\mdline{6544}A.\hspace*{0.5em}\mdline{6544}Appendix}\label{sec-appendix}%mdk%mdk + +%mdk-data-line={6546} +\subsection{\mdline{6546}A.1.\hspace*{0.5em}\mdline{6546}Revision History}\label{sec-revision-history}%mdk%mdk + +%mdk-data-line={6548} +\subsubsection{\mdline{6548}A.1.1.\hspace*{0.5em}\mdline{6548}Changes in v1.4.0}\label{sec-changes-in-v140}%mdk%mdk + +%mdk-data-line={6550} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6550} +\item\mdline{6550}Add a \mdline{6550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Type}}}\mdline{6550} field to the \mdline{6550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{6550} message allowing users to restrict the +type of meters that can be used for a table and a new \mdline{6551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}eburst}}}\mdline{6551} field to the +\mdline{6552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{6552} message for use with one of the new \mdline{6552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{6552} types.%mdk + +%mdk-data-line={6553} +\item\mdline{6553}Add a \mdline{6553}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PlatformProperties}}}\mdline{6553} message specifying desired underlying platform +properties to the \mdline{6554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{6554} message.%mdk + +%mdk-data-line={6555} +\item\mdline{6555}Add a \mdline{6555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6555} field to the \mdline{6555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{6555} message.%mdk + +%mdk-data-line={6556} +\item\mdline{6556}Clarify that the limitation on supported types for \mdline{6556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6556}, action +\mdline{6557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6557}, and Packet IO metadata fields (no support for signed integers, with +type \mdline{6558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{6558}) apply to all minor revisions of P4Runtime v1, not just to +P4Runtime v1.0.%mdk + +%mdk-data-line={6560} +\item\mdline{6560}Fix invalid \mdline{6560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{6560} in the One Shot Action Selector Programming +example.%mdk + +%mdk-data-line={6562} +\item\mdline{6562}Specify Read behavior in the absence of a P4Info (\mdline{6562}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{6562} +not set yet).%mdk + +%mdk-data-line={6564} +\item\mdline{6564}Clarify that for updates of type \mdline{6564}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{6564}, error codes other than +\mdline{6565}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6565} can be returned when applicable.%mdk + +%mdk-data-line={6566} +\item\mdline{6566}Enable C++ Arena Allocation\mdline{6566}~[\mdcite{arenaallocation}{4}]\mdline{6566} by default in p4runtime.proto.%mdk + +%mdk-data-line={6567} +\item\mdline{6567}Add support for string role identifiers and deprecate integer role +identifiers.%mdk + +%mdk-data-line={6569} +\item\mdline{6569}Add support for specifying a role in \mdline{6569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{6569} messages: if present, only +entities belonging to this specific role are returned.%mdk + +%mdk-data-line={6571} +\item\mdline{6571}Specify that \mdline{6571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{6571} must be less than or equal to \mdline{6571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{6571} for Action +Selectors.%mdk + +%mdk-data-line={6573} +\item\mdline{6573}Simplify specification for arbitration updates for which there is no change to +the controller\mdline{6574}'\mdline{6574}s \mdline{6574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{6574}; in particular, a \mdline{6574}\textquotedblleft{}no-op\textquotedblright{}\mdline{6574} arbitration update +from a primary controller (the controller already was, and remains, the +primary controller) is essentially treated the same way as an arbitration +update which leads to the election of a new primary controller.%mdk + +%mdk-data-line={6578} +\item\mdline{6578}Enable P4Runtime servers to provide per-color counter values when direct or +indirect meter entries are read.%mdk + +%mdk-data-line={6580} +\item\mdline{6580}Clarify that the (\mdline{6580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{6580}, \mdline{6580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{6580}, \mdline{6580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{6580}) 3-tuples are only unique +for live controllers.%mdk + +%mdk-data-line={6582} +\item\mdline{6582}Add a \mdline{6582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{6582} field to the \mdline{6582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{6582} message +in P4Info.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6585} +\subsubsection{\mdline{6585}A.1.2.\hspace*{0.5em}\mdline{6585}Changes in v1.3.0}\label{sec-changes-in-v130}%mdk%mdk + +%mdk-data-line={6587} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6587} +\item\mdline{6587}Add IANA assigned TCP port, 9559, to P4Runtime server discussion.%mdk + +%mdk-data-line={6588} +\item\mdline{6588}Move \mdline{6588}\textquotedblleft{}Security considerations\textquotedblright{}\mdline{6588} section to P4Runtime server discussion.%mdk + +%mdk-data-line={6589} +\item\mdline{6589}Deprecate \mdline{6589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{6589} field (int32) in favor of \mdline{6589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{6589} (bytes). This allows +using the watch port feature with the \mdline{6590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_translation}}}\mdline{6590} feature.%mdk + +%mdk-data-line={6591} +\item\mdline{6591}Replace master, slave, master arbitration with more inclusive language: +primary, backup, and client arbitration%mdk + +%mdk-data-line={6593} +\item\mdline{6593}Clarify that source locations for annotations are optional in the P4Info +message.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6596} +\subsubsection{\mdline{6596}A.1.3.\hspace*{0.5em}\mdline{6596}Changes in v1.2.0}\label{sec-changes-in-v120}%mdk%mdk + +%mdk-data-line={6598} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6598} +\item\mdline{6598}Add new \mdline{6598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6598} match kind. At the moment, \mdline{6598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6598} is only supported by +the v1model architecture\mdline{6599}~[\mdcite{v1model}{44}]\mdline{6599}, and not by PSA. It will eventually be +included in the core P4 language.%mdk + +%mdk-data-line={6601} +\item\mdline{6601}Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists.%mdk + +%mdk-data-line={6603} +\item\mdline{6603}Add a new \mdline{6603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6603} field of type \mdline{6603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{6603} to \mdline{6603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{6603}. This is more +flexible than the now deprecated \mdline{6604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{6604} field.%mdk + +%mdk-data-line={6605} +\item\mdline{6605}Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +\mdline{6607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6607} annotation.%mdk + +%mdk-data-line={6608} +\item\mdline{6608}Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature.%mdk + +%mdk-data-line={6610} +\item\mdline{6610}Support using \mdline{6610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{6610} as the controller type in the \mdline{6610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6610} +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type.%mdk + +%mdk-data-line={6613} +\item\mdline{6613}Add optional P4 source locations to both structured and unstructured +annotations.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6616} +\subsubsection{\mdline{6616}A.1.4.\hspace*{0.5em}\mdline{6616}Changes in v1.1.0}\label{sec-changes-in-v110}%mdk%mdk + +%mdk-data-line={6618} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6618} +\item\mdline{6618}Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously.%mdk + +%mdk-data-line={6624} +\item\mdline{6624}Add \mdline{6624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{6624} field to stream messages sent by the server.%mdk + +%mdk-data-line={6625} +\item\mdline{6625}Add \mdline{6625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6625} RPC to query the P4Runtime API version implemented by the +server.%mdk + +%mdk-data-line={6627} +\item\mdline{6627}Support wildcard reads for multicast groups and clone sessions.%mdk + +%mdk-data-line={6628} +\item\mdline{6628}Support for modifying direct resources of const tables.%mdk + +%mdk-data-line={6629} +\item\mdline{6629}Support P4 user-defined types for Packet IO metadata fields.%mdk + +%mdk-data-line={6630} +\item\mdline{6630}Clarify consistency requirements for \mdline{6630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6630} and \mdline{6630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{6630} RPCs.%mdk + +%mdk-data-line={6631} +\item\mdline{6631}Add Appendix providing implementation advice for avoiding common pitfalls: + +%mdk-data-line={6632} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6632} +\item\mdline{6632}advice on setting gRPC Metadata Maximum Size%mdk + +%mdk-data-line={6633} +\item\mdline{6633}advice on setting gRPC Server Maximum Receive Message Size%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6634} +\item\mdline{6634}Clarify limitations on supported types for \mdline{6634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6634}, action \mdline{6634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6634}, and +Packet IO metadata fields.%mdk + +%mdk-data-line={6636} +\item\mdline{6636}Clarify that reading entire forwarding state with empty \mdline{6636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{6636} is not +supported.%mdk + +%mdk-data-line={6638} +\item\mdline{6638}Document that \mdline{6638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6638} need only be supported when applied to +type declarations in P4.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6641} +\subsection{\mdline{6641}A.2.\hspace*{0.5em}\mdline{6641}P4 Annotations}\label{sec-p4-annotations}%mdk%mdk + +%mdk-data-line={6643} +\noindent\mdline{6643}Table\mdline{6643}~\mdref{tab-p4-annotations}{\mdcaptionlabel{7}}\mdline{6643} lists P4\mdline{6643}\mdsub{16}\mdline{6643} annotations introduced primarily for +the purpose of adding features for the P4Runtime API.%mdk + +%mdk-data-line={6646} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{6648} Annotation}}&\multicolumn{1}{|c|}{{\bfseries\mdline{6648} Description}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{6650} \mdline{6650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{6650}}&\multicolumn{1}{|l|}{\mdline{6650} See section\mdline{6650}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6650}}\\ +\multicolumn{1}{|l}{\mdline{6651} \mdline{6651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{6651}}&\multicolumn{1}{|l|}{\mdline{6651} See section\mdline{6651}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{6651}}\\ +\multicolumn{1}{|l}{\mdline{6652} \mdline{6652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{6652}}&\multicolumn{1}{|l|}{\mdline{6652} See section\mdline{6652}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6652}}\\ +\multicolumn{1}{|l}{\mdline{6653} \mdline{6653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6653}}&\multicolumn{1}{|l|}{\mdline{6653} See section\mdline{6653}~\mdref{sec-id-allocation}{6.3}\mdline{6653}}\\ +\multicolumn{1}{|l}{\mdline{6654} \mdline{6654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{6654}}&\multicolumn{1}{|l|}{\mdline{6654} See sections\mdline{6654}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{6654},\mdline{6654}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{6654}}\\ +\multicolumn{1}{|l}{\mdline{6655} \mdline{6655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@selector\_size\_semantics}}}\mdline{6655}}&\multicolumn{1}{|l|}{\mdline{6655} See section\mdline{6655}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{6655}}\\ +\multicolumn{1}{|l}{\mdline{6656} \mdline{6656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_member\_weight}}}\mdline{6656}}&\multicolumn{1}{|l|}{\mdline{6656} See section\mdline{6656}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{6656}}\\ +\multicolumn{1}{|l}{\mdline{6657} \mdline{6657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@two\_rate\_three\_color}}}\mdline{6657}}&\multicolumn{1}{|l|}{\mdline{6657} See section\mdline{6657}~\mdref{sec-meter-directmeter}{6.4.5}\mdline{6657}}\\ +\multicolumn{1}{|l}{\mdline{6658} \mdline{6658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@single\_rate\_three\_color}}}\mdline{6658}}&\multicolumn{1}{|l|}{\mdline{6658} See section\mdline{6658}~\mdref{sec-meter-directmeter}{6.4.5}\mdline{6658}}\\ +\multicolumn{1}{|l}{\mdline{6659} \mdline{6659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@single\_rate\_two\_color}}}\mdline{6659}}&\multicolumn{1}{|l|}{\mdline{6659} See section\mdline{6659}~\mdref{sec-meter-directmeter}{6.4.5}\mdline{6659}}\\ +\multicolumn{1}{|l}{\mdline{6660} \mdline{6660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{6660}}&\multicolumn{1}{|l|}{\mdline{6660} See section\mdline{6660}~\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1}\mdline{6660}}\\ +\multicolumn{1}{|l}{\mdline{6661} \mdline{6661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@platform\_property}}}\mdline{6661}}&\multicolumn{1}{|l|}{\mdline{6661} See section\mdline{6661}~\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1}\mdline{6661}}\\ +\multicolumn{1}{|l}{\mdline{6662} \mdline{6662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6662}}&\multicolumn{1}{|l|}{\mdline{6662} See sections\mdline{6662}~\mdref{sec-user-defined-types}{8.4.6}\mdline{6662},\mdline{6662}~\mdref{sec-translation-of-port-numbers}{18.1.1}\mdline{6662}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={6664} +\mdhr{}%mdk + +%mdk-data-line={6665} +\noindent\mdline{6665}\mdcaption{\textbf{Table~\mdcaptionlabel{7}.}~\mdcaptiontext{P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-annotations}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={6668} +\subsection{\mdline{6668}A.3.\hspace*{0.5em}\mdline{6668}A More Complex Value Set Example}\label{sec-value-set-example}%mdk%mdk + +%mdk-data-line={6670} +\noindent\mdline{6670}This section includes a more complex Value Set example, with multiple matches of +different kinds.%mdk + +%mdk-data-line={6673} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6674} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6683} +\noindent\mdline{6683}This P4 Value Set declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={6686} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6687} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6714} +\noindent\mdline{6714}A P4Runtime client can set the membership for this Value Set with \mdline{6714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6714} +messages similar to this one:%mdk + +%mdk-data-line={6717} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6718} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xac}~\}\\ +~~~~~~\}\\ +~~~~~~{\mdcolor{darkgreen}\#~match~for~field\_id~2~is~missing~=\textgreater{}~don't~care~match}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xdc}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~~~ternary~\{~value:~{\mdcolor{purple}0x88}~mask:~{\mdcolor{purple}8}f~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6752} +\subsection{\mdline{6752}A.4.\hspace*{0.5em}\mdline{6752}Guidelines for Implementations}\label{sec-guidelines-for-implementations}%mdk%mdk + +%mdk-data-line={6754} +\noindent\mdline{6754}This section contains practical advice for implementing P4Runtime clients and +servers.%mdk + +%mdk-data-line={6757} +\subsubsection{\mdline{6757}A.4.1.\hspace*{0.5em}\mdline{6757}gRPC Metadata Maximum Size}\label{sec-grpc-metadata-maximum-size}%mdk%mdk + +%mdk-data-line={6759} +\noindent\mdline{6759}In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the \mdline{6760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6760} gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the \mdline{6761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6761} P4Runtime RPC. The \mdline{6761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6761} RPC +returns an individual error for every item in a batch (see Section +\mdline{6763}\mdref{sec-write-rpc}{12}\mdline{6763}), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +\mdline{6765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{6765} error, without any of the individual errors.%mdk + +%mdk-data-line={6767} +\mdline{6767}To fix this problem, one can set the \mdline{6767}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6767} option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it\mdline{6769}'\mdline{6769}s +limit, as only the receiving side\mdline{6770}'\mdline{6770}s limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every \mdline{6772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{6772}, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +\mdline{6774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}8192~+~MAX\_UPDATES\_PER\_WRITE~*~100}}}\mdline{6774} bytes of metadata.%mdk + +%mdk-data-line={6776} +\mdline{6776}For example, in C++, one can create a client channel as follows:%mdk + +%mdk-data-line={6777} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6778} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}~=~{\mdcolor{purple}100};\\ +::{\mdcolor{navy}grpc::}ChannelArguments~arguments;\\ +arguments{\bfseries{\mdcolor{navy}.}}SetInt({\mdcolor{teal}GRPC\_ARG\_MAX\_METADATA\_SIZE},~{\mdcolor{purple}8192}~+~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}*{\mdcolor{purple}100});\\ +{\bfseries{\mdcolor{navy}return}}~{\mdcolor{navy}grpc::}CreateCustomChannel(address,~credentials,~arguments);}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6784} +\subsubsection{\mdline{6784}A.4.2.\hspace*{0.5em}\mdline{6784}gRPC Server Maximum Receive Message Size}\label{sec-grpc-server-maximum-receive-message-size}%mdk%mdk + +%mdk-data-line={6786} +\noindent\mdline{6786}At the time of writing, the default maximum receive message size in gRPC is 4MB +\mdline{6787}\textemdash{}\mdline{6787} while the default maximum send message size is unlimited. This can be a +problem for the \mdline{6788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{6788} RPC, since for some targets the +binary \mdline{6789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6789} can exceed 4MB, in which case by default the P4Runtime +server would return an \mdline{6790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6790} error. To a lesser extent, this may +affect the \mdline{6791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6791} RPC as well, in case of extremely large batches.%mdk + +%mdk-data-line={6793} +\mdline{6793}To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of \mdline{6795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6795} for their target(s). This can be done by +setting the \mdline{6796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_receive\_message\_length}}}\mdline{6796} when building the gRPC server.%mdk + +%mdk-data-line={6798} +\mdline{6798}For example, in C++, one can set the maximum receive message size as follows:%mdk + +%mdk-data-line={6799} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6800} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE}~=~{\mdcolor{purple}128}~*~{\mdcolor{purple}1024}~*~{\mdcolor{purple}1024};~~{\mdcolor{darkgreen}//~128MB}\\ +::{\mdcolor{navy}grpc::}ServerBuilder~server\_builder;\\ +builder{\bfseries{\mdcolor{navy}.}}AddListeningPort({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});\\ +builder{\bfseries{\mdcolor{navy}.}}RegisterService({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});~~{\mdcolor{darkgreen}//~register~P4Runtime~service}\\ +builder{\bfseries{\mdcolor{navy}.}}SetMaxReceiveMessageSize({\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE});\\ +builder{\bfseries{\mdcolor{navy}.}}BuildAndStart();}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6808} +\noindent\mdline{6808}On the client side, we recommend that P4Runtime clients do not use \mdline{6808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6808} +batches larger than the default maximum receive message size (4MB)\mdline{6809} \mdline{6809}\textemdash{}\mdline{6809} in case +the server did not deem necessary to increase the default value\mdline{6810} \mdline{6810}\textemdash{}\mdline{6810}, unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB).%mdk + +%mdk-data-line={6815} +\subsection{\mdline{6815}A.5.\hspace*{0.5em}\mdline{6815}P4Runtime Entries files}\label{sec-entries-files}%mdk%mdk + +%mdk-data-line={6817} +\noindent\mdline{6817}The open source P4 compiler \mdline{6817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{6817}~[\mdcite{p4c}{15}]\mdline{6817} implements an option to +generate an \mdline{6818}\textquotedblleft{}entries file\textquotedblright{}\mdline{6818}, \mdline{6818}i.e.\mdline{6818} a file that contains all table +entries declared via the \mdline{6819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{6819} table property within the program.%mdk + +%mdk-data-line={6821} +\mdline{6821}An example P4\mdline{6821}\mdsub{16}\mdline{6821} program that can be used to demonstrate this +capability is \mdline{6822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table-entries-ternary-bmv2.p4}}}\mdline{6822}~[\mdcite{p4ctestprogramforconstentries}{16}]\mdline{6822}:%mdk +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}git~clone~https://github.com/p4lang/p4c\\ +cd~p4c/testdata/p4\_16\_samples\\ +mkdir~tmp\\ +p4test~--arch~v1model~\textbackslash{}\\ +\preindent{4}--p4runtime-files~tmp/p4info.txt~\textbackslash{}\\ +\preindent{4}--p4runtime-entries-files~tmp/entries.txt~\textbackslash{}\\ +\preindent{4}table-entries-ternary-bmv2.p4}}%mdk +\end{mdpre}\noindent\mdline{6832}You can replace the \mdline{6832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}.txt}}}\mdline{6832} suffix of the file name \mdline{6832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tmp/entries.txt}}}\mdline{6832} +in the example command above with \mdline{6833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}.json}}}\mdline{6833} or \mdline{6833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}.bin}}}\mdline{6833}. The \mdline{6833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}.bin}}}\mdline{6833} +format is a binary P4Runtime API protobuf message format. The \mdline{6834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}.txt}}}\mdline{6834} +format is the text encoding of the same Protobuf messages. + +%mdk-data-line={6837} +\mdline{6837}Target devices are \mdline{6837}\emph{not}\mdline{6837} required to use this file. For example, if a +target has a P4 compiler back end that encodes all of the necessary +details from the P4 source program, including the \mdline{6839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{6839} of tables, +in a target-specific binary format, then that target might have no +reason to generate these entries files.%mdk + +%mdk-data-line={6843} +\mdline{6843}Some target devices might choose to generate entries files, and also +to require doing so in order to have a correct implementation. For +example, a target runtime implementation might take a target-specific +binary format for the compiled P4 program that does \mdline{6846}\emph{not}\mdline{6846} contain any +data describing the \mdline{6847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{6847} of tables, plus the entries file +generated by \mdline{6848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{6848}, and use the entries file to load the initial +entries of tables into the device.%mdk + +%mdk-data-line={6851} +\mdline{6851}The format of the entries file is a single \mdline{6851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6851} message +containing one \mdline{6852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{6852} sub-message per entry in the P4 source program +defined via an \mdline{6853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{6853} table property. All \mdline{6853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{6853} sub-messages +have \mdline{6854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6854} equal to \mdline{6854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{6854}, and \mdline{6854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{6854} is a \mdline{6854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{6854} message +containing the data for one table entry.%mdk + +%mdk-data-line={6857} +\mdline{6857}Note that if a P4Runtime client attempted to send a \mdline{6857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6857} to +a P4Runtime server with the contents of the entries file, the server +must return an error for each entry that has \mdline{6859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const}}}\mdline{6859} true, as +described in Section\mdline{6860}~\mdref{sec-table-entry}{9.1}\mdline{6860}.%mdk + +%mdk-data-line={6862;build/P4Runtime-Spec-bib.bbl.mdk:1} +%mdk-data-line={6862;build/P4Runtime-Spec-bib.bbl.mdk:2} +\mdsetrefname{References}%mdk +{\mdbibindent{0}%mdk +\begin{thebibliography}{45}%mdk +\label{sec-bibliography}%mdk + +%mdk-data-line={references.bib:78} +\bibitem{p4spec}\mdbibitemlabel{{}[1]}\textquotedblleft{}$P4_{16}$ 1.2.1 Specification.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html}}.\label{p4spec}%mdk%mdk + +%mdk-data-line={references.bib:154} +\bibitem{rfc2697}\mdbibitemlabel{{}[2]}\textquotedblleft{}A Single Rate Three Color Marker.\textquotedblright{} \href{https://tools.ietf.org/html/rfc2697}{{\ttfamily https://\hspace{0pt}tools.\hspace{0pt}ietf.\hspace{0pt}org/\hspace{0pt}html/\hspace{0pt}rfc2697}}.\label{rfc2697}%mdk%mdk + +%mdk-data-line={references.bib:149} +\bibitem{rfc2698}\mdbibitemlabel{{}[3]}\textquotedblleft{}A Two Rate Three Color Marker.\textquotedblright{} \href{https://tools.ietf.org/html/rfc2698}{{\ttfamily https://\hspace{0pt}tools.\hspace{0pt}ietf.\hspace{0pt}org/\hspace{0pt}html/\hspace{0pt}rfc2698}}.\label{rfc2698}%mdk%mdk + +%mdk-data-line={references.bib:224} +\bibitem{arenaallocation}\mdbibitemlabel{{}[4]}\textquotedblleft{}C++ Arena Allocation Guide.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/reference/arenas}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}reference/\hspace{0pt}arenas}}.\label{arenaallocation}%mdk%mdk + +%mdk-data-line={references.bib:32} +\bibitem{p4complextypes}\mdbibitemlabel{{}[5]}\textquotedblleft{}Complex Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-p4-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}p4-\hspace{0pt}type}}.\label{p4complextypes}%mdk%mdk + +%mdk-data-line={references.bib:37} +\bibitem{protodefaults}\mdbibitemlabel{{}[6]}\textquotedblleft{}Default Values for Protobuf 3 ($proto3$) Fields.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23default}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}default}}.\label{protodefaults}%mdk%mdk + +%mdk-data-line={references.bib:93} +\bibitem{p4enums}\mdbibitemlabel{{}[7]}\textquotedblleft{}Enums in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-enum-types}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}enum-\hspace{0pt}types}}.\label{p4enums}%mdk%mdk + +%mdk-data-line={references.bib:134} +\bibitem{apiversioning}\mdbibitemlabel{{}[8]}\textquotedblleft{}Google Cloud APIs Versioning.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning}}.\label{apiversioning}%mdk%mdk + +%mdk-data-line={references.bib:139} +\bibitem{apiversioningbackwardscompatibility}\mdbibitemlabel{{}[9]}\textquotedblleft{}Google Cloud APIs Versioning - Backwards-Compatibility.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning\%23backwards_compatibility}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning\#\hspace{0pt}backwards\_\hspace{0pt}compatibility}}.\label{apiversioningbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:169} +\bibitem{grpcauth}\mdbibitemlabel{{}[10]}\textquotedblleft{}gRPC Authentication.\textquotedblright{} \href{https://grpc.io/docs/guides/auth.html}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}guides/\hspace{0pt}auth.\hspace{0pt}html}}.\label{grpcauth}%mdk%mdk + +%mdk-data-line={references.bib:7} +\bibitem{grpc}\mdbibitemlabel{{}[11]}\textquotedblleft{}gRPC Main Site.\textquotedblright{} \href{https://grpc.io}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io}}.\label{grpc}%mdk%mdk + +%mdk-data-line={references.bib:164} +\bibitem{grpcstreamc}\mdbibitemlabel{{}[12]}\textquotedblleft{}gRPC Streaming RPCs in C++.\textquotedblright{} \href{https://grpc.io/docs/tutorials/basic/c.html\%23streaming-rpcs}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}tutorials/\hspace{0pt}basic/\hspace{0pt}c.\hspace{0pt}html\#\hspace{0pt}streaming-\hspace{0pt}rpcs}}.\label{grpcstreamc}%mdk%mdk + +%mdk-data-line={references.bib:129} +\bibitem{p4newtypes}\mdbibitemlabel{{}[13]}\textquotedblleft{}Introducing New Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-newtype}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}newtype}}.\label{p4newtypes}%mdk%mdk + +%mdk-data-line={references.bib:159} +\bibitem{p4matchtypes}\mdbibitemlabel{{}[14]}\textquotedblleft{}Match Types in P4.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-match-kind-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}match-\hspace{0pt}kind-\hspace{0pt}type}}.\label{p4matchtypes}%mdk%mdk + +%mdk-data-line={references.bib:229} +\bibitem{p4c}\mdbibitemlabel{{}[15]}\textquotedblleft{}P4\_16 Reference Compiler.\textquotedblright{} \href{https://github.com/p4lang/p4c}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4c}}.\label{p4c}%mdk%mdk + +%mdk-data-line={references.bib:234} +\bibitem{p4ctestprogramforconstentries}\mdbibitemlabel{{}[16]}\textquotedblleft{}P4\_16 Reference Compiler Test Program Table-Entries-Ternary-bmv2.p4.\textquotedblright{} \href{https://github.com/p4lang/p4c/blob/main/testdata/p4_16_samples/table-entries-ternary-bmv2.p4}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4c/\hspace{0pt}blob/\hspace{0pt}main/\hspace{0pt}testdata/\hspace{0pt}p4\_\hspace{0pt}16\_\hspace{0pt}samples/\hspace{0pt}table-\hspace{0pt}entries-\hspace{0pt}ternary-\hspace{0pt}bmv2.\hspace{0pt}p4}}.\label{p4ctestprogramforconstentries}%mdk%mdk + +%mdk-data-line={references.bib:214} +\bibitem{p4annotations}\mdbibitemlabel{{}[17]}\textquotedblleft{}P4 Annotations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-annotations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}annotations}}.\label{p4annotations}%mdk%mdk + +%mdk-data-line={references.bib:194} +\bibitem{p4concurrency}\mdbibitemlabel{{}[18]}\textquotedblleft{}P4 Concurrency Model.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-concurrency}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}concurrency}}.\label{p4concurrency}%mdk%mdk + +%mdk-data-line={references.bib:1} +\bibitem{p4runtimerepo}\mdbibitemlabel{{}[19]}\textquotedblleft{}p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.\textquotedblright{} \href{https://github.com/p4lang/p4runtime}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4runtime}}.\label{p4runtimerepo}%mdk%mdk + +%mdk-data-line={references.bib:42} +\bibitem{pirepo}\mdbibitemlabel{{}[20]}\textquotedblleft{}p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.\textquotedblright{} \href{https://github.com/p4lang/PI}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}PI}}.\label{pirepo}%mdk%mdk + +%mdk-data-line={references.bib:124} +\bibitem{p4apiwgcharter}\mdbibitemlabel{{}[21]}\textquotedblleft{}P4.org API Working Group Charter.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4_API_WG_charter.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4\_\hspace{0pt}API\_\hspace{0pt}WG\_\hspace{0pt}charter.\hspace{0pt}html}}.\label{p4apiwgcharter}%mdk%mdk + +%mdk-data-line={references.bib:174} +\bibitem{p4actionannotations}\mdbibitemlabel{{}[22]}\textquotedblleft{}P4 Standard Annotations on Table Actions.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-action-anno}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}action-\hspace{0pt}anno}}.\label{p4actionannotations}%mdk%mdk + +%mdk-data-line={references.bib:88} +\bibitem{pna}\mdbibitemlabel{{}[23]}\textquotedblleft{}Portable NIC Architecture Specification (v0.7).\textquotedblright{} \href{https://p4.org/p4-spec/docs/PNA-v0.7.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PNA-\hspace{0pt}v0.\hspace{0pt}7.\hspace{0pt}html}}.\label{pna}%mdk%mdk + +%mdk-data-line={references.bib:83} +\bibitem{psa}\mdbibitemlabel{{}[24]}\textquotedblleft{}Portable Switch Architecture Specification (v1.1.0).\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html}}.\label{psa}%mdk%mdk + +%mdk-data-line={references.bib:209} +\bibitem{protooneofbackwardscompatibility}\mdbibitemlabel{{}[25]}\textquotedblleft{}Protobuf OneOf Backwards-Compatibility Issues.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23backwards-compatibility-issues}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}backwards-\hspace{0pt}compatibility-\hspace{0pt}issues}}.\label{protooneofbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:12} +\bibitem{proto}\mdbibitemlabel{{}[26]}\textquotedblleft{}Protocol Buffers Main Site.\textquotedblright{} \href{https://developers.google.com/protocol-buffers}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers}}.\label{proto}%mdk%mdk + +%mdk-data-line={references.bib:179} +\bibitem{psaactionselector}\mdbibitemlabel{{}[27]}\textquotedblleft{}PSA Action Selector.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-action-selector}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}action-\hspace{0pt}selector}}.\label{psaactionselector}%mdk%mdk + +%mdk-data-line={references.bib:189} +\bibitem{psaatomicityofcontrolplaneops}\mdbibitemlabel{{}[28]}\textquotedblleft{}PSA Atomicity of Control Plane Operations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-atomicity-of-control-plane-api-operations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}atomicity-\hspace{0pt}of-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}api-\hspace{0pt}operations}}.\label{psaatomicityofcontrolplaneops}%mdk%mdk + +%mdk-data-line={references.bib:199} +\bibitem{psatranslation}\mdbibitemlabel{{}[29]}\textquotedblleft{}PSA Data Plane vs Control Plane Types.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-data-plane-vs-control-plane-values}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}data-\hspace{0pt}plane-\hspace{0pt}vs-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}values}}.\label{psatranslation}%mdk%mdk + +%mdk-data-line={references.bib:184} +\bibitem{psaemptygroupactionappendix}\mdbibitemlabel{{}[30]}\textquotedblleft{}PSA Empty Group Action Appendix.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23appendix-empty-action-selector-groups}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}appendix-\hspace{0pt}empty-\hspace{0pt}action-\hspace{0pt}selector-\hspace{0pt}groups}}.\label{psaemptygroupactionappendix}%mdk%mdk + +%mdk-data-line={references.bib:58} +\bibitem{p4selectexpr}\mdbibitemlabel{{}[31]}\textquotedblleft{}Select Expressions in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-select}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}select}}.\label{p4selectexpr}%mdk%mdk + +%mdk-data-line={references.bib:144} +\bibitem{semver}\mdbibitemlabel{{}[32]}\textquotedblleft{}Semantic Versioning.\textquotedblright{} \href{https://semver.org/}{{\ttfamily https://\hspace{0pt}semver.\hspace{0pt}org/\hspace{0pt}}}.\label{semver}%mdk%mdk + +%mdk-data-line={references.bib:113} +\bibitem{protostatus}\mdbibitemlabel{{}[33]}\textquotedblleft{}Status.proto:the Protobuf Status Message.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}src/\hspace{0pt}proto/\hspace{0pt}grpc/\hspace{0pt}status/\hspace{0pt}status.\hspace{0pt}proto}}.\label{protostatus}%mdk%mdk + +%mdk-data-line={references.bib:68} +\bibitem{p4revisions122}\mdbibitemlabel{{}[34]}\textquotedblleft{}Summary of Changes Made in $P4_{16}$ Version 1.2.2.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.4.html\%23sec-summary-of-changes-made-in-version-122-released-may-17-2021}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}4.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}summary-\hspace{0pt}of-\hspace{0pt}changes-\hspace{0pt}made-\hspace{0pt}in-\hspace{0pt}version-\hspace{0pt}122-\hspace{0pt}released-\hspace{0pt}may-\hspace{0pt}17-\hspace{0pt}2021}}.\label{p4revisions122}%mdk%mdk + +%mdk-data-line={references.bib:73} +\bibitem{p4revisions124}\mdbibitemlabel{{}[35]}\textquotedblleft{}Summary of Changes Made in $P4_{16}$ Version 1.2.4.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.4.html\%23sec-summary-of-changes-made-in-version-124}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}4.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}summary-\hspace{0pt}of-\hspace{0pt}changes-\hspace{0pt}made-\hspace{0pt}in-\hspace{0pt}version-\hspace{0pt}124}}.\label{p4revisions124}%mdk%mdk + +%mdk-data-line={references.bib:48} +\bibitem{p4tableproperties}\mdbibitemlabel{{}[36]}\textquotedblleft{}Table Properties in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-props}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}props}}.\label{p4tableproperties}%mdk%mdk + +%mdk-data-line={references.bib:98} +\bibitem{protoany}\mdbibitemlabel{{}[37]}\textquotedblleft{}The Any Protobuf Message.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23any}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}any}}.\label{protoany}%mdk%mdk + +%mdk-data-line={references.bib:103} +\bibitem{grpcstatus}\mdbibitemlabel{{}[38]}\textquotedblleft{}The gRPC $Status$ Class.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/status.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}impl/\hspace{0pt}codegen/\hspace{0pt}status.\hspace{0pt}h}}.\label{grpcstatus}%mdk%mdk + +%mdk-data-line={references.bib:119} +\bibitem{grpcerrordetails}\mdbibitemlabel{{}[39]}\textquotedblleft{}The gRPC C++ Error Details Library.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/support/error_details.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}support/\hspace{0pt}error\_\hspace{0pt}details.\hspace{0pt}h}}.\label{grpcerrordetails}%mdk%mdk + +%mdk-data-line={references.bib:108} +\bibitem{grpcstatuscodes}\mdbibitemlabel{{}[40]}\textquotedblleft{}The gRPC Canonical Status Codes.\textquotedblright{} \href{https://developers.google.com/maps-booking/reference/grpc-api/status_codes}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}maps-\hspace{0pt}booking/\hspace{0pt}reference/\hspace{0pt}grpc-\hspace{0pt}api/\hspace{0pt}status\_\hspace{0pt}codes}}.\label{grpcstatuscodes}%mdk%mdk + +%mdk-data-line={references.bib:22} +\bibitem{openconfig}\mdbibitemlabel{{}[41]}\textquotedblleft{}The OpenConfig Project.\textquotedblright{} \href{http://openconfig.net}{{\ttfamily http://\hspace{0pt}openconfig.\hspace{0pt}net}}.\label{openconfig}%mdk%mdk + +%mdk-data-line={references.bib:204} +\bibitem{protomessagedifferencer}\mdbibitemlabel{{}[42]}\textquotedblleft{}The Protobuf MessageDifferencer in the C++ API.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.util.message_differencer}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}reference/\hspace{0pt}cpp/\hspace{0pt}google.\hspace{0pt}protobuf.\hspace{0pt}util.\hspace{0pt}message\_\hspace{0pt}differencer}}.\label{protomessagedifferencer}%mdk%mdk + +%mdk-data-line={references.bib:27} +\bibitem{stratum}\mdbibitemlabel{{}[43]}\textquotedblleft{}The Stratum Project.\textquotedblright{} \href{https://stratumproject.org/}{{\ttfamily https://\hspace{0pt}stratumproject.\hspace{0pt}org/\hspace{0pt}}}.\label{stratum}%mdk%mdk + +%mdk-data-line={references.bib:219} +\bibitem{v1model}\mdbibitemlabel{{}[44]}\textquotedblleft{}v1model Architecture Definition.\textquotedblright{} \href{https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4c/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}p4include/\hspace{0pt}v1model.\hspace{0pt}p4}}.\label{v1model}%mdk%mdk + +%mdk-data-line={references.bib:53} +\bibitem{p4valuesets}\mdbibitemlabel{{}[45]}\textquotedblleft{}Value Sets in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-value-set}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}value-\hspace{0pt}set}}.\label{p4valuesets}%mdk%mdk +\par%mdk +\end{thebibliography}}%mdk%mdk +}%mdk + + +\end{document} diff --git a/spec/main/ellipse.sty b/spec/main/ellipse.sty new file mode 100644 index 00000000..7c0ecb3e --- /dev/null +++ b/spec/main/ellipse.sty @@ -0,0 +1,318 @@ +%% +%% This is file `ellipse.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ellipse.dtx (with options: `package') +%% +%% Copyright (C) 2015 +%% Daan Leijen +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". +%% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{ellipse} + [2004/11/05 v1.0 .dtx ellipse file] +\RequirePackage{pict2e} + +\providecommand*\pIIe@csedef[1]{\expandafter\edef\csname #1\endcsname} +\newcommand*\pIIe@ellip@csqrt[3]{% + \@ovxx=#1\relax + \ifdim\@ovxx<\z@\@ovxx-\@ovxx\fi + \@ovyy=#2\relax + \ifdim\@ovyy<\z@\@ovyy-\@ovyy\fi + \edef\pIIe@csname{@csqrt(\number\@ovxx,\number\@ovyy)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@ellip@csqrt@% + \pIIe@csedef{\pIIe@csname}{\the\dimen@}% + #3\dimen@ + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} +\newcommand*\pIIe@ellip@csqrt@{% + \@ovdx\@ovxx + \advance\@ovdx by \@ovyy + \dimen@0.7071067\@ovdx + \ifdim\dimen@<\@ovyy\dimen@\@ovyy\fi + \ifdim\dimen@<\@ovxx\dimen@\@ovxx\fi + \ifdim\@ovdx<128\p@ + \edef\@tempa{\strip@pt\@ovxx}% + \@ovxx\@tempa\@ovxx + \edef\@tempa{\strip@pt\@ovyy}% + \@ovyy\@tempa\@ovyy + \advance\@ovxx by \@ovyy + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \fi +} + +\newcommand*\pIIe@atan@{% + \@tempdima\dimen@ + \@tempdimb\@tempdima + \ifdim\@tempdimb<\z@\@tempdimb-\@tempdimb\fi + \dimen@0.0663\@tempdimb + \advance\dimen@ 0.2447pt\relax + \advance\@tempdimb -1pt\relax + \edef\@tempa{\strip@pt\@tempdimb}% + \dimen@\@tempa\dimen@ + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \dimen@-\dimen@ + \advance\dimen@ 0.7853\@tempdima +} + +\newcommand*\pIIe@atantwo[3]{% + \edef\pIIe@csname{@atan2(\number\dimexpr#1\relax,\number\dimexpr#2\relax)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@atantwo@{#1}{#2}{#3}% + \pIIe@csedef{\pIIe@csname}{\the\dimexpr#3\relax}% + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} + +\newcommand*\pIIe@atantwo@[3]{% + \@tempdima\dimexpr#2\relax + \@tempdimb\dimexpr#1\relax + \ifdim\@tempdima=\z@\relax + \ifdim\@tempdimb>\z@\relax\dimen@90\p@ + \else\ifdim\@tempdimb<\z@\relax\dimen@-90\p@ + \else\dimen@0\p@ + \fi\fi + \else + \@tempdimd\z@ + \ifdim\@tempdima<\z@\relax + \ifdim\@tempdimb<\z@\relax\@tempdimd-180\p@ + \else\@tempdimd180\p@ + \fi + \fi + \dimen@\dimexpr1pt * \@tempdimb/\@tempdima\relax + \@tempdimc\dimen@ + \ifdim\@tempdimc<\z@\relax\@tempdimc-\@tempdimc\fi + \ifdim\@tempdimc>\p@\relax + \dimen@\dimexpr1pt * \@tempdima/\@tempdimb\relax + \ifdim\dimen@<\z@\relax\def\@tempsign{-}\else\def\@tempsign{}\fi + \pIIe@atan@ + \dimen@-\dimen@ + \advance\dimen@ by \@tempsign1.5707pt\relax + \else + \pIIe@atan@ + \fi + \dimen@57.29578\dimen@ + \advance\dimen@ by \@tempdimd + \fi + #3\dimen@% +} + +\newcommand*\pIIe@noneto[2]{} +\newcommand*\pIIe@ellip@sincost@[2]{% + \CalculateSin{#1}% + \CalculateCos{#1}% + \@tempdima\UseSin{#1}\p@ + \@tempdimb\UseCos{#1}\p@ + \ifdim\@tempdima=\p@\relax + \pIIe@csedef{@ellipsin#2}{1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else\ifdim\@tempdima=-\p@\relax + \pIIe@csedef{@ellipsin#2}{-1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else + \@tempdimc\@ellipratio\dimexpr1pt * \@tempdima/\@tempdimb\relax + %\typeout{ i#2=\the\@tempdimc, sin(#1)=\the\@tempdima}% + \pIIe@ellip@csqrt{\p@}{\@tempdimc}\@tempdimd + \ifdim\@tempdimb<\z@\relax\@tempdimd-\@tempdimd\fi + \pIIe@csedef{@ellipsin#2}{\strip@pt\dimexpr1pt * \@tempdimc/\@tempdimd\relax}% + \pIIe@csedef{@ellipcos#2}{\strip@pt\dimexpr1pt * \p@/\@tempdimd\relax}% + \fi\fi +} + +\newcommand*\pIIe@ellip@sincost[2]{% + %\typeout{ calc sin cos: angles (#1,#2), radii: (\the\@ovro,\the\@ovri)}% + \edef\@ellipratio{\strip@pt\dimexpr1pt * \@ovro/\@ovri\relax}% + \pIIe@ellip@sincost@{#1}{one}% + \pIIe@ellip@sincost@{#2}{two}% + %\typeout{ sincos(a=#1)=(\@ellipsinone,\@ellipcosone), sincos(a=#2)=(\@ellipsintwo,\@ellipcostwo), }% +} +\newcommand*\pIIe@omega[3]{% + \@tempdima\csname @ellipcos#3\endcsname\@ovro + \advance\@tempdima by #1\relax + \@tempdimb\csname @ellipsin#3\endcsname\@ovri + \advance\@tempdimb by #2\relax +} + +\newcommand*\pIIe@omegai[1]{% + \@tempdimc\csname @ellipsin#1\endcsname\@ovro + \@tempdimc-\@tempdimc + \@tempdimd\csname @ellipcos#1\endcsname\@ovri +} + +\newcommand*\pIIe@ellip@kappa{% + \@ovyy\@ellipsinone\p@ + \@ovxx\@ellipcosone\p@ + \@tempdima\@ellipcostwo\@ovyy + \@tempdima-\@tempdima + \advance\@tempdima by \@ellipsintwo\@ovxx + \@tempdimb\@ellipcostwo\@ovxx + \advance\@tempdimb by \@ellipsintwo\@ovyy + \ifdim\@tempdima=\z@\relax + \edef\@ellipkappa{0}% + \else + \dimen@\dimexpr1pt - \@tempdimb\relax + \dimen@\dimexpr1pt * \dimen@/\@tempdima\relax + \pIIe@ellip@csqrt{2\p@}{1.73205\dimen@}{\dimen@}% + \advance\dimen@ by -\p@ + \divide\dimen@ by 3% + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \edef\@ellipkappa{\strip@pt\dimen@}% + \fi + %\typeout{ calculated kappa: \@ellipkappa}% +} + +\newcommand*\pIIe@elliparc@[5]{% + %\typeout{elliparc: #1, center: (#2, #3), radius (\the\@ovro, \the\@ovri),angle (#4, #5)}% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \pIIe@ellip@sincost{#4}{#5}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@t[5]{% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \CalculateSin{#4}\CalculateCos{#4}% + \edef\@ellipsinone{\UseSin{#4}}% + \edef\@ellipcosone{\UseCos{#4}}% + \CalculateSin{#5}\CalculateCos{#5}% + \edef\@ellipsintwo{\UseSin{#5}}% + \edef\@ellipcostwo{\UseCos{#5}}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@draw[2]{% + \pIIe@ellip@kappa% + \pIIe@omega{#1}{#2}{one}% + %\typeout{ point one: (\the\@tempdima,\the\@tempdimb)}% + \@ellip@startto\@tempdima\@tempdimb + \pIIe@omegai{one}% + \advance\@tempdima by \@ellipkappa\@tempdimc + \advance\@tempdimb by \@ellipkappa\@tempdimd + \pIIe@add@nums\@tempdima\@tempdimb + %\typeout{ control one: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@omega{#1}{#2}{two}% + \pIIe@omegai{two}% + \@tempdimc\@ellipkappa\@tempdimc + \@tempdimd\@ellipkappa\@tempdimd + \@tempdimc-\@tempdimc + \@tempdimd-\@tempdimd + \advance\@tempdimc by \@tempdima + \advance\@tempdimd by \@tempdimb + \pIIe@add@nums\@tempdimc\@tempdimd + %\typeout{ control two: (\the\@tempdimc,\the\@tempdimd)}% + \pIIe@add@CP\@tempdima\@tempdimb + %\typeout{ point two: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@addtoGraph\pIIe@curveto@op +} +\newcommand*\pIIe@elliparc[7][0]{% + \@ovro #4\relax + \@ovri #5\relax + \iffalse%dim\@ovro=\@ovri + \pIIe@arc[#1]{#2}{#3}{#4}{#6}{#7} + \else + \ifdim \@ovro<\z@ \pIIe@badcircarg\else + \ifdim \@ovri<\z@ \pIIe@badcircarg\else + \@arclen #7\p@ \advance\@arclen -#6\p@ + \ifdim \@arclen<\z@ \def\@tempsign{-}\else\def\@tempsign{}\fi + \ifdim \@tempsign\@arclen>720\p@ + \PackageWarning {ellipse}{The arc angle is reduced to -720..720}% + \@whiledim \@tempsign\@arclen>720\p@ \do {\advance\@arclen-\@tempsign360\p@}% + \@tempdima #6\p@ \advance\@tempdima \@arclen + \edef\@angleend{\strip@pt\@tempdima}% + \pIIe@@elliparc{#1}{#2}{#3}{#6}{\@angleend}% + \else + \pIIe@@elliparc{#1}{#2}{#3}{#6}{#7}% + \fi + \fi + \fi + \fi +} +\newcommand*\pIIe@@elliparc[5]{% + \begingroup + \ifdim \@tempsign\@arclen>90\p@ + \divide\@arclen 2% + \@tempdima #4\p@\advance\@tempdima by \@arclen + \edef\@anglemid{\strip@pt\@tempdima}% + \def\@tempa{\pIIe@@elliparc{#1}{#2}{#3}{#4}}% + \expandafter\@tempa\expandafter{\@anglemid}% + \def\@tempa{\pIIe@@elliparc{2}{#2}{#3}}% + \expandafter\@tempa\expandafter{\@anglemid}{#5}% + \else + \pIIe@elliparc@{#1}{#2}{#3}{#4}{#5}% + \fi + \endgroup +}% + +\newcommand*\pIIeelliparc[7][0]{% + \@killglue + \pIIe@elliparc[#1]{#2\unitlength}{#3\unitlength}{#4\unitlength}{#5\unitlength}{#6}{#7}% + \ignorespaces% +} +\ifx\undefined\elliparc\else + \PackageWarning{ellipse}{\protect\elliparc\space is redefined}% +\fi +\let\elliparc\pIIeelliparc + +\newcommand*\pIIeearc + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\newcommand*\pIIe@earc@[3][0,360]{\pIIe@earc@@(#1){#2}{#3}} +\def\pIIe@earc@@(#1,#2)#3#4{% + \if@tempswa + \pIIe@moveto\z@\z@ + \pIIe@elliparc{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@closepath\pIIe@fillGraph + \else + \pIIe@elliparc[1]{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@strokeGraph + \fi} +\ifx\undefined\earc\else + \PackageWarning{ellipse}{\protect\earc\space is redefined}% +\fi +\let\earc\pIIeearc + +\newcommand*\pIIeellipse + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\let\ellipse\pIIeellipse + +\endinput +%% +%% End of file `ellipse.sty'. diff --git a/spec/main/embedded-plus-single-remote-controller.png b/spec/main/embedded-plus-single-remote-controller.png new file mode 100644 index 00000000..2e0f1803 Binary files /dev/null and b/spec/main/embedded-plus-single-remote-controller.png differ diff --git a/spec/main/embedded-plus-single-remote-controller.svg b/spec/main/embedded-plus-single-remote-controller.svg new file mode 100644 index 00000000..9fe2ce9c --- /dev/null +++ b/spec/main/embedded-plus-single-remote-controller.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spec/main/embedded-plus-two-remote-controllers.png b/spec/main/embedded-plus-two-remote-controllers.png new file mode 100644 index 00000000..b6dc04fc Binary files /dev/null and b/spec/main/embedded-plus-two-remote-controllers.png differ diff --git a/spec/main/embedded-plus-two-remote-controllers.svg b/spec/main/embedded-plus-two-remote-controllers.svg new file mode 100644 index 00000000..0f97ba38 --- /dev/null +++ b/spec/main/embedded-plus-two-remote-controllers.svg @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + + + Entities + + + + + + + \ No newline at end of file diff --git a/spec/main/embedded-plus-two-remote-ha-controllers.png b/spec/main/embedded-plus-two-remote-ha-controllers.png new file mode 100644 index 00000000..392f8963 Binary files /dev/null and b/spec/main/embedded-plus-two-remote-ha-controllers.png differ diff --git a/spec/main/embedded-plus-two-remote-ha-controllers.svg b/spec/main/embedded-plus-two-remote-ha-controllers.svg new file mode 100644 index 00000000..97ab6fc3 --- /dev/null +++ b/spec/main/embedded-plus-two-remote-ha-controllers.svg @@ -0,0 +1,511 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + Primary (Active) + + + + + + Backup (Standby) + + + + + + + \ No newline at end of file diff --git a/spec/main/error-report.png b/spec/main/error-report.png new file mode 100644 index 00000000..766cb77f Binary files /dev/null and b/spec/main/error-report.png differ diff --git a/spec/main/error-report.svg b/spec/main/error-report.svg new file mode 100644 index 00000000..a2709a72 --- /dev/null +++ b/spec/main/error-report.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StatusCode error_code_; // canonical error codestring error_message_;string binary_error_details_; // serialized google.rpc.Status + + + + + + + + + + + + + google.rpc.Status + + + + + + int32 error_code; // canonical error codestring message;repeated Any details; // P4Error + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + + + p4.Error + + + + + + p4.Error + + + + + + + + + + + + + + + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + grpc::Status + + + + + + + \ No newline at end of file diff --git a/spec/main/longbox.sty b/spec/main/longbox.sty new file mode 100644 index 00000000..cab48934 --- /dev/null +++ b/spec/main/longbox.sty @@ -0,0 +1,853 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longbox}[2015/12/01, Daan Leijen, Provides basic longbox that can break over pages] +\RequirePackage{options} + +\@ifclassloaded{beamer}{% + \newcommand\lb@savefootnotes{}% + \newcommand\lb@restorefootnotes{}% +}% +{\RequirePackage{footnote}% + \newcommand\lb@savefootnotes{\savenotes}% + \newcommand\lb@restorefootnotes{\spewnotes}% +} + + +% -------------------------------------------------------- +% Debugging +% -------------------------------------------------------- + +\newcommand*\lb@debug[1]{% + \ontoggle{lb@debug}{\typeout{longbox debug: #1}}% +} +\newcommand*\lb@typeout[1]{% + \ontoggle{lb@verbose}{\typeout{longbox: #1}}% +} +\newcommand*\lb@warncannotsplit{% + \PackageWarning{longbox}{Cannot split box; it seems you are using a non-splittable contents}% +} +\newcommand*\lb@warnbadsplit[1]{% + \PackageWarning{longbox}{Bad split (underful vbox by \the#1)}% +} + + +% -------------------------------------------------------- +% Utilities for LaTeX internals +% -------------------------------------------------------- + +% Suppress the indentation on the following paragraph +\providecommand\nofirstindent{\@afterindentfalse\@afterheading} + +% Suppress the paragraph skip on the following paragraph +\providecommand\nofirstparskip{\addvskip{-\parskip}} + +% In contrast to addvspace, addvskip is not suppressed in a minipage +\providecommand\addvskip[1]{% + \ifvmode + \ifdim\lastskip=\z@ + \vskip #1\relax + \else + \@tempskipb#1\relax\@xaddvskip + \fi + \else\@noitemerr\fi +} + + +% Skip to 0.3\baselineskip multiple taking prevdepth into account. +\newskip\lb@prevdepth +\newcommand\lb@skiptobaseline{% + \global\lb@prevdepth=-\@m\p@\relax + \ifvmode + \ifdim\lastskip=\z@\relax + \ifdim\prevdepth=-\@m\p@\else + \dimen@\prevdepth + % Calculate the modulus of the previous depth with 0.3|\baselineskip| in |\dimen@|. + \@tempcnta\prevdepth + \@tempskipa=0.3\baselineskip\relax + \@tempcntb=\@tempskipa\relax + \divide \@tempcnta by \@tempcntb + \dimen@\prevdepth + \advance\dimen@ -\@tempcnta\@tempskipa + % Skip back by that amount, and then skip by 0.3|\baselineskip|. + \vskip -\dimen@ + \vskip \@tempskipa\relax + \global\lb@prevdepth=\@tempskipa\relax + \fi + \fi + \fi +} + +% unvbox a box, and return a vbox with a given background color +% \unvcolorbox{}{} +\newcommand\unvcolorbox[2]{% + \ifoptionblank{#1}{\vbox{\unvbox#2}}{% + \lb@debug{vcolorbox: #1}% + \vbox{\offinterlineskip + \hbox to \z@{\vbox to \z@{\optioncolor{#1}\hrule\@width\wd#2\@height\ht#2\@depth\dp#2\vss}\hss}% + \unvbox#2% + }% + }% +} + +% create a vbox with a given background color +\newcommand\vcolorbox[2]{% + \eifblank{#1}{\vbox{#2}}{% + \setbox\z@=\vbox{#2}\relax + \unvcolorbox{#1}{\z@}% + }% +}% + +% -------------------------------------------------------- +% The following macros come from mdframed +% -------------------------------------------------------- + +% Determine the amount of free space left on the current page +\newlength\lb@freevspace +\newcommand*\lb@setfreevspace@page{% + \lb@debug{ determine free space}% + \bgroup\@nobreakfalse\addpenalty\z@\egroup% + \penalty\@M\relax\vskip 2\baselineskip\relax% + \penalty9999\relax\vskip -2\baselineskip\relax% + \penalty9999% + \ifdim\pagegoal=\maxdimen\relax% + \lb@freevspace=\vsize% + \else + \lb@freevspace=\dimexpr\pagegoal-\pagetotal-\parskip\relax% + \fi + \lb@debug{free space: \the\lb@freevspace, in page: \the\textheight, vsize=\the\vsize}% +} + +\newcommand*\lb@shiftdim[2]{% + %\letoption{#1}\lb@list + \expandafter\lb@setheadtail@#1,\relax + \eifblank{\lb@head}{}{\option@invoke{/longbox/@breakat-previous}{\lb@head}}% + #2\option{/longbox/@breakat-previous}% + \eifblank{\lb@tail}{}{\let#1\lb@tail}% push back tail +} +\def\lb@comma{,}% +\def\lb@setheadtail@#1,#2\relax{% + \def\lb@head{#1}% + \def\lb@tail{#2}% adds commas! +} + +\newcommand*\lb@setfreevspace{% + \eifblank{\lb@breakat}{\lb@setfreevspace@page}{% + \def\lb@eject{\par}%no eject + \lb@extrasplit=\z@\relax% + \lb@shiftdim{\lb@breakat}\lb@freevspace + \ifdim\lb@freevspace>\z@\else\lb@setfreevspace@page\fi + }% +} + + +% Suppress overfull-underfull vbox messages +\newcommand*\lb@ignorevbadness{% + \edef\lb@currentvbadness{\the\vbadness}% + \edef\lb@currentvfuzz{\the\vfuzz}% + \vbadness=\@M\relax% + \vfuzz=\maxdimen\relax% + \afterassignment\lb@restorevbadness +} +\newcommand*\lb@restorevbadness{% + \vbadness=\lb@currentvbadness\relax + \vfuzz=\lb@currentvfuzz\relax +} + + +% -------------------------------------------------------- +% The 'long vbox' (lvbox) environment collects long material +% into a long \vbox, instead of a \hbox like a lrbox in latex. +% The collected box can contain any box, minipage, lrbox, fbox etc, +% but not outer-par material like a figure. Footnotes can be +% dealt with useing lb@savefootnotes. +% +% The material is typeset in a \vbox according to a given width. +% inside the environment, the boolean 'inlvbox' is true. +% +% \begin{lvbox}{}{} +% -------------------------------------------------------- + +\newif\ifinlvbox +\newcommand\lvbox[4]{% + \setbox#1\vbox\bgroup + \begingroup + \inlvboxtrue + % reset defaults + \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\par\@@par + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + % set margin and linewidth + \leftmargin=#2\relax\rightmargin=#4\relax + \@totalleftmargin=\leftmargin% + %\leftskip=#2\relax\rightskip=#4\relax\@rightskip=#4\relax + \linewidth=#3\relax + % set primitive tex margins + \leftskip=\@totalleftmargin% + \rightskip=\rightmargin% + \@rightskip=\rightmargin% + \hsize=\dimexpr\@totalleftmargin+\linewidth+\rightmargin\relax + \columnwidth\hsize + \textwidth\hsize + \nofirstindent + %\nofirstparskip +} +\def\endlvbox{\endgroup\egroup} + + + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + + +\newsavebox\lb@headbox +\newsavebox\lb@savebox +\newsavebox\lb@mainbox + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@setbaseline[1]{% + %\typeout{ set baseline, \the\dp#1,\the\ht#1}% + \ifcase\lb@baseline% + \relax%bottom + \or%middle + \setbox#1=\vbox{\hbox{\lower \dimexpr(\dp#1 + \ht#1)/2 - \dp#1\relax\vbox{\unvbox#1}}}% + \or%top + \setbox#1=\vtop{\unvbox#1}% + \fi + %\typeout{ .new dim: \the\dp#1, \the\ht#1}% +} + + +\@ifundefined{define@key}{}% + {\define@key{longbox}{options}{\options{#1}\option{/longbox/adjust-options}}}% + +\newcommand*\lb@render@breakbox{% + %\typeout{render breakbox entry (in output routine), height=\the\bb@height}% + \bb@restorekeys{longbox}% + \lb@skiptop=\ifbb@isfirst\option{/longbox/skip-top}\else\option{/longbox/skip-break-top}\fi\relax + \lb@skipbottom=\ifbb@islast\option{/longbox/skip-bottom}\else\option{/longbox/skip-break-bottom}\fi\relax + \lb@skipbreaktop=\ifbb@isfirst 0pt\else\option{/longbox/skip-break-top}\fi + \lb@skipbreakbottom=\ifbb@islast 0pt\else\option{/longbox/skip-break-bottom}\fi + %\typeout{ render: skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom, break-top=\the\dimexpr\option{/longbox/skip-bottom}}% + \options{% + /longbox/@part-height=\bb@height + \lb@skipbreaktop + \lb@skipbreakbottom, + /longbox/@part-width=\option{/longbox/width} + \option{/longbox/skip-left} + \option{/longbox/skip-right},%\bb@width, + /longbox/@part-depth=0pt, + /longbox/@part-needtop=\ifbb@isfirst true\else false\fi, + /longbox/@part-needbottom=\ifbb@islast true\else false\fi, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-depth=\option{/longbox/@part-depth}, + }% + %\typeout{breakbox: width=\expandafter\the\option{/longbox/width}, \the\bb@width, \the\dimexpr\option{/longbox/@part-width}}% + \vbox{% + \kern -\lb@skipbreaktop% todo: move to breakbox? + \option{/longbox/render}% + \kern -\lb@skipbreakbottom + }% +} + +\newcommand*\lb@render@vbox[1]{% + \lb@debug{render vbox entry}% + \lb@restoreoptions + \lb@skiptop=\dimexpr\iftoggle{/longbox/@part-needtop}{\option{/longbox/skip-top}}{\option{/longbox/skip-break-top}}\relax + \lb@skipbottom=\dimexpr\iftoggle{/longbox/@part-needbottom}{\option{/longbox/skip-bottom}}{\option{/longbox/skip-break-bottom}}\relax + %\typeout{ skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom}% + % add top skip while maintaining the baseline. + \ifdim\lb@skiptop=\z@\relax\else + \setbox\z@=\vtop{\unvcopy#1}% + \dimen@=\ht\z@ + \setbox#1=\vbox{\offinterlineskip + \hrule width \z@ height \dimexpr\dimen@ + \lb@skiptop\relax depth -\dimen@ + \unvbox#1% + }% + \fi + % add bottom skip while maintaining the baseline. + \ifdim\lb@skipbottom=\z@\relax\else + \dimen@=\dp#1% + \setbox#1=\vbox{\offinterlineskip\unvbox#1\hrule width \z@ height -\dimen@ depth \dimexpr\dimen@ + \lb@skipbottom\relax}% + \fi + \lb@setbaseline{#1}% + \options{% + /longbox/@part-height=\dimexpr\ht#1 + \dp#1\relax, + /longbox/@part-width=\dimexpr\wd#1 + \option{/longbox/skip-left} + \option{/longbox/skip-right}\relax, + /longbox/@part-depth=\dp#1, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-depth=\option{/longbox/@part-depth} - \lb@skipbottom, + }% + %\typeout{ longbox: height=\the\dimexpr\option{/longbox/@content-box-height}, outer height=\the\dimexpr\option{/longbox/@part-height}\relax}% + % lower the box depending on vertical alignment + \ifcase\option{/longbox/vertical-align/@ord}\relax + \@tempdima\z@ + \or + %bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%middle + \@tempdima\dimexpr0.5\option{/longbox/@part-height} - \option{/longbox/@part-depth}\relax + \or%top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%text-bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%text-top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%super + \@tempdima=-0.9ex% + \or%sub + \@tempdima=0.7ex% + \else + \@tempdima\z@ + \fi + \advance\@tempdima by -\option{/longbox/raise}% + \option@invoke{/longbox/@lower}{\@tempdima}% + \noindent\hbox{\lower \@tempdima\vbox{\offinterlineskip + \hbox to \z@{% + \vbox to \z@{% + \hbox{\lower \option{/longbox/@part-height}\vbox{\offinterlineskip{\option{/longbox/render}}}}% + \vss}% + \hss + }% + \hbox{% + \ifdim\option{/longbox/skip-left}=\z@\else\hskip\option{/longbox/skip-left}\fi + \box#1% + \ifdim\option{/longbox/skip-right}=\z@\else\hskip\option{/longbox/skip-right}\fi + %$\box#1% + }% + }}% +} + +\newcommand*\lb@single@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} +\newcommand*\lb@first@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@middle@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@last@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand*\lb@env@start{% + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore +} + +\newcount\lb@usevbox +\newlength\lb@width +\newlength\lb@height +\newlength\lb@skiptop +\newlength\lb@skipright +\newlength\lb@skipbottom +\newlength\lb@skipleft +\newlength\lb@skipbreaktop +\newlength\lb@skipbreakbottom +\newlength\lb@outerwidth +\newlength\lb@extrasplit +\newcount\lb@textalign +\newcount\lb@baseline +\newtoggle{lb@baselineskip}% +\newtoggle{lb@breakable}% +\newtoggle{lb@debug}% +\newtoggle{lb@verbose}% +\def\lb@breakat{}% +\def\lb@halign{}% +\def\lb@eject{}% +\def\lb@insertafter{} +\def\lb@insertbefore{} + +\newcommand*\lb@peekoptions[1]{% + % process options inside a group and just set necessary parameters + % this way, nested boxes don't influence each other's parameters + \begingroup + \options{#1}% + \option{/longbox/adjust-options}% + \protected@edef\lb@temp{\endgroup + \lb@width=\the\dimexpr\option{/longbox/width}\relax + \lb@height=\the\dimexpr\option{/longbox/height}\relax + \lb@textalign=\the\numexpr\option{/longbox/text-align/@ord}\relax + \lb@baseline=\the\numexpr\option{/longbox/baseline/@ord}\relax + \lb@skiptop=\the\dimexpr\option{/longbox/skip-top}\relax + \lb@skipright=\the\dimexpr\option{/longbox/skip-right}\relax + \lb@skipbottom=\the\dimexpr\option{/longbox/skip-bottom}\relax + \lb@skipleft=\the\dimexpr\option{/longbox/skip-left}\relax + \lb@skipbreaktop=\the\dimexpr\option{/longbox/skip-break-top}\relax + \lb@skipbreakbottom=\the\dimexpr\option{/longbox/skip-break-bottom}\relax + \lb@usevbox=\iftoggle{/longbox/use-vbox}{1}{0}\relax + \lb@outerwidth=\the\dimexpr\option{/longbox/outer-width}\relax + \lb@extrasplit=\the\dimexpr\option{/longbox/split-minimum}\relax + \def\noexpand\lb@insertafter{\option{/longbox/insert-after}}% + \def\noexpand\lb@insertbefore{\option{/longbox/insert-before}}% + \def\noexpand\lb@breakat{\option{/longbox/breakat}}% + \def\noexpand\lb@halign{\option{/longbox/height-align}}% + \def\noexpand\lb@eject{\option{/longbox/eject}}% + \noexpand\csname toggle\iftoggle{/longbox/baseline-skip}{true}{false}\endcsname{lb@baselineskip}% + \noexpand\csname toggle\iftoggle{/longbox/breakable}{true}{false}\endcsname{lb@breakable}% + \noexpand\csname toggle\iftoggle{/longbox/debug}{true}{false}\endcsname{lb@debug}% + \noexpand\csname toggle\iftoggle{/longbox/verbose}{true}{false}\endcsname{lb@verbose}% + }% + \lb@temp +} + +\newenvironment{longbox@env}[2]{% + % save options + \lb@peekoptions{#1,#2}% + % + \ifnum\lb@usevbox=0\relax + \lb@debug{start breakbox}% + \let\bb@render\lb@render@breakbox + \bb@savekeys{longbox}{options={#1,#2,outer-width=\the\lb@outerwidth}}% + \iftoggle{lb@baselineskip}{\typeout{**insert bskip}}{\typeout{**suppress bskip}\vskip 1pt}% + \begin{breakbox}% + \ifdim\lb@skiptop=\z@\relax\else\vspace{\lb@skiptop}\fi% + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \begin{bb@margins}{\lb@skipleft}{\dimen@}% + \else + \lb@debug{start vbox}% + \def\lb@restoreoptions{\options{#1,#2}\option{/longbox/adjust-options}}% + \lb@savefootnotes + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \lb@debug{ width=\the\lb@width, linewidth=\the\linewidth, skipleft=\the\lb@skipleft, right=\the\lb@skipright, total right=\the\dimen@}% + \iftoggle{lb@baselineskip}{\lb@skiptobaseline}{\lb@prevdepth=-\@m pt}% + \lvbox{\lb@mainbox}{0pt}{\lb@width}{0pt}%{\lb@skipleft}{\lb@width}{\lb@skipright}% + \prevdepth=\lb@prevdepth + \fi + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore + \begingroup +}{% + \par\unskip + \endgroup + \lb@insertafter + %\ifdim\lb@skipbottom=\z@\relax\else\vskip\lb@skipbottom\fi% + \ifnum\lb@usevbox=0\relax + \end{bb@margins}% + \ifdim\lb@skipbottom=\z@\relax\else\hrule width \z@ height \lb@skipbottom\fi%\vspace{\lb@skipbottom}\fi% + \iftoggle{lb@baselineskip}{}{\vskip 1sp}% + \end{breakbox}% + \lb@debug{end breakbox}% + \else + \ontoggle{lb@baselineskip}{\lb@skiptobaseline}% + \endlvbox% + \lb@debug{initial lvbox: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@processbox + %\setbox\lb@mainbox=\hbox{\lower \lb@skipbottom\vbox{\offinterlineskip\unvbox\lb@mainbox}}% + \lb@restorefootnotes + \lb@debug{end vbox}% + \fi +} + +\newcommand\longbox@cmd[3]{% + \begingroup + %\options{/options/collectunknown,/longbox/scoped,#2}% set scoped options first + %\option{/longbox/scoped/@adjust-options}% + \lb@peekoptions{#1,#2}% + \leavevmode + %\setbox\lb@mainbox=\hbox{% + % \begingroup + % #3% + % \endgroup + %}% + \setbox\lb@mainbox=\hbox{% + \begingroup + \ifcase\lb@textalign\relax + %default=left + \or%left + \or\hss%center + \or\hss%right + \else%justify + \fi + \lb@insertbefore + #3% + \lb@insertafter + \ifnum\lb@textalign<3\relax\hss\fi% default,left,center + \endgroup + }% + \options{#1,#2}% + \ifdim\option{/longbox/width}=-1sp\relax + \options{/longbox/width=\wd\lb@mainbox}%set to natural width + \fi + \option{/longbox/adjust-options}% + % make it a vbox + \setbox\lb@mainbox=\vbox{\offinterlineskip% + \hbox to \option{/longbox/width}{% + \unhbox\lb@mainbox + }% + }% + \def\lb@restoreoptions{}% + \letoption{/longbox/height-align}\lb@halign + \lb@height=\option{/longbox/height}\relax + \lb@baseline=\option{/longbox/baseline/@ord}\relax + \lb@processbox + \endgroup +} + +\newcommand\lb@processbox{% + \ifdim\lb@height<0pt\relax + \lb@setbaseline{\lb@mainbox}% + \else + \lb@restrictheight + \fi + \lb@typesetbox +} + +\newcommand\lb@typesetbox{% + \ifinlvbox + \iftoggle{lb@breakable}{% + %\lb@debug{disable breakable due to nesting of long-boxes}% + \togglefalse{lb@breakable}% + }{}% + \fi + \ifhmode\lb@single@{\lb@mainbox}\else\lb@typeset\fi +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@restrictheight{% + \lb@typeout{restrict height to \the\lb@height}% + \lb@splitheight=\lb@height% + %lb@debug{before height split: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + %split failed.. do nothing + \lb@debug{could not restrict height}% + \else + % store splitted off content in the mainbox (and discard the rest) + \setbox\lb@mainbox\vbox{\unvbox\lb@headbox}% + \lb@debug{restricted height to \the\ht\lb@mainbox}% + \fi + % set baseline + \lb@setbaseline{\lb@mainbox}% + % height align + %\letoption{/longbox/height-align}\lb@halign + \eifstrequal{\lb@halign}{bottom}% + {\setbox\lb@mainbox=\vbox{\hbox{\vbox to \lb@splitheight{\vss\unvbox\lb@mainbox}}}}% + {\eifstrequal{\lb@halign}{middle}% + {\dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\hbox{% + \lower \dimexpr0.5\dimen@ + \dp\lb@mainbox\relax% + \vbox to \lb@splitheight{\vss\unvbox\lb@mainbox\vss}}}}% + {% default is top + \dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\vtop to \lb@splitheight{\box\lb@mainbox\vss}}% + }% + }% +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newlength\lb@neededvspace +\newcommand\lb@typeset[1][0pt]{% + \iftoggle{lb@breakable}{% + \lb@setfreevspace + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skiptop+\lb@skipbottom\relax}% + \lb@debug{needed: \the\lb@neededvspace, available: \the\lb@freevspace}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@single@{\lb@mainbox}% + \else + \lb@typeout{longbox needs splitting}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skiptop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \ifdim\dimexpr\lb@freevspace + #1\relax<\textheight\relax % test if we were at a fresh page.. (and prevent infinite recursion) + \lb@debug{failed to split the box, inserting a page break}% + \hrule \@height\z@ \@width\hsize + \lb@eject% + \lb@typeset[\textheight]% try again, but pass \textheight to guard against infinite recursion + \else + % on a fresh page we should not fail anymore.. just output as is.. + % lb@warncannotsplit + \lb@single@{\lb@mainbox}% + \fi + \else + % first part success + \lb@typeout{first part splitted}% + \lb@first@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest + \fi + \fi + }{%\else + \lb@debug{unbreakable box}% + \lb@single@{\lb@mainbox}% always directly output an unbreakable box + }% +} + +\newcommand\lb@typesetrest{% + \lb@setfreevspace% + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skipbottom+\lb@skipbreaktop\relax}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@typeout{output last part of box}% + \lb@last@{\lb@mainbox}% + \else + \lb@debug{split box further}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skipbreaktop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \lb@typeout{failed to split box!}% + \lb@last@{\lb@mainbox}% + \else + % middle part success + \lb@typeout{output middle part of box}% + \lb@middle@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest% continue the iteration... + \fi + \fi +} + +% -------------------------------------------------------- +% Split a long vbox over multiple pages. +% This code is based on similar code in the mdframed package +% -------------------------------------------------------- + +\newlength\lb@splitheight +\newlength\lb@insurance % tiny extra space to ensure our box will really fit +\setlength\lb@insurance{1pt} + +% expects split target height in lb@splitheight, and splits off the start of lb@mainbox to lb@headbox +\newcommand\lb@splitbox{% + \ifdim\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax>\lb@splitheight\relax + % the main box is larger than our target split height.. + \ifdim\lb@extrasplit>\lb@splitheight\relax + % not enough space to bother + \lb@typeout{not enough space on page for a split}% + \setbox\lb@headbox=\vbox{}% empty head + \else + % try a split; lower the split height a bit so we are sure to fit + \advance\lb@splitheight -\lb@insurance\relax + \lb@debug{split: \the\lb@splitheight, from \the\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax}% + \setbox\lb@savebox=\vbox{\unvcopy\lb@mainbox}% save original + \lb@trysplit{\lb@splitheight}% + \ifdim\dimexpr\ht\lb@headbox + \dp\lb@headbox>\lb@splitheight\relax + % too big, bad split. Try other splits.. iterate N times with 1 or 5pt less before giving up + \dimen@=\lb@splitheight\relax + \@tempcnta=\z@\relax + \loop + \ifdim\dimexpr\ht\lb@headbox+\dp\lb@headbox\relax>\lb@splitheight\relax + \ifnum\@tempcnta<50% + \advance\dimen@ by -\p@\relax% try a slightly smaller height.. + \else + \advance\dimen@ by -5\p@\relax% try larger increase after 50pt.. + \fi + \advance\@tempcnta by \@ne\relax + \lb@ignorevbadness + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \lb@trysplit{\dimen@}% + \ifdim\lb@extrasplit<\dimen@\relax\else\lb@splitstop\fi % don't try to split too small + \ifnum\@tempcnta<100\relax\else\lb@splitstop\fi % and not more than N attempts + \repeat% + \ifnum\@tempcnta<100\relax + \dimen@=\dimexpr\lb@splitheight - \ht\lb@headbox - \dp\lb@headbox\relax + \ifdim\dimen@>\option{/longbox/split-badness}\relax + \lb@warnbadsplit{\dimen@}% + \fi + \fi + \fi + \fi + \else + % mainbox fits in our target lb@splitheight + \setbox\lb@headbox=\vbox{\unvbox\lb@mainbox}% + \setbox\lb@mainbox=\vbox{}% + \fi +} + +\newcommand\lb@splitstop{% + \lb@typeout{cannot find a good split}% + \let\iterate\relax + \lb@warncannotsplit + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \setbox\lb@headbox=\vbox{}% empty head + \@tempcnta=\@M\relax +} + +\newcommand\lb@trysplit[1]{% try to split at given height + \lb@typeout{try to split at: \the\dimexpr #1\relax}% + \lb@ignorevbadness + \setbox\lb@headbox=\vsplit\lb@mainbox to #1\relax% + \setbox\lb@headbox=\vbox{\unvbox\lb@headbox}% + \setbox\lb@mainbox=\vbox{\unvbox\lb@mainbox}% +} + +% -------------------------------------------------------- +% The longbox environment uses options to set its options +% -------------------------------------------------------- + + +% keys and styles that can be set once globally +\options{% + /longbox/.new family, +}% + +\options{/longbox,% + % computed + @part-needtop/.new toggle, + @part-needbottom/.new toggle, + @part-height/.new length, + @part-width/.new length, + @part-depth/.new length, + @content-box-height/.new length, + @content-box-width/.new length, + @content-box-depth/.new length, + @breakat-previous/.new length, + @lower/.new length, + % + debug/.new toggle, + verbose/.new toggle, + render/.new value =\lb@render@fbox, + adjust-options/.new value = {\longbox@adjustoptions}, + eject/.new value = {\protect\vfill\protect\eject}, + use-vbox/.new toggle = true, + split-minimum/.new length = {1.5\baselineskip}, + split-badness/.new length = \baselineskip, + % + height-align/.new choice= {top,middle,bottom}, + baseline/.new choice = {bottom,middle,top}, + text-align/.new choice = {default,left,center,right,justify}, + vertical-align/.new choice = {baseline,bottom,middle,top,text-bottom,text-top,super,sub}, + raise/.new length = {0pt}, + baseline-skip/.new toggle =true, + % + height/.new length = -1sp, + width/.new length = -1sp, + outer-height/.new length= -1sp, + outer-width/.new length = -1sp, + insert-before/.new value= {}, + insert-after/.new value = {}, + breakat/.new value = {}, + breakable/.new toggle = false, + skip/.new style = {skip-top=#1,skip-right=#1,skip-bottom=#1,skip-left=#1}, + skip-top/.new length, + skip-right/.new length, + skip-bottom/.new length, + skip-left/.new length, + skip-break-bottom/.new length, + skip-break-top/.new length, +} + +\newcommand\longbox@adjustoptions{% + %\typeout{ standard longbox adjustoptions}% + \lb@debug{ current width=\the\dimexpr\option{/longbox/width}, outer=\the\dimexpr\option{/longbox/outer-width}, linewidth=\the\linewidth}% + \ontoggle{/longbox/debug}{\option@invoke{/longbox/verbose}{true}}% + % adjust height + \ifdim\option{/longbox/height}=-1sp\relax + \ifdim\option{/longbox/outer-height}=-1sp\else + \option@invoke{/longbox/height}% + {\option{/longbox/outer-height}-\option{/longbox/skip-top}-\option{/longbox/skip-bottom}}% + \fi + \fi + % set width + \ifdim\option{/longbox/width}=-1sp\relax + \ifdim\option{/longbox/outer-width}=-1sp\relax + \option@invoke{/longbox/outer-width}{\linewidth}% + \fi + \dimen@=\dimexpr\option{/longbox/outer-width}-\option{/longbox/skip-left}-\option{/longbox/skip-right}\relax + \ifdim\dimen@<\z@\relax\dimen@=\z@\fi + \option@invoke{/longbox/width}{\dimen@}% + \fi + % use a breakbox whenever we are in external vertical mode and not width or height restricted. + \iftoggle{/longbox/use-vbox}{}{% + \ifinner\toggletrue{/longbox/use-vbox}\else + \ifhmode\toggletrue{/longbox/use-vbox}\else + \ifdim\option{/longbox/height}>-1sp\toggletrue{/longbox/use-vbox}\else + \iftoggle{/longbox/breakable}{}{\toggletrue{/longbox/use-vbox}}% + \ifoptionblank{/longbox/breakat}{}{\toggletrue{/longbox/use-vbox}}% + \fi\fi\fi + }% +} + +\newenvironment{longbox}[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \begin{longbox@env}{/longbox}{#1}% +}{\end{longbox@env}} + +\newcommand\lbox[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \longbox@cmd{/longbox}{#1}% +} + +\newcommand*\lb@render@fbox{% + %\typeout{render defaultbox: bgcolor=\bb@bgcolor, needtop=\iftoggle{/longbox/@part-needtop}{true}{false}}% + \@ovdx=\dimexpr\option{/longbox/@part-width} - 2\fboxrule\relax% + \@ovdy=\dimexpr\option{/longbox/@part-height}\relax% + \iftoggle{/longbox/@part-needbottom}% + {\@tempdima=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdima=\dimexpr\fboxrule + \bb@stickout\relax + \advance\bb@height by \@tempdima + \advance\@ovdy by \@tempdima}% + \iftoggle{/longbox/@part-needtop}% + {\@tempdimb=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdimb=\dimexpr\bb@stickout\relax + \advance\bb@height by \@tempdimb + \advance\@ovdy by \@tempdimb}% + % + \hbox{\lower \@tempdima\vbox{% + \vskip -\@tempdimb + \ontoggle{/longbox/@part-needtop}{\lb@debug{toprule wd=\expandafter\the\option{/longbox/width}}\hrule width \option{/longbox/@part-width} height \fboxrule}% + \hbox{% + \vrule width \fboxrule height \@ovdy% + \ifx\bb@bgcolor\@empty + \vrule width \@ovdx height \z@\relax + \else + {\color{\bb@bgcolor}\vrule width \@ovdx height \@ovdy}% + \fi + \vrule width \fboxrule height \@ovdy% + }% + \ontoggle{/longbox/@part-needbottom}{\hrule width \option{/longbox/@part-width} height \fboxrule}% + }}% +} \ No newline at end of file diff --git a/spec/main/longfbox.sty b/spec/main/longfbox.sty new file mode 100644 index 00000000..0df01331 --- /dev/null +++ b/spec/main/longfbox.sty @@ -0,0 +1,1344 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longfbox}[2015/12/01, Daan Leijen, Provides long fbox that can break over pages] + +\RequirePackage{options} +\RequirePackage{longbox} +\RequirePackage{pict2e} +\RequirePackage{ellipse} + +% -------------------------------------------------------- +% Dimension calulations +% -------------------------------------------------------- + +% dimmin/dimmax return minimum or maximum dimension +\providecommand\dim@min[2]{\ifdim#1>#2#2\else #1\fi} +\providecommand\dim@max[2]{\ifdim#1>#2#1\else #2\fi} + +\newcommand*\option@dimmin[2]{\dim@min{\option{#1}}{\option{#2}}} +\newcommand*\option@dimmax[2]{\dim@max{\option{#1}}{\option{#2}}} + + +% -------------------------------------------------------- +% Add a new 'sides' option type +% -------------------------------------------------------- + +\options{ + /handlers/new sides/.new handler = []{ + \ifblank{#2}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#1-top={##1}, #1-right={##2}, #1-bottom={##3}, #1-left={##4}}}}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#2}}}% + \optionsalso{ + #1/.new cmdx = {##1,##2,##3,##4,##5\relax}{,,,,\relax}{% + \ifblank{##2##3##4}{\option{#1/@cmd@sides}{##1}{##1}{##1}{##1}}% + {\ifblank{##3##4}{\option{#1/@cmd@sides}{##1}{##2}{##1}{##2}}% + {\ifblank{##4}{\option{#1/@cmd@sides}{##1}{##2}{##3}{##2}}% + {\option{#1/@cmd@sides}{##1}{##2}{##3}{##4}}% + }% + }% + }, + #1/.type = sides, + }% + },% +} + +\newcommand*\optionlengthlimit[3]{% len, min, max + \letoption{#1}\opt@temp + \ifdim\opt@temp<\dimexpr#2\relax + \option@invoke{#1}{#2}% + \else\ifdim\opt@temp>\dimexpr#3\relax + \option@invoke{#1}{#3}% + \fi\fi +} + +\newcommand*\optionradiuslimit[4]{% r1, r2, min, max + \letoption{#1}\opt@tempa + \letoption{#2}\opt@tempb + \ifdim\opt@tempa<\dimexpr#3\relax\option@invoke{#1}{#3}\fi + \ifdim\opt@tempb<\dimexpr#3\relax\option@invoke{#2}{#3}\fi + \ifdim\dimexpr\opt@tempa + \opt@tempb\relax=\z@\relax\else + \ifdim\dimexpr\opt@tempa+\opt@tempb\relax>\dimexpr#4\relax + \edef\opt@perc{\the\numexpr(\number\dimexpr#4\relax)/% + (\number\dimexpr(\opt@tempa+\opt@tempb)/100\relax)}% + %\typeout{scale:\the\opt@tempa,\the\opt@tempb, by \opt@perc percent to make \the\dimexpr#4\relax}% + \edef\opt@temp{\dimexpr\opt@perc\dimexpr\the\opt@tempa\relax / 100\relax}% + \option@einvoke{#1}{\opt@temp}% + \option@einvoke{#2}{\dimexpr#4 - \opt@temp\relax}% + %\typeout{ scaled to: \the\opt@temp,\the\dimexpr#4 - \opt@temp\relax}% + \fi + \fi +} + + +% \begin{macro}{\trig@atantan} +% \marg{a}\marg{b}\marg{$\alpha$}{dimen$_\mathit{reg}$}\\ +% Assigns $\atan_2(\frac{\sin(\alpha)}{b},\frac{\cos(\alpha)}{a})$ to dimension register \textit{dimen$_\mathit{reg}$}, +% where $a$ and $b$ are dimensions. +% Returns $\alpha$ when $a = b$, or when $a=0$ or $b=0$. +% \begin{macrocode} +\newcommand*\trig@atantan[4]{% + %\typeout{ atantan:(\the#1,\the#2,\the#3, #4)}% + \@tempdima\dimexpr#1\relax + \@tempdimb\dimexpr#2\relax +% \end{macrocode} +% If $a = b$, we have a circle and the result is $\alpha$. +% \begin{macrocode} + \ifdim\@tempdima=\@tempdimb + #4\dimexpr#3\relax + \else\ifdim\@tempdima=\z@ + #4\dimexpr#3\relax + \else\ifdim\@tempdimb=\z@ + #4\dimexpr#3\relax + \else + \edef\trig@temp{\strip@pt\dimexpr#3\relax}% + \CalculateSin{\trig@temp}\CalculateCos{\trig@temp}% + \@tempdimc\dimexpr1\p@ * \dimexpr\UseSin{\trig@temp}\p@\relax/\@tempdimb\relax + \@tempdimd\dimexpr1\p@ * \dimexpr\UseCos{\trig@temp}\p@\relax/\@tempdima\relax + \pIIe@atantwo{\@tempdimc}{\@tempdimd}\dimen@ + \ifdim\dimen@<\z@ + \ifdim\dimexpr#3\relax<\z@\else\advance\dimen@360\p@\fi + \fi + \@tempdima\dimexpr#3 - \dimen@\relax + \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi + \ifdim\@tempdima<360\p@\else\advance\dimen@360\p@\fi + %\typeout{atan: \the\dimexpr#3\relax versus. \the\dimen@ }% + #4\dimen@ + \fi\fi\fi +} +% \end{macrocode} +% \end{macro} + +% rough approximation of the perimeter; +% if |radius-x == radius-y| = 0 (a circle), the approximation is precise. +% otherwise, works best when |angle2-angle1| <= 45 and gets worse from there on. +\newcommand*\ellip@letarcperimeter[5]{% 'radius-x', 'radius-y', 'angle-1', 'angle-2', '\result' + \@tempdima\dimexpr#3\relax + \@tempdimb\dimexpr#4\relax + \@tempdimc\dimexpr\@tempdima - \@tempdimb\relax + \ifdim\@tempdimc<\z@\@tempdimc-\@tempdimc\fi + \ifdim#1=#2\relax% circle? + \edef\@tempa{\strip@pt\@tempdimc}% angle difference delta as factor + \dimen@\@tempa\dimexpr#1\relax% r*delta + \dimen@0.017453\dimen@% (2*pi/360) * r * delta = 2*pi*r * (delta/360) + \else% ellipse: take the distance between the points on the ellipse, works pretty good if delta <= 45, and ok'ish for delta <= 90 + \@ovro\dimexpr#1\relax + \@ovri\dimexpr#2\relax + \edef\fbox@tempa{\strip@pt\@tempdima}% + \edef\fbox@tempb{\strip@pt\@tempdimb}% + \pIIe@ellip@sincost{\fbox@tempa}{\fbox@tempb}% + \@tempdima\@ellipcosone\@ovro + \@tempdimb\@ellipsinone\@ovri + \@tempdimc\@ellipcostwo\@ovro + \@tempdimd\@ellipsintwo\@ovri + \advance\@tempdimc by -\@tempdima% + \advance\@tempdimd by -\@tempdimb% + \pIIe@ellip@csqrt{\@tempdimc}{\@tempdimd}{\dimen@}% + %\typeout{ distance: \the\dimen@, from (x,y)=(\the\@tempdimc,\the\@tempdimd), radii=(\the#1,\the#2), angles=(\the#3,\the#4)}% + \fi + \edef#5{\the\dimen@}% +} + + +% ------------------------------------------------------------------------------ +% Borders using the picture environment +% ------------------------------------------------------------------------------ + +\newcommand*\fbox@border@pict{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \begingroup + \hbox{% + \unitlength\p@ + \begin{picture}(0,0)(0,\optionunit{/fbox/@border-box-height})% bottom-left is origin + % markers + \ontoggle{/fbox/show-markers}{% + \linethickness{\option{/fbox/marker-width}}% + \optioncolor{/fbox/marker-color}% + \fbox@rect{0pt}{0pt}{\option{/fbox/@border-box-width}}{\option{/fbox/@border-box-height}}% + \fbox@rect{\option{/fbox/border-left-width}}{\option{/fbox/border-\fbox@bottom-width}}% + {\option{/fbox/@border-box-width}-\option{/fbox/border-right-width}}% + {\option{/fbox/@border-box-height}-\option{/fbox/border-\fbox@top-width}}%S + }% + %compute corner coordinates + \fbox@border@calccorners + %put down the background color + \fbox@border@colorbackground + \option{/fbox/picture-insert-before}% + %put down the sides + \fbox@border@side{3}{-2}{0}%top + \fbox@border@side{5}{-4}{3}%left + \fbox@border@side{-6}{7}{2}%bottom + \fbox@border@side{-8}{1}{1}%right + \end{picture}% + }% + \endgroup + \fi +} + +\newcommand*\fbox@border@pict@after{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \letoption{/fbox/picture-insert-after}\fbox@insertafter + \eifblank{\fbox@insertafter}{}{% + \begingroup + \hbox{% + \begin{picture}(0,0)(0,0)% bottom-left is origin + \fbox@insertafter + \end{picture}% + }% + \endgroup + }% + \fi +} + +\newcommand*\fbox@border@side[3]{% + \fbox@setoct@angles{#1}% + \edef\fbox@style{\option{/fbox/border-\fbox@side-style}}% + \optioncolor{/fbox/border-\fbox@side-color}% + \option{/fbox/picture-side-insert-before}% + \ifcsdef{fbox@border@pict@\fbox@style}% + {\csuse{fbox@border@pict@\fbox@style}{#1}{#2}{#3}}% + {\PackageWarning{longfbox}{Unknown style "\fbox@style". Using "solid" instead.}% + \fbox@border@pict@solid{#1}{#2}{#3}}% + \option{/fbox/picture-side-insert-after}% +} + +% ------------------------------------------------------------------------------ +% Define standard border styles for the picture environment +% +% a style has the form \fbox@border@pict@ + + + + + + +
+
+
+
P4Runtime Specification
+
version 1.0.0
+
+
+
The P4.org API Working Group
+
2019-10-09
+
+

Abstract. P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.

+ + +

1. Introduction and Scope

+

This document is published by the P4.org API Working Group, which was +chartered [16] to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called P4Runtime. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +https://github.com/p4lang/p4runtime/tree/v1.0.0/proto. +

1.1. P4 Language Version Applicability

+

P4Runtime is designed to be implemented in conjunction with the P416 language +version or later. P414 programs should be translated into P416 to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P416 1.0, but were introduced in P416 1.1.0 [1]. +

1.2. In Scope

+

This specification document defines the semantics of P4Runtime messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime: +

+
    +
  • Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA) [18] externs (e.g. Counters, Meters, Action +Profiles, ). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0. +
  • +
  • Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism. +
  • +
  • Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy. +
  • +
  • Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities. +
  • +
  • Packet I/O to enable streaming packets to & from the control plane. +
  • +
  • Batching support, with different atomicity guarantees. +
  • +
  • In-the-field device-reconfiguration with a new P4 data plane. +
+ +

The following are in the scope of this specification document: +

+
    +
  • Rationale for the P4Runtime design. +
  • +
  • Reference architecture and use-cases for deploying a P4Runtime service. +
  • +
  • Detailed description of the API semantics. +
  • +
  • Requirements for conformant implementations of the API. +
+

1.3. Not In Scope

+

The following are not in scope of P4Runtime: +

+
    +
  • Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +[32]. An open source implementation of these APIs is also in progress +as part of the Stratum project [34]. +
  • +
  • Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures. +
+ +

The following are not in scope of this specification document: +

+
    +
  • Description of the P4 programming language; it is assumed that the reader is +already familiar with P416 [1]. +
  • +
  • Descriptions of gRPC and Protobuf files in general. +
  • +
  • Controller role definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme. +
+

2. Terms and Definitions

+
+
arbitration
+
Refers to the process through which P4Runtime ensures that at any given +time, there is a single master (i.e. a client with write access) for a given +role. Also referred to as “master-slave arbitration”. +
+
client
+
The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +
+
COS
+
Class of Service. +
+
device
+
Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +
+
entity
+
An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +
+
gRPC
+
gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +[9]. +
+
HA
+
High-Availability. Refers to a redundancy architecture. +
+
Instrumentation
+
The part of the P4Runtime server which implements the calls to the device or +target native “SDK” or backend. +
+
IPC
+
Inter-Process Communication. +
+
P4 Blob
+
A more colloquial term for P4 Device Config (Blob = Binary Large Object). +
+
P4 Device Config
+
The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its “program.” +
+
P4Info
+
Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +
+
P4RT
+
Abbreviation for P4Runtime. +
+
Protobuf (Protocol Buffers)
+
The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See [19]. +
+
PSA
+
Portable Switch Architecture [18]; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +
+
RPC
+
Remote Procedure Call. +
+
RTT
+
Round-trip time. +
+
SDN
+
Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +probrammable, centralized network controller. +
+
SDN port
+
A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +
+
server
+
The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +
+
stream
+
Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (StreamChannel), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and master-slave arbitration, among other +things. +
+
switch config
+
Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +
+
target
+
The hardware or software entity which “executes” the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with “device”. +
+
URI
+
Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.

3. Reference Architecture

+

Figure 1 represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. A multi-master protocol allows more than +one controller to participate, and a role-based arbitration scheme ensures only +one controller has write access to each read/write entity, or the pipeline config +itself. Any controller may perform read access to any entity or the pipeline +config. Later sections describe this in detail. For the sake of brevity, the +term controller may refer to one or more controllers. +

+

The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +[14]. It may be compiled via protoc the Protobuf compiler +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server. +

+

Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository [15]. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, e.g. via callbacks, thus reducing the burden of implementing +P4Runtime. +

+

The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard. +

+

The controller can also set the ForwardingPipelineConfig, which amounts to +installing and running the compiled P4 program output, which is included in the +p4_device_config Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +ForwardingPipelineConfig to retrieve the device config and the P4Info. +

+
+

reference-architecture +

+
+ +
Figure 1. P4Runtime Reference Architecture.

3.1. Idealized Workflow

+

In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the ForwardingPipelineConfig +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a SetForwardingPipelineConfig +RPC. Metadata in the P4Info describes both the overall program itself +(PkgInfo) as well as all entity instances derived from the P4 program +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise “handle” used in API +calls. +

+

In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible. +

+

In some use cases, it is expected that a controller will store a +collection of multiple P4 “packages”, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the ForwardingPipelineConfig from the target via the +GetForwardingPipelineRequest RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state. +

3.2. P4 as a Behavioral Description Language

+

P4 can be considered a behavioral description of a switching device which may or +may not execute “P4” natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a SetForwardingPipelineRequest to +change its pipeline “program”, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device. +

+

While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API. +

+

In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the PkgInfo +message as well as the embedded doc fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections. +

3.3. Alternative Workflows

+

Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary. +

3.3.1. P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config

+

In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +p4_device_config. The device's configuration might be derived via some other +means to implement the P4 source code's intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane. +

3.3.2. No P4 Source Available, P4Info Available

+

In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are: +

+
    +
  1. +

    The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security. +

  2. +
  3. +

    The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info. +

+ +

As discussed in Section 3.2, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, e.g. documentation. +

3.3.3. Partial P4Info and P4 Source are Available

+

In this situation, a subset of the target's pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code. +

3.3.4. P4Info Role-Based Subsets

+

In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more. +

4. Controller Use-cases

+

P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +section. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime's flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex. +

4.1. Single Embedded Controller

+

Figure 2 shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases. +

+

P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC. +

+
+

single-embedded-controller +

+
+ +
Figure 2. Use-Case: Single Embedded Controller

4.2. Single Remote Controller

+

Figure 3 shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections. +

+
+

single-remote-controller +

+
+ +
Figure 3. Use-Case: Single Remote Controller

4.3. Embedded + Single Remote Controller

+

Figure 4 illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller. +

+

For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables. +

+
+

embedded-plus-single-remote-controller +

+
+ +
Figure 4. Use-Case: Embedded Plus Single Remote Controller

4.4. Embedded + Two Remote Controllers

+

Figure 5 illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +e.g. routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership. +

+
+

embedded-plus-two-remote-controllers +

+
+ +
Figure 5. Use-Case: Embedded Plus Two Remote Controllers

4.5. Embedded Controller + Two High-Availability Remote Controllers

+

Figure 6 illustrates a single +embedded controller plus two remote controllers in an active-standby HA +(High-Availability) configuration. Controller #1 is the active controller and is +in charge of some entities. If it fails, Controller #2 takes over and manages +the tables formerly owned by Controller #1. The mechanics of HA architectures +are beyond the scope of this document, but the P4Runtime multi-master +arbitration scheme supports it. +

+
+

embedded-plus-two-remote-ha-controllers +

+
+ +
Figure 6. Use-Case: Embedded Plus Two Remote High-Availability Controllers

5. Master-Slave Arbitration and Controller Replication

+

The P4Runtime interface allows multiple controllers to be connected to the +P4Runtime server running on the device at the same time for the following +reasons: +

+
    +
  1. +

    Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, “roles” (or “realms”) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +master and the rest are slaves. Role definition, i.e. how P4 entities get +assigned to each role, is out-of-scope of this document. +

  2. +
  3. +

    Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby slave controllers, which take over controlling the +devices in case the master controller goes offline. +

+ +

To support multiple controllers, P4Runtime uses the streaming channel (available +via StreamChannel RPC) for session management. The workflow is described as +follows: +

+
    +
  • +

    Each controller instance (e.g. a controller process) can participate in one or +more roles. For each (device_id, role_id), the controller receives an +election_id. This election_id can be the same for different roles and/or +devices, as long as the tuple (device_id, role_id, election_id) is +unique. For each (device_id, role_id) that the controller wishes to +control, it establishes a StreamChannel with the P4Runtime server +responsible for that device, and sends a MasterArbitrationUpdate message +containing that tuple of (device_id, role_id, election_id) values. The +P4Runtime server selects a master independently for each (device_id, +role_id) pair. The master is the client that has the highest election_id +among all active StreamChannel connections with the same (device_id, +role_id) values. A connection between a controller instance and a device id + which involves a persistent StreamChannel can be referred to as a +P4Runtime client. +

    +

    Note that the P4Runtime server does not assign a role_id or election_id to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the election_id values used for each +StreamChannel. The P4Runtime server only keeps track of the (device_id, +role_id, election_id) of each StreamChannel that has sent a successful +MasterArbitrationUpdate message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +WriteRequest message to identify which client is making the WriteRequest, +not only the election_id. This enables controllers to re-use the same +numeric election_id values across different (device_id, role_id) +pairs. P4Runtime does not require election_id values be reused across such +different (device_id, role_id) pairs; it allows it. +

  • +
  • +

    To start a controller session, a controller first opens a bidirectional stream +channel to the server via the StreamChannel RPC for each device. This is the +first thing the controller does to identify itself to the P4Runtime server on +the device. This stream will be used for two purposes: +

    +
      +
    • +

      Session management: As soon as the controller opens the stream +channel, it sends a StreamMessageRequest message to the switch. The +controller populates the MasterArbitrationUpdate field in this message +using its role_id and election_id. Note that the status field in the +MasterArbitrationUpdate is not populated by the controller. This field +is populated by the P4Runtime server when it sends a response back to the +client, as explained below. +

    • +
    • +

      Streaming of notifications (e.g. digests) and packet I/O: The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the master controller can participate in packet +I/O. This feature is explained in more details in the Packet +I/O section. +

    +
  • +
  • +

    Note that the stream is opened per device. In case a switching platform has +multiple devices (e.g. multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different masters for different +devices. In this case, it is the responsibility of the P4Runtime server to +keep track of the master for each device (and role). More specifically, the +P4Runtime server will know which stream corresponds to the master controller +for each pair of (device_id, role_id) at any point of time. +

  • +
  • +

    The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered “offline” or +“dead” as soon as its corresponding stream channel to the switch is +broken, in which case the P4Runtime server quickly sets one of the slave +controllers with the highest election_id as master. +

  • +
  • +

    The mechanism via which the controller receives the P4Runtime server details +which includes the device_id, ip and port, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +device_id) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks. +

  • +
  • +

    After the controller sends a StreamMessageRequest message to the P4Runtime +server, the server sends a StreamMessageResponse message back to the +controller, in which it populates the MasterArbitrationUpdate. The +controller must populate the device_id, role, and election_id +fields. The election_id field is set to the highest value, i.e. the value +for the current master. The server also populates the status field in the +MasterArbitrationUpdate (note that this field is not populated in the +MasterArbitrationUpdate received by the controller). The value of the status +message is one of the following: +

    +
      +
    • OK (with status.code set to google.rpc.OK) when the controller is +determined to be the master for a given (device_id, role_id). +
    • +
    • Non-OK (with status.code set to google.rpc.ALREADY_EXISTS) when the +controller is determined to be a slave for a given (device_id, +role_id). +
    +
+ +

gRPC enables the server to identify which client originated each message in the +StreamChannel stream. For example, the C++ gRPC library [10] in +synchronous mode enables a server process to cause a function to be called when +a new client creates a StreamChannel stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +StreamChannel is closed normally (or broken, e.g. because a client process +unexpectedly terminated). Thus the server can easily associate all +StreamChannel messages received from the same client, because they are +processed within the context of the same function call. +

+

A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values device_id, role_id, and election_id in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods [8] that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server. +

5.1. Default Role

+

A controller can omit the role message in MasterArbitrationUpdate. This +implies the “default role”, which corresponds to “full pipeline access”. This +also implies that a default role has a role.id of 0 (default). If using a +default role, all RPCs from the controller (e.g. Write) must set the role_id +to 0. +

5.2. Role Config

+

The role.config field in the MasterArbitrationUpdate message sent by the +controller describes the role configuration, i.e. which operations are in the +scope of a given role. In particular, the definition of a role may include the +following: +

+
    +
  • A list of P4 entities for which the controller may issue Write updates and +receive notification messages (e.g. DigestList and +IdleTimeoutNotification). +
  • +
  • Whether the controller is able to receive PacketIn messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketIn messages should be sent to the controller. +
  • +
  • Whether the controller is able to send PacketOut messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketOut messages are allowed to be sent by the controller. +
+ +

An unset role.config implies “full pipeline access” (similar to the default +role explained above). In order to support different role definition schemes, +role.config is defined as an Any Protobuf message [28]. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion. +

5.3. Rules for Handling MasterArbitrationUpdate Messages Received from Controllers

+
    +
  1. +

    If the MasterArbitrationUpdate message is received for the first time (for +a newly connected controller): +

    +
      +
    1. +

      If device_id does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +NOT_FOUND error. +

    2. +
    3. +

      If the election_id is already used by another controller for the same +(device_id, role_id), the P4Runtime server shall terminate the stream +by returning an INVALID_ARGUMENT error. +

    4. +
    5. +

      If the max number of clients for the given (device_id, role_id) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a RESOURCE_EXHAUSTED error. +

    6. +
    7. +

      Otherwise, the controller is added to a list of connected controllers for +the given (device_id, role_id) and the controller is notified by +sending a StreamMessageResponse message back to it, as explained +earlier. +

    +
  2. +
  3. +

    If the MasterArbitrationUpdate message is received from an already +connected controller: +

    +
      +
    1. +

      If the device_id does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. +

    2. +
    3. +

      Otherwise, if the role.id matches the current role_id assigned to +this stream: +

      +
        +
      1. +

        If the election_id also matches the one assigned to this stream, +the server will accept the (new) role.config only if this +controller is the current master. If the controller is not a master, +the operation is a no-op. +

      2. +
      3. +

        If the election_id is already assigned to another controller stream +for the same (device_id, role_id), the P4Runtime server shall +terminate the stream by returning an INVALID_ARGUMENT error. +

      4. +
      5. +

        Otherwise, the P4Runtime server updates the election_id for this +controller. If this makes the client the new master, the server will +also accept the given role.config and follow the “mastership change +rules” described in the following section. +

      +
    4. +
    5. +

      Otherwise (i.e. role.id is different from current role_id assigned to +this stream), the P4Runtime server moves the controller to the new role. +This controller will then be treated as a new controller for the new +(device_id, role_id). The server accepts the given role.config only +if the client becomes master, in which case the server also follows the +“mastership change rules” described in the following +section. +

    +
+ +

If role.config does not match the “out-of-band” scheme previously agreed upon, +the server must return an INVALID_ARGUMENT error. +

5.4. Mastership Change

+

“Mastership change” refers to either one of these cases: +

+
    +
  1. +

    A new MasterArbitrationUpdate is received from an already connected +controller for a given (device_id, role_id), which changes the controller +mastership status (the controller becomes master or slave). +

  2. +
  3. +

    A streaming channel for a given master controller breaks, forcing a new +master to be elected. +

+ +

In case of a mastership change, the P4Runtime server shall send the +election_id of the master to all the connected controllers for a given +(device_id, role_id). The StreamMessageResponse sent back to all the +connected controllers has a MasterArbitrationUpdate message populated with the +device_id, role_id, and election_id of the master, as well as an OK status +for the master and non-OK status (with ALREADY_EXISTS error code) for slaves. +

6. The P4Info Message

+

The purpose of P4Info was described under +Reference Architecture. +Here we describe the various +components. +

6.1. Common Messages

+

These messages appear nested within many other messages. +

6.1.1. Documentation Message

+

Documentation is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers. +

+
+
+
message Documentation {
+  // A brief description of something, e.g. one sentence
+  string brief = 1;
+  // A more verbose description of something.
+  // Multiline is accepted. Markup format (if any) is TBD.
+  string description = 2;
+}

6.1.2. Preamble Message

+

The preamble serves as the “descriptor” for each entity and contains the unique +instance ID, name, alias, annotations and documentation. +

+
+
+
message Preamble {
+  // ids share the same number-space; e.g. table ids cannot overlap with counter
+  // ids. Even though this is irrelevant to this proto definition, the ids are
+  // allocated in such a way that it is possible based on an id to deduce the
+  // resource type (e.g. table, action, counter, ...). This means that code
+  // using these ids can detect if the wrong resource type is used
+  // somewhere. This also means that ids of different types can be mixed
+  // (e.g. direct resource list for a table) without ambiguity. Note that id 0
+  // is reserved and means "invalid id".
+  uint32 id = 1;
+  // fully qualified name of the P4 object, e.g. c1.c2.ipv4_lpm
+  string name = 2;
+  // an alias (alternative name) for the P4 object, probably shorter than its
+  // fully qualified name. The only constraint is for it to be unique with
+  // respect to other P4 objects of the same type. By default, the compiler uses
+  // the shortest suffix of the name that uniquely identifies the object. For
+  // example if the P4 program contains two tables with names s.c1.t and s.c2.t,
+  // the default aliases will respectively be c1.t and c2.t. In the future, the
+  // P4 programmer may also be able to override the default alias for any P4
+  // object (TBD).
+  string alias = 3;
+  repeated string annotations = 4;
+  // Documentation of the entity
+  Documentation doc = 5;
+}

6.1.3. Annotating P4 Entities with Documentation

+

P4 entities may be annotated using the following annotations: +

+
+
+
@brief(string...)
+@description(string...)
+

Attaching either or both of these annotations to an entity will generate a +P4Info Documentation Message, which in turn will +appear in the Preamble Message for the entity. +

+

The P4 compiler should not emit annotation messages in the P4Info for these +specific cases; instead, it should generate the Documentation messages as +described. +

+

The following example shows documentation annotations for a table entity: +

+
+
+
@brief("Match IPv4 addresses to next-hop MAC and port")
+@description("Match IPv4 addresses to next-hop MAC and port. \
+Uses LPM match type.")
+table my_ipv4_lkup {
+  ...
+}

6.2. PkgInfo Message

+

The PkgInfo message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. PkgInfo can be extracted +and used to facilitate “browsing” of available P4 programs from a +library. Although all fields are technically “optional,” every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included. +

+
+
+
// Can be used to manage multiple P4 packages.
+message PkgInfo {
+  // a definitive name for this configuration, e.g. switch.p4_v1.0
+  string name = 1;
+  // configuration version, free-format string
+  string version = 2;
+  // brief and detailed descriptions
+  Documentation doc = 3;
+  // Miscellaneous metadata, free-form; a way to extend PkgInfo
+  repeated string annotations = 4;
+  // the target architecture, e.g. "psa"
+  string arch = 5;
+  // organization which produced the configuration, e.g. "p4.org"
+  string organization = 6;
+  // contact info for support,e.g. "tech-support@acme.org"
+  string contact = 7;
+  // url for more information, e.g. "http://support.p4.org/ref/p4/switch.p4_v1.0"
+  string url = 8;
+}

6.2.1. Annotating P4 code with PkgInfo

+

A P4 progam's PkgInfo may be declared using one or more of the following +annotations, attached to the main block only: +

+
+
+
@pkginfo(key=value)
+@pkginfo(key=value[,key=value,...])
+@brief("A brief description")
+@description("A longer\
+description")
+@custom_annotation(...)
+@another_custom_annotation(...)
+

Above we see several different types of annotations: +

+
    +
  • +

    @pkginfo - This is used to populate a specific field within the PkgInfo +message. Multiple @pkginfo annotations are allowed. For compactness, +multiple key-value pairs can appear in a single @pkginfo annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The keys must be from +among the message fields inside PkgInfo, for example, name, version, +etc. Each key-value pair assigns a value to the corresponding field inside the +single PkgInfo message for the program's P4Info. One exception is that the +Documentation field of PkgInfo must be expressed as individual +@description and @brief annotations, see next bullets. The key arch will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself. +

  • +
  • +

    @brief - This will populate the PkgInfo.doc.brief message field. +

  • +
  • +

    @description - This will populate the PkgInfo.doc.description message field +

  • +
  • +

    @<anything else> - This will create a PkgInfo.annotation entry +

+ +

Declaring one or more of these annotations on main will +generate a single corresponding PkgInfo message in the P4Info as described in +PkgInfo Message. +

+

The following example shows @pkginfo annotations using a mixture of single and +multiple key-value pairs. It also shows @brief and @description annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the PkgInfo message. The custom annotations will +be appended to the PkgInfo.annotations list. +

+
+
+
@pkginfo(name="switch.p4",version="2")
+@pkginfo(organization="p4.org")
+@pkginfo(contact="info@p4.org")
+@pkginfo(url="www.p4.org")
+@brief("L2/L3 switch")
+@description("L2/L3 switch.\
+Built for data-center profile.")
+@my_annotation1(...) // Not well-known, this will appear in PkgInfo annotations
+@my_annotation2(...) // Not well-known, this will appear in PkgInfo annotations
+PSA_Switch(IgPipeline, PacketReplicationEngine(), EgPipeline,
+           BufferingQueueingEngine()) main;

6.3. ID Allocation for P4Info Objects

+

P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(e.g. table, action, counter, ). The most significant 8 bits of the ID +encodes the object type (as per Table 1). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (p4.config.v1.P4Ids.Prefix). These values must +be used (e.g. by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table 2 shows the ID +layout. +

+
+ + + + + + + + + + + + + + + + + + + + + +
8-bit prefix value P4 object type
0x00 Reserved (unspecified)
0x01 Action
0x02 Table
0x03 Value-set
0x04 Controller header (header type with @controller_header annotation)
0x050x0f Reserved (for future P4 built-in objects)
0x10 Reserved (start of PSA extern types)
0x11 PSA Action profiles / selectors
0x12 PSA Counter
0x13 PSA Direct counter
0x14 PSA Meter
0x15 PSA Direct meter
0x16 PSA Register
0x17 PSA Digest
0x180x7f Reserved (for future PSA extern types)
0x80 Reserved (start of vendor-specific extern types)
0x810xfe Vendor-specific extern types
0xff Reserved (max prefix value)
+
+ +
Table 1. Mapping of P4Info object type to 8-bit ID prefix value
+
+ + + + +
MSB bit 31 .. bit 24 bit 23 .. bit 0 LSB
Object type prefix Generated suffix (e.g. by the compiler)
+
+ +
Table 2. Format of P4Info object IDs
+

It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with @id (see Table +3). The compiler must honor the @id annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (i.e. if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same @id value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. +

+
+ + + + + + + + + + +
P4 declaration(s) Compiler-allocated ID(s)
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) table tA... Error(same ID suffixes for 2 objects of the same type)
@id(0x12ab34) table tB...
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) action act1... 0x0112ab34
+
+ +
Table 3. Example of statically-assigned P4Info object IDs

6.4. P4Info Objects

6.4.1. Table

+

Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this table. +

  • +
  • +

    match_fields, a repeated field of type MatchField representing the data to +be used to construct the lookup key matched in this table. Each MatchField +message is defined with the following fields: +

    +
      +
    • +

      id, the uint32 identifier of this MatchField, unique in the scope of +this table. No rules are prescribed on the way MatchField IDs should be +allocated, as long as two MatchField of the same table do not have the +same ID. Nonetheless, we recommend that the IDs be assigned incrementally, +starting from 1, in the same order as in the P4 key declaration. +

    • +
    • +

      name, the string representing the name of this MatchField. +

    • +
    • +

      annotations, a repeated field of strings, each one representing a P4 +annotation associated to this match field. +

    • +
    • +

      bitwidth, an int32 value set to the size in bits of this match field. +

    • +
    • +

      match, a oneof describing the match behavior for this field; it can be +either: +

      +
        +
      • match_type, an enum field of type MatchType, which includes all +possible PSA match kinds. +
      • +
      • other_match_type, a string field which can be used to encode any +architecture-specific match type. +
      +
    • +
    • +

      doc, a Documentation message describing this match field. +

    • +
    • +

      type_name, which indicates whether the match field has a user-defined +type; this is useful for +translation. +

    +
  • +
  • +

    action_refs, a repeated ActionRef field representing the set of possible +actions for this table. The ActionRef message is used to reference an action +specified in the same P4Info message and it includes the following fields: +

    +
      +
    • id, the uint32 identifier of the action. +
    • +
    • scope, an enum value which can take one of three values: + TABLE_AND_DEFAULT, TABLE_ONLY and DEFAULT_ONLY. The scope of the + action is determined by the use of the P4 standard annotations + @tableonly and @defaultonly [17]. TABLE_ONLY + (@tableonly annotation) means that the action can only appear within + the table, and never as the default action. DEFAULT_ONLY + (@defaultonly annotation) means that the action can only be used as the + default action. TABLE_AND_DEFAULT is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action. +
    • +
    • annotations, a repeated string field, each one representing a P4 +annotation associated to the action reference in this table. +
    +
  • +
  • +

    const_default_action_id, if this table has a constant default action, this +field will carry the uint32 identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action's +arguments. +

  • +
  • +

    implementation_id, the uint32 identifier of the “implementation” of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (e.g. a PSA ActionProfile or ActionSelector +instance). The table is then referred to as an indirect match table. +

  • +
  • +

    direct_resource_ids, repeated uint32 identifiers for all the direct +resources attached to this table, such as DirectMeter and DirectCounter +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2. +

  • +
  • +

    size, an int64 describing the desired number of table entries that the +target should support for the table. See the “Size” subsection within the +“Table Properties” section of the P416 language specification for details +[27]. +

  • +
  • +

    idle_timeout_behavior, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +Idle-Timeout section). Value can be any of the +IdleTimeoutBehavior enum: +

    +
      +
    • NO_TIMEOUT (default value), which means that idle timeout is not +supported for this table. +
    • +
    • NOTIFY_CONTROL, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +Table Idle Timeout Notifications). +
    +
  • +
  • +

    is_const_table, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime. +

  • +
  • +

    other_properties, an Any Protobuf message [28] to embed +architecture-specific table properties [27] which are not part +of the core P4 language or of the PSA architecture. +

+

6.4.2. Action

+

Action messages are used to specify all possible actions of all match-action +tables. +

+

The Action message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this action +

  • +
  • +

    params, a repeated field of Param messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each Param message contains the +following fields: +

    +
      +
    • id, the uint32 identifier of this parameter. No rules are prescribed +on the way Param IDs should be allocated, as long as two Param of the +same action do not have the same ID. Nonetheless, we recommend that the +IDs be assigned incrementally, starting from 1, in the same order as in +the P4 action declaration. +
    • +
    • name, the string representing the name of this parameter. +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this parameter. +
    • +
    • bitwidth, an int32 value set to the size in bits of this parameter. +
    • +
    • doc, which describes this parameter using a Documentation message. +
    • +
    • type_name, which indicates whether the action parameter has a +user-defined type; this is useful for +translation. +
    +
+

6.4.3. ActionProfile

+

ActionProfile messages are used to specify all available instances of Action +Profile and Action Selector PSA externs. +

+

PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile member, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime. +

+

PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into groups. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime. +

+

While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same ActionProfile message to describe both. +

+

The ActionProfile message includes the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Action +Profile or Selector. +

  • +
  • +

    table_ids, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector. +

  • +
  • +

    with_selector, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern. +

  • +
  • +

    size, an int64 representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum sum +of all member weights across all selector groups. +

  • +
  • +

    max_group_size, an int32 representing the maximum sum of all member +weights within any given selector group, in the case of an Action Selector, or +0 for an Action Profile. PSA programs can use the @max_group_size annotation +to provide this value for Action Selectors. If the annotation is omitted, the +P4Info field will default to 0. +

+

6.4.4. Counter & DirectCounter

+

Counter and DirectCounter messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is: +

+
    +
  • +

    Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index. +

  • +
  • +

    Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table. +

+ +

Both Counter and DirectCounter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this counter +extern instance. +

  • +
  • +

    spec, a message of of type CounterSpec used to describe the compile-time +configuration of this counter. Currently, the CounterSpec message is used to +carry only the counter unit, which can be any of the CounterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES: byte counter. +
    • +
    • PACKETS: packet counter. +
    • +
    • BOTH: combination of both byte and packet counter. +
    +
+ +

For indexed counters, the Counter message contains also a size field, an +int64 representing the maximum number of independent values that can be held +by this counter array. Conversely, the DirectCounter message contains a +direct_table_id field that carries the unit32 identifier of the table to +which this direct counter is attached. +

+

For indexed counters, the Counter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.5. Meter & DirectMeter

+

Meter and DirectMeter messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is: +

+
    +
  • +

    Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +e.g. to set the rate threshold. +

  • +
  • +

    Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table. +

+ +

Both Meter and DirectMeter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this meter +extern instance. +

  • +
  • +

    spec, a message of type MeterSpec used to describe the capabilities of +this meter extern instance. Currently, the MeterSpec message is used to +carry only the meter unit, which can be any of the MeterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES, which signifies that this meter can be configured with rates +expressed in bytes/second. +
    • +
    • PACKETS, for rates expressed in packets/second. +
    +
+ +

For indexed meters, the Meter message contains also a size field, an int64 +representing the maximum number of independent cells that can be held by this +meter. Conversely, the DirectMeter message contains a direct_table_id field +that carries the uint32 identifier of the table to which this direct meter is +attached. +

+

For indexed meters, the Meter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.6. ControllerPacketMetadata

+

ControllerPacketMetadata messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server. +

+

When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet. +

+

Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +@controller_header("packet_in") and @controller_header("packet_out"), +respectively. ControllerPacketMetadata messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages). +

+

A P4Info message can contain at most two ControllerPacketMetadata messages, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message where preamble.name is set to "packet_in" +and "packet_out" for packet-in and packet-out metadata, respectively. +

  • +
  • +

    metadata, a repeated field of type Metadata, where each Metadata message +includes the following fields: +

    +
      +
    • id, a uint32 identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two Metadata of the +same ControllerPacketMetadata message do not have the same +ID. Nonetheless, if the P4Info message was generated from a P4 compiler, +we recommend that the IDs be assigned incrementally, starting from 1, in +the same order as the fields in the P4 header declaration. +
    • +
    • name, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below). +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this metadata. +
    • +
    • bitwidth, an int32 representing the size in bit of this metadata. +
    +
+ +

As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding ControllerPacketMetadata +messages. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  bit<9> egress_port; /* suggested port where the packet
+                         should be sent */
+  bit<8> queue_id;    /* suggested queue ID */
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  bit<9> ingress_port; /* data plane port ID where
+                          the original packet was received */
+  bit<1> is_clone;     /* 1 if this is a clone of the
+                          original packet */
+}
+
+
+
controller_packet_metadata {
+  preamble {
+    id: 2868916615
+    name: "packet_out"
+    annotations: "@controller_header(\"packet_out\")"
+  }
+  metadata {
+    id: 1
+    name: "egress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "queue_id"
+    bitwidth: 8
+  }
+}
+
+controller_packet_metadata {
+  preamble {
+    id: 2868941301
+    name: "packet_in"
+    annotations: "@controller_header(\"packet_in\")"
+  }
+  metadata {
+    id: 1
+    name: "ingress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "is_clone"
+    bitwidth: 1
+  }
+}
+

Note that the use of @controller_header is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages. +

6.4.7. ValueSet

+

ValueSet messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P416 +specification [35]. +

+

The ValueSet message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Value +Set. +

  • +
  • +

    match, a repeated field of MatchField messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the match_fields repeated field in the +Table message. +

  • +
  • +

    size, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +value_set constructor call. +

+ +

According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of bit<W>, +tuple, or struct [24]. The rest of this section looks at all 3 of +these cases and gives an example ValueSet message when appropriate. +

+
    +
  1. +

    If the type parameter is bit<W>, match will include exactly one +MatchField message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used): +

    +
      +
    • id: set to 1 +
    • +
    • bitwidth: set to the value of W +
    • +
    • match_type: set to EXACT +
    +
+ +
+
+
@id(1) value_set<bit<8> >(4) pvs;
+select (hdr.f8) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    bitwidth: 8
+    match_type: EXACT
+  }
+  size: 4
+}
+
    +
  1. +

    If the type parameter is a tuple, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program. +

  2. +
  3. +

    If the type parameter is a struct, this version of P4Runtime requires that +all the fields of the struct be of type bit<W> (where W can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +match field will include one MatchField message for each field in the +struct, with the following fields: +

    +
      +
    • id: must be unique with respect to the other match entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. +
    • +
    • name: set to the name of the corresponding struct field. +
    • +
    • annotations: set to the list of P4 annotations associated with the struct +field, except for the @match annotation, if present (see the match field +below). +
    • +
    • bitwidth: set to the value of W for the corresponding struct field. +
    • +
    • match: by default match_type is set to EXACT; the P4 programmer can +specify a different match type by using the @match annotation +[24]. +
    • +
    • doc: documentation associated with the struct field. +
    +
+ +
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a user-defined +type that resolves to a bit<W>, or a struct where +one or more fields is a user-defined type that +resolves to a bit<W>. For each MatchField that corresponds to a user-defined +type, the type_name field must be set to the appropriate value (i.e. the name +of the type). +

6.4.8. Register

+

Register messages are used to specify all possible instances of Register PSA +externs. +

+

Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime. +

+

The Register message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this register +instance. +

  • +
  • +

    type_spec, which specifies the data type stored by this register, expressed +using a P4DataTypeSpec message (see section on Representation of Arbitrary +P4 Types). +

  • +
  • +

    size, an int32 value representing the total number of independent register +cells available. +

  • +
  • +

    index_type_name, which indicates whether the register index has a +user-defined type. This is useful for +translation. The underlying built-in type +must be a fixed-width unsigned bitstring (bit<W>). +

+

6.4.9. Digest

+

Digest messages are used to specify all possible instances of Packet Digest +PSA externs. +

+

A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages. +

+

The Digest message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this digest +instance. +

  • +
  • +

    type_spec, which specifies the data type of an individual digest +notification using a P4DataTypeSpec message (see section on Representation +of Arbitrary P4 Types). +

+

6.4.10. Extern

+

Extern messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one Extern message instance in P4Info. The Extern message defines +the following fields: +

+
    +
  • +

    extern_type_id, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the reserved +range [0x81, 0xfe]. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture. +

  • +
  • +

    extern_type_name, which specifies the fully-qualified P4 name of the extern +type. +

  • +
  • +

    instances, a repeated field of ExternInstance Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +ExternInstance in turn defines the following fields: +

    +
      +
    • preamble, a Preamble message with the ID, name, and alias of this digest +instance. +
    • +
    • info, an Any Protobuf message [28] which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for info should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on Extending +P4Runtime for non-PSA Architectures for more +information. +
    +
+ +

If the P4 program does not include any instance of a given extern type, the +Extern message instance for that type should be omitted from the P4Info. +

6.5. Support for Arbitrary P4 Types with P4TypeInfo

+

See section on Representation of Arbitrary P4 +Types. +

7. P4 Forwarding-Pipeline Configuration

+

The ForwardingPipelineConfig captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the “Device Configuration” and sometimes also referred to as +the “P4 Blob”. It is defined as: +

+
+
+
message ForwardingPipelineConfig {
+  config.P4Info p4info = 1;
+  bytes p4_device_config = 2;
+  message Cookie {
+    uint64 cookie = 1;
+  }
+  Cookie cookie = 3;
+}
+

The p4info field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic. +

+

The p4_device_config is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new ForwardingPipelineConfig on that target. +

+

The cookie field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a GetForwardingPipelineConfig RPC. +When writing the config via a SetForwardingPipelineConfig RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present. +

8. General Principles for Message Formatting

8.1. Set / Unset Protobuf Field

+

In Protobuf version 3 (proto3), the default value for a message field is +“unset” [4]. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +CounterEntry message, an “unset” index field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the index message field is +set, a single entry will be read. +

+

Let's look at the counter example in more details. Based on this specification +document, the C++ server code which processes CounterEntry messages may look +like this: +

+
+
+
auto *counter_entry = ...
+if (counter_entry->has_index()) {
+  auto index = counter_entry->index().index();
+  read_one_entry(counter_entry->id(), index);
+} else {
+  read_all_entries(counter_entry->id());
+}
+
    +
  1. +

    Reading a single counter entry at index 0 in the counter array with id +<id>: +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
      +entry.mutable_index();
      +// The above line sets the index field; it is equivalent to:
      +// auto *index = entry.mutable_index();
      +// index->set_index(0);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
      +index {}
    • +
    • Expected behavior: Counter entry at index 0 is read. Notice that the +index subfield is missing under the index field message of +CounterEntry in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages. +
    +
  2. +
  3. +

    Reading all counter entries by leaving the index field unset +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
    • +
    • Expected behavior: All counter entries for the provided counter +instance are read. Notice that the index message field is unset (default +value) and is therefore omitted from the textual representation of the +message. +
    +
+

8.2. Read-Write Symmetry

+

The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example: +

+
+
+
intended_value = value
+
+status = server.write(intended_value, p4_entity)
+observed_value = server.read(p4_entity)
+
+assert(intended_value == observed_value)
+

To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If Read RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol's complexities to the client implementations. +

+

In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the match fields in a TableEntry message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +MessageDifferencer class [33] included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance. +

8.3. Zero as Reserved Value

+

p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a uint32. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a WriteRequest or a SetForwardingPipelineConfigRequest. +

8.4. Bytestrings

+

P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (bit<W>) or signed (int<W>), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +bytes Protobuf type. The correct bitwidth as per the P4 program of +each integer variable exposed through P4Runtime is specified in the P4Info +message. +

+

The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals: +

+
    +
  • +

    It ensures that a properly encoded binary string's integer value conforms +to the P4Info-specified bitwidth. +

  • +
  • +

    It supports read-write symmetry. +

  • +
  • +

    It helps facilitate non-disruptive P4 program updates. +

+ +

In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type bit<W> and/or int<W>. +

+

Note that this representation does not make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range. +

+

In the P4Runtime API version 1.0, values of table key fields, action parameters, +and fields in packet-in and packet-out headers between a device and the +controller (see 6.4.6), may not be of type int<W>. +The rules for encoding signed values thus only apply to messages of type +P4Data (see 8.5.3). +

+

For a value of type bit<W>, the fewest number of bits required to represent +the integer value $V > 0$ is the smallest integer $A$ such that $V \leq 2^A -1$. +

+

For a value of type int<W>, the fewest number of bits required to represent +the integer value $V \neq 0$ in 2's complement form is the smallest integer $A$ +such that $-2^{A-1} \leq V \leq 2^{A-1} - 1$. +

+

As a special case, define that the value $V=0$ requires at least $A=1$ bit to +represent, regardless of whether it is signed or unsigned. +

+

The shortest possible binary string for an integer $V$ that needs $A$ bits to +represent it is computed as: +

+
+
+
minimum_string_size = floor((A + 7) / 8)
+

Binary strings with the byte length computed as minimum_string_size promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies. +

+

Any additional bits in the bytes sent for an unsigned integer value (type +bit<W>) must be 0. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with 0. +

+

Any additional bits in the bytes sent for a signed integer value (type int<W>) +must be copies of the sign bit, i.e. 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with copies of the +sign bit, i.e. 0 for non-negative values, or 0xff for negative values. In 2's +complement representation, this is called “sign extension”, and leaves the +numeric value represented unchanged. +

+

Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value. +

+

For a received bitstring expected to fit within a bit<W> type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring's width is W bits or less. +

+

For a received bitstring expected to fit within an int<W> type, the value it +represents is in range if, after “undoing sign extension”, the remaining bit +string's width is W bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other. +

+

If the string's byte length is zero, the server always rejects the string. +

+

When the server rejects a binary string due to any of the previous criteria, +it returns an OUT_OF_RANGE error. +

+

For all binary strings, P4Runtime uses big-endian (i.e. network) byte-order. +For signed integer values (int<W> P4 type), P4Runtime uses the same two's +complement bitwise representation as P4. Table 4 +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above. +

+
+ + + + + + + + + + + + + + + + + +
P4 type Integer value P4Runtime binary string Read-write symmetry
bit<8> 99 (0x63) \x63 yes
bit<16> 99 (0x63) \x00\x63 no
bit<16> 99 (0x63) \x63 yes
bit<16> 12388 (0x3064) \x30\x64 yes
bit<16> 12388 (0x3064) \x00\x30\x64 no
bit<12> 99 (0x63) \x00\x63 no
bit<12> 99 (0x63) \x63 yes
bit<12> 99 (0x63) \x00\x00\x63 no
int<8> 99 (0x63) \x63 yes
int<8> -99 (-0x63) \x9d yes
int<8> -99 (-0x63) \xff\x9d no
int<12> -739 (-0x2e3) \xfd\x1d yes
int<16> 0 (0x0) \x00\x00 no
int<16> 0 (0x0) \x00 yes
+
+ +
Table 4. Examples of Valid Bytestring Encoding
+

Table 5 shows some examples of invalid +P4Runtime binary strings: +

+
+ + + + + + + + + + + + +
P4 type P4Runtime binary string
bit<8> \x01\x63
bit<8> empty string
bit<16> \x01\x00\x63
bit<12> \x10\x63
bit<12> \x01\x00\x63
bit<12> \x00\x40\x63
int<8> \x00\x9d
int<12> \x8d\x1d
int<16> empty string
+
+ +
Table 5. Examples of Invalid Bytestring Encoding
+

As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from bit<8> to bit<9>, a server +running the bit<9> version of the P4 program will accept requests from +clients that remain on the bit<8> P4Runtime version. +

+

Despite the server's binary string flexibility for P4 program update support, +the client and server must both remain aware of the +read-write symmetry +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values. +

+

Representation of variable-length integer values (varbit<W> P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary string, +whose length is the dynamic-length of the expression. When the value is +provided by the P4Runtime client, the server must verify that the length of the +binary string is less than the maximum length specified in the P4 program, and +return an OUT_OF_RANGE error code otherwise. +

8.5. Representation of Arbitrary P4 Types

8.5.1. Problem Statement

+

The P416 language includes more complex types than just binary strings +[3]. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table 6 shows the different +P416 types and how they are allowed to be used, as per the P416 +specification. +

+
+ + + + + + + + + + + + + + + + + + + +
Container type
Element type header header_union struct or tuple
bit<W> allowed error allowed
int<W> allowed error allowed
varbit<W> allowed error allowed
int error error error
void error error error
error error error allowed
match_kind error error error
bool error error allowed
enum allowed1 error allowed
header error allowed allowed
header stack error error allowed
header_union error error allowed
struct error error allowed
tuple error error allowed
+
+ +
Table 6. P4 Type Usage
+

For example, the following P416 objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects. +

+
+
+
Digest<tuple<bit<4>, bit<8> > >() digest_complex;
+digest_complex.pack({ hdr.ipv4.version, hdr.ipv4.protocol });
+// ...
+header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

One solution would be to use only binary string (bytes type) in +p4runtime.proto and to define a custom serialization format for complex P416 +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P416 types. +

8.5.2. P4 Type Specifications in p4info.proto

+

In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type ip_t, which is a header union with 2 possible headers: +ipv4 with type ipv4_t and ipv6 with type ipv6_t. Similarly, they need to +know the field layout for both of these header types. +

+

To achieve this we introduce 2 main Protobuf messages: P4TypeInfo and +P4DataTypeSpec. +

+

P4TypeInfo is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P416 program. These +named types are struct, header, header_union, enum and +serializable_enum; for each of these we have a type specification message, +respectively P4StructTypeSpec, P4HeaderTypeSpec, P4HeaderUnionTypeSpec, +P4EnumTypeSpec and P4SerializableEnumTypeSpec. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. P4TypeInfo also includes the list of parser errors for the program, as +a P4ErrorTypeSpec message. +

+

P4DataTypeSpec is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each P4DataTypeSpec message corresponds to a compile-time type in the +original P416 program (e.g. the type parameter of an extern). This +compile-time type is represented as a Protobuf oneof, which can be: +

+
    +
  • +

    a string representing the name of the type in case of a named type (struct, +header, header_union, enum, serializable_enum or user-defined “new” +type), +

  • +
  • +

    an empty Protobuf message for bool and error, or +

  • +
  • +

    a Protobuf message for other anonymous types (bit<W>, int<W>, varbit<W>, +tuple or stack). The “binary string” types (bit<W>, int<W>, and +varbit<W>) are grouped together in the P4BitstringLikeTypeSpec message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf bytes +type). +

+ +

For all P416 compound types (tuple, struct, header, and header_union), +the order of members in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P416 declaration. The same goes for the order of members of an enum +(serializable or not) or members of error. +

8.5.3. P4Data in p4runtime.proto

+

P4Runtime uses the P4Data message to represent values of arbitrary types. The +P4Runtime client must generate correct P4Data messages based on the type +specification information included in P4Info. The P4Data message was designed +to introduce little overhead compared to using binary strings in the most common +case (P416 bit<W> type). +

+

Just like its P4Info counterpart - P4DataTypeSpec -, P4Data uses a Protobuf +oneof to represent all possible values. +

+

We define a canonical representation for P4Data messages therefore +guaranteeing read-write symmetry by introducing the following requirements: +

+
    +
  • +

    The order of members in P4StructLike and the order of bitstrings in +P4Header must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P416 type +declaration. +

  • +
  • +

    An invalid header is represented by a P4Header message where the is_valid +field is false and the bitstrings repeated field is empty. +

  • +
  • +

    An invalid header union (i.e. all headers in the union are invalid) is +represented by a P4HeaderUnion message where the valid_header_name is the +empty string (default value for the field) and the valid_header is unset. +

  • +
  • +

    The order of entries in P4HeaderStack and P4HeaderUnionStack is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the entries field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding P4HeaderStackTypeSpec or +P4HeaderUnionStackTypeSpec message. +

+

8.5.4. Example

+

Let's look at the Register example again: +

+
+
+
header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

Here's the corresponding entry in the P4Info message: +

+
+
+
registers {
+  preamble {
+    id: 369119267
+    name: "register_ip"
+    alias: "register_ip"
+  }
+  type_spec {
+    header_union {
+      name: "ip_t"
+    }
+  }
+  size: 128
+}
+type_info {
+  headers {
+    key: "ipv4_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  headers {
+    key: "ipv6_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  header_unions {
+    key: "ip_t"
+    value {
+      members {
+        name: "ipv4"
+        header {
+          name: "ipv4_t"
+        }
+      }
+      members {
+        name: "ipv6"
+        header {
+          name: "ipv6_t"
+        }
+      }
+    }
+  }
+}
+

Here's a p4.WriteRequest to set the value of register_ip[12]: +

+
+
+
update {
+  type: INSERT
+  entity {
+    register_entry {
+      register_id: 369119267
+      index {
+        index: 12
+      }
+      data {
+        header_union {
+          valid_header_name: "ipv4"
+          valid_header {
+            is_valid: true
+            bitstrings: "\x04"
+            bitstrings: # ...
+          }
+        }
+      }
+    }
+  }
+}

8.5.5. enum, serializable enum and error

+

P416 supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or “unsafe” enum) +[5]. For enum types with no underlying type as well as error +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in P4Data to represent enum and +error values. +

+

Serializable enum types have an underlying fixed-width unsigned integer +representation (bit<W>). All named enum members must be assigned an integer +value by the P4 programmer, but not all valid numeric values for the +underlying type need to have a corresponding name. P4TypeInfo includes the +mapping between entry name and entry value. When providing serializable enum +values through P4Data, one must use the assigned integer value (enum_value +bytestring field). P4Runtime does not provide a way for the client to use the +name even when the enum member has one instead of the value, as it makes it +easier for the server to respect the read-write +symmetry principle. +

8.5.6. User-defined types

+

P416 enables programmers to introduce new types [11]. While similar +to typedef, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +translation. When introducing a new type, the +declaration can be annotated with @p4runtime_translation to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for port numbers, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. The @p4runtime_translation annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (bit<W>) and the type exposed to the control plane will also be a +fixed-width unsigned bitstring, with a potentially different bitwidth. It takes +two parameters: a URI (Uniform Resource Identifier) which uniquely identifies +the translation being performed on entities of the new type to the P4Runtime +server and the bitwidth of the bitstring type exposed to the control plane. It +is recommended that the URI includes at least the P4 architecture name and the +type name. +

+

User-defined types are specified using the P4NewTypeSpec message, which has +the following fields: +

+
    +
  • +

    representation, a Protobuf oneof specifying how values of this type are +exchanged between client and server; it can be either: +

    +
      +
    • +

      original_type, if and only if no @p4runtime_translation annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 type declaration is itself a +user-defined type, original_type is obtained by “walking” the chain of +type declarations recursively until a built-in type (e.g bit<W>) is +found. +

    • +
    • +

      translated_type, if and only if the P4 type declaration was annotated +with @p4runtime_translation. It is of type P4NewTypeTranslation, which +itself has two fields uri and sdn_bitwidth , which map to the +two input parameters to the annotation. +

    +
  • +
  • +

    annotations, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration. +

+ +

For example, an architecture in this case PSA may introduce a new type +for port numbers: +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type bit<9> PortId_t;
+

In this case, the P4Info message would include the following P4TypeInfo +message: +

+
+
+
type_info {
+  new_types {
+    key: "PortId_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+

Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (e.g. through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over @p4runtime_translation to enable users +to overwrite annotations included as part of the P4 architecture definition. +

8.5.7. Trade-off for v1.0 Release

+

For the v1.0 release of P4Runtime, it was decided not to replace occurrences of +bytes with P4Data in the p4.v1.FieldMatch message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-release +implementations of P4Runtime. Similarly it has been decided to keep using +bytes to provide action parameter values. However P4Data is used whenever +appropriate for PSA externs and we encourage the use of P4Data in +architecture-specific extensions. +

+

In order to support translation for action +parameters and match fields, we include a type_name field in +p4.config.v1.MatchField and p4.config.v1.Action.Param. +

9. P4 Entity Messages

+

P4Runtime covers P4 entities that are either part of the P416 language, or +defined as PSA externs. The sections below describe the messages for each +supported entity. +

9.1. TableEntry

+

The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action's +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification. +

+

P4Runtime supports inserting, modifying, deleting and reading table entries with +the TableEntry entity, which has the following fields: +

+
    +
  • +

    table_id, which identifies the table instance; the table_id is determined +by the P4Info message. +

  • +
  • +

    match, a repeated field of FieldMatch messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration. +

  • +
  • +

    action, which indicates which of the table's actions to execute in case of +match and with which argument values. +

  • +
  • +

    priority, a 32-bit integer used to order entries when the table's match key +includes a ternary or range match. +

  • +
  • +

    controller_metadata, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. +

  • +
  • +

    meter_config, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    counter_data, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    is_default_action, a boolean flag which indicates whether the table entry is +the default entry for the table. See Default entry +section for more information. +

  • +
  • +

    idle_timeout_ns and time_since_last_hit, which are two fields used to +implement idle-timeout support for the table, if applicable. See +Idle-timeout section for more information. +

+ +

The priority field must be set to a non-zero value if the match key includes a +ternary match (i.e. in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has a TERNARY or RANGE match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches. +

+

The match and priority fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for MODIFY and DELETE updates. When deleting +an entry, these key fields (along with is_default_action) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a keyless +table (the table has an empty match key), the server must reject all attempts to +INSERT a match entry and return an INVALID_ARGUMENT error. +

+

The number of match entries that a table should support is indicated in P4Info +(size field of Table message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P416 specification for the +size property [27]. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +RESOURCE_EXHAUSTED when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached. +

9.1.1. Match Format

+

The bytes fields in the FieldMatch message follow the format described in +Bytestrings. +

+

For “don't care” matches, the P4Runtime client must omit the field's entire +FieldMatch entry when building the match repeated field of the TableEntry +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for “don't care” matches, which is needed +to ensure read-write symmetry. For PSA match types, +a “don't care” match for a specific match key field is defined as follows: +

+
    +
  • +

    For a TERNARY match, it is logically equivalent to a mask of zeros. +

  • +
  • +

    For an LPM match, it is logically equivalent to a prefix_len of zero. +

  • +
  • +

    For a RANGE match, it is logically equivalent to a range which includes all +possible values for the field. +

+ +

Note that there is no “don't care” value for EXACT matches and therefore exact +match fields can never be omitted from the TableEntry message. +

+

The following example shows a P4Runtime message that treats a TERNARY field +as a “don't care” match. The P4 program defines table t with TERNARY +and EXACT fields in its match key: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: ternary;
+    istd.ingress_port: exact;
+  }
+  actions = {
+    drop;
+  }
+}
+

In this P4Runtime request, the client omits the table's TERNARY field +from the repeated match field to indicate a “don't care” match. As shown +below, the match specifies only the EXACT field given by field_id: 2. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 33554439  # Table t's ID.
+    match {
+      # field_id 1 is not present to use the don't care ternary value.
+      field_id: 2
+      exact {
+        value: "\x20"
+      }
+    }
+    action {
+      # Action selection goes here.
+    }
+  }
+}
+

For every member of the TableEntry repeated match field, field_id must be +a valid id for the table, as per the P4Info, and one of the fields in +field_match_type must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an INVALID_ARGUMENT error code. +

+
    +
  • EXACT match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.exact().value()))
+
    +
  • LPM match + +
      +
    • The binary string encoding of the value (when present) must conform to the +Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • “Don't care” bits must be 0 in value. +
+ +
+
+
assert(BytestringValid(match.lpm().value()))
+
+pLen = match.lpm().prefix_len()
+assert(pLen > 0)
+
+trailing_zeros = countTrailingZeros(match.lpm().value())
+assert(trailing_zeros >= field_bits - pLen)
+
    +
  • TERNARY match + +
      +
    • The binary string encoding of the value (when present) and mask (when +present) must conform to the Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • Masked bits must be 0 in value. This constraint taken together +with the Bytestrings requirements means that the +value's binary string is never longer than the mask's binary string. +When the value's string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask. +
+ +
+
+
assert(BytestringValid(match.ternary().value()))
+assert(BytestringValid(match.ternary().mask()))
+assert(match.ternary().value().size() <= match.ternary().mask().size());
+
+value = parseInteger(match.ternary().value())
+mask = parseInteger(match.ternary().mask())
+
+assert(mask != 0)
+
+assert(value & mask == value)
+
    +
  • RANGE match + +
      +
    • The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the Bytestrings +requirements. +
    • +
    • Low bound must be less than or equal to the high bound. +
    • +
    • “Don't care” match must be omitted. +
+ +
+
+
assert(BytestringValid(match.range().low()))
+assert(BytestringValid(match.range().high()))
+
+low = parseInteger(match.range().low())
+high = parseInteger(match.range().high())
+
+assert(low <= high)
+
+assert(low != min_field_value || high != max_field_value)

9.1.2. Action Specification

+

The TableEntry action field must be set for every INSERT and MODIFY +update, except when resetting the default entry. Based on +the implementation property value of the P4 table, the oneof in the +TableAction message will either be: +

+
    +
  • +

    an Action specification for direct tables (with no P4 implementation +property) +

  • +
  • +

    an action profile member id for indirect tables for which the implementation +property is an action profile with no selector. +

  • +
  • +

    an action profile member id or group id for indirect tables for which the +implementation property is an action profile with selector. +

  • +
  • +

    an ActionProfileActionSet specification for indirect tables for +which the implementation property is an action profile with +selector. This usage is described in One Shot Action Selector +Programming +

+ +

If the action field is not set (and if is_default_action is false) or if the +oneof does not match the table description in the P4Info (e.g. the oneof is +action_profile_member_id for a direct table), the server must return an +INVALID_ARGUMENT error code. +

+

The Action Protobuf message has the following fields: +

+
    +
  • +

    action_id, which identifies the action instance; the action_id is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an INVALID_ARGUMENT error +code. If the client uses a valid action_id for the table but does not +respect the action scope specified in P4Info (e.g. tries to set a TABLE_ONLY +action as the default action), the server must return a PERMISSION_DENIED +error code. +

  • +
  • +

    params: a repeated Protobuf field of action parameter values, each encoded +as a Param message. For each parameter, param_id must be valid for the +action (as per the P4Info) and value must follow the format described in +Bytestrings. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an INVALID_ARGUMENT error code +if a parameter id is missing, if an extra parameter id not found in the +P4Info was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +Bytestrings format. +

+ +

For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a NOT_FOUND error code. +

9.1.3. Default Entry

+

According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer or defaults to NoAction +(which is a no-op) otherwise and assuming it is not declared as const, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow INSERT and DELETE updates on the default entry and the +P4Runtime server must return an INVALID_ARGUMENT error code if the client +attempts one. +

+

The default entry is identified by setting the is_default_action boolean field +to true. When this flag is set to true, the repeated match field must be empty +and the priority field must be set to zero, otherwise the P4Runtime server +must return an INVALID_ARGUMENT error code. When performing a MODIFY update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its controller_metadata value as well as the configurations for its +direct resources will be reset to their defaults. If +the default entry is constant (as indicated by the P4 program and the P4Info +message), the server must return a PERMISSION_DENIED error code if the client +attempts to modify it. +

+

Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to direct resources. +

+

In this P4Runtime release, we have decided to restrict the default entry for +indirect tables tables with an ActionProfile or ActionSelector +implementation property to a constant NoAction action entry, with the hope +that it would simplify the implementation of the P4Runtime service. +

9.1.4. Constant Tables

+

Constant tables are defined as tables whose match entries are immutable. They +are identified by the is_const_table flag in P4Info. The only write updates +which are allowed for constant tables are MODIFY operations on the default +action, assuming the default action itself is not constant. If the P4Runtime +client attempts to perform any other kind of write update on a constant table, +the server must return a PERMISSION_DENIED error. However, the contents of +such tables can be queried by the client through a ReadRequest. When reading +static (immutable) entries from a constant table, the following fields and +only these fields , must be set by the server: table_id, match, action, +priority and is_default_action. In particular, we assume that constant +tables cannot be assigned direct resources and idle timeout is not supported for +static entries. If the table requires a priority value for entries, the server +must populate the priority field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P416 does not support assigning explicit priorities to static +entries. When a priority value is required (e.g. for tables including RANGE +and / or TERNARY matches in the case of PSA), it is inferred based on the +order in which entries appear in the table declaration. +

9.1.5. Wildcard Reads

+

When performing a ReadRequest, the P4Runtime client can select all entries +from one or all tables on the target and use several of the TableEntry fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as priority and “unset” for message fields such as match. The following +fields may be used to select and filter results: +

+
    +
  • table_id: If default (0), entries from all tables including constant +tables will be selected and no other filter can be used. Otherwise only +the specified table will be considered. +
  • +
  • match: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned. +
  • +
  • action: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an action_id (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id. +
  • +
  • priority: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value. +
  • +
  • controller_metadata: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +controller_metadata value. +
  • +
  • is_default_action: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered. +
+ +

For example, in order to read all entries from all tables from device 3, the +client can use the following ReadRequest message. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0
+    priority: 0
+    controller_metadata: 0
+  }
+}
+

In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following ReadRequest +message: +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+    priority: 11
+    controller_metadata: 0
+  }
+}
+

The canonical representation of “don't care” matches, combined with the ability +to do a wildcard read on all table entries by leaving the match field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single “don't care” entry or to do a wildcard +read. If a table has no fields with match kind EXACT, it is possible via +P4Runtime to add an entry that is “don't care” for all fields (i.e. has an empty +match field) but is not the default entry (i.e. is_default_action is +false). When reading this entry from the table, there is no way to read only +that entry from the table, because it would require providing an unset match +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single LPM match: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: lpm;
+  }
+  actions = {
+    drop; fwd;
+  }
+}
+

The following WriteRequest message can be used to add 2 entries: +

+
+
+
device_id: 3
+entities {
+  table_entry { # don't care entry
+    table_id: 0x0212ab34
+    # ...
+  }
+  table entry {
+    table_id: 0x0212ab34
+    match {
+      field_id: 1
+      lpm {
+        value: 0x0a000000
+        prefix_len: 8
+      }
+    # ...
+  }
+}
+

The first entry is a “don't care” entry, while the second one matches all +10.0.0.0/8 addresses. The second entry has higher priority than the first one. +

+

The following ReadRequest message will return all entries in the table, not +just the “don't care” entry. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+  }
+}
+

This issue also exists for tables with TERNARY and / or RANGE +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the “don't care” entry will be returned to the +client. If the client uses distinct priority values for all entries which is +strongly recommended to achieve deterministic behavior , +then there is no ambiguity because the wildcard read will actually return a +single entry (the “don't care” entry) as long as the priority field is set to +the correct value. +

9.1.6. Direct Resources

+

In addition to the DirectCounterEntry and DirectMeterEntry entities, +P4Runtime support reading and writing direct resources as part of the +TableEntry message. This is convenient for two reasons: +

+
    +
  • +

    A table entry and its direct resources can be read with a single entity when +doing a Read RPC call +

  • +
  • +

    The initial configuration for an entry's direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can “hit” the table entry without +executing the appropriate meter entry. +

+ +

Once the table entry has been inserted, the P4Runtime client is free to use the +DirectCounterEntry and DirectMeterEntry messages for read and write +operations on DirectCounter and DirectMeter instances. For example, it is +usually more convenient as well as more efficient to use DirectCounterEntry to +query a counter entry value rather than use TableEntry, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry. +

+

The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does not need to be “executed” in +every action bound to the table. It is an error to provide a direct resource +configuration in a TableEntry message when programming an action that does not +execute the direct resource, and the server must return an INVALID_ARGUMENT +error code. +

+

We leverage Protobuf's ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the TableEntry message. The list below describes how +the server must handle the meter_config and counter_data fields for read and +write requests, based on whether the fields are set or not. We do not cover +error cases in the list, i.e. we assume that we are dealing with a table which +is assigned a direct counter / a direct meter, and that the action being used +for the table entry “executes” the direct resource appropriately. +

+
    +
  • +

    meter_config field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets). +
      • +
      • if set: The initial configuration for the meter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The meter entry's configuration is reset to the default +(meter returns GREEN for all packets). +
      • +
      • if set: The value provided by the client is used to re-configure +the meter entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the meter entry's +configuration (meter_config is unset in the response). +
      • +
      • if set: If the meter entry's configuration is the default +configuration, meter_config is unset in the response. Otherwise, the +response includes the meter entry's configuration that was written by +the client earlier. This respects the “read-write symmetry” principle. +
    +
  • +
  • +

    counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for the counter entry is the default +(0). +
      • +
      • if set: The initial value for the counter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The counter entry's value is not changed. +
      • +
      • if set: The value provided by the client is written to the counter +entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the counter entry's value +(counter_data is unset in the response). +
      • +
      • if set: The response includes the counter entry's value read from +the target. +
    +
+ +

In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +meter_config field unset when inserting or modifying a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the TableEntry message +(i.e. the meter_config field must be set to match the existing configuration). +

9.1.7. Idle-timeout

+

P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not “hit” (i.e. not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification using the +IdleTimeoutNotification message to the master client, which can then take +action, such as remove the idle table entry. +

+

Two fields of the TableEntry Protobuf message are used to implement idle +timeout: +

+
    +
  • +

    idle_timeout_ns: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, i.e. no +IdleTimeoutNotification message will ever be generated for this entry. When +a client reads a TableEntry, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry. +

  • +
  • +

    time_since_last_hit: a Protobuf message with a single field (elapsed_ns) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The time_since_last_hit field must be unset for a +TableEntry write. When reading a table entry, time_since_last_hit must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0. +

+ +

These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an INVALID_ARGUMENT error code if at least one of these +conditions is met: +

+
    +
  • idle_timeout_ns is set to a non-zero value, or +
  • +
  • time_since_last_hit is set +
+ +

The target should do its best to approximate the idle_timeout_ns value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the TableEntry write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for time_since_last_hit. +

+

P4Runtime does not support idle timeout for default entries. When the +is_default_action flag is set in a TableEntry message, idle_timeout_ns +must be set to 0 (default) and time_since_last_hit must be unset. If the +server receives a TableEntry message which violates this, it must return an +INVALID_ARGUMENT error. +

+

For more information about idle timeout, in particular regarding +IdleTimeoutNotification, please refer to the Table idle timeout +notifications section. +

9.2. ActionProfileMember & ActionProfileGroup

+

P4Runtime defines an API for programming a PSA ActionProfile extern using +ActionProfileMember messages. A PSA ActionSelector extern can be programmed +using both ActionProfileMember and ActionProfileGroup messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table t for L3 routing, implemented with an action +selector as. +

+
+
+
ActionSelector(HashAlgorithm.crc32,
+               /*size = */ 32w1024,
+               /*output_width = */ 32w10) as;
+
+action set_nhop(PortId_t p, EthAddr smac, EthAddr dmac) {
+  istd.egress_port = p;
+  hdr.ethernet.smac = smac;
+  hdr.ethernet.dmac = dmac;
+}
+
+table t {
+  key = {
+    hdr.ipv4.dip: lpm;  // LPM on destination IP address
+  }
+  actions = {
+    set_nhop;
+  }
+  implementation = as;
+}
+

When programming table t in the example above, a P4Runtime client should +specify the TableAction in the TableEntry to be a reference to either an +action profile member or group. The reference is a uint32 identifier that +uniquely identifies a member or group programmed in the action selector as. +

+

If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata. +

+

If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata. +

9.2.1. Action Profile Member Programming

+

Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a uint32 identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the actions +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the actions attributes of the +tables must have an identical list of P4 actions. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector. +

+

An ActionProfileMember entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info. +

  • +
  • +

    member_id is the uint32 identifier of the action profile member entry being +updated. +

  • +
  • +

    action is the specification of the P4 action instance bound to the action +profile member entry. +

+ +

An action profile member may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an ALREADY_EXISTS error +code. The action specification must be provided, or the server must return +INVALID_ARGUMENT. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return RESOURCE_EXHAUSTED. +
  • +
  • MODIFY: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return NOT_FOUND, +and the action specification must be provided, or the server must return +INVALID_ARGUMENT. +
  • +
  • DELETE: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a NOT_FOUND error code. The member +must not be part of an action profile group, or the server must return +FAILED_PRECONDITION. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return FAILED_PRECONDITION. member_id is the only field which is +considered when performing a DELETE and every other field will be ignored. +
+

9.2.2. Action Profile Group Programming

+

Action profile groups are entries in an ActionSelector and are referenced by a +uint32 identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type. +

+

An ActionProfileGroup entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionSelector +extern instance, as defined in P4Info. +

  • +
  • +

    group_id is the uint32 identifier of the action profile group entry being +updated. +

  • +
  • +

    members is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields: +

    +
      +
    • member_id for looking up the member table in the selector. +
    • +
    • weight specifying the probability of the member's selection at +runtime. 0 is not a valid weight value and the server must return +INVALID_ARGUMENT if the client attempts to use it. +
    • +
    • watch is the controller-defined 32-bit port number that the member's +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. +
    +
  • +
  • +

    max_size is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +MODIFY update. See the subsection below for the rules on setting +max_size. +

+ +

An action profile group may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new group entry bound to a set of existing action profile +members. The group_id must be different from ids of already programmed +groups for that selector, or the server must return an ALREADY_EXISTS error +code. All members specified in the group must exist in the selector, or the +server must return NOT_FOUND. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target. +
  • +
  • MODIFY: Modify the member set specification of an existing group entry. An +entry with the group_id must exist, or the server must return +NOT_FOUND. All members specified in the group entry must exist in the +selector, or the server must return NOT_FOUND. The value of max_size must +be identical to the value used when inserting the group, otherwise an +INVALID_ARGUMENT error is returned. +
  • +
  • DELETE: Delete the group entry and deallocate the group_id. The group must +not be referenced in the table action of any table entry, or the server must +return a FAILED_PRECONDITION error code. If the group_id is invalid, the +server must return NOT_FOUND. group_id is the only field which is +considered when performing a DELETE and every other field will be ignored. +
+ +

When setting the group membership with INSERT or MODIFY, the members +repeated field must not include duplicates, i.e. members with the same +member_id. The weight field is used instead to logically “repeat” the member +inside the group. +

+

It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation “stores” the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made. +

9.2.2.1. Rules on Setting max_size
+

The valid values for max_size depend on the static max_group_size included +in the P4Info message: +

+
    +
  • +

    If max_group_size is greater than 0, then max_size must be greater than 0, +and less than or equal to max_group_size. We assume that the target can +support selector groups for which the sum of all member weights is up to +max_group_size, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If max_size is greater than max_group_size, the server +must return INVALID_ARGUMENT. +

  • +
  • +

    Otherwise (i.e. if max_group_size is 0), the P4Runtime client can set +max_size to any value greater than or equal to 0. +

    +
      +
    • +

      A max_size of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (INSERT or MODIFY), the target must return a +RESOURCE_EXHAUSTED error. +

    • +
    • +

      If max_size is greater than 0 and the value is not supported by the +target, the server must return a RESOURCE_EXHAUSTED error at +group-creation time. +

    +
+

9.2.3. One Shot Action Selector Programming

+

P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids. +

+

One shots are programmed by choosing the ActionProfileActionSet message as the +TableAction. The ActionProfileActionSet message consists of a set of +ActionProfileAction messages, which in turn have the following fields: +

+
    +
  • +

    action is one of the actions specified by the table that is being +programmed. +

  • +
  • +

    weight specifying the probability of the action's selection at runtime. 0 is +not a valid weight value and the server must return INVALID_ARGUMENT if +the client attempts to use it. The sum of all weights across all +ActionProfileAction messages for that ActionProfileActionSet message must +not exceed the max_group_size specificed in the P4Info (if greater than 0), +or the server must return INVALID_ARGUMENT. +

  • +
  • +

    watch is the controller-defined 32-bit port number that the action's +liveness depends on. At runtime, the action must be excluded from selection if +the watch port is down. +

+ +

Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics. +

+

To preserve read-write symmetry, an implementation must answer ReadRequests +with the original one shot messages. It may not return a desugared version of +the one shot message. +

+

For example, consider the action selector table defined +here. This table could be programmed +with the following one shot update: +

+
+
+
table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action {
+    action_profile_action_set {
+      action_profile_actions {
+        action { /* set nexthop 1 */ }
+        weight: 1
+        watch: 1
+      }
+      action_profile_actions {
+        action { /* set nexthop 2 */ }
+        weight: 2
+        watch: 2
+      }
+      action_profile_actions {
+        action { /* set nexthop 3 */ }
+        weight: 3
+        watch: 3
+      }
+    }
+  }
+}
+

Which would be equivalent to the following updates, where GROUP_ID, +MEMBER_ID_1, MEMBER_ID_2, and MEMBER_ID_3 are unused ids: +

+
+
+
action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_1
+  action { /* set nexthop 1 */ }
+}
+action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_2
+  action { /* set nexthop 2 */ }
+}
+action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_3
+  action {  /* set nexthop 3 */ }
+}
+action_profile_group {
+  action_profile_id: 0x11ab12cd
+  group_id: GROUP_ID
+  members {
+    member_id: MEMBER_ID_1
+    weight: 1
+    watch: 1
+  }
+  members {
+    member_id: MEMBER_ID_2
+    weight: 2
+    watch: 2
+  }
+  members {
+    member_id: MEMBER_ID_3
+    weight: 3
+    watch: 3
+  }
+}
+table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action { action_profile_group_id: GROUP_ID }
+}
+

Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure correct ordering between the dependent +updates. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct WriteRequest batches are required. +

+

It is possible to include several ActionProfileAction messages with the same +exact action specification in one ActionProfileActionSet message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the weight field. Note that to preserve read-write symmetry, the server +must not coalesce multiple ActionProfileAction messages with the same action +specification into one. +

+

All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with ActionProfileMember and +ActionProfileGroup messages. Programming some entries with one shots, and +other entries with ActionProfileMember and ActionProfileGroup messages is +not allowed, and the server must return the error code INVALID_ARGUMENT in +that case. +

+

A P4Runtime server must support the one shot style of programming tables with +an action selector implementation. Support for the ActionProfileMember and +ActionProfileGroup style is optional. If ActionProfileMember and +ActionProfileGroup are not supported by a server, it must return an +UNIMPLEMENTED error for every ActionProfileMember or ActionProfileGroup +message that it receives. +

9.2.4. Constraints on action selector programming

+

The PSA specification states that the following features are optional in +action selector implementations [20]: +

+
    +
  1. Support for non-empty groups where in the same group, different members are +bound to different actions. +
  2. +
  3. Predictable data plane behavior when a matched table entry points to an empty +group. +
+ +

For 1., if a client tries to INSERT or MODIFY a group with members bound to +different actions, the server should return UNIMPLEMENTED if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return UNIMPLEMENTED (modifying the action parameter values must be +supported, however). +

+

PSA 1.1 introduces the psa_empty_group_action table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. psa_empty_group_action is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of psa_empty_group_action at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +NoAction. Even when psa_empty_group_action is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of psa_empty_group_action mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming. +

+

The PSA specification includes a discussion on how to implement +psa_empty_group_action in software in the P4Runtime server +[23]. +

9.3. CounterEntry & DirectCounterEntry

+

PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The CounterData +P4Runtime message can be used for all three types of PSA counters PACKETS, +BYTES and PACKETS_AND_BYTES and consists of the following fields: +

+
    +
  • byte_count is an int64, corresponding to the number of octets. +
  • +
  • packet_count is an int64, corresponding to the number of packets. +
+ +
+
+
message CounterData {
+  int64 byte_count = 1;
+  int64 packet_count = 2;
+}
+

P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of byte_count and packet_count fields, which +is equivalent to specifying the counter type PACKETS_AND_BYTES. Counters may +be defined as direct or indirect (indexed) instances. +

9.3.1. DirectCounterEntry

+

A direct counter is a direct resource associated with a TableEntry (see +Direct Resources). The counter_data field of the +TableEntry message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +DirectCounterEntry message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed. +

+
+
+
message DirectCounterEntry {
+  TableEntry table_entry = 1;
+  CounterData data = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectCounterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match TableEntry.match of the table entry +to which this direct counter entry is associated. If a matching TableEntry +is not found, the server returns the error code NOT_FOUND. +

  • +
  • +

    data is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified. +

+ +

Specifying DirectCounterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read the contents of a +DirectCounter: +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the counter value in the counter_data field of the TableEntry message +(see Direct resources). +

  • +
  • +

    Explicitly request the counter value by including the DirectCounterEntry in +the ReadRequest. The table_entry.match field must match the TableEntry +whose counter is being read. If no such entry is found, the server returns the +error code NOT_FOUND. +

+

9.3.2. CounterEntry

+

An indirect or indexed counter is not associated with a specific TableEntry +and may be updated independently of any action. It may be read or written using +the P4Runtime CounterEntry message whose fields are defined as follows: +

+
    +
  • +

    counter_id is a uint32, the unique identifier for the counter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +the counter array. +

  • +
  • +

    data is a Protobuf message of type CounterData, which represents the +counter value. +

+ +
+
+
message CounterEntry {
+  uint32 counter_id = 1;
+  Index index = 2;
+  CounterData data = 3;
+}
+

The CounterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the counter entries in the +array have default value 0. +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect counter instance whose unique id is counter_id +and array index is specified by index. The counter value is set to the value +specified by the client in the data field. Note that the counter value is +not modified if this Protobuf field is not set. If index is omitted all +counter values in the array will be set to the value provided by the +client. The server must return INVALID_ARGUMENT for a negative index value +and OUT_OF_RANGE if the index value exceeds the size of the counter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a ReadRequest by including a CounterEntry +entity for each of the instances, specifying the counter_id and +index. Wildcard reads are also supported as follows. +

+
    +
  • +

    If the counter_id field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id counter_id. +

+

9.4. MeterEntry & DirectMeterEntry

+

Meters are an advanced mechanism for keeping statistics, involving stateful +“marking” and usually “throttling” of packets based on configured rates of +traffic. The PSA metering function is based on the Two Rate Three Color Marker +(trTCM) defined in RFC 2698 [2]. The trTCM meters an arbitrary packet +stream using two configured rates the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes and +“marks” its packets as GREEN, YELLOW or RED based on the observed rate. +

+

A meter may be configured as a direct or indirect instance, similar to a +counter. The MeterConfig P4Runtime message represents meter configuration. +

+
+
+
message MeterConfig {
+  int64 cir = 1;  // Committed Information Rate
+  int64 cburst = 2;  // Committed Burst Size
+  int64 pir = 3;  // Peak Information Rate
+  int64 pburst = 4;  // Peak Burst Size
+}

9.4.1. DirectMeterEntry

+

A direct meter is a direct resource associated with a TableEntry (see Direct +resources). The meter_config field of the TableEntry +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +DirectMeterEntry message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed. +

+
+
+
message DirectMeterEntry {
+  TableEntry table_entry = 1;
+  MeterConfig config = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectMeterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match the match key of the TableEntry +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching TableEntry is not found, +the server returns the error code NOT_FOUND. +

  • +
  • +

    config is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets). +

+ +

Specifying DirectMeterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read a DirectMeter config. +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the meter config in the meter_config field of the TableEntry +message (see Direct resources). +

  • +
  • +

    Explicitly request the meter configuration by including the DirectMeterEntry +in the ReadRequest. The table_entry.match field must match the +TableEntry whose meter config is being read. If no such entry is found, the +server returns the error code NOT_FOUND. +

+

9.4.2. MeterEntry

+

An indirect or indexed meter is not associated with a specific TableEntry and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime MeterEntry message whose fields are defined as +follows: +

+
    +
  • +

    meter_id is a uint32, the unique identifier for the meter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +a meter array. +

  • +
  • +

    config is a Protobuf message of type MeterConfig, which represents the +meter configuration. +

+ +
+
+
message MeterEntry {
+  uint32 meter_id = 1;
+  Index index = 2;
+  MeterConfig config = 3;
+}
+

The MeterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the meter entries in the +array have a default configuration (GREEN for all packets). +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect meter instance whose unique id is meter_id and +array index is specified by index. The meter is reconfigured using the +config field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the index field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if config is unset). The server must return INVALID_ARGUMENT for a +negative index value and OUT_OF_RANGE if the index value exceeds the size of +the meter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a ReadRequest by including a MeterEntry entity for each +of the instances, specifying the meter_id and index. Wildcard reads are also +supported as follows: +

+
    +
  • +

    If the meter_id field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id meter_id. +

+

9.5. PacketReplicationEngineEntry

+

The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets. +

9.5.1. MulticastGroupEntry

+

Multicasting is achieved in PSA programs by setting the multicast_group +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the MulticastGroupEntry API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example. +

+
+
+
control arp_multicast(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ethernet.isValid() &&
+        hdr.ethernet.eth_type == ETH_TYPE_ARP) {
+      smeta.multicast_group = (MulticastGroup_t) 1;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    multicast_group_entry {
+      multicast_group_id: 1
+      replicas { egress_port: 5 instance: 1 }
+      replicas { egress_port: 12 instance: 2 }
+      replicas { egress_port: 18 instance: 3 }
+      replicas { egress_port: 24 instance: 4 }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +PSA Metadata Translation section. +

+

The egress packets may be distinguished for further processing in the egress +using the instance metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 multicast_group metadata is set to a value that is not +programmed in the PRE, then the packet is dropped. +

+

A multicast group may be inserted, modified or deleted as per the following +semantics. +

+
    +
  • INSERT: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The multicast_group_id field is a uint32 and must not exceed +the maximum value supported by the target. The PSA specification states that 0 +is a special value which indicates that no multicast replication is to be +performed for a packet [22]. Therefore multicast_group_id must +never be set to 0. If one of these constraints is violated, the P4Runtime +server must return an INVALID_ARGUMENT error. The replica instance ID is +also a uint32, and its value may not exceed the maximum allowed by the +target for the EgressInstance_t type (0 is allowed), or the server must +return an INVALID_ARGUMENT error. The egress port must be a 32-bit SDN port +number and must refer to a singleton port. No two replicas may have identical +values of both egress_port and instance, or the server must return +INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify the set of replicas for a given multicast group entry, +indexed by the given multicast_group_id. Same restrictions as INSERT apply +here. +
  • +
  • DELETE: Delete the multicast group indexed by the given +multicast_group_id. The replicas need not be provided for this +operation. Any packets with their multicast_group metadata in the data plane +set to the deleted multicast_group_id will be dropped. +
+

9.5.2. CloneSessionEntry

+

PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +clone_session_id identifier and a boolean flag clone in the packet +metadata. The clone_session_id serves as a handle to the clone attributes, +namely a set replicas of (egress port, instance) pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +CloneSessionEntry API. +

+

The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the clone_low_ttl control block is applied in the ingress +pipeline to create an ingress-to-egress clone. +

+
+
+
control clone_low_ttl(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ipv4.isValid() &&
+        hdr.ipv4.ttl <= LOW_TTL_THRESHOLD) {
+      smeta.clone_session_id = 10w100;
+      smeta.clone = true;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    clone_session_entry {
+      session_id: 100
+      replicas { egress_port: 0xfffffffd instance: 1 } # to CPU
+      class_of_service: 2
+      packet_length_bytes: 4096
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type CloneSessionId_t [22]). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes. +

+

The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port 0xfffffffd; see +Translation of Port Numbers). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port. +

+

If the clone_session_id data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created. +

+

A clone session may be inserted, modified or deleted as per the following +semantics: +

+
    +
  • INSERT: Add a new clone session entry bound to a set of egress ports and +replica IDs. The session_id is a uint32, must be unique across all clone +session entries, and its value may not exceed the maximum supported by the +target (0 is allowed), or the P4Runtime server must return an +INVALID_ARGUMENT error. The replica instance ID is also a uint32, and +its value may not exceed the maximum allowed by the target for the +EgressInstance_t type (0 is allowed), or the server must also return an +INVALID_ARGUMENT error. The egress port in the replica must be a 32-bit SDN +port number and must refer to a singleton port. The class of service for each +clone packet instance will be set to the value programmed in the clone session +entry (class_of_service field). This value must be a valid value for the PSA +CloneSessionId_t type, which supports runtime translation by default +[22], or the server must return INVALID_ARGUMENT. See PSA +Metadata Translation for more +information. The packet_length_bytes field must be set to a non-zero value +if the clone packet should be truncated to the given value (in bytes). If the +packet_length_bytes field is 0 (default), no truncation on the clone will be +performed. +
  • +
  • MODIFY: Modify the attributes of a given clone session entry, indexed by the +given clone_session_id. Same restrictions as INSERT apply here. +
  • +
  • DELETE: Delete the clone session indexed by the given +clone_session_id. Other fields need not be provided for this operation. Any +packet with their clone_session_id metadata in the data plane set to the +deleted session_id will no longer be cloned. +
+

9.6. ValueSetEntry

+

Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL ethtypes is used to +transition the parser state machine to the parse_trill_types state. +

+
+
+
state parse_l2 {
+  @id(1) value_set<ETH_TYPE_BITWIDTH>(MAX_TRILL_TYPES) trill_types;
+  extract(hdr.ethernet);
+  select (hdr.ethernet.eth_type) {
+    ETH_TYPE_IPV4: parse_ipv4;
+    ETH_TYPE_IPV6: parse_ipv6;
+    trill_types:   parse_trill_types;
+    _:             reject;
+  }
+}
+

The corresponding entry in the P4Info for this Value Set is: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "trill_types"
+  }
+  match {
+    id: 1
+    bitwidth: <ETH_TYPE_BITWIDTH>
+    match_type: EXACT
+  }
+  size: <MAX_TRILL_TYPES>
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0x22f3 }
+      }
+      match {
+        field_id: 1
+        exact { value: 0x893b }
+      }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the parse_trill_types state. +

+

A ValueSetEntry entity update message has the following fields: +

+
    +
  • +

    value_set_id is the uint32 identifier of the Value Set instance, as +defined in P4Info. +

  • +
  • +

    members is a repeated field of type ValueSetMember. When “selecting” +against a Value Set, every member will be considered and if at least one +“matches”, the corresponding parser transition will be taken. Each +ValueSetMember contains a repeated field of FieldMatch messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a ValueSetMember if and only if +it matches all its FieldMatch messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. FieldMatch messages in a ValueSetEntry follow +the same rules as in a TableEntry. +

+ +

A ValueSetEntry may only be modified. If the update type is INSERT or +DELETE, the server must return an INVALID_ARGUMENT error. If the update type +is MODIFY, the server writes the members given in the repeated field to the +Value Set entry indexed by the given value_set_id. The maximum number of +matches must not exceed the maximum size given by the size field in P4Info of +the Value Set, otherwise the server must return a RESOURCE_EXHAUSTED error. To +empty a Value Set (i.e. restore it to its initial state), the P4Runtime client +can perform a MODIFY update with an empty members repeated field. +

+

To facilitate read-write symmetry, the server must +return an ALREADY_EXISTS error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary and range matches: +overlapping entries do not need to be ordered and the parse state transition +is determined by whether or not the packet matches at least one entry in the +set. +

+

See Appendix A.2 for a more complex Value Set example. +

9.7. RegisterEntry

+

The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The RegisterEntry P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations. +

+

RegisterEntry has the following fields: +

+
    +
  • +

    register_id, which identifies the PSA Register extern instance which is +being accessed by the client; the register_id is specified by the P4Info +message. +

  • +
  • +

    index, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the RegisterEntry message +used for the request. When an index is provided , the server must validate +its value, and return INVALID_ARGUMENT for a negative index or +OUT_OF_RANGE if the index exceeds the size of the register array. +

  • +
  • +

    data: the data to be written to the array (if RegisterEntry is part of a +WriteRequest message) or the data read from the array (if RegisterEntry is +part of a ReadResponse message). The data field is a P4Data message and +must match the format described by the type_spec field of the corresponding +Register entry in the P4Info, or the server must return an INVALID_ARGUMENT +error. +

+

9.8. DigestEntry

+

A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly. +

+

The DigestEntry P4Runtime entity is used to configure how the device must +generate digest messages. The DigestEntry Protobuf message is not used to +carry digest data, which is done on the StreamChannel bidirectional stream +using the DigestList (digest data sent by the target to the client) and +DigestListAck (digest data acknowledgments sent by the client to the target) +Protobuf messages. +

+

In this section, we refer to the data learned by a single data plane call to +Digest<T>::pack as a “digest message” and we use “digest list” to designate +the list of digest messages bundled by the P4Runtime service in a single +DigestList stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are “duplicate” if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are “distinct” +if they are not duplicate. +

+

DigestEntry has the following fields: +

+
    +
  • +

    digest_id, which identifies the PSA Digest extern instance which emitted the +data; the digest_id is determined by the P4Info message. +

  • +
  • +

    config, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +digest_id; these parameters are: +

    +
      +
    • max_timeout_ns: the maximum server buffering delay in nanoseconds for an +outstanding digest message. +
    • +
    • max_list_size: the maximum digest list size in number of digest +messages sent by the server to the client as a single DigestList +Protobuf message. +
    • +
    • ack_timeout_ns: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data. +
    +
+ +

Here is the significance of the different Update types for DigestEntry: +

+
    +
  • INSERT: Enable server generation of DigestList messages for given digest +instance and use provided configuration parameters. +
  • +
  • MODIFY: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance. +
  • +
  • DELETE: Disable server generation of DigestList messages for given digest +instance. +
+ +

A server should buffer digest messages until either: +

+
    +
  • max_timeout_ns time has passed since the first digest message was added to +the empty buffer, or +
  • +
  • max_list_size distinct digest messages have been received from the +data plane and added to the buffer +
+ +

At which point the server should, with best effort, generate a DigestList +stream message with the buffer contents and send it to the master client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software. +

+

To avoid sending duplicate digest messages across different DigestList +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the master client indicates that it has received the +digest list and acted on it. The server must keep a “cache” containing the set +of all digest messages that have been sent, but not acknowledged yet by the +master client, up-to ack_timeout_ns in the past. The server must delete all +cache entries for a given digest list when they are at least ack_timeout_ns +old or when a matching DigestListAck message (i.e. with the same digest_id +and list_id fields as the DigestList message) is received. +

+

The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged DigestList messages. +

+

When max_timeout_ns is set to 0 and / or max_list_size is set to 1, the +server should, with best effort, generate a DigestList message for every +digest message generated by the data plane which is not already in the cache. If +ack_timeout_ns is set to 0, the cache must always be an empty set. If +max_list_size is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +max_timeout_ns configuration parameter. +

+

The P4Runtime server may empty the digest message cache in case of a client +mastership change. +

+

Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server: +

+
+
+
DigestStream stream;
+DigestCache cache;
+DigestBuffer buffers;
+
+// sends digest list when it is ready
+send_buffer(Id digest_id) {
+  buffer = buffers[digest_id];
+  stream.write(DigestList(buffer));
+  cache.merge(buffer);  // updates cache with new digest list
+  buffer.clear();
+}
+
+// callback which handles data plane digest messages from device
+handle_dataplane_digest(Digest msg) {
+  digest_id = msg.digest_id();
+  buffer = buffers[digest_id];
+  if (msg in cache OR msg in buffer) return;
+  buffer.enqueue(msg);
+  if (buffer.length() < max_list_size(digest_id)) return;
+  send_buffer(digest_id);
+}
+
+// callback which handles ack messages received on the stream
+handle_stream_ack(DigestListAck ack) {
+  // clear all cache entries matching the tuple (digest_id, list_id)
+  cache.erase( (ack.digest_id(), ack.list_id() )
+}
+
+// loop to enforce timeouts
+while (true) {
+  now = now();
+  // check for buffers that need to be sent
+  for ((digest_id, buffer) in buffers) {
+    if (now - buffer.first_enq_time() >= max_timeout_ns(digest_id))
+      send_buffer(buffer_id);
+  }
+  // check for expired entries in cache
+  for ((digest_id, list_id, sent_time) in cache) {
+    if (now - sent_time >= ack_timeout_ns(digest_id))
+      cache.erase( (digest_id, list_id) );
+  }
+  sleep(X);
+}

9.9. ExternEntry

+

This is used to support a P4 extern entity that is not part of PSA. It is +defined as: +

+
+
+
message ExternEntry {
+  uint32 extern_type_id = 1;
+  uint32 extern_id = 2;
+  google.protobuf.Any entry = 3;
+}
+

Each ExternEntry entity maps to an Extern message in the +P4Info and an ExternInstance message within that +message. The extern_type_id field must be equal to the one in +ExternEntry. The extern_id field must be equal to the ID included in the +preamble of the corresponding ExternInstance message. +

+

entry itself is embedded as an Any Protobuf message [28] to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on Extending P4Runtime for non-PSA +Architectures for more information. +

10. Error Reporting Messages

+

P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case. +

+

gRPC uses grpc::Status [29] to represent the status returned by an +RPC. It has 3 attributes: +

+
+
+
StatusCode code_;
+grpc::string error_message_;
+grpc::string binary_error_details_;
+

The code_ represents a canonical error [31] and describes the +overall RPC status. The error_message_ is a developer-facing error message, +which should be in English. The binary_error_details_ carries a serialized +google.rpc.Status message [26] message, which has 3 fields: +

+
+
+
int32 code = 1;  // see code.proto
+string message = 2;
+repeated google.protobuf.Any details = 3;
+

The code and message fields must be the same as code_ and error_message_ +fields from grpc::Status above. The details field is a list that consists of +p4.Error messages that carry error details for individual elements inside +batch-request RPCs (e.g. Write and Read). p4.Error includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices [31]. +

+

Figure 7 illustrates how these messages fit together. +

+
+

error-report +

+
+ +
Figure 7. P4Runtime Error Report Message Format
+

gRPC provides utility functions ExtractErrorDetails() and SetErrorDetails() +[30] to easily convert between grpc::Status and +google.rpc.Status. +

+

Please see sections on individual P4Runtime RPCs for details on how +grpc::Status is populated for reporting errors. +

11. Atomicity of Individual Write and Read Operations

+

Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane apply +operation, and every single Write operation on a table that inserts, deletes, +or modifies one table entry, the apply operation should behave as if that +Write operation has not yet occurred, or as if the Write operation is +complete. The P4 program should never behave as if the Write operation is +partially complete. These guarantees also apply to extern instances: Read and +Write operations on extern entities must execute atomically relative to extern +data plane methods. +

+

The atomicity guarantees provided by P4Runtime for individual Read and Write +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification [21]. +

+

The P416 language introduces an @atomic annotation [13], to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the @atomic annotation for Write +operations, as well as non-wildcard Read operations, +relative to data plane execution. Consider the following P4 example written for +PSA: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024) r1;
+
+  apply {
+    // ...
+    @atomic {
+        Value_t v = r1.read((Index_t)1);
+        v = v + 1;
+        r1.write((Index_t)1, v);
+    }
+  }
+}
+

If a P4Runtime server is processing messages which write to Register r1 at +index 1, these writes must not happen between the data plane read and +write. +

+

Now let's consider the following example: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024, (Value_t)0 /* initial value */) r1;
+
+  apply {
+    @atomic {
+        r1.write((Index_t)1, (Value_t)100);
+        r1.write((Index_t)2, (Value_t)100);
+    }
+    @atomic {
+        r1.write((Index_t)1, (Value_t)200);
+        r1.write((Index_t)2, (Value_t)200);
+    }
+  }
+}
+

If a P4Runtime client issues a wildcard Read on Register r1, there is no +guarantee that r1[1] == r1[2] in the response, as the read for r1[1] may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for r1[2] may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read r1[1] and r1[2] separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +ReadRequest message) of individual read requests. Similar to a batch +ReadRequest, a wildcard read of a register can execute the reads of the +register array elements (r1[1], r1[2], ) in an arbitrary order relative +to each other. +

+

If the @atomic annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program. +

12. Write RPC

+

The Write RPC updates one or more P4 entities on the target. The request is +defined as follows: +

+
+
+
message WriteRequest {
+  uint64 device_id = 1;
+  uint64 role_id = 2;
+  Uint128 election_id = 3;
+  repeated Update updates = 4;
+  enum Atomicity {
+    CONTINUE_ON_ERROR = 0;
+    ROLLBACK_ON_ERROR = 1;
+    DATAPLANE_ATOMIC = 2;
+  }
+  Atomicity atomicity = 5;
+}
+

The device_id uniquely identifies the target P4 device. The role_id and +election_id define the client role and election-id as described in the +Master-Slave Arbitration and Controller Replication +section. The server is expected to perform the following checks (in this order) +before processing the updates list: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role_id does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the master for (device_id, role_id) according to the +election_id value, the server must return a PERMISSION_DENIED error. +

  4. +
  5. +

    If the Write is attempted before a ForwardingPipelineConfig has been set, +the server must return a FAILED_PRECONDITION error. +

+ +

The updates field is a list of P4 entity updates to be applied. Each update is +defined as: +

+
+
+
message Update {
+  enum Type {
+    UNSPECIFIED = 0;
+    INSERT = 1;
+    MODIFY = 2;
+    DELETE = 3;
+  }
+  Type type = 1;
+  Entity entity = 2;
+}
+

This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a logical table (e.g. +CounterEntry) or an actual table (e.g. TableEntry) in the P4 data +plane. Each entity in the container is uniquely identified by its key. Please +refer to the P4 Entity Messages section for details on +what parts of the entity specification make up the key for each P4 entity. +

+

An update can be one of the following types: +

+
    +
  • +

    INSERT: Inserts the given P4 entity in the entity container. +The entity field always specifies the full state of the P4 entity. +If the entity already exists, an ALREADY_EXISTS error is returned, and +the existing entity remains unchanged. +If the entity is malformed, an INVALID_ARGUMENT error is returned. +If the entity cannot be inserted because the container is already full, +a RESOURCE_EXHAUSTED error is returned. +

  • +
  • +

    MODIFY: Modifies the P4 entity to its new specified state. This uses +assign or full-snapshot semantics, i.e. the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an INVALID_ARGUMENT error is usually returned (unless a +more specific error code applies [31]). If the entity does not +exist, a NOT_FOUND error is returned. +

  • +
  • +

    DELETE: Deletes the specified P4 entity. If the entity does not exist, a +NOT_FOUND error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored. +

+ +

The Write RPC is idempotent, i.e. multiple invocations of the same +RPC, with no intervening data plane operations, do not have any side +effects. The end result (modified end state on P4Runtime server and P4 +device) is always the same as the result of the initial invocation, +even if the response differs. +

+

If an update is not allowed under the given controller role, the server must +return a PERMISSION_DENIED error for this update. +

12.1. Batching and Ordering of Updates

+

P4Runtime supports batching of Write operations. The list of updates in a +WriteRequest is referred to as a batch. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of TableEntry entities). +

+

The P4Runtime server may arbitrarily reorder message within a batch to maximize +performance, and clients should not depend on a specific processing order (e.g. +FIFO or inferring implicit dependencies within a batch). In particular, P4 +entities (e.g. table entries) may be inserted in the data plane in an order +different than what is received in the WriteRequest. +

+

The Write RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the Write RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, +with the exception of any operations that return an error status. +If two updates from the client depend on each other (e.g. inserting an +ActionProfileMember followed by pointing a TableEntry to it), they should be +separated across two batches (and therefore two Write RPCs). In other words, +the client must wait until the dependent Write RPC is acknowledged before +invoking a Write RPC that depends on it. +

+

P4Runtime is based on gRPC which provides a concurrent server design. A target +implementation may support concurrent execution of a given RPC handler, or it +may internally choose to serialize RPC processing (using locks, message queue, +etc.). A client is free to invoke multiple outstanding Write RPCs. This is a +valid scenario if there are no dependent updates among these RPCs. However, if +there are dependencies, the client should be aware that there is no way to +guarantee their ordering, and this will lead to non-deterministic and/or +erroneous behavior. Given the risk, most clients are advised to stick to a +synchronous model where there can be at most one Write RPC in flight. +

12.2. Batch Atomicity

+

A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the Atomicity +enum. A P4Runtime server is required to support only the modes marked as +Required below: +

+
    +
  • +

    Required: CONTINUE_ON_ERROR: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that see each of +these intermediate stages. +

  • +
  • +

    Optional: ROLLBACK_ON_ERROR: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is all-or-none, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that see each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure. +

    +

    If a P4Runtime server does not support this option at all, an +UNIMPLEMENTED error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (e.g. it is +more straightforward to implement batches that contain only INSERT +operations, vs. those that contain DELETE operations), an +UNIMPLEMENTED error is returned when the batch cannot be executed +in a data plane-atomic way. +

  • +
  • +

    Optional: DATAPLANE_ATOMIC: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +transaction. The details and design of how to achieve data plane-atomicity is +outside the scope of this specification. One possibility is to limit the +target to half of the data plane's table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table. +

    +

    If a P4Runtime server does not support this option at all, an UNIMPLEMENTED +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an UNIMPLEMENTED error is returned when the batch +cannot be executed in a data plane-atomic way. +

+ +

There is no expectation that a given client must always use the same Atomicity +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use DATAPLANE_ATOMIC at one time and default behavior +(CONTINUE_ON_ERROR) at other times. +

12.3. Error Reporting

+

Please see section Error Reporting Messages for +information on error reporting messages and guidelines. P4Runtime server will +populate grpc::Status as follows: +

+
    +
  1. +

    If all batch updates succeeded, set grpc::Status::code_ to OK and do not +populate any other field. +

  2. +
  3. +

    If an error is encountered before even trying to attempt individual batch +updates, set grpc::Status::code_ that best describes that RPC-wide +error. For example, use UNAVAILABLE if the P4Runtime service is not yet +ready to handle requests. Set error_message_ to describe the issue. Do not +set error_details in this case. +

  4. +
  5. +

    Otherwise, if one or more updates in the batch (WriteRequest.updates) +failed, set grpc::Status::code_ to UNKNOWN. For example, one update in +the batch may fail with RESOURCE_EXHAUSTED and another with +INVALID_ARGUMENT. A p4.Error message is used to capture the status of +each and every update in the batch. The number of p4.Error messages packed +into google.rpc.Status.details field should therefore always match the +number of updates in the WriteRequest, and the order of +p4.Error messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +p4.Error should set the code to OK and omit other fields. +

+ +
+
+
# Example of a grpc::Status returned for a Write RPC with a batch of 3 updates.
+# The first and third updates encountered an error, while the second update
+# succeeded.
+code_ = 2  # UNKNOWN
+error_message_ = "Write failure."
+binary_error_details {
+  code: 2  # UNKNOWN
+  message: "Write failure."
+  details {
+    canonical_code: 8  # RESOURCE_EXHAUSTED
+    message: "Table is full."
+    space: "targetX-psa-vendorY"
+    code: 500  # ERR_TABLE_FULL
+  }
+  details {
+    canonical_code: 0  # OK
+  }
+  details {
+    canonical_code: 6  # ALREADY_EXISTS
+    message: "Entity already exists."
+    space: "targetX-psa-vendorY"
+    code: 600  # ERR_ENTITY_ALREADY_EXISTS
+  }
+}

13. Read RPC

+

The Read RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as: +

+
+
+
message ReadRequest {
+  uint64 device_id = 1;
+  repeated Entity entities = 2;
+}
+

The device_id uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +NOT_FOUND error. The entities repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server. +

+

The Read response consists of a sequence of messages (a gRPC stream) with +each message defined as: +

+
+
+
message ReadResponse {
+  repeated Entity entities = 1;
+}
+

The entities repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the Finish() method on the stream object +[10]). +

13.1. Nomenclature

+
+
request
+
An element of the p4.ReadRequest.entities repeated field. +
+
batch
+
Refers to the p4.ReadRequest.entities repeated field.
+

Each request acts as a query filter for that entity type. If a request fully +specifies the entity key, the Read operation should retrieve a single P4 +entity. Please refer to the P4 Entity Messages section +for details on what parts of the entity specification make up the entity key. +

13.2. Wildcard Reads

+

P4Runtime allows wildcard read of P4 entities. A request may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the P4 Entity Messages section for details on +what parts of the entity can be wildcarded in a given request. +

+

For example, in a request of type CounterEntry: +

+
    +
  • A default counter_id implies a request to read all counter-entries for all +indirect counters. +
  • +
  • A particular (non-default) counter_id in conjunction with index unset +implies a request to read all counter-entries for the given indirect counter +ID. +
+

13.3. Batch Processing

+

A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type request +appears only once in the batch. +

+

A P4Runtime server will process the batch as follows: +

+
    +
  1. +

    Lock state (preventing new writes) and validate each request in the batch: +

    +
      +
    1. +

      If it is a valid request, perform the read; +

      +
        +
      1. If the read was successful, return the entities read in +ReadResponse stream. +
      2. +
      3. If the read failed (exception / critical-error), prepare a p4.Error +with code set to INTERNAL. +
      +
    2. +
    3. +

      If the request is invalid (invalid-argument, not-supported, etc.), +prepare a p4.Error with relevant canonical code to capture the error. +

    +
  2. +
  3. +

    Unlock the state (allowing new writes); +

  4. +
  5. +

    Close the ReadResponse stream and return a grpc::Status as follows: +

    +
      +
    1. +

      If no errors were encountered, set code to OK and do not populate any +other field. +

    2. +
    3. +

      Otherwise, the overall code should be set to UNKNOWN. See section +Error Reporting Messages for information +on error reporting messages and guidelines. Assemble a list of p4.Error +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +google.rpc.Status.details field. This behavior also matches Write +RPC. +

    +
+

13.3.1. Example

+

If a client asked to read {a,b,c,d} and b and d requests didn't +validate, the server will return entities corresponding to a and c, followed by +a status {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} in the +details field. +

+

The P4Runtime server is not required to perform any optimization (e.g. merge two +requests in the batch if one is a subset of other). As a result of this, it +is possible for the ReadResponse to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging. +

+

There is no requirement that each request in the batch will correspond to one +ReadResponse message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit. +

+

A P4Runtime server must be prepared to handle multiple concurrent Read RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (e.g. in a single-threaded architecture), it may choose to serialize +Read RPC processing. +

14. SetForwardingPipelineConfig RPC

+

A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the SetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message SetForwardingPipelineConfigRequest {
+  enum Action {
+    UNSPECIFIED = 0;
+    VERIFY = 1;
+    VERIFY_AND_SAVE = 2;
+    VERIFY_AND_COMMIT = 3;
+    COMMIT = 4;
+    RECONCILE_AND_COMMIT = 5;
+  }
+  uint64 device_id = 1;
+  uint64 role_id = 2;
+  Uint128 election_id = 3;
+  Action action = 4;
+  ForwardingPipelineConfig config = 5;
+}
+

The server is expected to perform the following checks (in this order) +before performing the required action: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role_id does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the master for (device_id, role_id) according to the +election_id value, the server must return a PERMISSION_DENIED error. +

+ +

The action is the type of configuration action requested, it can be one of: +

+
    +
  • +

    VERIFY: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an INVALID_ARGUMENT +error if config is not provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_SAVE: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent Read / Write requests must refer to fields in the new +config. Returns an INVALID_ARGUMENT error if the forwarding config is not +provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_COMMIT: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an INVALID_ARGUMENT error if the forwarding config is not provided of if the +provided config cannot be realized. +

  • +
  • +

    COMMIT: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a NOT_FOUND error if no saved config +is found, i.e. if no VERIFY_AND_SAVE action preceded this one. Returns an +INVALID_ARGUMENT error if a config is provided with this message. +

  • +
  • +

    RECONCILE_AND_COMMIT: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an UNIMPLEMENTED error. For targets that support this option, an +INVALID_ARGUMENT error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target. +

+ +

The config field is a message of type ForwardingPipelineConfig that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(e.g. generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the Forwarding-Pipeline +Configuration section for details. +

+

A P4Runtime server running on a non-programmable device may not +support SetForwardingPipelineConfig (e.g. the forwarding-pipeline +config is part of the device's software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +UNIMPLEMENTED error. +

15. GetForwardingPipelineConfig RPC

+

The forwarding-pipeline configuration of the target can be retrieved by invoking +the GetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message GetForwardingPipelineConfigRequest {
+  enum ResponseType {
+    ALL = 0;
+    COOKIE_ONLY = 1;
+    P4INFO_AND_COOKIE = 2;
+    DEVICE_CONFIG_AND_COOKIE = 3;
+  }
+  uint64 device_id = 1;
+  ResponseType response_type = 2;
+}
+

The device_id uniquely identifies the target P4 device. A NOT_FOUND error is +returned if the device_id is not recognized by the P4Runtime server. +

+

The response_type is used to specify which fields to populate in the response, +its value can be one of: +

+
    +
  • +

    ALL: returns a ForwardingPipelineConfig with all fields +set as stored by the target. This is the default behaviour if the +response_type field is not set. +

  • +
  • +

    COOKIE_ONLY: reply by setting only the cookie field in the +ForwardingPipelineConfig, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message. +

  • +
  • +

    P4INFO_AND_COOKIE: reply by setting the p4info and cookie fields. +

  • +
  • +

    DEVICE_CONFIG_AND_COOKIE: reply by setting the p4_device_config and +cookie fields. +

+ +

The response contains the ForwardingPipelineConfig for the specified device: +

+
+
+
message GetForwardingPipelineConfigResponse {
+  ForwardingPipelineConfig config = 1;
+}
+

If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level config field will be unset in the response. Examples are +(i) a server that only allows configuration via SetForwardingPipelineConfig +but this RPC hasn't been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn't yet occurred. +

+

Once a forwarding-pipeline config is installed on the device (either via +SetForwardingPipelineConfig or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +config.p4_device_config will be empty / unset in the response, even if +response_type in the request was set to ALL. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the SetForwardingPipelineConfig RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +SetForwardingPipelineConfig, the value of config.cookie will be unset. +

+

If a P4Runtime server supports both SetForwardingPipelineConfig as well as +returning the p4_device_config, there should be read-write symmetry between +SetForwardingPipelineConfig and GetForwardingPipelineConfig RPCs. +

16. P4Runtime Stream Messages

16.1. Packet I/O

+

P4Runtime supports controller packet-in and packet-out by means of PacketIn +and PacketOut stream messages, respectively. +

+

PacketIn messages are sent by the P4Runtime server to the client. Conversely, +PacketOut messages are sent by the client to the server. +

+

As introduced in the ControllerPacketMetadata +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with @controller_header. The expected metadata is described +in the P4Info using the ControllerPacketMetadata messages. +

+

Both PacketIn and PacketOut stream messages share the same fields and are +defined as follows: +

+
+
+
// Packet sent from the controller to the switch.
+message PacketOut {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+// Packet sent from the switch to the controller.
+message PacketIn {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+message PacketMetadata {
+  // This refers to Metadata.id coming from P4Info ControllerPacketMetadata.
+  uint32 metadata_id = 1;
+  bytes value = 2;
+}
+
    +
  • +

    payload is used to carry the full packet content, including the headers. +

  • +
  • +

    metadata is a repeated field of PacketMetadata messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +ControllerPacketMetadata. Indeed, when a P4Runtime client (or server) +generates a PacketOut (or PacketIn) message, it needs to populate the +metadata field with as many values as in ControllerPacketMetadata.metadata +for the packet-out (or packet-in) case. Each PacketMetadata.value is a +binary string and must conform to the Bytestrings +requirements based on the corresponding P4Info +ControllerPacketMetadata.metadata specification. +

+

16.2. Master Arbitration Update

+

As explained earlier in this document, the controller uses the StreamChannel +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via Write RPC), +it needs to start a controller session and become a “master”. To do so, the +controller first opens a bidirectional stream channel to the server via +StreamChannel for each device and sends a StreamMessageRequest message. The +controller populates the MasterArbitrationUpdate field in this message using +its role_id and election_id and the device_id of the device, as explained +in detail in the Master-Slave Arbitration and Controller +Replication +section. For any given (device_id, role_id), the controller with the highest +election_id is the master and the rest are slaves. +

+

The MasterArbitrationUpdate message is defined as follows: +

+
+
+
message Role {
+  // role_id for this role. Defined offline in agreement across the
+  // entire control plane.
+  uint64 id = 1;
+  // Describes the role configuration.
+  google.protobuf.Any config = 2;
+}
+
+message MasterArbitrationUpdate {
+  // Identifies the device (aka target or node or switching chip).
+  uint64 device_id = 1;
+  // The role for which the mastership is being arbitrated.
+  Role role = 2;
+  // The election_id (unique per role).
+  Uint128 election_id = 3;
+  // Switch populates this with OK for the client that is the master,
+  // and with an error status for all other connected clients (at
+  // every mastership change). The controller does not populate this
+  // field.
+  google.rpc.Status status = 4;
+}
+

Note that the status field in the MasterArbitrationUpdate message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a StreamMessageResponse message back to the controller, in which +it populates the MasterArbitrationUpdate message using the device_id, +role, and election_id it previously received from the controller. The server +also populates the status field in the MasterArbitrationUpdate as follows: +

+
    +
  • +

    OK (with status.code set to google.rpc.OK) when the controller is +determined to be the master for a given (device_id, role_id). +

  • +
  • +

    Non-OK (with status.code set to google.rpc.ALREADY_EXISTS) when the +controller is determined to be a slave for a given (device_id, role_id). +

+

16.3. Digest Messages

+

See the DigestEntry section. +

16.4. Table Idle Timeout Notification

+

When a table supports idle timeout (as per the P4Info message), the master +client can specify a TTL value for each entry in the table (see +Idle-timeout section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an IdleTimeoutNotification message on the +StreamChannel bidirectional stream to the master client. The master client can +then take the action of its choice, most likely remove the idle entry. +

+

The IdleTimeoutNotification Protobuf message has the following fields: +

+
    +
  • +

    timestamp: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server's local clock. +

  • +
  • +

    table_entry: a repeated field of entries which have expired. Each individual +entry is identified by a single TableEntry message. For each TableEntry, +the key fields (table_id, match and priority) must be set, along with +the controller_metadata field and the idle_timeout_ns field. Other fields +may be set by the server but should be ignored by the client. +

+ +

Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +IdleTimeoutNotification message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an IdleTimeoutNotification +message with an empty table_entry repeated field. +

+

After generating an idle notification, the P4Runtime server must “reset” the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the master client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle. +

+

Here is a reasonable pseudo-code implementation for idle timeout for table +entries: +

+
+
+
IdleTimeoutStream stream;
+
+scanning_interval = 10ms;
+
+while (true) {
+  // iterate over all tables which support idle timeout
+  for (table in tables) {
+    if (!table.idle_timeout_supported) continue;
+    // we coalesce all idle notifications for the same table in one
+    // message
+    IdleTimeoutNotification msg;
+    // read time_since_last_hit from device
+    entries = device.load_table_entries_from_hw(table);
+    for (entry in entries) {
+      if (entry.idle_timeout == 0) continue;  // no TTL
+      if (entry.time_since_last_hit < entry.idle_timeout) continue;
+      msg.table_entry_add(entry);
+      entry.reset_time_since_last_hit();
+    }
+    if (msg.table_entry_size() == 0) continue;  // no notifications
+    msg.set_timestamp(now());
+    stream.write(msg);
+  }
+  sleep(scanning_interval);
+}

16.5. Architecture-Specific Notifications

+

P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on StreamChannel, by including an Any Protobuf field [28] +named other in both StreamMessageRequest and StreamMessageResponse. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the PSA Digest +extern. See section on Extending P4Runtime for non-PSA +Architectures for more information. +

17. Portability Considerations

17.1. PSA Metadata Translation

+

The Portable Switch Architecture (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +[22]. For such metadata, a translation between the controller's +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. +

+
+

psa-metadata-translation +

+
+ +
Figure 8. P4Runtime Metadata Translation for the Portable Switch Architecture
+

Figure 8 illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller's 32 bit port +numbers to a target's 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch. +

17.1.1. Translation of Port Numbers

+

In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller's space and the PSA device's space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +user-defined P4 types, namely PortId_t and +PortIdInHeader_t, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in psa.p4 for +the PSA device in Switch 1. +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type PortId_t bit<9>;
+@p4runtime_translation("p4.org/psa/v1/PortIdInHeader_t", 32)
+type PortIdInHeader_t bit<32>;
+

The first argument to the @p4runtime_translation annotation is a URI that +indicates to the P4Runtime server which numerical mapping provided by the +out-of-band switch configuration mechanism to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports). +

+

An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows: +

+
+
+
enum SdnPort {
+  SDN_PORT_UNSPECIFIED = 0;
+
+  // SDN ports are numbered starting form 1.
+  SDN_PORT_MIN = 1;
+
+  // The maximum value of an SDN port (physical or logical).
+  SDN_PORT_MAX = 0xfffffeff;
+
+  // Reserved SDN port numbers (0xfffffff0 - 0xffffffff)
+
+  SDN_PORT_RECIRCULATE = 0xfffffffa;
+  SDN_PORT_CPU = 0xfffffffd;
+}
+

The switch config will map SDN_PORT_RECIRCULATE and SDN_PORT_CPU as well +as any SDN port number corresponding to a “regular” front-panel port to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation. +

+

The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs. +

17.1.2. Translation of Packet-IO Header Fields

+

Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  PortIdInHeader_t egress_port;
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  PortIdInHeader_t ingress_port;
+}
+

The header-level annotation @controller_header is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (egress_port) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI first argument to the @p4runtime_translation +annotation). Any subsequent reference to the egress_port field in the +data plane will use the translated value. PortIdInHeader_t is used in the +header definition instead of PortId_t to guarantee byte-aligned headers in +case this is required by the target. +

+

A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target's PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the ingress_port field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller. +

17.1.3. Translation of Match Fields

+

Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table's match key as shown in the example below: +

+
+
+
table t {
+  key = {
+    istd.ingress_port: exact;  // PSA standard metadata ingress port
+  }
+  actions = {
+    drop;
+  }
+}
+

Table t has an exact match on PSA standard metadata ingress port +(istd.ingress_port). Since the field is of type PortId_t, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in t from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table t is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values. +

+

Note that it may be infeasible to translate the value-mask pair for ternary +matches: LPM, TERNARY or RANGE match kinds. The P4Runtime server may +require that for these match kinds the port match be either de facto “exact” +(0xffffffff mask for TERNARY, prefix-length of 32 for LPM, or same low and +high bounds for RANGE) or “don't care”. +

17.1.4. Translation of Action Parameters

+

PortId_t type parameters can be part of a P4 action definition as shown in the +example below: +

+
+
+
action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+}
+
+table t {
+  key = {
+    hdr.h.f: exact;
+  }
+  actions = {
+    a;
+  }
+}
+

The controller may write entries in table t with action a to set the egress +port as shown in the P4 code above. The action parameter p is of type +PortId_t, which leads to a 32-bit bitwidth for p being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device. +

17.1.5. Port Translation for PSA Extern APIs

+

The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch field is +of type uint32 to carry the 32-bit SDN representation of the port being +watched. The P4Runtime server will translate the given watch port number into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device. +

+

The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type uint32 to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane. +

17.1.6. Using Port as an Index to a Register, Indirect Counter or Indirect Meter

+

P4Runtime supports using a translated value (PortId_t or any other translated +type for which the underlying built-in type is bit<W>) as an index to a +register, indirect counter, or indirect meter. +

+
+
+
Counter<bit<32> /* counter entry type */, PortId_t /* index type */>(
+  32w1024, PSA_CounterType_t.PACKETS) counter;
+action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+  counter.count(p);
+}
+

This P4 Counter declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
counters {
+  preamble {
+    id: 0x12000001
+    name: "counter"
+  }
+  spec {
+    unit: PACKETS
+  }
+  index_type_name {
+    name: "PortId_t"
+  }
+}
+

The controller may read and write counter values from indexed counter counter +using SDN port numbers as indices, and not device-specific port numbers. The +index_type_name field in the P4Info message is a signal to the P4Runtime +server that translation is required. +

18. P4Runtime Versioning

+

P4Runtime follows the Google guidelines for versioning cloud APIs +[6]. We use a MAJOR.MINOR.PATCH style version number scheme and +we increment the: +

+
    +
  • MAJOR version when we make incompatible API changes, +
  • +
  • MINOR version when we add functionality in a backwards-compatible manner, +
  • +
  • PATCH version when we make backwards-compatible bug fixes. +
+ +

The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is p4.v1 and the package +name for P4Info is p4.config.v1. Even though p4 and p4.config are two +different Protobuf packages, p4 depends on p4.config and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence. +

+

As recommended in [6], we may consider using pre-GA release +suffixes (such as alpha or beta) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1). +

+

Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner. [7] describes +what constitute a backwards-compatible change. We expect MAJOR version bumps +to be a rare event. +

+

Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor + patch version numbers in future releases. +

+

All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository [14] and the version label follows +semantic versioning rules [25]. +

19. Extending P4Runtime for non-PSA Architectures

+

P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place. +

+

When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names: +

+
    +
  • p4/[organization]/arch/config/<major version>/p4info.proto +
  • +
  • p4/[organization]/arch/<major version>/p4runtime.proto +
+ +

We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they “extend”. +

+

For the remainder of this section, we will refer to these two files as +p4info-ext and p4runtime-ext respectively. +

19.1. Extending P4Runtime for Architecture-Specific Externs

+

Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both p4info-ext and +p4runtime-ext. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example: +

+
+
+
// T must be a bit<W> type, it indicates the width of each counter cell
+extern MyNewPacketCounter<T> {
+  counter(bit<32> size);
+  increment(in bit<32> index);
+}

19.1.1. Extending the P4Info message

+
    +
  • Id prefixes 0x81 through 0xfe are reserved for architecture-specific +externs. It is recommended that p4info-ext include a P4Ids message based +on the one in p4info.proto that the P4 compiler can refer to when assigning +IDs to each extern instance. +
+ +
+
+
message P4Ids {
+  enum Prefix {
+    UNSPECIFIED = 0;
+    MY_NEW_PACKET_COUNTER = 0x81;
+  }
+}
+
    +
  • p4info-ext should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +p4.config.v1.ExternInstance message as the info +field, which is of type Any [28]. +
+ +
+
+
message MyNewPacketCounter {
+  // corresponds to the T type parameter in the P4 extern definition
+  p4.config.v1.P4DataTypeSpec type_spec = 1;
+  // constructor argument
+  int64 size = 2;
+}

19.1.2. Extending the P4Runtime Service

+

Just like p4info-ext, p4runtime-ext should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an ExternEntry message generated by the +P4Runtime client. +

+

Here is a possible Protobuf message for our MyNewPacketCounter P4 extern: +

+
+
+
// This message enables reading / writing data to the counter at the provided
+// index
+message MyNewPacketCounter {
+  int64 index = 1;
+  p4.v1.P4Data data = 2;
+}
+

P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an Any Protobuf field [28] named other +in both p4.v1.StreamMessageRequest and +p4.v1.StreamMessageResponse. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in p4runtime-ext and embed instances of these messages in +p4.v1.StreamMessageRequest and p4.v1.StreamMessageResponse as appropriate. +

19.2. Architecture-Specific Table Extensions

19.2.1. New Match Types

+

An architecture may introduce new table match types [12]. P4Runtime +accounts for this by providing the following hooks: +

+
    +
  • +

    The match field in p4.config.v1.MatchField (p4info.proto) is a oneof +which can be either one of the default match types (EXACT, LPM, TERNARY +or RANGE) or an architecture-specific match type encoded as a string. +

  • +
  • +

    The field_match_type field in p4.v1.FieldMatch (p4runtime.proto) is a +oneof which includes an Any Protobuf message [28] field +(other). p4info-ext should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in p4.v1.FieldMatch as the +other field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info. +

+

19.2.2. New Table Properties

+

An architecture may introduce additional table properties +[27]. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +p4.config.v1.Table message includes the other_properties Any Protobuf +field [28]. At the moment, there is not any mechanism to extend the +p4.v1.TableEntry message based on the value of architecture-specific table +properties, but we may include on in future versions of the API. +

20. Known-limitations of P4Runtime v1.0.0

+
    +
  • +

    FieldMatch, action Param, and controller packet metadata fields only +support unsigned bitstrings, i.e. values of type bit<W> (not the more +general P4Data). +

  • +
  • +

    Support for PSA Random & Timestamp externs is postponed to a future minor +version update. +

  • +
  • +

    P4Info does not include information about which of a table's actions execute +which direct resource(s). +

  • +
  • +

    The default action for indirect match tables is restricted to a const +NoAction known at compile-time. +

  • +
  • +

    There is no mechanism for changing the value of the psa_empty_group_action +table property at runtime. +

  • +
  • +

    There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor + +patch version numbers. +

+

21. Security concerns for P4Runtime

+

Appropriate measures and security best practices need to be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. +

A. Appendix

A.1. P4 Annotations

+

Table 7 lists P416 annotations introduced primarily for +the purpose of adding features for the P4Runtime API. +

+
+ + + + + + + + + + +
Annotation Description
@brief See section 6.1.3
@controller_header See section 6.4.6
@description See section 6.1.3
@id See section 6.3
@max_group_size See sections 6.4.3, 9.2.2
@pkginfo See section 6.2.1
@p4runtime_translation See sections 8.5.6, 17.1.1
+
+ +
Table 7. P4 annotations introduced by P4Runtime

A.2. A More Complex Value Set Example

+

This section includes a more complex Value Set example, with multiple matches of +different kinds. +

+
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+

This P4 Value Set declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

A P4Runtime client can set the membership for this Value Set with WriteRequest +messages similar to this one: +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xac }
+      }
+      # match for field_id 2 is missing => don't care match
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xdc }
+      }
+      match {
+        field_id: 2
+        ternary { value: 0x88 mask: 8f }
+      }
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+  }
+}
+

References

+
+ +
[2]“A Two Rate Three Color Marker.” https://​tools.​ietf.​org/​html/​rfc2698.
+ + + + +
[7]“Google Cloud APIs Versioning - Backwards-Compatibility.” https://​cloud.​google.​com/​apis/​design/​versioning#​backwards_​compatibility.
+ +
[9]“gRPC Main Site.” https://​grpc.​io.
+ + + + +
[14]“p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” https://​github.​com/​p4lang/​p4runtime.
+
[15]“p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.” https://​github.​com/​p4lang/​PI.
+ + +
[18]“Portable Switch Architecture Specification (v1.1.0).” https://​p4.​org/​p4-​spec/​docs/​PSA-​v1.​1.​0.​html.
+ + + + + + +
[25]“Semantic Versioning.” https://​semver.​org/​.
+ + + + + + +
[32]“The OpenConfig Project.” http://​openconfig.​net.
+ +
[34]“The Stratum Project.” https://​stratumproject.​org/​.
+
+
+
+ +
+

1.an enum type used as a field in a header must specify a +underlying type and representation for enum elements. +

+ + + diff --git a/spec/v1.0.0/P4Runtime-Spec.log b/spec/v1.0.0/P4Runtime-Spec.log new file mode 100644 index 00000000..a07b677b --- /dev/null +++ b/spec/v1.0.0/P4Runtime-Spec.log @@ -0,0 +1,12875 @@ +This is XeTeX, Version 3.14159265-2.6-0.99992 (TeX Live 2015/Debian) (preloaded format=xelatex 2018.8.17) 9 OCT 2019 00:40 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**build/P4Runtime-Spec.tex +(./build/P4Runtime-Spec.tex +LaTeX2e <2016/02/01> +Babel <3.9q> and hyphenation patterns for 81 language(s) loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2014/09/29 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo +File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@section=\count80 +\c@subsection=\count81 +\c@subsubsection=\count82 +\c@paragraph=\count83 +\c@subparagraph=\count84 +\c@figure=\count85 +\c@table=\count86 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) (build/madoko2.sty (/usr/share/texlive/texmf-dist/tex/latex/colortbl/colortbl.sty +Package: colortbl 2012/02/13 v1.0a Color table columns (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty +Package: array 2014/10/28 v2.4c Tabular extension package (FMi) +\col@sep=\dimen103 +\extrarowheight=\dimen104 +\NC@list=\toks14 +\extratabsurround=\skip43 +\backup@length=\skip44 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty +Package: color 2016/01/03 v1.1b Standard LaTeX Color (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package color Info: Driver file: xetex.def on input line 143. +(/usr/share/texlive/texmf-dist/tex/xelatex/xetex-def/xetex.def +File: xetex.def 2015/09/11 v4.06 LaTeX color/graphics driver for XeTeX (TeX Live/RRM/JK) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +))) +\everycr=\toks15 +\minrowclearance=\skip45 +) (/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: xetex.def on input line 225. +LaTeX Info: Redefining \color on input line 702. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) (build/options.sty +Package: options 2015/03/01, Daan Leijen, Provides convenient path-value (or key-value) options +(/usr/share/texlive/texmf-dist/tex/latex/etoolbox/etoolbox.sty +Package: etoolbox 2015/08/02 v2.2a e-TeX tools for LaTeX (JAW) +\etb@tempcnta=\count87 +) +\opt@nesting=\count88 +\opt@idx=\count89 +\opt@choiceord=\count90 +) (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty +Package: iftex 2013/04/04 v0.2 Provides if(tex) conditional for PDFTeX, XeTeX, and LuaTeX +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2014/10/28 v1.0g Enhanced LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks16 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2016/01/03 v1.0q Standard LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2016/01/03 v1.10 sin cos tan (DPC) +) (/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg +File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live +) +Package graphics Info: Driver file: xetex.def on input line 95. +) +\Gin@req@height=\dimen105 +\Gin@req@width=\dimen106 +) (build/longfbox.sty +Package: longfbox 2015/12/01, Daan Leijen, Provides long fbox that can break over pages +(build/longbox.sty +Package: longbox 2015/12/01, Daan Leijen, Provides basic longbox that can break over pages +(/usr/share/texlive/texmf-dist/tex/latex/mdwtools/footnote.sty +Package: footnote 1997/01/28 1.13 Save footnotes around boxes +\fn@notes=\box26 +\fn@width=\dimen107 +) +\lb@prevdepth=\skip46 +\lb@freevspace=\skip47 +\lb@headbox=\box27 +\lb@savebox=\box28 +\lb@mainbox=\box29 +\lb@usevbox=\count91 +\lb@width=\skip48 +\lb@height=\skip49 +\lb@skiptop=\skip50 +\lb@skipright=\skip51 +\lb@skipbottom=\skip52 +\lb@skipleft=\skip53 +\lb@skipbreaktop=\skip54 +\lb@skipbreakbottom=\skip55 +\lb@outerwidth=\skip56 +\lb@extrasplit=\skip57 +\lb@textalign=\count92 +\lb@baseline=\count93 +\lb@neededvspace=\skip58 +\lb@splitheight=\skip59 +\lb@insurance=\skip60 +\/longbox/@part-height=\skip61 +\/longbox/@part-width=\skip62 +\/longbox/@part-depth=\skip63 +\/longbox/@content-box-height=\skip64 +\/longbox/@content-box-width=\skip65 +\/longbox/@content-box-depth=\skip66 +\/longbox/@breakat-previous=\skip67 +\/longbox/@lower=\skip68 +\/longbox/split-minimum=\skip69 +\/longbox/split-badness=\skip70 +\/longbox/raise=\skip71 +\/longbox/height=\skip72 +\/longbox/width=\skip73 +\/longbox/outer-height=\skip74 +\/longbox/outer-width=\skip75 +\/longbox/skip-top=\skip76 +\/longbox/skip-right=\skip77 +\/longbox/skip-bottom=\skip78 +\/longbox/skip-left=\skip79 +\/longbox/skip-break-bottom=\skip80 +\/longbox/skip-break-top=\skip81 +) (/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.sty +Package: pict2e 2016/02/05 v0.3b Improved picture commands (HjG,RN,JT) +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.cfg +File: pict2e.cfg 2016/02/05 v0.1u pict2e configuration for teTeX/TeXLive +) +Package pict2e Info: Driver file: xetex.def on input line 119. +Package pict2e Info: Driver file for pict2e: p2e-xetex.def on input line 121. +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/p2e-xetex.def +File: p2e-xetex.def 2016/02/05 v0.1u Driver-dependant file (RN,HjG,JT) +) +\pIIe@GRAPH=\toks17 +\@arclen=\dimen108 +\@arcrad=\dimen109 +\@tempdimd=\dimen110 +) (build/ellipse.sty +Package: ellipse 2004/11/05 v1.0 .dtx ellipse file +) +\fbox@oct=\count94 +\fbox@quad=\count95 +\fbox@diaq=\count96 +\fbox@sign=\count97 +\fbox@anglestart=\skip82 +\fbox@angleend=\skip83 +\fbox@dash=\skip84 +\fbox@dashskip=\skip85 +\fbox@anglecur=\skip86 +\fbox@dashangle=\skip87 +\fbox@dashskipangle=\skip88 +\fbox@delta=\skip89 +\fbox@from=\skip90 +\fbox@to=\skip91 +\/fbox/padding-top=\skip92 +\/fbox/padding-right=\skip93 +\/fbox/padding-bottom=\skip94 +\/fbox/padding-left=\skip95 +\/fbox/padding-break-top=\skip96 +\/fbox/padding-break-bottom=\skip97 +\/fbox/margin-top=\skip98 +\/fbox/margin-right=\skip99 +\/fbox/margin-bottom=\skip100 +\/fbox/margin-left=\skip101 +\/fbox/margin-break-top=\skip102 +\/fbox/margin-break-bottom=\skip103 +\/fbox/border-top-width=\skip104 +\/fbox/border-right-width=\skip105 +\/fbox/border-bottom-width=\skip106 +\/fbox/border-left-width=\skip107 +\/fbox/border-break-top-width=\skip108 +\/fbox/border-break-bottom-width=\skip109 +\/fbox/@lower=\skip110 +\/fbox/@padding-box-height=\skip111 +\/fbox/@padding-box-depth=\skip112 +\/fbox/@padding-box-width=\skip113 +\/fbox/@border-box-width=\skip114 +\/fbox/@border-box-height=\skip115 +\/fbox/@border-box-depth=\skip116 +\/fbox/@border-top-left-radius-x=\skip117 +\/fbox/@border-top-right-radius-x=\skip118 +\/fbox/@border-bottom-left-radius-x=\skip119 +\/fbox/@border-bottom-right-radius-x=\skip120 +\/fbox/@border-top-left-radius-y=\skip121 +\/fbox/@border-top-right-radius-y=\skip122 +\/fbox/@border-bottom-left-radius-y=\skip123 +\/fbox/@border-bottom-right-radius-y=\skip124 +\/fbox/@border-top-left-ix=\skip125 +\/fbox/@border-top-left-iy=\skip126 +\/fbox/@border-top-right-ix=\skip127 +\/fbox/@border-top-right-iy=\skip128 +\/fbox/@border-bottom-left-ix=\skip129 +\/fbox/@border-bottom-left-iy=\skip130 +\/fbox/@border-bottom-right-ix=\skip131 +\/fbox/@border-bottom-right-iy=\skip132 +\/fbox/@border-top-left-phi=\skip133 +\/fbox/@border-top-right-phi=\skip134 +\/fbox/@border-bottom-left-phi=\skip135 +\/fbox/@border-bottom-right-phi=\skip136 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2016/03/03 v2.15a AMS math features +\@mathmargin=\skip137 +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2000/06/29 v2.01 AMS text +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen111 +)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen112 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 1999/12/14 v2.01 operator names +) +\inf@bad=\count98 +LaTeX Info: Redefining \frac on input line 199. +\uproot@=\count99 +\leftroot@=\count100 +LaTeX Info: Redefining \overline on input line 297. +\classnum@=\count101 +\DOTSCASE@=\count102 +LaTeX Info: Redefining \ldots on input line 394. +LaTeX Info: Redefining \dots on input line 397. +LaTeX Info: Redefining \cdots on input line 518. +\Mathstrutbox@=\box30 +\strutbox@=\box31 +\big@size=\dimen113 +LaTeX Font Info: Redeclaring font encoding OML on input line 630. +LaTeX Font Info: Redeclaring font encoding OMS on input line 631. +\macc@depth=\count103 +\c@MaxMatrixCols=\count104 +\dotsspace@=\muskip10 +\c@parentequation=\count105 +\dspbrk@lvl=\count106 +\tag@help=\toks19 +\row@=\count107 +\column@=\count108 +\maxfields@=\count109 +\andhelp@=\toks20 +\eqnshift@=\dimen114 +\alignsep@=\dimen115 +\tagshift@=\dimen116 +\tagwidth@=\dimen117 +\totwidth@=\dimen118 +\lineht@=\dimen119 +\@envbody=\toks21 +\multlinegap=\skip138 +\multlinetaggap=\skip139 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2735. +LaTeX Info: Redefining \] on input line 2736. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +) (/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/stmaryrd.sty +Package: stmaryrd 1994/03/03 St Mary's Road symbol package +\symstmry=\mathgroup6 +LaTeX Font Info: Overwriting symbol font `stmry' in version `bold' +(Font) U/stmry/m/n --> U/stmry/b/n on input line 89. +) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty +Package: textcomp 2005/09/27 v1.99g Standard LaTeX package +Package textcomp Info: Sub-encoding information: +(textcomp) 5 = only ISO-Adobe without \textcurrency +(textcomp) 4 = 5 + \texteuro +(textcomp) 3 = 4 + \textohm +(textcomp) 2 = 3 + \textestimated + \textcurrency +(textcomp) 1 = TS1 - \textcircled - \t +(textcomp) 0 = TS1 (full) +(textcomp) Font families with sub-encoding setting implement +(textcomp) only a restricted character set as indicated. +(textcomp) Family '?' is the default used for unknown fonts. +(textcomp) See the documentation for details. +Package textcomp Info: Setting ? sub-encoding to TS1/1 on input line 79. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +) +LaTeX Info: Redefining \oldstylenums on input line 334. +Package textcomp Info: Setting cmr sub-encoding to TS1/0 on input line 349. +Package textcomp Info: Setting cmss sub-encoding to TS1/0 on input line 350. +Package textcomp Info: Setting cmtt sub-encoding to TS1/0 on input line 351. +Package textcomp Info: Setting cmvtt sub-encoding to TS1/0 on input line 352. +Package textcomp Info: Setting cmbr sub-encoding to TS1/0 on input line 353. +Package textcomp Info: Setting cmtl sub-encoding to TS1/0 on input line 354. +Package textcomp Info: Setting ccr sub-encoding to TS1/0 on input line 355. +Package textcomp Info: Setting ptm sub-encoding to TS1/4 on input line 356. +Package textcomp Info: Setting pcr sub-encoding to TS1/4 on input line 357. +Package textcomp Info: Setting phv sub-encoding to TS1/4 on input line 358. +Package textcomp Info: Setting ppl sub-encoding to TS1/3 on input line 359. +Package textcomp Info: Setting pag sub-encoding to TS1/4 on input line 360. +Package textcomp Info: Setting pbk sub-encoding to TS1/4 on input line 361. +Package textcomp Info: Setting pnc sub-encoding to TS1/4 on input line 362. +Package textcomp Info: Setting pzc sub-encoding to TS1/4 on input line 363. +Package textcomp Info: Setting bch sub-encoding to TS1/4 on input line 364. +Package textcomp Info: Setting put sub-encoding to TS1/5 on input line 365. +Package textcomp Info: Setting uag sub-encoding to TS1/5 on input line 366. +Package textcomp Info: Setting ugq sub-encoding to TS1/5 on input line 367. +Package textcomp Info: Setting ul8 sub-encoding to TS1/4 on input line 368. +Package textcomp Info: Setting ul9 sub-encoding to TS1/4 on input line 369. +Package textcomp Info: Setting augie sub-encoding to TS1/5 on input line 370. +Package textcomp Info: Setting dayrom sub-encoding to TS1/3 on input line 371. +Package textcomp Info: Setting dayroms sub-encoding to TS1/3 on input line 372. +Package textcomp Info: Setting pxr sub-encoding to TS1/0 on input line 373. +Package textcomp Info: Setting pxss sub-encoding to TS1/0 on input line 374. +Package textcomp Info: Setting pxtt sub-encoding to TS1/0 on input line 375. +Package textcomp Info: Setting txr sub-encoding to TS1/0 on input line 376. +Package textcomp Info: Setting txss sub-encoding to TS1/0 on input line 377. +Package textcomp Info: Setting txtt sub-encoding to TS1/0 on input line 378. +Package textcomp Info: Setting lmr sub-encoding to TS1/0 on input line 379. +Package textcomp Info: Setting lmdh sub-encoding to TS1/0 on input line 380. +Package textcomp Info: Setting lmss sub-encoding to TS1/0 on input line 381. +Package textcomp Info: Setting lmssq sub-encoding to TS1/0 on input line 382. +Package textcomp Info: Setting lmvtt sub-encoding to TS1/0 on input line 383. +Package textcomp Info: Setting lmtt sub-encoding to TS1/0 on input line 384. +Package textcomp Info: Setting qhv sub-encoding to TS1/0 on input line 385. +Package textcomp Info: Setting qag sub-encoding to TS1/0 on input line 386. +Package textcomp Info: Setting qbk sub-encoding to TS1/0 on input line 387. +Package textcomp Info: Setting qcr sub-encoding to TS1/0 on input line 388. +Package textcomp Info: Setting qcs sub-encoding to TS1/0 on input line 389. +Package textcomp Info: Setting qpl sub-encoding to TS1/0 on input line 390. +Package textcomp Info: Setting qtm sub-encoding to TS1/0 on input line 391. +Package textcomp Info: Setting qzc sub-encoding to TS1/0 on input line 392. +Package textcomp Info: Setting qhvc sub-encoding to TS1/0 on input line 393. +Package textcomp Info: Setting futs sub-encoding to TS1/4 on input line 394. +Package textcomp Info: Setting futx sub-encoding to TS1/4 on input line 395. +Package textcomp Info: Setting futj sub-encoding to TS1/4 on input line 396. +Package textcomp Info: Setting hlh sub-encoding to TS1/3 on input line 397. +Package textcomp Info: Setting hls sub-encoding to TS1/3 on input line 398. +Package textcomp Info: Setting hlst sub-encoding to TS1/3 on input line 399. +Package textcomp Info: Setting hlct sub-encoding to TS1/5 on input line 400. +Package textcomp Info: Setting hlx sub-encoding to TS1/5 on input line 401. +Package textcomp Info: Setting hlce sub-encoding to TS1/5 on input line 402. +Package textcomp Info: Setting hlcn sub-encoding to TS1/5 on input line 403. +Package textcomp Info: Setting hlcw sub-encoding to TS1/5 on input line 404. +Package textcomp Info: Setting hlcf sub-encoding to TS1/5 on input line 405. +Package textcomp Info: Setting pplx sub-encoding to TS1/3 on input line 406. +Package textcomp Info: Setting pplj sub-encoding to TS1/3 on input line 407. +Package textcomp Info: Setting ptmx sub-encoding to TS1/4 on input line 408. +Package textcomp Info: Setting ptmj sub-encoding to TS1/4 on input line 409. +) (/usr/share/texlive/texmf-dist/tex/latex/psnfss/pifont.sty +Package: pifont 2005/04/12 PSNFSS-v9.2a Pi font support (SPQR) +LaTeX Font Info: Try loading font information for U+pzd on input line 63. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upzd.fd +File: upzd.fd 2001/06/04 font definitions for U/pzd. +) +LaTeX Font Info: Try loading font information for U+psy on input line 64. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upsy.fd +File: upsy.fd 2001/06/04 font definitions for U/psy. +)) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2012/11/06 v6.83m Hypertext links for LaTeX +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO) +Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO) +Package hobsub Info: Skipping package `infwarerr' (already loaded). +Package hobsub Info: Skipping package `ltxcmds' (already loaded). +Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO) +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is not detected. +Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) +Package etexcmds Info: Could not find \expanded. +(etexcmds) That can mean that you are not using pdfTeX 1.50 or +(etexcmds) that some package has redefined \expanded. +(etexcmds) In the latter case, load this package earlier. +Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) +Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO) +Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: pdfTeX >= 1.30 not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode not found. +Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO) +Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO) +Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO) +Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO) +Package: xcolor-patch 2011/01/30 xcolor patch +Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO) +Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO) +Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO) +Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2011/03/04 v1.3 Hooks for auxiliary files (HO) +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) +) +\@linkdim=\dimen120 +\Hy@linkcounter=\count110 +\Hy@pagecounter=\count111 +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count112 +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Hyper figures OFF on input line 4443. +Package hyperref Info: Link nesting OFF on input line 4448. +Package hyperref Info: Hyper index ON on input line 4451. +Package hyperref Info: Plain pages OFF on input line 4458. +Package hyperref Info: Backreferencing OFF on input line 4463. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4688. +\c@Hy@tempcnt=\count113 +(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip11 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 5041. +\XeTeXLinkMargin=\dimen121 +\Fld@menulength=\count114 +\Field@Width=\dimen122 +\Fld@charsize=\dimen123 +Package hyperref Info: Hyper figures OFF on input line 6295. +Package hyperref Info: Link nesting OFF on input line 6300. +Package hyperref Info: Hyper index ON on input line 6303. +Package hyperref Info: backreferencing OFF on input line 6310. +Package hyperref Info: Link coloring OFF on input line 6315. +Package hyperref Info: Link coloring with OCG OFF on input line 6320. +Package hyperref Info: PDF/A mode OFF on input line 6325. +LaTeX Info: Redefining \ref on input line 6365. +LaTeX Info: Redefining \pageref on input line 6369. +\Hy@abspage=\count115 +\c@Item=\count116 +\c@Hfootnote=\count117 +) + +Package hyperref Message: Driver (autodetected): hxetex. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hxetex.def +File: hxetex.def 2012/11/06 v6.83m Hyperref driver for XeTeX +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def +File: puenc.def 2012/11/06 v6.83m Hyperref: PDF Unicode definition (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/stringenc.sty +Package: stringenc 2011/12/02 v1.10 Convert strings between diff. encodings (HO) +) +\pdfm@box=\box32 +\c@Hy@AnnotLevel=\count118 +\HyField@AnnotCount=\count119 +\Fld@listcount=\count120 +\c@bookmark@seq@number=\count121 +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO) +Package rerunfilecheck Info: Feature \pdfmdfivesum is not available +(rerunfilecheck) (e.g. pdfTeX or LuaTeX with package `pdftexcmds'). +(rerunfilecheck) Therefore file contents cannot be checked efficiently +(rerunfilecheck) and the loading of the package is aborted. +) +\Hy@SectionHShift=\skip140 +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bookmark.sty +Package: bookmark 2011/12/02 v1.24 PDF bookmarks (HO) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bkm-dvipdfm.def +File: bkm-dvipdfm.def 2011/12/02 v1.24 bookmark driver for dvipdfm (HO) +\BKM@id=\count122 +)) (/usr/share/texlive/texmf-dist/tex/latex/booktabs/booktabs.sty +Package: booktabs 2005/04/14 v1.61803 publication quality tables +\heavyrulewidth=\dimen124 +\lightrulewidth=\dimen125 +\cmidrulewidth=\dimen126 +\belowrulesep=\dimen127 +\belowbottomsep=\dimen128 +\aboverulesep=\dimen129 +\abovetopsep=\dimen130 +\cmidrulesep=\dimen131 +\cmidrulekern=\dimen132 +\defaultaddspace=\dimen133 +\@cmidla=\count123 +\@cmidlb=\count124 +\@aboverulesep=\dimen134 +\@belowrulesep=\dimen135 +\@thisruleclass=\count125 +\@lastruleclass=\count126 +\@thisrulewidth=\dimen136 +) (/usr/share/texlive/texmf-dist/tex/latex/tools/longtable.sty +Package: longtable 2014/10/28 v4.11 Multi-page Table package (DPC) +\LTleft=\skip141 +\LTright=\skip142 +\LTpre=\skip143 +\LTpost=\skip144 +\LTchunksize=\count127 +\LTcapwidth=\dimen137 +\LT@head=\box33 +\LT@firsthead=\box34 +\LT@foot=\box35 +\LT@lastfoot=\box36 +\LT@cols=\count128 +\LT@rows=\count129 +\c@LT@tables=\count130 +\c@LT@chunks=\count131 +\LT@p@ftn=\toks23 +) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Package: anyfontsize 2007/11/22 anyfontsize.sty by pts +) (/usr/share/texlive/texmf-dist/tex/latex/enumitem/enumitem.sty +Package: enumitem 2011/09/28 v3.5.2 Customized lists +\labelindent=\skip145 +\enit@outerparindent=\dimen138 +\enit@toks=\toks24 +\enit@inbox=\box37 +\enitdp@description=\count132 +) (/usr/share/texlive/texmf-dist/tex/latex/wrapfig/wrapfig.sty +\wrapoverhang=\dimen139 +\WF@size=\dimen140 +\c@WF@wrappedlines=\count133 +\WF@box=\box38 +\WF@everypar=\toks25 +Package: wrapfig 2003/01/31 v 3.6 +) (/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.sty (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty +Package: expl3 2016/01/19 v6377 L3 programming layer (loader) +(/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3-code.tex +Package: expl3 2016/01/19 v6377 L3 programming layer (code) +L3 Module: l3bootstrap 2016/01/01 v6339 L3 Bootstrap code +L3 Module: l3names 2015/12/21 v6328 L3 Namespace for primitives +L3 Module: l3basics 2015/11/22 v6315 L3 Basic definitions +L3 Module: l3expan 2015/09/10 v5983 L3 Argument expansion +L3 Module: l3tl 2015/09/29 v6121 L3 Token lists +L3 Module: l3str 2016/01/03 v6357 L3 Strings +L3 Module: l3seq 2015/08/05 v5777 L3 Sequences and stacks +L3 Module: l3int 2016/01/05 v6366 L3 Integers +\c_max_int=\count134 +\l_tmpa_int=\count135 +\l_tmpb_int=\count136 +\g_tmpa_int=\count137 +\g_tmpb_int=\count138 +L3 Module: l3quark 2015/08/17 v5855 L3 Quarks +L3 Module: l3prg 2015/11/01 v6216 L3 Control structures +\g__prg_map_int=\count139 +L3 Module: l3clist 2015/09/02 v5901 L3 Comma separated lists +L3 Module: l3token 2015/11/11 v6249 L3 Experimental token manipulation +L3 Module: l3prop 2016/01/05 v6366 L3 Property lists +L3 Module: l3msg 2015/09/28 v6113 L3 Messages +L3 Module: l3file 2015/12/03 v6317 L3 File and I/O operations +\l_iow_line_count_int=\count140 +\l__iow_target_count_int=\count141 +\l__iow_current_line_int=\count142 +\l__iow_current_word_int=\count143 +\l__iow_current_indentation_int=\count144 +L3 Module: l3skip 2016/01/05 v6366 L3 Dimensions and skips +\c_zero_dim=\dimen141 +\c_max_dim=\dimen142 +\l_tmpa_dim=\dimen143 +\l_tmpb_dim=\dimen144 +\g_tmpa_dim=\dimen145 +\g_tmpb_dim=\dimen146 +\c_zero_skip=\skip146 +\c_max_skip=\skip147 +\l_tmpa_skip=\skip148 +\l_tmpb_skip=\skip149 +\g_tmpa_skip=\skip150 +\g_tmpb_skip=\skip151 +\c_zero_muskip=\muskip12 +\c_max_muskip=\muskip13 +\l_tmpa_muskip=\muskip14 +\l_tmpb_muskip=\muskip15 +\g_tmpa_muskip=\muskip16 +\g_tmpb_muskip=\muskip17 +L3 Module: l3keys 2015/11/17 v6284 L3 Key-value interfaces +\g__keyval_level_int=\count145 +\l_keys_choice_int=\count146 +L3 Module: l3fp 2015/08/25 v5890 L3 Floating points +\c__fp_leading_shift_int=\count147 +\c__fp_middle_shift_int=\count148 +\c__fp_trailing_shift_int=\count149 +\c__fp_big_leading_shift_int=\count150 +\c__fp_big_middle_shift_int=\count151 +\c__fp_big_trailing_shift_int=\count152 +\c__fp_Bigg_leading_shift_int=\count153 +\c__fp_Bigg_middle_shift_int=\count154 +\c__fp_Bigg_trailing_shift_int=\count155 +L3 Module: l3box 2015/08/09 v5822 L3 Experimental boxes +\c_empty_box=\box39 +\l_tmpa_box=\box40 +\l_tmpb_box=\box41 +\g_tmpa_box=\box42 +\g_tmpb_box=\box43 +L3 Module: l3coffins 2015/08/06 v5789 L3 Coffin code layer +\l__coffin_internal_box=\box44 +\l__coffin_internal_dim=\dimen147 +\l__coffin_offset_x_dim=\dimen148 +\l__coffin_offset_y_dim=\dimen149 +\l__coffin_x_dim=\dimen150 +\l__coffin_y_dim=\dimen151 +\l__coffin_x_prime_dim=\dimen152 +\l__coffin_y_prime_dim=\dimen153 +\c_empty_coffin=\box45 +\l__coffin_aligned_coffin=\box46 +\l__coffin_aligned_internal_coffin=\box47 +\l_tmpa_coffin=\box48 +\l_tmpb_coffin=\box49 +\l__coffin_display_coffin=\box50 +\l__coffin_display_coord_coffin=\box51 +\l__coffin_display_pole_coffin=\box52 +\l__coffin_display_offset_dim=\dimen154 +\l__coffin_display_x_dim=\dimen155 +\l__coffin_display_y_dim=\dimen156 +L3 Module: l3color 2014/08/23 v5354 L3 Experimental color support +L3 Module: l3sys 2015/09/25 v6087 L3 Experimental system/runtime functions +L3 Module: l3candidates 2016/01/14 v6376 L3 Experimental additions to l3kernel +\l__box_top_dim=\dimen157 +\l__box_bottom_dim=\dimen158 +\l__box_left_dim=\dimen159 +\l__box_right_dim=\dimen160 +\l__box_top_new_dim=\dimen161 +\l__box_bottom_new_dim=\dimen162 +\l__box_left_new_dim=\dimen163 +\l__box_right_new_dim=\dimen164 +\l__box_internal_box=\box53 +\l__coffin_bounding_shift_dim=\dimen165 +\l__coffin_left_corner_dim=\dimen166 +\l__coffin_right_corner_dim=\dimen167 +\l__coffin_bottom_corner_dim=\dimen168 +\l__coffin_top_corner_dim=\dimen169 +\l__coffin_scaled_total_height_dim=\dimen170 +\l__coffin_scaled_width_dim=\dimen171 +L3 Module: l3luatex 2015/11/11 v6250 L3 Experimental LuaTeX-specific functions +) (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def +File: l3xdvidpfmx.def 2015/11/11 v6250 L3 Experimental driver: xdvipdfmx +)) (/usr/share/texlive/texmf-dist/tex/latex/l3packages/xparse/xparse.sty +Package: xparse 2016/01/19 v6377 L3 Experimental document command parser +\l__xparse_current_arg_int=\count156 +\l__xparse_m_args_int=\count157 +\l__xparse_mandatory_args_int=\count158 +\l__xparse_processor_int=\count159 +\l__xparse_v_nesting_int=\count160 +) +Package: fontspec 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec-xetex.sty +Package: fontspec-xetex 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +\l_fontspec_script_int=\count161 +\l_fontspec_language_int=\count162 +\l_fontspec_strnum_int=\count163 +\l__fontspec_tmpa_dim=\dimen172 +\l__fontspec_tmpb_dim=\dimen173 +\l__fontspec_tmpc_dim=\dimen174 +\g__file_internal_ior=\read1 +(/usr/share/texlive/texmf-dist/tex/latex/base/fontenc.sty +Package: fontenc 2005/09/27 v1.99g Standard LaTeX package +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1enc.def +File: eu1enc.def 2010/05/27 v0.1h Experimental Unicode font encodings +) +LaTeX Font Info: Try loading font information for EU1+lmr on input line 105. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmr.fd +File: eu1lmr.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) (/usr/share/texlive/texmf-dist/tex/xelatex/xunicode/xunicode.sty +File: xunicode.sty 2011/09/09 v0.981 provides access to latin accents and many other characters in Unicode lower plane +(/usr/share/texmf/tex/latex/tipa/t3enc.def +File: t3enc.def 2001/12/31 T3 encoding +LaTeX Font Info: Try loading font information for EU1+lmss on input line 357. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmss.fd +File: eu1lmss.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) +\tipaTiiicode=\count164 +\tipasavetokens=\toks26 +\tipachecktokens=\toks27 +) +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \__fontspec_post_arg:w with sig. 'mmO{}' on line 353. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \fontspec with sig. 'om' on line 355. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmainfont with sig. 'om' on line 365. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setsansfont with sig. 'om' on line 375. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmonofont with sig. 'om' on line 385. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathrm with sig. 'om' on line 399. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setboldmathrm with sig. 'om' on line 407. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathsf with sig. 'om' on line 415. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathtt with sig. 'om' on line 423. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfamily with sig. 'mom' on line 437. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontface with sig. 'mom' on line 453. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \defaultfontfeatures with sig. 't+om' on line 467. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \addfontfeatures with sig. 'm' on line 529. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfeature with sig. 'mm' on line 540. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newAATfeature with sig. 'mmmm' on line 548. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newopentypefeature with sig. 'mmm' on line 556. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeature with sig. 'mm' on line 577. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeatureoption with sig. 'mmm' on line 586. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontscript with sig. 'mm' on line 590. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontlanguage with sig. 'mm' on line 594. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \DeclareFontsExtensions with sig. 'm' on line 599. +................................................. +\l__fontspec_tmp_int=\count165 +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.cfg) +LaTeX Info: Redefining \itshape on input line 2705. +LaTeX Info: Redefining \slshape on input line 2710. +LaTeX Info: Redefining \scshape on input line 2715. +LaTeX Info: Redefining \upshape on input line 2720. +\l__fontspec_em_int=\count166 +\l__fontspec_emdef_int=\count167 +LaTeX Info: Redefining \em on input line 2736. +LaTeX Info: Redefining \emph on input line 2742. +LaTeX Info: Redefining \- on input line 2746. +................................................. +. LaTeX info: "xparse/redefine-command" +. +. Redefining command \oldstylenums with sig. 'm' on line 2841. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \liningnums with sig. 'm' on line 2845. +................................................. +)) +Package hyperref Info: Option `colorlinks' set `true' on input line 87. +\px=\skip152 +\c@md@targetcount=\count168 +\mdcompactskip=\skip153 +\mdcompacttopsep=\skip154 +\dim@rem=\skip155 +\dim@ch=\skip156 +\md@height=\skip157 +\dim@marginbottom=\skip158 +\dim@paddingbottom=\skip159 +\md@interaction=\count169 +\mddefinitionsskip=\skip160 +\md@captionlen=\skip161 +\mdtoclevel=\count170 +\c@mdtoclevelbold=\count171 +\c@mdtocleveldots=\count172 +\mdtocskip=\skip162 +\mdpreskip=\skip163 +\presp=\skip164 +LaTeX Font Info: Try loading font information for EU1+lmtt on input line 801. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmtt.fd +File: eu1lmtt.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +\md@postskip=\skip165 +\ppresp=\skip166 +\md@thmcaption=\box54 +\md@defaultcolwidth=\skip167 +\mdtabularskip=\skip168 +\mdbibindentunit=\skip169 +\c@md@authorcount=\count173 +\c@mdx@authorcount=\count174 +\c@@mdTargetCount=\count175 +\@snippetBox=\box55 +\@snippetWidth=\skip170 +\@snippetHeight=\skip171 +\@snippetDepth=\skip172 +\c@snippets=\count176 +) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty +Package: geometry 2010/09/12 v5.6 Page Geometry +\Gm@cnth=\count177 +\Gm@cntv=\count178 +\c@Gm@tempcnt=\count179 +\Gm@bindingoffset=\dimen175 +\Gm@wd@mp=\dimen176 +\Gm@odd@mp=\dimen177 +\Gm@even@mp=\dimen178 +\Gm@layoutwidth=\dimen179 +\Gm@layoutheight=\dimen180 +\Gm@layouthoffset=\dimen181 +\Gm@layoutvoffset=\dimen182 +\Gm@dimlist=\toks28 +) (/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +\fancy@headwidth=\skip173 +\f@ncyO@elh=\skip174 +\f@ncyO@erh=\skip175 +\f@ncyO@olh=\skip176 +\f@ncyO@orh=\skip177 +\f@ncyO@elf=\skip178 +\f@ncyO@erf=\skip179 +\f@ncyO@olf=\skip180 +\f@ncyO@orf=\skip181 +) (build/P4Runtime-Spec.aux + +LaTeX Warning: Label `sec-wildcard-reads' multiply defined. + + +LaTeX Warning: Label `sec-example' multiply defined. + +) +\openout1 = `P4Runtime-Spec.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for TS1+cmr on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1cmr.fd +File: ts1cmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions +) +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for EU1/lmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T3/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for T3+cmr on input line 14. +(/usr/share/texmf/tex/latex/tipa/t3cmr.fd +File: t3cmr.fd 2001/12/31 TIPA font definitions +) +LaTeX Font Info: ... okay on input line 14. +\AtBeginShipoutBox=\box56 +Package hyperref Info: Link coloring ON on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2012/10/27 v2.43 Cross-referencing by name of section +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO) +) +\c@section@level=\count180 +) +LaTeX Info: Redefining \ref on input line 14. +LaTeX Info: Redefining \pageref on input line 14. +LaTeX Info: Redefining \nameref on input line 14. +................................................. +. fontspec info: "setup-math" +. +. Adjusting the maths setup (use [no-math] to avoid this). +................................................. +\symlegacymaths=\mathgroup7 +LaTeX Font Info: Overwriting symbol font `legacymaths' in version `bold' +(Font) OT1/cmr/m/n --> OT1/cmr/bx/n on input line 14. +LaTeX Font Info: Redeclaring math accent \acute on input line 14. +LaTeX Font Info: Redeclaring math accent \grave on input line 14. +LaTeX Font Info: Redeclaring math accent \ddot on input line 14. +LaTeX Font Info: Redeclaring math accent \tilde on input line 14. +LaTeX Font Info: Redeclaring math accent \bar on input line 14. +LaTeX Font Info: Redeclaring math accent \breve on input line 14. +LaTeX Font Info: Redeclaring math accent \check on input line 14. +LaTeX Font Info: Redeclaring math accent \hat on input line 14. +LaTeX Font Info: Redeclaring math accent \dot on input line 14. +LaTeX Font Info: Redeclaring math accent \mathring on input line 14. +LaTeX Font Info: Redeclaring math symbol \Gamma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Delta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Theta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Lambda on input line 14. +LaTeX Font Info: Redeclaring math symbol \Xi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Pi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Sigma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Upsilon on input line 14. +LaTeX Font Info: Redeclaring math symbol \Phi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Psi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Omega on input line 14. +LaTeX Font Info: Redeclaring math symbol \mathdollar on input line 14. +LaTeX Font Info: Redeclaring symbol font `operators' on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `normal' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/cmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `bold' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/cmr/bx/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) EU1/lmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/cmr/m/it --> EU1/lmr/m/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/cmr/bx/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/cmss/m/n --> EU1/lmss/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/cmtt/m/n --> EU1/lmtt/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) EU1/lmr/m/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' +(Font) OT1/cmr/bx/it --> EU1/lmr/bx/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/cmss/bx/n --> EU1/lmss/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/cmtt/m/n --> EU1/lmtt/bx/n on input line 14. +*geometry* driver: auto-detecting +*geometry* detected driver: xetex +*geometry* verbose mode - [ preamble ] result: +* driver: xetex +* paper: +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: +* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt) +* v-part:(T,H,B)=(72.26999pt, 632.3625pt, 90.3375pt) +* \paperwidth=614.295pt +* \paperheight=794.96999pt +* \textwidth=469.75502pt +* \textheight=632.3625pt +* \oddsidemargin=0.0pt +* \evensidemargin=0.0pt +* \topmargin=-37.0pt +* \headheight=30.0pt +* \headsep=25.0pt +* \topskip=11.0pt +* \footskip=30.0pt +* \marginparwidth=59.0pt +* \marginparsep=10.0pt +* \columnsep=10.0pt +* \skip\footins=10.0pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +resolve font stack: UtopiaStd-Regular + +\g__fontspec_family_UtopiaStd-Regular_int=\count181 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'UtopiaStd-Regular(0)' created for font 'UtopiaStd-Regular' with +. options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;" +. - 'small caps' (m/sc) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;+smcp;" +................................................. + +resolved font stack 'UtopiaStd-Regular' to: UtopiaStd-Regular +LaTeX Font Info: Try loading font information for U+msa on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Try loading font information for U+msb on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Try loading font information for U+stmry on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/Ustmry.fd) + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/bx/n' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 35. + +resolve font stack: LuxiMono + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +\g__fontspec_family_LuxiMono_int=\count182 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'LuxiMono(0)' created for font 'LuxiMono' with options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: <->"LuxiMono/OT:" +. - 'small caps' (m/sc) with NFSS spec.: +................................................. + +resolved font stack 'LuxiMono' to: LuxiMono +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/se-ascii-print.def +File: se-ascii-print.def 2011/12/02 v1.10 stringenc: Printable ASCII characters +) [1 + +] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[2] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <10.95> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 293. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Font Warning: Font shape `EU1/LuxiMono(0)/bx/n' undefined +(Font) using `EU1/LuxiMono(0)/m/n' instead on input line 293. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[3] + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/m/it' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 471. + +[4] [5] [6] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[7] +File: build/reference-architecture.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[8] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[9] +File: build/single-embedded-controller.png Graphic file (type QTm) + +File: build/single-remote-controller.png Graphic file (type QTm) + [10] +File: build/embedded-plus-single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-controllers.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-ha-controllers.png Graphic file (type QTm) + [11] [12] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[13] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[14] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[15] +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <12> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 1458. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1458. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1458. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1458. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1458. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1458. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1458. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1458. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1458. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1458. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1458. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1458. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1458. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1458. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1688) in paragraph at lines 1539--1542 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If the \EU1/LuxiMono(0)/bx/n/8.2125 election_id \EU1/UtopiaStd-Regular(0)/m/it/10.95 is already assigned to another controller stream for the same + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[16] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1620. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1620. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1620. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1620. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1620. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1620. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1620. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1620. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1620. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1620. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1620. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1620. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1620. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1644. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1644. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1644. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1644. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1644. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1644. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1644. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1644. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1644. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1644. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1644. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1644. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1644. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[17] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1685. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1685. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1685. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1685. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1685. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1685. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1685. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1685. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1685. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1685. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1685. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1685. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1685. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1730. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1730. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1730. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1730. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1730. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1730. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1730. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1730. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1730. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1730. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1730. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1730. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1730. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[18] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[19] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: `!h' float specifier changed to `!ht'. + + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (12.45624pt too wide) in paragraph at lines 1953--1966 + [] + [] + + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1982. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1982. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1982. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1982. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1982. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1982. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1982. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1982. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1982. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1982. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1982. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1982. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1982. + +[20] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[21] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[22] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2170. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2170. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2170. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2170. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2170. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2170. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2170. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2170. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2170. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2170. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2170. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2170. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2170. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2228. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2228. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2228. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2228. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2228. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2228. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2228. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2228. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2228. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2228. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2228. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2228. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2228. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[23] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2301. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2301. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[24] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2382. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2382. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.59204pt too wide) in paragraph at lines 2436--2438 +[]\EU1/LuxiMono(0)/bx/n/8.2125 BYTES\EU1/UtopiaStd-Regular(0)/m/it/10.95 , which signifies that this meter can be configured with rates expressed in bytes/second. + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2461. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2461. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2461. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2461. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2461. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2461. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2461. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2461. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2461. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2461. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2461. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2461. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2461. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[25] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (18.74199pt too wide) in paragraph at lines 2478--2485 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 carrying P4 standard annotations \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_in") \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_out")\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[26] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[27] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2614. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[28] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[29] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2832. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2832. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2832. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2832. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2832. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2832. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2832. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2832. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2832. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2832. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2832. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2832. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2832. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2879. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[30] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2917. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[31] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[32] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[33] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[34] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[35] [36] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1629) in paragraph at lines 3521--3523 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For example, the following P4$[]$ objects involve complex types that need to be exposed in + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[37] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1454) in paragraph at lines 3569--3578 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 ification for all the named types in the P4$[]$ program. These named types are \EU1/LuxiMono(0)/bx/n/8.2125 struct\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 header\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + + +Underfull \hbox (badness 1831) in paragraph at lines 3569--3578 +\EU1/LuxiMono(0)/bx/n/8.2125 header_union\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 enum \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 serializable_enum\EU1/UtopiaStd-Regular(0)/m/it/10.95 ; for each of these we have a type specification mes- + [] + + +Underfull \hbox (badness 1845) in paragraph at lines 3569--3578 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 sage, respectively \EU1/LuxiMono(0)/bx/n/8.2125 P4StructTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnionTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4EnumTypeSpec \EU1/UtopiaStd-Regular(0)/m/it/10.95 and + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (33.06564pt too wide) in paragraph at lines 3604--3611 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 “binary string” types (\EU1/LuxiMono(0)/bx/n/8.2125 bit\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 int\EU1/UtopiaStd-Regular(0)/m/it/10.95 , and \EU1/LuxiMono(0)/bx/n/8.2125 varbit\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) are grouped together in the \EU1/LuxiMono(0)/bx/n/8.2125 P4BitstringLikeTypeSpec + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3621. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3621. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3621. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3621. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3621. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3621. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3621. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3621. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3621. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3621. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3621. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3621. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3621. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[38] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.46094pt too wide) in paragraph at lines 3658--3661 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 An invalid header union (i.e. all headers in the union are invalid) is represented by a \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnion + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[39] [40] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3795. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3795. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[41] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (24.68944pt too wide) in paragraph at lines 3871--3876 +[]\EU1/LuxiMono(0)/bx/n/8.2125 translated_type\EU1/UtopiaStd-Regular(0)/m/it/10.95 , if and only if the P4 \EU1/LuxiMono(0)/bx/n/8.2125 type \EU1/UtopiaStd-Regular(0)/m/it/10.95 declaration was annotated with \EU1/LuxiMono(0)/bx/n/8.2125 @p4runtime_translation\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[42] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3958. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3958. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3958. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3958. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3958. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3958. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3958. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3958. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3958. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3958. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3958. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3958. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3958. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[43] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[44] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[45] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[46] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[47] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[48] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[49] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[50] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[51] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[52] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4928. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[53] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[54] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (9.29865pt too wide) in paragraph at lines 5176--5178 + []\EU1/lmr/bx/n/10.95 9.2.2.1.| Rules on Setting \EU1/LuxiMono(0)/bx/n/8.2125 max_size[] \EU1/UtopiaStd-Regular(0)/m/it/10.95 The valid values for \EU1/LuxiMono(0)/bx/n/8.2125 max_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 depend on the static \EU1/LuxiMono(0)/bx/n/8.2125 max_group_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[55] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[56] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[57] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[58] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5451. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5451. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5491. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5491. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5491. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5491. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5491. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5491. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5491. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5491. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5491. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5491. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5491. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5491. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5491. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1331) in paragraph at lines 5494--5501 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 A direct counter is a direct resource associated with a \EU1/LuxiMono(0)/bx/n/8.2125 TableEntry \EU1/UtopiaStd-Regular(0)/m/it/10.95 (see [][]Direct Resources[][]). The + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[59] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5568. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[60] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5661. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5692. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5692. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5692. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5692. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5692. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5692. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5692. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5692. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5692. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5692. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5692. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5692. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5692. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[61] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5769. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5769. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5769. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5769. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5769. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5769. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5769. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5769. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5769. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5769. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5769. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5769. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5769. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[62] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5865. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5865. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5865. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5865. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5865. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5865. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5865. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5865. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5865. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5865. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5865. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5865. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5865. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5875. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5875. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5875. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5875. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5875. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5875. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5875. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5875. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5875. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5875. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5875. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5875. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5875. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[63] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5979. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5979. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5979. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5979. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5979. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5979. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5979. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5979. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5979. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5979. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5979. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5979. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5979. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[64] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[65] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.93839pt too wide) in paragraph at lines 6090--6092 +[]\EU1/LuxiMono(0)/bx/n/8.2125 MODIFY\EU1/UtopiaStd-Regular(0)/m/it/10.95 : Modify the attributes of a given clone session entry, indexed by the given \EU1/LuxiMono(0)/bx/n/8.2125 clone_session_id\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6102. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6102. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6102. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6102. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6102. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6102. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6102. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6102. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6102. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6102. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6102. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6102. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6102. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[66] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6238. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6238. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6238. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6238. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6238. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6238. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6238. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6238. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6238. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6238. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6238. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6238. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6238. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[67] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6282. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6282. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6282. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6282. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6282. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6282. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6282. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6282. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6282. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6282. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6282. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6282. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6282. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[68] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[69] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6480. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6480. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6480. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6480. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6480. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6480. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6480. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6480. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6480. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6480. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6480. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6480. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6480. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[70] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/error-report.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <14.4> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 6597. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6597. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6597. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[71] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: Hyper reference `wildcard-reads' on page 72 undefined on input line 6619. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[72] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6699. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6699. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6699. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6699. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6699. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6699. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6699. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6699. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6699. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6699. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6699. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6699. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6699. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[73] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[74] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[75] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (34.34796pt too wide) in paragraph at lines 6971--6976 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If an error is encountered before even trying to attempt individual batch updates, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.66206pt too wide) in paragraph at lines 6980--6991 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 Otherwise, if one or more updates in the batch (\EU1/LuxiMono(0)/bx/n/8.2125 WriteRequest.updates\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) failed, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[76] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7027. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7027. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7027. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7027. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7027. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7027. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7027. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7027. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7027. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7027. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7027. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7027. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7027. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[77] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.4752pt too wide) in paragraph at lines 7222--7226 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 responding to \EU1/LuxiMono(0)/bx/n/8.2125 a \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 c\EU1/UtopiaStd-Regular(0)/m/it/10.95 , followed by a status \EU1/LuxiMono(0)/bx/n/8.2125 {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[78] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7250. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7250. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7250. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7250. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7250. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7250. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7250. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7250. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7250. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7250. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7250. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7250. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7250. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[79] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7373. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7373. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7373. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7373. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7373. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7373. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7373. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7373. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7373. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7373. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7373. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7373. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7373. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[80] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 7471--7474 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If a P4Runtime server supports both \EU1/LuxiMono(0)/bx/n/8.2125 SetForwardingPipelineConfig \EU1/UtopiaStd-Regular(0)/m/it/10.95 as well as returning the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[81] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[82] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[83] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[84] +File: build/psa-metadata-translation.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[85] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[86] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[87] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[88] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[89] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 8178. + + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 8178. + +[90] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 8214--8221 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 p4info-ext should include a Protobuf message definition for every extern type that can + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[91] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 4036) in paragraph at lines 8269--8276 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 P4Runtime also supports streaming arbitrary Protobuf messages between the server and the + [] + + +Underfull \hbox (badness 1629) in paragraph at lines 8269--8276 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 client, by including an \EU1/LuxiMono(0)/bx/n/8.2125 Any \EU1/UtopiaStd-Regular(0)/m/it/10.95 Protobuf field [[][]28[][]] named \EU1/LuxiMono(0)/bx/n/8.2125 other \EU1/UtopiaStd-Regular(0)/m/it/10.95 in both \EU1/LuxiMono(0)/bx/n/8.2125 p4.v1.StreamMessageRequest + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[92] +Underfull \hbox (badness 1997) in paragraph at lines 8387--8389 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 Table [][]7[][] lists P4$[]$ annotations introduced primarily for the purpose of adding features for the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[93] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[94] +Underfull \hbox (badness 10000) in paragraph at lines 8543--8544 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Enums in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 1. 0- spec. html# sec- enum- + [] + + +Underfull \hbox (badness 4001) in paragraph at lines 8549--8550 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Google Cloud APIs Versioning - Backwards-Compatibility.” [][]\EU1/lmtt/m/n/10.95 https:// cloud. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 8558--8559 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “gRPC Streaming RPCs in C++.” [][]\EU1/lmtt/m/n/10.95 https:// grpc. io/ docs/ tutorials/ basic/ c. html# + [] + + +Underfull \hbox (badness 7576) in paragraph at lines 8561--8562 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Introducing New Types in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 1. 0- spec. + [] + + +Underfull \hbox (badness 2671) in paragraph at lines 8567--8568 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “P4 Concurrency Model.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 1. 0- spec. html# sec- + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 8570--8571 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” + [] + +[95] +Underfull \hbox (badness 10000) in paragraph at lines 8588--8589 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Action Selector.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# sec- action- + [] + + +Underfull \hbox (badness 2409) in paragraph at lines 8597--8598 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Empty Group Action Appendix.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# + [] + + +Underfull \hbox (badness 6396) in paragraph at lines 8600--8601 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Select Expressions in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 1. 0- spec. html# + [] + + +Underfull \hbox (badness 1668) in paragraph at lines 8612--8613 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Any Protobuf Message.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ protocol- buffers/ docs/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 8618--8619 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC C++ Error Details Library.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ grpc/ grpc/ blob/ master/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 8621--8622 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC Canonical Status Codes.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ maps- booking/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 8627--8628 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Protobuf MessageDifferencer in the C++ API.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + +[96] +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 8639. +[97] +Package atveryend Info: Empty hook `AfterLastShipout' on input line 8639. +(build/P4Runtime-Spec.aux) +Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 8639. +Package atveryend Info: Empty hook `AtEndAfterFileList' on input line 8639. + +LaTeX Font Warning: Some font shapes were not available, defaults substituted. + + +LaTeX Warning: There were undefined references. + + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 27509 strings out of 493638 + 517170 string characters out of 6146796 + 564847 words of memory out of 5000000 + 30611 multiletter control sequences out of 15000+600000 + 14633 words of font info for 98 fonts, out of 8000000 for 9000 + 1328 hyphenation exceptions out of 8191 + 48i,19n,81p,10429b,901s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on build/P4Runtime-Spec.pdf (97 pages). diff --git a/spec/v1.0.0/P4Runtime-Spec.pdf b/spec/v1.0.0/P4Runtime-Spec.pdf new file mode 100644 index 00000000..488a23a3 Binary files /dev/null and b/spec/v1.0.0/P4Runtime-Spec.pdf differ diff --git a/spec/v1.0.0/P4Runtime-Spec.tex b/spec/v1.0.0/P4Runtime-Spec.tex new file mode 100644 index 00000000..fc090e9b --- /dev/null +++ b/spec/v1.0.0/P4Runtime-Spec.tex @@ -0,0 +1,8639 @@ +\documentclass[11pt]{article} +% generated by Madoko, version 1.1.4 +%mdk-data-line={1} + + +\usepackage[heading-base={2},section-num={False},bib-label={hide},fontspec={True}]{madoko2} +\usepackage[top=1in, bottom=1.25in, left=1in, right=1in]{geometry} +\usepackage{fancyhdr} +%mdk-data-line={11} + + \setlength{\headheight}{30pt} + \setlength{\emergencystretch}{2em} + +\begin{document} + + + +{\mdfontfamily{UtopiaStd-Regular} +%mdk-data-line={203} +\mdxtitleblockstart{} +%mdk-data-line={203} +\mdxtitle{{\sffamily{\bfseries\mdline{203}P4Runtime Specification}}}%mdk + +%mdk-data-line={206} +\mdxtitlenote{{\sffamily{\bfseries\mdline{206}version 1.0.0}}}%mdk +\mdxauthorstart{} +%mdk-data-line={211} +\mdxauthorname{\mdline{211}The P4.org API Working Group}%mdk +\mdxauthorend +%mdk-data-line={220} +\mdxtitlefooter{{\sffamily{\bfseries\mdline{220}2019-10-09}}}%mdk +\mdtitleauthorrunning{}{}\mdxtitleblockend%mdk + +%mdk-data-line={205} +\begin{abstract}%mdk + +%mdk-data-line={206} +\noindent\mdline{206}P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.%mdk +%mdk +\end{abstract}%mdk +\mdline{214} +\begin{mdtoc}%mdk + +\section*{Contents}\label{sec-contents}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-introduction-and-scope}{\mdref{sec-introduction-and-scope}{1.\hspace*{0.5em}Introduction and Scope}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-language-version-applicability}{\mdref{sec-p4-language-version-applicability}{1.1.\hspace*{0.5em}P4 Language Version Applicability}}%mdk + +\mdtocitemx{sec-in-scope}{\mdref{sec-in-scope}{1.2.\hspace*{0.5em}In Scope}}%mdk + +\mdtocitemx{sec-not-in-scope}{\mdref{sec-not-in-scope}{1.3.\hspace*{0.5em}Not In Scope}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-terms-and-definitions}{\mdref{sec-terms-and-definitions}{2.\hspace*{0.5em}Terms and Definitions}}%mdk + +\mdtocitemx{sec-reference-architecture}{\mdref{sec-reference-architecture}{3.\hspace*{0.5em}Reference Architecture}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-idealized-workflow}{\mdref{sec-idealized-workflow}{3.1.\hspace*{0.5em}Idealized Workflow}}%mdk + +\mdtocitemx{sec-p4-as-behavioral-description-language}{\mdref{sec-p4-as-behavioral-description-language}{3.2.\hspace*{0.5em}P4 as a Behavioral Description Language}}%mdk + +\mdtocitemx{sec-alternative-workflows}{\mdref{sec-alternative-workflows}{3.3.\hspace*{0.5em}Alternative Workflows}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{\mdref{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{3.3.1.\hspace*{0.5em}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}}%mdk + +\mdtocitemx{sec-no-p4-source-available-p4info-available}{\mdref{sec-no-p4-source-available-p4info-available}{3.3.2.\hspace*{0.5em}No P4 Source Available, P4Info Available}}%mdk + +\mdtocitemx{sec-partial-p4info-and-p4-source-are-available}{\mdref{sec-partial-p4info-and-p4-source-are-available}{3.3.3.\hspace*{0.5em}Partial P4Info and P4 Source are Available}}%mdk + +\mdtocitemx{sec-p4info-role-based-subsets}{\mdref{sec-p4info-role-based-subsets}{3.3.4.\hspace*{0.5em}P4Info Role-Based Subsets}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-controller-use-cases}{\mdref{sec-controller-use-cases}{4.\hspace*{0.5em}Controller Use-cases}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-single-embedded-controller}{\mdref{sec-single-embedded-controller}{4.1.\hspace*{0.5em}Single Embedded Controller}}%mdk + +\mdtocitemx{sec-single-remote-controller}{\mdref{sec-single-remote-controller}{4.2.\hspace*{0.5em}Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-single-remote-controller}{\mdref{sec-embedded-single-remote-controller}{4.3.\hspace*{0.5em}Embedded + Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-two-remote-controllers}{\mdref{sec-embedded-two-remote-controllers}{4.4.\hspace*{0.5em}Embedded + Two Remote Controllers}}%mdk + +\mdtocitemx{sec-embedded-controller-two-high-availability-remote-controllers}{\mdref{sec-embedded-controller-two-high-availability-remote-controllers}{4.5.\hspace*{0.5em}Embedded Controller + Two High-Availability Remote Controllers}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-master-slave-arbitration-and-controller-replication}{\mdref{sec-master-slave-arbitration-and-controller-replication}{5.\hspace*{0.5em}Master-Slave Arbitration and Controller Replication}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-default-role}{\mdref{sec-default-role}{5.1.\hspace*{0.5em}Default Role}}%mdk + +\mdtocitemx{sec-arbitration-role-config}{\mdref{sec-arbitration-role-config}{5.2.\hspace*{0.5em}Role Config}}%mdk + +\mdtocitemx{sec-rules-for-handling-masterarbitrationupdate-messages-received-from-controllers}{\mdref{sec-rules-for-handling-masterarbitrationupdate-messages-received-from-controllers}{5.3.\hspace*{0.5em}Rules for Handling \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}} Messages Received from Controllers}}%mdk + +\mdtocitemx{sec-master-change}{\mdref{sec-master-change}{5.4.\hspace*{0.5em}Mastership Change}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-the-p4info-message}{\mdref{sec-the-p4info-message}{6.\hspace*{0.5em}The P4Info Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-common-messages}{\mdref{sec-common-messages}{6.1.\hspace*{0.5em}Common Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-documentation-message}{\mdref{sec-documentation-message}{6.1.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}} Message}}%mdk + +\mdtocitemx{sec-preamble-message}{\mdref{sec-preamble-message}{6.1.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}} Message}}%mdk + +\mdtocitemx{sec-annotating-p4-entities-with-documentation}{\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3.\hspace*{0.5em}Annotating P4 Entities with \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-pkginfo-message}{\mdref{sec-pkginfo-message}{6.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}} Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-annotating-p4-code-with-pkginfo}{\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1.\hspace*{0.5em}Annotating P4 code with PkgInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-id-allocation}{\mdref{sec-id-allocation}{6.3.\hspace*{0.5em}ID Allocation for P4Info Objects}}%mdk + +\mdtocitemx{sec-p4info-objects}{\mdref{sec-p4info-objects}{6.4.\hspace*{0.5em}P4Info Objects}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table}{\mdref{sec-table}{6.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}}%mdk + +\mdtocitemx{sec-action}{\mdref{sec-action}{6.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}}%mdk + +\mdtocitemx{sec-p4info-action-profile}{\mdref{sec-p4info-action-profile}{6.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}}%mdk + +\mdtocitemx{sec-counter-directcounter}{\mdref{sec-counter-directcounter}{6.4.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}}%mdk + +\mdtocitemx{sec-meter-directmeter}{\mdref{sec-meter-directmeter}{6.4.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}}%mdk + +\mdtocitemx{sec-controller-packet-meta}{\mdref{sec-controller-packet-meta}{6.4.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}}%mdk + +\mdtocitemx{sec-valueset}{\mdref{sec-valueset}{6.4.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}}%mdk + +\mdtocitemx{sec-register}{\mdref{sec-register}{6.4.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}}%mdk + +\mdtocitemx{sec-digest}{\mdref{sec-digest}{6.4.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}}%mdk + +\mdtocitemx{sec-p4info-extern}{\mdref{sec-p4info-extern}{6.4.10.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{\mdref{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{6.5.\hspace*{0.5em}Support for Arbitrary P4 Types with P4TypeInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-fwd-pipe-config}{\mdref{sec-p4-fwd-pipe-config}{7.\hspace*{0.5em}P4 Forwarding-Pipeline Configuration}}%mdk + +\mdtocitemx{sec-general-principles-for-message-formatting}{\mdref{sec-general-principles-for-message-formatting}{8.\hspace*{0.5em}General Principles for Message Formatting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-set-unset-protobuf-field}{\mdref{sec-set-unset-protobuf-field}{8.1.\hspace*{0.5em}Set / Unset Protobuf Field}}%mdk + +\mdtocitemx{sec-read-write-symmetry}{\mdref{sec-read-write-symmetry}{8.2.\hspace*{0.5em}Read-Write Symmetry}}%mdk + +\mdtocitemx{sec-zero-as-reserved-value}{\mdref{sec-zero-as-reserved-value}{8.3.\hspace*{0.5em}Zero as Reserved Value}}%mdk + +\mdtocitemx{sec-bytestrings}{\mdref{sec-bytestrings}{8.4.\hspace*{0.5em}Bytestrings}}%mdk + +\mdtocitemx{sec-representation-of-arbitrary-p4-types}{\mdref{sec-representation-of-arbitrary-p4-types}{8.5.\hspace*{0.5em}Representation of Arbitrary P4 Types}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-problem-statement}{\mdref{sec-problem-statement}{8.5.1.\hspace*{0.5em}Problem Statement}}%mdk + +\mdtocitemx{sec-p4-type-specifications-in-p4infoproto}{\mdref{sec-p4-type-specifications-in-p4infoproto}{8.5.2.\hspace*{0.5em}P4 Type Specifications in p4info.proto}}%mdk + +\mdtocitemx{sec-p4data-in-p4runtime-proto}{\mdref{sec-p4data-in-p4runtime-proto}{8.5.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}} in p4runtime.proto}}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{8.5.4.\hspace*{0.5em}Example}}%mdk + +\mdtocitemx{sec-enum-serializable-enum-and-error}{\mdref{sec-enum-serializable-enum-and-error}{8.5.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}, serializable \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}}%mdk + +\mdtocitemx{sec-user-defined-types}{\mdref{sec-user-defined-types}{8.5.6.\hspace*{0.5em}User-defined types}}%mdk + +\mdtocitemx{sec-trade-off-for-v10-release}{\mdref{sec-trade-off-for-v10-release}{8.5.7.\hspace*{0.5em}Trade-off for v1.0 Release}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-entity-msgs}{\mdref{sec-p4-entity-msgs}{9.\hspace*{0.5em}P4 Entity Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table-entry}{\mdref{sec-table-entry}{9.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-match-format}{\mdref{sec-match-format}{9.1.1.\hspace*{0.5em}Match Format}}%mdk + +\mdtocitemx{sec-action-specification}{\mdref{sec-action-specification}{9.1.2.\hspace*{0.5em}Action Specification}}%mdk + +\mdtocitemx{sec-default-entry}{\mdref{sec-default-entry}{9.1.3.\hspace*{0.5em}Default Entry}}%mdk + +\mdtocitemx{sec-constant-tables}{\mdref{sec-constant-tables}{9.1.4.\hspace*{0.5em}Constant Tables}}%mdk + +\mdtocitemx{sec-wildcard-reads}{\mdref{sec-wildcard-reads}{9.1.5.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-direct-resources}{\mdref{sec-direct-resources}{9.1.6.\hspace*{0.5em}Direct Resources}}%mdk + +\mdtocitemx{sec-idle-timeout}{\mdref{sec-idle-timeout}{9.1.7.\hspace*{0.5em}Idle-timeout}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-and-group}{\mdref{sec-action-profile-member-and-group}{9.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-programming}{\mdref{sec-action-profile-member-programming}{9.2.1.\hspace*{0.5em}Action Profile Member Programming}}%mdk + +\mdtocitemx{sec-action-profile-group-programming}{\mdref{sec-action-profile-group-programming}{9.2.2.\hspace*{0.5em}Action Profile Group Programming}}%mdk + +\mdtocitemx{sec-oneshot}{\mdref{sec-oneshot}{9.2.3.\hspace*{0.5em}One Shot Action Selector Programming}}%mdk + +\mdtocitemx{sec-constraints-on-action-selector-programming}{\mdref{sec-constraints-on-action-selector-programming}{9.2.4.\hspace*{0.5em}Constraints on action selector programming}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-counterentry-directcounterentry}{\mdref{sec-counterentry-directcounterentry}{9.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directcounterentry}{\mdref{sec-directcounterentry}{9.3.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\mdtocitemx{sec-counterentry}{\mdref{sec-counterentry}{9.3.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-meterentry-directmeterentry}{\mdref{sec-meterentry-directmeterentry}{9.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directmeterentry}{\mdref{sec-directmeterentry}{9.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\mdtocitemx{sec-meterentry}{\mdref{sec-meterentry}{9.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-packetreplicationengineentry}{\mdref{sec-packetreplicationengineentry}{9.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-multicastgroupentry}{\mdref{sec-multicastgroupentry}{9.5.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}}%mdk + +\mdtocitemx{sec-clonesessionentry}{\mdref{sec-clonesessionentry}{9.5.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-valuesetentry}{\mdref{sec-valuesetentry}{9.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}}%mdk + +\mdtocitemx{sec-registerentry}{\mdref{sec-registerentry}{9.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}}%mdk + +\mdtocitemx{sec-digestentry}{\mdref{sec-digestentry}{9.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}}%mdk + +\mdtocitemx{sec-extern-entry}{\mdref{sec-extern-entry}{9.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-error-reporting-messages}{\mdref{sec-error-reporting-messages}{10.\hspace*{0.5em}Error Reporting Messages}}%mdk + +\mdtocitemx{sec-atomicity-of-individual-write-and-read-operations}{\mdref{sec-atomicity-of-individual-write-and-read-operations}{11.\hspace*{0.5em}Atomicity of Individual \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} Operations}}%mdk + +\mdtocitemx{sec-write-rpc}{\mdref{sec-write-rpc}{12.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-batching-and-ordering-of-updates}{\mdref{sec-batching-and-ordering-of-updates}{12.1.\hspace*{0.5em}Batching and Ordering of Updates}}%mdk + +\mdtocitemx{sec-batch-atomicity}{\mdref{sec-batch-atomicity}{12.2.\hspace*{0.5em}Batch Atomicity}}%mdk + +\mdtocitemx{sec-error-reporting}{\mdref{sec-error-reporting}{12.3.\hspace*{0.5em}Error Reporting}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-read-rpc}{\mdref{sec-read-rpc}{13.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-nomenclature}{\mdref{sec-nomenclature}{13.1.\hspace*{0.5em}Nomenclature}}%mdk + +\mdtocitemx{sec-wildcard-reads}{\mdref{sec-wildcard-reads}{13.2.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-batch-processing}{\mdref{sec-batch-processing}{13.3.\hspace*{0.5em}Batch Processing}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{13.3.1.\hspace*{0.5em}Example}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-setforwardingpipelineconfig-rpc}{\mdref{sec-setforwardingpipelineconfig-rpc}{14.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-getforwardingpipelineconfig-rpc}{\mdref{sec-getforwardingpipelineconfig-rpc}{15.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-p4runtime-stream-messages}{\mdref{sec-p4runtime-stream-messages}{16.\hspace*{0.5em}P4Runtime Stream Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-packet-i_o}{\mdref{sec-packet-i_o}{16.1.\hspace*{0.5em}Packet I/O}}%mdk + +\mdtocitemx{sec-master-arbitration-update}{\mdref{sec-master-arbitration-update}{16.2.\hspace*{0.5em}Master Arbitration Update}}%mdk + +\mdtocitemx{sec-digest-messages}{\mdref{sec-digest-messages}{16.3.\hspace*{0.5em}Digest Messages}}%mdk + +\mdtocitemx{sec-table-idle-timeout-notification}{\mdref{sec-table-idle-timeout-notification}{16.4.\hspace*{0.5em}Table Idle Timeout Notification}}%mdk + +\mdtocitemx{sec-architecture-specific-notifications}{\mdref{sec-architecture-specific-notifications}{16.5.\hspace*{0.5em}Architecture-Specific Notifications}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-portability-considerations}{\mdref{sec-portability-considerations}{17.\hspace*{0.5em}Portability Considerations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-psa-metadata-translation}{\mdref{sec-psa-metadata-translation}{17.1.\hspace*{0.5em}PSA Metadata Translation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-translation-of-port-numbers}{\mdref{sec-translation-of-port-numbers}{17.1.1.\hspace*{0.5em}Translation of Port Numbers}}%mdk + +\mdtocitemx{sec-translation-of-packet-io-header-fields}{\mdref{sec-translation-of-packet-io-header-fields}{17.1.2.\hspace*{0.5em}Translation of Packet-IO Header Fields}}%mdk + +\mdtocitemx{sec-translation-of-match-fields}{\mdref{sec-translation-of-match-fields}{17.1.3.\hspace*{0.5em}Translation of Match Fields}}%mdk + +\mdtocitemx{sec-translation-of-action-parameters}{\mdref{sec-translation-of-action-parameters}{17.1.4.\hspace*{0.5em}Translation of Action Parameters}}%mdk + +\mdtocitemx{sec-port-translation-for-psa-extern-apis}{\mdref{sec-port-translation-for-psa-extern-apis}{17.1.5.\hspace*{0.5em}Port Translation for PSA Extern APIs}}%mdk + +\mdtocitemx{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{\mdref{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{17.1.6.\hspace*{0.5em}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-versioning}{\mdref{sec-p4runtime-versioning}{18.\hspace*{0.5em}P4Runtime Versioning}}%mdk + +\mdtocitemx{sec-extending-p4runtime}{\mdref{sec-extending-p4runtime}{19.\hspace*{0.5em}Extending P4Runtime for non-PSA Architectures}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-p4runtime-for-architecture-specific-externs}{\mdref{sec-extending-p4runtime-for-architecture-specific-externs}{19.1.\hspace*{0.5em}Extending P4Runtime for Architecture-Specific Externs}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-the-p4info-message}{\mdref{sec-extending-the-p4info-message}{19.1.1.\hspace*{0.5em}Extending the P4Info message}}%mdk + +\mdtocitemx{sec-extending-the-p4runtime-service}{\mdref{sec-extending-the-p4runtime-service}{19.1.2.\hspace*{0.5em}Extending the P4Runtime Service}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-architecture-specific-table-extensions}{\mdref{sec-architecture-specific-table-extensions}{19.2.\hspace*{0.5em}Architecture-Specific Table Extensions}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-new-match-types}{\mdref{sec-new-match-types}{19.2.1.\hspace*{0.5em}New Match Types}}%mdk + +\mdtocitemx{sec-new-table-properties}{\mdref{sec-new-table-properties}{19.2.2.\hspace*{0.5em}New Table Properties}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-known-limitations-of-p4runtime-v100}{\mdref{sec-known-limitations-of-p4runtime-v100}{20.\hspace*{0.5em}Known-limitations of P4Runtime v1.0.0}}%mdk + +\mdtocitemx{sec-security-concerns-for-p4runtime}{\mdref{sec-security-concerns-for-p4runtime}{21.\hspace*{0.5em}Security concerns for P4Runtime}}%mdk + +\mdtocitemx{sec-appendix}{\mdref{sec-appendix}{A.\hspace*{0.5em}Appendix}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-annotations}{\mdref{sec-p4-annotations}{A.1.\hspace*{0.5em}P4 Annotations}}%mdk + +\mdtocitemx{sec-value-set-example}{\mdref{sec-value-set-example}{A.2.\hspace*{0.5em}A More Complex Value Set Example}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-bibliography}{\mdref{sec-bibliography}{References}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{215} +\begin{mdtoc}%mdk + +\section*{Figures}\label{sec-figures}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{fig-reference-architecture}{\mdref{fig-reference-architecture}{\mdcaptionlabel{1}. P4Runtime Reference Architecture.}}%mdk + +\mdtocitemx{fig-single-embedded-controller}{\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}. Use-Case: Single Embedded Controller}}%mdk + +\mdtocitemx{fig-single-remote-controller}{\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}. Use-Case: Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-single-remote-controller}{\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}. Use-Case: Embedded Plus Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-controllers}{\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}. Use-Case: Embedded Plus Two Remote Controllers}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-ha-controllers}{\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}. Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk + +\mdtocitemx{fig-error-report}{\mdref{fig-error-report}{\mdcaptionlabel{7}. P4Runtime Error Report Message Format}}%mdk + +\mdtocitemx{fig-psa-metadata-translation}{\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}. P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{216} +\begin{mdtoc}%mdk + +\section*{Tables}\label{sec-tables}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{tab-mapping-p4-obj-ids}{\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}. Mapping of P4Info object type to 8-bit ID prefix value}}%mdk + +\mdtocitemx{tab-format-p4-obj-ids}{\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}. Format of P4Info object IDs}}%mdk + +\mdtocitemx{tab-exmpl-p4-obj-ids}{\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}. Example of statically-assigned P4Info object IDs}}%mdk + +\mdtocitemx{tab-valid-bytestring-encoding}{\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}. Examples of Valid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-invalid-bytestring-encoding}{\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}. Examples of Invalid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-p4-type-usage}{\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}. P4 Type Usage}}%mdk + +\mdtocitemx{tab-p4-annotations}{\mdref{tab-p4-annotations}{\mdcaptionlabel{7}. P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk + +%mdk-data-line={218} +\section{\mdline{218}1.\hspace*{0.5em}\mdline{218}Introduction and Scope}\label{sec-introduction-and-scope}%mdk%mdk + +%mdk-data-line={220} +\noindent\mdline{220}This document is published by the \mdline{220}\emph{P4.org API Working Group}\mdline{220}, which was +chartered\mdline{221}~[\mdcite{p4apiwgcharter}{16}]\mdline{221} to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called \mdline{223}\emph{P4Runtime}\mdline{223}. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +\mdline{226}\href{https://github.com/p4lang/p4runtime/tree/v1.0.0/proto}{https://github.com/p4lang/p4runtime/tree/v1.0.0/proto}\mdline{226}.%mdk + +%mdk-data-line={228} +\subsection{\mdline{228}1.1.\hspace*{0.5em}\mdline{228}P4 Language Version Applicability}\label{sec-p4-language-version-applicability}%mdk%mdk + +%mdk-data-line={230} +\noindent\mdline{230}P4Runtime is designed to be implemented in conjunction with the P4\mdline{230}\mdsub{16}\mdline{230} language +version or later. P4\mdline{231}\mdsub{14}\mdline{231} programs should be translated into P4\mdline{231}\mdsub{16}\mdline{231} to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P4\mdline{233}\mdsub{16}\mdline{233} 1.0, but were introduced in P4\mdline{233}\mdsub{16}\mdline{233} 1.1.0\mdline{233}~[\mdcite{p4spec}{1}]\mdline{233}.%mdk + +%mdk-data-line={235} +\subsection{\mdline{235}1.2.\hspace*{0.5em}\mdline{235}In Scope}\label{sec-in-scope}%mdk%mdk + +%mdk-data-line={237} +\noindent\mdline{237}This specification document defines the \mdline{237}\emph{semantics}\mdline{237} of \mdline{237}\emph{P4Runtime}\mdline{237} messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime:%mdk + +%mdk-data-line={241} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={241} +\item\mdline{241}Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA)\mdline{242}~[\mdcite{psa}{18}]\mdline{242} externs (\mdline{242}e.g.\mdline{242} Counters, Meters, Action +Profiles, \mdline{243}\dots{}\mdline{243}). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0.%mdk + +%mdk-data-line={245} +\item\mdline{245}Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism.%mdk + +%mdk-data-line={247} +\item\mdline{247}Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy.%mdk + +%mdk-data-line={250} +\item\mdline{250}Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities.%mdk + +%mdk-data-line={252} +\item\mdline{252}Packet I/O to enable streaming packets to \mdline{252}\&\mdline{252} from the control plane.%mdk + +%mdk-data-line={253} +\item\mdline{253}Batching support, with different atomicity guarantees.%mdk + +%mdk-data-line={254} +\item\mdline{254}In-the-field device-reconfiguration with a new P4 data plane.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={256} +\noindent\mdline{256}The following are in the scope of this specification document:%mdk + +%mdk-data-line={258} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={258} +\item\mdline{258}Rationale for the P4Runtime design.%mdk + +%mdk-data-line={259} +\item\mdline{259}Reference architecture and use-cases for deploying a P4Runtime service.%mdk + +%mdk-data-line={260} +\item\mdline{260}Detailed description of the API semantics.%mdk + +%mdk-data-line={261} +\item\mdline{261}Requirements for conformant implementations of the API.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={263} +\subsection{\mdline{263}1.3.\hspace*{0.5em}\mdline{263}Not In Scope}\label{sec-not-in-scope}%mdk%mdk + +%mdk-data-line={265} +\noindent\mdline{265}The following are not in scope of P4Runtime:%mdk + +%mdk-data-line={267} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={267} +\item\mdline{267}Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +\mdline{272}[\mdcite{openconfig}{32}]\mdline{272}. An open source implementation of these APIs is also in progress +as part of the Stratum project\mdline{273}~[\mdcite{stratum}{34}]\mdline{273}.%mdk + +%mdk-data-line={274} +\item\mdline{274}Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={279} +\noindent\mdline{279}The following are not in scope of this specification document:%mdk + +%mdk-data-line={281} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={281} +\item\mdline{281}Description of the P4 programming language; it is assumed that the reader is +already familiar with P4\mdline{282}\mdsub{16}\mdline{282}~[\mdcite{p4spec}{1}]\mdline{282}.%mdk + +%mdk-data-line={283} +\item\mdline{283}Descriptions of gRPC and Protobuf files in general.%mdk + +%mdk-data-line={284} +\item\mdline{284}Controller\mdline{284}~\mdref{sec-arbitration-role-config}{role}\mdline{284} definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={288} +\section{\mdline{288}2.\hspace*{0.5em}\mdline{288}Terms and Definitions}\label{sec-terms-and-definitions}%mdk%mdk + +%mdk-data-line={290} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries arbitration}}%mdk + +%mdk-data-line={290} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{290}Refers to the process through which P4Runtime ensures that at any given +time, there is a single master (\mdline{291}i.e.\mdline{291} a client with write access) for a given +role. Also referred to as \mdline{292}\textquotedblleft{}master-slave arbitration\textquotedblright{}\mdline{292}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries client}}%mdk + +%mdk-data-line={294} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{294}The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries COS}}%mdk + +%mdk-data-line={298} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{298}Class of Service. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries device}}%mdk + +%mdk-data-line={300} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{300}Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries entity}}%mdk + +%mdk-data-line={304} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{304}An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries gRPC}}%mdk + +%mdk-data-line={307} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{307}gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +\mdline{308}[\mdcite{grpc}{9}]\mdline{308}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries HA}}%mdk + +%mdk-data-line={310} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{310}High-Availability. Refers to a redundancy architecture. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Instrumentation}}%mdk + +%mdk-data-line={312} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{312}The part of the P4Runtime server which implements the calls to the device or +target native \mdline{313}\textquotedblleft{}SDK\textquotedblright{}\mdline{313} or backend. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries IPC}}%mdk + +%mdk-data-line={315} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{315}Inter-Process Communication. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Blob}}%mdk + +%mdk-data-line={317} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{317}A more colloquial term for P4 Device Config (Blob = Binary Large Object). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Device Config}}%mdk + +%mdk-data-line={319} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{319}The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its \mdline{321}\textquotedblleft{}program.\textquotedblright{}\mdline{321} +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4Info}}%mdk + +%mdk-data-line={323} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{323}Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4RT}}%mdk + +%mdk-data-line={327} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{327}Abbreviation for P4Runtime. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Protobuf (Protocol Buffers)}}%mdk + +%mdk-data-line={329} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{329}The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See\mdline{330}~[\mdcite{proto}{19}]\mdline{330}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries PSA}}%mdk + +%mdk-data-line={332} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{332}Portable Switch Architecture\mdline{332}~[\mdcite{psa}{18}]\mdline{332}; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RPC}}%mdk + +%mdk-data-line={336} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{336}Remote Procedure Call. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RTT}}%mdk + +%mdk-data-line={338} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{338}Round-trip time. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN}}%mdk + +%mdk-data-line={340} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{340}Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +probrammable, centralized network \mdline{345}\emph{controller}\mdline{345}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN port}}%mdk + +%mdk-data-line={347} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{347}A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries server}}%mdk + +%mdk-data-line={351} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{351}The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries stream}}%mdk + +%mdk-data-line={355} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{355}Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (\mdline{356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{356}), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and master-slave arbitration, among other +things. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries switch config}}%mdk + +%mdk-data-line={361} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{361}Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries target}}%mdk + +%mdk-data-line={366} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{366}The hardware or software entity which \mdline{366}\textquotedblleft{}executes\textquotedblright{}\mdline{366} the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with \mdline{367}\textquotedblleft{}device\textquotedblright{}\mdline{367}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries URI}}%mdk + +%mdk-data-line={369} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{369}Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={373} +\section{\mdline{373}3.\hspace*{0.5em}\mdline{373}Reference Architecture}\label{sec-reference-architecture}%mdk%mdk + +%mdk-data-line={374} +\noindent\mdline{374}Figure\mdline{374}~\mdref{fig-reference-architecture}{\mdcaptionlabel{1}}\mdline{374} represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. A multi-master protocol allows more than +one controller to participate, and a role-based arbitration scheme ensures only +one controller has write access to each read/write entity, or the pipeline config +itself. Any controller may perform read access to any entity or the pipeline +config. Later sections describe this in detail. For the sake of brevity, the +term controller may refer to one or more controllers.%mdk + +%mdk-data-line={383} +\mdline{383}The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +\mdline{386}[\mdcite{p4runtimerepo}{14}]\mdline{386}. It may be compiled via protoc\mdline{386} \mdline{386}\textemdash{}\mdline{386} the Protobuf compiler\mdline{386} \mdline{386}\textemdash{}\mdline{386} +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server.%mdk + +%mdk-data-line={391} +\mdline{391}Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository\mdline{392}~[\mdcite{pirepo}{15}]\mdline{392}. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, \mdline{394}e.g.\mdline{394} via callbacks, thus reducing the burden of implementing +P4Runtime.%mdk + +%mdk-data-line={397} +\mdline{397}The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard.%mdk + +%mdk-data-line={401} +\mdline{401}The controller can also set the \mdline{401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{401}, which amounts to +installing and running the compiled P4 program output, which is included in the +\mdline{403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{403} Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +\mdline{405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{405} to retrieve the device config and the P4Info.%mdk + +%mdk-data-line={408} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={409} +\noindent\mdline{409}\includegraphics[keepaspectratio=true,height=7cm]{build/reference-architecture}{}\mdline{409}%mdk + +%mdk-data-line={410} +\mdhr{}%mdk + +%mdk-data-line={411} +\noindent\mdline{411}\mdcaption{\textbf{Figure~\mdcaptionlabel{1}.}~\mdcaptiontext{P4Runtime Reference Architecture.}}%mdk +%mdk +\end{mdcenter}\label{fig-reference-architecture}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={415} +\subsection{\mdline{415}3.1.\hspace*{0.5em}\mdline{415}Idealized Workflow}\label{sec-idealized-workflow}%mdk%mdk + +%mdk-data-line={417} +\noindent\mdline{417}In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the \mdline{418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{418} +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a \mdline{420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{420} +RPC. Metadata in the P4Info describes both the overall program itself +(\mdline{422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{422}) as well as all entity instances derived from the P4 program\mdline{422} \mdline{422}\textemdash{}\mdline{422} +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise \mdline{424}\textquotedblleft{}handle\textquotedblright{}\mdline{424} used in API +calls.%mdk + +%mdk-data-line={427} +\mdline{427}In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible.%mdk + +%mdk-data-line={433} +\mdline{433}In some use cases, it is expected that a controller will store a +collection of multiple P4 \mdline{434}\textquotedblleft{}packages\textquotedblright{}\mdline{434}, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the \mdline{436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{436} from the target via the +\mdline{437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineRequest}}}\mdline{437} RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state.%mdk + +%mdk-data-line={441} +\subsection{\mdline{441}3.2.\hspace*{0.5em}\mdline{441}P4 as a Behavioral Description Language}\label{sec-p4-as-behavioral-description-language}%mdk%mdk + +%mdk-data-line={443} +\noindent\mdline{443}P4 can be considered a behavioral description of a switching device which may or +may not execute \mdline{444}\textquotedblleft{}P4\textquotedblright{}\mdline{444} natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a \mdline{446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineRequest}}}\mdline{446} to +change its pipeline \mdline{447}\textquotedblleft{}program\textquotedblright{}\mdline{447}, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device.%mdk + +%mdk-data-line={453} +\mdline{453}While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API.%mdk + +%mdk-data-line={462} +\mdline{462}In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the \mdline{463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{463} +message as well as the embedded \mdline{464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{464} fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections.%mdk + +%mdk-data-line={468} +\subsection{\mdline{468}3.3.\hspace*{0.5em}\mdline{468}Alternative Workflows}\label{sec-alternative-workflows}%mdk%mdk + +%mdk-data-line={470} +\noindent\mdline{470}Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary.%mdk + +%mdk-data-line={474} +\subsubsection{\mdline{474}3.3.1.\hspace*{0.5em}\mdline{474}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}\label{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}%mdk%mdk + +%mdk-data-line={476} +\noindent\mdline{476}In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +\mdline{478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{478}. The device\mdline{478}'\mdline{478}s configuration might be derived via some other +means to implement the P4 source code\mdline{479}'\mdline{479}s intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane.%mdk + +%mdk-data-line={483} +\subsubsection{\mdline{483}3.3.2.\hspace*{0.5em}\mdline{483}No P4 Source Available, P4Info Available}\label{sec-no-p4-source-available-p4info-available}%mdk%mdk + +%mdk-data-line={485} +\noindent\mdline{485}In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are:%mdk + +%mdk-data-line={488} +\begin{enumerate}%mdk + +%mdk-data-line={488} +\item{} +%mdk-data-line={488} +\mdline{488}The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security.%mdk%mdk + +%mdk-data-line={491} +\item{} +%mdk-data-line={491} +\mdline{491}The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={494} +\noindent\mdline{494}As discussed in Section\mdline{494}~\mdref{sec-p4-as-behavioral-description-language}{3.2}\mdline{494}, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, e.g. documentation.%mdk + +%mdk-data-line={499} +\subsubsection{\mdline{499}3.3.3.\hspace*{0.5em}\mdline{499}Partial P4Info and P4 Source are Available}\label{sec-partial-p4info-and-p4-source-are-available}%mdk%mdk + +%mdk-data-line={501} +\noindent\mdline{501}In this situation, a subset of the target\mdline{501}'\mdline{501}s pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code.%mdk + +%mdk-data-line={508} +\subsubsection{\mdline{508}3.3.4.\hspace*{0.5em}\mdline{508}P4Info Role-Based Subsets}\label{sec-p4info-role-based-subsets}%mdk%mdk + +%mdk-data-line={510} +\noindent\mdline{510}In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more.%mdk + +%mdk-data-line={514} +\section{\mdline{514}4.\hspace*{0.5em}\mdline{514}Controller Use-cases}\label{sec-controller-use-cases}%mdk%mdk + +%mdk-data-line={516} +\noindent\mdline{516}P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +\mdline{518}\mdref{sec-master-slave-arbitration-and-controller-replication}{section}\mdline{518}. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime\mdline{520}'\mdline{520}s flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex.%mdk + +%mdk-data-line={523} +\subsection{\mdline{523}4.1.\hspace*{0.5em}\mdline{523}Single Embedded Controller}\label{sec-single-embedded-controller}%mdk%mdk + +%mdk-data-line={525} +\noindent\mdline{525}Figure\mdline{525}~\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}}\mdline{525} shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases.%mdk + +%mdk-data-line={530} +\mdline{530}P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC.%mdk + +%mdk-data-line={535} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={536} +\noindent\mdline{536}\includegraphics[keepaspectratio=true,height=6cm]{build/single-embedded-controller}{}\mdline{536}%mdk + +%mdk-data-line={537} +\mdhr{}%mdk + +%mdk-data-line={538} +\noindent\mdline{538}\mdcaption{\textbf{Figure~\mdcaptionlabel{2}.}~\mdcaptiontext{Use-Case: Single Embedded Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-embedded-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={542} +\subsection{\mdline{542}4.2.\hspace*{0.5em}\mdline{542}Single Remote Controller}\label{sec-single-remote-controller}%mdk%mdk + +%mdk-data-line={544} +\noindent\mdline{544}Figure\mdline{544}~\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}}\mdline{544} shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections.%mdk + +%mdk-data-line={549} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={550} +\noindent\mdline{550}\includegraphics[keepaspectratio=true,height=7cm]{build/single-remote-controller}{}\mdline{550}%mdk + +%mdk-data-line={551} +\mdhr{}%mdk + +%mdk-data-line={552} +\noindent\mdline{552}\mdcaption{\textbf{Figure~\mdcaptionlabel{3}.}~\mdcaptiontext{Use-Case: Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={556} +\subsection{\mdline{556}4.3.\hspace*{0.5em}\mdline{556}Embedded\mdline{556} \mdline{556}+ Single Remote Controller}\label{sec-embedded-single-remote-controller}%mdk%mdk + +%mdk-data-line={558} +\noindent\mdline{558}Figure\mdline{558}~\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}}\mdline{558} illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller.%mdk + +%mdk-data-line={565} +\mdline{565}For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables.%mdk + +%mdk-data-line={569} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={570} +\noindent\mdline{570}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-single-remote-controller}{}\mdline{570}%mdk + +%mdk-data-line={571} +\mdhr{}%mdk + +%mdk-data-line={572} +\noindent\mdline{572}\mdcaption{\textbf{Figure~\mdcaptionlabel{4}.}~\mdcaptiontext{Use-Case: Embedded Plus Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={577} +\subsection{\mdline{577}4.4.\hspace*{0.5em}\mdline{577}Embedded\mdline{577} \mdline{577}+ Two Remote Controllers}\label{sec-embedded-two-remote-controllers}%mdk%mdk + +%mdk-data-line={579} +\noindent\mdline{579}Figure\mdline{579}~\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}}\mdline{579} illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +\mdline{582}e.g.\mdline{582} routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership.%mdk + +%mdk-data-line={585} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={586} +\noindent\mdline{586}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-controllers}{}\mdline{586}%mdk + +%mdk-data-line={587} +\mdhr{}%mdk + +%mdk-data-line={588} +\noindent\mdline{588}\mdcaption{\textbf{Figure~\mdcaptionlabel{5}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={593} +\subsection{\mdline{593}4.5.\hspace*{0.5em}\mdline{593}Embedded Controller\mdline{593} \mdline{593}+ Two High-Availability Remote Controllers}\label{sec-embedded-controller-two-high-availability-remote-controllers}%mdk%mdk + +%mdk-data-line={595} +\noindent\mdline{595}Figure\mdline{595}~\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}}\mdline{595} illustrates a single +embedded controller plus two remote controllers in an active-standby HA +(High-Availability) configuration. Controller \mdline{597}\#\mdline{597}1 is the active controller and is +in charge of some entities. If it fails, Controller \mdline{598}\#\mdline{598}2 takes over and manages +the tables formerly owned by Controller \mdline{599}\#\mdline{599}1. The mechanics of HA architectures +are beyond the scope of this document, but the P4Runtime multi-master +arbitration scheme supports it.%mdk + +%mdk-data-line={603} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={604} +\noindent\mdline{604}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-ha-controllers}{}\mdline{604}%mdk + +%mdk-data-line={605} +\mdhr{}%mdk + +%mdk-data-line={606} +\noindent\mdline{606}\mdcaption{\textbf{Figure~\mdcaptionlabel{6}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-ha-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={610} +\section{\mdline{610}5.\hspace*{0.5em}\mdline{610}Master-Slave Arbitration and Controller Replication}\label{sec-master-slave-arbitration-and-controller-replication}%mdk%mdk + +%mdk-data-line={613} +\noindent\mdline{613}The P4Runtime interface allows multiple controllers to be connected to the +P4Runtime server running on the device at the same time for the following +reasons:%mdk + +%mdk-data-line={617} +\begin{enumerate}%mdk + +%mdk-data-line={617} +\item{} +%mdk-data-line={617} +\mdline{617}Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, \mdline{618}\textquotedblleft{}roles\textquotedblright{}\mdline{618} (or \mdline{618}\textquotedblleft{}realms\textquotedblright{}\mdline{618}) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +master and the rest are slaves. Role definition, \mdline{621}i.e.\mdline{621} how P4 entities get +assigned to each role, is \mdline{622}\textbf{out-of-scope}\mdline{622} of this document.%mdk%mdk + +%mdk-data-line={624} +\item{} +%mdk-data-line={624} +\mdline{624}Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby slave controllers, which take over controlling the +devices in case the master controller goes offline.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={628} +\noindent\mdline{628}To support multiple controllers, P4Runtime uses the streaming channel (available +via \mdline{629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{629} RPC) for session management. The workflow is described as +follows:%mdk + +%mdk-data-line={632} +\begin{itemize}%mdk + +%mdk-data-line={632} +\item{} +%mdk-data-line={632} +\mdline{632}Each controller instance (e.g. a controller process) can participate in one or +more roles. For each (\mdline{633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{633}, \mdline{633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{633}), the controller receives an +\mdline{634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{634}. This \mdline{634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{634} can be the same for different roles and/or +devices, as long as the tuple (\mdline{635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{635}, \mdline{635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{635}, \mdline{635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{635}) is +unique. For each (\mdline{636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{636}, \mdline{636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{636}) that the controller wishes to +control, it establishes a \mdline{637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{637} with the P4Runtime server +responsible for that device, and sends a \mdline{638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{638} message +containing that tuple of (\mdline{639}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{639}, \mdline{639}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{639}, \mdline{639}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{639}) values. The +P4Runtime server selects a master independently for each (\mdline{640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{640}, +\mdline{641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{641}) pair. The master is the client that has the highest \mdline{641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{641} +among all active \mdline{642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{642} connections with the same (\mdline{642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{642}, +\mdline{643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{643}) values. A connection between a controller instance and a device id +\mdline{644}\textemdash{}\mdline{644} which involves a persistent \mdline{644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{644} \mdline{644}\textemdash{}\mdline{644} can be referred to as a +P4Runtime client.%mdk + +%mdk-data-line={647} +\mdline{647}Note that the P4Runtime server does not assign a \mdline{647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{647} or \mdline{647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{647} to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the \mdline{649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{649} values used for each +\mdline{650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{650}. The P4Runtime server only keeps track of the (\mdline{650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{650}, +\mdline{651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{651}, \mdline{651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{651}) of each \mdline{651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{651} that has sent a successful +\mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{652} message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +\mdline{654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{654} message to identify which client is making the \mdline{654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{654}, +not only the \mdline{655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{655}. This enables controllers to re-use the same +numeric \mdline{656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{656} values across different (\mdline{656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{656}, \mdline{656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{656}) +pairs. P4Runtime does not require \mdline{657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{657} values be reused across such +different (\mdline{658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{658}, \mdline{658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{658}) pairs; it allows it.%mdk%mdk + +%mdk-data-line={660} +\item{} +%mdk-data-line={660} +\mdline{660}To start a controller session, a controller first opens a bidirectional stream +channel to the server via the \mdline{661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{661} RPC for each device. This is the +first thing the controller does to identify itself to the P4Runtime server on +the device. This stream will be used for two purposes:%mdk + +%mdk-data-line={665} +\begin{itemize}%mdk + +%mdk-data-line={665} +\item{} +%mdk-data-line={665} +\mdline{665}\textbf{Session management:}\mdline{665} As soon as the controller opens the stream +channel, it sends a \mdline{666}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{666} message to the switch. The +controller populates the \mdline{667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{667} field in this message +using its \mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{668} and \mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{668}. Note that the \mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{668} field in the +\mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{669} is not populated by the controller. This field +is populated by the P4Runtime server when it sends a response back to the +client, as explained below.%mdk%mdk + +%mdk-data-line={673} +\item{} +%mdk-data-line={673} +\mdline{673}\textbf{Streaming of notifications (e.g. digests) and packet I/O:}\mdline{673} The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the master controller can participate in packet +I/O. This feature is explained in more details in the\mdline{677}~\mdref{sec-packet-i_o}{Packet +I/O}\mdline{678} section.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={680} +\item{} +%mdk-data-line={680} +\mdline{680}Note that the stream is opened per device. In case a switching platform has +multiple devices (\mdline{681}e.g.\mdline{681} multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different masters for different +devices. In this case, it is the responsibility of the P4Runtime server to +keep track of the master for each device (and role). More specifically, the +P4Runtime server will know which stream corresponds to the master controller +for each pair of (\mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{686}, \mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{686}) at any point of time.%mdk%mdk + +%mdk-data-line={688} +\item{} +%mdk-data-line={688} +\mdline{688}The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered \mdline{689}\textquotedblleft{}offline\textquotedblright{}\mdline{689} or +\mdline{690}\textquotedblleft{}dead\textquotedblright{}\mdline{690} as soon as its corresponding stream channel to the switch is +broken, in which case the P4Runtime server quickly sets one of the slave +controllers with the highest \mdline{692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{692} as master.%mdk%mdk + +%mdk-data-line={694} +\item{} +%mdk-data-line={694} +\mdline{694}The mechanism via which the controller receives the P4Runtime server details +which includes the \mdline{695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{695}, \mdline{695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip}}}\mdline{695} and \mdline{695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{695}, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +\mdline{699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{699}) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks.%mdk%mdk + +%mdk-data-line={704} +\item{} +%mdk-data-line={704} +\mdline{704}After the controller sends a \mdline{704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{704} message to the P4Runtime +server, the server sends a \mdline{705}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{705} message back to the +controller, in which it populates the \mdline{706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{706}. The +controller must populate the \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{707}, \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{707}, and \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{707} +fields. The \mdline{708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{708} field is set to the highest value, \mdline{708}i.e.\mdline{708} the value +for the current master. The server also populates the \mdline{709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{709} field in the +\mdline{710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{710} (note that this field is not populated in the +\mdline{711}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{711} received by the controller). The value of the status +message is one of the following:%mdk + +%mdk-data-line={713} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={713} +\item\mdline{713}OK (with \mdline{713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{713} set to \mdline{713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.OK}}}\mdline{713}) when the controller is +determined to be the master for a given (\mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{714}, \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{714}).%mdk + +%mdk-data-line={715} +\item\mdline{715}Non-OK (with \mdline{715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{715} set to \mdline{715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.ALREADY\_EXISTS}}}\mdline{715}) when the +controller is determined to be a slave for a given (\mdline{716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{716}, +\mdline{717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{717}).%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={719} +\noindent\mdline{719}gRPC enables the server to identify which client originated each message in the +\mdline{720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{720} stream. For example, the C++ gRPC library\mdline{720}~[\mdcite{grpcstreamc}{10}]\mdline{720} in +synchronous mode enables a server process to cause a function to be called when +a new client creates a \mdline{722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{722} stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +\mdline{724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{724} is closed normally (or broken, \mdline{724}e.g.\mdline{724} because a client process +unexpectedly terminated). Thus the server can easily associate all +\mdline{726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{726} messages received from the same client, because they are +processed within the context of the same function call.%mdk + +%mdk-data-line={729} +\mdline{729}A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values \mdline{734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{734}, \mdline{734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{734}, and \mdline{734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{734} in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods\mdline{736}~[\mdcite{grpcauth}{8}]\mdline{736} that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server.%mdk + +%mdk-data-line={740} +\subsection{\mdline{740}5.1.\hspace*{0.5em}\mdline{740}Default Role}\label{sec-default-role}%mdk%mdk + +%mdk-data-line={742} +\noindent\mdline{742}A controller can omit the role message in \mdline{742}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{742}. This +implies the \mdline{743}\textquotedblleft{}default role\textquotedblright{}\mdline{743}, which corresponds to \mdline{743}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{743}. This +also implies that a default role has a \mdline{744}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{744} of 0 (default). If using a +default role, all RPCs from the controller (\mdline{745}e.g.\mdline{745} \mdline{745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{745}) must set the \mdline{745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{745} +to 0.%mdk + +%mdk-data-line={748} +\subsection{\mdline{748}5.2.\hspace*{0.5em}\mdline{748}Role Config}\label{sec-arbitration-role-config}%mdk%mdk + +%mdk-data-line={750} +\noindent\mdline{750}The \mdline{750}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{750} field in the \mdline{750}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{750} message sent by the +controller describes the role configuration, \mdline{751}i.e.\mdline{751} which operations are in the +scope of a given role. In particular, the definition of a role may include the +following:%mdk + +%mdk-data-line={755} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={755} +\item\mdline{755}A list of P4 entities for which the controller may issue \mdline{755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{755} updates and +receive notification messages (\mdline{756}e.g.\mdline{756} \mdline{756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{756} and +\mdline{757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{757}).%mdk + +%mdk-data-line={758} +\item\mdline{758}Whether the controller is able to receive \mdline{758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{758} messages, along with a +filtering mechanism based on the values of the \mdline{759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{759} fields to +select which \mdline{760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{760} messages should be sent to the controller.%mdk + +%mdk-data-line={761} +\item\mdline{761}Whether the controller is able to send \mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{761} messages, along with a +filtering mechanism based on the values of the \mdline{762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{762} fields to +select which \mdline{763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{763} messages are allowed to be sent by the controller.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={765} +\noindent\mdline{765}An unset \mdline{765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{765} implies \mdline{765}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{765} (similar to the default +role explained above). In order to support different role definition schemes, +\mdline{767}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{767} is defined as an \mdline{767}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{767} Protobuf message\mdline{767}~[\mdcite{protoany}{28}]\mdline{767}. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion.%mdk + +%mdk-data-line={772} +\subsection{\mdline{772}5.3.\hspace*{0.5em}\mdline{772}Rules for Handling \mdline{772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{772} Messages Received from Controllers}\label{sec-rules-for-handling-masterarbitrationupdate-messages-received-from-controllers}%mdk%mdk + +%mdk-data-line={774} +\begin{enumerate}%mdk + +%mdk-data-line={774} +\item{} +%mdk-data-line={774} +\mdline{774}If the \mdline{774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{774} message is received for the first time (for +a newly connected controller):%mdk + +%mdk-data-line={777} +\begin{enumerate}%mdk + +%mdk-data-line={777} +\item{} +%mdk-data-line={777} +\mdline{777}If \mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{777} does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +\mdline{779}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{779} error.%mdk%mdk + +%mdk-data-line={781} +\item{} +%mdk-data-line={781} +\mdline{781}If the \mdline{781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{781} is already used by another controller for the same +(\mdline{782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{782}, \mdline{782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{782}), the P4Runtime server shall terminate the stream +by returning an \mdline{783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{783} error.%mdk%mdk + +%mdk-data-line={785} +\item{} +%mdk-data-line={785} +\mdline{785}If the max number of clients for the given (\mdline{785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{785}, \mdline{785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{785}) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a \mdline{787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{787} error.%mdk%mdk + +%mdk-data-line={789} +\item{} +%mdk-data-line={789} +\mdline{789}Otherwise, the controller is added to a list of connected controllers for +the given (\mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{790}, \mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{790}) and the controller is notified by +sending a \mdline{791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{791} message back to it, as explained +earlier.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={794} +\item{} +%mdk-data-line={794} +\mdline{794}If the \mdline{794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{794} message is received from an already +connected controller:%mdk + +%mdk-data-line={797} +\begin{enumerate}%mdk + +%mdk-data-line={797} +\item{} +%mdk-data-line={797} +\mdline{797}If the \mdline{797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{797} does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{799} error.%mdk%mdk + +%mdk-data-line={801} +\item{} +%mdk-data-line={801} +\mdline{801}Otherwise, if the \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{801} matches the current \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{801} assigned to +this stream:%mdk + +%mdk-data-line={804} +\begin{enumerate}%mdk + +%mdk-data-line={804} +\item{} +%mdk-data-line={804} +\mdline{804}If the \mdline{804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{804} also matches the one assigned to this stream, +the server will accept the (new) \mdline{805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{805} only if this +controller is the current master. If the controller is not a master, +the operation is a no-op.%mdk%mdk + +%mdk-data-line={809} +\item{} +%mdk-data-line={809} +\mdline{809}If the \mdline{809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{809} is already assigned to another controller stream +for the same (\mdline{810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{810}, \mdline{810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{810}), the P4Runtime server shall +terminate the stream by returning an \mdline{811}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{811} error.%mdk%mdk + +%mdk-data-line={813} +\item{} +%mdk-data-line={813} +\mdline{813}Otherwise, the P4Runtime server updates the \mdline{813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{813} for this +controller. If this makes the client the new master, the server will +also accept the given \mdline{815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{815} and follow the \mdline{815}\textquotedblleft{}mastership change +rules\textquotedblright{}\mdline{816} described in the\mdline{816}~\mdref{sec-master-change}{following section}\mdline{816}.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={818} +\item{} +%mdk-data-line={818} +\mdline{818}Otherwise (\mdline{818}i.e.\mdline{818} \mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{818} is different from current \mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{818} assigned to +this stream), the P4Runtime server moves the controller to the new role. +This controller will then be treated as a new controller for the new +(\mdline{821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{821}, \mdline{821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{821}). The server accepts the given \mdline{821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{821} only +if the client becomes master, in which case the server also follows the +\mdline{823}\textquotedblleft{}mastership change rules\textquotedblright{}\mdline{823} described in the\mdline{823}~\mdref{sec-master-change}{following +section}\mdline{824}.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={826} +\noindent\mdline{826}If \mdline{826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{826} does not match the \mdline{826}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{826} scheme previously agreed upon, +the server must return an \mdline{827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{827} error.%mdk + +%mdk-data-line={829} +\subsection{\mdline{829}5.4.\hspace*{0.5em}\mdline{829}Mastership Change}\label{sec-master-change}%mdk%mdk + +%mdk-data-line={831} +\noindent\mdline{831}\textquotedblleft{}Mastership change\textquotedblright{}\mdline{831} refers to either one of these cases:%mdk + +%mdk-data-line={833} +\begin{enumerate}%mdk + +%mdk-data-line={833} +\item{} +%mdk-data-line={833} +\mdline{833}A new \mdline{833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{833} is received from an already connected +controller for a given (\mdline{834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{834}, \mdline{834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{834}), which changes the controller +mastership status (the controller becomes master or slave).%mdk%mdk + +%mdk-data-line={837} +\item{} +%mdk-data-line={837} +\mdline{837}A streaming channel for a given master controller breaks, forcing a new +master to be elected.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={840} +\noindent\mdline{840}In case of a mastership change, the P4Runtime server shall send the +\mdline{841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{841} of the master to \mdline{841}\emph{all}\mdline{841} the connected controllers for a given +(\mdline{842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{842}, \mdline{842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{842}). The \mdline{842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{842} sent back to all the +connected controllers has a \mdline{843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{843} message populated with the +\mdline{844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{844}, \mdline{844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{844}, and \mdline{844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{844} of the master, as well as an OK status +for the master and non-OK status (with \mdline{845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{845} error code) for slaves.%mdk + +%mdk-data-line={847} +\section{\mdline{847}6.\hspace*{0.5em}\mdline{847}The P4Info Message}\label{sec-the-p4info-message}%mdk%mdk + +%mdk-data-line={849} +\noindent\mdline{849}The purpose of P4Info was described under +\mdline{850}\mdref{sec-reference-architecture}{Reference Architecture}\mdline{850}. +Here we describe the various +components.%mdk + +%mdk-data-line={854} +\subsection{\mdline{854}6.1.\hspace*{0.5em}\mdline{854}Common Messages}\label{sec-common-messages}%mdk%mdk + +%mdk-data-line={856} +\noindent\mdline{856}These messages appear nested within many other messages.%mdk + +%mdk-data-line={858} +\subsubsection{\mdline{858}6.1.1.\hspace*{0.5em}\mdline{858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{858} Message}\label{sec-documentation-message}%mdk%mdk + +%mdk-data-line={860} +\noindent\mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{860} is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers.%mdk + +%mdk-data-line={864} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={865} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Documentation~\{\\ +~~{\mdcolor{darkgreen}//~A~brief~description~of~something,~e.g.~one~sentence}\\ +~~{\bfseries{\mdcolor{navy}string}}~brief~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~A~more~verbose~description~of~something.}\\ +~~{\mdcolor{darkgreen}//~Multiline~is~accepted.~Markup~format~(if~any)~is~TBD.}\\ +~~{\bfseries{\mdcolor{navy}string}}~description~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={873} +\subsubsection{\mdline{873}6.1.2.\hspace*{0.5em}\mdline{873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{873} Message}\label{sec-preamble-message}%mdk%mdk + +%mdk-data-line={875} +\noindent\mdline{875}The preamble serves as the \mdline{875}\textquotedblleft{}descriptor\textquotedblright{}\mdline{875} for each entity and contains the unique +instance ID, name, alias, annotations and documentation.%mdk + +%mdk-data-line={878} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={879} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Preamble~\{\\ +~~{\mdcolor{darkgreen}//~ids~share~the~same~number-space;~e.g.~table~ids~cannot~overlap~with~counter}\\ +~~{\mdcolor{darkgreen}//~ids.~Even~though~this~is~irrelevant~to~this~proto~definition,~the~ids~are}\\ +~~{\mdcolor{darkgreen}//~allocated~in~such~a~way~that~it~is~possible~based~on~an~id~to~deduce~the}\\ +~~{\mdcolor{darkgreen}//~resource~type~(e.g.~table,~action,~counter,~...).~This~means~that~code}\\ +~~{\mdcolor{darkgreen}//~using~these~ids~can~detect~if~the~wrong~resource~type~is~used}\\ +~~{\mdcolor{darkgreen}//~somewhere.~This~also~means~that~ids~of~different~types~can~be~mixed}\\ +~~{\mdcolor{darkgreen}//~(e.g.~direct~resource~list~for~a~table)~without~ambiguity.~Note~that~id~0}\\ +~~{\mdcolor{darkgreen}//~is~reserved~and~means~"invalid~id".}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name~of~the~P4~object,~e.g.~c1.c2.ipv4\_lpm}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~an~alias~(alternative~name)~for~the~P4~object,~probably~shorter~than~its}\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name.~The~only~constraint~is~for~it~to~be~unique~with}\\ +~~{\mdcolor{darkgreen}//~respect~to~other~P4~objects~of~the~same~type.~By~default,~the~compiler~uses}\\ +~~{\mdcolor{darkgreen}//~the~shortest~suffix~of~the~name~that~uniquely~identifies~the~object.~For}\\ +~~{\mdcolor{darkgreen}//~example~if~the~P4~program~contains~two~tables~with~names~s.c1.t~and~s.c2.t,}\\ +~~{\mdcolor{darkgreen}//~the~default~aliases~will~respectively~be~c1.t~and~c2.t.~In~the~future,~the}\\ +~~{\mdcolor{darkgreen}//~P4~programmer~may~also~be~able~to~override~the~default~alias~for~any~P4}\\ +~~{\mdcolor{darkgreen}//~object~(TBD).}\\ +~~{\bfseries{\mdcolor{navy}string}}~alias~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~Documentation~of~the~entity}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={906} +\subsubsection{\mdline{906}6.1.3.\hspace*{0.5em}\mdline{906}Annotating P4 Entities with \mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}\label{sec-annotating-p4-entities-with-documentation}%mdk%mdk + +%mdk-data-line={908} +\noindent\mdline{908}P4 entities may be annotated using the following annotations:%mdk + +%mdk-data-line={910} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={911} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}(string...)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}(string...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={915} +\noindent\mdline{915}Attaching either or both of these annotations to an entity will generate a +P4Info\mdline{916}~\mdref{sec-documentation-message}{Documentation Message}\mdline{916}, which in turn will +appear in the\mdline{917}~\mdref{sec-preamble-message}{Preamble Message}\mdline{917} for the entity.%mdk + +%mdk-data-line={919} +\mdline{919}The P4 compiler should not emit \mdline{919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation}}}\mdline{919} messages in the P4Info for these +specific cases; instead, it should generate the \mdline{920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{920} messages as +described.%mdk + +%mdk-data-line={923} +\mdline{923}The following example shows documentation annotations for a \mdline{923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table}}}\mdline{923} entity:%mdk + +%mdk-data-line={925} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={926} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port.~\textbackslash{}}\\ +Uses~LPM~match~{\bfseries{\mdcolor{navy}type}}.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}table~my\_ipv4\_lkup~\{}\\ +{\mdcolor{maroon}~~...}\\ +{\mdcolor{maroon}\}}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={934} +\subsection{\mdline{934}6.2.\hspace*{0.5em}\mdline{934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{934} Message}\label{sec-pkginfo-message}%mdk%mdk + +%mdk-data-line={936} +\noindent\mdline{936}The \mdline{936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{936} message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. \mdline{937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{937} can be extracted +and used to facilitate \mdline{938}\textquotedblleft{}browsing\textquotedblright{}\mdline{938} of available P4 programs from a +library. Although all fields are technically \mdline{939}\textquotedblleft{}optional,\textquotedblright{}\mdline{939} every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included.%mdk + +%mdk-data-line={943} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={944} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Can~be~used~to~manage~multiple~P4~packages.}\\ +{\bfseries{\mdcolor{navy}message}}~PkgInfo~\{\\ +~~{\mdcolor{darkgreen}//~a~definitive~name~for~this~configuration,~e.g.~switch.p4\_v1.0}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~configuration~version,~free-format~string}\\ +~~{\bfseries{\mdcolor{navy}string}}~version~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~brief~and~detailed~descriptions}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~free-form;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~the~target~architecture,~e.g.~"psa"}\\ +~~{\bfseries{\mdcolor{navy}string}}~arch~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\mdcolor{darkgreen}//~organization~which~produced~the~configuration,~e.g.~"p4.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~organization~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~{\mdcolor{darkgreen}//~contact~info~for~support,e.g.~"tech-support@acme.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~contact~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~url~for~more~information,~e.g.~"http://support.p4.org/ref/p4/switch.p4\_v1.0"}\\ +~~{\bfseries{\mdcolor{navy}string}}~url~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}8};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={965} +\subsubsection{\mdline{965}6.2.1.\hspace*{0.5em}\mdline{965}Annotating P4 code with PkgInfo}\label{sec-annotating-p4-code-with-pkginfo}%mdk%mdk + +%mdk-data-line={967} +\noindent\mdline{967}A P4 progam\mdline{967}'\mdline{967}s \mdline{967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{967} may be declared using one or more of the following +annotations, attached to the \mdline{968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{968} block only:%mdk + +%mdk-data-line={970} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={971} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value{}[,key=value,...])}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("A~brief~description")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("A~longer\textbackslash{}}\\ +description{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@custom\_annotation(...)}\\ +{\mdcolor{maroon}@another\_custom\_annotation(...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={980} +\noindent\mdline{980}Above we see several different types of annotations:%mdk + +%mdk-data-line={982} +\begin{itemize}%mdk + +%mdk-data-line={982} +\item{} +%mdk-data-line={982} +\mdline{982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{982} \mdline{982}- This is used to populate a specific field within the \mdline{982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{982} +message. Multiple \mdline{983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{983} annotations are allowed. For compactness, +multiple key-value pairs can appear in a single \mdline{984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{984} annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The \mdline{986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{986}s must be from +among the message fields inside \mdline{987}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{987}, for example, \mdline{987}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{987}, \mdline{987}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}version}}}\mdline{987}, +etc. Each key-value pair assigns a value to the corresponding field inside the +single \mdline{989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{989} message for the program\mdline{989}'\mdline{989}s P4Info. One exception is that the +\mdline{990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{990} field of \mdline{990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{990} must be expressed as individual +\mdline{991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{991} and \mdline{991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{991} annotations, see next bullets. The key \mdline{991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}arch}}}\mdline{991} will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself.%mdk%mdk + +%mdk-data-line={995} +\item{} +%mdk-data-line={995} +\mdline{995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{995} \mdline{995}- This will populate the \mdline{995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.brief}}}\mdline{995} message field.%mdk%mdk + +%mdk-data-line={997} +\item{} +%mdk-data-line={997} +\mdline{997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{997} \mdline{997}- This will populate the \mdline{997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.description}}}\mdline{997} message field%mdk%mdk + +%mdk-data-line={999} +\item{} +%mdk-data-line={999} +\mdline{999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@\textless{}anything~else\textgreater{}}}}\mdline{999} \mdline{999}- This will create a \mdline{999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotation}}}\mdline{999} entry%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1001} +\noindent\mdline{1001}Declaring one or more of these annotations on \mdline{1001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1001} will +generate a single corresponding \mdline{1002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1002} message in the P4Info as described in +\mdline{1003}\mdref{sec-pkginfo-message}{PkgInfo Message}\mdline{1003}.%mdk + +%mdk-data-line={1005} +\mdline{1005}The following example shows \mdline{1005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1005} annotations using a mixture of single and +multiple key-value pairs. It also shows \mdline{1006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1006} and \mdline{1006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1006} annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the \mdline{1008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1008} message. The custom annotations will +be appended to the \mdline{1009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotations}}}\mdline{1009} list.%mdk + +%mdk-data-line={1011} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1012} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(name="switch.p4",version="2")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(organization="p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(contact="info@p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(url="www.p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("L2/L3~switch")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("L2/L3~switch.\textbackslash{}}\\ +Built~for~data-center~profile.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@my\_annotation1(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}@my\_annotation2(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}PSA\_Switch(IgPipeline,~PacketReplicationEngine(),~EgPipeline,}\\ +{\mdcolor{maroon}~~~~~~~~~~~BufferingQueueingEngine())~main;}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1025} +\subsection{\mdline{1025}6.3.\hspace*{0.5em}\mdline{1025}ID Allocation for P4Info Objects}\label{sec-id-allocation}%mdk%mdk + +%mdk-data-line={1027} +\noindent\mdline{1027}P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(\mdline{1031}e.g.\mdline{1031} table, action, counter, \mdline{1031}\dots{}\mdline{1031}). The most significant 8 bits of the ID +encodes the object type (as per Table\mdline{1032}~\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}}\mdline{1032}). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (\mdline{1034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.P4Ids.Prefix}}}\mdline{1034}). These values must +be used (\mdline{1035}e.g.\mdline{1035} by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table\mdline{1037}~\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}}\mdline{1037} shows the ID +layout.%mdk + +%mdk-data-line={1040} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1042} 8-bit prefix value}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1042} P4 object type}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{1044} 0x00}&\multicolumn{1}{|l|}{\mdline{1044} Reserved (unspecified)}\\ +\multicolumn{1}{|l}{\mdline{1045} 0x01}&\multicolumn{1}{|l|}{\mdline{1045} Action}\\ +\multicolumn{1}{|l}{\mdline{1046} 0x02}&\multicolumn{1}{|l|}{\mdline{1046} Table}\\ +\multicolumn{1}{|l}{\mdline{1047} 0x03}&\multicolumn{1}{|l|}{\mdline{1047} Value-set}\\ +\multicolumn{1}{|l}{\mdline{1048} 0x04}&\multicolumn{1}{|l|}{\mdline{1048} Controller header (header type with \mdline{1048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1048} annotation)}\\ +\multicolumn{1}{|l}{\mdline{1049} 0x05\mdline{1049}\dots{}\mdline{1049}0x0f}&\multicolumn{1}{|l|}{\mdline{1049} Reserved (for future P4 built-in objects)}\\ +\multicolumn{1}{|l}{\mdline{1050} 0x10}&\multicolumn{1}{|l|}{\mdline{1050} Reserved (start of PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1051} 0x11}&\multicolumn{1}{|l|}{\mdline{1051} PSA Action profiles / selectors}\\ +\multicolumn{1}{|l}{\mdline{1052} 0x12}&\multicolumn{1}{|l|}{\mdline{1052} PSA Counter}\\ +\multicolumn{1}{|l}{\mdline{1053} 0x13}&\multicolumn{1}{|l|}{\mdline{1053} PSA Direct counter}\\ +\multicolumn{1}{|l}{\mdline{1054} 0x14}&\multicolumn{1}{|l|}{\mdline{1054} PSA Meter}\\ +\multicolumn{1}{|l}{\mdline{1055} 0x15}&\multicolumn{1}{|l|}{\mdline{1055} PSA Direct meter}\\ +\multicolumn{1}{|l}{\mdline{1056} 0x16}&\multicolumn{1}{|l|}{\mdline{1056} PSA Register}\\ +\multicolumn{1}{|l}{\mdline{1057} 0x17}&\multicolumn{1}{|l|}{\mdline{1057} PSA Digest}\\ +\multicolumn{1}{|l}{\mdline{1058} 0x18\mdline{1058}\dots{}\mdline{1058}0x7f}&\multicolumn{1}{|l|}{\mdline{1058} Reserved (for future PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1059} 0x80}&\multicolumn{1}{|l|}{\mdline{1059} Reserved (start of vendor-specific extern types)}\\ +\multicolumn{1}{|l}{\mdline{1060} 0x81\mdline{1060}\dots{}\mdline{1060}0xfe}&\multicolumn{1}{|l|}{\mdline{1060} Vendor-specific extern types}\\ +\multicolumn{1}{|l}{\mdline{1061} 0xff}&\multicolumn{1}{|l|}{\mdline{1061} Reserved (max prefix value)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1063} +\mdhr{}%mdk + +%mdk-data-line={1064} +\noindent\mdline{1064}\mdcaption{\textbf{Table~\mdcaptionlabel{1}.}~\mdcaptiontext{Mapping of P4Info object type to 8-bit ID prefix value}}%mdk +%mdk +\end{mdcenter}\label{tab-mapping-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1067} +\begin{table}[h!]%mdk +\begin{mdblock}{text-align=center,breakable=true}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{cc}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1069} MSB bit 31 \mdline{1069}\dots{}\mdline{1069}\dots{}\mdline{1069}.. bit 24}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1069} bit 23 \mdline{1069}\dots{}\mdline{1069}\dots{}\mdline{1069}\dots{}\mdline{1069}\dots{}\mdline{1069}\dots{}\mdline{1069}\dots{}\mdline{1069}\dots{}\mdline{1069}.. bit 0 LSB}}\\ + +\midrule +\multicolumn{1}{|c}{\mdline{1071} Object type prefix}&\multicolumn{1}{|c|}{\mdline{1071} Generated suffix (\mdline{1071}e.g.\mdline{1071} by the compiler)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1073} +\mdhr{}%mdk + +%mdk-data-line={1074} +\noindent\mdline{1074}\mdcaption{\textbf{Table~\mdcaptionlabel{2}.}~\mdcaptiontext{Format of P4Info object IDs}}%mdk%mdk +\end{mdblock}\label{tab-format-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1078} +\mdline{1078}It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with \mdline{1079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1079} (see Table +\mdline{1080}\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}}\mdline{1080}). The compiler must honor the \mdline{1080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1080} annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (\mdline{1082}i.e.\mdline{1082} if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same \mdline{1084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1084} value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type.%mdk + +%mdk-data-line={1088} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth-7cm)/1}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{\mdinline{width=7cm}{{\bfseries\mdline{1090} P4 declaration(s)}}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1090} Compiler-allocated ID(s)}}\\ + +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1092} \mdline{1092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1092}}}&\multicolumn{1}{|l|}{\mdline{1092} 0x0212ab34}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1094} \mdline{1094}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1094}}}&\multicolumn{1}{|l|}{\mdline{1094} \mdline{1094}\textbf{Error}\mdline{1094}(same ID suffixes for 2 objects of the same type)}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1095} \mdline{1095}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tB...}}}\mdline{1095}}}&\multicolumn{1}{|l|}{\mdline{1095}}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1097} \mdline{1097}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1097}}}&\multicolumn{1}{|l|}{\mdline{1097} 0x0212ab34}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1098} \mdline{1098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~action~act1...}}}\mdline{1098}}}&\multicolumn{1}{|l|}{\mdline{1098} 0x0112ab34}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1100} +\mdhr{}%mdk + +%mdk-data-line={1101} +\noindent\mdline{1101}\mdcaption{\textbf{Table~\mdcaptionlabel{3}.}~\mdcaptiontext{Example of statically-assigned P4Info object IDs}}%mdk +%mdk +\end{mdcenter}\label{tab-exmpl-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1104} +\subsection{\mdline{1104}6.4.\hspace*{0.5em}\mdline{1104}P4Info Objects}\label{sec-p4info-objects}%mdk%mdk + +%mdk-data-line={1106} +\subsubsection{\mdline{1106}6.4.1.\hspace*{0.5em}\mdline{1106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}\label{sec-table}%mdk%mdk + +%mdk-data-line={1108} +\noindent\mdline{1108}Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields:%mdk + +%mdk-data-line={1111} +\begin{itemize}%mdk + +%mdk-data-line={1111} +\item{} +%mdk-data-line={1111} +\mdline{1111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1111}, a \mdline{1111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1111} message with the ID, name, and alias of this table.%mdk%mdk + +%mdk-data-line={1113} +\item{} +%mdk-data-line={1113} +\mdline{1113}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1113}, a repeated field of type \mdline{1113}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1113} representing the data to +be used to construct the lookup key matched in this table. Each \mdline{1114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1114} +message is defined with the following fields:%mdk + +%mdk-data-line={1117} +\begin{itemize}%mdk + +%mdk-data-line={1117} +\item{} +%mdk-data-line={1117} +\mdline{1117}id, the \mdline{1117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1117} identifier of this \mdline{1117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1117}, unique in the scope of +this table. No rules are prescribed on the way \mdline{1118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1118} IDs should be +allocated, as long as two \mdline{1119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1119} of the same table do not have the +same ID. Nonetheless, we recommend that the IDs be assigned incrementally, +starting from 1, in the same order as in the P4 key declaration.%mdk%mdk + +%mdk-data-line={1123} +\item{} +%mdk-data-line={1123} +\mdline{1123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1123}, the string representing the name of this \mdline{1123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1123}.%mdk%mdk + +%mdk-data-line={1125} +\item{} +%mdk-data-line={1125} +\mdline{1125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1125}, a repeated field of strings, each one representing a P4 +annotation associated to this match field.%mdk%mdk + +%mdk-data-line={1128} +\item{} +%mdk-data-line={1128} +\mdline{1128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1128}, an \mdline{1128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1128} value set to the size in bits of this match field.%mdk%mdk + +%mdk-data-line={1130} +\item{} +%mdk-data-line={1130} +\mdline{1130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1130}, a \mdline{1130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{1130} describing the match behavior for this field; it can be +either:%mdk + +%mdk-data-line={1132} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1132} +\item\mdline{1132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1132}, an enum field of type \mdline{1132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchType}}}\mdline{1132}, which includes all +possible PSA match kinds.%mdk + +%mdk-data-line={1134} +\item\mdline{1134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_match\_type}}}\mdline{1134}, a string field which can be used to encode any +architecture-specific match type.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1137} +\item{} +%mdk-data-line={1137} +\mdline{1137}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1137}, a \mdline{1137}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1137} message describing this match field.%mdk%mdk + +%mdk-data-line={1139} +\item{} +%mdk-data-line={1139} +\mdline{1139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1139}, which indicates whether the match field has a\mdline{1139}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1140}; this is useful for +\mdline{1141}\mdref{sec-psa-metadata-translation}{translation}\mdline{1141}.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1143} +\item{} +%mdk-data-line={1143} +\mdline{1143}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_refs}}}\mdline{1143}, a repeated \mdline{1143}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1143} field representing the set of possible +actions for this table. The \mdline{1144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1144} message is used to reference an action +specified in the same P4Info message and it includes the following fields:%mdk + +%mdk-data-line={1146} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1146} +\item\mdline{1146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1146}, the \mdline{1146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1146} identifier of the action.%mdk + +%mdk-data-line={1147} +\item\mdline{1147}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1147}, an enum value which can take one of three values: + \mdline{1148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1148}, \mdline{1148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1148} and \mdline{1148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1148}. The \mdline{1148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1148} of the + action is determined by the use of the P4 standard annotations + \mdline{1150}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1150} and \mdline{1150}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1150}~[\mdcite{p4actionannotations}{17}]\mdline{1150}. \mdline{1150}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1150} + (\mdline{1151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1151} annotation) means that the action can only appear within + the table, and never as the default action. \mdline{1152}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1152} + (\mdline{1153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1153} annotation) means that the action can only be used as the + default action. \mdline{1154}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1154} is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action.%mdk + +%mdk-data-line={1157} +\item\mdline{1157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1157}, a repeated string field, each one representing a P4 +annotation associated to the action \mdline{1158}\emph{reference}\mdline{1158} in this table.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1160} +\item{} +%mdk-data-line={1160} +\mdline{1160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\_default\_action\_id}}}\mdline{1160}, if this table has a constant default action, this +field will carry the \mdline{1161}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1161} identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action\mdline{1164}'\mdline{1164}s +arguments.%mdk%mdk + +%mdk-data-line={1167} +\item{} +%mdk-data-line={1167} +\mdline{1167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation\_id}}}\mdline{1167}, the \mdline{1167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1167} identifier of the \mdline{1167}\textquotedblleft{}implementation\textquotedblright{}\mdline{1167} of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (\mdline{1170}e.g.\mdline{1170} a PSA \mdline{1170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1170} or \mdline{1170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{1170} +instance). The table is then referred to as an indirect match table.%mdk%mdk + +%mdk-data-line={1173} +\item{} +%mdk-data-line={1173} +\mdline{1173}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_resource\_ids}}}\mdline{1173}, repeated \mdline{1173}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1173} identifiers for all the direct +resources attached to this table, such as \mdline{1174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1174} and \mdline{1174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1174} +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2.%mdk%mdk + +%mdk-data-line={1180} +\item{} +%mdk-data-line={1180} +\mdline{1180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1180}, an \mdline{1180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1180} describing the desired number of table entries that the +target should support for the table. See the \mdline{1181}\textquotedblleft{}Size\textquotedblright{}\mdline{1181} subsection within the +\mdline{1182}\textquotedblleft{}Table Properties\textquotedblright{}\mdline{1182} section of the P4\mdline{1182}\mdsub{16}\mdline{1182} language specification for details +\mdline{1183}[\mdcite{p4tableproperties}{27}]\mdline{1183}.%mdk%mdk + +%mdk-data-line={1185} +\item{} +%mdk-data-line={1185} +\mdline{1185}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_behavior}}}\mdline{1185}, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +\mdline{1187}\mdref{sec-idle-timeout}{Idle-Timeout}\mdline{1187} section). Value can be any of the +\mdline{1188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutBehavior}}}\mdline{1188} enum:%mdk + +%mdk-data-line={1189} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1189} +\item\mdline{1189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NO\_TIMEOUT}}}\mdline{1189} (default value), which means that idle timeout is not +supported for this table.%mdk + +%mdk-data-line={1191} +\item\mdline{1191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOTIFY\_CONTROL}}}\mdline{1191}, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +\mdline{1193}\mdref{sec-table-idle-timeout-notification}{Table Idle Timeout Notifications}\mdline{1193}).%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1195} +\item{} +%mdk-data-line={1195} +\mdline{1195}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{1195}, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime.%mdk%mdk + +%mdk-data-line={1198} +\item{} +%mdk-data-line={1198} +\mdline{1198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{1198}, an \mdline{1198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1198} Protobuf message\mdline{1198}~[\mdcite{protoany}{28}]\mdline{1198} to embed +architecture-specific table properties\mdline{1199}~[\mdcite{p4tableproperties}{27}]\mdline{1199} which are not part +of the core P4 language or of the PSA architecture.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1202} +\subsubsection{\mdline{1202}6.4.2.\hspace*{0.5em}\mdline{1202}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}\label{sec-action}%mdk%mdk + +%mdk-data-line={1204} +\noindent\mdline{1204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1204} messages are used to specify all possible actions of all match-action +tables.%mdk + +%mdk-data-line={1207} +\mdline{1207}The \mdline{1207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1207} message defines the following fields:%mdk + +%mdk-data-line={1209} +\begin{itemize}%mdk + +%mdk-data-line={1209} +\item{} +%mdk-data-line={1209} +\mdline{1209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1209}, a \mdline{1209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1209} message with the ID, name, and alias of this action%mdk%mdk + +%mdk-data-line={1211} +\item{} +%mdk-data-line={1211} +\mdline{1211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{1211}, a repeated field of \mdline{1211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1211} messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each \mdline{1213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1213} message contains the +following fields:%mdk + +%mdk-data-line={1215} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1215} +\item\mdline{1215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1215}, the \mdline{1215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1215} identifier of this parameter. No rules are prescribed +on the way \mdline{1216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1216} IDs should be allocated, as long as two \mdline{1216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1216} of the +same action do not have the same ID. Nonetheless, we recommend that the +IDs be assigned incrementally, starting from 1, in the same order as in +the P4 action declaration.%mdk + +%mdk-data-line={1220} +\item\mdline{1220}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1220}, the string representing the name of this parameter.%mdk + +%mdk-data-line={1221} +\item\mdline{1221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1221}, a repeated field of strings, each one representing a P4 +annotation associated to this parameter.%mdk + +%mdk-data-line={1223} +\item\mdline{1223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1223}, an \mdline{1223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1223} value set to the size in bits of this parameter.%mdk + +%mdk-data-line={1224} +\item\mdline{1224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1224}, which describes this parameter using a \mdline{1224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1224} message.%mdk + +%mdk-data-line={1225} +\item\mdline{1225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1225}, which indicates whether the action parameter has a +\mdline{1226}\mdref{sec-user-defined-types}{user-defined type}\mdline{1226}; this is useful for +\mdline{1227}\mdref{sec-psa-metadata-translation}{translation}\mdline{1227}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1229} +\subsubsection{\mdline{1229}6.4.3.\hspace*{0.5em}\mdline{1229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}\label{sec-p4info-action-profile}%mdk%mdk + +%mdk-data-line={1231} +\noindent\mdline{1231}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1231} messages are used to specify all available instances of Action +Profile and Action Selector PSA externs.%mdk + +%mdk-data-line={1234} +\mdline{1234}PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile \mdline{1238}\emph{member}\mdline{1238}, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime.%mdk + +%mdk-data-line={1242} +\mdline{1242}PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into \mdline{1243}\emph{groups}\mdline{1243}. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime.%mdk + +%mdk-data-line={1252} +\mdline{1252}While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same \mdline{1253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1253} message to describe both.%mdk + +%mdk-data-line={1255} +\mdline{1255}The \mdline{1255}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1255} message includes the following fields:%mdk + +%mdk-data-line={1257} +\begin{itemize}%mdk + +%mdk-data-line={1257} +\item{} +%mdk-data-line={1257} +\mdline{1257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1257}, a \mdline{1257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1257} message with the ID, name, and alias of this Action +Profile or Selector.%mdk%mdk + +%mdk-data-line={1260} +\item{} +%mdk-data-line={1260} +\mdline{1260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_ids}}}\mdline{1260}, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector.%mdk%mdk + +%mdk-data-line={1263} +\item{} +%mdk-data-line={1263} +\mdline{1263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}with\_selector}}}\mdline{1263}, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern.%mdk%mdk + +%mdk-data-line={1266} +\item{} +%mdk-data-line={1266} +\mdline{1266}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1266}, an \mdline{1266}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1266} representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum sum +of all member weights across all selector groups.%mdk%mdk + +%mdk-data-line={1270} +\item{} +%mdk-data-line={1270} +\mdline{1270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1270}, an \mdline{1270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1270} representing the maximum sum of all member +weights within any given selector group, in the case of an Action Selector, or +0 for an Action Profile. PSA programs can use the \mdline{1272}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{1272} annotation +to provide this value for Action Selectors. If the annotation is omitted, the +P4Info field will default to 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1276} +\subsubsection{\mdline{1276}6.4.4.\hspace*{0.5em}\mdline{1276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1276} \mdline{1276}\&\mdline{1276} \mdline{1276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}\label{sec-counter-directcounter}%mdk%mdk + +%mdk-data-line={1278} +\noindent\mdline{1278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1278} and \mdline{1278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1278} messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is:%mdk + +%mdk-data-line={1284} +\begin{itemize}%mdk + +%mdk-data-line={1284} +\item{} +%mdk-data-line={1284} +\mdline{1284}Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index.%mdk%mdk + +%mdk-data-line={1288} +\item{} +%mdk-data-line={1288} +\mdline{1288}Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1291} +\noindent\mdline{1291}Both \mdline{1291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1291} and \mdline{1291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1291} messages share the following fields:%mdk + +%mdk-data-line={1293} +\begin{itemize}%mdk + +%mdk-data-line={1293} +\item{} +%mdk-data-line={1293} +\mdline{1293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1293}, a \mdline{1293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1293} message with the ID, name, and alias of this counter +extern instance.%mdk%mdk + +%mdk-data-line={1296} +\item{} +%mdk-data-line={1296} +\mdline{1296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1296}, a message of of type \mdline{1296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1296} used to describe the compile-time +configuration of this counter. Currently, the \mdline{1297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1297} message is used to +carry only the counter unit, which can be any of the \mdline{1298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec.Unit}}}\mdline{1298} enum +values:%mdk + +%mdk-data-line={1300} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1300} +\item\mdline{1300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1300}: reserved value.%mdk + +%mdk-data-line={1301} +\item\mdline{1301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1301}: byte counter.%mdk + +%mdk-data-line={1302} +\item\mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1302}: packet counter.%mdk + +%mdk-data-line={1303} +\item\mdline{1303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BOTH}}}\mdline{1303}: combination of both byte and packet counter.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1305} +\noindent\mdline{1305}For indexed counters, the \mdline{1305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1305} message contains also a \mdline{1305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1305} field, an +\mdline{1306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1306} representing the maximum number of independent values that can be held +by this counter array. Conversely, the \mdline{1307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1307} message contains a +\mdline{1308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1308} field that carries the \mdline{1308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}unit32}}}\mdline{1308} identifier of the table to +which this direct counter is attached.%mdk + +%mdk-data-line={1311} +\mdline{1311}For indexed counters, the \mdline{1311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1311} message contains also an \mdline{1311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1311} +field, which indicates whether the index has a\mdline{1312}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1313}. This is useful for +\mdline{1314}\mdref{sec-psa-metadata-translation}{translation}\mdline{1314}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1315}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1315}).%mdk + +%mdk-data-line={1317} +\subsubsection{\mdline{1317}6.4.5.\hspace*{0.5em}\mdline{1317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1317} \mdline{1317}\&\mdline{1317} \mdline{1317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}\label{sec-meter-directmeter}%mdk%mdk + +%mdk-data-line={1319} +\noindent\mdline{1319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1319} and \mdline{1319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1319} messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is:%mdk + +%mdk-data-line={1325} +\begin{itemize}%mdk + +%mdk-data-line={1325} +\item{} +%mdk-data-line={1325} +\mdline{1325}Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +\mdline{1327}e.g.\mdline{1327} to set the rate threshold.%mdk%mdk + +%mdk-data-line={1329} +\item{} +%mdk-data-line={1329} +\mdline{1329}Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1332} +\noindent\mdline{1332}Both \mdline{1332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1332} and \mdline{1332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1332} messages share the following fields:%mdk + +%mdk-data-line={1334} +\begin{itemize}%mdk + +%mdk-data-line={1334} +\item{} +%mdk-data-line={1334} +\mdline{1334}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1334}, a \mdline{1334}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1334} message with the ID, name, and alias of this meter +extern instance.%mdk%mdk + +%mdk-data-line={1337} +\item{} +%mdk-data-line={1337} +\mdline{1337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1337}, a message of type \mdline{1337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1337} used to describe the capabilities of +this meter extern instance. Currently, the \mdline{1338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1338} message is used to +carry only the meter unit, which can be any of the \mdline{1339}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Unit}}}\mdline{1339} enum +values:%mdk + +%mdk-data-line={1341} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1341} +\item\mdline{1341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1341}: reserved value.%mdk + +%mdk-data-line={1342} +\item\mdline{1342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1342}, which signifies that this meter can be configured with rates +expressed in bytes/second.%mdk + +%mdk-data-line={1344} +\item\mdline{1344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1344}, for rates expressed in packets/second.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1346} +\noindent\mdline{1346}For indexed meters, the \mdline{1346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1346} message contains also a \mdline{1346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1346} field, an \mdline{1346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1346} +representing the maximum number of independent cells that can be held by this +meter. Conversely, the \mdline{1348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1348} message contains a \mdline{1348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1348} field +that carries the \mdline{1349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1349} identifier of the table to which this direct meter is +attached.%mdk + +%mdk-data-line={1352} +\mdline{1352}For indexed meters, the \mdline{1352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1352} message contains also an \mdline{1352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1352} +field, which indicates whether the index has a\mdline{1353}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1354}. This is useful for +\mdline{1355}\mdref{sec-psa-metadata-translation}{translation}\mdline{1355}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1356}).%mdk + +%mdk-data-line={1358} +\subsubsection{\mdline{1358}6.4.6.\hspace*{0.5em}\mdline{1358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\label{sec-controller-packet-meta}%mdk%mdk + +%mdk-data-line={1360} +\noindent\mdline{1360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1360} messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server.%mdk + +%mdk-data-line={1366} +\mdline{1366}When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet.%mdk + +%mdk-data-line={1372} +\mdline{1372}Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +\mdline{1374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_in")}}}\mdline{1374} and \mdline{1374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_out")}}}\mdline{1374}, +respectively. \mdline{1375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1375} messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages).%mdk + +%mdk-data-line={1380} +\mdline{1380}A P4Info message can contain at most two \mdline{1380}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata~messages}}}\mdline{1380}, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields:%mdk + +%mdk-data-line={1384} +\begin{itemize}%mdk + +%mdk-data-line={1384} +\item{} +%mdk-data-line={1384} +\mdline{1384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1384}, a \mdline{1384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1384} message where \mdline{1384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble.name}}}\mdline{1384} is set to \mdline{1384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_in"}}}\mdline{1384} +and \mdline{1385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_out"}}}\mdline{1385} for packet-in and packet-out metadata, respectively.%mdk%mdk + +%mdk-data-line={1387} +\item{} +%mdk-data-line={1387} +\mdline{1387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{1387}, a repeated field of type \mdline{1387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1387}, where each \mdline{1387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1387} message +includes the following fields:%mdk + +%mdk-data-line={1389} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1389} +\item\mdline{1389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1389}, a \mdline{1389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1389} identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two \mdline{1390}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1390} of the +same \mdline{1391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1391} message do not have the same +ID. Nonetheless, if the P4Info message was generated from a P4 compiler, +we recommend that the IDs be assigned incrementally, starting from 1, in +the same order as the fields in the P4 header declaration.%mdk + +%mdk-data-line={1395} +\item\mdline{1395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1395}, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below).%mdk + +%mdk-data-line={1399} +\item\mdline{1399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1399}, a repeated field of strings, each one representing a P4 +annotation associated to this metadata.%mdk + +%mdk-data-line={1401} +\item\mdline{1401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1401}, an \mdline{1401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1401} representing the size in bit of this metadata.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1403} +\noindent\mdline{1403}As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding \mdline{1404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1404} +messages.%mdk + +%mdk-data-line={1407} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1408} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~egress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~port~where~the~packet}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~should~be~sent~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~queue\_id;~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~queue~ID~}{\mdcolor{darkgreen}*/}\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~ingress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~data~plane~port~ID~where}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~the~original~packet~was~received~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}1}\textgreater{}~is\_clone;~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~1~if~this~is~a~clone~of~the}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~original~packet~}{\mdcolor{darkgreen}*/}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1423} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1424} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868916615}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_out}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_out}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}egress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}queue\_id}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~\}\\ +\}\\ +\\ +controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868941301}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_in}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_in}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ingress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}is\_clone}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}1}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1461} +\noindent\mdline{1461}Note that the use of \mdline{1461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1461} is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages.%mdk + +%mdk-data-line={1467} +\subsubsection{\mdline{1467}6.4.7.\hspace*{0.5em}\mdline{1467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}\label{sec-valueset}%mdk%mdk + +%mdk-data-line={1469} +\noindent\mdline{1469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1469} messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P4\mdline{1472}\mdsub{16}\mdline{1472} +specification\mdline{1473}~[\mdcite{p4valuesets}{35}]\mdline{1473}.%mdk + +%mdk-data-line={1475} +\mdline{1475}The \mdline{1475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1475} message defines the following fields:%mdk + +%mdk-data-line={1477} +\begin{itemize}%mdk + +%mdk-data-line={1477} +\item{} +%mdk-data-line={1477} +\mdline{1477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1477}, a \mdline{1477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1477} message with the ID, name, and alias of this Value +Set.%mdk%mdk + +%mdk-data-line={1480} +\item{} +%mdk-data-line={1480} +\mdline{1480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1480}, a repeated field of \mdline{1480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1480} messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the \mdline{1483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1483} repeated field in the +\mdline{1484}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{1484} message.%mdk%mdk + +%mdk-data-line={1486} +\item{} +%mdk-data-line={1486} +\mdline{1486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1486}, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +\mdline{1488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set}}}\mdline{1488} constructor call.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1490} +\noindent\mdline{1490}According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of \mdline{1493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1493}, +\mdline{1494}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1494}, or \mdline{1494}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1494}~[\mdcite{p4selectexpr}{24}]\mdline{1494}. The rest of this section looks at all 3 of +these cases and gives an example \mdline{1495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1495} message when appropriate.%mdk + +%mdk-data-line={1497} +\begin{enumerate}%mdk + +%mdk-data-line={1497} +\item{} +%mdk-data-line={1497} +\mdline{1497}If the type parameter is \mdline{1497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1497}, \mdline{1497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1497} will include exactly one +\mdline{1498}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1498} message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used):%mdk + +%mdk-data-line={1501} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1501} +\item\mdline{1501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1501}: set to 1%mdk + +%mdk-data-line={1502} +\item\mdline{1502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1502}: set to the value of \mdline{1502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1502}%mdk + +%mdk-data-line={1503} +\item\mdline{1503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1503}: set to \mdline{1503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1503}%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1505} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1506} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}bit\textless{}8\textgreater{}~\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(hdr.f8)~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1509} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1510} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1524} +\begin{enumerate}[,start=2]%mdk + +%mdk-data-line={1524} +\item{} +%mdk-data-line={1524} +\mdline{1524}If the type parameter is a \mdline{1524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1524}, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program.%mdk%mdk + +%mdk-data-line={1529} +\item{} +%mdk-data-line={1529} +\mdline{1529}If the type parameter is a \mdline{1529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1529}, this version of P4Runtime requires that +all the fields of the struct be of type \mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1530} (where \mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1530} can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +\mdline{1533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1533} field will include one \mdline{1533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1533} message for each field in the +struct, with the following fields:%mdk + +%mdk-data-line={1536} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1536} +\item\mdline{1536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1536}: must be unique with respect to the other \mdline{1536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1536} entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration.%mdk + +%mdk-data-line={1540} +\item\mdline{1540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1540}: set to the name of the corresponding struct field.%mdk + +%mdk-data-line={1541} +\item\mdline{1541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1541}: set to the list of P4 annotations associated with the struct +field, except for the \mdline{1542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1542} annotation, if present (see the \mdline{1542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1542} field +below).%mdk + +%mdk-data-line={1544} +\item\mdline{1544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1544}: set to the value of \mdline{1544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1544} for the corresponding struct field.%mdk + +%mdk-data-line={1545} +\item\mdline{1545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1545}: by default \mdline{1545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1545} is set to \mdline{1545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1545}; the P4 programmer can +specify a different match type by using the \mdline{1546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1546} annotation +\mdline{1547}[\mdcite{p4selectexpr}{24}]\mdline{1547}.%mdk + +%mdk-data-line={1548} +\item\mdline{1548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1548}: documentation associated with the struct field.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1550} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1551} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1559} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1560} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1587} +\noindent\mdline{1587}Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a\mdline{1588}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1589} that resolves to a \mdline{1589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1589}, or a \mdline{1589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1589} where +one or more fields is a\mdline{1590}~\mdref{sec-user-defined-types}{user-defined type}\mdline{1590} that +resolves to a \mdline{1591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1591}. For each \mdline{1591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1591} that corresponds to a user-defined +type, the \mdline{1592}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1592} field must be set to the appropriate value (\mdline{1592}i.e.\mdline{1592} the name +of the type).%mdk + +%mdk-data-line={1595} +\subsubsection{\mdline{1595}6.4.8.\hspace*{0.5em}\mdline{1595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}\label{sec-register}%mdk%mdk + +%mdk-data-line={1597} +\noindent\mdline{1597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1597} messages are used to specify all possible instances of Register PSA +externs.%mdk + +%mdk-data-line={1600} +\mdline{1600}Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime.%mdk + +%mdk-data-line={1604} +\mdline{1604}The \mdline{1604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1604} message defines the following fields:%mdk + +%mdk-data-line={1606} +\begin{itemize}%mdk + +%mdk-data-line={1606} +\item{} +%mdk-data-line={1606} +\mdline{1606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1606}, a \mdline{1606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1606} message with the ID, name, and alias of this register +instance.%mdk%mdk + +%mdk-data-line={1609} +\item{} +%mdk-data-line={1609} +\mdline{1609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1609}, which specifies the data type stored by this register, expressed +using a \mdline{1610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1610} message (see section on\mdline{1610}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary +P4 Types}\mdline{1611}).%mdk%mdk + +%mdk-data-line={1613} +\item{} +%mdk-data-line={1613} +\mdline{1613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1613}, an \mdline{1613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1613} value representing the total number of independent register +cells available.%mdk%mdk + +%mdk-data-line={1616} +\item{} +%mdk-data-line={1616} +\mdline{1616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1616}, which indicates whether the register index has a +\mdline{1617}\mdref{sec-user-defined-types}{user-defined type}\mdline{1617}. This is useful for +\mdline{1618}\mdref{sec-psa-metadata-translation}{translation}\mdline{1618}. The underlying built-in type +must be a fixed-width unsigned bitstring (\mdline{1619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1619}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1621} +\subsubsection{\mdline{1621}6.4.9.\hspace*{0.5em}\mdline{1621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}\label{sec-digest}%mdk%mdk + +%mdk-data-line={1623} +\noindent\mdline{1623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1623} messages are used to specify all possible instances of Packet Digest +PSA externs.%mdk + +%mdk-data-line={1626} +\mdline{1626}A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages.%mdk + +%mdk-data-line={1635} +\mdline{1635}The \mdline{1635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1635} message defines the following fields:%mdk + +%mdk-data-line={1637} +\begin{itemize}%mdk + +%mdk-data-line={1637} +\item{} +%mdk-data-line={1637} +\mdline{1637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1637}, a \mdline{1637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1637} message with the ID, name, and alias of this digest +instance.%mdk%mdk + +%mdk-data-line={1640} +\item{} +%mdk-data-line={1640} +\mdline{1640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1640}, which specifies the data type of an individual digest +notification using a \mdline{1641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1641} message (see section on\mdline{1641}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation +of Arbitrary P4 Types}\mdline{1642}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1644} +\subsubsection{\mdline{1644}6.4.10.\hspace*{0.5em}\mdline{1644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}\label{sec-p4info-extern}%mdk%mdk + +%mdk-data-line={1646} +\noindent\mdline{1646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1646} messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one \mdline{1649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1649} message instance in P4Info. The \mdline{1649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1649} message defines +the following fields:%mdk + +%mdk-data-line={1652} +\begin{itemize}%mdk + +%mdk-data-line={1652} +\item{} +%mdk-data-line={1652} +\mdline{1652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{1652}, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the\mdline{1653}~\mdref{sec-id-allocation}{reserved +range}\mdline{1654} \mdline{1654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{}[0x81,~0xfe]}}}\mdline{1654}. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture.%mdk%mdk + +%mdk-data-line={1659} +\item{} +%mdk-data-line={1659} +\mdline{1659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_name}}}\mdline{1659}, which specifies the fully-qualified P4 name of the extern +type.%mdk%mdk + +%mdk-data-line={1662} +\item{} +%mdk-data-line={1662} +\mdline{1662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instances}}}\mdline{1662}, a repeated field of \mdline{1662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{1662} Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +\mdline{1664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{1664} in turn defines the following fields:%mdk + +%mdk-data-line={1666} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1666} +\item\mdline{1666}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1666}, a \mdline{1666}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1666} message with the ID, name, and alias of this digest +instance.%mdk + +%mdk-data-line={1668} +\item\mdline{1668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{1668}, an \mdline{1668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1668} Protobuf message\mdline{1668}~[\mdcite{protoany}{28}]\mdline{1668} which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for \mdline{1670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{1670} should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on\mdline{1672}~\mdref{sec-extending-p4runtime}{Extending +P4Runtime for non-PSA Architectures}\mdline{1673} for more +information.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1676} +\noindent\mdline{1676}If the P4 program does not include any instance of a given extern type, the +\mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1677} message instance for that type should be omitted from the P4Info.%mdk + +%mdk-data-line={1679} +\subsection{\mdline{1679}6.5.\hspace*{0.5em}\mdline{1679}Support for Arbitrary P4 Types with P4TypeInfo}\label{sec-support-for-arbitrary-p4-types-with-p4typeinfo}%mdk%mdk + +%mdk-data-line={1681} +\noindent\mdline{1681}See section on\mdline{1681}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary P4 +Types}\mdline{1682}.%mdk + +%mdk-data-line={1684} +\section{\mdline{1684}7.\hspace*{0.5em}\mdline{1684}P4 Forwarding-Pipeline Configuration}\label{sec-p4-fwd-pipe-config}%mdk%mdk + +%mdk-data-line={1686} +\noindent\mdline{1686}The \mdline{1686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{1686} captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the \mdline{1688}\textquotedblleft{}Device Configuration\textquotedblright{}\mdline{1688} and sometimes also referred to as +the \mdline{1689}\textquotedblleft{}P4 Blob\textquotedblright{}\mdline{1689}. It is defined as:%mdk + +%mdk-data-line={1691} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1692} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ForwardingPipelineConfig~\{\\ +~~config.P{\mdcolor{purple}4}Info~p4info~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~p4\_device\_config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}message}}~Cookie~\{\\ +~~~~{\bfseries{\mdcolor{navy}uint64}}~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~\}\\ +~~Cookie~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1702} +\noindent\mdline{1702}The \mdline{1702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{1702} field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic.%mdk + +%mdk-data-line={1705} +\mdline{1705}The \mdline{1705}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{1705} is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new \mdline{1707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{1707} on that target.%mdk + +%mdk-data-line={1709} +\mdline{1709}The \mdline{1709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{1709} field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a \mdline{1714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{1714} RPC. +When writing the config via a \mdline{1715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{1715} RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present.%mdk + +%mdk-data-line={1719} +\section{\mdline{1719}8.\hspace*{0.5em}\mdline{1719}General Principles for Message Formatting}\label{sec-general-principles-for-message-formatting}%mdk%mdk + +%mdk-data-line={1721} +\subsection{\mdline{1721}8.1.\hspace*{0.5em}\mdline{1721}Set / Unset Protobuf Field}\label{sec-set-unset-protobuf-field}%mdk%mdk + +%mdk-data-line={1723} +\noindent\mdline{1723}In Protobuf version 3 (\mdline{1723}\emph{proto3}\mdline{1723}), the default value for a message field is +\mdline{1724}\textquotedblleft{}unset\textquotedblright{}\mdline{1724}~[\mdcite{protodefaults}{4}]\mdline{1724}. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +\mdline{1729}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{1729} message, an \mdline{1729}\textquotedblleft{}unset\textquotedblright{}\mdline{1729} \mdline{1729}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1729} field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the \mdline{1731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1731} message field is +set, a single entry will be read.%mdk + +%mdk-data-line={1734} +\mdline{1734}Let\mdline{1734}'\mdline{1734}s look at the counter example in more details. Based on this specification +document, the C++ server code which processes \mdline{1735}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{1735} messages may look +like this:%mdk + +%mdk-data-line={1737} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1738} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}auto}}~*counter\_entry~=~...\\ +{\bfseries{\mdcolor{navy}if}}~(counter\_entry-\textgreater{}has\_index())~\{\\ +~~{\bfseries{\mdcolor{navy}auto}}~index~=~counter\_entry-\textgreater{}index().index();\\ +~~read\_one\_entry(counter\_entry-\textgreater{}id(),~index);\\ +\}~{\bfseries{\mdcolor{navy}else}}~\{\\ +~~read\_all\_entries(counter\_entry-\textgreater{}id());\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1747} +\begin{enumerate}%mdk + +%mdk-data-line={1747} +\item{} +%mdk-data-line={1747} +\mdline{1747}Reading a single counter entry at index 0 in the counter array with id +\mdline{1748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textless{}id\textgreater{}}}}\mdline{1748}:%mdk + +%mdk-data-line={1749} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1749} +\item\mdline{1749}Here is the C++ client code: + +%mdk-data-line={1750} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1751} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});\\ +entry.mutable\_index();\\ +{\mdcolor{darkgreen}//~The~above~line~sets~the~index~field;~it~is~equivalent~to:}\\ +{\mdcolor{darkgreen}//~auto~*index~=~entry.mutable\_index();}\\ +{\mdcolor{darkgreen}//~index-\textgreater{}set\_index(0);}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={1758} +\item\mdline{1758}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={1759} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1760} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}\\ +index~\{\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={1763} +\item\mdline{1763}\textbf{Expected behavior}\mdline{1763}: Counter entry at index 0 is read. Notice that the +\mdline{1764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1764} subfield is missing under the \mdline{1764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1764} field message of +\mdline{1765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{1765} in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1770} +\item{} +%mdk-data-line={1770} +\mdline{1770}Reading all counter entries by leaving the \mdline{1770}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1770} field unset%mdk + +%mdk-data-line={1771} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1771} +\item\mdline{1771}Here is the C++ client code: + +%mdk-data-line={1772} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1773} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={1776} +\item\mdline{1776}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={1777} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1778} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={1780} +\item\mdline{1780}\textbf{Expected behavior}\mdline{1780}: All counter entries for the provided counter +instance are read. Notice that the \mdline{1781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1781} message field is unset (default +value) and is therefore omitted from the textual representation of the +message.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1785} +\subsection{\mdline{1785}8.2.\hspace*{0.5em}\mdline{1785}Read-Write Symmetry}\label{sec-read-write-symmetry}%mdk%mdk + +%mdk-data-line={1787} +\noindent\mdline{1787}The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example:%mdk + +%mdk-data-line={1793} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1794} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}intended\_value~=~value\\ +\\ +status~=~server.write(intended\_value,~p4\_entity)\\ +observed\_value~=~server.read(p4\_entity)\\ +\\ +assert(intended\_value~==~observed\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1802} +\noindent\mdline{1802}To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If \mdline{1806}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{1806} RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol\mdline{1809}'\mdline{1809}s complexities to the client implementations.%mdk + +%mdk-data-line={1811} +\mdline{1811}In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the \mdline{1814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1814} fields in a \mdline{1814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{1814} message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +\mdline{1817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MessageDifferencer}}}\mdline{1817} class\mdline{1817}~[\mdcite{protomessagedifferencer}{33}]\mdline{1817} included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance.%mdk + +%mdk-data-line={1822} +\subsection{\mdline{1822}8.3.\hspace*{0.5em}\mdline{1822}Zero as Reserved Value}\label{sec-zero-as-reserved-value}%mdk%mdk + +%mdk-data-line={1824} +\noindent\mdline{1824}p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a \mdline{1825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1825}. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a \mdline{1828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{1828} or a \mdline{1828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfigRequest}}}\mdline{1828}.%mdk + +%mdk-data-line={1830} +\subsection{\mdline{1830}8.4.\hspace*{0.5em}\mdline{1830}Bytestrings}\label{sec-bytestrings}%mdk%mdk + +%mdk-data-line={1832} +\noindent\mdline{1832}P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (\mdline{1834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1834}) or signed (\mdline{1834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1834}), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +\mdline{1837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{1837} Protobuf type. The correct bitwidth\mdline{1837} \mdline{1837}\textemdash{}\mdline{1837} as per the P4 program\mdline{1837} \mdline{1837}\textemdash{}\mdline{1837} of +each integer variable exposed through P4Runtime is specified in the P4Info +message.%mdk + +%mdk-data-line={1841} +\mdline{1841}The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals:%mdk + +%mdk-data-line={1844} +\begin{itemize}%mdk + +%mdk-data-line={1844} +\item{} +%mdk-data-line={1844} +\mdline{1844}It ensures that a properly encoded binary string\mdline{1844}'\mdline{1844}s integer value conforms +to the P4Info-specified bitwidth.%mdk%mdk + +%mdk-data-line={1847} +\item{} +%mdk-data-line={1847} +\mdline{1847}It supports\mdline{1847}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{1847}.%mdk%mdk + +%mdk-data-line={1849} +\item{} +%mdk-data-line={1849} +\mdline{1849}It helps facilitate non-disruptive P4 program updates.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1851} +\noindent\mdline{1851}In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type \mdline{1856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1856} and/or \mdline{1856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1856}.%mdk + +%mdk-data-line={1858} +\mdline{1858}Note that this representation does \mdline{1858}\emph{not}\mdline{1858} make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range.%mdk + +%mdk-data-line={1867} +\mdline{1867}In the P4Runtime API version 1.0, values of table key fields, action parameters, +and fields in packet-in and packet-out headers between a device and the +controller (see\mdline{1869}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{1869}), may not be of type \mdline{1869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1869}. +The rules for encoding signed values thus only apply to messages of type +\mdline{1871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{1871} (see\mdline{1871}~\mdref{sec-p4data-in-p4runtime-proto}{8.5.3}\mdline{1871}).%mdk + +%mdk-data-line={1873} +\mdline{1873}For a value of type \mdline{1873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1873}, the fewest number of bits required to represent +the integer value \mdline{1874}$V > 0$\mdline{1874} is the smallest integer \mdline{1874}$A$\mdline{1874} such that \mdline{1874}$V \leq 2^A -1$\mdline{1875}.%mdk + +%mdk-data-line={1877} +\mdline{1877}For a value of type \mdline{1877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1877}, the fewest number of bits required to represent +the integer value \mdline{1878}$V \neq 0$\mdline{1878} in 2\mdline{1878}'\mdline{1878}s complement form is the smallest integer \mdline{1878}$A$\mdline{1878} +such that \mdline{1879}$-2^{A-1} \leq V \leq 2^{A-1} - 1$\mdline{1879}.%mdk + +%mdk-data-line={1881} +\mdline{1881}As a special case, define that the value \mdline{1881}$V=0$\mdline{1881} requires at least \mdline{1881}$A=1$\mdline{1881} bit to +represent, regardless of whether it is signed or unsigned.%mdk + +%mdk-data-line={1884} +\mdline{1884}The shortest possible binary string for an integer \mdline{1884}$V$\mdline{1884} that needs \mdline{1884}$A$\mdline{1884} bits to +represent it is computed as:%mdk + +%mdk-data-line={1886} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1887} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size~=~floor(({\mdcolor{teal}A}~+~{\mdcolor{purple}7})~/~{\mdcolor{purple}8})}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1890} +\noindent\mdline{1890}Binary strings with the byte length computed as \mdline{1890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{1890} promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies.%mdk + +%mdk-data-line={1894} +\mdline{1894}Any additional bits in the bytes sent for an unsigned integer value (type +\mdline{1895}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1895}) must be 0. If additional bytes are transmitted above the +\mdline{1896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{1896} minimum required, they must be filled with 0.%mdk + +%mdk-data-line={1898} +\mdline{1898}Any additional bits in the bytes sent for a signed integer value (type \mdline{1898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1898}) +must be copies of the sign bit, i.e. 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +\mdline{1901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{1901} minimum required, they must be filled with copies of the +sign bit, i.e. 0 for non-negative values, or 0xff for negative values. In 2\mdline{1902}'\mdline{1902}s +complement representation, this is called \mdline{1903}\textquotedblleft{}sign extension\textquotedblright{}\mdline{1903}, and leaves the +numeric value represented unchanged.%mdk + +%mdk-data-line={1906} +\mdline{1906}Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value.%mdk + +%mdk-data-line={1912} +\mdline{1912}For a received bitstring expected to fit within a \mdline{1912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1912} type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring\mdline{1914}'\mdline{1914}s width is \mdline{1914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1914} bits or less.%mdk + +%mdk-data-line={1916} +\mdline{1916}For a received bitstring expected to fit within an \mdline{1916}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1916} type, the value it +represents is in range if, after \mdline{1917}\textquotedblleft{}undoing sign extension\textquotedblright{}\mdline{1917}, the remaining bit +string\mdline{1918}'\mdline{1918}s width is \mdline{1918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1918} bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other.%mdk + +%mdk-data-line={1924} +\mdline{1924}If the string\mdline{1924}'\mdline{1924}s byte length is zero, the server always rejects the string.%mdk + +%mdk-data-line={1926} +\mdline{1926}When the server rejects a binary string due to any of the previous criteria, +it returns an \mdline{1927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{1927} error.%mdk + +%mdk-data-line={1929} +\mdline{1929}For all binary strings, P4Runtime uses big-endian (\mdline{1929}i.e.\mdline{1929} network) byte-order. +For signed integer values (\mdline{1930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1930} P4 type), P4Runtime uses the same two\mdline{1930}'\mdline{1930}s +complement bitwise representation as P4. Table\mdline{1931}~\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}}\mdline{1931} +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above.%mdk + +%mdk-data-line={1935} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1937} P4 type}}&\multicolumn{1}{|c}{{\bfseries\mdline{1937} Integer value}}&\multicolumn{1}{|c}{{\bfseries\mdline{1937} P4Runtime binary string}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1937} Read-write symmetry}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{1939} \mdline{1939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{1939}}&\multicolumn{1}{|l}{\mdline{1939} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{1939} \mdline{1939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{1939}}&\multicolumn{1}{|l|}{\mdline{1939} yes}\\ +\multicolumn{1}{|l}{\mdline{1940} \mdline{1940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{1940}}&\multicolumn{1}{|l}{\mdline{1940} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{1940} \mdline{1940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{1940}}&\multicolumn{1}{|l|}{\mdline{1940} no}\\ +\multicolumn{1}{|l}{\mdline{1941} \mdline{1941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{1941}}&\multicolumn{1}{|l}{\mdline{1941} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{1941} \mdline{1941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{1941}}&\multicolumn{1}{|l|}{\mdline{1941} yes}\\ +\multicolumn{1}{|l}{\mdline{1942} \mdline{1942}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{1942}}&\multicolumn{1}{|l}{\mdline{1942} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{1942} \mdline{1942}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x30\textbackslash{}x64}}}\mdline{1942}}&\multicolumn{1}{|l|}{\mdline{1942} yes}\\ +\multicolumn{1}{|l}{\mdline{1943} \mdline{1943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{1943}}&\multicolumn{1}{|l}{\mdline{1943} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{1943} \mdline{1943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x30\textbackslash{}x64}}}\mdline{1943}}&\multicolumn{1}{|l|}{\mdline{1943} no}\\ +\multicolumn{1}{|l}{\mdline{1944} \mdline{1944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{1944}}&\multicolumn{1}{|l}{\mdline{1944} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{1944} \mdline{1944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{1944}}&\multicolumn{1}{|l|}{\mdline{1944} no}\\ +\multicolumn{1}{|l}{\mdline{1945} \mdline{1945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{1945}}&\multicolumn{1}{|l}{\mdline{1945} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{1945} \mdline{1945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{1945}}&\multicolumn{1}{|l|}{\mdline{1945} yes}\\ +\multicolumn{1}{|l}{\mdline{1946} \mdline{1946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{1946}}&\multicolumn{1}{|l}{\mdline{1946} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{1946} \mdline{1946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00\textbackslash{}x63}}}\mdline{1946}}&\multicolumn{1}{|l|}{\mdline{1946} no}\\ +\multicolumn{1}{|l}{\mdline{1947} \mdline{1947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{1947}}&\multicolumn{1}{|l}{\mdline{1947} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{1947} \mdline{1947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{1947}}&\multicolumn{1}{|l|}{\mdline{1947} yes}\\ +\multicolumn{1}{|l}{\mdline{1948} \mdline{1948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{1948}}&\multicolumn{1}{|l}{\mdline{1948} \mdline{1948}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{1948} \mdline{1948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x9d}}}\mdline{1948}}&\multicolumn{1}{|l|}{\mdline{1948} yes}\\ +\multicolumn{1}{|l}{\mdline{1949} \mdline{1949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{1949}}&\multicolumn{1}{|l}{\mdline{1949} \mdline{1949}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{1949} \mdline{1949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xff\textbackslash{}x9d}}}\mdline{1949}}&\multicolumn{1}{|l|}{\mdline{1949} no}\\ +\multicolumn{1}{|l}{\mdline{1950} \mdline{1950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{1950}}&\multicolumn{1}{|l}{\mdline{1950} \mdline{1950}-739 (-0x2e3)}&\multicolumn{1}{|l}{\mdline{1950} \mdline{1950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xfd\textbackslash{}x1d}}}\mdline{1950}}&\multicolumn{1}{|l|}{\mdline{1950} yes}\\ +\multicolumn{1}{|l}{\mdline{1951} \mdline{1951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{1951}}&\multicolumn{1}{|l}{\mdline{1951} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{1951} \mdline{1951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00}}}\mdline{1951}}&\multicolumn{1}{|l|}{\mdline{1951} no}\\ +\multicolumn{1}{|l}{\mdline{1952} \mdline{1952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{1952}}&\multicolumn{1}{|l}{\mdline{1952} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{1952} \mdline{1952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00}}}\mdline{1952}}&\multicolumn{1}{|l|}{\mdline{1952} yes}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1954} +\mdhr{}%mdk + +%mdk-data-line={1955} +\noindent\mdline{1955}\mdcaption{\textbf{Table~\mdcaptionlabel{4}.}~\mdcaptiontext{Examples of Valid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-valid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1957} +\mdline{1957}Table\mdline{1957}~\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}}\mdline{1957} shows some examples of invalid +P4Runtime binary strings:%mdk + +%mdk-data-line={1960} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1962} P4 type}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1962} P4Runtime binary string}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{1964} \mdline{1964}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{1964}}&\multicolumn{1}{|l|}{\mdline{1964} \mdline{1964}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x63}}}\mdline{1964}}\\ +\multicolumn{1}{|l}{\mdline{1965} \mdline{1965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{1965}}&\multicolumn{1}{|l|}{\mdline{1965} \mdline{1965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{1965}}\\ +\multicolumn{1}{|l}{\mdline{1966} \mdline{1966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{1966}}&\multicolumn{1}{|l|}{\mdline{1966} \mdline{1966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{1966}}\\ +\multicolumn{1}{|l}{\mdline{1967} \mdline{1967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{1967}}&\multicolumn{1}{|l|}{\mdline{1967} \mdline{1967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x10\textbackslash{}x63}}}\mdline{1967}}\\ +\multicolumn{1}{|l}{\mdline{1968} \mdline{1968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{1968}}&\multicolumn{1}{|l|}{\mdline{1968} \mdline{1968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{1968}}\\ +\multicolumn{1}{|l}{\mdline{1969} \mdline{1969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{1969}}&\multicolumn{1}{|l|}{\mdline{1969} \mdline{1969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x40\textbackslash{}x63}}}\mdline{1969}}\\ +\multicolumn{1}{|l}{\mdline{1970} \mdline{1970}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{1970}}&\multicolumn{1}{|l|}{\mdline{1970} \mdline{1970}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x9d}}}\mdline{1970}}\\ +\multicolumn{1}{|l}{\mdline{1971} \mdline{1971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{1971}}&\multicolumn{1}{|l|}{\mdline{1971} \mdline{1971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x8d\textbackslash{}x1d}}}\mdline{1971}}\\ +\multicolumn{1}{|l}{\mdline{1972} \mdline{1972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{1972}}&\multicolumn{1}{|l|}{\mdline{1972} \mdline{1972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{1972}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1974} +\mdhr{}%mdk + +%mdk-data-line={1975} +\noindent\mdline{1975}\mdcaption{\textbf{Table~\mdcaptionlabel{5}.}~\mdcaptiontext{Examples of Invalid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-invalid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1977} +\mdline{1977}As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from \mdline{1982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{1982} to \mdline{1982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{1982}, a server +running the \mdline{1983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{1983} version of the P4 program will accept requests from +clients that remain on the \mdline{1984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{1984} P4Runtime version.%mdk + +%mdk-data-line={1986} +\mdline{1986}Despite the server\mdline{1986}'\mdline{1986}s binary string flexibility for P4 program update support, +the client and server must both remain aware of the +\mdline{1988}\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{1988} +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values.%mdk + +%mdk-data-line={1993} +\mdline{1993}Representation of variable-length integer values (\mdline{1993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{1993} P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary string, +whose length is the \mdline{1995}\emph{dynamic-length}\mdline{1995} of the expression. When the value is +provided by the P4Runtime client, the server must verify that the length of the +binary string is less than the maximum length specified in the P4 program, and +return an \mdline{1998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{1998} error code otherwise.%mdk + +%mdk-data-line={2000} +\subsection{\mdline{2000}8.5.\hspace*{0.5em}\mdline{2000}Representation of Arbitrary P4 Types}\label{sec-representation-of-arbitrary-p4-types}%mdk%mdk + +%mdk-data-line={2002} +\subsubsection{\mdline{2002}8.5.1.\hspace*{0.5em}\mdline{2002}Problem Statement}\label{sec-problem-statement}%mdk%mdk + +%mdk-data-line={2004} +\noindent\mdline{2004}The P4\mdline{2004}\mdsub{16}\mdline{2004} language includes more complex types than just binary strings +\mdline{2005}[\mdcite{p4complextypes}{3}]\mdline{2005}. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table\mdline{2008}~\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}}\mdline{2008} shows the different +P4\mdline{2009}\mdsub{16}\mdline{2009} types and how they are allowed to be used, as per the P4\mdline{2009}\mdsub{16}\mdline{2009} +specification.%mdk + +%mdk-data-line={2012} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|l}{{\bfseries\mdline{2014}}}&\multicolumn{3}{|c|}{{\bfseries\mdline{2014} Container type}}\\ +\cmidrule{2-2}\cmidrule{3-3}\cmidrule{4-4} +\multicolumn{1}{|l}{{\bfseries\mdline{2016} Element type}}&\multicolumn{1}{|l}{{\bfseries\mdline{2016} header}}&\multicolumn{1}{|l}{{\bfseries\mdline{2016} header\mdline{2016}\_\mdline{2016}union}}&\multicolumn{1}{|l|}{{\bfseries\mdline{2016} struct or tuple}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2018} \mdline{2018}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2018}}&\multicolumn{1}{|l}{\mdline{2018} allowed}&\multicolumn{1}{|l}{\mdline{2018} error}&\multicolumn{1}{|l|}{\mdline{2018} allowed}\\ +\multicolumn{1}{|l}{\mdline{2019} \mdline{2019}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2019}}&\multicolumn{1}{|l}{\mdline{2019} allowed}&\multicolumn{1}{|l}{\mdline{2019} error}&\multicolumn{1}{|l|}{\mdline{2019} allowed}\\ +\multicolumn{1}{|l}{\mdline{2020} \mdline{2020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2020}}&\multicolumn{1}{|l}{\mdline{2020} allowed}&\multicolumn{1}{|l}{\mdline{2020} error}&\multicolumn{1}{|l|}{\mdline{2020} allowed}\\ +\multicolumn{1}{|l}{\mdline{2021} \mdline{2021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int}}}\mdline{2021}}&\multicolumn{1}{|l}{\mdline{2021} error}&\multicolumn{1}{|l}{\mdline{2021} error}&\multicolumn{1}{|l|}{\mdline{2021} error}\\ +\multicolumn{1}{|l}{\mdline{2022} \mdline{2022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}void}}}\mdline{2022}}&\multicolumn{1}{|l}{\mdline{2022} error}&\multicolumn{1}{|l}{\mdline{2022} error}&\multicolumn{1}{|l|}{\mdline{2022} error}\\ +\multicolumn{1}{|l}{\mdline{2023} \mdline{2023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2023}}&\multicolumn{1}{|l}{\mdline{2023} error}&\multicolumn{1}{|l}{\mdline{2023} error}&\multicolumn{1}{|l|}{\mdline{2023} allowed}\\ +\multicolumn{1}{|l}{\mdline{2024} \mdline{2024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_kind}}}\mdline{2024}}&\multicolumn{1}{|l}{\mdline{2024} error}&\multicolumn{1}{|l}{\mdline{2024} error}&\multicolumn{1}{|l|}{\mdline{2024} error}\\ +\multicolumn{1}{|l}{\mdline{2025} \mdline{2025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2025}}&\multicolumn{1}{|l}{\mdline{2025} error}&\multicolumn{1}{|l}{\mdline{2025} error}&\multicolumn{1}{|l|}{\mdline{2025} allowed}\\ +\multicolumn{1}{|l}{\mdline{2026} \mdline{2026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2026}}&\multicolumn{1}{|l}{\mdline{2026} allowed\mdline{2026}\mdfootnote{1}{%mdk-data-line={2036} +%mdk-data-line={2036} +\noindent\mdline{2036}an \mdline{2036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2036} type used as a field in a \mdline{2036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2036} must specify a +underlying type and representation for \mdline{2037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2037} elements.%mdk +\label{fn-enum_header}%mdk%mdk +}\mdline{2026}}&\multicolumn{1}{|l}{\mdline{2026} error}&\multicolumn{1}{|l|}{\mdline{2026} allowed}\\ +\multicolumn{1}{|l}{\mdline{2027} \mdline{2027}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2027}}&\multicolumn{1}{|l}{\mdline{2027} error}&\multicolumn{1}{|l}{\mdline{2027} allowed}&\multicolumn{1}{|l|}{\mdline{2027} allowed}\\ +\multicolumn{1}{|l}{\mdline{2028} header stack}&\multicolumn{1}{|l}{\mdline{2028} error}&\multicolumn{1}{|l}{\mdline{2028} error}&\multicolumn{1}{|l|}{\mdline{2028} allowed}\\ +\multicolumn{1}{|l}{\mdline{2029} \mdline{2029}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2029}}&\multicolumn{1}{|l}{\mdline{2029} error}&\multicolumn{1}{|l}{\mdline{2029} error}&\multicolumn{1}{|l|}{\mdline{2029} allowed}\\ +\multicolumn{1}{|l}{\mdline{2030} \mdline{2030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2030}}&\multicolumn{1}{|l}{\mdline{2030} error}&\multicolumn{1}{|l}{\mdline{2030} error}&\multicolumn{1}{|l|}{\mdline{2030} allowed}\\ +\multicolumn{1}{|l}{\mdline{2031} \mdline{2031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2031}}&\multicolumn{1}{|l}{\mdline{2031} error}&\multicolumn{1}{|l}{\mdline{2031} error}&\multicolumn{1}{|l|}{\mdline{2031} allowed}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2033} +\mdhr{}%mdk + +%mdk-data-line={2034} +\noindent\mdline{2034}\mdcaption{\textbf{Table~\mdcaptionlabel{6}.}~\mdcaptiontext{P4 Type Usage}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-type-usage}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2039} +\mdline{2039}For example, the following P4\mdline{2039}\mdsub{16}\mdline{2039} objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects.%mdk + +%mdk-data-line={2042} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2043} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}{\bfseries{\mdcolor{navy}tuple}}\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}4}\textgreater{},~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~\textgreater{}~\textgreater{}()~digest\_complex;\\ +digest\_complex.pack(\{~hdr.ipv4.version,~hdr.ipv4.protocol~\});\\ +{\mdcolor{darkgreen}//~...}\\ +{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2053} +\noindent\mdline{2053}One solution would be to use only binary string (\mdline{2053}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2053} type) in +p4runtime.proto and to define a custom serialization format for complex P4\mdline{2054}\mdsub{16}\mdline{2054} +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P4\mdline{2061}\mdsub{16}\mdline{2061} types.%mdk + +%mdk-data-line={2063} +\subsubsection{\mdline{2063}8.5.2.\hspace*{0.5em}\mdline{2063}P4 Type Specifications in p4info.proto}\label{sec-p4-type-specifications-in-p4infoproto}%mdk%mdk + +%mdk-data-line={2065} +\noindent\mdline{2065}In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type \mdline{2069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip\_t}}}\mdline{2069}, which is a header union with 2 possible headers: +\mdline{2070}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4}}}\mdline{2070} with type \mdline{2070}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4\_t}}}\mdline{2070} and \mdline{2070}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6}}}\mdline{2070} with type \mdline{2070}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6\_t}}}\mdline{2070}. Similarly, they need to +know the field layout for both of these header types.%mdk + +%mdk-data-line={2073} +\mdline{2073}To achieve this we introduce 2 main Protobuf messages: \mdline{2073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2073} and +\mdline{2074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2074}.%mdk + +%mdk-data-line={2076} +\mdline{2076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2076} is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P4\mdline{2077}\mdsub{16}\mdline{2077} program. These +named types are \mdline{2078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2078}, \mdline{2078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2078}, \mdline{2078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2078}, \mdline{2078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2078} and +\mdline{2079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2079}; for each of these we have a type specification message, +respectively \mdline{2080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructTypeSpec}}}\mdline{2080}, \mdline{2080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderTypeSpec}}}\mdline{2080}, \mdline{2080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionTypeSpec}}}\mdline{2080}, +\mdline{2081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4EnumTypeSpec}}}\mdline{2081} and \mdline{2081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4SerializableEnumTypeSpec}}}\mdline{2081}. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. \mdline{2083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2083} also includes the list of parser errors for the program, as +a \mdline{2084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4ErrorTypeSpec}}}\mdline{2084} message.%mdk + +%mdk-data-line={2086} +\mdline{2086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2086} is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each \mdline{2088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2088} message corresponds to a compile-time type in the +original P4\mdline{2089}\mdsub{16}\mdline{2089} program (\mdline{2089}e.g.\mdline{2089} the type parameter of an extern). This +compile-time type is represented as a Protobuf \mdline{2090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2090}, which can be:%mdk + +%mdk-data-line={2092} +\begin{itemize}%mdk + +%mdk-data-line={2092} +\item{} +%mdk-data-line={2092} +\mdline{2092}a string representing the name of the type in case of a named type (\mdline{2092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2092}, +\mdline{2093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2093}, \mdline{2093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2093}, \mdline{2093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2093}, \mdline{2093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2093} or user-defined \mdline{2093}\textquotedblleft{}new\textquotedblright{}\mdline{2093} +\mdline{2094}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2094}),%mdk%mdk + +%mdk-data-line={2096} +\item{} +%mdk-data-line={2096} +\mdline{2096}an empty Protobuf message for \mdline{2096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2096} and \mdline{2096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2096}, or%mdk%mdk + +%mdk-data-line={2098} +\item{} +%mdk-data-line={2098} +\mdline{2098}a Protobuf message for other anonymous types (\mdline{2098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2098}, \mdline{2098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2098}, \mdline{2098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2098}, +\mdline{2099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2099} or stack). The \mdline{2099}\textquotedblleft{}binary string\textquotedblright{}\mdline{2099} types (\mdline{2099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2099}, \mdline{2099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2099}, and +\mdline{2100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2100}) are grouped together in the \mdline{2100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4BitstringLikeTypeSpec}}}\mdline{2100} message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf \mdline{2102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2102} +type).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2105} +\noindent\mdline{2105}For all P4\mdline{2105}\mdsub{16}\mdline{2105} compound types (\mdline{2105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2105}, \mdline{2105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2105}, \mdline{2105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2105}, and \mdline{2105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2105}), +the order of \mdline{2106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2106} in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P4\mdline{2108}\mdsub{16}\mdline{2108} declaration. The same goes for the order of members of an \mdline{2108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2108} +(serializable or not) or members of \mdline{2109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2109}.%mdk + +%mdk-data-line={2111} +\subsubsection{\mdline{2111}8.5.3.\hspace*{0.5em}\mdline{2111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2111} in p4runtime.proto}\label{sec-p4data-in-p4runtime-proto}%mdk%mdk + +%mdk-data-line={2113} +\noindent\mdline{2113}P4Runtime uses the \mdline{2113}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2113} message to represent values of arbitrary types. The +P4Runtime client must generate correct \mdline{2114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2114} messages based on the type +specification information included in P4Info. The \mdline{2115}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2115} message was designed +to introduce little overhead compared to using binary strings in the most common +case (P4\mdline{2117}\mdsub{16}\mdline{2117} \mdline{2117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2117} type).%mdk + +%mdk-data-line={2119} +\mdline{2119}Just like its P4Info counterpart\mdline{2119} \mdline{2119}- \mdline{2119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2119} \mdline{2119}-, \mdline{2119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2119} uses a Protobuf +\mdline{2120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2120} to represent all possible values.%mdk + +%mdk-data-line={2122} +\mdline{2122}We define a canonical representation for \mdline{2122}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2122} messages\mdline{2122} \mdline{2122}\textemdash{}\mdline{2122} therefore +guaranteeing read-write symmetry\mdline{2123} \mdline{2123}\textemdash{}\mdline{2123} by introducing the following requirements:%mdk + +%mdk-data-line={2125} +\begin{itemize}%mdk + +%mdk-data-line={2125} +\item{} +%mdk-data-line={2125} +\mdline{2125}The order of \mdline{2125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2125} in \mdline{2125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructLike}}}\mdline{2125} and the order of \mdline{2125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2125} in +\mdline{2126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2126} must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P4\mdline{2127}\mdsub{16}\mdline{2127} type +declaration.%mdk%mdk + +%mdk-data-line={2130} +\item{} +%mdk-data-line={2130} +\mdline{2130}An invalid header is represented by a \mdline{2130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2130} message where the \mdline{2130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_valid}}}\mdline{2130} +field is false and the \mdline{2131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2131} repeated field is empty.%mdk%mdk + +%mdk-data-line={2133} +\item{} +%mdk-data-line={2133} +\mdline{2133}An invalid header union (\mdline{2133}i.e.\mdline{2133} all headers in the union are invalid) is +represented by a \mdline{2134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnion}}}\mdline{2134} message where the \mdline{2134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header\_name}}}\mdline{2134} is the +empty string (default value for the field) and the \mdline{2135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header}}}\mdline{2135} is unset.%mdk%mdk + +%mdk-data-line={2137} +\item{} +%mdk-data-line={2137} +\mdline{2137}The order of \mdline{2137}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2137} in \mdline{2137}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStack}}}\mdline{2137} and \mdline{2137}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStack}}}\mdline{2137} is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the \mdline{2139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2139} field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding \mdline{2141}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStackTypeSpec}}}\mdline{2141} or +\mdline{2142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStackTypeSpec}}}\mdline{2142} message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2144} +\subsubsection{\mdline{2144}8.5.4.\hspace*{0.5em}\mdline{2144}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={2146} +\noindent\mdline{2146}Let\mdline{2146}'\mdline{2146}s look at the Register example again:%mdk + +%mdk-data-line={2148} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2149} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2156} +\noindent\mdline{2156}Here\mdline{2156}'\mdline{2156}s the corresponding entry in the P4Info message:%mdk + +%mdk-data-line={2158} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2159} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}registers~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}369119267}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~\}\\ +~~type\_spec~\{\\ +~~~~header\_union~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~size:~{\mdcolor{purple}128}\\ +\}\\ +type\_info~\{\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~header\_unions~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2215} +\noindent\mdline{2215}Here\mdline{2215}'\mdline{2215}s a \mdline{2215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.WriteRequest}}}\mdline{2215} to set the value of \mdline{2215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_ip{}[12]}}}\mdline{2215}:%mdk + +%mdk-data-line={2217} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2218} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}update~\{\\ +~~type:~INSERT\\ +~~entity~\{\\ +~~~~register\_entry~\{\\ +~~~~~~register\_id:~{\mdcolor{purple}369119267}\\ +~~~~~~index~\{\\ +~~~~~~~~index:~{\mdcolor{purple}12}\\ +~~~~~~\}\\ +~~~~~~data~\{\\ +~~~~~~~~header\_union~\{\\ +~~~~~~~~~~valid\_header\_name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~~~valid\_header~\{\\ +~~~~~~~~~~~~is\_valid:~true\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x04}{\mdcolor{maroon}"}\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{darkgreen}\#~...}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2241} +\subsubsection{\mdline{2241}8.5.5.\hspace*{0.5em}\mdline{2241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2241}, serializable \mdline{2241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2241} and \mdline{2241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}\label{sec-enum-serializable-enum-and-error}%mdk%mdk + +%mdk-data-line={2243} +\noindent\mdline{2243}P4\mdline{2243}\mdsub{16}\mdline{2243} supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or \mdline{2244}\textquotedblleft{}unsafe\textquotedblright{}\mdline{2244} enum) +\mdline{2245}[\mdcite{p4enums}{5}]\mdline{2245}. For \mdline{2245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2245} types with no underlying type\mdline{2245} \mdline{2245}\textemdash{}\mdline{2245} as well as \mdline{2245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2245} \mdline{2245}\textemdash{}\mdline{2245} +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in \mdline{2248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2248} to represent \mdline{2248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2248} and +\mdline{2249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2249} values.%mdk + +%mdk-data-line={2251} +\mdline{2251}Serializable \mdline{2251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2251} types have an underlying fixed-width unsigned integer +representation (\mdline{2252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2252}). All named enum members must be assigned an integer +value by the P4 programmer, but \mdline{2253}\emph{not all}\mdline{2253} valid numeric values for the +underlying type need to have a corresponding name. \mdline{2254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2254} includes the +mapping between entry name and entry value. When providing serializable enum +values through \mdline{2256}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2256}, one must use the assigned integer value (\mdline{2256}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum\_value}}}\mdline{2256} +bytestring field). P4Runtime does not provide a way for the client to use the +name\mdline{2258} \mdline{2258}\textemdash{}\mdline{2258} even when the enum member has one\mdline{2258} \mdline{2258}\textemdash{}\mdline{2258} instead of the value, as it makes it +easier for the server to respect the\mdline{2259}~\mdref{sec-read-write-symmetry}{read-write +symmetry}\mdline{2260} principle.%mdk + +%mdk-data-line={2262} +\subsubsection{\mdline{2262}8.5.6.\hspace*{0.5em}\mdline{2262}User-defined types}\label{sec-user-defined-types}%mdk%mdk + +%mdk-data-line={2264} +\noindent\mdline{2264}P4\mdline{2264}\mdsub{16}\mdline{2264} enables programmers to introduce new types\mdline{2264}~[\mdcite{p4newtypes}{11}]\mdline{2264}. While similar +to \mdline{2265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{2265}, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +\mdline{2268}\mdref{sec-psa-metadata-translation}{translation}\mdline{2268}. When introducing a new type, the +declaration can be annotated with \mdline{2269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2269} to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for\mdline{2271}~\mdref{sec-translation-of-port-numbers}{port numbers}\mdline{2271}, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. \mdline{2274}\textbf{The \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}} annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}})}\mdline{2276} and the type exposed to the control plane will also be a +fixed-width unsigned bitstring, with a potentially different bitwidth. It takes +two parameters: a \mdline{2278}\emph{URI}\mdline{2278} (Uniform Resource Identifier) which uniquely identifies +the translation being performed on entities of the new type to the P4Runtime +server and the \mdline{2280}\emph{bitwidth}\mdline{2280} of the bitstring type exposed to the control plane. It +is recommended that the URI includes at least the P4 architecture name and the +type name.%mdk + +%mdk-data-line={2284} +\mdline{2284}User-defined types are specified using the \mdline{2284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{2284} message, which has +the following fields:%mdk + +%mdk-data-line={2287} +\begin{itemize}%mdk + +%mdk-data-line={2287} +\item{} +%mdk-data-line={2287} +\mdline{2287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}representation}}}\mdline{2287}, a Protobuf \mdline{2287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2287} specifying how values of this type are +exchanged between client and server; it can be either:%mdk + +%mdk-data-line={2290} +\begin{itemize}%mdk + +%mdk-data-line={2290} +\item{} +%mdk-data-line={2290} +\mdline{2290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2290}, if and only if no \mdline{2290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2290} annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 \mdline{2292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2292} declaration is itself a +user-defined type, \mdline{2293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2293} is obtained by \mdline{2293}\textquotedblleft{}walking\textquotedblright{}\mdline{2293} the chain of +\mdline{2294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2294} declarations recursively until a built-in type (e.g \mdline{2294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2294}) is +found.%mdk%mdk + +%mdk-data-line={2297} +\item{} +%mdk-data-line={2297} +\mdline{2297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}translated\_type}}}\mdline{2297}, if and only if the P4 \mdline{2297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2297} declaration was annotated +with \mdline{2298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2298}. It is of type \mdline{2298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeTranslation}}}\mdline{2298}, which +itself has two fields\mdline{2299} \mdline{2299}\textemdash{}\mdline{2299} \mdline{2299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uri}}}\mdline{2299} and \mdline{2299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_bitwidth}}}\mdline{2299} \mdline{2299}\textemdash{}\mdline{2299}, which map to the +two input parameters to the annotation.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2302} +\item{} +%mdk-data-line={2302} +\mdline{2302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{2302}, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2305} +\noindent\mdline{2305}For example, an architecture\mdline{2305} \mdline{2305}\textemdash{}\mdline{2305} in this case PSA\mdline{2305} \mdline{2305}\textemdash{}\mdline{2305} may introduce a new type +for port numbers:%mdk + +%mdk-data-line={2307} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2308} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2312} +\noindent\mdline{2312}In this case, the P4Info message would include the following \mdline{2312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2312} +message:%mdk + +%mdk-data-line={2315} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2316} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2329} +\noindent\mdline{2329}Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (\mdline{2330}e.g.\mdline{2330} through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over \mdline{2332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2332} to enable users +to overwrite annotations included as part of the P4 architecture definition.%mdk + +%mdk-data-line={2335} +\subsubsection{\mdline{2335}8.5.7.\hspace*{0.5em}\mdline{2335}Trade-off for v1.0 Release}\label{sec-trade-off-for-v10-release}%mdk%mdk + +%mdk-data-line={2337} +\noindent\mdline{2337}For the v1.0 release of P4Runtime, it was decided not to replace occurrences of +\mdline{2338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2338} with \mdline{2338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2338} in the \mdline{2338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{2338} message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-release +implementations of P4Runtime. Similarly it has been decided to keep using +\mdline{2341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2341} to provide action parameter values. However \mdline{2341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2341} is used whenever +appropriate for PSA externs and we encourage the use of \mdline{2342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2342} in +architecture-specific extensions.%mdk + +%mdk-data-line={2345} +\mdline{2345}In order to support\mdline{2345}~\mdref{sec-psa-metadata-translation}{translation}\mdline{2345} for action +parameters and match fields, we include a \mdline{2346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2346} field in +\mdline{2347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{2347} and \mdline{2347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Action.Param}}}\mdline{2347}.%mdk + +%mdk-data-line={2349} +\section{\mdline{2349}9.\hspace*{0.5em}\mdline{2349}P4 Entity Messages}\label{sec-p4-entity-msgs}%mdk%mdk + +%mdk-data-line={2351} +\noindent\mdline{2351}P4Runtime covers P4 entities that are either part of the P4\mdline{2351}\mdsub{16}\mdline{2351} language, or +defined as PSA externs. The sections below describe the messages for each +supported entity.%mdk + +%mdk-data-line={2355} +\subsection{\mdline{2355}9.1.\hspace*{0.5em}\mdline{2355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}\label{sec-table-entry}%mdk%mdk + +%mdk-data-line={2357} +\noindent\mdline{2357}The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action\mdline{2359}'\mdline{2359}s +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification.%mdk + +%mdk-data-line={2365} +\mdline{2365}P4Runtime supports inserting, modifying, deleting and reading table entries with +the \mdline{2366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2366} entity, which has the following fields:%mdk + +%mdk-data-line={2368} +\begin{itemize}%mdk + +%mdk-data-line={2368} +\item{} +%mdk-data-line={2368} +\mdline{2368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2368}, which identifies the table instance; the \mdline{2368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2368} is determined +by the P4Info message.%mdk%mdk + +%mdk-data-line={2371} +\item{} +%mdk-data-line={2371} +\mdline{2371}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2371}, a repeated field of \mdline{2371}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2371} messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration.%mdk%mdk + +%mdk-data-line={2375} +\item{} +%mdk-data-line={2375} +\mdline{2375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2375}, which indicates which of the table\mdline{2375}'\mdline{2375}s actions to execute in case of +match and with which argument values.%mdk%mdk + +%mdk-data-line={2378} +\item{} +%mdk-data-line={2378} +\mdline{2378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2378}, a 32-bit integer used to order entries when the table\mdline{2378}'\mdline{2378}s match key +includes a ternary or range match.%mdk%mdk + +%mdk-data-line={2381} +\item{} +%mdk-data-line={2381} +\mdline{2381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2381}, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry.%mdk%mdk + +%mdk-data-line={2386} +\item{} +%mdk-data-line={2386} +\mdline{2386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2386}, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See\mdline{2387}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2388} section for more information.%mdk%mdk + +%mdk-data-line={2390} +\item{} +%mdk-data-line={2390} +\mdline{2390}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2390}, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See\mdline{2391}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2392} section for more information.%mdk%mdk + +%mdk-data-line={2394} +\item{} +%mdk-data-line={2394} +\mdline{2394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2394}, a boolean flag which indicates whether the table entry is +the default entry for the table. See\mdline{2395}~\mdref{sec-default-entry}{Default entry}\mdline{2395} +section for more information.%mdk%mdk + +%mdk-data-line={2398} +\item{} +%mdk-data-line={2398} +\mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2398} and \mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2398}, which are two fields used to +implement idle-timeout support for the table, if applicable. See +\mdline{2400}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{2400} section for more information.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2402} +\noindent\mdline{2402}The \mdline{2402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2402} field must be set to a non-zero value if the match key includes a +ternary match (\mdline{2403}i.e.\mdline{2403} in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has a \mdline{2404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2404} or \mdline{2404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2404} match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches.%mdk + +%mdk-data-line={2413} +\mdline{2413}The \mdline{2413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2413} and \mdline{2413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2413} fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for \mdline{2415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2415} and \mdline{2415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{2415} updates. When deleting +an entry, these key fields (along with \mdline{2416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2416}) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a \mdline{2418}\emph{keyless}\mdline{2418} +table (the table has an empty match key), the server must reject all attempts to +\mdline{2420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2420} a match entry and return an \mdline{2420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2420} error.%mdk + +%mdk-data-line={2422} +\mdline{2422}The number of match entries that a table \mdline{2422}\emph{should}\mdline{2422} support is indicated in P4Info +(\mdline{2423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2423} field of \mdline{2423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{2423} message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P4\mdline{2424}\mdsub{16}\mdline{2424} specification for the +\mdline{2425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2425} property\mdline{2425}~[\mdcite{p4tableproperties}{27}]\mdline{2425}. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +\mdline{2429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{2429} when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached.%mdk + +%mdk-data-line={2434} +\subsubsection{\mdline{2434}9.1.1.\hspace*{0.5em}\mdline{2434}Match Format}\label{sec-match-format}%mdk%mdk + +%mdk-data-line={2436} +\noindent\mdline{2436}The bytes fields in the \mdline{2436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2436} message follow the format described in +\mdline{2437}\mdref{sec-bytestrings}{Bytestrings}\mdline{2437}.%mdk + +%mdk-data-line={2439} +\mdline{2439}For \mdline{2439}\textquotedblleft{}don't care\textquotedblright{}\mdline{2439} matches, the P4Runtime client must omit the field\mdline{2439}'\mdline{2439}s entire +\mdline{2440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2440} entry when building the \mdline{2440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2440} repeated field of the \mdline{2440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2440} +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for \mdline{2442}\textquotedblleft{}don't care\textquotedblright{}\mdline{2442} matches, which is needed +to ensure\mdline{2443}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2443}. For PSA match types, +a \mdline{2444}\textquotedblleft{}don't care\textquotedblright{}\mdline{2444} match for a specific match key field is defined as follows:%mdk + +%mdk-data-line={2446} +\begin{itemize}%mdk + +%mdk-data-line={2446} +\item{} +%mdk-data-line={2446} +\mdline{2446}For a \mdline{2446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2446} match, it is logically equivalent to a mask of zeros.%mdk%mdk + +%mdk-data-line={2448} +\item{} +%mdk-data-line={2448} +\mdline{2448}For an \mdline{2448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2448} match, it is logically equivalent to a prefix\mdline{2448}\_\mdline{2448}len of zero.%mdk%mdk + +%mdk-data-line={2450} +\item{} +%mdk-data-line={2450} +\mdline{2450}For a \mdline{2450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2450} match, it is logically equivalent to a range which includes all +possible values for the field.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2453} +\noindent\mdline{2453}Note that there is no \mdline{2453}\textquotedblleft{}don't care\textquotedblright{}\mdline{2453} value for \mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2453} matches and therefore exact +match fields can never be omitted from the \mdline{2454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2454} message.%mdk + +%mdk-data-line={2456} +\mdline{2456}The following example shows a P4Runtime message that treats a \mdline{2456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2456} field +as a \mdline{2457}\textquotedblleft{}don't care\textquotedblright{}\mdline{2457} match. The P4 program defines table \mdline{2457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{2457} with \mdline{2457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2457} +and \mdline{2458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2458} fields in its match key:%mdk + +%mdk-data-line={2460} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2461} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~ternary;\\ +~~~~istd.ingress\_port:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2472} +\noindent\mdline{2472}In this P4Runtime request, the client omits the table\mdline{2472}'\mdline{2472}s \mdline{2472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2472} field +from the repeated \mdline{2473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2473} field to indicate a \mdline{2473}\textquotedblleft{}don't care\textquotedblright{}\mdline{2473} match. As shown +below, the \mdline{2474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2474} specifies only the \mdline{2474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2474} field given by \mdline{2474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id:~2}}}\mdline{2474}.%mdk + +%mdk-data-line={2476} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2477} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}33554439}~~{\mdcolor{darkgreen}\#~Table~t's~ID.}\\ +~~~~match~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~field\_id~1~is~not~present~to~use~the~don't~care~ternary~value.}\\ +~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~exact~\{\\ +~~~~~~~~value:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x20}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~action~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~Action~selection~goes~here.}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2495} +\noindent\mdline{2495}For every member of the \mdline{2495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2495} repeated \mdline{2495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2495} field, \mdline{2495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id}}}\mdline{2495} must be +a valid id for the table, as per the P4Info, and one of the fields in +\mdline{2497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{2497} must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an \mdline{2499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2499} error code.%mdk + +%mdk-data-line={2501} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2501} +\item\mdline{2501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2501} match + +%mdk-data-line={2502} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2502} +\item\mdline{2502}The binary string encoding of the value must conform to the +\mdline{2503}\mdref{sec-bytestrings}{Bytestrings}\mdline{2503} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2505} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2506} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.exact().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2509} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2509} +\item\mdline{2509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2509} match + +%mdk-data-line={2510} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2510} +\item\mdline{2510}The binary string encoding of the value (when present) must conform to the +\mdline{2511}\mdref{sec-bytestrings}{Bytestrings}\mdline{2511} requirements.%mdk + +%mdk-data-line={2512} +\item\mdline{2512}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2512} match must be omitted.%mdk + +%mdk-data-line={2513} +\item\mdline{2513}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2513} bits must be 0 in value.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2515} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2516} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.lpm().value()))\\ +\\ +pLen~=~match.lpm().prefix\_len()\\ +assert(pLen~\textgreater{}~0)\\ +\\ +trailing\_zeros~=~countTrailingZeros(match.lpm().value())\\ +assert(trailing\_zeros~\textgreater{}=~field\_bits~-~pLen)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2525} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2525} +\item\mdline{2525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2525} match + +%mdk-data-line={2526} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2526} +\item\mdline{2526}The binary string encoding of the value (when present) and mask (when +present) must conform to the\mdline{2527}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2527} requirements.%mdk + +%mdk-data-line={2528} +\item\mdline{2528}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2528} match must be omitted.%mdk + +%mdk-data-line={2529} +\item\mdline{2529}Masked bits must be 0 in value. This constraint taken together +with the\mdline{2530}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2530} requirements means that the +value\mdline{2531}'\mdline{2531}s binary string is never longer than the mask\mdline{2531}'\mdline{2531}s binary string. +When the value\mdline{2532}'\mdline{2532}s string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2536} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2537} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.ternary().value()))\\ +assert(BytestringValid(match.ternary().mask()))\\ +assert(match.ternary().value().size()~\textless{}=~match.ternary().mask().size());\\ +\\ +value~=~parseInteger(match.ternary().value())\\ +mask~=~parseInteger(match.ternary().mask())\\ +\\ +assert(mask~!=~0)\\ +\\ +assert(value~\&~mask~==~value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2549} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2549} +\item\mdline{2549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2549} match + +%mdk-data-line={2550} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2550} +\item\mdline{2550}The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the\mdline{2551}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2551} +requirements.%mdk + +%mdk-data-line={2553} +\item\mdline{2553}Low bound must be less than or equal to the high bound.%mdk + +%mdk-data-line={2554} +\item\mdline{2554}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2554} match must be omitted.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2556} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2557} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.range().low()))\\ +assert(BytestringValid(match.range().high()))\\ +\\ +low~=~parseInteger(match.range().low())\\ +high~=~parseInteger(match.range().high())\\ +\\ +assert(low~\textless{}=~high)\\ +\\ +assert(low~!=~min\_field\_value~\textbar{}\textbar{}~high~!=~max\_field\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2568} +\subsubsection{\mdline{2568}9.1.2.\hspace*{0.5em}\mdline{2568}Action Specification}\label{sec-action-specification}%mdk%mdk + +%mdk-data-line={2570} +\noindent\mdline{2570}The \mdline{2570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2570} \mdline{2570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2570} field must be set for every \mdline{2570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2570} and \mdline{2570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2570} +update, except when resetting the\mdline{2571}~\mdref{sec-default-entry}{default entry}\mdline{2571}. Based on +the implementation property value of the P4 table, the \mdline{2572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2572} in the +\mdline{2573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{2573} message will either be:%mdk + +%mdk-data-line={2575} +\begin{itemize}%mdk + +%mdk-data-line={2575} +\item{} +%mdk-data-line={2575} +\mdline{2575}an \mdline{2575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{2575} specification for direct tables (with no P4 \mdline{2575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2575} +property)%mdk%mdk + +%mdk-data-line={2578} +\item{} +%mdk-data-line={2578} +\mdline{2578}an action profile member id for indirect tables for which the \mdline{2578}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2578} +property is an action profile with no selector.%mdk%mdk + +%mdk-data-line={2581} +\item{} +%mdk-data-line={2581} +\mdline{2581}an action profile member id or group id for indirect tables for which the +\mdline{2582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2582} property is an action profile with selector.%mdk%mdk + +%mdk-data-line={2584} +\item{} +%mdk-data-line={2584} +\mdline{2584}an \mdline{2584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{2584} specification for indirect tables for +which the \mdline{2585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2585} property is an action profile with +selector. This usage is described in\mdline{2586}~\mdref{sec-oneshot}{One Shot Action Selector +Programming}\mdline{2587}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2589} +\noindent\mdline{2589}If the \mdline{2589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2589} field is not set (and if \mdline{2589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2589} is false) or if the +\mdline{2590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2590} does not match the table description in the P4Info (\mdline{2590}e.g.\mdline{2590} the \mdline{2590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2590} is +\mdline{2591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member\_id}}}\mdline{2591} for a direct table), the server must return an +\mdline{2592}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2592} error code.%mdk + +%mdk-data-line={2594} +\mdline{2594}The \mdline{2594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{2594} Protobuf message has the following fields:%mdk + +%mdk-data-line={2596} +\begin{itemize}%mdk + +%mdk-data-line={2596} +\item{} +%mdk-data-line={2596} +\mdline{2596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{2596}, which identifies the action instance; the \mdline{2596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{2596} is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an \mdline{2598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2598} error +code. If the client uses a valid \mdline{2599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{2599} for the table but does not +respect the action scope specified in P4Info (\mdline{2600}e.g.\mdline{2600} tries to set a \mdline{2600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{2600} +action as the default action), the server must return a \mdline{2601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{2601} +error code.%mdk%mdk + +%mdk-data-line={2604} +\item{} +%mdk-data-line={2604} +\mdline{2604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{2604}: a repeated Protobuf field of action parameter values, each encoded +as a \mdline{2605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{2605} message. For each parameter, \mdline{2605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}param\_id}}}\mdline{2605} must be valid for the +action (as per the P4Info) and value must follow the format described in +\mdline{2607}\mdref{sec-bytestrings}{Bytestrings}\mdline{2607}. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an \mdline{2609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2609} error code +if a parameter id is missing, if an extra parameter\mdline{2610} \mdline{2610}\textemdash{}\mdline{2610} id not found in the +P4Info\mdline{2611} \mdline{2611}\textemdash{}\mdline{2611} was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +\mdline{2613}\mdref{sec-bytestrings}{Bytestrings}\mdline{2613} format.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2615} +\noindent\mdline{2615}For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a \mdline{2617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{2617} error code.%mdk + +%mdk-data-line={2619} +\subsubsection{\mdline{2619}9.1.3.\hspace*{0.5em}\mdline{2619}Default Entry}\label{sec-default-entry}%mdk%mdk + +%mdk-data-line={2621} +\noindent\mdline{2621}According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer\mdline{2622} \mdline{2622}\textemdash{}\mdline{2622} or defaults to \mdline{2622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{2622} +(which is a no-op) otherwise\mdline{2623} \mdline{2623}\textemdash{}\mdline{2623} and assuming it is not declared as \mdline{2623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{2623}, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow \mdline{2625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2625} and \mdline{2625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{2625} updates on the default entry and the +P4Runtime server must return an \mdline{2626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2626} error code if the client +attempts one.%mdk + +%mdk-data-line={2629} +\mdline{2629}The default entry is identified by setting the \mdline{2629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2629} boolean field +to true. When this flag is set to true, the repeated \mdline{2630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2630} field must be empty +and the \mdline{2631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2631} field must be set to zero, otherwise the P4Runtime server +must return an \mdline{2632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2632} error code. When performing a \mdline{2632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2632} update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its \mdline{2636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2636} value as well as the configurations for its +\mdline{2637}\mdref{sec-direct-resources}{direct resources}\mdline{2637} will be reset to their defaults. If +the default entry is constant (as indicated by the P4 program and the P4Info +message), the server must return a \mdline{2639}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{2639} error code if the client +attempts to modify it.%mdk + +%mdk-data-line={2642} +\mdline{2642}Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to\mdline{2643}~\mdref{sec-direct-resources}{direct resources}\mdline{2643}.%mdk + +%mdk-data-line={2645} +\mdline{2645}In this P4Runtime release, we have decided to restrict the default entry for +indirect tables\mdline{2646} \mdline{2646}\textemdash{}\mdline{2646} tables with an ActionProfile or ActionSelector +\mdline{2647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2647} property\mdline{2647} \mdline{2647}\textemdash{}\mdline{2647} to a constant \mdline{2647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{2647} action entry, with the hope +that it would simplify the implementation of the P4Runtime service.%mdk + +%mdk-data-line={2650} +\subsubsection{\mdline{2650}9.1.4.\hspace*{0.5em}\mdline{2650}Constant Tables}\label{sec-constant-tables}%mdk%mdk + +%mdk-data-line={2652} +\noindent\mdline{2652}Constant tables are defined as tables whose match entries are immutable. They +are identified by the \mdline{2653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{2653} flag in P4Info. The only write updates +which are allowed for constant tables are \mdline{2654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2654} operations on the default +action, assuming the default action itself is not constant. If the P4Runtime +client attempts to perform any other kind of write update on a constant table, +the server must return a \mdline{2657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{2657} error. However, the contents of +such tables can be queried by the client through a \mdline{2658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2658}. When reading +static (immutable) entries from a constant table, the following fields\mdline{2659} \mdline{2659}\textemdash{}\mdline{2659} and +only these fields\mdline{2660} \mdline{2660}\textemdash{}\mdline{2660}, must be set by the server: \mdline{2660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2660}, \mdline{2660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2660}, \mdline{2660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2660}, +\mdline{2661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2661} and \mdline{2661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2661}. In particular, we assume that constant +tables cannot be assigned direct resources and idle timeout is not supported for +static entries. If the table requires a priority value for entries, the server +must populate the \mdline{2664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2664} field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P4\mdline{2666}\mdsub{16}\mdline{2666} does not support assigning explicit priorities to static +entries. When a priority value is required (\mdline{2667}e.g.\mdline{2667} for tables including \mdline{2667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2667} +and / or \mdline{2668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2668} matches in the case of PSA), it is inferred based on the +order in which entries appear in the table declaration.%mdk + +%mdk-data-line={2671} +\subsubsection{\mdline{2671}9.1.5.\hspace*{0.5em}\mdline{2671}Wildcard Reads}\label{sec-wildcard-reads}%mdk%mdk + +%mdk-data-line={2673} +\noindent\mdline{2673}When performing a \mdline{2673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2673}, the P4Runtime client can select all entries +from one or all tables on the target and use several of the \mdline{2674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2674} fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as \mdline{2678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2678} and \mdline{2678}\textquotedblleft{}unset\textquotedblright{}\mdline{2678} for message fields such as \mdline{2678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2678}. The following +fields may be used to select and filter results:%mdk + +%mdk-data-line={2681} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2681} +\item\mdline{2681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2681}: If default (0), entries from all tables\mdline{2681} \mdline{2681}\textemdash{}\mdline{2681} including constant +tables\mdline{2682} \mdline{2682}\textemdash{}\mdline{2682} will be selected and no other filter can be used. Otherwise only +the specified table will be considered.%mdk + +%mdk-data-line={2684} +\item\mdline{2684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2684}: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned.%mdk + +%mdk-data-line={2688} +\item\mdline{2688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2688}: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an \mdline{2689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{2689} (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id.%mdk + +%mdk-data-line={2695} +\item\mdline{2695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2695}: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value.%mdk + +%mdk-data-line={2698} +\item\mdline{2698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2698}: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +\mdline{2700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2700} value.%mdk + +%mdk-data-line={2701} +\item\mdline{2701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2701}: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2705} +\noindent\mdline{2705}For example, in order to read all entries from all tables from device 3, the +client can use the following \mdline{2706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2706} message.%mdk + +%mdk-data-line={2708} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2709} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0}\\ +~~~~priority:~{\mdcolor{purple}0}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2719} +\noindent\mdline{2719}In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following \mdline{2720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2720} +message:%mdk + +%mdk-data-line={2723} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2724} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~priority:~{\mdcolor{purple}11}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2734} +\noindent\mdline{2734}The canonical representation of \mdline{2734}\textquotedblleft{}don't care\textquotedblright{}\mdline{2734} matches, combined with the ability +to do a wildcard read on all table entries by leaving the \mdline{2735}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2735} field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single \mdline{2737}\textquotedblleft{}don't care\textquotedblright{}\mdline{2737} entry or to do a wildcard +read. If a table has no fields with match kind \mdline{2738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2738}, it is possible via +P4Runtime to add an entry that is \mdline{2739}\textquotedblleft{}don't care\textquotedblright{}\mdline{2739} for all fields (\mdline{2739}i.e.\mdline{2739} has an empty +\mdline{2740}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2740} field) but is not the default entry (\mdline{2740}i.e.\mdline{2740} \mdline{2740}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2740} is +false). When reading this entry from the table, there is no way to read \mdline{2741}\emph{only}\mdline{2741} +that entry from the table, because it would require providing an unset \mdline{2742}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2742} +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single \mdline{2745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2745} match:%mdk + +%mdk-data-line={2747} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2748} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;~fwd;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2758} +\noindent\mdline{2758}The following \mdline{2758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{2758} message can be used to add 2 entries:%mdk + +%mdk-data-line={2759} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2760} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{~{\mdcolor{darkgreen}\#~don't~care~entry}\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +~~table~entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~match~\{\\ +~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~lpm~\{\\ +~~~~~~~~value:~{\mdcolor{purple}0x0a000000}\\ +~~~~~~~~prefix\_len:~{\mdcolor{purple}8}\\ +~~~~~~\}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2779} +\noindent\mdline{2779}The first entry is a \mdline{2779}\textquotedblleft{}don't care\textquotedblright{}\mdline{2779} entry, while the second one matches all +\mdline{2780}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}10.0.0.0/8}}}\mdline{2780} addresses. The second entry has higher priority than the first one.%mdk + +%mdk-data-line={2782} +\mdline{2782}The following \mdline{2782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2782} message will return \mdline{2782}\emph{all}\mdline{2782} entries in the table, not +just the \mdline{2783}\textquotedblleft{}don't care\textquotedblright{}\mdline{2783} entry.%mdk + +%mdk-data-line={2784} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2785} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2793} +\noindent\mdline{2793}This issue also exists for tables with \mdline{2793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2793} and / or \mdline{2793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2793} +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the \mdline{2796}\textquotedblleft{}don't care\textquotedblright{}\mdline{2796} entry will be returned to the +client. If the client uses distinct priority values for all entries\mdline{2797} \mdline{2797}\textemdash{}\mdline{2797} which is +strongly recommended to achieve\mdline{2798}~\mdref{sec-table-entry}{deterministic behavior}\mdline{2798} \mdline{2798}\textemdash{}\mdline{2798}, +then there is no ambiguity because the wildcard read will actually return a +single entry (the \mdline{2800}\textquotedblleft{}don't care\textquotedblright{}\mdline{2800} entry) as long as the \mdline{2800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2800} field is set to +the correct value.%mdk + +%mdk-data-line={2803} +\subsubsection{\mdline{2803}9.1.6.\hspace*{0.5em}\mdline{2803}Direct Resources}\label{sec-direct-resources}%mdk%mdk + +%mdk-data-line={2805} +\noindent\mdline{2805}In addition to the \mdline{2805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{2805} and \mdline{2805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{2805} entities, +P4Runtime support reading and writing direct resources as part of the +\mdline{2807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2807} message. This is convenient for two reasons:%mdk + +%mdk-data-line={2809} +\begin{itemize}%mdk + +%mdk-data-line={2809} +\item{} +%mdk-data-line={2809} +\mdline{2809}A table entry and its direct resources can be read with a single entity when +doing a \mdline{2810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{2810} RPC call%mdk%mdk + +%mdk-data-line={2812} +\item{} +%mdk-data-line={2812} +\mdline{2812}The initial configuration for an entry\mdline{2812}'\mdline{2812}s direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can \mdline{2817}\textquotedblleft{}hit\textquotedblright{}\mdline{2817} the table entry without +executing the appropriate meter entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2820} +\noindent\mdline{2820}Once the table entry has been inserted, the P4Runtime client is free to use the +\mdline{2821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{2821} and \mdline{2821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{2821} messages for read and write +operations on \mdline{2822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{2822} and \mdline{2822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{2822} instances. For example, it is +usually more convenient as well as more efficient to use \mdline{2823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{2823} to +query a counter entry value rather than use \mdline{2824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2824}, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry.%mdk + +%mdk-data-line={2828} +\mdline{2828}The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does \mdline{2829}\emph{not}\mdline{2829} need to be \mdline{2829}\textquotedblleft{}executed\textquotedblright{}\mdline{2829} in +every action bound to the table. It is an error to provide a direct resource +configuration in a \mdline{2831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2831} message when programming an action that does not +execute the direct resource, and the server must return an \mdline{2832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2832} +error code.%mdk + +%mdk-data-line={2835} +\mdline{2835}We leverage Protobuf\mdline{2835}'\mdline{2835}s ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the \mdline{2837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2837} message. The list below describes how +the server must handle the \mdline{2838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2838} and \mdline{2838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2838} fields for read and +write requests, based on whether the fields are set or not. We do not cover +error cases in the list, \mdline{2840}i.e.\mdline{2840} we assume that we are dealing with a table which +is assigned a direct counter / a direct meter, and that the action being used +for the table entry \mdline{2842}\textquotedblleft{}executes\textquotedblright{}\mdline{2842} the direct resource appropriately.%mdk + +%mdk-data-line={2844} +\begin{itemize}%mdk + +%mdk-data-line={2844} +\item{} +%mdk-data-line={2844} +\mdline{2844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2844} field%mdk + +%mdk-data-line={2845} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2845} +\item\mdline{2845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{2845} + +%mdk-data-line={2846} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2846} +\item\mdline{2846}if \mdline{2846}\textbf{unset}\mdline{2846}: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets).%mdk + +%mdk-data-line={2848} +\item\mdline{2848}if \mdline{2848}\textbf{set}\mdline{2848}: The initial configuration for the meter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2850} +\item\mdline{2850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{2850} + +%mdk-data-line={2851} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2851} +\item\mdline{2851}if \mdline{2851}\textbf{unset}\mdline{2851}: The meter entry\mdline{2851}'\mdline{2851}s configuration is reset to the default +(meter returns GREEN for all packets).%mdk + +%mdk-data-line={2853} +\item\mdline{2853}if \mdline{2853}\textbf{set}\mdline{2853}: The value provided by the client is used to re-configure +the meter entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2855} +\item\mdline{2855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2855} + +%mdk-data-line={2856} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2856} +\item\mdline{2856}if \mdline{2856}\textbf{unset}\mdline{2856}: The response does not include the meter entry\mdline{2856}'\mdline{2856}s +configuration (\mdline{2857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2857} is unset in the response).%mdk + +%mdk-data-line={2858} +\item\mdline{2858}if \mdline{2858}\textbf{set}\mdline{2858}: If the meter entry\mdline{2858}'\mdline{2858}s configuration is the default +configuration, \mdline{2859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2859} is unset in the response. Otherwise, the +response includes the meter entry\mdline{2860}'\mdline{2860}s configuration that was written by +the client earlier. This respects the \mdline{2861}\textquotedblleft{}read-write symmetry\textquotedblright{}\mdline{2861} principle.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2863} +\item{} +%mdk-data-line={2863} +\mdline{2863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2863} field%mdk + +%mdk-data-line={2864} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2864} +\item\mdline{2864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{2864} + +%mdk-data-line={2865} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2865} +\item\mdline{2865}if \mdline{2865}\textbf{unset}\mdline{2865}: The initial value for the counter entry is the default +(0).%mdk + +%mdk-data-line={2867} +\item\mdline{2867}if \mdline{2867}\textbf{set}\mdline{2867}: The initial value for the counter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2869} +\item\mdline{2869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{2869} + +%mdk-data-line={2870} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2870} +\item\mdline{2870}if \mdline{2870}\textbf{unset}\mdline{2870}: The counter entry\mdline{2870}'\mdline{2870}s value is not changed.%mdk + +%mdk-data-line={2871} +\item\mdline{2871}if \mdline{2871}\textbf{set}\mdline{2871}: The value provided by the client is written to the counter +entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2873} +\item\mdline{2873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2873} + +%mdk-data-line={2874} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2874} +\item\mdline{2874}if \mdline{2874}\textbf{unset}\mdline{2874}: The response does not include the counter entry\mdline{2874}'\mdline{2874}s value +(\mdline{2875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2875} is unset in the response).%mdk + +%mdk-data-line={2876} +\item\mdline{2876}if \mdline{2876}\textbf{set}\mdline{2876}: The response includes the counter entry\mdline{2876}'\mdline{2876}s value read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2879} +\noindent\mdline{2879}In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +\mdline{2881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2881} field unset when inserting \mdline{2881}\textbf{or modifying}\mdline{2881} a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the \mdline{2883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2883} message +(\mdline{2884}i.e.\mdline{2884} the \mdline{2884}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2884} field must be set to match the existing configuration).%mdk + +%mdk-data-line={2886} +\subsubsection{\mdline{2886}9.1.7.\hspace*{0.5em}\mdline{2886}Idle-timeout}\label{sec-idle-timeout}%mdk%mdk + +%mdk-data-line={2888} +\noindent\mdline{2888}P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not \mdline{2890}\textquotedblleft{}hit\textquotedblright{}\mdline{2890} (\mdline{2890}i.e.\mdline{2890} not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification\mdline{2892} \mdline{2892}\textemdash{}\mdline{2892} using the +\mdline{2893}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{2893} message\mdline{2893} \mdline{2893}\textemdash{}\mdline{2893} to the master client, which can then take +action, such as remove the idle table entry.%mdk + +%mdk-data-line={2896} +\mdline{2896}Two fields of the \mdline{2896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2896} Protobuf message are used to implement idle +timeout:%mdk + +%mdk-data-line={2899} +\begin{itemize}%mdk + +%mdk-data-line={2899} +\item{} +%mdk-data-line={2899} +\mdline{2899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2899}: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, \mdline{2900}i.e.\mdline{2900} no +\mdline{2901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{2901} message will ever be generated for this entry. When +a client reads a \mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2902}, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry.%mdk%mdk + +%mdk-data-line={2906} +\item{} +%mdk-data-line={2906} +\mdline{2906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2906}: a Protobuf message with a single field (\mdline{2906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{2906}) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The \mdline{2908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2908} field must be unset for a +\mdline{2909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2909} write. When reading a table entry, \mdline{2909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2909} must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2914} +\noindent\mdline{2914}These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an \mdline{2916}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2916} error code if at least one of these +conditions is met:%mdk + +%mdk-data-line={2919} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2919} +\item\mdline{2919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2919} is set to a non-zero value, or%mdk + +%mdk-data-line={2920} +\item\mdline{2920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2920} is set%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2922} +\noindent\mdline{2922}The target should do its best to approximate the \mdline{2922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2922} value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the \mdline{2925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2925} write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for \mdline{2927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2927}.%mdk + +%mdk-data-line={2929} +\mdline{2929}P4Runtime does not support idle timeout for default entries. When the +\mdline{2930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2930} flag is set in a \mdline{2930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2930} message, \mdline{2930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2930} +must be set to 0 (default) and \mdline{2931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2931} must be unset. If the +server receives a \mdline{2932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2932} message which violates this, it must return an +\mdline{2933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2933} error.%mdk + +%mdk-data-line={2935} +\mdline{2935}For more information about idle timeout, in particular regarding +\mdline{2936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{2936}, please refer to the\mdline{2936}~\mdref{sec-table-idle-timeout-notification}{Table idle timeout +notifications}\mdline{2937} section.%mdk + +%mdk-data-line={2939} +\subsection{\mdline{2939}9.2.\hspace*{0.5em}\mdline{2939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{2939} \mdline{2939}\&\mdline{2939} \mdline{2939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}\label{sec-action-profile-member-and-group}%mdk%mdk + +%mdk-data-line={2941} +\noindent\mdline{2941}P4Runtime defines an API for programming a PSA ActionProfile extern using +\mdline{2942}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{2942} messages. A PSA ActionSelector extern can be programmed +using both \mdline{2943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{2943} and \mdline{2943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{2943} messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table \mdline{2947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{2947} for L3 routing, implemented with an action +selector \mdline{2948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{2948}.%mdk + +%mdk-data-line={2950} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2951} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector(HashAlgorithm.crc32,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}size~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w1024,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}output\_width~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w10)~as;\\ +\\ +{\bfseries{\mdcolor{navy}action}}~set\_nhop(PortId\_t~p,~EthAddr~smac,~EthAddr~dmac)~\{\\ +~~istd.egress\_port~=~p;\\ +~~hdr.ethernet.smac~=~smac;\\ +~~hdr.ethernet.dmac~=~dmac;\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;~~{\mdcolor{darkgreen}//~LPM~on~destination~IP~address}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~set\_nhop;\\ +~~\}\\ +~~implementation~=~as;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2972} +\noindent\mdline{2972}When programming table \mdline{2972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{2972} in the example above, a P4Runtime client should +specify the \mdline{2973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{2973} in the \mdline{2973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2973} to be a reference to either an +action profile member or group. The reference is a \mdline{2974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{2974} identifier that +uniquely identifies a member or group programmed in the action selector \mdline{2975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{2975}.%mdk + +%mdk-data-line={2977} +\mdline{2977}If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata.%mdk + +%mdk-data-line={2982} +\mdline{2982}If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata.%mdk + +%mdk-data-line={2993} +\subsubsection{\mdline{2993}9.2.1.\hspace*{0.5em}\mdline{2993}Action Profile Member Programming}\label{sec-action-profile-member-programming}%mdk%mdk + +%mdk-data-line={2995} +\noindent\mdline{2995}Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a \mdline{2996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{2996} identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the \mdline{2998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{2998} +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the \mdline{3000}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3000} attributes of the +tables \mdline{3001}\emph{must have an identical list of P4 actions}\mdline{3001}. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector.%mdk + +%mdk-data-line={3005} +\mdline{3005}An \mdline{3005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3005} entity update message has the following fields:%mdk + +%mdk-data-line={3007} +\begin{itemize}%mdk + +%mdk-data-line={3007} +\item{} +%mdk-data-line={3007} +\mdline{3007}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3007} is the \mdline{3007}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3007} identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3010} +\item{} +%mdk-data-line={3010} +\mdline{3010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3010} is the \mdline{3010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3010} identifier of the action profile member entry being +updated.%mdk%mdk + +%mdk-data-line={3013} +\item{} +%mdk-data-line={3013} +\mdline{3013}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3013} is the specification of the P4 action instance bound to the action +profile member entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3016} +\noindent\mdline{3016}An action profile member may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3019} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3019} +\item\mdline{3019}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3019}: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an \mdline{3021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3021} error +code. The action specification must be provided, or the server must return +\mdline{3023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3023}. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return \mdline{3025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3025}.%mdk + +%mdk-data-line={3026} +\item\mdline{3026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3026}: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return \mdline{3027}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3027}, +and the action specification must be provided, or the server must return +\mdline{3029}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3029}.%mdk + +%mdk-data-line={3030} +\item\mdline{3030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3030}: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a \mdline{3031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3031} error code. The member +must not be part of an action profile group, or the server must return +\mdline{3033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3033}. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return \mdline{3036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3036}. \mdline{3036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3036} is the only field which is +considered when performing a \mdline{3037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3037} and every other field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3039} +\subsubsection{\mdline{3039}9.2.2.\hspace*{0.5em}\mdline{3039}Action Profile Group Programming}\label{sec-action-profile-group-programming}%mdk%mdk + +%mdk-data-line={3041} +\noindent\mdline{3041}Action profile groups are entries in an ActionSelector and are referenced by a +\mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3042} identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type.%mdk + +%mdk-data-line={3046} +\mdline{3046}An \mdline{3046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3046} entity update message has the following fields:%mdk + +%mdk-data-line={3048} +\begin{itemize}%mdk + +%mdk-data-line={3048} +\item{} +%mdk-data-line={3048} +\mdline{3048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3048} is the \mdline{3048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3048} identifier of the PSA ActionSelector +extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3051} +\item{} +%mdk-data-line={3051} +\mdline{3051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3051} is the \mdline{3051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3051} identifier of the action profile group entry being +updated.%mdk%mdk + +%mdk-data-line={3054} +\item{} +%mdk-data-line={3054} +\mdline{3054}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3054} is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields:%mdk + +%mdk-data-line={3057} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3057} +\item\mdline{3057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3057} for looking up the member table in the selector.%mdk + +%mdk-data-line={3058} +\item\mdline{3058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3058} specifying the probability of the member\mdline{3058}'\mdline{3058}s selection at +runtime. 0 is not a valid \mdline{3059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3059} value and the server must return +\mdline{3060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3060} if the client attempts to use it.%mdk + +%mdk-data-line={3061} +\item\mdline{3061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3061} is the controller-defined 32-bit port number that the member\mdline{3061}'\mdline{3061}s +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3065} +\item{} +%mdk-data-line={3065} +\mdline{3065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3065} is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +\mdline{3067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3067} update. See the subsection below for the\mdline{3067}~\mdref{sec-max-size-rules}{rules on setting +\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\mdline{3068}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3070} +\noindent\mdline{3070}An action profile group may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3073} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3073} +\item\mdline{3073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3073}: Add a new group entry bound to a set of existing action profile +members. \mdline{3074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}The~group\_id}}}\mdline{3074} must be different from ids of already programmed +groups for that selector, or the server must return an \mdline{3075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3075} error +code. All members specified in the group must exist in the selector, or the +server must return \mdline{3077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3077}. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target.%mdk + +%mdk-data-line={3079} +\item\mdline{3079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3079}: Modify the member set specification of an existing group entry. An +entry with the \mdline{3080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3080} must exist, or the server must return +\mdline{3081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3081}. All members specified in the group entry must exist in the +selector, or the server must return \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3082}. The value of \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3082} must +be identical to the value used when inserting the group, otherwise an +\mdline{3084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3084} error is returned.%mdk + +%mdk-data-line={3085} +\item\mdline{3085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3085}: Delete the group entry and deallocate the \mdline{3085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3085}. The group must +not be referenced in the table action of any table entry, or the server must +return a \mdline{3087}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3087} error code. If the \mdline{3087}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3087} is invalid, the +server must return \mdline{3088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3088}. \mdline{3088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3088} is the only field which is +considered when performing a \mdline{3089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3089} and every other field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3091} +\noindent\mdline{3091}When setting the group membership with \mdline{3091}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3091} or \mdline{3091}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3091}, the \mdline{3091}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3091} +repeated field must not include duplicates, \mdline{3092}i.e.\mdline{3092} members with the same +\mdline{3093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3093}. The \mdline{3093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3093} field is used instead to logically \mdline{3093}\textquotedblleft{}repeat\textquotedblright{}\mdline{3093} the member +inside the group.%mdk + +%mdk-data-line={3096} +\mdline{3096}It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation \mdline{3097}\textquotedblleft{}stores\textquotedblright{}\mdline{3097} the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made.%mdk + +%mdk-data-line={3101} +\paragraph{\mdline{3101}9.2.2.1.\hspace*{0.5em}\mdline{3101}Rules on Setting \mdline{3101}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\label{sec-max-size-rules}%mdk%mdk + +%mdk-data-line={3103} +\noindent\mdline{3103}The valid values for \mdline{3103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3103} depend on the static \mdline{3103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3103} included +in the P4Info message:%mdk + +%mdk-data-line={3106} +\begin{itemize}%mdk + +%mdk-data-line={3106} +\item{} +%mdk-data-line={3106} +\mdline{3106}If \mdline{3106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3106} is greater than 0, then \mdline{3106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3106} must be greater than 0, +and less than or equal to \mdline{3107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3107}. We assume that the target can +support selector groups for which the sum of all member weights is up to +\mdline{3109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3109}, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If \mdline{3110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3110} is greater than \mdline{3110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3110}, the server +must return \mdline{3111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3111}.%mdk%mdk + +%mdk-data-line={3113} +\item{} +%mdk-data-line={3113} +\mdline{3113}Otherwise (\mdline{3113}i.e.\mdline{3113} if \mdline{3113}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3113} is 0), the P4Runtime client can set +\mdline{3114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3114} to any value greater than or equal to 0.%mdk + +%mdk-data-line={3116} +\begin{itemize}%mdk + +%mdk-data-line={3116} +\item{} +%mdk-data-line={3116} +\mdline{3116}A \mdline{3116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3116} of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (\mdline{3119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3119} or \mdline{3119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3119}), the target must return a +\mdline{3120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3120} error.%mdk%mdk + +%mdk-data-line={3122} +\item{} +%mdk-data-line={3122} +\mdline{3122}If \mdline{3122}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3122} is greater than 0 and the value is not supported by the +target, the server must return a \mdline{3123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3123} error at +group-creation time.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3126} +\subsubsection{\mdline{3126}9.2.3.\hspace*{0.5em}\mdline{3126}One Shot Action Selector Programming}\label{sec-oneshot}%mdk%mdk + +%mdk-data-line={3128} +\noindent\mdline{3128}P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids.%mdk + +%mdk-data-line={3134} +\mdline{3134}One shots are programmed by choosing the \mdline{3134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3134} message as the +\mdline{3135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3135}. The \mdline{3135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3135} message consists of a set of +\mdline{3136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3136} messages, which in turn have the following fields:%mdk + +%mdk-data-line={3138} +\begin{itemize}%mdk + +%mdk-data-line={3138} +\item{} +%mdk-data-line={3138} +\mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3138} is one of the actions specified by the table that is being +programmed.%mdk%mdk + +%mdk-data-line={3141} +\item{} +%mdk-data-line={3141} +\mdline{3141}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3141} specifying the probability of the action\mdline{3141}'\mdline{3141}s selection at runtime. 0 is +not a valid \mdline{3142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3142} value and the server must return \mdline{3142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3142} if +the client attempts to use it. The sum of all weights across all +\mdline{3144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3144} messages for that \mdline{3144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3144} message must +not exceed the \mdline{3145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3145} specificed in the P4Info (if greater than 0), +or the server must return \mdline{3146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3146}.%mdk%mdk + +%mdk-data-line={3148} +\item{} +%mdk-data-line={3148} +\mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3148} is the controller-defined 32-bit port number that the action\mdline{3148}'\mdline{3148}s +liveness depends on. At runtime, the action must be excluded from selection if +the watch port is down.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3152} +\noindent\mdline{3152}Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics.%mdk + +%mdk-data-line={3157} +\mdline{3157}To preserve read-write symmetry, an implementation must answer \mdline{3157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3157}s +with the original one shot messages. It may not return a desugared version of +the one shot message.%mdk + +%mdk-data-line={3161} +\mdline{3161}For example, consider the action selector table defined +\mdline{3162}\mdref{sec-action-profile-member-and-group}{here}\mdline{3162}. This table could be programmed +with the following one shot update:%mdk + +%mdk-data-line={3165} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3166} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{\\ +~~~~action\_profile\_action\_set~\{\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}1}\\ +~~~~~~~~watch:~{\mdcolor{purple}1}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}2}\\ +~~~~~~~~watch:~{\mdcolor{purple}2}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}3}\\ +~~~~~~~~watch:~{\mdcolor{purple}3}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3191} +\noindent\mdline{3191}Which would be equivalent to the following updates, where \mdline{3191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GROUP\_ID}}}\mdline{3191}, +\mdline{3192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_1}}}\mdline{3192}, \mdline{3192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_2}}}\mdline{3192}, and \mdline{3192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_3}}}\mdline{3192} are unused ids:%mdk + +%mdk-data-line={3194} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3195} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_1\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_2\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_3\\ +~~action~\{~~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +\}\\ +action\_profile\_group~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~group\_id:~GROUP\_ID\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_1\\ +~~~~weight:~{\mdcolor{purple}1}\\ +~~~~watch:~{\mdcolor{purple}1}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_2\\ +~~~~weight:~{\mdcolor{purple}2}\\ +~~~~watch:~{\mdcolor{purple}2}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_3\\ +~~~~weight:~{\mdcolor{purple}3}\\ +~~~~watch:~{\mdcolor{purple}3}\\ +~~\}\\ +\}\\ +table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{~action\_profile\_group\_id:~GROUP\_ID~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3236} +\noindent\mdline{3236}Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure\mdline{3237}~\mdref{sec-batching-and-ordering-of-updates}{correct ordering between the dependent +updates}\mdline{3238}. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct \mdline{3240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3240} batches are required.%mdk + +%mdk-data-line={3242} +\mdline{3242}It is possible to include several \mdline{3242}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3242} messages with the same +exact \mdline{3243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3243} specification in one \mdline{3243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3243} message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the \mdline{3245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3245} field. Note that to preserve read-write symmetry, the server +must not coalesce multiple \mdline{3246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3246} messages with the same \mdline{3246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3246} +specification into one.%mdk + +%mdk-data-line={3249} +\mdline{3249}All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with \mdline{3250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3250} and +\mdline{3251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3251} messages. Programming some entries with one shots, and +other entries with \mdline{3252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3252} and \mdline{3252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3252} messages is +not allowed, and the server must return the error code \mdline{3253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3253} in +that case.%mdk + +%mdk-data-line={3256} +\mdline{3256}A P4Runtime server \mdline{3256}\emph{must}\mdline{3256} support the one shot style of programming tables with +an action selector implementation. Support for the \mdline{3257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3257} and +\mdline{3258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3258} style is \mdline{3258}\emph{optional}\mdline{3258}. If \mdline{3258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3258} and +\mdline{3259}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3259} are not supported by a server, it must return an +\mdline{3260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3260} error for every \mdline{3260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3260} or \mdline{3260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3260} +message that it receives.%mdk + +%mdk-data-line={3263} +\subsubsection{\mdline{3263}9.2.4.\hspace*{0.5em}\mdline{3263}Constraints on action selector programming}\label{sec-constraints-on-action-selector-programming}%mdk%mdk + +%mdk-data-line={3265} +\noindent\mdline{3265}The PSA specification states that the following features are \mdline{3265}\emph{optional}\mdline{3265} in +action selector implementations\mdline{3266}~[\mdcite{psaactionselector}{20}]\mdline{3266}:%mdk + +%mdk-data-line={3268} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3268} +\item\mdline{3268}Support for non-empty groups where in the same group, different members are +bound to different actions.%mdk + +%mdk-data-line={3270} +\item\mdline{3270}Predictable data plane behavior when a matched table entry points to an empty +group.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={3273} +\noindent\mdline{3273}For 1., if a client tries to \mdline{3273}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3273} or \mdline{3273}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3273} a group with members bound to +different actions, the server should return \mdline{3274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3274} if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return \mdline{3280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3280} (modifying the action parameter values must be +supported, however).%mdk + +%mdk-data-line={3283} +\mdline{3283}PSA 1.1 introduces the \mdline{3283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3283} table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. \mdline{3287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3287} is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of \mdline{3290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3290} at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +\mdline{3292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3292}. Even when \mdline{3292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3292} is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of \mdline{3296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3296} mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming.%mdk + +%mdk-data-line={3301} +\mdline{3301}The PSA specification includes a discussion on how to implement +\mdline{3302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3302} in software in the P4Runtime server +\mdline{3303}[\mdcite{psaemptygroupactionappendix}{23}]\mdline{3303}.%mdk + +%mdk-data-line={3305} +\subsection{\mdline{3305}9.3.\hspace*{0.5em}\mdline{3305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3305} \mdline{3305}\&\mdline{3305} \mdline{3305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-counterentry-directcounterentry}%mdk%mdk + +%mdk-data-line={3307} +\noindent\mdline{3307}PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The \mdline{3309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3309} +P4Runtime message can be used for all three types of PSA counters\mdline{3310} \mdline{3310}\textemdash{}\mdline{3310} \mdline{3310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{3310}, +\mdline{3311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{3311} and \mdline{3311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3311} \mdline{3311}\textemdash{}\mdline{3311} and consists of the following fields:%mdk + +%mdk-data-line={3313} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3313} +\item\mdline{3313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3313} is an \mdline{3313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3313}, corresponding to the number of octets.%mdk + +%mdk-data-line={3314} +\item\mdline{3314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3314} is an \mdline{3314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3314}, corresponding to the number of packets.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3316} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3317} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterData~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~byte\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}int64}}~packet\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3323} +\noindent\mdline{3323}P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of \mdline{3324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3324} and \mdline{3324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3324} fields, which +is equivalent to specifying the counter type \mdline{3325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3325}. Counters may +be defined as direct or indirect (indexed) instances.%mdk + +%mdk-data-line={3328} +\subsubsection{\mdline{3328}9.3.1.\hspace*{0.5em}\mdline{3328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-directcounterentry}%mdk%mdk + +%mdk-data-line={3330} +\noindent\mdline{3330}A direct counter is a direct resource associated with a \mdline{3330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3330} (see +\mdline{3331}\mdref{sec-direct-resources}{Direct Resources}\mdline{3331}). The \mdline{3331}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3331} field of the +\mdline{3332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3332} message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +\mdline{3335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3335} message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed.%mdk + +%mdk-data-line={3338} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3339} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectCounterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3345} +\noindent\mdline{3345}A \mdline{3345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3345} may only include an \mdline{3345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3345} message of type \mdline{3345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3345} with a +\mdline{3346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3346}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3348} +\begin{itemize}%mdk + +%mdk-data-line={3348} +\item{} +%mdk-data-line={3348} +\mdline{3348}the \mdline{3348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3348} field must match \mdline{3348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry.match}}}\mdline{3348} of the table entry +to which this direct counter entry is associated. If a matching \mdline{3349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3349} +is not found, the server returns the error code \mdline{3350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3350}.%mdk%mdk + +%mdk-data-line={3352} +\item{} +%mdk-data-line={3352} +\mdline{3352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3352} is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3356} +\noindent\mdline{3356}Specifying \mdline{3356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3356} in an \mdline{3356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3356} message of type \mdline{3356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3356} or +\mdline{3357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3357} is not allowed, and the server must return the error code +\mdline{3358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3358} in that case.%mdk + +%mdk-data-line={3360} +\mdline{3360}A client may use \mdline{3360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3360} in two ways to read the contents of a +\mdline{3361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3361}:%mdk + +%mdk-data-line={3363} +\begin{itemize}%mdk + +%mdk-data-line={3363} +\item{} +%mdk-data-line={3363} +\mdline{3363}As a direct resource associated with a table entry, request the server to +return the counter value in the \mdline{3364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3364} field of the \mdline{3364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3364} message +(see\mdline{3365}~\mdref{sec-direct-resources}{Direct resources}\mdline{3365}).%mdk%mdk + +%mdk-data-line={3367} +\item{} +%mdk-data-line={3367} +\mdline{3367}Explicitly request the counter value by including the \mdline{3367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3367} in +the \mdline{3368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3368}. The \mdline{3368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3368} field must match the \mdline{3368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3368} +whose counter is being read. If no such entry is found, the server returns the +error code \mdline{3370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3370}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3372} +\subsubsection{\mdline{3372}9.3.2.\hspace*{0.5em}\mdline{3372}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}\label{sec-counterentry}%mdk%mdk + +%mdk-data-line={3374} +\noindent\mdline{3374}An indirect or indexed counter is not associated with a specific \mdline{3374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3374} +and may be updated independently of any action. It may be read or written using +the P4Runtime \mdline{3376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3376} message whose fields are defined as follows:%mdk + +%mdk-data-line={3378} +\begin{itemize}%mdk + +%mdk-data-line={3378} +\item{} +%mdk-data-line={3378} +\mdline{3378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3378} is a \mdline{3378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3378}, the unique identifier for the counter.%mdk%mdk + +%mdk-data-line={3380} +\item{} +%mdk-data-line={3380} +\mdline{3380}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3380} is a Protobuf message that encapsulates an \mdline{3380}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3380}, used to index into +the counter array.%mdk%mdk + +%mdk-data-line={3383} +\item{} +%mdk-data-line={3383} +\mdline{3383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3383} is a Protobuf message of type \mdline{3383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3383}, which represents the +counter value.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3386} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3387} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~counter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3394} +\noindent\mdline{3394}The \mdline{3394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3394} can only be used in a \mdline{3394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3394} with the \mdline{3394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3394} update +type. The P4Runtime server must return an \mdline{3395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3395} error code for +update types \mdline{3396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3396} and \mdline{3396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3396}. By default all the counter entries in the +array have default value 0.%mdk + +%mdk-data-line={3399} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3399} +\item\mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3399}: Server returns the error code \mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3399}.%mdk + +%mdk-data-line={3400} +\item\mdline{3400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3400}: Modify an indirect counter instance whose unique id is \mdline{3400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3400} +and array index is specified by \mdline{3401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3401}. The counter value is set to the value +specified by the client in the \mdline{3402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3402} field. Note that the counter value is +not modified if this Protobuf field is not set. If \mdline{3403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3403} is omitted all +counter values in the array will be set to the value provided by the +client. The server must return \mdline{3405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3405} for a negative index value +and \mdline{3406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3406} if the index value exceeds the size of the counter array.%mdk + +%mdk-data-line={3407} +\item\mdline{3407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3407}: Server returns the error code \mdline{3407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3407}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3409} +\noindent\mdline{3409}A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a \mdline{3410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3410} by including a \mdline{3410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3410} +entity for each of the instances, specifying the \mdline{3411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3411} and +\mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3412}. Wildcard reads are also supported as follows.%mdk + +%mdk-data-line={3414} +\begin{itemize}%mdk + +%mdk-data-line={3414} +\item{} +%mdk-data-line={3414} +\mdline{3414}If the \mdline{3414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3414} field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the \mdline{3415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3415}.%mdk%mdk + +%mdk-data-line={3417} +\item{} +%mdk-data-line={3417} +\mdline{3417}If the \mdline{3417}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3417} field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id \mdline{3418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3418}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3420} +\subsection{\mdline{3420}9.4.\hspace*{0.5em}\mdline{3420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3420} \mdline{3420}\&\mdline{3420} \mdline{3420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-meterentry-directmeterentry}%mdk%mdk + +%mdk-data-line={3422} +\noindent\mdline{3422}Meters are an advanced mechanism for keeping statistics, involving stateful +\mdline{3423}\textquotedblleft{}marking\textquotedblright{}\mdline{3423} and usually \mdline{3423}\textquotedblleft{}throttling\textquotedblright{}\mdline{3423} of packets based on configured rates of +traffic. The PSA metering function is based on the \mdline{3424}\emph{Two Rate Three Color Marker}\mdline{3424} +(trTCM) defined in RFC 2698\mdline{3425}~[\mdcite{rfc2698}{2}]\mdline{3425}. The trTCM meters an arbitrary packet +stream using two configured rates\mdline{3426} \mdline{3426}\textemdash{}\mdline{3426} the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes\mdline{3427} \mdline{3427}\textemdash{}\mdline{3427} and +\mdline{3428}\textquotedblleft{}marks\textquotedblright{}\mdline{3428} its packets as GREEN, YELLOW or RED based on the observed rate.%mdk + +%mdk-data-line={3430} +\mdline{3430}A meter may be configured as a direct or indirect instance, similar to a +counter. The \mdline{3431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{3431} P4Runtime message represents meter configuration.%mdk + +%mdk-data-line={3433} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3434} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterConfig~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~cir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~Committed~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~cburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};~~{\mdcolor{darkgreen}//~Committed~Burst~Size}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};~~{\mdcolor{darkgreen}//~Peak~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};~~{\mdcolor{darkgreen}//~Peak~Burst~Size}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3442} +\subsubsection{\mdline{3442}9.4.1.\hspace*{0.5em}\mdline{3442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-directmeterentry}%mdk%mdk + +%mdk-data-line={3444} +\noindent\mdline{3444}A direct meter is a direct resource associated with a \mdline{3444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3444} (see\mdline{3444}~\mdref{sec-direct-resources}{Direct +resources}\mdline{3445}). The \mdline{3445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3445} field of the \mdline{3445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3445} +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +\mdline{3449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3449} message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed.%mdk + +%mdk-data-line={3452} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3453} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectMeterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3459} +\noindent\mdline{3459}A \mdline{3459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3459} may only include an \mdline{3459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3459} message of type \mdline{3459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3459} with a +\mdline{3460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3460}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3462} +\begin{itemize}%mdk + +%mdk-data-line={3462} +\item{} +%mdk-data-line={3462} +\mdline{3462}the \mdline{3462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3462} field must match the match key of the \mdline{3462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3462} +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching \mdline{3464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3464} is not found, +the server returns the error code \mdline{3465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3465}.%mdk%mdk + +%mdk-data-line={3467} +\item{} +%mdk-data-line={3467} +\mdline{3467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3467} is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3471} +\noindent\mdline{3471}Specifying \mdline{3471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3471} in an \mdline{3471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3471} message of type \mdline{3471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3471} or +\mdline{3472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3472} is not allowed, and the server must return the error code +\mdline{3473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3473} in that case.%mdk + +%mdk-data-line={3475} +\mdline{3475}A client may use \mdline{3475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3475} in two ways to read a \mdline{3475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3475} config.%mdk + +%mdk-data-line={3477} +\begin{itemize}%mdk + +%mdk-data-line={3477} +\item{} +%mdk-data-line={3477} +\mdline{3477}As a direct resource associated with a table entry, request the server to +return the meter config in the \mdline{3478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3478} field of the \mdline{3478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3478} +message (see\mdline{3479}~\mdref{sec-direct-resources}{Direct resources}\mdline{3479}).%mdk%mdk + +%mdk-data-line={3481} +\item{} +%mdk-data-line={3481} +\mdline{3481}Explicitly request the meter configuration by including the \mdline{3481}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3481} +in the \mdline{3482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3482}. The \mdline{3482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3482} field must match the +\mdline{3483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3483} whose meter config is being read. If no such entry is found, the +server returns the error code \mdline{3484}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3484}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3486} +\subsubsection{\mdline{3486}9.4.2.\hspace*{0.5em}\mdline{3486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}\label{sec-meterentry}%mdk%mdk + +%mdk-data-line={3488} +\noindent\mdline{3488}An indirect or indexed meter is not associated with a specific \mdline{3488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3488} and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime \mdline{3490}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3490} message whose fields are defined as +follows:%mdk + +%mdk-data-line={3493} +\begin{itemize}%mdk + +%mdk-data-line={3493} +\item{} +%mdk-data-line={3493} +\mdline{3493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3493} is a \mdline{3493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3493}, the unique identifier for the meter.%mdk%mdk + +%mdk-data-line={3495} +\item{} +%mdk-data-line={3495} +\mdline{3495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3495} is a Protobuf message that encapsulates an \mdline{3495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3495}, used to index into +a meter array.%mdk%mdk + +%mdk-data-line={3498} +\item{} +%mdk-data-line={3498} +\mdline{3498}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3498} is a Protobuf message of type \mdline{3498}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{3498}, which represents the +meter configuration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3501} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3502} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~meter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3509} +\noindent\mdline{3509}The \mdline{3509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3509} can only be used in a \mdline{3509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3509} with the \mdline{3509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3509} update +type. The P4Runtime server must return an \mdline{3510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3510} error code for +update types \mdline{3511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3511} and \mdline{3511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3511}. By default all the meter entries in the +array have a default configuration (GREEN for all packets).%mdk + +%mdk-data-line={3514} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3514} +\item\mdline{3514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3514}: Server returns the error code \mdline{3514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3514}.%mdk + +%mdk-data-line={3515} +\item\mdline{3515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3515}: Modify an indirect meter instance whose unique id is \mdline{3515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3515} and +array index is specified by \mdline{3516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3516}. The meter is reconfigured using the +\mdline{3517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3517} field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the \mdline{3519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3519} field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if \mdline{3521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3521} is unset). The server must return \mdline{3521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3521} for a +negative index value and \mdline{3522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3522} if the index value exceeds the size of +the meter array.%mdk + +%mdk-data-line={3524} +\item\mdline{3524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3524}: Server returns the error code \mdline{3524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3524}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3526} +\noindent\mdline{3526}A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a \mdline{3527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3527} by including a \mdline{3527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3527} entity for each +of the instances, specifying the \mdline{3528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3528} and \mdline{3528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3528}. Wildcard reads are also +supported as follows:%mdk + +%mdk-data-line={3531} +\begin{itemize}%mdk + +%mdk-data-line={3531} +\item{} +%mdk-data-line={3531} +\mdline{3531}If the \mdline{3531}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3531} field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the \mdline{3532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3532}.%mdk%mdk + +%mdk-data-line={3534} +\item{} +%mdk-data-line={3534} +\mdline{3534}If the \mdline{3534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3534} field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id \mdline{3535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3535}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3537} +\subsection{\mdline{3537}9.5.\hspace*{0.5em}\mdline{3537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}\label{sec-packetreplicationengineentry}%mdk%mdk + +%mdk-data-line={3539} +\noindent\mdline{3539}The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets.%mdk + +%mdk-data-line={3545} +\subsubsection{\mdline{3545}9.5.1.\hspace*{0.5em}\mdline{3545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}\label{sec-multicastgroupentry}%mdk%mdk + +%mdk-data-line={3547} +\noindent\mdline{3547}Multicasting is achieved in PSA programs by setting the \mdline{3547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{3547} +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the \mdline{3550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{3550} API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example.%mdk + +%mdk-data-line={3555} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3556} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~arp\_multicast({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ethernet.isValid()~\&\&\\ +~~~~~~~~hdr.ethernet.eth\_type~==~ETH\_TYPE\_ARP)~\{\\ +~~~~~~smeta.multicast\_group~=~(MulticastGroup\_t)~{\mdcolor{purple}1};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3566} +\noindent\mdline{3566}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={3569} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3570} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~multicast\_group\_entry~\{\\ +~~~~~~multicast\_group\_id:~{\mdcolor{purple}1}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}5}~instance:~{\mdcolor{purple}1}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}12}~instance:~{\mdcolor{purple}2}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}18}~instance:~{\mdcolor{purple}3}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}24}~instance:~{\mdcolor{purple}4}~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3584} +\noindent\mdline{3584}As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +\mdline{3589}\mdref{sec-translation-of-port-numbers}{PSA Metadata Translation}\mdline{3589} section.%mdk + +%mdk-data-line={3591} +\mdline{3591}The egress packets may be distinguished for further processing in the egress +using the \mdline{3592}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{3592} metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 \mdline{3594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{3594} metadata is set to a value that is not +programmed in the PRE, then the packet is dropped.%mdk + +%mdk-data-line={3597} +\mdline{3597}A multicast group may be inserted, modified or deleted as per the following +semantics.%mdk + +%mdk-data-line={3600} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3600} +\item\mdline{3600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3600}: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The \mdline{3601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3601} field is a \mdline{3601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3601} and must not exceed +the maximum value supported by the target. The PSA specification states that 0 +is a special value which indicates that no multicast replication is to be +performed for a packet\mdline{3604}~[\mdcite{psatranslation}{22}]\mdline{3604}. Therefore \mdline{3604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3604} must +never be set to 0. If one of these constraints is violated, the P4Runtime +server must return an \mdline{3606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3606} error. The replica \mdline{3606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{3606} ID is +also a \mdline{3607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3607}, and its value may not exceed the maximum allowed by the +target for the \mdline{3608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{3608} type (0 is allowed), or the server must +return an \mdline{3609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3609} error. The egress port must be a 32-bit SDN port +number and must refer to a singleton port. No two replicas may have identical +values of \mdline{3611}\emph{both}\mdline{3611} \mdline{3611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{3611} and \mdline{3611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{3611}, or the server must return +\mdline{3612}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3612}.%mdk + +%mdk-data-line={3613} +\item\mdline{3613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3613}: Modify the set of replicas for a given multicast group entry, +indexed by the given \mdline{3614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3614}. Same restrictions as \mdline{3614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3614} apply +here.%mdk + +%mdk-data-line={3616} +\item\mdline{3616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3616}: Delete the multicast group indexed by the given +\mdline{3617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3617}. The replicas need not be provided for this +operation. Any packets with their \mdline{3618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{3618} metadata in the data plane +set to the deleted \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3619} will be dropped.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3621} +\subsubsection{\mdline{3621}9.5.2.\hspace*{0.5em}\mdline{3621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}\label{sec-clonesessionentry}%mdk%mdk + +%mdk-data-line={3623} +\noindent\mdline{3623}PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +\mdline{3627}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3627} identifier and a boolean flag \mdline{3627}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone}}}\mdline{3627} in the packet +metadata. The \mdline{3628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3628} serves as a handle to the clone attributes, +namely a set \mdline{3629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}replicas}}}\mdline{3629} of \mdline{3629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(egress~port,~instance)}}}\mdline{3629} pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +\mdline{3632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{3632} API.%mdk + +%mdk-data-line={3634} +\mdline{3634}The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the \mdline{3637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_low\_ttl}}}\mdline{3637} control block is applied in the ingress +pipeline to create an ingress-to-egress clone.%mdk + +%mdk-data-line={3640} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3641} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~clone\_low\_ttl({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ipv4.isValid()~\&\&\\ +~~~~~~~~hdr.ipv4.ttl~\textless{}=~LOW\_TTL\_THRESHOLD)~\{\\ +~~~~~~smeta.clone\_session\_id~=~{\mdcolor{purple}10}w100;\\ +~~~~~~smeta.clone~=~{\bfseries{\mdcolor{navy}true}};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3653} +\noindent\mdline{3653}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={3656} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3657} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~clone\_session\_entry~\{\\ +~~~~~~session\_id:~{\mdcolor{purple}100}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}0xfffffffd}~instance:~{\mdcolor{purple}1}~\}~{\mdcolor{darkgreen}\#~to~CPU}\\ +~~~~~~class\_of\_service:~{\mdcolor{purple}2}\\ +~~~~~~packet\_length\_bytes:~{\mdcolor{purple}4096}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3670} +\noindent\mdline{3670}As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type \mdline{3674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{3674}~[\mdcite{psatranslation}{22}]\mdline{3674}). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes.%mdk + +%mdk-data-line={3679} +\mdline{3679}The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port \mdline{3680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfffffffd}}}\mdline{3680}; see +\mdline{3681}\mdref{sec-translation-of-port-numbers}{Translation of Port Numbers}\mdline{3681}). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port.%mdk + +%mdk-data-line={3684} +\mdline{3684}If the \mdline{3684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3684} data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created.%mdk + +%mdk-data-line={3687} +\mdline{3687}A clone session may be inserted, modified or deleted as per the following +semantics:%mdk + +%mdk-data-line={3690} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3690} +\item\mdline{3690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3690}: Add a new clone session entry bound to a set of egress ports and +replica IDs. The \mdline{3691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{3691} is a \mdline{3691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3691}, must be unique across all clone +session entries, and its value may not exceed the maximum supported by the +target (0 is allowed), or the P4Runtime server must return an +\mdline{3694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3694} error. The replica \mdline{3694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{3694} ID is also a \mdline{3694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3694}, and +its value may not exceed the maximum allowed by the target for the +\mdline{3696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{3696} type (0 is allowed), or the server must also return an +\mdline{3697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3697} error. The egress port in the replica must be a 32-bit SDN +port number and must refer to a singleton port. The class of service for each +clone packet instance will be set to the value programmed in the clone session +entry (\mdline{3700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}class\_of\_service}}}\mdline{3700} field). This value must be a valid value for the PSA +\mdline{3701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{3701} type, which supports runtime translation by default +\mdline{3702}[\mdcite{psatranslation}{22}]\mdline{3702}, or the server must return \mdline{3702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3702}. See\mdline{3702}~\mdref{sec-translation-of-port-numbers}{PSA +Metadata Translation}\mdline{3703} for more +information. The \mdline{3704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{3704} field must be set to a non-zero value +if the clone packet should be truncated to the given value (in bytes). If the +\mdline{3706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{3706} field is 0 (default), no truncation on the clone will be +performed.%mdk + +%mdk-data-line={3708} +\item\mdline{3708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3708}: Modify the attributes of a given clone session entry, indexed by the +given \mdline{3709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3709}. Same restrictions as \mdline{3709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3709} apply here.%mdk + +%mdk-data-line={3710} +\item\mdline{3710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3710}: Delete the clone session indexed by the given +\mdline{3711}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3711}. Other fields need not be provided for this operation. Any +packet with their \mdline{3712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3712} metadata in the data plane set to the +deleted \mdline{3713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{3713} will no longer be cloned.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3715} +\subsection{\mdline{3715}9.6.\hspace*{0.5em}\mdline{3715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}\label{sec-valuesetentry}%mdk%mdk + +%mdk-data-line={3717} +\noindent\mdline{3717}Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL ethtypes is used to +transition the parser state machine to the \mdline{3721}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{3721} state.%mdk + +%mdk-data-line={3723} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3724} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}state}}~parse\_l2~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}(MAX\_TRILL\_TYPES)~trill\_types;}\\ +~~extract(hdr.ethernet);\\ +~~{\bfseries{\mdcolor{navy}select}}~(hdr.ethernet.eth\_type)~\{\\ +~~~~ETH\_TYPE\_IPV4:~parse\_ipv4;\\ +~~~~ETH\_TYPE\_IPV6:~parse\_ipv6;\\ +~~~~trill\_types:~~~parse\_trill\_types;\\ +~~~~\_:~~~~~~~~~~~~~reject;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3736} +\noindent\mdline{3736}The corresponding entry in the P4Info for this Value Set is:%mdk + +%mdk-data-line={3738} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3739} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}trill\_types}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~\textless{}MAX\_TRILL\_TYPES\textgreater{}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3753} +\noindent\mdline{3753}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={3756} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3757} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x22f3}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x893b}~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3775} +\noindent\mdline{3775}As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the \mdline{3777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{3777} state.%mdk + +%mdk-data-line={3779} +\mdline{3779}A \mdline{3779}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{3779} entity update message has the following fields:%mdk + +%mdk-data-line={3781} +\begin{itemize}%mdk + +%mdk-data-line={3781} +\item{} +%mdk-data-line={3781} +\mdline{3781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{3781} is the \mdline{3781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3781} identifier of the Value Set instance, as +defined in P4Info.%mdk%mdk + +%mdk-data-line={3784} +\item{} +%mdk-data-line={3784} +\mdline{3784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3784} is a repeated field of type \mdline{3784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{3784}. When \mdline{3784}\textquotedblleft{}selecting\textquotedblright{}\mdline{3784} +against a Value Set, every member will be considered and if at least one +\mdline{3786}\textquotedblleft{}matches\textquotedblright{}\mdline{3786}, the corresponding parser transition will be taken. Each +\mdline{3787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{3787} contains a repeated field of \mdline{3787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3787} messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a \mdline{3789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{3789} if and only if +it matches all its \mdline{3790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3790} messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. \mdline{3792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3792} messages in a \mdline{3792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{3792} follow +the\mdline{3793}~\mdref{sec-match-format}{same rules}\mdline{3793} as in a \mdline{3793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3793}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3795} +\noindent\mdline{3795}A \mdline{3795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{3795} may only be modified. If the update type is \mdline{3795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3795} or +\mdline{3796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3796}, the server must return an \mdline{3796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3796} error. If the update type +is \mdline{3797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3797}, the server writes the members given in the repeated field to the +Value Set entry indexed by the given \mdline{3798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{3798}. The maximum number of +matches must not exceed the maximum size given by the \mdline{3799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{3799} field in P4Info of +the Value Set, otherwise the server must return a \mdline{3800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3800} error. To +empty a Value Set (\mdline{3801}i.e.\mdline{3801} restore it to its initial state), the P4Runtime client +can perform a \mdline{3802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3802} update with an empty \mdline{3802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3802} repeated field.%mdk + +%mdk-data-line={3804} +\mdline{3804}To facilitate\mdline{3804}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{3804}, the server must +return an \mdline{3805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3805} error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary and range matches: +overlapping entries do not need to be ordered and the parse state transition +is determined by whether or not the packet matches at least one entry in the +set.%mdk + +%mdk-data-line={3811} +\mdline{3811}See Appendix\mdline{3811}~\mdref{sec-value-set-example}{A.2}\mdline{3811} for a more complex Value Set example.%mdk + +%mdk-data-line={3813} +\subsection{\mdline{3813}9.7.\hspace*{0.5em}\mdline{3813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}\label{sec-registerentry}%mdk%mdk + +%mdk-data-line={3815} +\noindent\mdline{3815}The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The \mdline{3816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3816} P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations.%mdk + +%mdk-data-line={3820} +\mdline{3820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3820} has the following fields:%mdk + +%mdk-data-line={3822} +\begin{itemize}%mdk + +%mdk-data-line={3822} +\item{} +%mdk-data-line={3822} +\mdline{3822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{3822}, which identifies the PSA Register extern instance which is +being accessed by the client; the \mdline{3823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{3823} is specified by the P4Info +message.%mdk%mdk + +%mdk-data-line={3826} +\item{} +%mdk-data-line={3826} +\mdline{3826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3826}, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the \mdline{3828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3828} message +used for the request. When an \mdline{3829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3829} is provided , the server must validate +its value, and return \mdline{3830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3830} for a negative index or +\mdline{3831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3831} if the index exceeds the size of the register array.%mdk%mdk + +%mdk-data-line={3833} +\item{} +%mdk-data-line={3833} +\mdline{3833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3833}: the data to be written to the array (if \mdline{3833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3833} is part of a +\mdline{3834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3834} message) or the data read from the array (if \mdline{3834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3834} is +part of a \mdline{3835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3835} message). The \mdline{3835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3835} field is a \mdline{3835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{3835} message and +must match the format described by the \mdline{3836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{3836} field of the corresponding +Register entry in the P4Info, or the server must return an \mdline{3837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3837} +error.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3840} +\subsection{\mdline{3840}9.8.\hspace*{0.5em}\mdline{3840}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}\label{sec-digestentry}%mdk%mdk + +%mdk-data-line={3842} +\noindent\mdline{3842}A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly.%mdk + +%mdk-data-line={3847} +\mdline{3847}The \mdline{3847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{3847} P4Runtime entity is used to \mdline{3847}\textbf{configure}\mdline{3847} how the device must +generate digest messages. The \mdline{3848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{3848} Protobuf message is not used to +carry digest data, which is done on the \mdline{3849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{3849} bidirectional stream +using the \mdline{3850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{3850} (digest data sent by the target to the client) and +\mdline{3851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{3851} (digest data acknowledgments sent by the client to the target) +Protobuf messages.%mdk + +%mdk-data-line={3854} +\mdline{3854}In this section, we refer to the data learned by a single data plane call to +\mdline{3855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}T\textgreater{}::pack}}}\mdline{3855} as a \mdline{3855}\textquotedblleft{}digest message\textquotedblright{}\mdline{3855} and we use \mdline{3855}\textquotedblleft{}digest list\textquotedblright{}\mdline{3855} to designate +the list of digest messages bundled by the P4Runtime service in a single +\mdline{3857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{3857} stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are \mdline{3859}\textquotedblleft{}duplicate\textquotedblright{}\mdline{3859} if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are \mdline{3860}\textquotedblleft{}distinct\textquotedblright{}\mdline{3860} +if they are not duplicate.%mdk + +%mdk-data-line={3863} +\mdline{3863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{3863} has the following fields:%mdk + +%mdk-data-line={3865} +\begin{itemize}%mdk + +%mdk-data-line={3865} +\item{} +%mdk-data-line={3865} +\mdline{3865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{3865}, which identifies the PSA Digest extern instance which emitted the +data; the \mdline{3866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{3866} is determined by the P4Info message.%mdk%mdk + +%mdk-data-line={3868} +\item{} +%mdk-data-line={3868} +\mdline{3868}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3868}, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +\mdline{3870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{3870}; these parameters are:%mdk + +%mdk-data-line={3872} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3872} +\item\mdline{3872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{3872}: the maximum server buffering delay in nanoseconds for an +outstanding digest message.%mdk + +%mdk-data-line={3874} +\item\mdline{3874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{3874}: the maximum digest list size\mdline{3874} \mdline{3874}\textemdash{}\mdline{3874} in number of digest +messages\mdline{3875} \mdline{3875}\textemdash{}\mdline{3875} sent by the server to the client as a single \mdline{3875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{3875} +Protobuf message.%mdk + +%mdk-data-line={3877} +\item\mdline{3877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{3877}: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3881} +\noindent\mdline{3881}Here is the significance of the different \mdline{3881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3881} types for \mdline{3881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{3881}:%mdk + +%mdk-data-line={3883} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3883} +\item\mdline{3883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3883}: Enable server generation of \mdline{3883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{3883} messages for given digest +instance and use provided configuration parameters.%mdk + +%mdk-data-line={3885} +\item\mdline{3885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3885}: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance.%mdk + +%mdk-data-line={3887} +\item\mdline{3887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3887}: Disable server generation of \mdline{3887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{3887} messages for given digest +instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3890} +\noindent\mdline{3890}A server should buffer digest messages until either:%mdk + +%mdk-data-line={3892} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3892} +\item\mdline{3892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{3892} time has passed since the first digest message was added to +the empty buffer, or%mdk + +%mdk-data-line={3894} +\item\mdline{3894}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{3894} \mdline{3894}\emph{distinct}\mdline{3894} digest messages have been received from the +data plane and added to the buffer%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3897} +\noindent\mdline{3897}At which point the server should, with best effort, generate a \mdline{3897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{3897} +stream message with the buffer contents and send it to the master client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software.%mdk + +%mdk-data-line={3903} +\mdline{3903}To avoid sending duplicate digest messages across different \mdline{3903}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{3903} +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the master client indicates that it has received the +digest list and acted on it. The server must keep a \mdline{3906}\textquotedblleft{}cache\textquotedblright{}\mdline{3906} containing the set +of all digest messages that have been sent, but not acknowledged yet by the +master client, up-to \mdline{3908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{3908} in the past. The server must delete all +cache entries for a given digest list when they are at least \mdline{3909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{3909} +old or when a matching \mdline{3910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{3910} message (\mdline{3910}i.e.\mdline{3910} with the same \mdline{3910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{3910} +and \mdline{3911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}list\_id}}}\mdline{3911} fields as the \mdline{3911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{3911} message) is received.%mdk + +%mdk-data-line={3913} +\mdline{3913}The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged \mdline{3918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{3918} messages.%mdk + +%mdk-data-line={3920} +\mdline{3920}When \mdline{3920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{3920} is set to 0 and / or \mdline{3920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{3920} is set to 1, the +server should, with best effort, generate a \mdline{3921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{3921} message for every +digest message generated by the data plane which is not already in the cache. If +\mdline{3923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{3923} is set to 0, the cache must always be an empty set. If +\mdline{3924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{3924} is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +\mdline{3926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{3926} configuration parameter.%mdk + +%mdk-data-line={3928} +\mdline{3928}The P4Runtime server may empty the digest message cache in case of a client +mastership change.%mdk + +%mdk-data-line={3931} +\mdline{3931}Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server:%mdk + +%mdk-data-line={3934} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3935} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestStream~stream;\\ +DigestCache~cache;\\ +DigestBuffer~buffers;\\ +\\ +{\mdcolor{darkgreen}//~sends~digest~list~when~it~is~ready}\\ +send\_buffer(Id~digest\_id)~\{\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~stream.write(DigestList(buffer));\\ +~~cache.merge(buffer);~~{\mdcolor{darkgreen}//~updates~cache~with~new~digest~list}\\ +~~buffer.clear();\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~data~plane~digest~messages~from~device}\\ +handle\_dataplane\_digest(Digest~msg)~\{\\ +~~digest\_id~=~msg.digest\_id();\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~{\bfseries{\mdcolor{navy}if}}~(msg~in~cache~{\mdcolor{teal}OR}~msg~in~buffer)~{\bfseries{\mdcolor{navy}return}};\\ +~~buffer.enqueue(msg);\\ +~~{\bfseries{\mdcolor{navy}if}}~(buffer.length()~\textless{}~max\_list\_size(digest\_id))~{\bfseries{\mdcolor{navy}return}};\\ +~~send\_buffer(digest\_id);\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~ack~messages~received~on~the~stream}\\ +handle\_stream\_ack(DigestListAck~ack)~\{\\ +~~{\mdcolor{darkgreen}//~clear~all~cache~entries~matching~the~tuple~(digest\_id,~list\_id)}\\ +~~cache.erase(~(ack.digest\_id(),~ack.list\_id()~)\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~loop~to~enforce~timeouts}\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~now~=~now();\\ +~~{\mdcolor{darkgreen}//~check~for~buffers~that~need~to~be~sent}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~buffer)~in~buffers)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~buffer.first\_enq\_time()~\textgreater{}=~max\_timeout\_ns(digest\_id))\\ +~~~~~~send\_buffer(buffer\_id);\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~check~for~expired~entries~in~cache}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~list\_id,~sent\_time)~in~cache)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~sent\_time~\textgreater{}=~ack\_timeout\_ns(digest\_id))\\ +~~~~~~cache.erase(~(digest\_id,~list\_id)~);\\ +~~\}\\ +~~sleep({\mdcolor{teal}X});\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3980} +\subsection{\mdline{3980}9.9.\hspace*{0.5em}\mdline{3980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\label{sec-extern-entry}%mdk%mdk + +%mdk-data-line={3982} +\noindent\mdline{3982}This is used to support a P4 extern entity that is not part of PSA. It is +defined as:%mdk + +%mdk-data-line={3985} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3986} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ExternEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_type\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~google.protobuf.Any~entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3993} +\noindent\mdline{3993}Each \mdline{3993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{3993} entity maps to an \mdline{3993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{3993} message in the +\mdline{3994}\mdref{sec-p4info-extern}{P4Info}\mdline{3994} and an \mdline{3994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{3994} message within that +message. The \mdline{3995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{3995} field must be equal to the one in +\mdline{3996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{3996}. The \mdline{3996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_id}}}\mdline{3996} field must be equal to the ID included in the +\mdline{3997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{3997} of the corresponding \mdline{3997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{3997} message.%mdk + +%mdk-data-line={3999} +\mdline{3999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entry}}}\mdline{3999} itself is embedded as an \mdline{3999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{3999} Protobuf message\mdline{3999}~[\mdcite{protoany}{28}]\mdline{3999} to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on\mdline{4003}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{4004} for more information.%mdk + +%mdk-data-line={4006} +\section{\mdline{4006}10.\hspace*{0.5em}\mdline{4006}Error Reporting Messages}\label{sec-error-reporting-messages}%mdk%mdk + +%mdk-data-line={4008} +\noindent\mdline{4008}P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case.%mdk + +%mdk-data-line={4012} +\mdline{4012}gRPC uses \mdline{4012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4012}~[\mdcite{grpcstatus}{29}]\mdline{4012} to represent the status returned by an +RPC. It has 3 attributes:%mdk + +%mdk-data-line={4015} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4016} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StatusCode~code\_;\\ +{\mdcolor{navy}grpc::}string~error\_message\_;\\ +{\mdcolor{navy}grpc::}string~binary\_error\_details\_;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4021} +\noindent\mdline{4021}The \mdline{4021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4021} represents a canonical error\mdline{4021}~[\mdcite{grpcstatuscodes}{31}]\mdline{4021} and describes the +overall RPC status. The \mdline{4022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4022} is a developer-facing error message, +which should be in English. The \mdline{4023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}binary\_error\_details\_}}}\mdline{4023} carries a serialized +\mdline{4024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4024} message\mdline{4024}~[\mdcite{protostatus}{26}]\mdline{4024} message, which has 3 fields:%mdk + +%mdk-data-line={4026} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4027} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}int32}}~code~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~see~code.proto}\\ +{\bfseries{\mdcolor{navy}string}}~{\bfseries{\mdcolor{navy}message}}~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +{\bfseries{\mdcolor{navy}repeated}}~google.protobuf.Any~details~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4032} +\noindent\mdline{4032}The code and message fields must be the same as \mdline{4032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4032} and \mdline{4032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4032} +fields from \mdline{4033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4033} above. The \mdline{4033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{4033} field is a list that consists of +\mdline{4034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4034} messages that carry error details for individual elements inside +batch-request RPCs (\mdline{4035}e.g.\mdline{4035} \mdline{4035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4035} and \mdline{4035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4035}). \mdline{4035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4035} includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices\mdline{4039}~[\mdcite{grpcstatuscodes}{31}]\mdline{4039}.%mdk + +%mdk-data-line={4041} +\mdline{4041}Figure\mdline{4041}~\mdref{fig-error-report}{\mdcaptionlabel{7}}\mdline{4041} illustrates how these messages fit together.%mdk + +%mdk-data-line={4043} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={4044} +\noindent\mdline{4044}\includegraphics[keepaspectratio=true,width=\dimwidth{0.70}]{build/error-report}{}\mdline{4044}%mdk + +%mdk-data-line={4045} +\mdhr{}%mdk + +%mdk-data-line={4046} +\noindent\mdline{4046}\mdcaption{\textbf{Figure~\mdcaptionlabel{7}.}~\mdcaptiontext{P4Runtime Error Report Message Format}}%mdk +%mdk +\end{mdcenter}\label{fig-error-report}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={4048} +\noindent\mdline{4048}gRPC provides utility functions \mdline{4048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExtractErrorDetails()}}}\mdline{4048} and \mdline{4048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetErrorDetails()}}}\mdline{4048} +\mdline{4049}[\mdcite{grpcerrordetails}{30}]\mdline{4049} to easily convert between \mdline{4049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4049} and +\mdline{4050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4050}.%mdk + +%mdk-data-line={4052} +\mdline{4052}Please see sections on individual P4Runtime RPCs for details on how +\mdline{4053}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4053} is populated for reporting errors.%mdk + +%mdk-data-line={4055} +\section{\mdline{4055}11.\hspace*{0.5em}\mdline{4055}Atomicity of Individual \mdline{4055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4055} and \mdline{4055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4055} Operations}\label{sec-atomicity-of-individual-write-and-read-operations}%mdk%mdk + +%mdk-data-line={4057} +\noindent\mdline{4057}Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane \mdline{4058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4058} +operation, and every single \mdline{4059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4059} operation on a table that inserts, deletes, +or modifies one table entry, the \mdline{4060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4060} operation should behave as if that +\mdline{4061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4061} operation has not yet occurred, or as if the \mdline{4061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4061} operation is +complete. The P4 program should never behave as if the \mdline{4062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4062} operation is +partially complete. These guarantees also apply to extern instances: \mdline{4063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4063} and +\mdline{4064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4064} operations on extern entities must execute atomically relative to extern +data plane methods.%mdk + +%mdk-data-line={4067} +\mdline{4067}The atomicity guarantees provided by P4Runtime for individual \mdline{4067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4067} and \mdline{4067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4067} +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification\mdline{4069}~[\mdcite{psaatomicityofcontrolplaneops}{21}]\mdline{4069}.%mdk + +%mdk-data-line={4071} +\mdline{4071}The P4\mdline{4071}\mdsub{16}\mdline{4071} language introduces an \mdline{4071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4071} annotation\mdline{4071}~[\mdcite{p4concurrency}{13}]\mdline{4071}, to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the \mdline{4073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4073} annotation for \mdline{4073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4073} +operations, as well as\mdline{4074}~\mdref{wildcard-reads}{non-wildcard \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} operations}\mdline{4074}, +relative to data plane execution. Consider the following P4 example written for +PSA:%mdk + +%mdk-data-line={4078} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4079} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024)~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\mdcolor{darkgreen}//~...}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~Value\_t~v~=~r1.read((Index\_t){\mdcolor{purple}1});\\ +~~~~~~~~v~=~v~+~{\mdcolor{purple}1};\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~v);\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4095} +\noindent\mdline{4095}If a P4Runtime server is processing messages which write to Register \mdline{4095}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4095} at +index \mdline{4096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}1}}}\mdline{4096}, these writes must not happen between the data plane \mdline{4096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}read}}}\mdline{4096} and +\mdline{4097}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}write}}}\mdline{4097}.%mdk + +%mdk-data-line={4099} +\mdline{4099}Now let\mdline{4099}'\mdline{4099}s consider the following example:%mdk + +%mdk-data-line={4101} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4102} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024,~(Value\_t){\mdcolor{purple}0}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~initial~value~}{\mdcolor{darkgreen}*/})~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}100});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}100});\\ +~~~~\}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}200});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}200});\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4120} +\noindent\mdline{4120}If a P4Runtime client issues a \mdline{4120}\emph{wildcard}\mdline{4120} \mdline{4120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4120} on Register \mdline{4120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4120}, there is no +guarantee that \mdline{4121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]~==~r1{}[2]}}}\mdline{4121} in the response, as the read for \mdline{4121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4121} may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for \mdline{4123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4123} may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read \mdline{4125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4125} and \mdline{4125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4125} separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +\mdline{4128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4128} message) of individual read requests. Similar to a batch +\mdline{4129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4129}, a wildcard read of a register can execute the reads of the +register array elements (\mdline{4130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4130}, \mdline{4130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4130}, \mdline{4130}\dots{}\mdline{4130}) in an arbitrary order relative +to each other.%mdk + +%mdk-data-line={4133} +\mdline{4133}If the \mdline{4133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4133} annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program.%mdk + +%mdk-data-line={4137} +\section{\mdline{4137}12.\hspace*{0.5em}\mdline{4137}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4137} RPC}\label{sec-write-rpc}%mdk%mdk + +%mdk-data-line={4139} +\noindent\mdline{4139}The \mdline{4139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4139} RPC updates one or more P4 entities on the target. The request is +defined as follows:%mdk + +%mdk-data-line={4142} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4143} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~WriteRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint64}}~role\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Update~updates~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\bfseries{\mdcolor{navy}enum}}~Atomicity~\{\\ +~~~~CONTINUE\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~ROLLBACK\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~DATAPLANE\_ATOMIC~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~\}\\ +~~Atomicity~atomicity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4157} +\noindent\mdline{4157}The \mdline{4157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4157} uniquely identifies the target P4 device. The \mdline{4157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4157} and +\mdline{4158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4158} define the client role and election-id as described in the +\mdline{4159}\mdref{sec-master-slave-arbitration-and-controller-replication}{Master-Slave Arbitration and Controller Replication}\mdline{4159} +section. The server is expected to perform the following checks (in this order) +before processing the \mdline{4161}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}updates}}}\mdline{4161} list:%mdk + +%mdk-data-line={4163} +\begin{enumerate}%mdk + +%mdk-data-line={4163} +\item{} +%mdk-data-line={4163} +\mdline{4163}If \mdline{4163}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4163} does not match any of the devices known to the P4Runtime +server or if \mdline{4164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4164} does not match any of the roles for the device, the +server must return a \mdline{4165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4165} error.%mdk%mdk + +%mdk-data-line={4167} +\item{} +%mdk-data-line={4167} +\mdline{4167}If the client is not the master for (\mdline{4167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4167}, \mdline{4167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4167}) according to the +\mdline{4168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4168} value, the server must return a \mdline{4168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4168} error.%mdk%mdk + +%mdk-data-line={4170} +\item{} +%mdk-data-line={4170} +\mdline{4170}If the \mdline{4170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4170} is attempted before a \mdline{4170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4170} has been set, +the server must return a \mdline{4171}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{4171} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4173} +\noindent\mdline{4173}The updates field is a list of P4 entity updates to be applied. Each update is +defined as:%mdk + +%mdk-data-line={4176} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4177} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Update~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Type~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~INSERT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~MODIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DELETE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~Type~type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Entity~entity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4189} +\noindent\mdline{4189}This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a \mdline{4190}\emph{logical}\mdline{4190} table (\mdline{4190}e.g.\mdline{4190} +\mdline{4191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4191}) or an actual table (\mdline{4191}e.g.\mdline{4191} \mdline{4191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4191}) in the P4 data +plane. Each entity in the container is uniquely identified by its \mdline{4192}\emph{key}\mdline{4192}. Please +refer to the\mdline{4193}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4193} section for details on +what parts of the entity specification make up the \mdline{4194}\emph{key}\mdline{4194} for each P4 entity.%mdk + +%mdk-data-line={4196} +\mdline{4196}An update can be one of the following types:%mdk + +%mdk-data-line={4198} +\begin{itemize}%mdk + +%mdk-data-line={4198} +\item{} +%mdk-data-line={4198} +\mdline{4198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4198}: Inserts the given P4 entity in the entity container. +The \mdline{4199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{4199} field always specifies the full state of the P4 entity. +If the entity already exists, an \mdline{4200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4200} error is returned, and +the existing entity remains unchanged. +If the entity is malformed, an \mdline{4202}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4202} error is returned. +If the entity cannot be inserted because the container is already full, +a \mdline{4204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4204} error is returned.%mdk%mdk + +%mdk-data-line={4206} +\item{} +%mdk-data-line={4206} +\mdline{4206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4206}: Modifies the P4 entity to its new specified state. This uses +\mdline{4207}\emph{assign}\mdline{4207} or \mdline{4207}\emph{full-snapshot}\mdline{4207} semantics, \mdline{4207}i.e.\mdline{4207} the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an \mdline{4209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4209} error is usually returned (unless a +more specific error code applies\mdline{4210}~[\mdcite{grpcstatuscodes}{31}]\mdline{4210}). If the entity does not +exist, a \mdline{4211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4211} error is returned.%mdk%mdk + +%mdk-data-line={4213} +\item{} +%mdk-data-line={4213} +\mdline{4213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4213}: Deletes the specified P4 entity. If the entity does not exist, a +\mdline{4214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4214} error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4217} +\noindent\mdline{4217}The \mdline{4217}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4217} RPC is idempotent, \mdline{4217}i.e.\mdline{4217} multiple invocations of the same +RPC, with no intervening data plane operations, do not have any side +effects. The end result (modified end state on P4Runtime server and P4 +device) is always the same as the result of the initial invocation, +even if the response differs.%mdk + +%mdk-data-line={4223} +\mdline{4223}If an update is not allowed under the given controller role, the server must +return a \mdline{4224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4224} error for this update.%mdk + +%mdk-data-line={4226} +\subsection{\mdline{4226}12.1.\hspace*{0.5em}\mdline{4226}Batching and Ordering of Updates}\label{sec-batching-and-ordering-of-updates}%mdk%mdk + +%mdk-data-line={4228} +\noindent\mdline{4228}P4Runtime supports batching of \mdline{4228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4228} operations. The list of updates in a +\mdline{4229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4229} is referred to as a \mdline{4229}\emph{batch}\mdline{4229}. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of \mdline{4231}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4231} entities).%mdk + +%mdk-data-line={4233} +\mdline{4233}The P4Runtime server may arbitrarily reorder message within a batch to maximize +performance, and clients should not depend on a specific processing order (\mdline{4234}e.g.\mdline{4234} +FIFO or inferring implicit dependencies within a batch). In particular, P4 +entities (\mdline{4236}e.g.\mdline{4236} table entries) may be inserted in the data plane in an order +different than what is received in the \mdline{4237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4237}.%mdk + +%mdk-data-line={4239} +\mdline{4239}The \mdline{4239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4239} RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the \mdline{4240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4240} RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, +with the exception of any operations that return an error status. +If two updates from the client depend on each other (\mdline{4243}e.g.\mdline{4243} inserting an +\mdline{4244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4244} followed by pointing a \mdline{4244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4244} to it), they should be +separated across two batches (and therefore two \mdline{4245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4245} RPCs). In other words, +the client must wait until the dependent \mdline{4246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4246} RPC is acknowledged before +invoking a \mdline{4247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4247} RPC that depends on it.%mdk + +%mdk-data-line={4249} +\mdline{4249}P4Runtime is based on gRPC which provides a concurrent server design. A target +implementation may support concurrent execution of a given RPC handler, or it +may internally choose to serialize RPC processing (using locks, message queue, +etc.). A client is free to invoke multiple outstanding \mdline{4252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4252} RPCs. This is a +valid scenario if there are no dependent updates among these RPCs. However, if +there are dependencies, the client should be aware that there is no way to +guarantee their ordering, and this will lead to non-deterministic and/or +erroneous behavior. Given the risk, most clients are advised to stick to a +synchronous model where there can be at most one Write \mdline{4257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RPC}}}\mdline{4257} in flight.%mdk + +%mdk-data-line={4259} +\subsection{\mdline{4259}12.2.\hspace*{0.5em}\mdline{4259}Batch Atomicity}\label{sec-batch-atomicity}%mdk%mdk + +%mdk-data-line={4261} +\noindent\mdline{4261}A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the \mdline{4262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4262} +enum. A P4Runtime server is required to support only the modes marked as +\mdline{4264}\emph{Required}\mdline{4264} below:%mdk + +%mdk-data-line={4266} +\begin{itemize}%mdk + +%mdk-data-line={4266} +\item{} +%mdk-data-line={4266} +\mdline{4266}\emph{Required}\mdline{4266}: \mdline{4266}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4266}: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that \mdline{4270}\emph{see}\mdline{4270} each of +these intermediate stages.%mdk%mdk + +%mdk-data-line={4273} +\item{} +%mdk-data-line={4273} +\mdline{4273}\emph{Optional}\mdline{4273}: \mdline{4273}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ROLLBACK\_ON\_ERROR}}}\mdline{4273}: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is \mdline{4277}\emph{all-or-none}\mdline{4277}, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that \mdline{4281}\emph{see}\mdline{4281} each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure.%mdk + +%mdk-data-line={4286} +\mdline{4286}If a P4Runtime server does not support this option at all, an +\mdline{4287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4287} error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (\mdline{4288}e.g.\mdline{4288} it is +more straightforward to implement batches that contain only \mdline{4289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4289} +operations, vs. those that contain \mdline{4290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4290} operations), an +\mdline{4291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4291} error is returned when the batch cannot be executed +in a data plane-atomic way.%mdk%mdk + +%mdk-data-line={4294} +\item{} +%mdk-data-line={4294} +\mdline{4294}\emph{Optional}\mdline{4294}: \mdline{4294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4294}: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +\mdline{4298}\emph{transaction}\mdline{4298}. The details and design of how to achieve data plane-atomicity is +outside the scope of this specification. One possibility is to limit the +target to half of the data plane\mdline{4300}'\mdline{4300}s table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table.%mdk + +%mdk-data-line={4307} +\mdline{4307}If a P4Runtime server does not support this option at all, an \mdline{4307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4307} +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an \mdline{4309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4309} error is returned when the batch +cannot be executed in a data plane-atomic way.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4312} +\noindent\mdline{4312}There is no expectation that a given client must always use the same \mdline{4312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4312} +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use \mdline{4315}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4315} at one time and default behavior +(\mdline{4316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4316}) at other times.%mdk + +%mdk-data-line={4318} +\subsection{\mdline{4318}12.3.\hspace*{0.5em}\mdline{4318}Error Reporting}\label{sec-error-reporting}%mdk%mdk + +%mdk-data-line={4320} +\noindent\mdline{4320}Please see section\mdline{4320}~\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{4320} for +information on error reporting messages and guidelines. P4Runtime server will +populate \mdline{4322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4322} as follows:%mdk + +%mdk-data-line={4324} +\begin{enumerate}%mdk + +%mdk-data-line={4324} +\item{} +%mdk-data-line={4324} +\mdline{4324}If all batch updates succeeded, set \mdline{4324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4324} to \mdline{4324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4324} and do not +populate any other field.%mdk%mdk + +%mdk-data-line={4327} +\item{} +%mdk-data-line={4327} +\mdline{4327}If an error is encountered before even trying to attempt individual batch +updates, set \mdline{4328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4328} that best describes that RPC-wide +error. For example, use \mdline{4329}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNAVAILABLE}}}\mdline{4329} if the P4Runtime service is not yet +ready to handle requests. Set \mdline{4330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4330} to describe the issue. Do not +set \mdline{4331}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_details}}}\mdline{4331} in this case.%mdk%mdk + +%mdk-data-line={4333} +\item{} +%mdk-data-line={4333} +\mdline{4333}Otherwise, if one or more updates in the batch (\mdline{4333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest.updates}}}\mdline{4333}) +failed, set \mdline{4334}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4334} to \mdline{4334}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{4334}. For example, one update in +the batch may fail with \mdline{4335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4335} and another with +\mdline{4336}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4336}. A \mdline{4336}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4336} message is used to capture the status of +each and every update in the batch. The number of \mdline{4337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4337} messages packed +into \mdline{4338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{4338} field should therefore always match the +number of updates in the \mdline{4339}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4339}, and the order of +\mdline{4340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4340} messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +\mdline{4342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4342} should set the code to \mdline{4342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4342} and omit other fields.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4344} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4345} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}\#~Example~of~a~grpc::Status~returned~for~a~Write~RPC~with~a~batch~of~3~updates.}\\ +{\mdcolor{darkgreen}\#~The~first~and~third~updates~encountered~an~error,~while~the~second~update}\\ +{\mdcolor{darkgreen}\#~succeeded.}\\ +code\_~=~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +error\_message\_~=~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +binary\_error\_details~\{\\ +~~code:~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}8}~~{\mdcolor{darkgreen}\#~RESOURCE\_EXHAUSTED}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Table~is~full.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}500}~~{\mdcolor{darkgreen}\#~ERR\_TABLE\_FULL}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}0}~~{\mdcolor{darkgreen}\#~OK}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}6}~~{\mdcolor{darkgreen}\#~ALREADY\_EXISTS}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Entity~already~exists.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}600}~~{\mdcolor{darkgreen}\#~ERR\_ENTITY\_ALREADY\_EXISTS}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4371} +\section{\mdline{4371}13.\hspace*{0.5em}\mdline{4371}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4371} RPC}\label{sec-read-rpc}%mdk%mdk + +%mdk-data-line={4373} +\noindent\mdline{4373}The \mdline{4373}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4373} RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as:%mdk + +%mdk-data-line={4376} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4377} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4383} +\noindent\mdline{4383}The \mdline{4383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4383} uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +\mdline{4385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4385} error. The \mdline{4385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{4385} repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server.%mdk + +%mdk-data-line={4388} +\mdline{4388}The \mdline{4388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read~}}}\mdline{4388}response consists of a sequence of messages (a gRPC \mdline{4388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}stream}}}\mdline{4388}) with +each message defined as:%mdk + +%mdk-data-line={4391} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4392} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadResponse~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4397} +\noindent\mdline{4397}The \mdline{4397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{4397} repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the \mdline{4401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Finish()}}}\mdline{4401} method on the stream object +\mdline{4402}[\mdcite{grpcstreamc}{10}]\mdline{4402}).%mdk + +%mdk-data-line={4404} +\subsection{\mdline{4404}13.1.\hspace*{0.5em}\mdline{4404}Nomenclature}\label{sec-nomenclature}%mdk%mdk + +%mdk-data-line={4406} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries request}}%mdk + +%mdk-data-line={4406} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{4406}An element of the \mdline{4406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{4406} repeated field. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries batch}}%mdk + +%mdk-data-line={4408} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{4408}Refers to the \mdline{4408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{4408} repeated field.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={4411} +\noindent\mdline{4411}Each \mdline{4411}\emph{request}\mdline{4411} acts as a query filter for that entity type. If a \mdline{4411}\emph{request}\mdline{4411} fully +specifies the entity key, the \mdline{4412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4412} operation should retrieve a single P4 +entity. Please refer to the\mdline{4413}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4413} section +for details on what parts of the entity specification make up the entity \mdline{4414}\emph{key}\mdline{4414}.%mdk + +%mdk-data-line={4416} +\subsection{\mdline{4416}13.2.\hspace*{0.5em}\mdline{4416}Wildcard Reads}\label{sec-wildcard-reads}%mdk%mdk + +%mdk-data-line={4418} +\noindent\mdline{4418}P4Runtime allows wildcard read of P4 entities. A \mdline{4418}\emph{request}\mdline{4418} may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the\mdline{4420}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4420} section for details on +what parts of the entity can be wildcarded in a given \mdline{4421}\emph{request}\mdline{4421}.%mdk + +%mdk-data-line={4423} +\mdline{4423}For example, in a \mdline{4423}\emph{request}\mdline{4423} of type \mdline{4423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4423}:%mdk + +%mdk-data-line={4425} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4425} +\item\mdline{4425}A default \mdline{4425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4425} implies a request to read all counter-entries for all +indirect counters.%mdk + +%mdk-data-line={4427} +\item\mdline{4427}A particular (non-default) \mdline{4427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4427} in conjunction with \mdline{4427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4427} unset +implies a request to read all counter-entries for the given indirect counter +ID.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4431} +\subsection{\mdline{4431}13.3.\hspace*{0.5em}\mdline{4431}Batch Processing}\label{sec-batch-processing}%mdk%mdk + +%mdk-data-line={4433} +\noindent\mdline{4433}A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type \mdline{4434}\emph{request}\mdline{4434} +appears only once in the batch.%mdk + +%mdk-data-line={4437} +\mdline{4437}A P4Runtime server will process the batch as follows:%mdk + +%mdk-data-line={4439} +\begin{enumerate}%mdk + +%mdk-data-line={4439} +\item{} +%mdk-data-line={4439} +\mdline{4439}Lock state (preventing new writes) and validate each \mdline{4439}\emph{request}\mdline{4439} in the batch:%mdk + +%mdk-data-line={4441} +\begin{enumerate}%mdk + +%mdk-data-line={4441} +\item{} +%mdk-data-line={4441} +\mdline{4441}If it is a valid \mdline{4441}\emph{request}\mdline{4441}, perform the read;%mdk + +%mdk-data-line={4443} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4443} +\item\mdline{4443}If the read was successful, return the entities read in +\mdline{4444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4444} stream.%mdk + +%mdk-data-line={4445} +\item\mdline{4445}If the read failed (exception / critical-error), prepare a \mdline{4445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4445} +with code set to \mdline{4446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INTERNAL}}}\mdline{4446}.%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={4448} +\item{} +%mdk-data-line={4448} +\mdline{4448}If the \mdline{4448}\emph{request}\mdline{4448} is invalid (invalid-argument, not-supported, etc.), +prepare a \mdline{4449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4449} with relevant canonical code to capture the error.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={4451} +\item{} +%mdk-data-line={4451} +\mdline{4451}Unlock the state (allowing new writes);%mdk%mdk + +%mdk-data-line={4453} +\item{} +%mdk-data-line={4453} +\mdline{4453}Close the \mdline{4453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4453} stream and return a \mdline{4453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4453} as follows:%mdk + +%mdk-data-line={4455} +\begin{enumerate}%mdk + +%mdk-data-line={4455} +\item{} +%mdk-data-line={4455} +\mdline{4455}If no errors were encountered, set code to \mdline{4455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4455} and do not populate any +other field.%mdk%mdk + +%mdk-data-line={4458} +\item{} +%mdk-data-line={4458} +\mdline{4458}Otherwise, the overall code should be set to \mdline{4458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{4458}. See section +\mdline{4459}\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{4459} for information +on error reporting messages and guidelines. Assemble a list of \mdline{4460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4460} +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +\mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{4464} field. This behavior also matches \mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4464} +RPC.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4467} +\subsubsection{\mdline{4467}13.3.1.\hspace*{0.5em}\mdline{4467}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={4469} +\noindent\mdline{4469}If a client asked to read \mdline{4469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{a,b,c,d\}}}}\mdline{4469} and \mdline{4469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}b}}}\mdline{4469} and \mdline{4469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}d}}}\mdline{4469} \mdline{4469}\emph{requests}\mdline{4469} didn\mdline{4469}'\mdline{4469}t +validate, the server will return entities corresponding to \mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{4470} and \mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}c}}}\mdline{4470}, followed by +a status \mdline{4471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{p4.Error(OK),~p4.Error(xxx),~p4.Error(yyy),~p4.Error(OK)\}}}}\mdline{4471} in the +\mdline{4472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{4472} field.%mdk + +%mdk-data-line={4474} +\mdline{4474}The P4Runtime server is not required to perform any optimization (\mdline{4474}e.g.\mdline{4474} merge two +\mdline{4475}\emph{requests}\mdline{4475} in the \mdline{4475}\emph{batch}\mdline{4475} if one is a subset of other). As a result of this, it +is possible for the \mdline{4476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4476} to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging.%mdk + +%mdk-data-line={4479} +\mdline{4479}There is no requirement that each request in the batch will correspond to one +\mdline{4480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4480} message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit.%mdk + +%mdk-data-line={4485} +\mdline{4485}A P4Runtime server must be prepared to handle multiple concurrent \mdline{4485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4485} RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (\mdline{4490}e.g.\mdline{4490} in a single-threaded architecture), it may choose to serialize +\mdline{4491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4491} RPC processing.%mdk + +%mdk-data-line={4493} +\section{\mdline{4493}14.\hspace*{0.5em}\mdline{4493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4493} RPC}\label{sec-setforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={4495} +\noindent\mdline{4495}A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the \mdline{4496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig~RPC}}}\mdline{4496}. The request is defined as:%mdk + +%mdk-data-line={4498} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4499} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~SetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Action~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~VERIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~VERIFY\_AND\_SAVE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~VERIFY\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~~~COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~~~RECONCILE\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint64}}~role\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~Action~action~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4516} +\noindent\mdline{4516}The server is expected to perform the following checks (in this order) +before performing the required \mdline{4517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{4517}:%mdk + +%mdk-data-line={4519} +\begin{enumerate}%mdk + +%mdk-data-line={4519} +\item{} +%mdk-data-line={4519} +\mdline{4519}If \mdline{4519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4519} does not match any of the devices known to the P4Runtime +server or if \mdline{4520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4520} does not match any of the roles for the device, the +server must return a \mdline{4521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4521} error.%mdk%mdk + +%mdk-data-line={4523} +\item{} +%mdk-data-line={4523} +\mdline{4523}If the client is not the master for (\mdline{4523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4523}, \mdline{4523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4523}) according to the +\mdline{4524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4524} value, the server must return a \mdline{4524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4524} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4526} +\noindent\mdline{4526}The action is the type of configuration action requested, it can be one of:%mdk + +%mdk-data-line={4528} +\begin{itemize}%mdk + +%mdk-data-line={4528} +\item{} +%mdk-data-line={4528} +\mdline{4528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY}}}\mdline{4528}: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an \mdline{4529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4529} +error if config is not provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={4532} +\item{} +%mdk-data-line={4532} +\mdline{4532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{4532}: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent \mdline{4534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4534} / \mdline{4534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4534} requests must refer to fields in the new +config. Returns an \mdline{4535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4535} error if the forwarding config is not +provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={4538} +\item{} +%mdk-data-line={4538} +\mdline{4538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_COMMIT}}}\mdline{4538}: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an \mdline{4540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4540} error if the forwarding config is not provided of if the +provided config cannot be realized.%mdk%mdk + +%mdk-data-line={4543} +\item{} +%mdk-data-line={4543} +\mdline{4543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COMMIT}}}\mdline{4543}: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4546} error if no saved config +is found, \mdline{4547}i.e.\mdline{4547} if no \mdline{4547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{4547} action preceded this one. Returns an +\mdline{4548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4548} error if a config is provided with this message.%mdk%mdk + +%mdk-data-line={4550} +\item{} +%mdk-data-line={4550} +\mdline{4550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RECONCILE\_AND\_COMMIT}}}\mdline{4550}: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an \mdline{4556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4556} error. For targets that support this option, an +\mdline{4557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4557} error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4561} +\noindent\mdline{4561}The \mdline{4561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4561} field is a message of type \mdline{4561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4561} that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(\mdline{4563}e.g.\mdline{4563} generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the\mdline{4564}~\mdref{sec-p4-fwd-pipe-config}{Forwarding-Pipeline +Configuration}\mdline{4565} section for details.%mdk + +%mdk-data-line={4567} +\mdline{4567}A P4Runtime server running on a non-programmable device may not +support \mdline{4568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4568} (\mdline{4568}e.g.\mdline{4568} the forwarding-pipeline +config is part of the device\mdline{4569}'\mdline{4569}s software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +\mdline{4571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4571} error.%mdk + +%mdk-data-line={4573} +\section{\mdline{4573}15.\hspace*{0.5em}\mdline{4573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{4573} RPC}\label{sec-getforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={4575} +\noindent\mdline{4575}The forwarding-pipeline configuration of the target can be retrieved by invoking +the \mdline{4576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig~RPC}}}\mdline{4576}. The request is defined as:%mdk + +%mdk-data-line={4578} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4579} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~ResponseType~\{\\ +~~~~ALL~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~COOKIE\_ONLY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~P{\mdcolor{purple}4}INFO\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DEVICE\_CONFIG\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~ResponseType~response\_type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4591} +\noindent\mdline{4591}The \mdline{4591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4591} uniquely identifies the target P4 device. A \mdline{4591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4591} error is +returned if the \mdline{4592}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4592} is not recognized by the P4Runtime server.%mdk + +%mdk-data-line={4594} +\mdline{4594}The \mdline{4594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{4594} is used to specify which fields to populate in the response, +its value can be one of:%mdk + +%mdk-data-line={4597} +\begin{itemize}%mdk + +%mdk-data-line={4597} +\item{} +%mdk-data-line={4597} +\mdline{4597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{4597}: returns a \mdline{4597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4597} with all fields +set as stored by the target. This is the default behaviour if the +\mdline{4599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{4599} field is not set.%mdk%mdk + +%mdk-data-line={4601} +\item{} +%mdk-data-line={4601} +\mdline{4601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COOKIE\_ONLY}}}\mdline{4601}: reply by setting only the \mdline{4601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{4601} field in the +\mdline{4602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4602}, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message.%mdk%mdk + +%mdk-data-line={4606} +\item{} +%mdk-data-line={4606} +\mdline{4606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4INFO\_AND\_COOKIE}}}\mdline{4606}: reply by setting the \mdline{4606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{4606} and \mdline{4606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{4606} fields.%mdk%mdk + +%mdk-data-line={4608} +\item{} +%mdk-data-line={4608} +\mdline{4608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEVICE\_CONFIG\_AND\_COOKIE}}}\mdline{4608}: reply by setting the \mdline{4608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{4608} and +\mdline{4609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{4609} fields.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4611} +\noindent\mdline{4611}The response contains the \mdline{4611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4611} for the specified device:%mdk + +%mdk-data-line={4613} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4614} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigResponse~\{\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4619} +\noindent\mdline{4619}If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level \mdline{4620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4620} field will be unset in the response. Examples are +(i) a server that only allows configuration via \mdline{4621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4621} +but this RPC hasn\mdline{4622}'\mdline{4622}t been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn\mdline{4623}'\mdline{4623}t yet occurred.%mdk + +%mdk-data-line={4625} +\mdline{4625}Once a forwarding-pipeline config is installed on the device (either via +\mdline{4626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4626} or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +\mdline{4628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.p4\_device\_config}}}\mdline{4628} will be empty / unset in the response, even if +\mdline{4629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{4629} in the request was set to \mdline{4629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{4629}. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the \mdline{4631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4631} RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +\mdline{4633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4633}, the value of \mdline{4633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.cookie}}}\mdline{4633} will be unset.%mdk + +%mdk-data-line={4635} +\mdline{4635}If a P4Runtime server supports both \mdline{4635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4635} as well as +returning the \mdline{4636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{4636}, there should be read-write symmetry between +\mdline{4637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4637} and \mdline{4637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{4637} RPCs.%mdk + +%mdk-data-line={4639} +\section{\mdline{4639}16.\hspace*{0.5em}\mdline{4639}P4Runtime Stream Messages}\label{sec-p4runtime-stream-messages}%mdk%mdk + +%mdk-data-line={4641} +\subsection{\mdline{4641}16.1.\hspace*{0.5em}\mdline{4641}Packet I/O}\label{sec-packet-i_o}%mdk%mdk + +%mdk-data-line={4643} +\noindent\mdline{4643}P4Runtime supports controller packet-in and packet-out by means of \mdline{4643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{4643} +and \mdline{4644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4644} stream messages, respectively.%mdk + +%mdk-data-line={4646} +\mdline{4646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{4646} messages are sent by the P4Runtime server to the client. Conversely, +\mdline{4647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4647} messages are sent by the client to the server.%mdk + +%mdk-data-line={4649} +\mdline{4649}As introduced in the\mdline{4649}~\mdref{sec-controller-packet-meta}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\mdline{4649} +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with \mdline{4651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{4651}. The expected metadata is described +in the P4Info using the \mdline{4652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{4652} messages.%mdk + +%mdk-data-line={4654} +\mdline{4654}Both \mdline{4654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{4654} and \mdline{4654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4654} stream messages share the same fields and are +defined as follows:%mdk + +%mdk-data-line={4657} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4658} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Packet~sent~from~the~controller~to~the~switch.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketOut~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~Packet~sent~from~the~switch~to~the~controller.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketIn~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~PacketMetadata~\{\\ +~~{\mdcolor{darkgreen}//~This~refers~to~Metadata.id~coming~from~P4Info~ControllerPacketMetadata.}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~metadata\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4677} +\begin{itemize}%mdk + +%mdk-data-line={4677} +\item{} +%mdk-data-line={4677} +\mdline{4677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}payload}}}\mdline{4677} is used to carry the full packet content, including the headers.%mdk%mdk + +%mdk-data-line={4679} +\item{} +%mdk-data-line={4679} +\mdline{4679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{4679} is a repeated field of \mdline{4679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{4679} messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +\mdline{4682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{4682}. Indeed, when a P4Runtime client (or server) +generates a \mdline{4683}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4683} (or \mdline{4683}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{4683}) message, it needs to populate the +\mdline{4684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{4684} field with as many values as in \mdline{4684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{4684} +for the packet-out (or packet-in) case. Each \mdline{4685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata.value}}}\mdline{4685} is a +binary string and must conform to the\mdline{4686}~\mdref{sec-bytestrings}{Bytestrings}\mdline{4686} +requirements based on the corresponding P4Info +\mdline{4688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{4688} specification.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4690} +\subsection{\mdline{4690}16.2.\hspace*{0.5em}\mdline{4690}Master Arbitration Update}\label{sec-master-arbitration-update}%mdk%mdk + +%mdk-data-line={4692} +\noindent\mdline{4692}As explained earlier in this document, the controller uses the \mdline{4692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4692} +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via \mdline{4694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4694} RPC), +it needs to start a controller session and become a \mdline{4695}\textquotedblleft{}master\textquotedblright{}\mdline{4695}. To do so, the +controller first opens a bidirectional stream channel to the server via +\mdline{4697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4697} for each device and sends a \mdline{4697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{4697} message. The +controller populates the \mdline{4698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4698} field in this message using +its \mdline{4699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4699} and \mdline{4699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4699} and the \mdline{4699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4699} of the device, as explained +in detail in the\mdline{4700}~\mdref{sec-master-slave-arbitration-and-controller-replication}{Master-Slave Arbitration and Controller +Replication}\mdline{4701} +section. For any given (\mdline{4702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4702}, \mdline{4702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4702}), the controller with the highest +\mdline{4703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4703} is the master and the rest are slaves.%mdk + +%mdk-data-line={4705} +\mdline{4705}The \mdline{4705}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4705} message is defined as follows:%mdk + +%mdk-data-line={4707} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4708} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Role~\{\\ +~~{\mdcolor{darkgreen}//~role\_id~for~this~role.~Defined~offline~in~agreement~across~the}\\ +~~{\mdcolor{darkgreen}//~entire~control~plane.}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Describes~the~role~configuration.}\\ +~~google.protobuf.Any~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~MasterArbitrationUpdate~\{\\ +~~{\mdcolor{darkgreen}//~Identifies~the~device~(aka~target~or~node~or~switching~chip).}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~The~role~for~which~the~mastership~is~being~arbitrated.}\\ +~~Role~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~The~election\_id~(unique~per~role).}\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Switch~populates~this~with~OK~for~the~client~that~is~the~master,}\\ +~~{\mdcolor{darkgreen}//~and~with~an~error~status~for~all~other~connected~clients~(at}\\ +~~{\mdcolor{darkgreen}//~every~mastership~change).~The~controller~does~not~populate~this}\\ +~~{\mdcolor{darkgreen}//~field.}\\ +~~google.{\bfseries{\mdcolor{navy}rpc}}.Status~status~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4731} +\noindent\mdline{4731}Note that the \mdline{4731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{4731} field in the \mdline{4731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4731} message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a \mdline{4733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{4733} message back to the controller, in which +it populates the \mdline{4734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4734} message using the \mdline{4734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4734}, +\mdline{4735}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{4735}, and \mdline{4735}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4735} it previously received from the controller. The server +also populates the \mdline{4736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{4736} field in the \mdline{4736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4736} as follows:%mdk + +%mdk-data-line={4738} +\begin{itemize}%mdk + +%mdk-data-line={4738} +\item{} +%mdk-data-line={4738} +\mdline{4738}OK (with \mdline{4738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{4738} set to \mdline{4738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.OK}}}\mdline{4738}) when the controller is +determined to be the master for a given (\mdline{4739}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4739}, \mdline{4739}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4739}).%mdk%mdk + +%mdk-data-line={4741} +\item{} +%mdk-data-line={4741} +\mdline{4741}Non-OK (with \mdline{4741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{4741} set to \mdline{4741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.ALREADY\_EXISTS}}}\mdline{4741}) when the +controller is determined to be a slave for a given (\mdline{4742}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4742}, \mdline{4742}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4742}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4744} +\subsection{\mdline{4744}16.3.\hspace*{0.5em}\mdline{4744}Digest Messages}\label{sec-digest-messages}%mdk%mdk + +%mdk-data-line={4746} +\noindent\mdline{4746}See the\mdline{4746}~\mdref{sec-digestentry}{DigestEntry}\mdline{4746} section.%mdk + +%mdk-data-line={4748} +\subsection{\mdline{4748}16.4.\hspace*{0.5em}\mdline{4748}Table Idle Timeout Notification}\label{sec-table-idle-timeout-notification}%mdk%mdk + +%mdk-data-line={4750} +\noindent\mdline{4750}When a table supports idle timeout (as per the P4Info message), the master +client can specify a TTL value for each entry in the table (see +\mdline{4752}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{4752} section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an \mdline{4754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{4754} message on the +\mdline{4755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4755} bidirectional stream to the master client. The master client can +then take the action of its choice, most likely remove the idle entry.%mdk + +%mdk-data-line={4758} +\mdline{4758}The \mdline{4758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{4758} Protobuf message has the following fields:%mdk + +%mdk-data-line={4760} +\begin{itemize}%mdk + +%mdk-data-line={4760} +\item{} +%mdk-data-line={4760} +\mdline{4760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}timestamp}}}\mdline{4760}: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server\mdline{4761}'\mdline{4761}s local clock.%mdk%mdk + +%mdk-data-line={4763} +\item{} +%mdk-data-line={4763} +\mdline{4763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{4763}: a repeated field of entries which have expired. Each individual +entry is identified by a single \mdline{4764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4764} message. For each \mdline{4764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4764}, +the \mdline{4765}\emph{key}\mdline{4765} fields (\mdline{4765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{4765}, \mdline{4765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{4765} and \mdline{4765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{4765}) must be set, along with +the \mdline{4766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{4766} field and the \mdline{4766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{4766} field. Other fields +may be set by the server but should be ignored by the client.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4769} +\noindent\mdline{4769}Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +\mdline{4771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{4771} message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an \mdline{4776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{4776} +message with an empty \mdline{4777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{4777} repeated field.%mdk + +%mdk-data-line={4779} +\mdline{4779}After generating an idle notification, the P4Runtime server must \mdline{4779}\textquotedblleft{}reset\textquotedblright{}\mdline{4779} the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the master client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle.%mdk + +%mdk-data-line={4786} +\mdline{4786}Here is a reasonable pseudo-code implementation for idle timeout for table +entries:%mdk + +%mdk-data-line={4789} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4790} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutStream~stream;\\ +\\ +scanning\_interval~=~{\mdcolor{purple}10}ms;\\ +\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~{\mdcolor{darkgreen}//~iterate~over~all~tables~which~support~idle~timeout}\\ +~~{\bfseries{\mdcolor{navy}for}}~(table~in~tables)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(!table.idle\_timeout\_supported)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~{\mdcolor{darkgreen}//~we~coalesce~all~idle~notifications~for~the~same~table~in~one}\\ +~~~~{\mdcolor{darkgreen}//~message}\\ +~~~~IdleTimeoutNotification~msg;\\ +~~~~{\mdcolor{darkgreen}//~read~time\_since\_last\_hit~from~device}\\ +~~~~entries~=~device.load\_table\_entries\_from\_hw(table);\\ +~~~~{\bfseries{\mdcolor{navy}for}}~(entry~in~entries)~\{\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.idle\_timeout~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~TTL}\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.time\_since\_last\_hit~\textless{}~entry.idle\_timeout)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~~~msg.table\_entry\_add(entry);\\ +~~~~~~entry.reset\_time\_since\_last\_hit();\\ +~~~~\}\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(msg.table\_entry\_size()~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~notifications}\\ +~~~~msg.set\_timestamp(now());\\ +~~~~stream.write(msg);\\ +~~\}\\ +~~sleep(scanning\_interval);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4817} +\subsection{\mdline{4817}16.5.\hspace*{0.5em}\mdline{4817}Architecture-Specific Notifications}\label{sec-architecture-specific-notifications}%mdk%mdk + +%mdk-data-line={4819} +\noindent\mdline{4819}P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on \mdline{4820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4820}, by including an \mdline{4820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{4820} Protobuf field\mdline{4820}~[\mdcite{protoany}{28}]\mdline{4820} +named \mdline{4821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{4821} in both \mdline{4821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{4821} and \mdline{4821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{4821}. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the\mdline{4823}~\mdref{sec-digestentry}{PSA \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}} +extern}\mdline{4824}. See section on\mdline{4824}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{4825} for more information.%mdk + +%mdk-data-line={4827} +\section{\mdline{4827}17.\hspace*{0.5em}\mdline{4827}Portability Considerations}\label{sec-portability-considerations}%mdk%mdk + +%mdk-data-line={4829} +\subsection{\mdline{4829}17.1.\hspace*{0.5em}\mdline{4829}PSA Metadata Translation}\label{sec-psa-metadata-translation}%mdk%mdk + +%mdk-data-line={4831} +\noindent\mdline{4831}The \mdline{4831}\emph{Portable Switch Architecture}\mdline{4831} (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +\mdline{4835}[\mdcite{psatranslation}{22}]\mdline{4835}. For such metadata, a translation between the controller\mdline{4835}'\mdline{4835}s +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service.%mdk + +%mdk-data-line={4841} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={4842} +\noindent\mdline{4842}\includegraphics[keepaspectratio=true,height=7cm]{build/psa-metadata-translation}{}\mdline{4842}%mdk + +%mdk-data-line={4843} +\mdhr{}%mdk + +%mdk-data-line={4844} +\noindent\mdline{4844}\mdcaption{\textbf{Figure~\mdcaptionlabel{8}.}~\mdcaptiontext{P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdcenter}\label{fig-psa-metadata-translation}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={4848} +\noindent\mdline{4848}Figure\mdline{4848}~\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}}\mdline{4848} illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller\mdline{4854}'\mdline{4854}s 32 bit port +numbers to a target\mdline{4855}'\mdline{4855}s 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch.%mdk + +%mdk-data-line={4859} +\subsubsection{\mdline{4859}17.1.1.\hspace*{0.5em}\mdline{4859}Translation of Port Numbers}\label{sec-translation-of-port-numbers}%mdk%mdk + +%mdk-data-line={4861} +\noindent\mdline{4861}In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller\mdline{4862}'\mdline{4862}s space and the PSA device\mdline{4862}'\mdline{4862}s space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +\mdline{4866}\mdref{sec-user-defined-types}{user-defined P4 types}\mdline{4866}, namely \mdline{4866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{4866} and +\mdline{4867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{4867}, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in \mdline{4870}\emph{psa.p4}\mdline{4870} for +the PSA device in Switch 1.%mdk + +%mdk-data-line={4873} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4874} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~PortId\_t~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{};\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortIdInHeader\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~PortIdInHeader\_t~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4880} +\noindent\mdline{4880}The first argument to the \mdline{4880}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{4880} annotation is a URI that +indicates to the P4Runtime server which numerical mapping\mdline{4881} \mdline{4881}\textemdash{}\mdline{4881} provided by the +out-of-band switch configuration mechanism\mdline{4882} \mdline{4882}\textemdash{}\mdline{4882} to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports).%mdk + +%mdk-data-line={4886} +\mdline{4886}An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows:%mdk + +%mdk-data-line={4892} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4893} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}enum}}~SdnPort~\{\\ +~~SDN\_PORT\_UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +\\ +~~{\mdcolor{darkgreen}//~SDN~ports~are~numbered~starting~form~1.}\\ +~~SDN\_PORT\_MIN~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\\ +~~{\mdcolor{darkgreen}//~The~maximum~value~of~an~SDN~port~(physical~or~logical).}\\ +~~SDN\_PORT\_MAX~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffeff};\\ +\\ +~~{\mdcolor{darkgreen}//~Reserved~SDN~port~numbers~(0xfffffff0~-~0xffffffff)}\\ +\\ +~~SDN\_PORT\_RECIRCULATE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffa};\\ +~~SDN\_PORT\_CPU~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffd};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4909} +\noindent\mdline{4909}The switch config will map \mdline{4909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_RECIRCULATE}}}\mdline{4909} and \mdline{4909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_CPU}}}\mdline{4909} \mdline{4909}\textemdash{}\mdline{4909} as well +as any SDN port number corresponding to a \mdline{4910}\textquotedblleft{}regular\textquotedblright{}\mdline{4910} front-panel port\mdline{4910} \mdline{4910}\textemdash{}\mdline{4910} to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation.%mdk + +%mdk-data-line={4914} +\mdline{4914}The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs.%mdk + +%mdk-data-line={4917} +\subsubsection{\mdline{4917}17.1.2.\hspace*{0.5em}\mdline{4917}Translation of Packet-IO Header Fields}\label{sec-translation-of-packet-io-header-fields}%mdk%mdk + +%mdk-data-line={4919} +\noindent\mdline{4919}Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:.%mdk + +%mdk-data-line={4922} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4923} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~PortIdInHeader\_t~egress\_port;\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~PortIdInHeader\_t~ingress\_port;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4934} +\noindent\mdline{4934}The header-level annotation \mdline{4934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{4934} is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (\mdline{4938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{4938}) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI\mdline{4942} \mdline{4942}\textemdash{}\mdline{4942} first argument to the \mdline{4942}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{4942} +annotation). Any subsequent reference to the \mdline{4943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{4943} field in the +data plane will use the translated value. \mdline{4944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{4944} is used in the +header definition instead of \mdline{4945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{4945} to guarantee byte-aligned headers in +case this is required by the target.%mdk + +%mdk-data-line={4948} +\mdline{4948}A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target\mdline{4950}'\mdline{4950}s PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the \mdline{4952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ingress\_port}}}\mdline{4952} field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller.%mdk + +%mdk-data-line={4958} +\subsubsection{\mdline{4958}17.1.3.\hspace*{0.5em}\mdline{4958}Translation of Match Fields}\label{sec-translation-of-match-fields}%mdk%mdk + +%mdk-data-line={4960} +\noindent\mdline{4960}Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table\mdline{4961}'\mdline{4961}s match key as shown in the example below:%mdk + +%mdk-data-line={4963} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4964} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~istd.ingress\_port:~exact;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~ingress~port}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4974} +\noindent\mdline{4974}Table \mdline{4974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{4974} has an exact match on PSA standard metadata ingress port +(\mdline{4975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}istd.ingress\_port}}}\mdline{4975}). Since the field is of type \mdline{4975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{4975}, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in \mdline{4978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{4978} from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table \mdline{4983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{4983} is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values.%mdk + +%mdk-data-line={4987} +\mdline{4987}Note that it may be infeasible to translate the value-mask pair for ternary +matches: \mdline{4988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{4988}, \mdline{4988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{4988} or \mdline{4988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{4988} match kinds. The P4Runtime server may +require that for these match kinds the port match be either \mdline{4989}\emph{de facto}\mdline{4989} \mdline{4989}\textquotedblleft{}exact\textquotedblright{}\mdline{4989} +(0xffffffff mask for \mdline{4990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{4990}, prefix-length of 32 for \mdline{4990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{4990}, or same low and +high bounds for \mdline{4991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{4991}) or \mdline{4991}\textquotedblleft{}don't care\textquotedblright{}\mdline{4991}.%mdk + +%mdk-data-line={4993} +\subsubsection{\mdline{4993}17.1.4.\hspace*{0.5em}\mdline{4993}Translation of Action Parameters}\label{sec-translation-of-action-parameters}%mdk%mdk + +%mdk-data-line={4995} +\noindent\mdline{4995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{4995} type parameters can be part of a P4 action definition as shown in the +example below:%mdk + +%mdk-data-line={4998} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4999} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.h.f:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~a;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5013} +\noindent\mdline{5013}The controller may write entries in table \mdline{5013}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5013} with action \mdline{5013}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5013} to set the egress +port as shown in the P4 code above. The action parameter \mdline{5014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5014} is of type +\mdline{5015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5015}, which leads to a 32-bit bitwidth for \mdline{5015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5015} being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device.%mdk + +%mdk-data-line={5021} +\subsubsection{\mdline{5021}17.1.5.\hspace*{0.5em}\mdline{5021}Port Translation for PSA Extern APIs}\label{sec-port-translation-for-psa-extern-apis}%mdk%mdk + +%mdk-data-line={5023} +\noindent\mdline{5023}The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch field is +of type \mdline{5029}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5029} to carry the 32-bit SDN representation of the port being +watched. The P4Runtime server will translate the given watch port number into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device.%mdk + +%mdk-data-line={5034} +\mdline{5034}The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type \mdline{5036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5036} to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane.%mdk + +%mdk-data-line={5040} +\subsubsection{\mdline{5040}17.1.6.\hspace*{0.5em}\mdline{5040}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}\label{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}%mdk%mdk + +%mdk-data-line={5042} +\noindent\mdline{5042}P4Runtime supports using a translated value (\mdline{5042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5042} or any other translated +type for which the underlying built-in type is \mdline{5043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5043}) as an index to a +register, indirect counter, or indirect meter.%mdk + +%mdk-data-line={5046} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5047} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~counter~entry~type~}{\mdcolor{darkgreen}*/},~PortId\_t~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~index~type~}{\mdcolor{darkgreen}*/}\textgreater{}(\\ +~~{\mdcolor{purple}32}w1024,~PSA\_CounterType\_t.PACKETS)~counter;\\ +{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +~~counter.count(p);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5055} +\noindent\mdline{5055}This P4 Counter declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={5058} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5059} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counters~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x12000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}counter}{\mdcolor{maroon}"}\\ +~~\}\\ +~~spec~\{\\ +~~~~unit:~PACKETS\\ +~~\}\\ +~~index\_type\_name~\{\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5073} +\noindent\mdline{5073}The controller may read and write counter values from indexed counter \mdline{5073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter}}}\mdline{5073} +using SDN port numbers as indices, and not device-specific port numbers. The +\mdline{5075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{5075} field in the P4Info message is a signal to the P4Runtime +server that translation is required.%mdk + +%mdk-data-line={5078} +\section{\mdline{5078}18.\hspace*{0.5em}\mdline{5078}P4Runtime Versioning}\label{sec-p4runtime-versioning}%mdk%mdk + +%mdk-data-line={5080} +\noindent\mdline{5080}P4Runtime follows the Google guidelines for versioning cloud APIs +\mdline{5081}[\mdcite{apiversioning}{6}]\mdline{5081}. We use a \mdline{5081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR.MINOR.PATCH}}}\mdline{5081} style version number scheme and +we increment the:%mdk + +%mdk-data-line={5084} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5084} +\item\mdline{5084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5084} version when we make incompatible API changes,%mdk + +%mdk-data-line={5085} +\item\mdline{5085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MINOR}}}\mdline{5085} version when we add functionality in a backwards-compatible manner,%mdk + +%mdk-data-line={5086} +\item\mdline{5086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PATCH}}}\mdline{5086} version when we make backwards-compatible bug fixes.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5088} +\noindent\mdline{5088}The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is \mdline{5090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1}}}\mdline{5090} and the package +name for P4Info is \mdline{5091}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1}}}\mdline{5091}. Even though \mdline{5091}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5091} and \mdline{5091}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5091} are two +different Protobuf packages, \mdline{5092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5092} depends on \mdline{5092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5092} and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence.%mdk + +%mdk-data-line={5096} +\mdline{5096}As recommended in\mdline{5096}~[\mdcite{apiversioning}{6}]\mdline{5096}, we may consider using pre-GA release +suffixes (such as \mdline{5097}\emph{alpha}\mdline{5097} or \mdline{5097}\emph{beta}\mdline{5097}) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1).%mdk + +%mdk-data-line={5101} +\mdline{5101}Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner.\mdline{5102}~[\mdcite{apiversioningbackwardscompatibility}{7}]\mdline{5102} describes +what constitute a backwards-compatible change. We expect \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5103} version bumps +to be a \mdline{5104}\textbf{rare}\mdline{5104} event.%mdk + +%mdk-data-line={5106} +\mdline{5106}Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor\mdline{5111} \mdline{5111}+ patch version numbers in future releases.%mdk + +%mdk-data-line={5113} +\mdline{5113}All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository\mdline{5114}~[\mdcite{p4runtimerepo}{14}]\mdline{5114} and the version label follows +semantic versioning rules\mdline{5115}~[\mdcite{semver}{25}]\mdline{5115}.%mdk + +%mdk-data-line={5117} +\section{\mdline{5117}19.\hspace*{0.5em}\mdline{5117}Extending P4Runtime for non-PSA Architectures}\label{sec-extending-p4runtime}%mdk%mdk + +%mdk-data-line={5119} +\noindent\mdline{5119}P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place.%mdk + +%mdk-data-line={5127} +\mdline{5127}When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names:%mdk + +%mdk-data-line={5131} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5131} +\item\mdline{5131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/config/\textless{}major~version\textgreater{}/p4info.proto}}}\mdline{5131}%mdk + +%mdk-data-line={5132} +\item\mdline{5132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/\textless{}major~version\textgreater{}/p4runtime.proto}}}\mdline{5132}%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5134} +\noindent\mdline{5134}We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they \mdline{5135}\textquotedblleft{}extend\textquotedblright{}\mdline{5135}.%mdk + +%mdk-data-line={5137} +\mdline{5137}For the remainder of this section, we will refer to these two files as +\mdline{5138}\emph{p4info-ext}\mdline{5138} and \mdline{5138}\emph{p4runtime-ext}\mdline{5138} respectively.%mdk + +%mdk-data-line={5140} +\subsection{\mdline{5140}19.1.\hspace*{0.5em}\mdline{5140}Extending P4Runtime for Architecture-Specific Externs}\label{sec-extending-p4runtime-for-architecture-specific-externs}%mdk%mdk + +%mdk-data-line={5142} +\noindent\mdline{5142}Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both \mdline{5143}\emph{p4info-ext}\mdline{5143} and +\mdline{5144}\emph{p4runtime-ext}\mdline{5144}. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example:%mdk + +%mdk-data-line={5148} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5149} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~T~must~be~a~bit\textless{}W\textgreater{}~type,~it~indicates~the~width~of~each~counter~cell}\\ +{\bfseries{\mdcolor{navy}extern}}~MyNewPacketCounter\textless{}T\textgreater{}~\{\\ +~~counter({\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~size);\\ +~~increment({\bfseries{\mdcolor{navy}in}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~index);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5156} +\subsubsection{\mdline{5156}19.1.1.\hspace*{0.5em}\mdline{5156}Extending the P4Info message}\label{sec-extending-the-p4info-message}%mdk%mdk + +%mdk-data-line={5158} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5158} +\item\mdline{5158}Id prefixes \mdline{5158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0x81}}}\mdline{5158} through \mdline{5158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfe}}}\mdline{5158} are reserved for architecture-specific +externs. It is recommended that \mdline{5159}\emph{p4info-ext}\mdline{5159} include a \mdline{5159}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Ids}}}\mdline{5159} message based +on the one in p4info.proto that the P4 compiler can refer to when\mdline{5160}~\mdref{sec-id-allocation}{assigning +IDs}\mdline{5161} to each extern instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5163} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5164} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~P{\mdcolor{purple}4}Ids~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Prefix~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~MY\_NEW\_PACKET\_COUNTER~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0x81};\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5172} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5172} +\item\mdline{5172}\emph{p4info-ext}\mdline{5172} should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +\mdline{5176}\mdref{sec-p4info-extern}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ExternInstance}}}}\mdline{5176} message as the \mdline{5176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{5176} +field, which is of type \mdline{5177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5177}~[\mdcite{protoany}{28}]\mdline{5177}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5179} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5180} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\mdcolor{darkgreen}//~corresponds~to~the~T~type~parameter~in~the~P4~extern~definition}\\ +~~p4.config.v1.P{\mdcolor{purple}4}DataTypeSpec~type\_spec~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~constructor~argument}\\ +~~{\bfseries{\mdcolor{navy}int64}}~size~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5188} +\subsubsection{\mdline{5188}19.1.2.\hspace*{0.5em}\mdline{5188}Extending the P4Runtime Service}\label{sec-extending-the-p4runtime-service}%mdk%mdk + +%mdk-data-line={5190} +\noindent\mdline{5190}Just like \mdline{5190}\emph{p4info-ext}\mdline{5190}, \mdline{5190}\emph{p4runtime-ext}\mdline{5190} should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an\mdline{5195}~\mdref{sec-extern-entry}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\mdline{5195} message generated by the +P4Runtime client.%mdk + +%mdk-data-line={5198} +\mdline{5198}Here is a possible Protobuf message for our \mdline{5198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyNewPacketCounter}}}\mdline{5198} P4 extern:%mdk + +%mdk-data-line={5199} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5200} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~This~message~enables~reading~/~writing~data~to~the~counter~at~the~provided}\\ +{\mdcolor{darkgreen}//~index}\\ +{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~p4.v1.P{\mdcolor{purple}4}Data~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5208} +\noindent\mdline{5208}P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an \mdline{5209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5209} Protobuf field\mdline{5209}~[\mdcite{protoany}{28}]\mdline{5209} named \mdline{5209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5209} +in both \mdline{5210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{5210} and +\mdline{5211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{5211}. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in \mdline{5213}\emph{p4runtime-ext}\mdline{5213} and embed instances of these messages in +\mdline{5214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{5214} and \mdline{5214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{5214} as appropriate.%mdk + +%mdk-data-line={5216} +\subsection{\mdline{5216}19.2.\hspace*{0.5em}\mdline{5216}Architecture-Specific Table Extensions}\label{sec-architecture-specific-table-extensions}%mdk%mdk + +%mdk-data-line={5218} +\subsubsection{\mdline{5218}19.2.1.\hspace*{0.5em}\mdline{5218}New Match Types}\label{sec-new-match-types}%mdk%mdk + +%mdk-data-line={5220} +\noindent\mdline{5220}An architecture may introduce new table match types\mdline{5220}~[\mdcite{p4matchtypes}{12}]\mdline{5220}. P4Runtime +accounts for this by providing the following hooks:%mdk + +%mdk-data-line={5223} +\begin{itemize}%mdk + +%mdk-data-line={5223} +\item{} +%mdk-data-line={5223} +\mdline{5223}The \mdline{5223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{5223} field in \mdline{5223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{5223} (p4info.proto) is a \mdline{5223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5223} +which can be either one of the default match types (\mdline{5224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{5224}, \mdline{5224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5224}, \mdline{5224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5224} +or \mdline{5225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5225}) or an architecture-specific match type encoded as a string.%mdk%mdk + +%mdk-data-line={5227} +\item{} +%mdk-data-line={5227} +\mdline{5227}The \mdline{5227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{5227} field in \mdline{5227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{5227} (p4runtime.proto) is a +\mdline{5228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5228} which includes an \mdline{5228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5228} Protobuf message\mdline{5228}~[\mdcite{protoany}{28}]\mdline{5228} field +(\mdline{5229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5229}). \mdline{5229}\emph{p4info-ext}\mdline{5229} should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in \mdline{5232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{5232} as the +\mdline{5233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5233} field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5236} +\subsubsection{\mdline{5236}19.2.2.\hspace*{0.5em}\mdline{5236}New Table Properties}\label{sec-new-table-properties}%mdk%mdk + +%mdk-data-line={5238} +\noindent\mdline{5238}An architecture may introduce additional table properties +\mdline{5239}[\mdcite{p4tableproperties}{27}]\mdline{5239}. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +\mdline{5241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Table}}}\mdline{5241} message includes the \mdline{5241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{5241} \mdline{5241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5241} Protobuf +field\mdline{5242}~[\mdcite{protoany}{28}]\mdline{5242}. At the moment, there is not any mechanism to extend the +\mdline{5243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.TableEntry}}}\mdline{5243} message based on the value of architecture-specific table +properties, but we may include on in future versions of the API.%mdk + +%mdk-data-line={5246} +\section{\mdline{5246}20.\hspace*{0.5em}\mdline{5246}Known-limitations of P4Runtime v1.0.0}\label{sec-known-limitations-of-p4runtime-v100}%mdk%mdk + +%mdk-data-line={5248} +\begin{itemize}%mdk + +%mdk-data-line={5248} +\item{} +%mdk-data-line={5248} +\mdline{5248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{5248}, action \mdline{5248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{5248}, and controller packet metadata fields only +support unsigned bitstrings, i.e. values of type \mdline{5249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5249} (not the more +general \mdline{5250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{5250}).%mdk%mdk + +%mdk-data-line={5252} +\item{} +%mdk-data-line={5252} +\mdline{5252}Support for PSA Random \mdline{5252}\&\mdline{5252} Timestamp externs is postponed to a future minor +version update.%mdk%mdk + +%mdk-data-line={5255} +\item{} +%mdk-data-line={5255} +\mdline{5255}P4Info does not include information about which of a table\mdline{5255}'\mdline{5255}s actions execute +which direct resource(s).%mdk%mdk + +%mdk-data-line={5258} +\item{} +%mdk-data-line={5258} +\mdline{5258}The default action for indirect match tables is restricted to a \mdline{5258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\\ +NoAction}}}\mdline{5259} known at compile-time.%mdk%mdk + +%mdk-data-line={5261} +\item{} +%mdk-data-line={5261} +\mdline{5261}There is no mechanism for changing the value of the \mdline{5261}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{5261} +table property at runtime.%mdk%mdk + +%mdk-data-line={5264} +\item{} +%mdk-data-line={5264} +\mdline{5264}There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor\mdline{5265} \mdline{5265}+ +patch version numbers.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5268} +\section{\mdline{5268}21.\hspace*{0.5em}\mdline{5268}Security concerns for P4Runtime}\label{sec-security-concerns-for-p4runtime}%mdk%mdk + +%mdk-data-line={5270} +\noindent\mdline{5270}Appropriate measures and security best practices need to be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client.%mdk + +%mdk-data-line={5277} +\section{\mdline{5277}A.\hspace*{0.5em}\mdline{5277}Appendix}\label{sec-appendix}%mdk%mdk + +%mdk-data-line={5279} +\subsection{\mdline{5279}A.1.\hspace*{0.5em}\mdline{5279}P4 Annotations}\label{sec-p4-annotations}%mdk%mdk + +%mdk-data-line={5281} +\noindent\mdline{5281}Table\mdline{5281}~\mdref{tab-p4-annotations}{\mdcaptionlabel{7}}\mdline{5281} lists P4\mdline{5281}\mdsub{16}\mdline{5281} annotations introduced primarily for +the purpose of adding features for the P4Runtime API.%mdk + +%mdk-data-line={5284} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{5286} Annotation}}&\multicolumn{1}{|c|}{{\bfseries\mdline{5286} Description}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{5288} \mdline{5288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{5288}}&\multicolumn{1}{|l|}{\mdline{5288} See section\mdline{5288}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{5288}}\\ +\multicolumn{1}{|l}{\mdline{5289} \mdline{5289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5289}}&\multicolumn{1}{|l|}{\mdline{5289} See section\mdline{5289}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{5289}}\\ +\multicolumn{1}{|l}{\mdline{5290} \mdline{5290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{5290}}&\multicolumn{1}{|l|}{\mdline{5290} See section\mdline{5290}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{5290}}\\ +\multicolumn{1}{|l}{\mdline{5291} \mdline{5291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{5291}}&\multicolumn{1}{|l|}{\mdline{5291} See section\mdline{5291}~\mdref{sec-id-allocation}{6.3}\mdline{5291}}\\ +\multicolumn{1}{|l}{\mdline{5292} \mdline{5292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{5292}}&\multicolumn{1}{|l|}{\mdline{5292} See sections\mdline{5292}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{5292},\mdline{5292}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{5292}}\\ +\multicolumn{1}{|l}{\mdline{5293} \mdline{5293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{5293}}&\multicolumn{1}{|l|}{\mdline{5293} See section\mdline{5293}~\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1}\mdline{5293}}\\ +\multicolumn{1}{|l}{\mdline{5294} \mdline{5294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5294}}&\multicolumn{1}{|l|}{\mdline{5294} See sections\mdline{5294}~\mdref{sec-user-defined-types}{8.5.6}\mdline{5294},\mdline{5294}~\mdref{sec-translation-of-port-numbers}{17.1.1}\mdline{5294}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={5296} +\mdhr{}%mdk + +%mdk-data-line={5297} +\noindent\mdline{5297}\mdcaption{\textbf{Table~\mdcaptionlabel{7}.}~\mdcaptiontext{P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-annotations}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={5300} +\subsection{\mdline{5300}A.2.\hspace*{0.5em}\mdline{5300}A More Complex Value Set Example}\label{sec-value-set-example}%mdk%mdk + +%mdk-data-line={5302} +\noindent\mdline{5302}This section includes a more complex Value Set example, with multiple matches of +different kinds.%mdk + +%mdk-data-line={5305} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5306} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5315} +\noindent\mdline{5315}This P4 Value Set declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={5318} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5319} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5346} +\noindent\mdline{5346}A P4Runtime client can set the membership for this Value Set with \mdline{5346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5346} +messages similar to this one:%mdk + +%mdk-data-line={5349} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5350} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xac}~\}\\ +~~~~~~\}\\ +~~~~~~{\mdcolor{darkgreen}\#~match~for~field\_id~2~is~missing~=\textgreater{}~don't~care~match}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xdc}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~~~ternary~\{~value:~{\mdcolor{purple}0x88}~mask:~{\mdcolor{purple}8}f~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5384;build/P4Runtime-Spec-bib.bbl.mdk:1} +%mdk-data-line={5384;build/P4Runtime-Spec-bib.bbl.mdk:2} +\mdsetrefname{References}%mdk +{\mdbibindent{0}%mdk +\begin{thebibliography}{35}%mdk +\label{sec-bibliography}%mdk + +%mdk-data-line={references.bib:69} +\bibitem{p4spec}\mdbibitemlabel{{}[1]}\textquotedblleft{}$P4_{16}$ 1.1.0 Specification.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.1.0-spec.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0-\hspace{0pt}spec.\hspace{0pt}html}}.\label{p4spec}%mdk%mdk + +%mdk-data-line={references.bib:135} +\bibitem{rfc2698}\mdbibitemlabel{{}[2]}\textquotedblleft{}A Two Rate Three Color Marker.\textquotedblright{} \href{https://tools.ietf.org/html/rfc2698}{{\ttfamily https://\hspace{0pt}tools.\hspace{0pt}ietf.\hspace{0pt}org/\hspace{0pt}html/\hspace{0pt}rfc2698}}.\label{rfc2698}%mdk%mdk + +%mdk-data-line={references.bib:38} +\bibitem{p4complextypes}\mdbibitemlabel{{}[3]}\textquotedblleft{}Complex Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.1.0-spec.html\%23sec-p4-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0-\hspace{0pt}spec.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}p4-\hspace{0pt}type}}.\label{p4complextypes}%mdk%mdk + +%mdk-data-line={references.bib:43} +\bibitem{protodefaults}\mdbibitemlabel{{}[4]}\textquotedblleft{}Default Values for Protobuf 3 ($proto3$) Fields.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23default}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}default}}.\label{protodefaults}%mdk%mdk + +%mdk-data-line={references.bib:79} +\bibitem{p4enums}\mdbibitemlabel{{}[5]}\textquotedblleft{}Enums in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.1.0-spec.html\%23sec-enum-types}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0-\hspace{0pt}spec.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}enum-\hspace{0pt}types}}.\label{p4enums}%mdk%mdk + +%mdk-data-line={references.bib:120} +\bibitem{apiversioning}\mdbibitemlabel{{}[6]}\textquotedblleft{}Google Cloud APIs Versioning.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning}}.\label{apiversioning}%mdk%mdk + +%mdk-data-line={references.bib:125} +\bibitem{apiversioningbackwardscompatibility}\mdbibitemlabel{{}[7]}\textquotedblleft{}Google Cloud APIs Versioning - Backwards-Compatibility.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning\%23backwards_compatibility}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning\#\hspace{0pt}backwards\_\hspace{0pt}compatibility}}.\label{apiversioningbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:150} +\bibitem{grpcauth}\mdbibitemlabel{{}[8]}\textquotedblleft{}gRPC Authentication.\textquotedblright{} \href{https://grpc.io/docs/guides/auth.html}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}guides/\hspace{0pt}auth.\hspace{0pt}html}}.\label{grpcauth}%mdk%mdk + +%mdk-data-line={references.bib:7} +\bibitem{grpc}\mdbibitemlabel{{}[9]}\textquotedblleft{}gRPC Main Site.\textquotedblright{} \href{https://grpc.io}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io}}.\label{grpc}%mdk%mdk + +%mdk-data-line={references.bib:145} +\bibitem{grpcstreamc}\mdbibitemlabel{{}[10]}\textquotedblleft{}gRPC Streaming RPCs in C++.\textquotedblright{} \href{https://grpc.io/docs/tutorials/basic/c.html\%23streaming-rpcs}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}tutorials/\hspace{0pt}basic/\hspace{0pt}c.\hspace{0pt}html\#\hspace{0pt}streaming-\hspace{0pt}rpcs}}.\label{grpcstreamc}%mdk%mdk + +%mdk-data-line={references.bib:115} +\bibitem{p4newtypes}\mdbibitemlabel{{}[11]}\textquotedblleft{}Introducing New Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.1.0-spec.html\%23sec-newtype}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0-\hspace{0pt}spec.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}newtype}}.\label{p4newtypes}%mdk%mdk + +%mdk-data-line={references.bib:140} +\bibitem{p4matchtypes}\mdbibitemlabel{{}[12]}\textquotedblleft{}Match Types in P4.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.1.0-spec.html\%23sec-match-kind-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0-\hspace{0pt}spec.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}match-\hspace{0pt}kind-\hspace{0pt}type}}.\label{p4matchtypes}%mdk%mdk + +%mdk-data-line={references.bib:175} +\bibitem{p4concurrency}\mdbibitemlabel{{}[13]}\textquotedblleft{}P4 Concurrency Model.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.1.0-spec.html\%23sec-concurrency}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0-\hspace{0pt}spec.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}concurrency}}.\label{p4concurrency}%mdk%mdk + +%mdk-data-line={references.bib:1} +\bibitem{p4runtimerepo}\mdbibitemlabel{{}[14]}\textquotedblleft{}p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.\textquotedblright{} \href{https://github.com/p4lang/p4runtime}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4runtime}}.\label{p4runtimerepo}%mdk%mdk + +%mdk-data-line={references.bib:48} +\bibitem{pirepo}\mdbibitemlabel{{}[15]}\textquotedblleft{}p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.\textquotedblright{} \href{https://github.com/p4lang/PI}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}PI}}.\label{pirepo}%mdk%mdk + +%mdk-data-line={references.bib:110} +\bibitem{p4apiwgcharter}\mdbibitemlabel{{}[16]}\textquotedblleft{}P4.org API Working Group Charter.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4_API_WG_charter.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4\_\hspace{0pt}API\_\hspace{0pt}WG\_\hspace{0pt}charter.\hspace{0pt}html}}.\label{p4apiwgcharter}%mdk%mdk + +%mdk-data-line={references.bib:155} +\bibitem{p4actionannotations}\mdbibitemlabel{{}[17]}\textquotedblleft{}P4 Standard Annotations on Table Actions.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.1.0-spec.html\%23sec-table-action-anno}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0-\hspace{0pt}spec.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}action-\hspace{0pt}anno}}.\label{p4actionannotations}%mdk%mdk + +%mdk-data-line={references.bib:74} +\bibitem{psa}\mdbibitemlabel{{}[18]}\textquotedblleft{}Portable Switch Architecture Specification (v1.1.0).\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html}}.\label{psa}%mdk%mdk + +%mdk-data-line={references.bib:12} +\bibitem{proto}\mdbibitemlabel{{}[19]}\textquotedblleft{}Protocol Buffers Main Site.\textquotedblright{} \href{https://developers.google.com/protocol-buffers}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers}}.\label{proto}%mdk%mdk + +%mdk-data-line={references.bib:160} +\bibitem{psaactionselector}\mdbibitemlabel{{}[20]}\textquotedblleft{}PSA Action Selector.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-action-selector}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}action-\hspace{0pt}selector}}.\label{psaactionselector}%mdk%mdk + +%mdk-data-line={references.bib:170} +\bibitem{psaatomicityofcontrolplaneops}\mdbibitemlabel{{}[21]}\textquotedblleft{}PSA Atomicity of Control Plane Operations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-atomicity-of-control-plane-api-operations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}atomicity-\hspace{0pt}of-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}api-\hspace{0pt}operations}}.\label{psaatomicityofcontrolplaneops}%mdk%mdk + +%mdk-data-line={references.bib:180} +\bibitem{psatranslation}\mdbibitemlabel{{}[22]}\textquotedblleft{}PSA Data Plane vs Control Plane Types.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-data-plane-vs-control-plane-values}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}data-\hspace{0pt}plane-\hspace{0pt}vs-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}values}}.\label{psatranslation}%mdk%mdk + +%mdk-data-line={references.bib:165} +\bibitem{psaemptygroupactionappendix}\mdbibitemlabel{{}[23]}\textquotedblleft{}PSA Empty Group Action Appendix.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23appendix-empty-action-selector-groups}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}appendix-\hspace{0pt}empty-\hspace{0pt}action-\hspace{0pt}selector-\hspace{0pt}groups}}.\label{psaemptygroupactionappendix}%mdk%mdk + +%mdk-data-line={references.bib:64} +\bibitem{p4selectexpr}\mdbibitemlabel{{}[24]}\textquotedblleft{}Select Expressions in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.1.0-spec.html\%23sec-select}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0-\hspace{0pt}spec.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}select}}.\label{p4selectexpr}%mdk%mdk + +%mdk-data-line={references.bib:130} +\bibitem{semver}\mdbibitemlabel{{}[25]}\textquotedblleft{}Semantic Versioning.\textquotedblright{} \href{https://semver.org/}{{\ttfamily https://\hspace{0pt}semver.\hspace{0pt}org/\hspace{0pt}}}.\label{semver}%mdk%mdk + +%mdk-data-line={references.bib:99} +\bibitem{protostatus}\mdbibitemlabel{{}[26]}\textquotedblleft{}Status.proto:the Protobuf Status Message.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}src/\hspace{0pt}proto/\hspace{0pt}grpc/\hspace{0pt}status/\hspace{0pt}status.\hspace{0pt}proto}}.\label{protostatus}%mdk%mdk + +%mdk-data-line={references.bib:54} +\bibitem{p4tableproperties}\mdbibitemlabel{{}[27]}\textquotedblleft{}Table Properties in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.1.0-spec.html\%23sec-table-props}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0-\hspace{0pt}spec.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}props}}.\label{p4tableproperties}%mdk%mdk + +%mdk-data-line={references.bib:84} +\bibitem{protoany}\mdbibitemlabel{{}[28]}\textquotedblleft{}The Any Protobuf Message.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23any}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}any}}.\label{protoany}%mdk%mdk + +%mdk-data-line={references.bib:89} +\bibitem{grpcstatus}\mdbibitemlabel{{}[29]}\textquotedblleft{}The gRPC $Status$ Class.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/status.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}impl/\hspace{0pt}codegen/\hspace{0pt}status.\hspace{0pt}h}}.\label{grpcstatus}%mdk%mdk + +%mdk-data-line={references.bib:105} +\bibitem{grpcerrordetails}\mdbibitemlabel{{}[30]}\textquotedblleft{}The gRPC C++ Error Details Library.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/support/error_details.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}support/\hspace{0pt}error\_\hspace{0pt}details.\hspace{0pt}h}}.\label{grpcerrordetails}%mdk%mdk + +%mdk-data-line={references.bib:94} +\bibitem{grpcstatuscodes}\mdbibitemlabel{{}[31]}\textquotedblleft{}The gRPC Canonical Status Codes.\textquotedblright{} \href{https://developers.google.com/maps-booking/reference/grpc-api/status_codes}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}maps-\hspace{0pt}booking/\hspace{0pt}reference/\hspace{0pt}grpc-\hspace{0pt}api/\hspace{0pt}status\_\hspace{0pt}codes}}.\label{grpcstatuscodes}%mdk%mdk + +%mdk-data-line={references.bib:22} +\bibitem{openconfig}\mdbibitemlabel{{}[32]}\textquotedblleft{}The OpenConfig Project.\textquotedblright{} \href{http://openconfig.net}{{\ttfamily http://\hspace{0pt}openconfig.\hspace{0pt}net}}.\label{openconfig}%mdk%mdk + +%mdk-data-line={references.bib:185} +\bibitem{protomessagedifferencer}\mdbibitemlabel{{}[33]}\textquotedblleft{}The Protobuf MessageDifferencer in the C++ API.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.util.message_differencer}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}reference/\hspace{0pt}cpp/\hspace{0pt}google.\hspace{0pt}protobuf.\hspace{0pt}util.\hspace{0pt}message\_\hspace{0pt}differencer}}.\label{protomessagedifferencer}%mdk%mdk + +%mdk-data-line={references.bib:27} +\bibitem{stratum}\mdbibitemlabel{{}[34]}\textquotedblleft{}The Stratum Project.\textquotedblright{} \href{https://stratumproject.org/}{{\ttfamily https://\hspace{0pt}stratumproject.\hspace{0pt}org/\hspace{0pt}}}.\label{stratum}%mdk%mdk + +%mdk-data-line={references.bib:59} +\bibitem{p4valuesets}\mdbibitemlabel{{}[35]}\textquotedblleft{}Value Sets in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.1.0-spec.html\%23sec-value-set}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0-\hspace{0pt}spec.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}value-\hspace{0pt}set}}.\label{p4valuesets}%mdk%mdk +\par%mdk +\end{thebibliography}}%mdk%mdk +}%mdk + + +\end{document} diff --git a/spec/v1.0.0/ellipse.sty b/spec/v1.0.0/ellipse.sty new file mode 100644 index 00000000..7c0ecb3e --- /dev/null +++ b/spec/v1.0.0/ellipse.sty @@ -0,0 +1,318 @@ +%% +%% This is file `ellipse.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ellipse.dtx (with options: `package') +%% +%% Copyright (C) 2015 +%% Daan Leijen +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". +%% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{ellipse} + [2004/11/05 v1.0 .dtx ellipse file] +\RequirePackage{pict2e} + +\providecommand*\pIIe@csedef[1]{\expandafter\edef\csname #1\endcsname} +\newcommand*\pIIe@ellip@csqrt[3]{% + \@ovxx=#1\relax + \ifdim\@ovxx<\z@\@ovxx-\@ovxx\fi + \@ovyy=#2\relax + \ifdim\@ovyy<\z@\@ovyy-\@ovyy\fi + \edef\pIIe@csname{@csqrt(\number\@ovxx,\number\@ovyy)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@ellip@csqrt@% + \pIIe@csedef{\pIIe@csname}{\the\dimen@}% + #3\dimen@ + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} +\newcommand*\pIIe@ellip@csqrt@{% + \@ovdx\@ovxx + \advance\@ovdx by \@ovyy + \dimen@0.7071067\@ovdx + \ifdim\dimen@<\@ovyy\dimen@\@ovyy\fi + \ifdim\dimen@<\@ovxx\dimen@\@ovxx\fi + \ifdim\@ovdx<128\p@ + \edef\@tempa{\strip@pt\@ovxx}% + \@ovxx\@tempa\@ovxx + \edef\@tempa{\strip@pt\@ovyy}% + \@ovyy\@tempa\@ovyy + \advance\@ovxx by \@ovyy + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \fi +} + +\newcommand*\pIIe@atan@{% + \@tempdima\dimen@ + \@tempdimb\@tempdima + \ifdim\@tempdimb<\z@\@tempdimb-\@tempdimb\fi + \dimen@0.0663\@tempdimb + \advance\dimen@ 0.2447pt\relax + \advance\@tempdimb -1pt\relax + \edef\@tempa{\strip@pt\@tempdimb}% + \dimen@\@tempa\dimen@ + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \dimen@-\dimen@ + \advance\dimen@ 0.7853\@tempdima +} + +\newcommand*\pIIe@atantwo[3]{% + \edef\pIIe@csname{@atan2(\number\dimexpr#1\relax,\number\dimexpr#2\relax)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@atantwo@{#1}{#2}{#3}% + \pIIe@csedef{\pIIe@csname}{\the\dimexpr#3\relax}% + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} + +\newcommand*\pIIe@atantwo@[3]{% + \@tempdima\dimexpr#2\relax + \@tempdimb\dimexpr#1\relax + \ifdim\@tempdima=\z@\relax + \ifdim\@tempdimb>\z@\relax\dimen@90\p@ + \else\ifdim\@tempdimb<\z@\relax\dimen@-90\p@ + \else\dimen@0\p@ + \fi\fi + \else + \@tempdimd\z@ + \ifdim\@tempdima<\z@\relax + \ifdim\@tempdimb<\z@\relax\@tempdimd-180\p@ + \else\@tempdimd180\p@ + \fi + \fi + \dimen@\dimexpr1pt * \@tempdimb/\@tempdima\relax + \@tempdimc\dimen@ + \ifdim\@tempdimc<\z@\relax\@tempdimc-\@tempdimc\fi + \ifdim\@tempdimc>\p@\relax + \dimen@\dimexpr1pt * \@tempdima/\@tempdimb\relax + \ifdim\dimen@<\z@\relax\def\@tempsign{-}\else\def\@tempsign{}\fi + \pIIe@atan@ + \dimen@-\dimen@ + \advance\dimen@ by \@tempsign1.5707pt\relax + \else + \pIIe@atan@ + \fi + \dimen@57.29578\dimen@ + \advance\dimen@ by \@tempdimd + \fi + #3\dimen@% +} + +\newcommand*\pIIe@noneto[2]{} +\newcommand*\pIIe@ellip@sincost@[2]{% + \CalculateSin{#1}% + \CalculateCos{#1}% + \@tempdima\UseSin{#1}\p@ + \@tempdimb\UseCos{#1}\p@ + \ifdim\@tempdima=\p@\relax + \pIIe@csedef{@ellipsin#2}{1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else\ifdim\@tempdima=-\p@\relax + \pIIe@csedef{@ellipsin#2}{-1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else + \@tempdimc\@ellipratio\dimexpr1pt * \@tempdima/\@tempdimb\relax + %\typeout{ i#2=\the\@tempdimc, sin(#1)=\the\@tempdima}% + \pIIe@ellip@csqrt{\p@}{\@tempdimc}\@tempdimd + \ifdim\@tempdimb<\z@\relax\@tempdimd-\@tempdimd\fi + \pIIe@csedef{@ellipsin#2}{\strip@pt\dimexpr1pt * \@tempdimc/\@tempdimd\relax}% + \pIIe@csedef{@ellipcos#2}{\strip@pt\dimexpr1pt * \p@/\@tempdimd\relax}% + \fi\fi +} + +\newcommand*\pIIe@ellip@sincost[2]{% + %\typeout{ calc sin cos: angles (#1,#2), radii: (\the\@ovro,\the\@ovri)}% + \edef\@ellipratio{\strip@pt\dimexpr1pt * \@ovro/\@ovri\relax}% + \pIIe@ellip@sincost@{#1}{one}% + \pIIe@ellip@sincost@{#2}{two}% + %\typeout{ sincos(a=#1)=(\@ellipsinone,\@ellipcosone), sincos(a=#2)=(\@ellipsintwo,\@ellipcostwo), }% +} +\newcommand*\pIIe@omega[3]{% + \@tempdima\csname @ellipcos#3\endcsname\@ovro + \advance\@tempdima by #1\relax + \@tempdimb\csname @ellipsin#3\endcsname\@ovri + \advance\@tempdimb by #2\relax +} + +\newcommand*\pIIe@omegai[1]{% + \@tempdimc\csname @ellipsin#1\endcsname\@ovro + \@tempdimc-\@tempdimc + \@tempdimd\csname @ellipcos#1\endcsname\@ovri +} + +\newcommand*\pIIe@ellip@kappa{% + \@ovyy\@ellipsinone\p@ + \@ovxx\@ellipcosone\p@ + \@tempdima\@ellipcostwo\@ovyy + \@tempdima-\@tempdima + \advance\@tempdima by \@ellipsintwo\@ovxx + \@tempdimb\@ellipcostwo\@ovxx + \advance\@tempdimb by \@ellipsintwo\@ovyy + \ifdim\@tempdima=\z@\relax + \edef\@ellipkappa{0}% + \else + \dimen@\dimexpr1pt - \@tempdimb\relax + \dimen@\dimexpr1pt * \dimen@/\@tempdima\relax + \pIIe@ellip@csqrt{2\p@}{1.73205\dimen@}{\dimen@}% + \advance\dimen@ by -\p@ + \divide\dimen@ by 3% + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \edef\@ellipkappa{\strip@pt\dimen@}% + \fi + %\typeout{ calculated kappa: \@ellipkappa}% +} + +\newcommand*\pIIe@elliparc@[5]{% + %\typeout{elliparc: #1, center: (#2, #3), radius (\the\@ovro, \the\@ovri),angle (#4, #5)}% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \pIIe@ellip@sincost{#4}{#5}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@t[5]{% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \CalculateSin{#4}\CalculateCos{#4}% + \edef\@ellipsinone{\UseSin{#4}}% + \edef\@ellipcosone{\UseCos{#4}}% + \CalculateSin{#5}\CalculateCos{#5}% + \edef\@ellipsintwo{\UseSin{#5}}% + \edef\@ellipcostwo{\UseCos{#5}}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@draw[2]{% + \pIIe@ellip@kappa% + \pIIe@omega{#1}{#2}{one}% + %\typeout{ point one: (\the\@tempdima,\the\@tempdimb)}% + \@ellip@startto\@tempdima\@tempdimb + \pIIe@omegai{one}% + \advance\@tempdima by \@ellipkappa\@tempdimc + \advance\@tempdimb by \@ellipkappa\@tempdimd + \pIIe@add@nums\@tempdima\@tempdimb + %\typeout{ control one: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@omega{#1}{#2}{two}% + \pIIe@omegai{two}% + \@tempdimc\@ellipkappa\@tempdimc + \@tempdimd\@ellipkappa\@tempdimd + \@tempdimc-\@tempdimc + \@tempdimd-\@tempdimd + \advance\@tempdimc by \@tempdima + \advance\@tempdimd by \@tempdimb + \pIIe@add@nums\@tempdimc\@tempdimd + %\typeout{ control two: (\the\@tempdimc,\the\@tempdimd)}% + \pIIe@add@CP\@tempdima\@tempdimb + %\typeout{ point two: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@addtoGraph\pIIe@curveto@op +} +\newcommand*\pIIe@elliparc[7][0]{% + \@ovro #4\relax + \@ovri #5\relax + \iffalse%dim\@ovro=\@ovri + \pIIe@arc[#1]{#2}{#3}{#4}{#6}{#7} + \else + \ifdim \@ovro<\z@ \pIIe@badcircarg\else + \ifdim \@ovri<\z@ \pIIe@badcircarg\else + \@arclen #7\p@ \advance\@arclen -#6\p@ + \ifdim \@arclen<\z@ \def\@tempsign{-}\else\def\@tempsign{}\fi + \ifdim \@tempsign\@arclen>720\p@ + \PackageWarning {ellipse}{The arc angle is reduced to -720..720}% + \@whiledim \@tempsign\@arclen>720\p@ \do {\advance\@arclen-\@tempsign360\p@}% + \@tempdima #6\p@ \advance\@tempdima \@arclen + \edef\@angleend{\strip@pt\@tempdima}% + \pIIe@@elliparc{#1}{#2}{#3}{#6}{\@angleend}% + \else + \pIIe@@elliparc{#1}{#2}{#3}{#6}{#7}% + \fi + \fi + \fi + \fi +} +\newcommand*\pIIe@@elliparc[5]{% + \begingroup + \ifdim \@tempsign\@arclen>90\p@ + \divide\@arclen 2% + \@tempdima #4\p@\advance\@tempdima by \@arclen + \edef\@anglemid{\strip@pt\@tempdima}% + \def\@tempa{\pIIe@@elliparc{#1}{#2}{#3}{#4}}% + \expandafter\@tempa\expandafter{\@anglemid}% + \def\@tempa{\pIIe@@elliparc{2}{#2}{#3}}% + \expandafter\@tempa\expandafter{\@anglemid}{#5}% + \else + \pIIe@elliparc@{#1}{#2}{#3}{#4}{#5}% + \fi + \endgroup +}% + +\newcommand*\pIIeelliparc[7][0]{% + \@killglue + \pIIe@elliparc[#1]{#2\unitlength}{#3\unitlength}{#4\unitlength}{#5\unitlength}{#6}{#7}% + \ignorespaces% +} +\ifx\undefined\elliparc\else + \PackageWarning{ellipse}{\protect\elliparc\space is redefined}% +\fi +\let\elliparc\pIIeelliparc + +\newcommand*\pIIeearc + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\newcommand*\pIIe@earc@[3][0,360]{\pIIe@earc@@(#1){#2}{#3}} +\def\pIIe@earc@@(#1,#2)#3#4{% + \if@tempswa + \pIIe@moveto\z@\z@ + \pIIe@elliparc{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@closepath\pIIe@fillGraph + \else + \pIIe@elliparc[1]{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@strokeGraph + \fi} +\ifx\undefined\earc\else + \PackageWarning{ellipse}{\protect\earc\space is redefined}% +\fi +\let\earc\pIIeearc + +\newcommand*\pIIeellipse + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\let\ellipse\pIIeellipse + +\endinput +%% +%% End of file `ellipse.sty'. diff --git a/spec/v1.0.0/embedded-plus-single-remote-controller.png b/spec/v1.0.0/embedded-plus-single-remote-controller.png new file mode 100644 index 00000000..2e0f1803 Binary files /dev/null and b/spec/v1.0.0/embedded-plus-single-remote-controller.png differ diff --git a/spec/v1.0.0/embedded-plus-single-remote-controller.svg b/spec/v1.0.0/embedded-plus-single-remote-controller.svg new file mode 100644 index 00000000..9fe2ce9c --- /dev/null +++ b/spec/v1.0.0/embedded-plus-single-remote-controller.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spec/v1.0.0/embedded-plus-two-remote-controllers.png b/spec/v1.0.0/embedded-plus-two-remote-controllers.png new file mode 100644 index 00000000..b6dc04fc Binary files /dev/null and b/spec/v1.0.0/embedded-plus-two-remote-controllers.png differ diff --git a/spec/v1.0.0/embedded-plus-two-remote-controllers.svg b/spec/v1.0.0/embedded-plus-two-remote-controllers.svg new file mode 100644 index 00000000..0f97ba38 --- /dev/null +++ b/spec/v1.0.0/embedded-plus-two-remote-controllers.svg @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + + + Entities + + + + + + + \ No newline at end of file diff --git a/spec/v1.0.0/embedded-plus-two-remote-ha-controllers.png b/spec/v1.0.0/embedded-plus-two-remote-ha-controllers.png new file mode 100644 index 00000000..f663e9bf Binary files /dev/null and b/spec/v1.0.0/embedded-plus-two-remote-ha-controllers.png differ diff --git a/spec/v1.0.0/embedded-plus-two-remote-ha-controllers.svg b/spec/v1.0.0/embedded-plus-two-remote-ha-controllers.svg new file mode 100644 index 00000000..710111fa --- /dev/null +++ b/spec/v1.0.0/embedded-plus-two-remote-ha-controllers.svg @@ -0,0 +1,510 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + Master (Active) + + + + + + Slave (Standby) + + + + + + + \ No newline at end of file diff --git a/spec/v1.0.0/error-report.png b/spec/v1.0.0/error-report.png new file mode 100644 index 00000000..766cb77f Binary files /dev/null and b/spec/v1.0.0/error-report.png differ diff --git a/spec/v1.0.0/error-report.svg b/spec/v1.0.0/error-report.svg new file mode 100644 index 00000000..a2709a72 --- /dev/null +++ b/spec/v1.0.0/error-report.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StatusCode error_code_; // canonical error codestring error_message_;string binary_error_details_; // serialized google.rpc.Status + + + + + + + + + + + + + google.rpc.Status + + + + + + int32 error_code; // canonical error codestring message;repeated Any details; // P4Error + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + + + p4.Error + + + + + + p4.Error + + + + + + + + + + + + + + + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + grpc::Status + + + + + + + \ No newline at end of file diff --git a/spec/v1.0.0/longbox.sty b/spec/v1.0.0/longbox.sty new file mode 100644 index 00000000..cab48934 --- /dev/null +++ b/spec/v1.0.0/longbox.sty @@ -0,0 +1,853 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longbox}[2015/12/01, Daan Leijen, Provides basic longbox that can break over pages] +\RequirePackage{options} + +\@ifclassloaded{beamer}{% + \newcommand\lb@savefootnotes{}% + \newcommand\lb@restorefootnotes{}% +}% +{\RequirePackage{footnote}% + \newcommand\lb@savefootnotes{\savenotes}% + \newcommand\lb@restorefootnotes{\spewnotes}% +} + + +% -------------------------------------------------------- +% Debugging +% -------------------------------------------------------- + +\newcommand*\lb@debug[1]{% + \ontoggle{lb@debug}{\typeout{longbox debug: #1}}% +} +\newcommand*\lb@typeout[1]{% + \ontoggle{lb@verbose}{\typeout{longbox: #1}}% +} +\newcommand*\lb@warncannotsplit{% + \PackageWarning{longbox}{Cannot split box; it seems you are using a non-splittable contents}% +} +\newcommand*\lb@warnbadsplit[1]{% + \PackageWarning{longbox}{Bad split (underful vbox by \the#1)}% +} + + +% -------------------------------------------------------- +% Utilities for LaTeX internals +% -------------------------------------------------------- + +% Suppress the indentation on the following paragraph +\providecommand\nofirstindent{\@afterindentfalse\@afterheading} + +% Suppress the paragraph skip on the following paragraph +\providecommand\nofirstparskip{\addvskip{-\parskip}} + +% In contrast to addvspace, addvskip is not suppressed in a minipage +\providecommand\addvskip[1]{% + \ifvmode + \ifdim\lastskip=\z@ + \vskip #1\relax + \else + \@tempskipb#1\relax\@xaddvskip + \fi + \else\@noitemerr\fi +} + + +% Skip to 0.3\baselineskip multiple taking prevdepth into account. +\newskip\lb@prevdepth +\newcommand\lb@skiptobaseline{% + \global\lb@prevdepth=-\@m\p@\relax + \ifvmode + \ifdim\lastskip=\z@\relax + \ifdim\prevdepth=-\@m\p@\else + \dimen@\prevdepth + % Calculate the modulus of the previous depth with 0.3|\baselineskip| in |\dimen@|. + \@tempcnta\prevdepth + \@tempskipa=0.3\baselineskip\relax + \@tempcntb=\@tempskipa\relax + \divide \@tempcnta by \@tempcntb + \dimen@\prevdepth + \advance\dimen@ -\@tempcnta\@tempskipa + % Skip back by that amount, and then skip by 0.3|\baselineskip|. + \vskip -\dimen@ + \vskip \@tempskipa\relax + \global\lb@prevdepth=\@tempskipa\relax + \fi + \fi + \fi +} + +% unvbox a box, and return a vbox with a given background color +% \unvcolorbox{}{} +\newcommand\unvcolorbox[2]{% + \ifoptionblank{#1}{\vbox{\unvbox#2}}{% + \lb@debug{vcolorbox: #1}% + \vbox{\offinterlineskip + \hbox to \z@{\vbox to \z@{\optioncolor{#1}\hrule\@width\wd#2\@height\ht#2\@depth\dp#2\vss}\hss}% + \unvbox#2% + }% + }% +} + +% create a vbox with a given background color +\newcommand\vcolorbox[2]{% + \eifblank{#1}{\vbox{#2}}{% + \setbox\z@=\vbox{#2}\relax + \unvcolorbox{#1}{\z@}% + }% +}% + +% -------------------------------------------------------- +% The following macros come from mdframed +% -------------------------------------------------------- + +% Determine the amount of free space left on the current page +\newlength\lb@freevspace +\newcommand*\lb@setfreevspace@page{% + \lb@debug{ determine free space}% + \bgroup\@nobreakfalse\addpenalty\z@\egroup% + \penalty\@M\relax\vskip 2\baselineskip\relax% + \penalty9999\relax\vskip -2\baselineskip\relax% + \penalty9999% + \ifdim\pagegoal=\maxdimen\relax% + \lb@freevspace=\vsize% + \else + \lb@freevspace=\dimexpr\pagegoal-\pagetotal-\parskip\relax% + \fi + \lb@debug{free space: \the\lb@freevspace, in page: \the\textheight, vsize=\the\vsize}% +} + +\newcommand*\lb@shiftdim[2]{% + %\letoption{#1}\lb@list + \expandafter\lb@setheadtail@#1,\relax + \eifblank{\lb@head}{}{\option@invoke{/longbox/@breakat-previous}{\lb@head}}% + #2\option{/longbox/@breakat-previous}% + \eifblank{\lb@tail}{}{\let#1\lb@tail}% push back tail +} +\def\lb@comma{,}% +\def\lb@setheadtail@#1,#2\relax{% + \def\lb@head{#1}% + \def\lb@tail{#2}% adds commas! +} + +\newcommand*\lb@setfreevspace{% + \eifblank{\lb@breakat}{\lb@setfreevspace@page}{% + \def\lb@eject{\par}%no eject + \lb@extrasplit=\z@\relax% + \lb@shiftdim{\lb@breakat}\lb@freevspace + \ifdim\lb@freevspace>\z@\else\lb@setfreevspace@page\fi + }% +} + + +% Suppress overfull-underfull vbox messages +\newcommand*\lb@ignorevbadness{% + \edef\lb@currentvbadness{\the\vbadness}% + \edef\lb@currentvfuzz{\the\vfuzz}% + \vbadness=\@M\relax% + \vfuzz=\maxdimen\relax% + \afterassignment\lb@restorevbadness +} +\newcommand*\lb@restorevbadness{% + \vbadness=\lb@currentvbadness\relax + \vfuzz=\lb@currentvfuzz\relax +} + + +% -------------------------------------------------------- +% The 'long vbox' (lvbox) environment collects long material +% into a long \vbox, instead of a \hbox like a lrbox in latex. +% The collected box can contain any box, minipage, lrbox, fbox etc, +% but not outer-par material like a figure. Footnotes can be +% dealt with useing lb@savefootnotes. +% +% The material is typeset in a \vbox according to a given width. +% inside the environment, the boolean 'inlvbox' is true. +% +% \begin{lvbox}{}{} +% -------------------------------------------------------- + +\newif\ifinlvbox +\newcommand\lvbox[4]{% + \setbox#1\vbox\bgroup + \begingroup + \inlvboxtrue + % reset defaults + \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\par\@@par + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + % set margin and linewidth + \leftmargin=#2\relax\rightmargin=#4\relax + \@totalleftmargin=\leftmargin% + %\leftskip=#2\relax\rightskip=#4\relax\@rightskip=#4\relax + \linewidth=#3\relax + % set primitive tex margins + \leftskip=\@totalleftmargin% + \rightskip=\rightmargin% + \@rightskip=\rightmargin% + \hsize=\dimexpr\@totalleftmargin+\linewidth+\rightmargin\relax + \columnwidth\hsize + \textwidth\hsize + \nofirstindent + %\nofirstparskip +} +\def\endlvbox{\endgroup\egroup} + + + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + + +\newsavebox\lb@headbox +\newsavebox\lb@savebox +\newsavebox\lb@mainbox + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@setbaseline[1]{% + %\typeout{ set baseline, \the\dp#1,\the\ht#1}% + \ifcase\lb@baseline% + \relax%bottom + \or%middle + \setbox#1=\vbox{\hbox{\lower \dimexpr(\dp#1 + \ht#1)/2 - \dp#1\relax\vbox{\unvbox#1}}}% + \or%top + \setbox#1=\vtop{\unvbox#1}% + \fi + %\typeout{ .new dim: \the\dp#1, \the\ht#1}% +} + + +\@ifundefined{define@key}{}% + {\define@key{longbox}{options}{\options{#1}\option{/longbox/adjust-options}}}% + +\newcommand*\lb@render@breakbox{% + %\typeout{render breakbox entry (in output routine), height=\the\bb@height}% + \bb@restorekeys{longbox}% + \lb@skiptop=\ifbb@isfirst\option{/longbox/skip-top}\else\option{/longbox/skip-break-top}\fi\relax + \lb@skipbottom=\ifbb@islast\option{/longbox/skip-bottom}\else\option{/longbox/skip-break-bottom}\fi\relax + \lb@skipbreaktop=\ifbb@isfirst 0pt\else\option{/longbox/skip-break-top}\fi + \lb@skipbreakbottom=\ifbb@islast 0pt\else\option{/longbox/skip-break-bottom}\fi + %\typeout{ render: skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom, break-top=\the\dimexpr\option{/longbox/skip-bottom}}% + \options{% + /longbox/@part-height=\bb@height + \lb@skipbreaktop + \lb@skipbreakbottom, + /longbox/@part-width=\option{/longbox/width} + \option{/longbox/skip-left} + \option{/longbox/skip-right},%\bb@width, + /longbox/@part-depth=0pt, + /longbox/@part-needtop=\ifbb@isfirst true\else false\fi, + /longbox/@part-needbottom=\ifbb@islast true\else false\fi, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-depth=\option{/longbox/@part-depth}, + }% + %\typeout{breakbox: width=\expandafter\the\option{/longbox/width}, \the\bb@width, \the\dimexpr\option{/longbox/@part-width}}% + \vbox{% + \kern -\lb@skipbreaktop% todo: move to breakbox? + \option{/longbox/render}% + \kern -\lb@skipbreakbottom + }% +} + +\newcommand*\lb@render@vbox[1]{% + \lb@debug{render vbox entry}% + \lb@restoreoptions + \lb@skiptop=\dimexpr\iftoggle{/longbox/@part-needtop}{\option{/longbox/skip-top}}{\option{/longbox/skip-break-top}}\relax + \lb@skipbottom=\dimexpr\iftoggle{/longbox/@part-needbottom}{\option{/longbox/skip-bottom}}{\option{/longbox/skip-break-bottom}}\relax + %\typeout{ skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom}% + % add top skip while maintaining the baseline. + \ifdim\lb@skiptop=\z@\relax\else + \setbox\z@=\vtop{\unvcopy#1}% + \dimen@=\ht\z@ + \setbox#1=\vbox{\offinterlineskip + \hrule width \z@ height \dimexpr\dimen@ + \lb@skiptop\relax depth -\dimen@ + \unvbox#1% + }% + \fi + % add bottom skip while maintaining the baseline. + \ifdim\lb@skipbottom=\z@\relax\else + \dimen@=\dp#1% + \setbox#1=\vbox{\offinterlineskip\unvbox#1\hrule width \z@ height -\dimen@ depth \dimexpr\dimen@ + \lb@skipbottom\relax}% + \fi + \lb@setbaseline{#1}% + \options{% + /longbox/@part-height=\dimexpr\ht#1 + \dp#1\relax, + /longbox/@part-width=\dimexpr\wd#1 + \option{/longbox/skip-left} + \option{/longbox/skip-right}\relax, + /longbox/@part-depth=\dp#1, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-depth=\option{/longbox/@part-depth} - \lb@skipbottom, + }% + %\typeout{ longbox: height=\the\dimexpr\option{/longbox/@content-box-height}, outer height=\the\dimexpr\option{/longbox/@part-height}\relax}% + % lower the box depending on vertical alignment + \ifcase\option{/longbox/vertical-align/@ord}\relax + \@tempdima\z@ + \or + %bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%middle + \@tempdima\dimexpr0.5\option{/longbox/@part-height} - \option{/longbox/@part-depth}\relax + \or%top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%text-bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%text-top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%super + \@tempdima=-0.9ex% + \or%sub + \@tempdima=0.7ex% + \else + \@tempdima\z@ + \fi + \advance\@tempdima by -\option{/longbox/raise}% + \option@invoke{/longbox/@lower}{\@tempdima}% + \noindent\hbox{\lower \@tempdima\vbox{\offinterlineskip + \hbox to \z@{% + \vbox to \z@{% + \hbox{\lower \option{/longbox/@part-height}\vbox{\offinterlineskip{\option{/longbox/render}}}}% + \vss}% + \hss + }% + \hbox{% + \ifdim\option{/longbox/skip-left}=\z@\else\hskip\option{/longbox/skip-left}\fi + \box#1% + \ifdim\option{/longbox/skip-right}=\z@\else\hskip\option{/longbox/skip-right}\fi + %$\box#1% + }% + }}% +} + +\newcommand*\lb@single@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} +\newcommand*\lb@first@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@middle@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@last@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand*\lb@env@start{% + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore +} + +\newcount\lb@usevbox +\newlength\lb@width +\newlength\lb@height +\newlength\lb@skiptop +\newlength\lb@skipright +\newlength\lb@skipbottom +\newlength\lb@skipleft +\newlength\lb@skipbreaktop +\newlength\lb@skipbreakbottom +\newlength\lb@outerwidth +\newlength\lb@extrasplit +\newcount\lb@textalign +\newcount\lb@baseline +\newtoggle{lb@baselineskip}% +\newtoggle{lb@breakable}% +\newtoggle{lb@debug}% +\newtoggle{lb@verbose}% +\def\lb@breakat{}% +\def\lb@halign{}% +\def\lb@eject{}% +\def\lb@insertafter{} +\def\lb@insertbefore{} + +\newcommand*\lb@peekoptions[1]{% + % process options inside a group and just set necessary parameters + % this way, nested boxes don't influence each other's parameters + \begingroup + \options{#1}% + \option{/longbox/adjust-options}% + \protected@edef\lb@temp{\endgroup + \lb@width=\the\dimexpr\option{/longbox/width}\relax + \lb@height=\the\dimexpr\option{/longbox/height}\relax + \lb@textalign=\the\numexpr\option{/longbox/text-align/@ord}\relax + \lb@baseline=\the\numexpr\option{/longbox/baseline/@ord}\relax + \lb@skiptop=\the\dimexpr\option{/longbox/skip-top}\relax + \lb@skipright=\the\dimexpr\option{/longbox/skip-right}\relax + \lb@skipbottom=\the\dimexpr\option{/longbox/skip-bottom}\relax + \lb@skipleft=\the\dimexpr\option{/longbox/skip-left}\relax + \lb@skipbreaktop=\the\dimexpr\option{/longbox/skip-break-top}\relax + \lb@skipbreakbottom=\the\dimexpr\option{/longbox/skip-break-bottom}\relax + \lb@usevbox=\iftoggle{/longbox/use-vbox}{1}{0}\relax + \lb@outerwidth=\the\dimexpr\option{/longbox/outer-width}\relax + \lb@extrasplit=\the\dimexpr\option{/longbox/split-minimum}\relax + \def\noexpand\lb@insertafter{\option{/longbox/insert-after}}% + \def\noexpand\lb@insertbefore{\option{/longbox/insert-before}}% + \def\noexpand\lb@breakat{\option{/longbox/breakat}}% + \def\noexpand\lb@halign{\option{/longbox/height-align}}% + \def\noexpand\lb@eject{\option{/longbox/eject}}% + \noexpand\csname toggle\iftoggle{/longbox/baseline-skip}{true}{false}\endcsname{lb@baselineskip}% + \noexpand\csname toggle\iftoggle{/longbox/breakable}{true}{false}\endcsname{lb@breakable}% + \noexpand\csname toggle\iftoggle{/longbox/debug}{true}{false}\endcsname{lb@debug}% + \noexpand\csname toggle\iftoggle{/longbox/verbose}{true}{false}\endcsname{lb@verbose}% + }% + \lb@temp +} + +\newenvironment{longbox@env}[2]{% + % save options + \lb@peekoptions{#1,#2}% + % + \ifnum\lb@usevbox=0\relax + \lb@debug{start breakbox}% + \let\bb@render\lb@render@breakbox + \bb@savekeys{longbox}{options={#1,#2,outer-width=\the\lb@outerwidth}}% + \iftoggle{lb@baselineskip}{\typeout{**insert bskip}}{\typeout{**suppress bskip}\vskip 1pt}% + \begin{breakbox}% + \ifdim\lb@skiptop=\z@\relax\else\vspace{\lb@skiptop}\fi% + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \begin{bb@margins}{\lb@skipleft}{\dimen@}% + \else + \lb@debug{start vbox}% + \def\lb@restoreoptions{\options{#1,#2}\option{/longbox/adjust-options}}% + \lb@savefootnotes + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \lb@debug{ width=\the\lb@width, linewidth=\the\linewidth, skipleft=\the\lb@skipleft, right=\the\lb@skipright, total right=\the\dimen@}% + \iftoggle{lb@baselineskip}{\lb@skiptobaseline}{\lb@prevdepth=-\@m pt}% + \lvbox{\lb@mainbox}{0pt}{\lb@width}{0pt}%{\lb@skipleft}{\lb@width}{\lb@skipright}% + \prevdepth=\lb@prevdepth + \fi + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore + \begingroup +}{% + \par\unskip + \endgroup + \lb@insertafter + %\ifdim\lb@skipbottom=\z@\relax\else\vskip\lb@skipbottom\fi% + \ifnum\lb@usevbox=0\relax + \end{bb@margins}% + \ifdim\lb@skipbottom=\z@\relax\else\hrule width \z@ height \lb@skipbottom\fi%\vspace{\lb@skipbottom}\fi% + \iftoggle{lb@baselineskip}{}{\vskip 1sp}% + \end{breakbox}% + \lb@debug{end breakbox}% + \else + \ontoggle{lb@baselineskip}{\lb@skiptobaseline}% + \endlvbox% + \lb@debug{initial lvbox: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@processbox + %\setbox\lb@mainbox=\hbox{\lower \lb@skipbottom\vbox{\offinterlineskip\unvbox\lb@mainbox}}% + \lb@restorefootnotes + \lb@debug{end vbox}% + \fi +} + +\newcommand\longbox@cmd[3]{% + \begingroup + %\options{/options/collectunknown,/longbox/scoped,#2}% set scoped options first + %\option{/longbox/scoped/@adjust-options}% + \lb@peekoptions{#1,#2}% + \leavevmode + %\setbox\lb@mainbox=\hbox{% + % \begingroup + % #3% + % \endgroup + %}% + \setbox\lb@mainbox=\hbox{% + \begingroup + \ifcase\lb@textalign\relax + %default=left + \or%left + \or\hss%center + \or\hss%right + \else%justify + \fi + \lb@insertbefore + #3% + \lb@insertafter + \ifnum\lb@textalign<3\relax\hss\fi% default,left,center + \endgroup + }% + \options{#1,#2}% + \ifdim\option{/longbox/width}=-1sp\relax + \options{/longbox/width=\wd\lb@mainbox}%set to natural width + \fi + \option{/longbox/adjust-options}% + % make it a vbox + \setbox\lb@mainbox=\vbox{\offinterlineskip% + \hbox to \option{/longbox/width}{% + \unhbox\lb@mainbox + }% + }% + \def\lb@restoreoptions{}% + \letoption{/longbox/height-align}\lb@halign + \lb@height=\option{/longbox/height}\relax + \lb@baseline=\option{/longbox/baseline/@ord}\relax + \lb@processbox + \endgroup +} + +\newcommand\lb@processbox{% + \ifdim\lb@height<0pt\relax + \lb@setbaseline{\lb@mainbox}% + \else + \lb@restrictheight + \fi + \lb@typesetbox +} + +\newcommand\lb@typesetbox{% + \ifinlvbox + \iftoggle{lb@breakable}{% + %\lb@debug{disable breakable due to nesting of long-boxes}% + \togglefalse{lb@breakable}% + }{}% + \fi + \ifhmode\lb@single@{\lb@mainbox}\else\lb@typeset\fi +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@restrictheight{% + \lb@typeout{restrict height to \the\lb@height}% + \lb@splitheight=\lb@height% + %lb@debug{before height split: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + %split failed.. do nothing + \lb@debug{could not restrict height}% + \else + % store splitted off content in the mainbox (and discard the rest) + \setbox\lb@mainbox\vbox{\unvbox\lb@headbox}% + \lb@debug{restricted height to \the\ht\lb@mainbox}% + \fi + % set baseline + \lb@setbaseline{\lb@mainbox}% + % height align + %\letoption{/longbox/height-align}\lb@halign + \eifstrequal{\lb@halign}{bottom}% + {\setbox\lb@mainbox=\vbox{\hbox{\vbox to \lb@splitheight{\vss\unvbox\lb@mainbox}}}}% + {\eifstrequal{\lb@halign}{middle}% + {\dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\hbox{% + \lower \dimexpr0.5\dimen@ + \dp\lb@mainbox\relax% + \vbox to \lb@splitheight{\vss\unvbox\lb@mainbox\vss}}}}% + {% default is top + \dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\vtop to \lb@splitheight{\box\lb@mainbox\vss}}% + }% + }% +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newlength\lb@neededvspace +\newcommand\lb@typeset[1][0pt]{% + \iftoggle{lb@breakable}{% + \lb@setfreevspace + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skiptop+\lb@skipbottom\relax}% + \lb@debug{needed: \the\lb@neededvspace, available: \the\lb@freevspace}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@single@{\lb@mainbox}% + \else + \lb@typeout{longbox needs splitting}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skiptop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \ifdim\dimexpr\lb@freevspace + #1\relax<\textheight\relax % test if we were at a fresh page.. (and prevent infinite recursion) + \lb@debug{failed to split the box, inserting a page break}% + \hrule \@height\z@ \@width\hsize + \lb@eject% + \lb@typeset[\textheight]% try again, but pass \textheight to guard against infinite recursion + \else + % on a fresh page we should not fail anymore.. just output as is.. + % lb@warncannotsplit + \lb@single@{\lb@mainbox}% + \fi + \else + % first part success + \lb@typeout{first part splitted}% + \lb@first@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest + \fi + \fi + }{%\else + \lb@debug{unbreakable box}% + \lb@single@{\lb@mainbox}% always directly output an unbreakable box + }% +} + +\newcommand\lb@typesetrest{% + \lb@setfreevspace% + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skipbottom+\lb@skipbreaktop\relax}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@typeout{output last part of box}% + \lb@last@{\lb@mainbox}% + \else + \lb@debug{split box further}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skipbreaktop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \lb@typeout{failed to split box!}% + \lb@last@{\lb@mainbox}% + \else + % middle part success + \lb@typeout{output middle part of box}% + \lb@middle@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest% continue the iteration... + \fi + \fi +} + +% -------------------------------------------------------- +% Split a long vbox over multiple pages. +% This code is based on similar code in the mdframed package +% -------------------------------------------------------- + +\newlength\lb@splitheight +\newlength\lb@insurance % tiny extra space to ensure our box will really fit +\setlength\lb@insurance{1pt} + +% expects split target height in lb@splitheight, and splits off the start of lb@mainbox to lb@headbox +\newcommand\lb@splitbox{% + \ifdim\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax>\lb@splitheight\relax + % the main box is larger than our target split height.. + \ifdim\lb@extrasplit>\lb@splitheight\relax + % not enough space to bother + \lb@typeout{not enough space on page for a split}% + \setbox\lb@headbox=\vbox{}% empty head + \else + % try a split; lower the split height a bit so we are sure to fit + \advance\lb@splitheight -\lb@insurance\relax + \lb@debug{split: \the\lb@splitheight, from \the\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax}% + \setbox\lb@savebox=\vbox{\unvcopy\lb@mainbox}% save original + \lb@trysplit{\lb@splitheight}% + \ifdim\dimexpr\ht\lb@headbox + \dp\lb@headbox>\lb@splitheight\relax + % too big, bad split. Try other splits.. iterate N times with 1 or 5pt less before giving up + \dimen@=\lb@splitheight\relax + \@tempcnta=\z@\relax + \loop + \ifdim\dimexpr\ht\lb@headbox+\dp\lb@headbox\relax>\lb@splitheight\relax + \ifnum\@tempcnta<50% + \advance\dimen@ by -\p@\relax% try a slightly smaller height.. + \else + \advance\dimen@ by -5\p@\relax% try larger increase after 50pt.. + \fi + \advance\@tempcnta by \@ne\relax + \lb@ignorevbadness + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \lb@trysplit{\dimen@}% + \ifdim\lb@extrasplit<\dimen@\relax\else\lb@splitstop\fi % don't try to split too small + \ifnum\@tempcnta<100\relax\else\lb@splitstop\fi % and not more than N attempts + \repeat% + \ifnum\@tempcnta<100\relax + \dimen@=\dimexpr\lb@splitheight - \ht\lb@headbox - \dp\lb@headbox\relax + \ifdim\dimen@>\option{/longbox/split-badness}\relax + \lb@warnbadsplit{\dimen@}% + \fi + \fi + \fi + \fi + \else + % mainbox fits in our target lb@splitheight + \setbox\lb@headbox=\vbox{\unvbox\lb@mainbox}% + \setbox\lb@mainbox=\vbox{}% + \fi +} + +\newcommand\lb@splitstop{% + \lb@typeout{cannot find a good split}% + \let\iterate\relax + \lb@warncannotsplit + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \setbox\lb@headbox=\vbox{}% empty head + \@tempcnta=\@M\relax +} + +\newcommand\lb@trysplit[1]{% try to split at given height + \lb@typeout{try to split at: \the\dimexpr #1\relax}% + \lb@ignorevbadness + \setbox\lb@headbox=\vsplit\lb@mainbox to #1\relax% + \setbox\lb@headbox=\vbox{\unvbox\lb@headbox}% + \setbox\lb@mainbox=\vbox{\unvbox\lb@mainbox}% +} + +% -------------------------------------------------------- +% The longbox environment uses options to set its options +% -------------------------------------------------------- + + +% keys and styles that can be set once globally +\options{% + /longbox/.new family, +}% + +\options{/longbox,% + % computed + @part-needtop/.new toggle, + @part-needbottom/.new toggle, + @part-height/.new length, + @part-width/.new length, + @part-depth/.new length, + @content-box-height/.new length, + @content-box-width/.new length, + @content-box-depth/.new length, + @breakat-previous/.new length, + @lower/.new length, + % + debug/.new toggle, + verbose/.new toggle, + render/.new value =\lb@render@fbox, + adjust-options/.new value = {\longbox@adjustoptions}, + eject/.new value = {\protect\vfill\protect\eject}, + use-vbox/.new toggle = true, + split-minimum/.new length = {1.5\baselineskip}, + split-badness/.new length = \baselineskip, + % + height-align/.new choice= {top,middle,bottom}, + baseline/.new choice = {bottom,middle,top}, + text-align/.new choice = {default,left,center,right,justify}, + vertical-align/.new choice = {baseline,bottom,middle,top,text-bottom,text-top,super,sub}, + raise/.new length = {0pt}, + baseline-skip/.new toggle =true, + % + height/.new length = -1sp, + width/.new length = -1sp, + outer-height/.new length= -1sp, + outer-width/.new length = -1sp, + insert-before/.new value= {}, + insert-after/.new value = {}, + breakat/.new value = {}, + breakable/.new toggle = false, + skip/.new style = {skip-top=#1,skip-right=#1,skip-bottom=#1,skip-left=#1}, + skip-top/.new length, + skip-right/.new length, + skip-bottom/.new length, + skip-left/.new length, + skip-break-bottom/.new length, + skip-break-top/.new length, +} + +\newcommand\longbox@adjustoptions{% + %\typeout{ standard longbox adjustoptions}% + \lb@debug{ current width=\the\dimexpr\option{/longbox/width}, outer=\the\dimexpr\option{/longbox/outer-width}, linewidth=\the\linewidth}% + \ontoggle{/longbox/debug}{\option@invoke{/longbox/verbose}{true}}% + % adjust height + \ifdim\option{/longbox/height}=-1sp\relax + \ifdim\option{/longbox/outer-height}=-1sp\else + \option@invoke{/longbox/height}% + {\option{/longbox/outer-height}-\option{/longbox/skip-top}-\option{/longbox/skip-bottom}}% + \fi + \fi + % set width + \ifdim\option{/longbox/width}=-1sp\relax + \ifdim\option{/longbox/outer-width}=-1sp\relax + \option@invoke{/longbox/outer-width}{\linewidth}% + \fi + \dimen@=\dimexpr\option{/longbox/outer-width}-\option{/longbox/skip-left}-\option{/longbox/skip-right}\relax + \ifdim\dimen@<\z@\relax\dimen@=\z@\fi + \option@invoke{/longbox/width}{\dimen@}% + \fi + % use a breakbox whenever we are in external vertical mode and not width or height restricted. + \iftoggle{/longbox/use-vbox}{}{% + \ifinner\toggletrue{/longbox/use-vbox}\else + \ifhmode\toggletrue{/longbox/use-vbox}\else + \ifdim\option{/longbox/height}>-1sp\toggletrue{/longbox/use-vbox}\else + \iftoggle{/longbox/breakable}{}{\toggletrue{/longbox/use-vbox}}% + \ifoptionblank{/longbox/breakat}{}{\toggletrue{/longbox/use-vbox}}% + \fi\fi\fi + }% +} + +\newenvironment{longbox}[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \begin{longbox@env}{/longbox}{#1}% +}{\end{longbox@env}} + +\newcommand\lbox[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \longbox@cmd{/longbox}{#1}% +} + +\newcommand*\lb@render@fbox{% + %\typeout{render defaultbox: bgcolor=\bb@bgcolor, needtop=\iftoggle{/longbox/@part-needtop}{true}{false}}% + \@ovdx=\dimexpr\option{/longbox/@part-width} - 2\fboxrule\relax% + \@ovdy=\dimexpr\option{/longbox/@part-height}\relax% + \iftoggle{/longbox/@part-needbottom}% + {\@tempdima=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdima=\dimexpr\fboxrule + \bb@stickout\relax + \advance\bb@height by \@tempdima + \advance\@ovdy by \@tempdima}% + \iftoggle{/longbox/@part-needtop}% + {\@tempdimb=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdimb=\dimexpr\bb@stickout\relax + \advance\bb@height by \@tempdimb + \advance\@ovdy by \@tempdimb}% + % + \hbox{\lower \@tempdima\vbox{% + \vskip -\@tempdimb + \ontoggle{/longbox/@part-needtop}{\lb@debug{toprule wd=\expandafter\the\option{/longbox/width}}\hrule width \option{/longbox/@part-width} height \fboxrule}% + \hbox{% + \vrule width \fboxrule height \@ovdy% + \ifx\bb@bgcolor\@empty + \vrule width \@ovdx height \z@\relax + \else + {\color{\bb@bgcolor}\vrule width \@ovdx height \@ovdy}% + \fi + \vrule width \fboxrule height \@ovdy% + }% + \ontoggle{/longbox/@part-needbottom}{\hrule width \option{/longbox/@part-width} height \fboxrule}% + }}% +} \ No newline at end of file diff --git a/spec/v1.0.0/longfbox.sty b/spec/v1.0.0/longfbox.sty new file mode 100644 index 00000000..0df01331 --- /dev/null +++ b/spec/v1.0.0/longfbox.sty @@ -0,0 +1,1344 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longfbox}[2015/12/01, Daan Leijen, Provides long fbox that can break over pages] + +\RequirePackage{options} +\RequirePackage{longbox} +\RequirePackage{pict2e} +\RequirePackage{ellipse} + +% -------------------------------------------------------- +% Dimension calulations +% -------------------------------------------------------- + +% dimmin/dimmax return minimum or maximum dimension +\providecommand\dim@min[2]{\ifdim#1>#2#2\else #1\fi} +\providecommand\dim@max[2]{\ifdim#1>#2#1\else #2\fi} + +\newcommand*\option@dimmin[2]{\dim@min{\option{#1}}{\option{#2}}} +\newcommand*\option@dimmax[2]{\dim@max{\option{#1}}{\option{#2}}} + + +% -------------------------------------------------------- +% Add a new 'sides' option type +% -------------------------------------------------------- + +\options{ + /handlers/new sides/.new handler = []{ + \ifblank{#2}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#1-top={##1}, #1-right={##2}, #1-bottom={##3}, #1-left={##4}}}}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#2}}}% + \optionsalso{ + #1/.new cmdx = {##1,##2,##3,##4,##5\relax}{,,,,\relax}{% + \ifblank{##2##3##4}{\option{#1/@cmd@sides}{##1}{##1}{##1}{##1}}% + {\ifblank{##3##4}{\option{#1/@cmd@sides}{##1}{##2}{##1}{##2}}% + {\ifblank{##4}{\option{#1/@cmd@sides}{##1}{##2}{##3}{##2}}% + {\option{#1/@cmd@sides}{##1}{##2}{##3}{##4}}% + }% + }% + }, + #1/.type = sides, + }% + },% +} + +\newcommand*\optionlengthlimit[3]{% len, min, max + \letoption{#1}\opt@temp + \ifdim\opt@temp<\dimexpr#2\relax + \option@invoke{#1}{#2}% + \else\ifdim\opt@temp>\dimexpr#3\relax + \option@invoke{#1}{#3}% + \fi\fi +} + +\newcommand*\optionradiuslimit[4]{% r1, r2, min, max + \letoption{#1}\opt@tempa + \letoption{#2}\opt@tempb + \ifdim\opt@tempa<\dimexpr#3\relax\option@invoke{#1}{#3}\fi + \ifdim\opt@tempb<\dimexpr#3\relax\option@invoke{#2}{#3}\fi + \ifdim\dimexpr\opt@tempa + \opt@tempb\relax=\z@\relax\else + \ifdim\dimexpr\opt@tempa+\opt@tempb\relax>\dimexpr#4\relax + \edef\opt@perc{\the\numexpr(\number\dimexpr#4\relax)/% + (\number\dimexpr(\opt@tempa+\opt@tempb)/100\relax)}% + %\typeout{scale:\the\opt@tempa,\the\opt@tempb, by \opt@perc percent to make \the\dimexpr#4\relax}% + \edef\opt@temp{\dimexpr\opt@perc\dimexpr\the\opt@tempa\relax / 100\relax}% + \option@einvoke{#1}{\opt@temp}% + \option@einvoke{#2}{\dimexpr#4 - \opt@temp\relax}% + %\typeout{ scaled to: \the\opt@temp,\the\dimexpr#4 - \opt@temp\relax}% + \fi + \fi +} + + +% \begin{macro}{\trig@atantan} +% \marg{a}\marg{b}\marg{$\alpha$}{dimen$_\mathit{reg}$}\\ +% Assigns $\atan_2(\frac{\sin(\alpha)}{b},\frac{\cos(\alpha)}{a})$ to dimension register \textit{dimen$_\mathit{reg}$}, +% where $a$ and $b$ are dimensions. +% Returns $\alpha$ when $a = b$, or when $a=0$ or $b=0$. +% \begin{macrocode} +\newcommand*\trig@atantan[4]{% + %\typeout{ atantan:(\the#1,\the#2,\the#3, #4)}% + \@tempdima\dimexpr#1\relax + \@tempdimb\dimexpr#2\relax +% \end{macrocode} +% If $a = b$, we have a circle and the result is $\alpha$. +% \begin{macrocode} + \ifdim\@tempdima=\@tempdimb + #4\dimexpr#3\relax + \else\ifdim\@tempdima=\z@ + #4\dimexpr#3\relax + \else\ifdim\@tempdimb=\z@ + #4\dimexpr#3\relax + \else + \edef\trig@temp{\strip@pt\dimexpr#3\relax}% + \CalculateSin{\trig@temp}\CalculateCos{\trig@temp}% + \@tempdimc\dimexpr1\p@ * \dimexpr\UseSin{\trig@temp}\p@\relax/\@tempdimb\relax + \@tempdimd\dimexpr1\p@ * \dimexpr\UseCos{\trig@temp}\p@\relax/\@tempdima\relax + \pIIe@atantwo{\@tempdimc}{\@tempdimd}\dimen@ + \ifdim\dimen@<\z@ + \ifdim\dimexpr#3\relax<\z@\else\advance\dimen@360\p@\fi + \fi + \@tempdima\dimexpr#3 - \dimen@\relax + \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi + \ifdim\@tempdima<360\p@\else\advance\dimen@360\p@\fi + %\typeout{atan: \the\dimexpr#3\relax versus. \the\dimen@ }% + #4\dimen@ + \fi\fi\fi +} +% \end{macrocode} +% \end{macro} + +% rough approximation of the perimeter; +% if |radius-x == radius-y| = 0 (a circle), the approximation is precise. +% otherwise, works best when |angle2-angle1| <= 45 and gets worse from there on. +\newcommand*\ellip@letarcperimeter[5]{% 'radius-x', 'radius-y', 'angle-1', 'angle-2', '\result' + \@tempdima\dimexpr#3\relax + \@tempdimb\dimexpr#4\relax + \@tempdimc\dimexpr\@tempdima - \@tempdimb\relax + \ifdim\@tempdimc<\z@\@tempdimc-\@tempdimc\fi + \ifdim#1=#2\relax% circle? + \edef\@tempa{\strip@pt\@tempdimc}% angle difference delta as factor + \dimen@\@tempa\dimexpr#1\relax% r*delta + \dimen@0.017453\dimen@% (2*pi/360) * r * delta = 2*pi*r * (delta/360) + \else% ellipse: take the distance between the points on the ellipse, works pretty good if delta <= 45, and ok'ish for delta <= 90 + \@ovro\dimexpr#1\relax + \@ovri\dimexpr#2\relax + \edef\fbox@tempa{\strip@pt\@tempdima}% + \edef\fbox@tempb{\strip@pt\@tempdimb}% + \pIIe@ellip@sincost{\fbox@tempa}{\fbox@tempb}% + \@tempdima\@ellipcosone\@ovro + \@tempdimb\@ellipsinone\@ovri + \@tempdimc\@ellipcostwo\@ovro + \@tempdimd\@ellipsintwo\@ovri + \advance\@tempdimc by -\@tempdima% + \advance\@tempdimd by -\@tempdimb% + \pIIe@ellip@csqrt{\@tempdimc}{\@tempdimd}{\dimen@}% + %\typeout{ distance: \the\dimen@, from (x,y)=(\the\@tempdimc,\the\@tempdimd), radii=(\the#1,\the#2), angles=(\the#3,\the#4)}% + \fi + \edef#5{\the\dimen@}% +} + + +% ------------------------------------------------------------------------------ +% Borders using the picture environment +% ------------------------------------------------------------------------------ + +\newcommand*\fbox@border@pict{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \begingroup + \hbox{% + \unitlength\p@ + \begin{picture}(0,0)(0,\optionunit{/fbox/@border-box-height})% bottom-left is origin + % markers + \ontoggle{/fbox/show-markers}{% + \linethickness{\option{/fbox/marker-width}}% + \optioncolor{/fbox/marker-color}% + \fbox@rect{0pt}{0pt}{\option{/fbox/@border-box-width}}{\option{/fbox/@border-box-height}}% + \fbox@rect{\option{/fbox/border-left-width}}{\option{/fbox/border-\fbox@bottom-width}}% + {\option{/fbox/@border-box-width}-\option{/fbox/border-right-width}}% + {\option{/fbox/@border-box-height}-\option{/fbox/border-\fbox@top-width}}%S + }% + %compute corner coordinates + \fbox@border@calccorners + %put down the background color + \fbox@border@colorbackground + \option{/fbox/picture-insert-before}% + %put down the sides + \fbox@border@side{3}{-2}{0}%top + \fbox@border@side{5}{-4}{3}%left + \fbox@border@side{-6}{7}{2}%bottom + \fbox@border@side{-8}{1}{1}%right + \end{picture}% + }% + \endgroup + \fi +} + +\newcommand*\fbox@border@pict@after{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \letoption{/fbox/picture-insert-after}\fbox@insertafter + \eifblank{\fbox@insertafter}{}{% + \begingroup + \hbox{% + \begin{picture}(0,0)(0,0)% bottom-left is origin + \fbox@insertafter + \end{picture}% + }% + \endgroup + }% + \fi +} + +\newcommand*\fbox@border@side[3]{% + \fbox@setoct@angles{#1}% + \edef\fbox@style{\option{/fbox/border-\fbox@side-style}}% + \optioncolor{/fbox/border-\fbox@side-color}% + \option{/fbox/picture-side-insert-before}% + \ifcsdef{fbox@border@pict@\fbox@style}% + {\csuse{fbox@border@pict@\fbox@style}{#1}{#2}{#3}}% + {\PackageWarning{longfbox}{Unknown style "\fbox@style". Using "solid" instead.}% + \fbox@border@pict@solid{#1}{#2}{#3}}% + \option{/fbox/picture-side-insert-after}% +} + +% ------------------------------------------------------------------------------ +% Define standard border styles for the picture environment +% +% a style has the form \fbox@border@pict@ + + + + + + +
+
+
+
P4Runtime Specification
+
version 1.1.0-rc.1
+
+
+
The P4.org API Working Group
+
2019-12-12
+
+

Abstract. P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.

+ + +

1. Introduction and Scope

+

This document is published by the P4.org API Working Group, which was +chartered [16] to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called P4Runtime. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +https://github.com/p4lang/p4runtime/tree/v1.1.0-rc.1/proto. +

1.1. P4 Language Version Applicability

+

P4Runtime is designed to be implemented in conjunction with the P416 language +version or later. P414 programs should be translated into P416 to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P416 1.0, but were introduced in P416 1.1.0 [28]. For +this version of P4Runtime, we recommend using P416 1.2.0 [1]. +

1.2. In Scope

+

This specification document defines the semantics of P4Runtime messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime: +

+
    +
  • Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA) [18] externs (e.g. Counters, Meters, Action +Profiles, ). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0. +
  • +
  • Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism. +
  • +
  • Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy. +
  • +
  • Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities. +
  • +
  • Packet I/O to enable streaming packets to & from the control plane. +
  • +
  • Batching support, with different atomicity guarantees. +
  • +
  • In-the-field device-reconfiguration with a new P4 data plane. +
+ +

The following are in the scope of this specification document: +

+
    +
  • Rationale for the P4Runtime design. +
  • +
  • Reference architecture and use-cases for deploying a P4Runtime service. +
  • +
  • Detailed description of the API semantics. +
  • +
  • Requirements for conformant implementations of the API. +
+

1.3. Not In Scope

+

The following are not in scope of P4Runtime: +

+
    +
  • Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +[34]. An open source implementation of these APIs is also in progress +as part of the Stratum project [36]. +
  • +
  • Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures. +
+ +

The following are not in scope of this specification document: +

+
    +
  • Description of the P4 programming language; it is assumed that the reader is +already familiar with P416 [1]. +
  • +
  • Descriptions of gRPC and Protobuf files in general. +
  • +
  • Controller role definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme. +
+

2. Terms and Definitions

+
+
arbitration
+
Refers to the process through which P4Runtime ensures that at any given +time, there is a single master (i.e. a client with write access) for a given +role. Also referred to as “master-slave arbitration”. +
+
client
+
The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +
+
COS
+
Class of Service. +
+
device
+
Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +
+
entity
+
An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +
+
gRPC
+
gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +[9]. +
+
HA
+
High-Availability. Refers to a redundancy architecture. +
+
Instrumentation
+
The part of the P4Runtime server which implements the calls to the device or +target native “SDK” or backend. +
+
IPC
+
Inter-Process Communication. +
+
P4 Blob
+
A more colloquial term for P4 Device Config (Blob = Binary Large Object). +
+
P4 Device Config
+
The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its “program.” +
+
P4Info
+
Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +
+
P4RT
+
Abbreviation for P4Runtime. +
+
Protobuf (Protocol Buffers)
+
The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See [20]. +
+
PSA
+
Portable Switch Architecture [18]; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +
+
RPC
+
Remote Procedure Call. +
+
RTT
+
Round-trip time. +
+
SDN
+
Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network controller. +
+
SDN port
+
A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +
+
server
+
The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +
+
stream
+
Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (StreamChannel), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and master-slave arbitration, among other +things. +
+
switch config
+
Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +
+
target
+
The hardware or software entity which “executes” the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with “device”. +
+
URI
+
Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.

3. Reference Architecture

+

Figure 1 represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. A multi-master protocol allows more than +one controller to participate, and a role-based arbitration scheme ensures only +one controller has write access to each read/write entity, or the pipeline +config itself. Any controller may perform read access to any entity or the +pipeline config. Later sections describe this in detail. For the sake of +brevity, the term controller may refer to one or more controllers. +

+

The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +[14]. It may be compiled via protoc the Protobuf compiler +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server. +

+

Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository [15]. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, e.g. via callbacks, thus reducing the burden of implementing +P4Runtime. +

+

The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard. +

+

The controller can also set the ForwardingPipelineConfig, which amounts to +installing and running the compiled P4 program output, which is included in the +p4_device_config Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +ForwardingPipelineConfig to retrieve the device config and the P4Info. +

+
+

reference-architecture +

+
+ +
Figure 1. P4Runtime Reference Architecture.

3.1. Idealized Workflow

+

In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the ForwardingPipelineConfig +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a SetForwardingPipelineConfig +RPC. Metadata in the P4Info describes both the overall program itself +(PkgInfo) as well as all entity instances derived from the P4 program +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise “handle” used in API +calls. +

+

In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible. +

+

In some use cases, it is expected that a controller will store a +collection of multiple P4 “packages”, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the ForwardingPipelineConfig from the target via the +GetForwardingPipelineRequest RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state. +

3.2. P4 as a Behavioral Description Language

+

P4 can be considered a behavioral description of a switching device which may or +may not execute “P4” natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a SetForwardingPipelineRequest to +change its pipeline “program”, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device. +

+

While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API. +

+

In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the PkgInfo +message as well as the embedded doc fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections. +

3.3. Alternative Workflows

+

Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary. +

3.3.1. P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config

+

In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +p4_device_config. The device's configuration might be derived via some other +means to implement the P4 source code's intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane. +

3.3.2. No P4 Source Available, P4Info Available

+

In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are: +

+
    +
  1. +

    The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security. +

  2. +
  3. +

    The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info. +

+ +

As discussed in Section 3.2, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, e.g. documentation. +

3.3.3. Partial P4Info and P4 Source are Available

+

In this situation, a subset of the target's pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code. +

3.3.4. P4Info Role-Based Subsets

+

In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more. +

3.4. P4Runtime State Across Restarts

+

All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade. +

4. Controller Use-cases

+

P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +section. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime's flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex. +

4.1. Single Embedded Controller

+

Figure 2 shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases. +

+

P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC. +

+
+

single-embedded-controller +

+
+ +
Figure 2. Use-Case: Single Embedded Controller

4.2. Single Remote Controller

+

Figure 3 shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections. +

+
+

single-remote-controller +

+
+ +
Figure 3. Use-Case: Single Remote Controller

4.3. Embedded + Single Remote Controller

+

Figure 4 illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller. +

+

For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables. +

+
+

embedded-plus-single-remote-controller +

+
+ +
Figure 4. Use-Case: Embedded Plus Single Remote Controller

4.4. Embedded + Two Remote Controllers

+

Figure 5 illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +e.g. routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership. +

+
+

embedded-plus-two-remote-controllers +

+
+ +
Figure 5. Use-Case: Embedded Plus Two Remote Controllers

4.5. Embedded Controller + Two High-Availability Remote Controllers

+

Figure 6 illustrates a single +embedded controller plus two remote controllers in an active-standby HA +(High-Availability) configuration. Controller #1 is the active controller and is +in charge of some entities. If it fails, Controller #2 takes over and manages +the tables formerly owned by Controller #1. The mechanics of HA architectures +are beyond the scope of this document, but the P4Runtime multi-master +arbitration scheme supports it. +

+
+

embedded-plus-two-remote-ha-controllers +

+
+ +
Figure 6. Use-Case: Embedded Plus Two Remote High-Availability Controllers

5. Master-Slave Arbitration and Controller Replication

+

The P4Runtime interface allows multiple controllers to be connected to the +P4Runtime server running on the device at the same time for the following +reasons: +

+
    +
  1. +

    Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, “roles” (or “realms”) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +master and the rest are slaves. Role definition, i.e. how P4 entities get +assigned to each role, is out-of-scope of this document. +

  2. +
  3. +

    Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby slave controllers. These can already have a connection +open, which can help them become master more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved. +

+ +

To support multiple controllers, P4Runtime uses the streaming channel (available +via StreamChannel RPC) for session management. The workflow is described as +follows: +

+
    +
  • +

    Each controller instance (e.g. a controller process) can participate in one or +more roles. For each (device_id, role_id), the controller receives an +election_id. This election_id can be the same for different roles and/or +devices, as long as the tuple (device_id, role_id, election_id) is +unique. For each (device_id, role_id) that the controller wishes to +control, it establishes a StreamChannel with the P4Runtime server +responsible for that device, and sends a MasterArbitrationUpdate message +containing that tuple of (device_id, role_id, election_id) values. The +P4Runtime server selects a master independently for each (device_id, +role_id) pair. The master is the client that has the highest election_id +that the device has ever received for the same (device_id, +role_id) values. A connection between a controller instance and a device id + which involves a persistent StreamChannel can be referred to as a +P4Runtime client. +

    +

    Note that the P4Runtime server does not assign a role_id or election_id to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the election_id values used for each +StreamChannel. The P4Runtime server only keeps track of the (device_id, +role_id, election_id) of each StreamChannel that has sent a successful +MasterArbitrationUpdate message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +WriteRequest message to identify which client is making the WriteRequest, +not only the election_id. This enables controllers to re-use the same +numeric election_id values across different (device_id, role_id) +pairs. P4Runtime does not require election_id values be reused across such +different (device_id, role_id) pairs; it allows it. +

  • +
  • +

    To start a controller session, a controller first opens a bidirectional stream +channel to the server via the StreamChannel RPC for each device. This stream +will be used for two purposes: +

    +
      +
    • +

      Session management: As soon as the controller opens the stream +channel, it sends a StreamMessageRequest message to the switch. The +controller populates the MasterArbitrationUpdate field in this message +using its role_id and election_id, as well as the device_id of the +device. Note that the status field in the MasterArbitrationUpdate is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below. +

    • +
    • +

      Streaming of notifications (e.g. digests) and packet I/O: The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the master controller can participate in packet +I/O. This feature is explained in more details in the Packet +I/O section. +

    + +

    Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state. +

  • +
  • +

    Note that the stream is opened per device. In case a switching platform has +multiple devices (e.g. multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different masters for different +devices. In this case, it is the responsibility of the P4Runtime server to +keep track of the master for each device (and role). More specifically, the +P4Runtime server will know which stream corresponds to the master controller +for each pair of (device_id, role_id) at any point of time. +

  • +
  • +

    The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered “offline” or +“dead” as soon as its stream channel to the switch is broken. When a master +channel gets broken: (i) an advisory message is sent to all other controllers +for that device_id and role_id, as described in the +following section (ii) the P4Runtime server +will be without a master, until a client sends a successful +MasterArbitrationUpdate (as per the rules in a +later section). +

  • +
  • +

    The mechanism via which the controller receives the P4Runtime server details +which includes the device_id, ip and port, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +device_id) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks. +

+ +

gRPC enables the server to identify which client originated each message in the +StreamChannel stream. For example, the C++ gRPC library [10] in +synchronous mode enables a server process to cause a function to be called when +a new client creates a StreamChannel stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +StreamChannel is closed normally (or broken, e.g. because a client process +unexpectedly terminated). Thus the server can easily associate all +StreamChannel messages received from the same client, because they are +processed within the context of the same function call. +

+

A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values device_id, role_id, and election_id in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods [8] that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server. +

5.1. Default Role

+

A controller can omit the role message in MasterArbitrationUpdate. This +implies the “default role”, which corresponds to “full pipeline access”. This +also implies that a default role has a role.id of 0 (default). If using a +default role, all RPCs from the controller (e.g. Write) must set the role_id +to 0. +

5.2. Role Config

+

The role.config field in the MasterArbitrationUpdate message sent by the +controller describes the role configuration, i.e. which operations are in the +scope of a given role. In particular, the definition of a role may include the +following: +

+
    +
  • A list of P4 entities for which the controller may issue Write updates and +receive notification messages (e.g. DigestList and +IdleTimeoutNotification). +
  • +
  • Whether the controller is able to receive PacketIn messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketIn messages should be sent to the controller. +
  • +
  • Whether the controller is able to send PacketOut messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketOut messages are allowed to be sent by the controller. +
+ +

An unset role.config implies “full pipeline access” (similar to the default +role explained above). In order to support different role definition schemes, +role.config is defined as an Any Protobuf message [30]. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion. +

+

It is the job of the P4Runtime server to remember the role.config for every +device_id and role_id pair. +

5.3. Rules for Handling MasterArbitrationUpdate Messages Received from Controllers

+
    +
  1. +

    If the MasterArbitrationUpdate message is received for the first time on +this particular channel (i.e. for a newly connected controller): +

    +
      +
    1. +

      If device_id does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +NOT_FOUND error. +

    2. +
    3. +

      If the election_id is set and is already used by another controller for +the same (device_id, role_id), the P4Runtime server shall terminate +the stream by returning an INVALID_ARGUMENT error. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the number of open streams for the given (device_id, role_id) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a RESOURCE_EXHAUSTED error. +

    8. +
    9. +

      Otherwise, the controller is added to a list of connected controllers for +the given (device_id, role_id) and the server remembers the +controllers device_id, role_id and election_id for this gRPC +channel. See below for the rules to determine if this controller becomes +a master or slave, and what notifications are sent as a consequence. +

    +
  2. +
  3. +

    Otherwise, if the MasterArbitrationUpdate message is received from an +already connected controller: +

    +
      +
    1. +

      If the device_id does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. +

    2. +
    3. +

      If the role.id does not match the current role_id assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. If the controller wishes to change its role, +it must close the current stream channel and open a new one. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the election_id is set and is already used by another controller +(excluding the controller making the request) for the same +(device_id, role_id), the P4Runtime server shall terminate the stream +by returning an INVALID_ARGUMENT error. +

    8. +
    9. +

      If the election_id matches the one assigned to this stream: +

      +
        +
      1. +

        If the controller for this channel is the master, then the server +updates the role.config to the one specified in the +MasterArbitrationUpdate. An advisory mastership message is sent to +all controllers for this device_id and role_id informing +them of the new role.config. Since the format of role.config is +out of scope for the P4Runtime specification, the server will send +the advisory message for every update, even if the master sets the +same role.config as it has before. See the +following section for the format of +the advisory message. +

      2. +
      3. +

        If the controller is a slave, this is a no-op and the role.config +is ignored. No response is sent to any controller. +

      +
    10. +
    11. +

      Otherwise, the server updates the election_id it has stored for this +controller. This change might cause a change in mastership (this +controller might become master, or the controller might have downgraded +itself to a slave, see below), as well as notifications being sent to one +or more controllers. +

    +
+ +

If the MasterArbitrationUpdate is accepted by either of the two steps above +(cases 1.5. and 2.6. above), then the server determines if there are changes in +mastership. Let election_id_past be the highest election ID the server has +ever seen for the given device_id and role_id (including the one of the +current master if there is one). +

+
    +
  1. +

    If election_id is greater than or equal to election_id_past, then the +controller becomes master. The server updates the role configuration to +role.config for the given role.id. Furthermore: +

    +
      +
    1. +

      If there was no master for this device_id and role_id before and +there are no Write requests still processing from a previous master, +then the server immediately sends an advisory notification to all +controllers for this device_id and role_id. See the +following section for the format of the +advisory message. +

    2. +
    3. +

      If there was a previous master or Write requests in flight, then the +server carries out the following steps (in this order): +

      +
        +
      1. +

        The server stops accepting Write requests from the previous master +(if there is one). At this point, the server will reject all Write +requests with PERMISSION_DENIED. +

      2. +
      3. +

        The server notifies all controllers other than the new master of the +mastership change by sending the advisory notification described in +the following section. +

      4. +
      5. +

        The server will finish processing any Write requests that have +already started. If there are errors, they are reported as usual to +the previous master. If the previous master has already disconnected, +any possible errors are dropped and not reported. +

      6. +
      7. +

        The server now accepts the current controller as the new master, thus +accepting Write requests from this controller. The server updates +the highest election ID (i.e. election_id_past) it has seen for +this device_id and role_id to election_id. +

      8. +
      9. +

        The server notifies the new master by sending the advisory message +described in the following section. +

      +
    +
  2. +
  3. +

    Otherwise, the controller becomes a slave. If the controller was previously a +master (and downgraded itself), then an advisory message is sent to all +controllers for this device_id and role_id. Otherwise, the advisory +message is only sent to the controller that sent the initial +MasterArbitrationUpdate. See the +following section for the format of the +advisory message. +

+

5.4. Mastership Notifications

+

For any given device_id and role_id, any time a new master is chosen, a +master downgrades its status to a slave, a master disconnects, or the +role.config is updated by the master, all controllers for that +(device_id, role_id) are informed of this by sending a +StreamMessageResponse. The MasterArbitrationUpdate is populated as follows: +

+
    +
  • +

    device_id and role.id as given. +

  • +
  • +

    role.config is set to the role configuration the server received most +recently in a MasterArbitrationUpdate from a master. +

  • +
  • +

    election_id is populated as follows: +

    +
      +
    • +

      If there has not been any master at all, the election_id is left unset. +

    • +
    • +

      Otherwise, election_id is set to the highest election ID that the server +has seen for this device_id and role_id (which is the election_id of +the current master if there is any). +

    +
  • +
  • +

    status is set differently based on whether the notification is sent to the +master or a slave controller: +

    +
      +
    • +

      If there is a master: +

      +
        +
      • +

        For the master, status is OK (with status.code set to +google.rpc.OK). +

      • +
      • +

        For all slave controllers, status is set to non-OK (with +status.code set to google.rpc.ALREADY_EXISTS). +

      +
    • +
    • +

      Otherwise, if there is no master currently, for all slave controllers, +status is set to non-OK (with status.code set to +google.rpc.NOT_FOUND). +

    +
+ +

Note that on mastership changes with outstanding Write request, some +notifications might be delayed, see the +previous section for details. +

6. The P4Info Message

+

The purpose of P4Info was described under +Reference Architecture. +Here we describe the various +components. +

6.1. Common Messages

+

These messages appear nested within many other messages. +

6.1.1. Documentation Message

+

Documentation is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers. +

+
+
+
message Documentation {
+  // A brief description of something, e.g. one sentence
+  string brief = 1;
+  // A more verbose description of something.
+  // Multiline is accepted. Markup format (if any) is TBD.
+  string description = 2;
+}

6.1.2. Preamble Message

+

The preamble serves as the “descriptor” for each entity and contains the unique +instance ID, name, alias, annotations and documentation. +

+
+
+
message Preamble {
+  // ids share the same number-space; e.g. table ids cannot overlap with counter
+  // ids. Even though this is irrelevant to this proto definition, the ids are
+  // allocated in such a way that it is possible based on an id to deduce the
+  // resource type (e.g. table, action, counter, ...). This means that code
+  // using these ids can detect if the wrong resource type is used
+  // somewhere. This also means that ids of different types can be mixed
+  // (e.g. direct resource list for a table) without ambiguity. Note that id 0
+  // is reserved and means "invalid id".
+  uint32 id = 1;
+  // fully qualified name of the P4 object, e.g. c1.c2.ipv4_lpm
+  string name = 2;
+  // an alias (alternative name) for the P4 object, probably shorter than its
+  // fully qualified name. The only constraint is for it to be unique with
+  // respect to other P4 objects of the same type. By default, the compiler uses
+  // the shortest suffix of the name that uniquely identifies the object. For
+  // example if the P4 program contains two tables with names s.c1.t and s.c2.t,
+  // the default aliases will respectively be c1.t and c2.t. In the future, the
+  // P4 programmer may also be able to override the default alias for any P4
+  // object (TBD).
+  string alias = 3;
+  repeated string annotations = 4;
+  // Documentation of the entity
+  Documentation doc = 5;
+}

6.1.3. Annotating P4 Entities with Documentation

+

P4 entities may be annotated using the following annotations: +

+
+
+
@brief(string...)
+@description(string...)
+

Attaching either or both of these annotations to an entity will generate a +P4Info Documentation Message, which in turn will +appear in the Preamble Message for the entity. +

+

The P4 compiler should not emit annotation messages in the P4Info for these +specific cases; instead, it should generate the Documentation messages as +described. +

+

The following example shows documentation annotations for a table entity: +

+
+
+
@brief("Match IPv4 addresses to next-hop MAC and port")
+@description("Match IPv4 addresses to next-hop MAC and port. \
+Uses LPM match type.")
+table my_ipv4_lkup {
+  ...
+}

6.2. PkgInfo Message

+

The PkgInfo message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. PkgInfo can be extracted +and used to facilitate “browsing” of available P4 programs from a +library. Although all fields are technically “optional,” every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included. +

+
+
+
// Can be used to manage multiple P4 packages.
+message PkgInfo {
+  // a definitive name for this configuration, e.g. switch.p4_v1.0
+  string name = 1;
+  // configuration version, free-format string
+  string version = 2;
+  // brief and detailed descriptions
+  Documentation doc = 3;
+  // Miscellaneous metadata, free-form; a way to extend PkgInfo
+  repeated string annotations = 4;
+  // the target architecture, e.g. "psa"
+  string arch = 5;
+  // organization which produced the configuration, e.g. "p4.org"
+  string organization = 6;
+  // contact info for support,e.g. "tech-support@acme.org"
+  string contact = 7;
+  // url for more information, e.g. "http://support.p4.org/ref/p4/switch.p4_v1.0"
+  string url = 8;
+}

6.2.1. Annotating P4 code with PkgInfo

+

A P4 progam's PkgInfo may be declared using one or more of the following +annotations, attached to the main block only: +

+
+
+
@pkginfo(key=value)
+@pkginfo(key=value[,key=value,...])
+@brief("A brief description")
+@description("A longer\
+description")
+@custom_annotation(...)
+@another_custom_annotation(...)
+

Above we see several different types of annotations: +

+
    +
  • +

    @pkginfo - This is used to populate a specific field within the PkgInfo +message. Multiple @pkginfo annotations are allowed. For compactness, +multiple key-value pairs can appear in a single @pkginfo annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The keys must be from +among the message fields inside PkgInfo, for example, name, version, +etc. Each key-value pair assigns a value to the corresponding field inside the +single PkgInfo message for the program's P4Info. One exception is that the +Documentation field of PkgInfo must be expressed as individual +@description and @brief annotations, see next bullets. The key arch will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself. +

  • +
  • +

    @brief - This will populate the PkgInfo.doc.brief message field. +

  • +
  • +

    @description - This will populate the PkgInfo.doc.description message +field +

  • +
  • +

    @<anything else> - This will create a PkgInfo.annotation entry +

+ +

Declaring one or more of these annotations on main will +generate a single corresponding PkgInfo message in the P4Info as described in +PkgInfo Message. +

+

The following example shows @pkginfo annotations using a mixture of single and +multiple key-value pairs. It also shows @brief and @description annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the PkgInfo message. The custom annotations will +be appended to the PkgInfo.annotations list. +

+
+
+
@pkginfo(name="switch.p4",version="2")
+@pkginfo(organization="p4.org")
+@pkginfo(contact="info@p4.org")
+@pkginfo(url="www.p4.org")
+@brief("L2/L3 switch")
+@description("L2/L3 switch.\
+Built for data-center profile.")
+@my_annotation1(...) // Not well-known, this will appear in PkgInfo annotations
+@my_annotation2(...) // Not well-known, this will appear in PkgInfo annotations
+PSA_Switch(IgPipeline, PacketReplicationEngine(), EgPipeline,
+           BufferingQueueingEngine()) main;

6.3. ID Allocation for P4Info Objects

+

P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(e.g. table, action, counter, ). The most significant 8 bits of the ID +encodes the object type (as per Table 1). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (p4.config.v1.P4Ids.Prefix). These values must +be used (e.g. by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table 2 shows the ID +layout. +

+
+ + + + + + + + + + + + + + + + + + + + + +
8-bit prefix value P4 object type
0x00 Reserved (unspecified)
0x01 Action
0x02 Table
0x03 Value-set
0x04 Controller header (header type with @controller_header annotation)
0x050x0f Reserved (for future P4 built-in objects)
0x10 Reserved (start of PSA extern types)
0x11 PSA Action profiles / selectors
0x12 PSA Counter
0x13 PSA Direct counter
0x14 PSA Meter
0x15 PSA Direct meter
0x16 PSA Register
0x17 PSA Digest
0x180x7f Reserved (for future PSA extern types)
0x80 Reserved (start of vendor-specific extern types)
0x810xfe Vendor-specific extern types
0xff Reserved (max prefix value)
+
+ +
Table 1. Mapping of P4Info object type to 8-bit ID prefix value
+
+ + + + +
MSB bit 31 .. bit 24 bit 23 .. bit 0 LSB
Object type prefix Generated suffix (e.g. by the compiler)
+
+ +
Table 2. Format of P4Info object IDs
+

It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with @id (see Table +3). The compiler must honor the @id annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (i.e. if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same @id value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. +

+
+ + + + + + + + + + +
P4 declaration(s) Compiler-allocated ID(s)
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) table tA... Error(same ID suffixes for 2 objects of the same type)
@id(0x12ab34) table tB...
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) action act1... 0x0112ab34
+
+ +
Table 3. Example of statically-assigned P4Info object IDs

6.4. P4Info Objects

6.4.1. Table

+

Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this table. +

  • +
  • +

    match_fields, a repeated field of type MatchField representing the data to +be used to construct the lookup key matched in this table. Each MatchField +message is defined with the following fields: +

    +
      +
    • +

      id, the uint32 identifier of this MatchField, unique in the scope of +this table. No rules are prescribed on the way MatchField IDs should be +allocated, as long as two MatchField of the same table do not have the +same ID. Nonetheless, we recommend that the IDs be assigned incrementally, +starting from 1, in the same order as in the P4 key declaration. +

    • +
    • +

      name, the string representing the name of this MatchField. +

    • +
    • +

      annotations, a repeated field of strings, each one representing a P4 +annotation associated to this match field. +

    • +
    • +

      bitwidth, an int32 value set to the size in bits of this match field. +

    • +
    • +

      match, a oneof describing the match behavior for this field; it can be +either: +

      +
        +
      • match_type, an enum field of type MatchType, which includes all +possible PSA match kinds. +
      • +
      • other_match_type, a string field which can be used to encode any +architecture-specific match type. +
      +
    • +
    • +

      doc, a Documentation message describing this match field. +

    • +
    • +

      type_name, which indicates whether the match field has a user-defined +type; this is useful for +translation. +

    +
  • +
  • +

    action_refs, a repeated ActionRef field representing the set of possible +actions for this table. The ActionRef message is used to reference an action +specified in the same P4Info message and it includes the following fields: +

    +
      +
    • id, the uint32 identifier of the action. +
    • +
    • scope, an enum value which can take one of three values: + TABLE_AND_DEFAULT, TABLE_ONLY and DEFAULT_ONLY. The scope of the + action is determined by the use of the P4 standard annotations + @tableonly and @defaultonly [17]. TABLE_ONLY + (@tableonly annotation) means that the action can only appear within + the table, and never as the default action. DEFAULT_ONLY + (@defaultonly annotation) means that the action can only be used as the + default action. TABLE_AND_DEFAULT is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action. +
    • +
    • annotations, a repeated string field, each one representing a P4 +annotation associated to the action reference in this table. +
    +
  • +
  • +

    const_default_action_id, if this table has a constant default action, this +field will carry the uint32 identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action's +arguments. +

  • +
  • +

    implementation_id, the uint32 identifier of the “implementation” of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (e.g. a PSA ActionProfile or ActionSelector +instance). The table is then referred to as an indirect match table. +

  • +
  • +

    direct_resource_ids, repeated uint32 identifiers for all the direct +resources attached to this table, such as DirectMeter and DirectCounter +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2. +

  • +
  • +

    size, an int64 describing the desired number of table entries that the +target should support for the table. See the “Size” subsection within the +“Table Properties” section of the P416 language specification for details +[29]. +

  • +
  • +

    idle_timeout_behavior, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +Idle-Timeout section). Value can be any of the +IdleTimeoutBehavior enum: +

    +
      +
    • NO_TIMEOUT (default value), which means that idle timeout is not +supported for this table. +
    • +
    • NOTIFY_CONTROL, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +Table Idle Timeout Notifications). +
    +
  • +
  • +

    is_const_table, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime. +

  • +
  • +

    other_properties, an Any Protobuf message [30] to embed +architecture-specific table properties [29] which are not part +of the core P4 language or of the PSA architecture. +

+

6.4.2. Action

+

Action messages are used to specify all possible actions of all match-action +tables. +

+

The Action message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this action +

  • +
  • +

    params, a repeated field of Param messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each Param message contains the +following fields: +

    +
      +
    • id, the uint32 identifier of this parameter. No rules are prescribed +on the way Param IDs should be allocated, as long as two Param of the +same action do not have the same ID. Nonetheless, we recommend that the +IDs be assigned incrementally, starting from 1, in the same order as in +the P4 action declaration. +
    • +
    • name, the string representing the name of this parameter. +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this parameter. +
    • +
    • bitwidth, an int32 value set to the size in bits of this parameter. +
    • +
    • doc, which describes this parameter using a Documentation message. +
    • +
    • type_name, which indicates whether the action parameter has a +user-defined type; this is useful for +translation. +
    +
+

6.4.3. ActionProfile

+

ActionProfile messages are used to specify all available instances of Action +Profile and Action Selector PSA externs. +

+

PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile member, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime. +

+

PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into groups. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime. +

+

While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same ActionProfile message to describe both. +

+

The ActionProfile message includes the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Action +Profile or Selector. +

  • +
  • +

    table_ids, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector. +

  • +
  • +

    with_selector, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern. +

  • +
  • +

    size, an int64 representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups. +

  • +
  • +

    max_group_size, an int32 representing the maximum sum of all member +weights within any given selector group, in the case of an Action Selector, or +0 for an Action Profile. PSA programs can use the @max_group_size annotation +to provide this value for Action Selectors. If the annotation is omitted, the +P4Info field will default to 0. +

+

6.4.4. Counter & DirectCounter

+

Counter and DirectCounter messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is: +

+
    +
  • +

    Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index. +

  • +
  • +

    Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table. +

+ +

Both Counter and DirectCounter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this counter +extern instance. +

  • +
  • +

    spec, a message of of type CounterSpec used to describe the compile-time +configuration of this counter. Currently, the CounterSpec message is used to +carry only the counter unit, which can be any of the CounterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES: byte counter. +
    • +
    • PACKETS: packet counter. +
    • +
    • BOTH: combination of both byte and packet counter. +
    +
+ +

For indexed counters, the Counter message contains also a size field, an +int64 representing the maximum number of independent values that can be held +by this counter array. Conversely, the DirectCounter message contains a +direct_table_id field that carries the unit32 identifier of the table to +which this direct counter is attached. +

+

For indexed counters, the Counter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.5. Meter & DirectMeter

+

Meter and DirectMeter messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is: +

+
    +
  • +

    Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +e.g. to set the rate threshold. +

  • +
  • +

    Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table. +

+ +

Both Meter and DirectMeter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this meter +extern instance. +

  • +
  • +

    spec, a message of type MeterSpec used to describe the capabilities of +this meter extern instance. Currently, the MeterSpec message is used to +carry only the meter unit, which can be any of the MeterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES, which signifies that this meter can be configured with rates +expressed in bytes/second. +
    • +
    • PACKETS, for rates expressed in packets/second. +
    +
+ +

For indexed meters, the Meter message contains also a size field, an int64 +representing the maximum number of independent cells that can be held by this +meter. Conversely, the DirectMeter message contains a direct_table_id field +that carries the uint32 identifier of the table to which this direct meter is +attached. +

+

For indexed meters, the Meter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.6. ControllerPacketMetadata

+

ControllerPacketMetadata messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server. +

+

When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet. +

+

Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +@controller_header("packet_in") and @controller_header("packet_out"), +respectively. ControllerPacketMetadata messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages). +

+

A P4Info message can contain at most two ControllerPacketMetadata messages, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message where preamble.name is set to "packet_in" +and "packet_out" for packet-in and packet-out metadata, respectively. +

  • +
  • +

    metadata, a repeated field of type Metadata, where each Metadata message +includes the following fields: +

    +
      +
    • id, a uint32 identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two Metadata of the +same ControllerPacketMetadata message do not have the same +ID. Nonetheless, if the P4Info message was generated from a P4 compiler, +we recommend that the IDs be assigned incrementally, starting from 1, in +the same order as the fields in the P4 header declaration. +
    • +
    • name, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below). +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this metadata. +
    • +
    • bitwidth, an int32 representing the size in bits of this metadata. +
    • +
    • type_name, which indicates whether the metadata field has a +user-defined type; this is useful for +translation. +
    +
+ +

As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding ControllerPacketMetadata +messages. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  bit<9> egress_port; /* suggested port where the packet
+                         should be sent */
+  bit<8> queue_id;    /* suggested queue ID */
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  bit<9> ingress_port; /* data plane port ID where
+                          the original packet was received */
+  bit<1> is_clone;     /* 1 if this is a clone of the
+                          original packet */
+}
+
+
+
controller_packet_metadata {
+  preamble {
+    id: 2868916615
+    name: "packet_out"
+    annotations: "@controller_header(\"packet_out\")"
+  }
+  metadata {
+    id: 1
+    name: "egress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "queue_id"
+    bitwidth: 8
+  }
+}
+
+controller_packet_metadata {
+  preamble {
+    id: 2868941301
+    name: "packet_in"
+    annotations: "@controller_header(\"packet_in\")"
+  }
+  metadata {
+    id: 1
+    name: "ingress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "is_clone"
+    bitwidth: 1
+  }
+}
+

Note that the use of @controller_header is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages. +

6.4.7. ValueSet

+

ValueSet messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P416 +specification [37]. +

+

The ValueSet message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Value +Set. +

  • +
  • +

    match, a repeated field of MatchField messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the match_fields repeated field in the +Table message. +

  • +
  • +

    size, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +value_set constructor call. +

+ +

According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of bit<W>, +tuple, or struct [25]. The rest of this section looks at all 3 of +these cases and gives an example ValueSet message when appropriate. +

+
    +
  1. +

    If the type parameter is bit<W>, match will include exactly one +MatchField message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used): +

    +
      +
    • id: set to 1 +
    • +
    • bitwidth: set to the value of W +
    • +
    • match_type: set to EXACT +
    +
+ +
+
+
@id(1) value_set<bit<8> >(4) pvs;
+select (hdr.f8) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    bitwidth: 8
+    match_type: EXACT
+  }
+  size: 4
+}
+
    +
  1. +

    If the type parameter is a tuple, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program. +

  2. +
  3. +

    If the type parameter is a struct, this version of P4Runtime requires that +all the fields of the struct be of type bit<W> (where W can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +match field will include one MatchField message for each field in the +struct, with the following fields: +

    +
      +
    • id: must be unique with respect to the other match entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. +
    • +
    • name: set to the name of the corresponding struct field. +
    • +
    • annotations: set to the list of P4 annotations associated with the struct +field, except for the @match annotation, if present (see the match field +below). +
    • +
    • bitwidth: set to the value of W for the corresponding struct field. +
    • +
    • type_name, which indicates whether the struct field has a user-defined +type; this is useful for +translation. +
    • +
    • match: by default match_type is set to EXACT; the P4 programmer can +specify a different match type by using the @match annotation +[25]. +
    • +
    • doc: documentation associated with the struct field. +
    +
+ +
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a user-defined +type that resolves to a bit<W>, or a struct where +one or more fields is a user-defined type that +resolves to a bit<W>. For each MatchField that corresponds to a user-defined +type, the type_name field must be set to the appropriate value (i.e. the name +of the type). +

6.4.8. Register

+

Register messages are used to specify all possible instances of Register PSA +externs. +

+

Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime. +

+

The Register message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this register +instance. +

  • +
  • +

    type_spec, which specifies the data type stored by this register, expressed +using a P4DataTypeSpec message (see section on Representation of Arbitrary +P4 Types). +

  • +
  • +

    size, an int32 value representing the total number of independent register +cells available. +

  • +
  • +

    index_type_name, which indicates whether the register index has a +user-defined type. This is useful for +translation. The underlying built-in type +must be a fixed-width unsigned bitstring (bit<W>). +

+

6.4.9. Digest

+

Digest messages are used to specify all possible instances of Packet Digest +PSA externs. +

+

A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages. +

+

The Digest message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this digest +instance. +

  • +
  • +

    type_spec, which specifies the data type of an individual digest +notification using a P4DataTypeSpec message (see section on Representation +of Arbitrary P4 Types). +

+

6.4.10. Extern

+

Extern messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one Extern message instance in P4Info. The Extern message defines +the following fields: +

+
    +
  • +

    extern_type_id, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the reserved +range [0x81, 0xfe]. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture. +

  • +
  • +

    extern_type_name, which specifies the fully-qualified P4 name of the extern +type. +

  • +
  • +

    instances, a repeated field of ExternInstance Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +ExternInstance in turn defines the following fields: +

    +
      +
    • preamble, a Preamble message with the ID, name, and alias of this digest +instance. +
    • +
    • info, an Any Protobuf message [30] which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for info should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on Extending +P4Runtime for non-PSA Architectures for more +information. +
    +
+ +

If the P4 program does not include any instance of a given extern type, the +Extern message instance for that type should be omitted from the P4Info. +

6.5. Support for Arbitrary P4 Types with P4TypeInfo

+

See section on Representation of Arbitrary P4 +Types. +

7. P4 Forwarding-Pipeline Configuration

+

The ForwardingPipelineConfig captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the “Device Configuration” and sometimes also referred to as +the “P4 Blob”. It is defined as: +

+
+
+
message ForwardingPipelineConfig {
+  config.P4Info p4info = 1;
+  bytes p4_device_config = 2;
+  message Cookie {
+    uint64 cookie = 1;
+  }
+  Cookie cookie = 3;
+}
+

The p4info field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic. +

+

The p4_device_config is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new ForwardingPipelineConfig on that target. +

+

The cookie field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a GetForwardingPipelineConfig RPC. +When writing the config via a SetForwardingPipelineConfig RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present. +

8. General Principles for Message Formatting

8.1. Set / Unset Protobuf Field

+

In Protobuf version 3 (proto3), the default value for a message field is +“unset” [4]. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +CounterEntry message, an “unset” index field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the index message field is +set, a single entry will be read. +

+

Let's look at the counter example in more details. Based on this specification +document, the C++ server code which processes CounterEntry messages may look +like this: +

+
+
+
auto *counter_entry = ...
+if (counter_entry->has_index()) {
+  auto index = counter_entry->index().index();
+  read_one_entry(counter_entry->id(), index);
+} else {
+  read_all_entries(counter_entry->id());
+}
+
    +
  1. +

    Reading a single counter entry at index 0 in the counter array with id +<id>: +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
      +entry.mutable_index();
      +// The above line sets the index field; it is equivalent to:
      +// auto *index = entry.mutable_index();
      +// index->set_index(0);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
      +index {}
    • +
    • Expected behavior: Counter entry at index 0 is read. Notice that the +index subfield is missing under the index field message of +CounterEntry in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages. +
    +
  2. +
  3. +

    Reading all counter entries by leaving the index field unset +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
    • +
    • Expected behavior: All counter entries for the provided counter +instance are read. Notice that the index message field is unset (default +value) and is therefore omitted from the textual representation of the +message. +
    +
+

8.2. Read-Write Symmetry

+

The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example: +

+
+
+
intended_value = value
+
+status = server.write(intended_value, p4_entity)
+observed_value = server.read(p4_entity)
+
+assert(intended_value == observed_value)
+

To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If Read RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol's complexities to the client implementations. +

+

In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the match fields in a TableEntry message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +MessageDifferencer class [35] included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance. +

8.3. Zero as Reserved Value

+

p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a uint32. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a WriteRequest or a SetForwardingPipelineConfigRequest. +

8.4. Bytestrings

+

P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (bit<W>) or signed (int<W>), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +bytes Protobuf type. The correct bitwidth as per the P4 program of +each integer variable exposed through P4Runtime is specified in the P4Info +message. +

+

The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals: +

+
    +
  • +

    It ensures that a properly encoded binary string's integer value conforms +to the P4Info-specified bitwidth. +

  • +
  • +

    It supports read-write symmetry. +

  • +
  • +

    It helps facilitate non-disruptive P4 program updates. +

+ +

In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type bit<W> and/or int<W>. +

+

Note that this representation does not make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range. +

+

In the P4Runtime API version 1.0, values of table key fields, action parameters, +and fields in packet-in and packet-out headers between a device and the +controller (see 6.4.6), may not be of type int<W>. +The rules for encoding signed values thus only apply to messages of type +P4Data (see 8.5.3). +

+

For a value of type bit<W>, the fewest number of bits required to represent +the integer value $V > 0$ is the smallest integer $A$ such that $V \leq 2^A -1$. +

+

For a value of type int<W>, the fewest number of bits required to represent +the integer value $V \neq 0$ in 2's complement form is the smallest integer $A$ +such that $-2^{A-1} \leq V \leq 2^{A-1} - 1$. +

+

As a special case, define that the value $V=0$ requires at least $A=1$ bit to +represent, regardless of whether it is signed or unsigned. +

+

The shortest possible binary string for an integer $V$ that needs $A$ bits to +represent it is computed as: +

+
+
+
minimum_string_size = floor((A + 7) / 8)
+

Binary strings with the byte length computed as minimum_string_size promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies. +

+

Any additional bits in the bytes sent for an unsigned integer value (type +bit<W>) must be 0. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with 0. +

+

Any additional bits in the bytes sent for a signed integer value (type int<W>) +must be copies of the sign bit, i.e. 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with copies of the +sign bit, i.e. 0 for non-negative values, or 0xff for negative values. In 2's +complement representation, this is called “sign extension”, and leaves the +numeric value represented unchanged. +

+

Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value. +

+

For a received bitstring expected to fit within a bit<W> type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring's width is W bits or less. +

+

For a received bitstring expected to fit within an int<W> type, the value it +represents is in range if, after “undoing sign extension”, the remaining bit +string's width is W bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other. +

+

If the string's byte length is zero, the server always rejects the string. +

+

When the server rejects a binary string due to any of the previous criteria, +it returns an OUT_OF_RANGE error. +

+

For all binary strings, P4Runtime uses big-endian (i.e. network) byte-order. +For signed integer values (int<W> P4 type), P4Runtime uses the same two's +complement bitwise representation as P4. Table 4 +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above. +

+
+ + + + + + + + + + + + + + + + + +
P4 type Integer value P4Runtime binary string Read-write symmetry
bit<8> 99 (0x63) \x63 yes
bit<16> 99 (0x63) \x00\x63 no
bit<16> 99 (0x63) \x63 yes
bit<16> 12388 (0x3064) \x30\x64 yes
bit<16> 12388 (0x3064) \x00\x30\x64 no
bit<12> 99 (0x63) \x00\x63 no
bit<12> 99 (0x63) \x63 yes
bit<12> 99 (0x63) \x00\x00\x63 no
int<8> 99 (0x63) \x63 yes
int<8> -99 (-0x63) \x9d yes
int<8> -99 (-0x63) \xff\x9d no
int<12> -739 (-0x2e3) \xfd\x1d yes
int<16> 0 (0x0) \x00\x00 no
int<16> 0 (0x0) \x00 yes
+
+ +
Table 4. Examples of Valid Bytestring Encoding
+

Table 5 shows some examples of invalid +P4Runtime binary strings: +

+
+ + + + + + + + + + + + +
P4 type P4Runtime binary string
bit<8> \x01\x63
bit<8> empty string
bit<16> \x01\x00\x63
bit<12> \x10\x63
bit<12> \x01\x00\x63
bit<12> \x00\x40\x63
int<8> \x00\x9d
int<12> \x8d\x1d
int<16> empty string
+
+ +
Table 5. Examples of Invalid Bytestring Encoding
+

As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from bit<8> to bit<9>, a server +running the bit<9> version of the P4 program will accept requests from +clients that remain on the bit<8> P4Runtime version. +

+

Despite the server's binary string flexibility for P4 program update support, +the client and server must both remain aware of the +read-write symmetry +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values. +

+

Representation of variable-length integer values (varbit<W> P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the dynamic-length of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an OUT_OF_RANGE error code otherwise. +

8.5. Representation of Arbitrary P4 Types

8.5.1. Problem Statement

+

The P416 language includes more complex types than just binary strings +[3]. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table 6 shows the different +P416 types and how they are allowed to be used, as per the P416 +specification. +

+
+ + + + + + + + + + + + + + + + + + + +
Container type
Element type header header_union struct or tuple
bit<W> allowed error allowed
int<W> allowed error allowed
varbit<W> allowed error allowed
int error error error
void error error error
error error error allowed
match_kind error error error
bool error error allowed
enum allowed1 error allowed
header error allowed allowed
header stack error error allowed
header_union error error allowed
struct error error allowed
tuple error error allowed
+
+ +
Table 6. P4 Type Usage
+

For example, the following P416 objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects. +

+
+
+
Digest<tuple<bit<4>, bit<8> > >() digest_complex;
+digest_complex.pack({ hdr.ipv4.version, hdr.ipv4.protocol });
+// ...
+header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

One solution would be to use only binary string (bytes type) in +p4runtime.proto and to define a custom serialization format for complex P416 +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P416 types. +

8.5.2. P4 Type Specifications in p4info.proto

+

In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type ip_t, which is a header union with 2 possible headers: +ipv4 with type ipv4_t and ipv6 with type ipv6_t. Similarly, they need to +know the field layout for both of these header types. +

+

To achieve this we introduce 2 main Protobuf messages: P4TypeInfo and +P4DataTypeSpec. +

+

P4TypeInfo is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P416 program. These +named types are struct, header, header_union, enum and +serializable_enum; for each of these we have a type specification message, +respectively P4StructTypeSpec, P4HeaderTypeSpec, P4HeaderUnionTypeSpec, +P4EnumTypeSpec and P4SerializableEnumTypeSpec. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. P4TypeInfo also includes the list of parser errors for the program, as +a P4ErrorTypeSpec message. +

+

P4DataTypeSpec is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each P4DataTypeSpec message corresponds to a compile-time type in the +original P416 program (e.g. the type parameter of an extern). This +compile-time type is represented as a Protobuf oneof, which can be: +

+
    +
  • +

    a string representing the name of the type in case of a named type (struct, +header, header_union, enum, serializable_enum or user-defined “new” +type), +

  • +
  • +

    an empty Protobuf message for bool and error, or +

  • +
  • +

    a Protobuf message for other anonymous types (bit<W>, int<W>, varbit<W>, +tuple or stack). The “binary string” types (bit<W>, int<W>, and +varbit<W>) are grouped together in the P4BitstringLikeTypeSpec message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf bytes +type). +

+ +

For all P416 compound types (tuple, struct, header, and header_union), +the order of members in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P416 declaration. The same goes for the order of members of an enum +(serializable or not) or members of error. +

8.5.3. P4Data in p4runtime.proto

+

P4Runtime uses the P4Data message to represent values of arbitrary types. The +P4Runtime client must generate correct P4Data messages based on the type +specification information included in P4Info. The P4Data message was designed +to introduce little overhead compared to using binary strings in the most common +case (P416 bit<W> type). +

+

Just like its P4Info counterpart - P4DataTypeSpec -, P4Data uses a Protobuf +oneof to represent all possible values. +

+

We define a canonical representation for P4Data messages therefore +guaranteeing read-write symmetry by introducing the following requirements: +

+
    +
  • +

    The order of members in P4StructLike and the order of bitstrings in +P4Header must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P416 type +declaration. +

  • +
  • +

    An invalid header is represented by a P4Header message where the is_valid +field is false and the bitstrings repeated field is empty. +

  • +
  • +

    An invalid header union (i.e. all headers in the union are invalid) is +represented by a P4HeaderUnion message where the valid_header_name is the +empty string (default value for the field) and the valid_header is unset. +

  • +
  • +

    The order of entries in P4HeaderStack and P4HeaderUnionStack is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the entries field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding P4HeaderStackTypeSpec or +P4HeaderUnionStackTypeSpec message. +

+

8.5.4. Example

+

Let's look at the Register example again: +

+
+
+
header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

Here's the corresponding entry in the P4Info message: +

+
+
+
registers {
+  preamble {
+    id: 369119267
+    name: "register_ip"
+    alias: "register_ip"
+  }
+  type_spec {
+    header_union {
+      name: "ip_t"
+    }
+  }
+  size: 128
+}
+type_info {
+  headers {
+    key: "ipv4_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  headers {
+    key: "ipv6_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  header_unions {
+    key: "ip_t"
+    value {
+      members {
+        name: "ipv4"
+        header {
+          name: "ipv4_t"
+        }
+      }
+      members {
+        name: "ipv6"
+        header {
+          name: "ipv6_t"
+        }
+      }
+    }
+  }
+}
+

Here's a p4.WriteRequest to set the value of register_ip[12]: +

+
+
+
update {
+  type: INSERT
+  entity {
+    register_entry {
+      register_id: 369119267
+      index {
+        index: 12
+      }
+      data {
+        header_union {
+          valid_header_name: "ipv4"
+          valid_header {
+            is_valid: true
+            bitstrings: "\x04"
+            bitstrings: # ...
+          }
+        }
+      }
+    }
+  }
+}

8.5.5. enum, serializable enum and error

+

P416 supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or “unsafe” enum) +[5]. For enum types with no underlying type as well as error +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in P4Data to represent enum and +error values. +

+

Serializable enum types have an underlying fixed-width unsigned integer +representation (bit<W>). All named enum members must be assigned an integer +value by the P4 programmer, but not all valid numeric values for the +underlying type need to have a corresponding name. P4TypeInfo includes the +mapping between entry name and entry value. When providing serializable enum +values through P4Data, one must use the assigned integer value (enum_value +bytestring field). P4Runtime does not provide a way for the client to use the +name even when the enum member has one instead of the value, as it makes +it easier for the server to respect the read-write +symmetry principle. +

8.5.6. User-defined types

+

P416 enables programmers to introduce new types [11]. While similar +to typedef, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +translation. When introducing a new type, the +declaration can be annotated with @p4runtime_translation to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for port numbers, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. The @p4runtime_translation annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (bit<W>) and the type exposed to the control plane will also be a +fixed-width unsigned bitstring, with a potentially different bitwidth. It takes +two parameters: a URI (Uniform Resource Identifier) which uniquely identifies +the translation being performed on entities of the new type to the P4Runtime +server and the bitwidth of the bitstring type exposed to the control plane. It +is recommended that the URI includes at least the P4 architecture name and the +type name. +

+

A @p4runtime_translation annotation need not have any effect if it is used to +annotate anything in a P4 program other than a type declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect. +

+

User-defined types are specified using the P4NewTypeSpec message, which has +the following fields: +

+
    +
  • +

    representation, a Protobuf oneof specifying how values of this type are +exchanged between client and server; it can be either: +

    +
      +
    • +

      original_type, if and only if no @p4runtime_translation annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 type declaration is itself a +user-defined type, original_type is obtained by “walking” the chain of +type declarations recursively until a built-in type (e.g. bit<W>) is +found. +

    • +
    • +

      translated_type, if and only if the P4 type declaration was annotated +with @p4runtime_translation. It is of type P4NewTypeTranslation, which +itself has two fields uri and sdn_bitwidth , which map to the +two input parameters to the annotation. +

    +
  • +
  • +

    annotations, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration. +

+ +

For example, an architecture in this case PSA may introduce a new type +for port numbers: +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type bit<9> PortId_t;
+

In this case, the P4Info message would include the following P4TypeInfo +message: +

+
+
+
type_info {
+  new_types {
+    key: "PortId_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+

Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (e.g. through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over @p4runtime_translation to enable users +to overwrite annotations included as part of the P4 architecture definition. +

8.5.7. Trade-off for v1.0 Release

+

For the v1.0 release of P4Runtime, it was decided not to replace occurrences of +bytes with P4Data in the p4.v1.FieldMatch message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-release +implementations of P4Runtime. Similarly it has been decided to keep using +bytes to provide action parameter values. However P4Data is used whenever +appropriate for PSA externs and we encourage the use of P4Data in +architecture-specific extensions. +

+

In order to support translation for action +parameters and match fields, we include a type_name field in +p4.config.v1.MatchField and p4.config.v1.Action.Param. +

9. P4 Entity Messages

+

P4Runtime covers P4 entities that are either part of the P416 language, or +defined as PSA externs. The sections below describe the messages for each +supported entity. +

9.1. TableEntry

+

The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action's +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification. +

+

P4Runtime supports inserting, modifying, deleting and reading table entries with +the TableEntry entity, which has the following fields: +

+
    +
  • +

    table_id, which identifies the table instance; the table_id is determined +by the P4Info message. +

  • +
  • +

    match, a repeated field of FieldMatch messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration. +

  • +
  • +

    action, which indicates which of the table's actions to execute in case of +match and with which argument values. +

  • +
  • +

    priority, a 32-bit integer used to order entries when the table's match key +includes a ternary or range match. +

  • +
  • +

    controller_metadata, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. +

  • +
  • +

    meter_config, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    counter_data, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    is_default_action, a boolean flag which indicates whether the table entry is +the default entry for the table. See Default entry +section for more information. +

  • +
  • +

    idle_timeout_ns and time_since_last_hit, which are two fields used to +implement idle-timeout support for the table, if applicable. See +Idle-timeout section for more information. +

+ +

The priority field must be set to a non-zero value if the match key includes a +ternary match (i.e. in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has a TERNARY or RANGE match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches. +

+

The match and priority fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for MODIFY and DELETE updates. When deleting +an entry, these key fields (along with is_default_action) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a keyless +table (the table has an empty match key), the server must reject all attempts to +INSERT a match entry and return an INVALID_ARGUMENT error. +

+

The number of match entries that a table should support is indicated in P4Info +(size field of Table message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P416 specification for the +size property [29]. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +RESOURCE_EXHAUSTED when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached. +

9.1.1. Match Format

+

The bytes fields in the FieldMatch message follow the format described in +Bytestrings. +

+

For “don't care” matches, the P4Runtime client must omit the field's entire +FieldMatch entry when building the match repeated field of the TableEntry +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for “don't care” matches, which is needed +to ensure read-write symmetry. For PSA match types, +a “don't care” match for a specific match key field is defined as follows: +

+
    +
  • +

    For a TERNARY match, it is logically equivalent to a mask of zeros. +

  • +
  • +

    For an LPM match, it is logically equivalent to a prefix_len of zero. +

  • +
  • +

    For a RANGE match, it is logically equivalent to a range which includes all +possible values for the field. +

+ +

Note that there is no “don't care” value for EXACT matches and therefore exact +match fields can never be omitted from the TableEntry message. +

+

The following example shows a P4Runtime message that treats a TERNARY field +as a “don't care” match. The P4 program defines table t with TERNARY +and EXACT fields in its match key: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: ternary;
+    istd.ingress_port: exact;
+  }
+  actions = {
+    drop;
+  }
+}
+

In this P4Runtime request, the client omits the table's TERNARY field +from the repeated match field to indicate a “don't care” match. As shown +below, the match specifies only the EXACT field given by field_id: 2. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 33554439  # Table t's ID.
+    match {
+      # field_id 1 is not present to use the don't care ternary value.
+      field_id: 2
+      exact {
+        value: "\x20"
+      }
+    }
+    action {
+      # Action selection goes here.
+    }
+  }
+}
+

For every member of the TableEntry repeated match field, field_id must be +a valid id for the table, as per the P4Info, and one of the fields in +field_match_type must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an INVALID_ARGUMENT error code. +

+
    +
  • EXACT match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.exact().value()))
+
    +
  • LPM match + +
      +
    • The binary string encoding of the value (when present) must conform to the +Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • “Don't care” bits must be 0 in value. +
+ +
+
+
assert(BytestringValid(match.lpm().value()))
+
+pLen = match.lpm().prefix_len()
+assert(pLen > 0)
+
+trailing_zeros = countTrailingZeros(match.lpm().value())
+assert(trailing_zeros >= field_bits - pLen)
+
    +
  • TERNARY match + +
      +
    • The binary string encoding of the value (when present) and mask (when +present) must conform to the Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • Masked bits must be 0 in value. This constraint taken together +with the Bytestrings requirements means that the +value's binary string is never longer than the mask's binary string. +When the value's string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask. +
+ +
+
+
assert(BytestringValid(match.ternary().value()))
+assert(BytestringValid(match.ternary().mask()))
+assert(match.ternary().value().size() <= match.ternary().mask().size());
+
+value = parseInteger(match.ternary().value())
+mask = parseInteger(match.ternary().mask())
+
+assert(mask != 0)
+
+assert(value & mask == value)
+
    +
  • RANGE match + +
      +
    • The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the Bytestrings +requirements. +
    • +
    • Low bound must be less than or equal to the high bound. +
    • +
    • “Don't care” match must be omitted. +
+ +
+
+
assert(BytestringValid(match.range().low()))
+assert(BytestringValid(match.range().high()))
+
+low = parseInteger(match.range().low())
+high = parseInteger(match.range().high())
+
+assert(low <= high)
+
+assert(low != min_field_value || high != max_field_value)

9.1.2. Action Specification

+

The TableEntry action field must be set for every INSERT update but may be +left unset for MODIFY updates, in which case the action specification for the +table entry will not be modified (if a MODIFY update has an unset action field +and does not modify any direct resource attached to the table then the MODIFY +update is a no-op). Based on the implementation property value of the P4 table, +the oneof in the TableAction message will either be: +

+
    +
  • +

    an Action specification for direct tables (with no P4 implementation +property) +

  • +
  • +

    an action profile member id for indirect tables for which the implementation +property is an action profile with no selector. +

  • +
  • +

    an action profile member id or group id for indirect tables for which the +implementation property is an action profile with selector. +

  • +
  • +

    an ActionProfileActionSet specification for indirect tables for +which the implementation property is an action profile with +selector. This usage is described in One Shot Action Selector +Programming +

+ +

If the oneof does not match the table description in the P4Info (e.g. the +oneof is action_profile_member_id for a direct table), the server must +return an INVALID_ARGUMENT error code. +

+

The Action Protobuf message has the following fields: +

+
    +
  • +

    action_id, which identifies the action instance; the action_id is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an INVALID_ARGUMENT error +code. If the client uses a valid action_id for the table but does not +respect the action scope specified in P4Info (e.g. tries to set a TABLE_ONLY +action as the default action), the server must return a PERMISSION_DENIED +error code. +

  • +
  • +

    params: a repeated Protobuf field of action parameter values, each encoded +as a Param message. For each parameter, param_id must be valid for the +action (as per the P4Info) and value must follow the format described in +Bytestrings. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an INVALID_ARGUMENT error code +if a parameter id is missing, if an extra parameter id not found in the +P4Info was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +Bytestrings format. +

+ +

For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a NOT_FOUND error code. +

9.1.3. Default Entry

+

According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer or defaults to NoAction +(which is a no-op) otherwise and assuming it is not declared as const, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow INSERT and DELETE updates on the default entry and the +P4Runtime server must return an INVALID_ARGUMENT error code if the client +attempts one. +

+

The default entry is identified by setting the is_default_action boolean field +to true. When this flag is set to true, the repeated match field must be empty +and the priority field must be set to zero, otherwise the P4Runtime server +must return an INVALID_ARGUMENT error code. When performing a MODIFY update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its controller_metadata value as well as the configurations for its +direct resources will be reset to their defaults. If +the default entry is constant (as indicated by the P4 program and the P4Info +message), the server must return a PERMISSION_DENIED error code if the client +attempts to modify it. +

+

Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to direct resources. +

+

In this P4Runtime release, we have decided to restrict the default entry for +indirect tables tables with an ActionProfile or ActionSelector +implementation property to a constant NoAction action entry, with the +hope that it would simplify the implementation of the P4Runtime service. +

9.1.4. Constant Tables

+

Constant tables are defined as tables whose match entries are immutable. They +are identified by the is_const_table flag in P4Info. +

+

The only write updates which are allowed for constant tables are MODIFY +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +PERMISSION_DENIED error. Just like any table entry MODIFY request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a PERMISSION_DENIED error. +

+

The contents of const tables can be queried by the client through a +ReadRequest. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: table_id, match, action, +is_default_action, and priority (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the priority field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P416 does not support assigning explicit priorities to static +entries. When a priority value is required (e.g. for tables including RANGE +and / or TERNARY matches in the case of PSA), it is inferred based on the +order in which entries appear in the table declaration. +

9.1.5. Wildcard Reads

+

When performing a ReadRequest, the P4Runtime client can select all entries +from one or all tables on the target and use several of the TableEntry fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as priority and “unset” for message fields such as match. The following +fields may be used to select and filter results: +

+
    +
  • table_id: If default (0), entries from all tables including constant +tables will be selected and no other filter can be used. Otherwise only +the specified table will be considered. +
  • +
  • match: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned. +
  • +
  • action: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an action_id (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id. +
  • +
  • priority: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value. +
  • +
  • controller_metadata: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +controller_metadata value. +
  • +
  • is_default_action: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered. +
+ +

For example, in order to read all entries from all tables from device 3, the +client can use the following ReadRequest message. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0
+    priority: 0
+    controller_metadata: 0
+  }
+}
+

In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following ReadRequest +message: +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+    priority: 11
+    controller_metadata: 0
+  }
+}
+

The canonical representation of “don't care” matches, combined with the ability +to do a wildcard read on all table entries by leaving the match field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single “don't care” entry or to do a wildcard +read. If a table has no fields with match kind EXACT, it is possible via +P4Runtime to add an entry that is “don't care” for all fields (i.e. has an empty +match field) but is not the default entry (i.e. is_default_action is +false). When reading this entry from the table, there is no way to read only +that entry from the table, because it would require providing an unset match +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single LPM match: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: lpm;
+  }
+  actions = {
+    drop; fwd;
+  }
+}
+

The following WriteRequest message can be used to add 2 entries: +

+
+
+
device_id: 3
+entities {
+  table_entry { # don't care entry
+    table_id: 0x0212ab34
+    # ...
+  }
+  table entry {
+    table_id: 0x0212ab34
+    match {
+      field_id: 1
+      lpm {
+        value: 0x0a000000
+        prefix_len: 8
+      }
+    # ...
+  }
+}
+

The first entry is a “don't care” entry, while the second one matches all +10.0.0.0/8 addresses. The second entry has higher priority than the first one. +

+

The following ReadRequest message will return all entries in the table, not +just the “don't care” entry. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+  }
+}
+

This issue also exists for tables with TERNARY and / or RANGE +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the “don't care” entry will be returned to the +client. If the client uses distinct priority values for all entries which is +strongly recommended to achieve deterministic behavior , +then there is no ambiguity because the wildcard read will actually return a +single entry (the “don't care” entry) as long as the priority field is set to +the correct value. +

9.1.6. Direct Resources

+

In addition to the DirectCounterEntry and DirectMeterEntry entities, +P4Runtime support reading and writing direct resources as part of the +TableEntry message. This is convenient for two reasons: +

+
    +
  • +

    A table entry and its direct resources can be read with a single entity when +doing a Read RPC call +

  • +
  • +

    The initial configuration for an entry's direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can “hit” the table entry without +executing the appropriate meter entry. +

+ +

Once the table entry has been inserted, the P4Runtime client is free to use the +DirectCounterEntry and DirectMeterEntry messages for read and write +operations on DirectCounter and DirectMeter instances. For example, it is +usually more convenient as well as more efficient to use DirectCounterEntry to +query a counter entry value rather than use TableEntry, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry. +

+

The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does not need to be “executed” in +every action bound to the table. It is an error to provide a direct resource +configuration in a TableEntry message when programming an action that does not +execute the direct resource, and the server must return an INVALID_ARGUMENT +error code. +

+

We leverage Protobuf's ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the TableEntry message. The list below describes how +the server must handle the meter_config and counter_data fields for read and +write requests, based on whether the fields are set or not. We do not cover +error cases in the list, i.e. we assume that we are dealing with a table which +is assigned a direct counter / a direct meter, and that the action being used +for the table entry “executes” the direct resource appropriately. +

+
    +
  • +

    meter_config field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets). +
      • +
      • if set: The initial configuration for the meter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The meter entry's configuration is reset to the default +(meter returns GREEN for all packets). +
      • +
      • if set: The value provided by the client is used to re-configure +the meter entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the meter entry's +configuration (meter_config is unset in the response). +
      • +
      • if set: If the meter entry's configuration is the default +configuration, meter_config is unset in the response. Otherwise, the +response includes the meter entry's configuration that was written by +the client earlier. This respects the “read-write symmetry” principle. +
    +
  • +
  • +

    counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for the counter entry is the default +(0). +
      • +
      • if set: The initial value for the counter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The counter entry's value is not changed. +
      • +
      • if set: The value provided by the client is written to the counter +entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the counter entry's value +(counter_data is unset in the response). +
      • +
      • if set: The response includes the counter entry's value read from +the target. +
    +
+ +

In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +meter_config field unset when inserting or modifying a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the TableEntry message +(i.e. the meter_config field must be set to match the existing configuration). +

9.1.7. Idle-timeout

+

P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not “hit” (i.e. not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification using the +IdleTimeoutNotification message to the master client, which can then take +action, such as remove the idle table entry. +

+

Two fields of the TableEntry Protobuf message are used to implement idle +timeout: +

+
    +
  • +

    idle_timeout_ns: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, i.e. no +IdleTimeoutNotification message will ever be generated for this entry. When +a client reads a TableEntry, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry. +

  • +
  • +

    time_since_last_hit: a Protobuf message with a single field (elapsed_ns) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The time_since_last_hit field must be unset for a +TableEntry write. When reading a table entry, time_since_last_hit must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0. +

+ +

These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an INVALID_ARGUMENT error code if at least one of these +conditions is met: +

+
    +
  • idle_timeout_ns is set to a non-zero value, or +
  • +
  • time_since_last_hit is set +
+ +

The target should do its best to approximate the idle_timeout_ns value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the TableEntry write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for time_since_last_hit. +

+

P4Runtime does not support idle timeout for default entries. When the +is_default_action flag is set in a TableEntry message, idle_timeout_ns +must be set to 0 (default) and time_since_last_hit must be unset. If the +server receives a TableEntry message which violates this, it must return an +INVALID_ARGUMENT error. +

+

For more information about idle timeout, in particular regarding +IdleTimeoutNotification, please refer to the Table idle timeout +notifications section. +

9.2. ActionProfileMember & ActionProfileGroup

+

P4Runtime defines an API for programming a PSA ActionProfile extern using +ActionProfileMember messages. A PSA ActionSelector extern can be programmed +using both ActionProfileMember and ActionProfileGroup messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table t for L3 routing, implemented with an action +selector as. +

+
+
+
ActionSelector(HashAlgorithm.crc32,
+               /*size = */ 32w1024,
+               /*output_width = */ 32w10) as;
+
+action set_nhop(PortId_t p, EthAddr smac, EthAddr dmac) {
+  istd.egress_port = p;
+  hdr.ethernet.smac = smac;
+  hdr.ethernet.dmac = dmac;
+}
+
+table t {
+  key = {
+    hdr.ipv4.dip: lpm;  // LPM on destination IP address
+  }
+  actions = {
+    set_nhop;
+  }
+  implementation = as;
+}
+

When programming table t in the example above, a P4Runtime client should +specify the TableAction in the TableEntry to be a reference to either an +action profile member or group. The reference is a uint32 identifier that +uniquely identifies a member or group programmed in the action selector as. +

+

If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata. +

+

If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata. +

9.2.1. Action Profile Member Programming

+

Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a uint32 identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the actions +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the actions attributes of the +tables must have an identical list of P4 actions. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector. +

+

An ActionProfileMember entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info. +

  • +
  • +

    member_id is the uint32 identifier of the action profile member entry +being updated. +

  • +
  • +

    action is the specification of the P4 action instance bound to the action +profile member entry. +

+ +

An action profile member may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an ALREADY_EXISTS error +code. The action specification must be provided, or the server must return +INVALID_ARGUMENT. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return RESOURCE_EXHAUSTED. +
  • +
  • MODIFY: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return NOT_FOUND, +and the action specification must be provided, or the server must return +INVALID_ARGUMENT. +
  • +
  • DELETE: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a NOT_FOUND error code. The member +must not be part of an action profile group, or the server must return +FAILED_PRECONDITION. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return FAILED_PRECONDITION. member_id is the only field which is +considered when performing a DELETE and every other field will be ignored. +
+

9.2.2. Action Profile Group Programming

+

Action profile groups are entries in an ActionSelector and are referenced by a +uint32 identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type. +

+

An ActionProfileGroup entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionSelector +extern instance, as defined in P4Info. +

  • +
  • +

    group_id is the uint32 identifier of the action profile group entry being +updated. +

  • +
  • +

    members is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields: +

    +
      +
    • member_id for looking up the member table in the selector. +
    • +
    • weight specifying the probability of the member's selection at +runtime. 0 is not a valid weight value and the server must return +INVALID_ARGUMENT if the client attempts to use it. +
    • +
    • watch is the controller-defined 32-bit port number that the member's +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. +
    +
  • +
  • +

    max_size is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +MODIFY update. See the subsection below for the rules on setting +max_size. +

+ +

An action profile group may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new group entry bound to a set of existing action profile +members. The group_id must be different from ids of already programmed +groups for that selector, or the server must return an ALREADY_EXISTS error +code. All members specified in the group must exist in the selector, or the +server must return NOT_FOUND. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target. +
  • +
  • MODIFY: Modify the member set specification of an existing group entry. An +entry with the group_id must exist, or the server must return +NOT_FOUND. All members specified in the group entry must exist in the +selector, or the server must return NOT_FOUND. The value of max_size must +be identical to the value used when inserting the group, otherwise an +INVALID_ARGUMENT error is returned. +
  • +
  • DELETE: Delete the group entry and deallocate the group_id. The group must +not be referenced in the table action of any table entry, or the server must +return a FAILED_PRECONDITION error code. If the group_id is invalid, the +server must return NOT_FOUND. group_id is the only field which is +considered when performing a DELETE and every other field will be ignored. +
+ +

When setting the group membership with INSERT or MODIFY, the members +repeated field must not include duplicates, i.e. members with the same +member_id. The weight field is used instead to logically “repeat” the member +inside the group. +

+

It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation “stores” the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made. +

9.2.2.1. Rules on Setting max_size
+

The valid values for max_size depend on the static max_group_size included +in the P4Info message: +

+
    +
  • +

    If max_group_size is greater than 0, then max_size must be greater than 0, +and less than or equal to max_group_size. We assume that the target can +support selector groups for which the sum of all member weights is up to +max_group_size, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If max_size is greater than max_group_size, the server +must return INVALID_ARGUMENT. +

  • +
  • +

    Otherwise (i.e. if max_group_size is 0), the P4Runtime client can set +max_size to any value greater than or equal to 0. +

    +
      +
    • +

      A max_size of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (INSERT or MODIFY), the target must return a +RESOURCE_EXHAUSTED error. +

    • +
    • +

      If max_size is greater than 0 and the value is not supported by the +target, the server must return a RESOURCE_EXHAUSTED error at +group-creation time. +

    +
+

9.2.3. One Shot Action Selector Programming

+

P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids. +

+

One shots are programmed by choosing the ActionProfileActionSet message as the +TableAction. The ActionProfileActionSet message consists of a set of +ActionProfileAction messages, which in turn have the following fields: +

+
    +
  • +

    action is one of the actions specified by the table that is being +programmed. +

  • +
  • +

    weight specifying the probability of the action's selection at runtime. 0 is +not a valid weight value and the server must return INVALID_ARGUMENT if +the client attempts to use it. The sum of all weights across all +ActionProfileAction messages for that ActionProfileActionSet message must +not exceed the max_group_size specificed in the P4Info (if greater than 0), +or the server must return INVALID_ARGUMENT. +

  • +
  • +

    watch is the controller-defined 32-bit port number that the action's +liveness depends on. At runtime, the action must be excluded from selection if +the watch port is down. +

+ +

Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics. +

+

To preserve read-write symmetry, an implementation must answer ReadRequests +with the original one shot messages. It may not return a desugared version of +the one shot message. +

+

For example, consider the action selector table defined +here. This table could be programmed +with the following one shot update: +

+
+
+
table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action {
+    action_profile_action_set {
+      action_profile_actions {
+        action { /* set nexthop 1 */ }
+        weight: 1
+        watch: 1
+      }
+      action_profile_actions {
+        action { /* set nexthop 2 */ }
+        weight: 2
+        watch: 2
+      }
+      action_profile_actions {
+        action { /* set nexthop 3 */ }
+        weight: 3
+        watch: 3
+      }
+    }
+  }
+}
+

Which would be equivalent to the following updates, where GROUP_ID, +MEMBER_ID_1, MEMBER_ID_2, and MEMBER_ID_3 are unused ids: +

+
+
+
action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_1
+  action { /* set nexthop 1 */ }
+}
+action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_2
+  action { /* set nexthop 2 */ }
+}
+action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_3
+  action {  /* set nexthop 3 */ }
+}
+action_profile_group {
+  action_profile_id: 0x11ab12cd
+  group_id: GROUP_ID
+  members {
+    member_id: MEMBER_ID_1
+    weight: 1
+    watch: 1
+  }
+  members {
+    member_id: MEMBER_ID_2
+    weight: 2
+    watch: 2
+  }
+  members {
+    member_id: MEMBER_ID_3
+    weight: 3
+    watch: 3
+  }
+}
+table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action { action_profile_group_id: GROUP_ID }
+}
+

Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure correct ordering between the dependent +updates. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct WriteRequest batches are required. +

+

It is possible to include several ActionProfileAction messages with the same +exact action specification in one ActionProfileActionSet message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the weight field. Note that to preserve read-write symmetry, the server +must not coalesce multiple ActionProfileAction messages with the same action +specification into one. +

+

All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with ActionProfileMember and +ActionProfileGroup messages. Programming some entries with one shots, and +other entries with ActionProfileMember and ActionProfileGroup messages is +not allowed, and the server must return the error code INVALID_ARGUMENT in +that case. +

+

A P4Runtime server must support the one shot style of programming tables with +an action selector implementation. Support for the ActionProfileMember and +ActionProfileGroup style is optional. If ActionProfileMember and +ActionProfileGroup are not supported by a server, it must return an +UNIMPLEMENTED error for every ActionProfileMember or ActionProfileGroup +message that it receives. +

9.2.4. Constraints on action selector programming

+

The PSA specification states that the following features are optional in +action selector implementations [21]: +

+
    +
  1. Support for non-empty groups where in the same group, different members are +bound to different actions. +
  2. +
  3. Predictable data plane behavior when a matched table entry points to an empty +group. +
+ +

For 1., if a client tries to INSERT or MODIFY a group with members bound to +different actions, the server should return UNIMPLEMENTED if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return UNIMPLEMENTED (modifying the action parameter values must be +supported, however). +

+

PSA 1.1 introduces the psa_empty_group_action table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. psa_empty_group_action is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of psa_empty_group_action at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +NoAction. Even when psa_empty_group_action is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of psa_empty_group_action mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming. +

+

The PSA specification includes a discussion on how to implement +psa_empty_group_action in software in the P4Runtime server +[24]. +

9.3. CounterEntry & DirectCounterEntry

+

PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The CounterData +P4Runtime message can be used for all three types of PSA counters PACKETS, +BYTES and PACKETS_AND_BYTES and consists of the following fields: +

+
    +
  • byte_count is an int64, corresponding to the number of octets. +
  • +
  • packet_count is an int64, corresponding to the number of packets. +
+ +
+
+
message CounterData {
+  int64 byte_count = 1;
+  int64 packet_count = 2;
+}
+

P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of byte_count and packet_count fields, which +is equivalent to specifying the counter type PACKETS_AND_BYTES. Counters may +be defined as direct or indirect (indexed) instances. +

9.3.1. DirectCounterEntry

+

A direct counter is a direct resource associated with a TableEntry (see +Direct Resources). The counter_data field of the +TableEntry message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +DirectCounterEntry message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed. +

+
+
+
message DirectCounterEntry {
+  TableEntry table_entry = 1;
+  CounterData data = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectCounterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match TableEntry.match of the table entry +to which this direct counter entry is associated. If a matching TableEntry +is not found, the server returns the error code NOT_FOUND. +

  • +
  • +

    data is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified. +

+ +

Specifying DirectCounterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read the contents of a +DirectCounter: +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the counter value in the counter_data field of the TableEntry message +(see Direct resources). +

  • +
  • +

    Explicitly request the counter value by including the DirectCounterEntry in +the ReadRequest. The table_entry.match field must match the TableEntry +whose counter is being read. If no such entry is found, the server returns the +error code NOT_FOUND. +

+

9.3.2. CounterEntry

+

An indirect or indexed counter is not associated with a specific TableEntry +and may be updated independently of any action. It may be read or written using +the P4Runtime CounterEntry message whose fields are defined as follows: +

+
    +
  • +

    counter_id is a uint32, the unique identifier for the counter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +the counter array. +

  • +
  • +

    data is a Protobuf message of type CounterData, which represents the +counter value. +

+ +
+
+
message CounterEntry {
+  uint32 counter_id = 1;
+  Index index = 2;
+  CounterData data = 3;
+}
+

The CounterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the counter entries in the +array have default value 0. +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect counter instance whose unique id is counter_id +and array index is specified by index. The counter value is set to the value +specified by the client in the data field. Note that the counter value is +not modified if this Protobuf field is not set. If index is omitted all +counter values in the array will be set to the value provided by the +client. The server must return INVALID_ARGUMENT for a negative index value +and OUT_OF_RANGE if the index value exceeds the size of the counter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a ReadRequest by including a CounterEntry +entity for each of the instances, specifying the counter_id and +index. Wildcard reads are also supported as follows. +

+
    +
  • +

    If the counter_id field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id counter_id. +

+

9.4. MeterEntry & DirectMeterEntry

+

Meters are an advanced mechanism for keeping statistics, involving stateful +“marking” and usually “throttling” of packets based on configured rates of +traffic. The PSA metering function is based on the Two Rate Three Color Marker +(trTCM) defined in RFC 2698 [2]. The trTCM meters an arbitrary packet +stream using two configured rates the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes and +“marks” its packets as GREEN, YELLOW or RED based on the observed rate. +

+

A meter may be configured as a direct or indirect instance, similar to a +counter. The MeterConfig P4Runtime message represents meter configuration. +

+
+
+
message MeterConfig {
+  int64 cir = 1;  // Committed Information Rate
+  int64 cburst = 2;  // Committed Burst Size
+  int64 pir = 3;  // Peak Information Rate
+  int64 pburst = 4;  // Peak Burst Size
+}

9.4.1. DirectMeterEntry

+

A direct meter is a direct resource associated with a TableEntry (see Direct +resources). The meter_config field of the TableEntry +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +DirectMeterEntry message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed. +

+
+
+
message DirectMeterEntry {
+  TableEntry table_entry = 1;
+  MeterConfig config = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectMeterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match the match key of the TableEntry +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching TableEntry is not found, +the server returns the error code NOT_FOUND. +

  • +
  • +

    config is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets). +

+ +

Specifying DirectMeterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read a DirectMeter config. +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the meter config in the meter_config field of the TableEntry +message (see Direct resources). +

  • +
  • +

    Explicitly request the meter configuration by including the DirectMeterEntry +in the ReadRequest. The table_entry.match field must match the +TableEntry whose meter config is being read. If no such entry is found, the +server returns the error code NOT_FOUND. +

+

9.4.2. MeterEntry

+

An indirect or indexed meter is not associated with a specific TableEntry and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime MeterEntry message whose fields are defined as +follows: +

+
    +
  • +

    meter_id is a uint32, the unique identifier for the meter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +a meter array. +

  • +
  • +

    config is a Protobuf message of type MeterConfig, which represents the +meter configuration. +

+ +
+
+
message MeterEntry {
+  uint32 meter_id = 1;
+  Index index = 2;
+  MeterConfig config = 3;
+}
+

The MeterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the meter entries in the +array have a default configuration (GREEN for all packets). +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect meter instance whose unique id is meter_id and +array index is specified by index. The meter is reconfigured using the +config field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the index field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if config is unset). The server must return INVALID_ARGUMENT for a +negative index value and OUT_OF_RANGE if the index value exceeds the size of +the meter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a ReadRequest by including a MeterEntry entity for each +of the instances, specifying the meter_id and index. Wildcard reads are also +supported as follows: +

+
    +
  • +

    If the meter_id field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id meter_id. +

+

9.5. PacketReplicationEngineEntry

+

The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets. +

9.5.1. MulticastGroupEntry

+

Multicasting is achieved in PSA programs by setting the multicast_group +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the MulticastGroupEntry API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example. +

+
+
+
control arp_multicast(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ethernet.isValid() &&
+        hdr.ethernet.eth_type == ETH_TYPE_ARP) {
+      smeta.multicast_group = (MulticastGroup_t) 1;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    multicast_group_entry {
+      multicast_group_id: 1
+      replicas { egress_port: 5 instance: 1 }
+      replicas { egress_port: 12 instance: 2 }
+      replicas { egress_port: 18 instance: 3 }
+      replicas { egress_port: 24 instance: 4 }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +PSA Metadata Translation section. +

+

The egress packets may be distinguished for further processing in the egress +using the instance metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 multicast_group metadata is set to a value that is not +programmed in the PRE, then the packet is dropped. +

+

A multicast group may be inserted, modified or deleted as per the following +semantics. +

+
    +
  • INSERT: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The multicast_group_id field is a uint32 and must be greater +than 0 (see explanation below), or the +P4Runtime server must return an INVALID_ARGUMENT error. The replica +instance ID is also a uint32, and its value may not exceed the maximum +allowed by the target for the EgressInstance_t type (0 is allowed), or the +server must return an INVALID_ARGUMENT error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of both egress_port and instance, or the server +must return INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify the set of replicas for a given multicast group entry, +indexed by the given multicast_group_id. Same restrictions as INSERT apply +here. +
  • +
  • DELETE: Delete the multicast group indexed by the given +multicast_group_id. The replicas need not be provided for this +operation. Any packets with their multicast_group metadata in the data plane +set to the deleted multicast_group_id will be dropped. +
+ +

When reading a multicast group, only multicast_group_id is considered. All +other fields in MulticastGroupEntry are ignored. To perform a wildcard +Read on all configured multicast group entries, the multicast_group_id field +must be set to 0, its default value. +

9.5.1.1. Valid Values for multicast_group_id
+

The PSA specification states that the valid data plane values for multicast +group ids (MulticastGroup_t) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target [23]. This means that, in the absence of +translation, the client must set the multicast_group_id field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special wildcard value which is used to read all the multicast groups +configured in the target, the multicast_group_id field must never be set to 0 +when performing a Write RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value. +

9.5.2. CloneSessionEntry

+

PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +clone_session_id identifier and a boolean flag clone in the packet +metadata. The clone_session_id serves as a handle to the clone attributes, +namely a set replicas of (egress port, instance) pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +CloneSessionEntry API. +

+

The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the clone_low_ttl control block is applied in the ingress +pipeline to create an ingress-to-egress clone. +

+
+
+
control clone_low_ttl(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ipv4.isValid() &&
+        hdr.ipv4.ttl <= LOW_TTL_THRESHOLD) {
+      smeta.clone_session_id = 10w100;
+      smeta.clone = true;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    clone_session_entry {
+      session_id: 100
+      replicas { egress_port: 0xfffffffd instance: 1 } # to CPU
+      class_of_service: 2
+      packet_length_bytes: 4096
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type CloneSessionId_t [23]). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes. +

+

The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port 0xfffffffd; see +Translation of Port Numbers). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port. +

+

If the clone_session_id data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created. +

+

A clone session may be inserted, modified or deleted as per the following +semantics: +

+
    +
  • INSERT: Add a new clone session entry bound to a set of egress ports and +replica IDs. The session_id is a uint32 and must be greater than 0 (see +explanation below), or the P4Runtime +server must return an INVALID_ARGUMENT error. The replica instance ID is +also a uint32, and its value may not exceed the maximum allowed by the +target for the EgressInstance_t type (0 is allowed), or the server must also +return an INVALID_ARGUMENT error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (class_of_service field). This value must be a valid +value for the PSA ClassOfService_t type, which supports runtime translation +by default [23], or the server must return +INVALID_ARGUMENT. See PSA Metadata +Translation for more information. The +packet_length_bytes field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +packet_length_bytes field is 0 (default), no truncation on the clone will be +performed. +
  • +
  • MODIFY: Modify the attributes of a given clone session entry, indexed by the +given clone_session_id. Same restrictions as INSERT apply here. +
  • +
  • DELETE: Delete the clone session indexed by the given +clone_session_id. Other fields need not be provided for this operation. Any +packet with their clone_session_id metadata in the data plane set to the +deleted session_id will no longer be cloned. +
+ +

When reading a clone session, only session_id is considered. All other fields +in CloneSessionEntry are ignored. To perform a wildcard Read on all +configured clone session entries, the session_id field must be set to 0, its +default value. The session_id field can never be equal to 0 in a Write +RPC. If it does, the server must return an INVALID_ARGUMENT error. +

9.5.2.1. Valid Values for session_id
+

The PSA specification states that the valid data plane values for clone +session ids (CloneSessionId_t) range from 0 to the maximum value supported by +the target [23]. Note that unlike for multicast group +ids, 0 is a valid data plane value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special wildcard value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a session_id +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is not enabled, we effectively +“lose” one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (e.g. because the target supports a very +limited number of clone sessions), one can enable translation on +CloneSessionId_t and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id. +

9.6. ValueSetEntry

+

Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the parse_trill_types state. +

+
+
+
state parse_l2 {
+  @id(1) value_set<ETH_TYPE_BITWIDTH>(MAX_TRILL_TYPES) trill_types;
+  extract(hdr.ethernet);
+  select (hdr.ethernet.eth_type) {
+    ETH_TYPE_IPV4: parse_ipv4;
+    ETH_TYPE_IPV6: parse_ipv6;
+    trill_types:   parse_trill_types;
+    _:             reject;
+  }
+}
+

The corresponding entry in the P4Info for this Value Set is: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "trill_types"
+  }
+  match {
+    id: 1
+    bitwidth: <ETH_TYPE_BITWIDTH>
+    match_type: EXACT
+  }
+  size: <MAX_TRILL_TYPES>
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0x22f3 }
+      }
+      match {
+        field_id: 1
+        exact { value: 0x893b }
+      }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the parse_trill_types state. +

+

A ValueSetEntry entity update message has the following fields: +

+
    +
  • +

    value_set_id is the uint32 identifier of the Value Set instance, as +defined in P4Info. +

  • +
  • +

    members is a repeated field of type ValueSetMember. When “selecting” +against a Value Set, every member will be considered and if at least one +“matches”, the corresponding parser transition will be taken. Each +ValueSetMember contains a repeated field of FieldMatch messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a ValueSetMember if and only if +it matches all its FieldMatch messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. FieldMatch messages in a ValueSetEntry follow +the same rules as in a TableEntry. +

+ +

A ValueSetEntry may only be modified. If the update type is INSERT or +DELETE, the server must return an INVALID_ARGUMENT error. If the update type +is MODIFY, the server writes the members given in the repeated field to the +Value Set entry indexed by the given value_set_id. The maximum number of +matches must not exceed the maximum size given by the size field in P4Info of +the Value Set, otherwise the server must return a RESOURCE_EXHAUSTED error. To +empty a Value Set (i.e. restore it to its initial state), the P4Runtime client +can perform a MODIFY update with an empty members repeated field. +

+

To facilitate read-write symmetry, the server must +return an ALREADY_EXISTS error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary and range matches: +overlapping entries do not need to be ordered and the parse state transition +is determined by whether or not the packet matches at least one entry in the +set. +

+

See Appendix A.3 for a more complex Value Set example. +

9.7. RegisterEntry

+

The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The RegisterEntry P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations. +

+

RegisterEntry has the following fields: +

+
    +
  • +

    register_id, which identifies the PSA Register extern instance which is +being accessed by the client; the register_id is specified by the P4Info +message. +

  • +
  • +

    index, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the RegisterEntry message +used for the request. When an index is provided , the server must validate +its value, and return INVALID_ARGUMENT for a negative index or +OUT_OF_RANGE if the index exceeds the size of the register array. +

  • +
  • +

    data: the data to be written to the array (if RegisterEntry is part of a +WriteRequest message) or the data read from the array (if RegisterEntry is +part of a ReadResponse message). The data field is a P4Data message and +must match the format described by the type_spec field of the corresponding +Register entry in the P4Info, or the server must return an INVALID_ARGUMENT +error. +

+

9.8. DigestEntry

+

A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly. +

+

The DigestEntry P4Runtime entity is used to configure how the device must +generate digest messages. The DigestEntry Protobuf message is not used to +carry digest data, which is done on the StreamChannel bidirectional stream +using the DigestList (digest data sent by the target to the client) and +DigestListAck (digest data acknowledgments sent by the client to the target) +Protobuf messages. +

+

In this section, we refer to the data learned by a single data plane call to +Digest<T>::pack as a “digest message” and we use “digest list” to designate +the list of digest messages bundled by the P4Runtime service in a single +DigestList stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are “duplicate” if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are “distinct” +if they are not duplicate. +

+

DigestEntry has the following fields: +

+
    +
  • +

    digest_id, which identifies the PSA Digest extern instance which emitted the +data; the digest_id is determined by the P4Info message. +

  • +
  • +

    config, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +digest_id; these parameters are: +

    +
      +
    • max_timeout_ns: the maximum server buffering delay in nanoseconds for an +outstanding digest message. +
    • +
    • max_list_size: the maximum digest list size in number of digest +messages sent by the server to the client as a single DigestList +Protobuf message. +
    • +
    • ack_timeout_ns: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data. +
    +
+ +

Here is the significance of the different Update types for DigestEntry: +

+
    +
  • INSERT: Enable server generation of DigestList messages for given digest +instance and use provided configuration parameters. +
  • +
  • MODIFY: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance. +
  • +
  • DELETE: Disable server generation of DigestList messages for given digest +instance. +
+ +

A server should buffer digest messages until either: +

+
    +
  • max_timeout_ns time has passed since the first digest message was added to +the empty buffer, or +
  • +
  • max_list_size distinct digest messages have been received from the +data plane and added to the buffer +
+ +

At which point the server should, with best effort, generate a DigestList +stream message with the buffer contents and send it to the master client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software. +

+

To avoid sending duplicate digest messages across different DigestList +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the master client indicates that it has received the +digest list and acted on it. The server must keep a “cache” containing the set +of all digest messages that have been sent, but not acknowledged yet by the +master client, up-to ack_timeout_ns in the past. The server must delete all +cache entries for a given digest list when they are at least ack_timeout_ns +old or when a matching DigestListAck message (i.e. with the same digest_id +and list_id fields as the DigestList message) is received. +

+

The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged DigestList messages. +

+

When max_timeout_ns is set to 0 and / or max_list_size is set to 1, the +server should, with best effort, generate a DigestList message for every +digest message generated by the data plane which is not already in the cache. If +ack_timeout_ns is set to 0, the cache must always be an empty set. If +max_list_size is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +max_timeout_ns configuration parameter. +

+

The P4Runtime server may empty the digest message cache in case of a client +mastership change. +

+

Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server: +

+
+
+
DigestStream stream;
+DigestCache cache;
+DigestBuffer buffers;
+
+// sends digest list when it is ready
+send_buffer(Id digest_id) {
+  buffer = buffers[digest_id];
+  stream.write(DigestList(buffer));
+  cache.merge(buffer);  // updates cache with new digest list
+  buffer.clear();
+}
+
+// callback which handles data plane digest messages from device
+handle_dataplane_digest(Digest msg) {
+  digest_id = msg.digest_id();
+  buffer = buffers[digest_id];
+  if (msg in cache OR msg in buffer) return;
+  buffer.enqueue(msg);
+  if (buffer.length() < max_list_size(digest_id)) return;
+  send_buffer(digest_id);
+}
+
+// callback which handles ack messages received on the stream
+handle_stream_ack(DigestListAck ack) {
+  // clear all cache entries matching the tuple (digest_id, list_id)
+  cache.erase( (ack.digest_id(), ack.list_id() )
+}
+
+// loop to enforce timeouts
+while (true) {
+  now = now();
+  // check for buffers that need to be sent
+  for ((digest_id, buffer) in buffers) {
+    if (now - buffer.first_enq_time() >= max_timeout_ns(digest_id))
+      send_buffer(buffer_id);
+  }
+  // check for expired entries in cache
+  for ((digest_id, list_id, sent_time) in cache) {
+    if (now - sent_time >= ack_timeout_ns(digest_id))
+      cache.erase( (digest_id, list_id) );
+  }
+  sleep(X);
+}

9.9. ExternEntry

+

This is used to support a P4 extern entity that is not part of PSA. It is +defined as: +

+
+
+
message ExternEntry {
+  uint32 extern_type_id = 1;
+  uint32 extern_id = 2;
+  google.protobuf.Any entry = 3;
+}
+

Each ExternEntry entity maps to an Extern message in the +P4Info and an ExternInstance message within that +message. The extern_type_id field must be equal to the one in +ExternEntry. The extern_id field must be equal to the ID included in the +preamble of the corresponding ExternInstance message. +

+

entry itself is embedded as an Any Protobuf message [30] to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on Extending P4Runtime for non-PSA +Architectures for more information. +

10. Error Reporting Messages

+

P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case. +

+

gRPC uses grpc::Status [31] to represent the status returned by an +RPC. It has 3 attributes: +

+
+
+
StatusCode code_;
+grpc::string error_message_;
+grpc::string binary_error_details_;
+

The code_ represents a canonical error [33] and describes the +overall RPC status. The error_message_ is a developer-facing error message, +which should be in English. The binary_error_details_ carries a serialized +google.rpc.Status message [27] message, which has 3 fields: +

+
+
+
int32 code = 1;  // see code.proto
+string message = 2;
+repeated google.protobuf.Any details = 3;
+

The code and message fields must be the same as code_ and error_message_ +fields from grpc::Status above. The details field is a list that consists of +p4.Error messages that carry error details for individual elements inside +batch-request RPCs (e.g. Write and Read). p4.Error includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices [33]. +

+

Figure 7 illustrates how these messages fit together. +

+
+

error-report +

+
+ +
Figure 7. P4Runtime Error Report Message Format
+

gRPC provides utility functions ExtractErrorDetails() and SetErrorDetails() +[32] to easily convert between grpc::Status and +google.rpc.Status. +

+

Please see sections on individual P4Runtime RPCs for details on how +grpc::Status is populated for reporting errors. +

+

Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on Stream Error +Reporting for more information. +

11. Atomicity of Individual Write and Read Operations

+

Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane apply +operation, and every single Write operation on a table that inserts, deletes, +or modifies one table entry, the apply operation should behave as if that +Write operation has not yet occurred, or as if the Write operation is +complete. The P4 program should never behave as if the Write operation is +partially complete. These guarantees also apply to extern instances: Read and +Write operations on extern entities must execute atomically relative to extern +data plane methods. +

+

The atomicity guarantees provided by P4Runtime for individual Read and Write +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification [22]. +

+

The P416 language introduces an @atomic annotation [13], to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the @atomic annotation for Write +operations, as well as non-wildcard Read operations, +relative to data plane execution. Consider the following P4 example written for +PSA: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024) r1;
+
+  apply {
+    // ...
+    @atomic {
+        Value_t v = r1.read((Index_t)1);
+        v = v + 1;
+        r1.write((Index_t)1, v);
+    }
+  }
+}
+

If a P4Runtime server is processing messages which write to Register r1 at +index 1, these writes must not happen between the data plane read and +write. +

+

Now let's consider the following example: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024, (Value_t)0 /* initial value */) r1;
+
+  apply {
+    @atomic {
+        r1.write((Index_t)1, (Value_t)100);
+        r1.write((Index_t)2, (Value_t)100);
+    }
+    @atomic {
+        r1.write((Index_t)1, (Value_t)200);
+        r1.write((Index_t)2, (Value_t)200);
+    }
+  }
+}
+

If a P4Runtime client issues a wildcard Read on Register r1, there is no +guarantee that r1[1] == r1[2] in the response, as the read for r1[1] may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for r1[2] may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read r1[1] and r1[2] separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +ReadRequest message) of individual read requests. Similar to a batch +ReadRequest, a wildcard read of a register can execute the reads of the +register array elements (r1[1], r1[2], ) in an arbitrary order relative +to each other. +

+

If the @atomic annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program. +

12. Write RPC

+

The Write RPC updates one or more P4 entities on the target. The request is +defined as follows: +

+
+
+
message WriteRequest {
+  uint64 device_id = 1;
+  uint64 role_id = 2;
+  Uint128 election_id = 3;
+  repeated Update updates = 4;
+  enum Atomicity {
+    CONTINUE_ON_ERROR = 0;
+    ROLLBACK_ON_ERROR = 1;
+    DATAPLANE_ATOMIC = 2;
+  }
+  Atomicity atomicity = 5;
+}
+

The device_id uniquely identifies the target P4 device. The role_id and +election_id define the client role and election-id as described in the +Master-Slave Arbitration and Controller +Replication +section. The server is expected to perform the following checks (in this order) +before processing the updates list: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role_id does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the master for (device_id, role_id) according to the +election_id value, the server must return a PERMISSION_DENIED error. +

  4. +
  5. +

    If the Write is attempted before a ForwardingPipelineConfig has been set, +the server must return a FAILED_PRECONDITION error. +

+ +

The updates field is a list of P4 entity updates to be applied. Each update is +defined as: +

+
+
+
message Update {
+  enum Type {
+    UNSPECIFIED = 0;
+    INSERT = 1;
+    MODIFY = 2;
+    DELETE = 3;
+  }
+  Type type = 1;
+  Entity entity = 2;
+}
+

This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a logical table (e.g. +CounterEntry) or an actual table (e.g. TableEntry) in the P4 data +plane. Each entity in the container is uniquely identified by its key. Please +refer to the P4 Entity Messages section for details on +what parts of the entity specification make up the key for each P4 entity. +

+

An update can be one of the following types: +

+
    +
  • +

    INSERT: Inserts the given P4 entity in the entity container. +The entity field always specifies the full state of the P4 entity. +If the entity already exists, an ALREADY_EXISTS error is returned, and +the existing entity remains unchanged. +If the entity is malformed, an INVALID_ARGUMENT error is returned. +If the entity cannot be inserted because the container is already full, +a RESOURCE_EXHAUSTED error is returned. +

  • +
  • +

    MODIFY: Modifies the P4 entity to its new specified state. This uses +assign or full-snapshot semantics, i.e. the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an INVALID_ARGUMENT error is usually returned (unless a +more specific error code applies [33]). If the entity does not +exist, a NOT_FOUND error is returned. +

  • +
  • +

    DELETE: Deletes the specified P4 entity. If the entity does not exist, a +NOT_FOUND error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored. +

+ +

If an update is not allowed under the given controller role, the server must +return a PERMISSION_DENIED error for this update. +

12.1. Batching and Ordering of Updates

+

P4Runtime supports batching of Write operations. The list of updates in a +WriteRequest is referred to as a batch. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of TableEntry entities). +

+

The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +WriteRequests can also be processed interleaved and/or in parallel. +However, the processing of updates must be strictly serializable. That +is, given a history $S$ of WriteRequests including the responses to those +requests, there must exist an order $L$ for all updates in $S$, such that: +

+
    +
  1. For two updates $u_1$ and $u_2$, if the write request containing $u_1$ +completed before the write request of $u_2$ was sent, then $u_1$ must appear +before $u_2$ in $L$. +
  2. +
  3. Executing all updates in $L$ sequentially must yield the same response for +every update as in $S$. +
  4. +
  5. The observable state of the switch after $S$ (e.g., through the Read RPC) +is identical to the one obtained by sequentially executing $L$. +
+ +

The Write RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the Write RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, +with the exception of any operations that return an error status. +If two updates from the client depend on each other (e.g. inserting an +ActionProfileMember followed by pointing a TableEntry to it) and the updates +are not split into separate batches, then the behavior may be non-deterministic. +Similarly, clients can invoke multiple outstanding Write RPCs. If the updates +across these RPCs have dependencies, the observed behavior may be +non-deterministic. For this reason, most clients are advised to split dependent +updates across separate Write calls. Additionally, each Write call has to be +sent sequentially, waiting for the previous call to be acknowledged before +sending the next one. +

12.2. Batch Atomicity

+

A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the Atomicity +enum. A P4Runtime server is required to support only the modes marked as +Required below: +

+
    +
  • +

    Required: CONTINUE_ON_ERROR: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that see each of +these intermediate stages. +

  • +
  • +

    Optional: ROLLBACK_ON_ERROR: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is all-or-none, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that see each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure. +

    +

    If a P4Runtime server does not support this option at all, an +UNIMPLEMENTED error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (e.g. it is +more straightforward to implement batches that contain only INSERT +operations, vs. those that contain DELETE operations), an +UNIMPLEMENTED error is returned when the batch cannot be executed +in a data plane-atomic way. +

  • +
  • +

    Optional: DATAPLANE_ATOMIC: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +transaction. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane's table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table. +

    +

    If a P4Runtime server does not support this option at all, an UNIMPLEMENTED +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an UNIMPLEMENTED error is returned when the batch +cannot be executed in a data plane-atomic way. +

+ +

There is no expectation that a given client must always use the same Atomicity +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use DATAPLANE_ATOMIC at one time and default behavior +(CONTINUE_ON_ERROR) at other times. +

12.3. Error Reporting

+

Please see section Error Reporting Messages for +information on error reporting messages and guidelines. P4Runtime server will +populate grpc::Status as follows: +

+
    +
  1. +

    If all batch updates succeeded, set grpc::Status::code_ to OK and do not +populate any other field. +

  2. +
  3. +

    If an error is encountered before even trying to attempt individual batch +updates, set grpc::Status::code_ that best describes that RPC-wide +error. For example, use UNAVAILABLE if the P4Runtime service is not yet +ready to handle requests. Set error_message_ to describe the issue. Do not +set error_details in this case. +

  4. +
  5. +

    Otherwise, if one or more updates in the batch (WriteRequest.updates) +failed, set grpc::Status::code_ to UNKNOWN. For example, one update in +the batch may fail with RESOURCE_EXHAUSTED and another with +INVALID_ARGUMENT. A p4.Error message is used to capture the status of +each and every update in the batch. The number of p4.Error messages packed +into google.rpc.Status.details field should therefore always match the +number of updates in the WriteRequest, and the order of +p4.Error messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +p4.Error should set the code to OK and omit other fields. +

+ +
+
+
# Example of a grpc::Status returned for a Write RPC with a batch of 3 updates.
+# The first and third updates encountered an error, while the second update
+# succeeded.
+code_ = 2  # UNKNOWN
+error_message_ = "Write failure."
+binary_error_details {
+  code: 2  # UNKNOWN
+  message: "Write failure."
+  details {
+    canonical_code: 8  # RESOURCE_EXHAUSTED
+    message: "Table is full."
+    space: "targetX-psa-vendorY"
+    code: 500  # ERR_TABLE_FULL
+  }
+  details {
+    canonical_code: 0  # OK
+  }
+  details {
+    canonical_code: 6  # ALREADY_EXISTS
+    message: "Entity already exists."
+    space: "targetX-psa-vendorY"
+    code: 600  # ERR_ENTITY_ALREADY_EXISTS
+  }
+}

13. Read RPC

+

The Read RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as: +

+
+
+
message ReadRequest {
+  uint64 device_id = 1;
+  repeated Entity entities = 2;
+}
+

The device_id uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +NOT_FOUND error. The entities repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server. +

+

Since ReadRequests do not mutate any state on the switch, they do not +require an election_id, and they do not require the presence of an open +StreamChannel between the server and client. +

+

The Read response consists of a sequence of messages (a gRPC stream) with +each message defined as: +

+
+
+
message ReadResponse {
+  repeated Entity entities = 1;
+}
+

The entities repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the Finish() method on the stream object +[10]). +

13.1. Nomenclature

+
+
request
+
An element of the p4.ReadRequest.entities repeated field. +
+
batch
+
Refers to the p4.ReadRequest.entities repeated field.
+

Each request acts as a query filter for that entity type. If a request fully +specifies the entity key, the Read operation should retrieve a single P4 +entity. Please refer to the P4 Entity Messages section +for details on what parts of the entity specification make up the entity key. +

13.2. Wildcard Reads

+

P4Runtime allows wildcard read of P4 entities. A request may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the P4 Entity Messages section for details on +what parts of the entity can be wildcarded in a given request. +

+

For example, in a request of type CounterEntry: +

+
    +
  • A default counter_id (0) implies a request to read all counter-entries for +all indirect counters. +
  • +
  • A particular (non-default) counter_id in conjunction with index unset +implies a request to read all counter-entries for the given indirect counter +ID. +
+ +

To read the entire forwarding state for a given device, the P4Runtime client can +generate the following ReadRequest: +

+
+
+
device_id: <ID>
+entities {
+  extern_entry { }  # read all extern instances for all supported extern types
+  table_entry { }  # read all table entries for all tables
+  action_profile_member { }  # read all members for all action profiles
+  action_profile_group { }  # read all groups for all action profiles
+  ...
+}
+

The entity oneof field in the Entity message must always be set, or the +server must return an INVALID_ARGUMENT error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty Entity message in the ReadRequest. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the entity oneof [19]. +

13.3. Batch Processing

+

A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type request +appears only once in the batch. +

+

A P4Runtime server will process the batch as follows: +

+
    +
  1. +

    Lock state (preventing new writes) and validate each request in the batch: +

    +
      +
    1. +

      If it is a valid request, perform the read; +

      +
        +
      1. If the read was successful, return the entities read in +ReadResponse stream. +
      2. +
      3. If the read failed (exception / critical-error), prepare a p4.Error +with code set to INTERNAL. +
      +
    2. +
    3. +

      If the request is invalid (invalid-argument, not-supported, etc.), +prepare a p4.Error with relevant canonical code to capture the error. +

    +
  2. +
  3. +

    Unlock the state (allowing new writes); +

  4. +
  5. +

    Close the ReadResponse stream and return a grpc::Status as follows: +

    +
      +
    1. +

      If no errors were encountered, set code to OK and do not populate any +other field. +

    2. +
    3. +

      Otherwise, the overall code should be set to UNKNOWN. See section +Error Reporting Messages for information +on error reporting messages and guidelines. Assemble a list of p4.Error +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +google.rpc.Status.details field. This behavior also matches Write +RPC. +

    +
+

13.3.1. Example

+

If a client asked to read {a,b,c,d} and b and d requests didn't +validate, the server will return entities corresponding to a and c, followed +by a status {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} in the +details field. +

+

The P4Runtime server is not required to perform any optimization (e.g. merge two +requests in the batch if one is a subset of other). As a result of this, it +is possible for the ReadResponse to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging. +

+

There is no requirement that each request in the batch will correspond to one +ReadResponse message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit. +

+

A P4Runtime server must be prepared to handle multiple concurrent Read RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (e.g. in a single-threaded architecture), it may choose to serialize +Read RPC processing. +

13.4. Parallelism of Read and Write Requests

+

A P4Runtime server may be implemented to serve at most one +ReadRequest or WriteRequest message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so. +

+

For example, imagine a client that wanted to use WriteRequest +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +WriteRequest messages with only a few updates to an ActionSelector +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +WriteRequest batch currently being processed, but it will not +complete for a significant amount of time. +

+

The restrictions on which a client may rely are: +

+
    +
  • The processing of any two WriteRequest messages W1 and W2 must +result in the same state as if one of them was completed before the +other began. +
  • +
  • For any WriteRequest W and any ReadRequest R, R must +return results consistent with a state where W has completed +processing, or W has not yet begun processing. +
+ +

For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a WriteRequest message it acquired a write lock for each stateful +object affected by the WriteRequest, and before starting the +processing of a ReadRequest message it acquired a read lock for each +stateful object accessed by the ReadRequest, such an implementation +meets all of the requirements above. +

+

It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, e.g. if the server somehow determined that two +WriteRequest messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly. +

14. SetForwardingPipelineConfig RPC

+

A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the SetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message SetForwardingPipelineConfigRequest {
+  enum Action {
+    UNSPECIFIED = 0;
+    VERIFY = 1;
+    VERIFY_AND_SAVE = 2;
+    VERIFY_AND_COMMIT = 3;
+    COMMIT = 4;
+    RECONCILE_AND_COMMIT = 5;
+  }
+  uint64 device_id = 1;
+  uint64 role_id = 2;
+  Uint128 election_id = 3;
+  Action action = 4;
+  ForwardingPipelineConfig config = 5;
+}
+

The server is expected to perform the following checks (in this order) +before performing the required action: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role_id does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the master for (device_id, role_id) according to the +election_id value, the server must return a PERMISSION_DENIED error. +

+ +

The action is the type of configuration action requested, it can be one of: +

+
    +
  • +

    VERIFY: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an INVALID_ARGUMENT +error if config is not provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_SAVE: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent Read / Write requests must refer to fields in the new +config. Returns an INVALID_ARGUMENT error if the forwarding config is not +provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_COMMIT: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an INVALID_ARGUMENT error if the forwarding config is not provided of if the +provided config cannot be realized. +

  • +
  • +

    COMMIT: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a NOT_FOUND error if no saved config +is found, i.e. if no VERIFY_AND_SAVE action preceded this one. Returns an +INVALID_ARGUMENT error if a config is provided with this message. +

  • +
  • +

    RECONCILE_AND_COMMIT: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an UNIMPLEMENTED error. For targets that support this option, an +INVALID_ARGUMENT error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target. +

+ +

The config field is a message of type ForwardingPipelineConfig that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(e.g. generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the Forwarding-Pipeline +Configuration section for details. +

+

A P4Runtime server running on a non-programmable device may not +support SetForwardingPipelineConfig (e.g. the forwarding-pipeline +config is part of the device's software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +UNIMPLEMENTED error. +

15. GetForwardingPipelineConfig RPC

+

The forwarding-pipeline configuration of the target can be retrieved by invoking +the GetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message GetForwardingPipelineConfigRequest {
+  enum ResponseType {
+    ALL = 0;
+    COOKIE_ONLY = 1;
+    P4INFO_AND_COOKIE = 2;
+    DEVICE_CONFIG_AND_COOKIE = 3;
+  }
+  uint64 device_id = 1;
+  ResponseType response_type = 2;
+}
+

The device_id uniquely identifies the target P4 device. A NOT_FOUND error is +returned if the device_id is not recognized by the P4Runtime server. +

+

The response_type is used to specify which fields to populate in the response, +its value can be one of: +

+
    +
  • +

    ALL: returns a ForwardingPipelineConfig with all fields +set as stored by the target. This is the default behaviour if the +response_type field is not set. +

  • +
  • +

    COOKIE_ONLY: reply by setting only the cookie field in the +ForwardingPipelineConfig, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message. +

  • +
  • +

    P4INFO_AND_COOKIE: reply by setting the p4info and cookie fields. +

  • +
  • +

    DEVICE_CONFIG_AND_COOKIE: reply by setting the p4_device_config and +cookie fields. +

+ +

The response contains the ForwardingPipelineConfig for the specified device: +

+
+
+
message GetForwardingPipelineConfigResponse {
+  ForwardingPipelineConfig config = 1;
+}
+

If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level config field will be unset in the response. Examples are +(i) a server that only allows configuration via SetForwardingPipelineConfig +but this RPC hasn't been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn't yet occurred. +

+

Once a forwarding-pipeline config is installed on the device (either via +SetForwardingPipelineConfig or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +config.p4_device_config will be empty / unset in the response, even if +response_type in the request was set to ALL. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the SetForwardingPipelineConfig RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +SetForwardingPipelineConfig, the value of config.cookie will be unset. +

+

If a P4Runtime server supports both SetForwardingPipelineConfig as well as +returning the p4_device_config, there should be read-write symmetry between +SetForwardingPipelineConfig and GetForwardingPipelineConfig RPCs. +

16. P4Runtime Stream Messages

16.1. Packet I/O

+

P4Runtime supports controller packet-in and packet-out by means of PacketIn +and PacketOut stream messages, respectively. +

+

PacketIn messages are sent by the P4Runtime server to the client. Conversely, +PacketOut messages are sent by the client to the server. Any PacketOut +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a StreamMessageResponse message with the error field set to +report the error to the client. See the section on Stream Error +Reporting for more information on error. +

+

As introduced in the ControllerPacketMetadata +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with @controller_header. The expected metadata is described +in the P4Info using the ControllerPacketMetadata messages. +

+

Both PacketIn and PacketOut stream messages share the same fields and are +defined as follows: +

+
+
+
// Packet sent from the controller to the switch.
+message PacketOut {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+// Packet sent from the switch to the controller.
+message PacketIn {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+message PacketMetadata {
+  // This refers to Metadata.id coming from P4Info ControllerPacketMetadata.
+  uint32 metadata_id = 1;
+  bytes value = 2;
+}
+
    +
  • +

    payload is used to carry the full packet content, including the headers. +

  • +
  • +

    metadata is a repeated field of PacketMetadata messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +ControllerPacketMetadata. Indeed, when a P4Runtime client (or server) +generates a PacketOut (or PacketIn) message, it needs to populate the +metadata field with as many values as in ControllerPacketMetadata.metadata +for the packet-out (or packet-in) case. Each PacketMetadata.value is a +binary string and must conform to the Bytestrings +requirements based on the corresponding P4Info +ControllerPacketMetadata.metadata specification. If the metadata field +does not match the P4Info specification, the server must drop the PacketOut +message and may generate a StreamMessageResponse message with the error +field set to report the error to the client which issued the PacketOut. See +the section on Stream Error Reporting for more +information on error. +

+

16.2. Master Arbitration Update

+

P4Runtime's master arbitration mechanism ensures that only the current master +can modify state on the switch, and that the election_id is monotonically +increasing. For example, the switch must finish all previous write operations +before changing masters, and must only accept write requests from the current +master. +

+

As explained earlier in this document, the controller uses the StreamChannel +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via Write RPC), +it needs to start a controller session and become a “master”. To do so, the +controller first opens a bidirectional stream channel to the server via +StreamChannel for each device and sends a StreamMessageRequest message. The +controller populates the MasterArbitrationUpdate field in this message using +its role_id and election_id and the device_id of the device, as explained +in detail in the Master-Slave Arbitration and Controller +Replication +section. For any given (device_id, role_id), the P4Runtime server keeps track +of the highest election_id that it has ever received. If a controller's +election_id is equal to the highest election_id that the server has ever +received, that controller is the master. All other controllers are slaves. Note +that it is possible that all controllers are slaves, and that there is no +master. There can be at most one master, because for any given +(device_id, role_id), each connected controller has a unique election_id. +

+

This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest election_id after such a restart. +However, across a full restart, the election_id must be +reset. In fact, a full restart is the only way to reset the election_id. +

+

The MasterArbitrationUpdate message is defined as follows: +

+
+
+
message Role {
+  // role_id for this role. Defined offline in agreement across the
+  // entire control plane.
+  uint64 id = 1;
+  // Describes the role configuration.
+  google.protobuf.Any config = 2;
+}
+
+message MasterArbitrationUpdate {
+  // Identifies the device (aka target or node or switching chip).
+  uint64 device_id = 1;
+  // The role for which the mastership is being arbitrated.
+  Role role = 2;
+  // The election_id (unique per role).
+  Uint128 election_id = 3;
+  // Switch populates this with OK for the client that is the master,
+  // and with an error status for all other connected clients (at
+  // every mastership change). The controller does not populate this
+  // field.
+  google.rpc.Status status = 4;
+}
+

Note that the status field in the MasterArbitrationUpdate message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a StreamMessageResponse message back to the controller, in which +it populates the MasterArbitrationUpdate message using the device_id, +role, and election_id it previously received from the controller. The server +also populates the status field in the MasterArbitrationUpdate according to +the rules in an earlier section. +

+

The sender need not specify an election_id. If the election_id is not +specified, the sender's election_id is considered lower than any +election_id, and the sender will thus never become master. This way, a +controller can choose to be a standby controller, in order to avoid master +“flapping” (if a standby controller connects to the switch shortly before the +actual master controller, therefore becoming master temporarily). +

16.3. Digest Messages

+

See the DigestEntry section. +

16.4. Table Idle Timeout Notification

+

When a table supports idle timeout (as per the P4Info message), the master +client can specify a TTL value for each entry in the table (see +Idle-timeout section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an IdleTimeoutNotification message on the +StreamChannel bidirectional stream to the master client. The master client can +then take the action of its choice, most likely remove the idle entry. +

+

The IdleTimeoutNotification Protobuf message has the following fields: +

+
    +
  • +

    timestamp: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server's local clock. +

  • +
  • +

    table_entry: a repeated field of entries which have expired. Each individual +entry is identified by a single TableEntry message. For each TableEntry, +the key fields (table_id, match and priority) must be set, along with +the controller_metadata field and the idle_timeout_ns field. Other fields +may be set by the server but should be ignored by the client. +

+ +

Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +IdleTimeoutNotification message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an IdleTimeoutNotification +message with an empty table_entry repeated field. +

+

After generating an idle notification, the P4Runtime server must “reset” the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the master client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle. +

+

Here is a reasonable pseudo-code implementation for idle timeout for table +entries: +

+
+
+
IdleTimeoutStream stream;
+
+scanning_interval = 10ms;
+
+while (true) {
+  // iterate over all tables which support idle timeout
+  for (table in tables) {
+    if (!table.idle_timeout_supported) continue;
+    // we coalesce all idle notifications for the same table in one
+    // message
+    IdleTimeoutNotification msg;
+    // read time_since_last_hit from device
+    entries = device.load_table_entries_from_hw(table);
+    for (entry in entries) {
+      if (entry.idle_timeout == 0) continue;  // no TTL
+      if (entry.time_since_last_hit < entry.idle_timeout) continue;
+      msg.table_entry_add(entry);
+      entry.reset_time_since_last_hit();
+    }
+    if (msg.table_entry_size() == 0) continue;  // no notifications
+    msg.set_timestamp(now());
+    stream.write(msg);
+  }
+  sleep(scanning_interval);
+}

16.5. Architecture-Specific Notifications

+

P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on StreamChannel, by including an Any Protobuf field [30] +named other in both StreamMessageRequest and StreamMessageResponse. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the PSA Digest +extern. See section on Extending P4Runtime for non-PSA +Architectures for more information. +

16.6. Stream Error Reporting

+

The P4Runtime server can asynchronously report errors which occur when +processing StreamMessageRequest messages, using the error message field (of +type StreamError) in StreamMessageResponse. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature. +

+

The StreamError message has the following fields: +

+
    +
  • canonical_code, which must be set to the appropriate canonical error code +[33]. +
  • +
  • message, an optional developer-facing error message describing the error. +
  • +
  • space and code, which are optional and can be used by vendors to provide +additional details on the error. code is a numeric error code drawn from a +vendor's chosen error space. +
  • +
  • details, which is a Protobuf oneof used to help the client identify which +StreamMessageRequest triggered the error. The server is required to set the +appropriate field in the oneof so that the client can identify which type +of stream message is responsible for the error (packet_out, +digest_list_ack or other), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid PacketOut message from the +client, the packet_out field (of type PacketOutError) should be set in +the details oneof, and the server may additionally set the packet_out +field in the PacketOutError sub-message (by copying it from the invalid +PacketOut message received on the stream channel) so that the client can +know exactly what packet-out triggered the error. +
+ +

The appropriate canonical error code [33] should be used when +populating the canonical_code field. For example: +

+
    +
  • if a controller is not allowed to send a PacketOut message under its +current role definition, the code should be set to PERMISSION_DENIED. +
  • +
  • if the metadata repeated field in PacketOut does not match the P4Info +definition, the code should be set to INVALID_ARGUMENT. It may be useful +for the server to set the packet_out field in this case, so that the client +can find out which set of metadata fields triggered the error. +
  • +
  • if the digest_id field in DigestListAck does not match any Digest entry +in P4Info, the code should be set to INVALID_ARGUMENT. +
+ +

The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, e.g. because of a +burst of PacketIn messages. +

+

Note that master-arbitration errors are never reported using the StreamError +message. Invalid MasterArbitrationUpdate messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section 5.3. +

16.6.1. Examples of StreamError Messages

+
    +
  • +

    Malformed packet-out metadata. If the server receives a PacketOut +message with a metadata field with id 7 which is not included in the P4Info +ControllerPacketMetadata message for “packet_out”, the server may send the +following StreamMessageResponse back to the client: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Unknown metadata field id 7."
    + packet_out {
    +   # copied from the PacketOut message received from the client
    +   packet_out {
    +     payload: ...
    +     metadata {
    +       id: 7
    +       name: "I_should_not_be_here"
    +       bitwidth: 32
    +     }
    +     # more metadata
    +   }
    + }
    +}
  • +
  • +

    Packet-out which exceeds the MTU. If the server receives a PacketOut +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following StreamMessageResponse: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Packet exceeds the MTU for port."
    + space: "targetX-psa-vendor1"
    + code: 123  # MTU_EXCEEDED
    + packet_out {
    +   # we do not set the packet_out field as it does not provide any
    +   # extra information to the client
    + }
    +}
+

17. Capabilities RPC

+

The Capabilities RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the CapabilitiesRequest message is empty and the CapabilitiesResponse +message only includes the p4runtime_api_version string field. This field must +be set to the full semantic version string [26] corresponding to the +version of the P4Runtime API implemented by the server, e.g. “1.1.0-rc.1”. +

+

Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three atomicity +modes for WriteRequest batches, two of them being +optional. In the future we may decide to leverage the CapabilitiesResponse +message to enable the server to report to the client which subset of these +atomicity modes is supported. +

+

The semantic version string included in CapabilitiesResponse can be used by +the client to determine which exact feature set is implemented by the server, +since minor releases may introduce new +functionality. However, because the Capabilities RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (i.e. an UNIMPLEMENTED error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0). +

18. Portability Considerations

18.1. PSA Metadata Translation

+

The Portable Switch Architecture (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +[23]. For such metadata, a translation between the controller's +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. +

+
+

psa-metadata-translation +

+
+ +
Figure 8. P4Runtime Metadata Translation for the Portable Switch Architecture
+

Figure 8 illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller's 32 bit port +numbers to a target's 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch. +

18.1.1. Translation of Port Numbers

+

In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller's space and the PSA device's space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +user-defined P4 types, namely PortId_t and +PortIdInHeader_t, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in psa.p4 for +the PSA device in Switch 1. +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type PortId_t bit<9>;
+@p4runtime_translation("p4.org/psa/v1/PortIdInHeader_t", 32)
+type PortIdInHeader_t bit<32>;
+

The first argument to the @p4runtime_translation annotation is a URI that +indicates to the P4Runtime server which numerical mapping provided by the +out-of-band switch configuration mechanism to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports). +

+

An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows: +

+
+
+
enum SdnPort {
+  SDN_PORT_UNSPECIFIED = 0;
+
+  // SDN ports are numbered starting form 1.
+  SDN_PORT_MIN = 1;
+
+  // The maximum value of an SDN port (physical or logical).
+  SDN_PORT_MAX = 0xfffffeff;
+
+  // Reserved SDN port numbers (0xfffffff0 - 0xffffffff)
+
+  SDN_PORT_RECIRCULATE = 0xfffffffa;
+  SDN_PORT_CPU = 0xfffffffd;
+}
+

The switch config will map SDN_PORT_RECIRCULATE and SDN_PORT_CPU as well +as any SDN port number corresponding to a “regular” front-panel port to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation. +

+

The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs. +

18.1.2. Translation of Packet-IO Header Fields

+

Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  PortIdInHeader_t egress_port;
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  PortIdInHeader_t ingress_port;
+}
+

The header-level annotation @controller_header is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (egress_port) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI first argument to the @p4runtime_translation +annotation). Any subsequent reference to the egress_port field in the +data plane will use the translated value. PortIdInHeader_t is used in the +header definition instead of PortId_t to guarantee byte-aligned headers in +case this is required by the target. +

+

A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target's PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the ingress_port field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller. +

18.1.3. Translation of Match Fields

+

Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table's match key as shown in the example below: +

+
+
+
table t {
+  key = {
+    istd.ingress_port: exact;  // PSA standard metadata ingress port
+  }
+  actions = {
+    drop;
+  }
+}
+

Table t has an exact match on PSA standard metadata ingress port +(istd.ingress_port). Since the field is of type PortId_t, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in t from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table t is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values. +

+

Note that it may be infeasible to translate the value-mask pair for ternary +matches: LPM, TERNARY or RANGE match kinds. The P4Runtime server may +require that for these match kinds the port match be either de facto “exact” +(0xffffffff mask for TERNARY, prefix-length of 32 for LPM, or same low and +high bounds for RANGE) or “don't care”. +

18.1.4. Translation of Action Parameters

+

PortId_t type parameters can be part of a P4 action definition as shown in the +example below: +

+
+
+
action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+}
+
+table t {
+  key = {
+    hdr.h.f: exact;
+  }
+  actions = {
+    a;
+  }
+}
+

The controller may write entries in table t with action a to set the egress +port as shown in the P4 code above. The action parameter p is of type +PortId_t, which leads to a 32-bit bitwidth for p being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device. +

18.1.5. Port Translation for PSA Extern APIs

+

The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch field is +of type uint32 to carry the 32-bit SDN representation of the port being +watched. The P4Runtime server will translate the given watch port number into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device. +

+

The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type uint32 to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane. +

18.1.6. Using Port as an Index to a Register, Indirect Counter or Indirect Meter

+

P4Runtime supports using a translated value (PortId_t or any other translated +type for which the underlying built-in type is bit<W>) as an index to a +register, indirect counter, or indirect meter. +

+
+
+
Counter<bit<32> /* counter entry type */, PortId_t /* index type */>(
+  32w1024, PSA_CounterType_t.PACKETS) counter;
+action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+  counter.count(p);
+}
+

This P4 Counter declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
counters {
+  preamble {
+    id: 0x12000001
+    name: "counter"
+  }
+  spec {
+    unit: PACKETS
+  }
+  index_type_name {
+    name: "PortId_t"
+  }
+}
+

The controller may read and write counter values from indexed counter counter +using SDN port numbers as indices, and not device-specific port numbers. The +index_type_name field in the P4Info message is a signal to the P4Runtime +server that translation is required. +

19. P4Runtime Versioning

+

P4Runtime follows the Google guidelines for versioning cloud APIs +[6]. We use a MAJOR.MINOR.PATCH style version number scheme and +we increment the: +

+
    +
  • MAJOR version when we make incompatible API changes, +
  • +
  • MINOR version when we add functionality in a backwards-compatible manner, +
  • +
  • PATCH version when we make backwards-compatible bug fixes. +
+ +

The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is p4.v1 and the package +name for P4Info is p4.config.v1. Even though p4 and p4.config are two +different Protobuf packages, p4 depends on p4.config and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence. +

+

As recommended in [6], we may consider using pre-GA release +suffixes (such as alpha or beta) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1). +

+

Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner. [7] describes +what constitute a backwards-compatible change. We expect MAJOR version bumps +to be a rare event. +

+

Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor + patch version numbers in future releases. +

+

All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository [14] and the version label follows +semantic versioning rules [26]. +

20. Extending P4Runtime for non-PSA Architectures

+

P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place. +

+

When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names: +

+
    +
  • p4/[organization]/arch/config/<major version>/p4info.proto +
  • +
  • p4/[organization]/arch/<major version>/p4runtime.proto +
+ +

We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they “extend”. +

+

For the remainder of this section, we will refer to these two files as +p4info-ext and p4runtime-ext respectively. +

20.1. Extending P4Runtime for Architecture-Specific Externs

+

Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both p4info-ext and +p4runtime-ext. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example: +

+
+
+
// T must be a bit<W> type, it indicates the width of each counter cell
+extern MyNewPacketCounter<T> {
+  counter(bit<32> size);
+  increment(in bit<32> index);
+}

20.1.1. Extending the P4Info message

+
    +
  • Id prefixes 0x81 through 0xfe are reserved for architecture-specific +externs. It is recommended that p4info-ext include a P4Ids message based +on the one in p4info.proto that the P4 compiler can refer to when assigning +IDs to each extern instance. +
+ +
+
+
message P4Ids {
+  enum Prefix {
+    UNSPECIFIED = 0;
+    MY_NEW_PACKET_COUNTER = 0x81;
+  }
+}
+
    +
  • p4info-ext should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +p4.config.v1.ExternInstance message as the info +field, which is of type Any [30]. +
+ +
+
+
message MyNewPacketCounter {
+  // corresponds to the T type parameter in the P4 extern definition
+  p4.config.v1.P4DataTypeSpec type_spec = 1;
+  // constructor argument
+  int64 size = 2;
+}

20.1.2. Extending the P4Runtime Service

+

Just like p4info-ext, p4runtime-ext should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an ExternEntry message generated by the +P4Runtime client. +

+

Here is a possible Protobuf message for our MyNewPacketCounter P4 extern: +

+
+
+
// This message enables reading / writing data to the counter at the provided
+// index
+message MyNewPacketCounter {
+  int64 index = 1;
+  p4.v1.P4Data data = 2;
+}
+

P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an Any Protobuf field [30] named other +in both p4.v1.StreamMessageRequest and +p4.v1.StreamMessageResponse. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in p4runtime-ext and embed instances of these messages in +p4.v1.StreamMessageRequest and p4.v1.StreamMessageResponse as appropriate. +

20.2. Architecture-Specific Table Extensions

20.2.1. New Match Types

+

An architecture may introduce new table match types [12]. P4Runtime +accounts for this by providing the following hooks: +

+
    +
  • +

    The match field in p4.config.v1.MatchField (p4info.proto) is a oneof +which can be either one of the default match types (EXACT, LPM, TERNARY +or RANGE) or an architecture-specific match type encoded as a string. +

  • +
  • +

    The field_match_type field in p4.v1.FieldMatch (p4runtime.proto) is a +oneof which includes an Any Protobuf message [30] field +(other). p4info-ext should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in p4.v1.FieldMatch as the +other field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info. +

+

20.2.2. New Table Properties

+

An architecture may introduce additional table properties +[29]. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +p4.config.v1.Table message includes the other_properties Any Protobuf +field [30]. At the moment, there is not any mechanism to extend the +p4.v1.TableEntry message based on the value of architecture-specific table +properties, but we may include on in future versions of the API. +

21. Known Limitations of Current P4Runtime Version

+
    +
  • +

    FieldMatch, action Param, and controller packet metadata fields only +support unsigned bitstrings, i.e. values of one of the following types (not +the more general P4Data): +

    +
      +
    • bit<W> +
    • +
    • bool. Note that as far as the P4Info message contents and +thus controller software is concerned, such fields of type bool +will be indistinguishable from those that have been declared with +type bit<1>. P4Runtime server software will automatically +perform any conversion needed between the type bit<1> values in +P4Runtime messages and the data plane representation. +
    • +
    • an enum with underlying type bit<W> +
    • +
    • a type or typedef with an underlying type that is one of the above (or +in general a “chain” of type and/or typedef that eventually ends with +one of the types above) +
    +
  • +
  • +

    Support for PSA Random & Timestamp externs is postponed to a future minor +version update. +

  • +
  • +

    P4Info does not include information about which of a table's actions execute +which direct resource(s). +

  • +
  • +

    The default action for indirect match tables is restricted to a const +NoAction known at compile-time. +

  • +
  • +

    There is no mechanism for changing the value of the psa_empty_group_action +table property at runtime. +

  • +
  • +

    There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor + +patch version numbers. +

+

22. Security concerns for P4Runtime

+

Appropriate measures and security best practices need to be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. +

A. Appendix

A.1. Revision History

A.1.1. Changes in v1.1.0

+
    +
  • Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously. +
  • +
  • Add error field to stream messages sent by the server. +
  • +
  • Add Capabilities RPC to query the P4Runtime API version implemented by the +server. +
  • +
  • Support wildcard reads for multicast groups and clone sessions. +
  • +
  • Support for modifying direct resources of const tables. +
  • +
  • Support P4 user-defined types for Packet IO metadata fields. +
  • +
  • Clarify consistency requirements for Write and Read RPCs. +
  • +
  • Add Appendix providing implementation advice for avoiding common pitfalls: + +
      +
    • advice on setting gRPC Metadata Maximum Size +
    • +
    • advice on setting gRPC Server Maximum Receive Message Size +
  • +
  • Clarify limitations on supported types for FieldMatch, action Param, and +Packet IO metadata fields. +
  • +
  • Clarify that reading entire forwarding state with empty entity is not +supported. +
  • +
  • Document that @p4runtime_translation need only be supported when applied to +type declarations in P4. +
+

A.2. P4 Annotations

+

Table 7 lists P416 annotations introduced primarily for +the purpose of adding features for the P4Runtime API. +

+
+ + + + + + + + + + +
Annotation Description
@brief See section 6.1.3
@controller_header See section 6.4.6
@description See section 6.1.3
@id See section 6.3
@max_group_size See sections 6.4.3, 9.2.2
@pkginfo See section 6.2.1
@p4runtime_translation See sections 8.5.6, 18.1.1
+
+ +
Table 7. P4 annotations introduced by P4Runtime

A.3. A More Complex Value Set Example

+

This section includes a more complex Value Set example, with multiple matches of +different kinds. +

+
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+

This P4 Value Set declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

A P4Runtime client can set the membership for this Value Set with WriteRequest +messages similar to this one: +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xac }
+      }
+      # match for field_id 2 is missing => don't care match
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xdc }
+      }
+      match {
+        field_id: 2
+        ternary { value: 0x88 mask: 8f }
+      }
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+  }
+}

A.4. Guidelines for Implementations

+

This section contains practical advice for implementing P4Runtime clients and +servers. +

A.4.1. gRPC Metadata Maximum Size

+

In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the grpc.max_metadata_size gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the Write P4Runtime RPC. The Write RPC +returns an individual error for every item in a batch (see Section +12), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +RESOURCE_EXHAUSTED error, without any of the individual errors. +

+

To fix this problem, one can set the grpc.max_metadata_size option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it's +limit, as only the receiving side's limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every p4.Error, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +8192 + MAX_UPDATES_PER_WRITE * 100 bytes of metadata. +

+

For example, in C++, one can create a client channel as follows: +

+
+
+
const int MAX_UPDATES_PER_WRITE = 100;
+::grpc::ChannelArguments arguments;
+arguments.SetInt(GRPC_ARG_MAX_METADATA_SIZE, 8192 + MAX_UPDATES_PER_WRITE*100);
+return grpc::CreateCustomChannel(address, credentials, arguments);

A.4.2. gRPC Server Maximum Receive Message Size

+

At the time of writing, the default maximum receive message size in gRPC is 4MB + while the default maximum send message size is unlimited. This can be a +problem for the SetForwardingPipelineConfig RPC, since for some targets the +binary p4_device_config can exceed 4MB, in which case by default the P4Runtime +server would return an INVALID_ARGUMENT error. To a lesser extent, this may +affect the Write RPC as well, in case of extremely large batches. +

+

To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of p4_device_config for their target(s). This can be done by +setting the grpc.max_receive_message_length when building the gRPC server. +

+

For example, in C++, one can set the maximum receive message size as follows: +

+
+
+
const int MAX_RECEIVE_MESSAGE_SIZE = 128 * 1024 * 1024;  // 128MB
+::grpc::ServerBuilder server_builder;
+builder.AddListeningPort(/*...*/);
+builder.RegisterService(/*...*/);  // register P4Runtime service
+builder.SetMaxReceiveMessageSize(MAX_RECEIVE_MESSAGE_SIZE);
+builder.BuildAndStart();
+

On the client side, we recommend that P4Runtime clients do not use Write +batches larger than the default maximum receive message size (4MB) in case +the server did not deem necessary to increase the default value , unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB). +

+

References

+
+ +
[2]“A Two Rate Three Color Marker.” https://​tools.​ietf.​org/​html/​rfc2698.
+ + + + +
[7]“Google Cloud APIs Versioning - Backwards-Compatibility.” https://​cloud.​google.​com/​apis/​design/​versioning#​backwards_​compatibility.
+ +
[9]“gRPC Main Site.” https://​grpc.​io.
+ + + + +
[14]“p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” https://​github.​com/​p4lang/​p4runtime.
+
[15]“p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.” https://​github.​com/​p4lang/​PI.
+ + +
[18]“Portable Switch Architecture Specification (v1.1.0).” https://​p4.​org/​p4-​spec/​docs/​PSA-​v1.​1.​0.​html.
+ + + + + + + +
[26]“Semantic Versioning.” https://​semver.​org/​.
+ + + + + + + +
[34]“The OpenConfig Project.” http://​openconfig.​net.
+ +
[36]“The Stratum Project.” https://​stratumproject.​org/​.
+
+
+
+ +
+

1.an enum type used as a field in a header must specify a +underlying type and representation for enum elements. +

+ + + diff --git a/spec/v1.1.0-rc.1/P4Runtime-Spec.log b/spec/v1.1.0-rc.1/P4Runtime-Spec.log new file mode 100644 index 00000000..eca801d1 --- /dev/null +++ b/spec/v1.1.0-rc.1/P4Runtime-Spec.log @@ -0,0 +1,13974 @@ +This is XeTeX, Version 3.14159265-2.6-0.99992 (TeX Live 2015/Debian) (preloaded format=xelatex 2018.8.17) 12 DEC 2019 05:26 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**build/P4Runtime-Spec.tex +(./build/P4Runtime-Spec.tex +LaTeX2e <2016/02/01> +Babel <3.9q> and hyphenation patterns for 81 language(s) loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2014/09/29 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo +File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@section=\count80 +\c@subsection=\count81 +\c@subsubsection=\count82 +\c@paragraph=\count83 +\c@subparagraph=\count84 +\c@figure=\count85 +\c@table=\count86 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) (build/madoko2.sty (/usr/share/texlive/texmf-dist/tex/latex/colortbl/colortbl.sty +Package: colortbl 2012/02/13 v1.0a Color table columns (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty +Package: array 2014/10/28 v2.4c Tabular extension package (FMi) +\col@sep=\dimen103 +\extrarowheight=\dimen104 +\NC@list=\toks14 +\extratabsurround=\skip43 +\backup@length=\skip44 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty +Package: color 2016/01/03 v1.1b Standard LaTeX Color (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package color Info: Driver file: xetex.def on input line 143. +(/usr/share/texlive/texmf-dist/tex/xelatex/xetex-def/xetex.def +File: xetex.def 2015/09/11 v4.06 LaTeX color/graphics driver for XeTeX (TeX Live/RRM/JK) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +))) +\everycr=\toks15 +\minrowclearance=\skip45 +) (/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: xetex.def on input line 225. +LaTeX Info: Redefining \color on input line 702. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) (build/options.sty +Package: options 2015/03/01, Daan Leijen, Provides convenient path-value (or key-value) options +(/usr/share/texlive/texmf-dist/tex/latex/etoolbox/etoolbox.sty +Package: etoolbox 2015/08/02 v2.2a e-TeX tools for LaTeX (JAW) +\etb@tempcnta=\count87 +) +\opt@nesting=\count88 +\opt@idx=\count89 +\opt@choiceord=\count90 +) (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty +Package: iftex 2013/04/04 v0.2 Provides if(tex) conditional for PDFTeX, XeTeX, and LuaTeX +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2014/10/28 v1.0g Enhanced LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks16 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2016/01/03 v1.0q Standard LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2016/01/03 v1.10 sin cos tan (DPC) +) (/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg +File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live +) +Package graphics Info: Driver file: xetex.def on input line 95. +) +\Gin@req@height=\dimen105 +\Gin@req@width=\dimen106 +) (build/longfbox.sty +Package: longfbox 2015/12/01, Daan Leijen, Provides long fbox that can break over pages +(build/longbox.sty +Package: longbox 2015/12/01, Daan Leijen, Provides basic longbox that can break over pages +(/usr/share/texlive/texmf-dist/tex/latex/mdwtools/footnote.sty +Package: footnote 1997/01/28 1.13 Save footnotes around boxes +\fn@notes=\box26 +\fn@width=\dimen107 +) +\lb@prevdepth=\skip46 +\lb@freevspace=\skip47 +\lb@headbox=\box27 +\lb@savebox=\box28 +\lb@mainbox=\box29 +\lb@usevbox=\count91 +\lb@width=\skip48 +\lb@height=\skip49 +\lb@skiptop=\skip50 +\lb@skipright=\skip51 +\lb@skipbottom=\skip52 +\lb@skipleft=\skip53 +\lb@skipbreaktop=\skip54 +\lb@skipbreakbottom=\skip55 +\lb@outerwidth=\skip56 +\lb@extrasplit=\skip57 +\lb@textalign=\count92 +\lb@baseline=\count93 +\lb@neededvspace=\skip58 +\lb@splitheight=\skip59 +\lb@insurance=\skip60 +\/longbox/@part-height=\skip61 +\/longbox/@part-width=\skip62 +\/longbox/@part-depth=\skip63 +\/longbox/@content-box-height=\skip64 +\/longbox/@content-box-width=\skip65 +\/longbox/@content-box-depth=\skip66 +\/longbox/@breakat-previous=\skip67 +\/longbox/@lower=\skip68 +\/longbox/split-minimum=\skip69 +\/longbox/split-badness=\skip70 +\/longbox/raise=\skip71 +\/longbox/height=\skip72 +\/longbox/width=\skip73 +\/longbox/outer-height=\skip74 +\/longbox/outer-width=\skip75 +\/longbox/skip-top=\skip76 +\/longbox/skip-right=\skip77 +\/longbox/skip-bottom=\skip78 +\/longbox/skip-left=\skip79 +\/longbox/skip-break-bottom=\skip80 +\/longbox/skip-break-top=\skip81 +) (/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.sty +Package: pict2e 2016/02/05 v0.3b Improved picture commands (HjG,RN,JT) +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.cfg +File: pict2e.cfg 2016/02/05 v0.1u pict2e configuration for teTeX/TeXLive +) +Package pict2e Info: Driver file: xetex.def on input line 119. +Package pict2e Info: Driver file for pict2e: p2e-xetex.def on input line 121. +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/p2e-xetex.def +File: p2e-xetex.def 2016/02/05 v0.1u Driver-dependant file (RN,HjG,JT) +) +\pIIe@GRAPH=\toks17 +\@arclen=\dimen108 +\@arcrad=\dimen109 +\@tempdimd=\dimen110 +) (build/ellipse.sty +Package: ellipse 2004/11/05 v1.0 .dtx ellipse file +) +\fbox@oct=\count94 +\fbox@quad=\count95 +\fbox@diaq=\count96 +\fbox@sign=\count97 +\fbox@anglestart=\skip82 +\fbox@angleend=\skip83 +\fbox@dash=\skip84 +\fbox@dashskip=\skip85 +\fbox@anglecur=\skip86 +\fbox@dashangle=\skip87 +\fbox@dashskipangle=\skip88 +\fbox@delta=\skip89 +\fbox@from=\skip90 +\fbox@to=\skip91 +\/fbox/padding-top=\skip92 +\/fbox/padding-right=\skip93 +\/fbox/padding-bottom=\skip94 +\/fbox/padding-left=\skip95 +\/fbox/padding-break-top=\skip96 +\/fbox/padding-break-bottom=\skip97 +\/fbox/margin-top=\skip98 +\/fbox/margin-right=\skip99 +\/fbox/margin-bottom=\skip100 +\/fbox/margin-left=\skip101 +\/fbox/margin-break-top=\skip102 +\/fbox/margin-break-bottom=\skip103 +\/fbox/border-top-width=\skip104 +\/fbox/border-right-width=\skip105 +\/fbox/border-bottom-width=\skip106 +\/fbox/border-left-width=\skip107 +\/fbox/border-break-top-width=\skip108 +\/fbox/border-break-bottom-width=\skip109 +\/fbox/@lower=\skip110 +\/fbox/@padding-box-height=\skip111 +\/fbox/@padding-box-depth=\skip112 +\/fbox/@padding-box-width=\skip113 +\/fbox/@border-box-width=\skip114 +\/fbox/@border-box-height=\skip115 +\/fbox/@border-box-depth=\skip116 +\/fbox/@border-top-left-radius-x=\skip117 +\/fbox/@border-top-right-radius-x=\skip118 +\/fbox/@border-bottom-left-radius-x=\skip119 +\/fbox/@border-bottom-right-radius-x=\skip120 +\/fbox/@border-top-left-radius-y=\skip121 +\/fbox/@border-top-right-radius-y=\skip122 +\/fbox/@border-bottom-left-radius-y=\skip123 +\/fbox/@border-bottom-right-radius-y=\skip124 +\/fbox/@border-top-left-ix=\skip125 +\/fbox/@border-top-left-iy=\skip126 +\/fbox/@border-top-right-ix=\skip127 +\/fbox/@border-top-right-iy=\skip128 +\/fbox/@border-bottom-left-ix=\skip129 +\/fbox/@border-bottom-left-iy=\skip130 +\/fbox/@border-bottom-right-ix=\skip131 +\/fbox/@border-bottom-right-iy=\skip132 +\/fbox/@border-top-left-phi=\skip133 +\/fbox/@border-top-right-phi=\skip134 +\/fbox/@border-bottom-left-phi=\skip135 +\/fbox/@border-bottom-right-phi=\skip136 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2016/03/03 v2.15a AMS math features +\@mathmargin=\skip137 +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2000/06/29 v2.01 AMS text +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen111 +)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen112 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 1999/12/14 v2.01 operator names +) +\inf@bad=\count98 +LaTeX Info: Redefining \frac on input line 199. +\uproot@=\count99 +\leftroot@=\count100 +LaTeX Info: Redefining \overline on input line 297. +\classnum@=\count101 +\DOTSCASE@=\count102 +LaTeX Info: Redefining \ldots on input line 394. +LaTeX Info: Redefining \dots on input line 397. +LaTeX Info: Redefining \cdots on input line 518. +\Mathstrutbox@=\box30 +\strutbox@=\box31 +\big@size=\dimen113 +LaTeX Font Info: Redeclaring font encoding OML on input line 630. +LaTeX Font Info: Redeclaring font encoding OMS on input line 631. +\macc@depth=\count103 +\c@MaxMatrixCols=\count104 +\dotsspace@=\muskip10 +\c@parentequation=\count105 +\dspbrk@lvl=\count106 +\tag@help=\toks19 +\row@=\count107 +\column@=\count108 +\maxfields@=\count109 +\andhelp@=\toks20 +\eqnshift@=\dimen114 +\alignsep@=\dimen115 +\tagshift@=\dimen116 +\tagwidth@=\dimen117 +\totwidth@=\dimen118 +\lineht@=\dimen119 +\@envbody=\toks21 +\multlinegap=\skip138 +\multlinetaggap=\skip139 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2735. +LaTeX Info: Redefining \] on input line 2736. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +) (/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/stmaryrd.sty +Package: stmaryrd 1994/03/03 St Mary's Road symbol package +\symstmry=\mathgroup6 +LaTeX Font Info: Overwriting symbol font `stmry' in version `bold' +(Font) U/stmry/m/n --> U/stmry/b/n on input line 89. +) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty +Package: textcomp 2005/09/27 v1.99g Standard LaTeX package +Package textcomp Info: Sub-encoding information: +(textcomp) 5 = only ISO-Adobe without \textcurrency +(textcomp) 4 = 5 + \texteuro +(textcomp) 3 = 4 + \textohm +(textcomp) 2 = 3 + \textestimated + \textcurrency +(textcomp) 1 = TS1 - \textcircled - \t +(textcomp) 0 = TS1 (full) +(textcomp) Font families with sub-encoding setting implement +(textcomp) only a restricted character set as indicated. +(textcomp) Family '?' is the default used for unknown fonts. +(textcomp) See the documentation for details. +Package textcomp Info: Setting ? sub-encoding to TS1/1 on input line 79. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +) +LaTeX Info: Redefining \oldstylenums on input line 334. +Package textcomp Info: Setting cmr sub-encoding to TS1/0 on input line 349. +Package textcomp Info: Setting cmss sub-encoding to TS1/0 on input line 350. +Package textcomp Info: Setting cmtt sub-encoding to TS1/0 on input line 351. +Package textcomp Info: Setting cmvtt sub-encoding to TS1/0 on input line 352. +Package textcomp Info: Setting cmbr sub-encoding to TS1/0 on input line 353. +Package textcomp Info: Setting cmtl sub-encoding to TS1/0 on input line 354. +Package textcomp Info: Setting ccr sub-encoding to TS1/0 on input line 355. +Package textcomp Info: Setting ptm sub-encoding to TS1/4 on input line 356. +Package textcomp Info: Setting pcr sub-encoding to TS1/4 on input line 357. +Package textcomp Info: Setting phv sub-encoding to TS1/4 on input line 358. +Package textcomp Info: Setting ppl sub-encoding to TS1/3 on input line 359. +Package textcomp Info: Setting pag sub-encoding to TS1/4 on input line 360. +Package textcomp Info: Setting pbk sub-encoding to TS1/4 on input line 361. +Package textcomp Info: Setting pnc sub-encoding to TS1/4 on input line 362. +Package textcomp Info: Setting pzc sub-encoding to TS1/4 on input line 363. +Package textcomp Info: Setting bch sub-encoding to TS1/4 on input line 364. +Package textcomp Info: Setting put sub-encoding to TS1/5 on input line 365. +Package textcomp Info: Setting uag sub-encoding to TS1/5 on input line 366. +Package textcomp Info: Setting ugq sub-encoding to TS1/5 on input line 367. +Package textcomp Info: Setting ul8 sub-encoding to TS1/4 on input line 368. +Package textcomp Info: Setting ul9 sub-encoding to TS1/4 on input line 369. +Package textcomp Info: Setting augie sub-encoding to TS1/5 on input line 370. +Package textcomp Info: Setting dayrom sub-encoding to TS1/3 on input line 371. +Package textcomp Info: Setting dayroms sub-encoding to TS1/3 on input line 372. +Package textcomp Info: Setting pxr sub-encoding to TS1/0 on input line 373. +Package textcomp Info: Setting pxss sub-encoding to TS1/0 on input line 374. +Package textcomp Info: Setting pxtt sub-encoding to TS1/0 on input line 375. +Package textcomp Info: Setting txr sub-encoding to TS1/0 on input line 376. +Package textcomp Info: Setting txss sub-encoding to TS1/0 on input line 377. +Package textcomp Info: Setting txtt sub-encoding to TS1/0 on input line 378. +Package textcomp Info: Setting lmr sub-encoding to TS1/0 on input line 379. +Package textcomp Info: Setting lmdh sub-encoding to TS1/0 on input line 380. +Package textcomp Info: Setting lmss sub-encoding to TS1/0 on input line 381. +Package textcomp Info: Setting lmssq sub-encoding to TS1/0 on input line 382. +Package textcomp Info: Setting lmvtt sub-encoding to TS1/0 on input line 383. +Package textcomp Info: Setting lmtt sub-encoding to TS1/0 on input line 384. +Package textcomp Info: Setting qhv sub-encoding to TS1/0 on input line 385. +Package textcomp Info: Setting qag sub-encoding to TS1/0 on input line 386. +Package textcomp Info: Setting qbk sub-encoding to TS1/0 on input line 387. +Package textcomp Info: Setting qcr sub-encoding to TS1/0 on input line 388. +Package textcomp Info: Setting qcs sub-encoding to TS1/0 on input line 389. +Package textcomp Info: Setting qpl sub-encoding to TS1/0 on input line 390. +Package textcomp Info: Setting qtm sub-encoding to TS1/0 on input line 391. +Package textcomp Info: Setting qzc sub-encoding to TS1/0 on input line 392. +Package textcomp Info: Setting qhvc sub-encoding to TS1/0 on input line 393. +Package textcomp Info: Setting futs sub-encoding to TS1/4 on input line 394. +Package textcomp Info: Setting futx sub-encoding to TS1/4 on input line 395. +Package textcomp Info: Setting futj sub-encoding to TS1/4 on input line 396. +Package textcomp Info: Setting hlh sub-encoding to TS1/3 on input line 397. +Package textcomp Info: Setting hls sub-encoding to TS1/3 on input line 398. +Package textcomp Info: Setting hlst sub-encoding to TS1/3 on input line 399. +Package textcomp Info: Setting hlct sub-encoding to TS1/5 on input line 400. +Package textcomp Info: Setting hlx sub-encoding to TS1/5 on input line 401. +Package textcomp Info: Setting hlce sub-encoding to TS1/5 on input line 402. +Package textcomp Info: Setting hlcn sub-encoding to TS1/5 on input line 403. +Package textcomp Info: Setting hlcw sub-encoding to TS1/5 on input line 404. +Package textcomp Info: Setting hlcf sub-encoding to TS1/5 on input line 405. +Package textcomp Info: Setting pplx sub-encoding to TS1/3 on input line 406. +Package textcomp Info: Setting pplj sub-encoding to TS1/3 on input line 407. +Package textcomp Info: Setting ptmx sub-encoding to TS1/4 on input line 408. +Package textcomp Info: Setting ptmj sub-encoding to TS1/4 on input line 409. +) (/usr/share/texlive/texmf-dist/tex/latex/psnfss/pifont.sty +Package: pifont 2005/04/12 PSNFSS-v9.2a Pi font support (SPQR) +LaTeX Font Info: Try loading font information for U+pzd on input line 63. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upzd.fd +File: upzd.fd 2001/06/04 font definitions for U/pzd. +) +LaTeX Font Info: Try loading font information for U+psy on input line 64. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upsy.fd +File: upsy.fd 2001/06/04 font definitions for U/psy. +)) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2012/11/06 v6.83m Hypertext links for LaTeX +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO) +Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO) +Package hobsub Info: Skipping package `infwarerr' (already loaded). +Package hobsub Info: Skipping package `ltxcmds' (already loaded). +Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO) +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is not detected. +Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) +Package etexcmds Info: Could not find \expanded. +(etexcmds) That can mean that you are not using pdfTeX 1.50 or +(etexcmds) that some package has redefined \expanded. +(etexcmds) In the latter case, load this package earlier. +Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) +Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO) +Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: pdfTeX >= 1.30 not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode not found. +Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO) +Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO) +Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO) +Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO) +Package: xcolor-patch 2011/01/30 xcolor patch +Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO) +Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO) +Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO) +Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2011/03/04 v1.3 Hooks for auxiliary files (HO) +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) +) +\@linkdim=\dimen120 +\Hy@linkcounter=\count110 +\Hy@pagecounter=\count111 +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count112 +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Hyper figures OFF on input line 4443. +Package hyperref Info: Link nesting OFF on input line 4448. +Package hyperref Info: Hyper index ON on input line 4451. +Package hyperref Info: Plain pages OFF on input line 4458. +Package hyperref Info: Backreferencing OFF on input line 4463. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4688. +\c@Hy@tempcnt=\count113 +(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip11 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 5041. +\XeTeXLinkMargin=\dimen121 +\Fld@menulength=\count114 +\Field@Width=\dimen122 +\Fld@charsize=\dimen123 +Package hyperref Info: Hyper figures OFF on input line 6295. +Package hyperref Info: Link nesting OFF on input line 6300. +Package hyperref Info: Hyper index ON on input line 6303. +Package hyperref Info: backreferencing OFF on input line 6310. +Package hyperref Info: Link coloring OFF on input line 6315. +Package hyperref Info: Link coloring with OCG OFF on input line 6320. +Package hyperref Info: PDF/A mode OFF on input line 6325. +LaTeX Info: Redefining \ref on input line 6365. +LaTeX Info: Redefining \pageref on input line 6369. +\Hy@abspage=\count115 +\c@Item=\count116 +\c@Hfootnote=\count117 +) + +Package hyperref Message: Driver (autodetected): hxetex. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hxetex.def +File: hxetex.def 2012/11/06 v6.83m Hyperref driver for XeTeX +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def +File: puenc.def 2012/11/06 v6.83m Hyperref: PDF Unicode definition (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/stringenc.sty +Package: stringenc 2011/12/02 v1.10 Convert strings between diff. encodings (HO) +) +\pdfm@box=\box32 +\c@Hy@AnnotLevel=\count118 +\HyField@AnnotCount=\count119 +\Fld@listcount=\count120 +\c@bookmark@seq@number=\count121 +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO) +Package rerunfilecheck Info: Feature \pdfmdfivesum is not available +(rerunfilecheck) (e.g. pdfTeX or LuaTeX with package `pdftexcmds'). +(rerunfilecheck) Therefore file contents cannot be checked efficiently +(rerunfilecheck) and the loading of the package is aborted. +) +\Hy@SectionHShift=\skip140 +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bookmark.sty +Package: bookmark 2011/12/02 v1.24 PDF bookmarks (HO) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bkm-dvipdfm.def +File: bkm-dvipdfm.def 2011/12/02 v1.24 bookmark driver for dvipdfm (HO) +\BKM@id=\count122 +)) (/usr/share/texlive/texmf-dist/tex/latex/booktabs/booktabs.sty +Package: booktabs 2005/04/14 v1.61803 publication quality tables +\heavyrulewidth=\dimen124 +\lightrulewidth=\dimen125 +\cmidrulewidth=\dimen126 +\belowrulesep=\dimen127 +\belowbottomsep=\dimen128 +\aboverulesep=\dimen129 +\abovetopsep=\dimen130 +\cmidrulesep=\dimen131 +\cmidrulekern=\dimen132 +\defaultaddspace=\dimen133 +\@cmidla=\count123 +\@cmidlb=\count124 +\@aboverulesep=\dimen134 +\@belowrulesep=\dimen135 +\@thisruleclass=\count125 +\@lastruleclass=\count126 +\@thisrulewidth=\dimen136 +) (/usr/share/texlive/texmf-dist/tex/latex/tools/longtable.sty +Package: longtable 2014/10/28 v4.11 Multi-page Table package (DPC) +\LTleft=\skip141 +\LTright=\skip142 +\LTpre=\skip143 +\LTpost=\skip144 +\LTchunksize=\count127 +\LTcapwidth=\dimen137 +\LT@head=\box33 +\LT@firsthead=\box34 +\LT@foot=\box35 +\LT@lastfoot=\box36 +\LT@cols=\count128 +\LT@rows=\count129 +\c@LT@tables=\count130 +\c@LT@chunks=\count131 +\LT@p@ftn=\toks23 +) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Package: anyfontsize 2007/11/22 anyfontsize.sty by pts +) (/usr/share/texlive/texmf-dist/tex/latex/enumitem/enumitem.sty +Package: enumitem 2011/09/28 v3.5.2 Customized lists +\labelindent=\skip145 +\enit@outerparindent=\dimen138 +\enit@toks=\toks24 +\enit@inbox=\box37 +\enitdp@description=\count132 +) (/usr/share/texlive/texmf-dist/tex/latex/wrapfig/wrapfig.sty +\wrapoverhang=\dimen139 +\WF@size=\dimen140 +\c@WF@wrappedlines=\count133 +\WF@box=\box38 +\WF@everypar=\toks25 +Package: wrapfig 2003/01/31 v 3.6 +) (/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.sty (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty +Package: expl3 2016/01/19 v6377 L3 programming layer (loader) +(/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3-code.tex +Package: expl3 2016/01/19 v6377 L3 programming layer (code) +L3 Module: l3bootstrap 2016/01/01 v6339 L3 Bootstrap code +L3 Module: l3names 2015/12/21 v6328 L3 Namespace for primitives +L3 Module: l3basics 2015/11/22 v6315 L3 Basic definitions +L3 Module: l3expan 2015/09/10 v5983 L3 Argument expansion +L3 Module: l3tl 2015/09/29 v6121 L3 Token lists +L3 Module: l3str 2016/01/03 v6357 L3 Strings +L3 Module: l3seq 2015/08/05 v5777 L3 Sequences and stacks +L3 Module: l3int 2016/01/05 v6366 L3 Integers +\c_max_int=\count134 +\l_tmpa_int=\count135 +\l_tmpb_int=\count136 +\g_tmpa_int=\count137 +\g_tmpb_int=\count138 +L3 Module: l3quark 2015/08/17 v5855 L3 Quarks +L3 Module: l3prg 2015/11/01 v6216 L3 Control structures +\g__prg_map_int=\count139 +L3 Module: l3clist 2015/09/02 v5901 L3 Comma separated lists +L3 Module: l3token 2015/11/11 v6249 L3 Experimental token manipulation +L3 Module: l3prop 2016/01/05 v6366 L3 Property lists +L3 Module: l3msg 2015/09/28 v6113 L3 Messages +L3 Module: l3file 2015/12/03 v6317 L3 File and I/O operations +\l_iow_line_count_int=\count140 +\l__iow_target_count_int=\count141 +\l__iow_current_line_int=\count142 +\l__iow_current_word_int=\count143 +\l__iow_current_indentation_int=\count144 +L3 Module: l3skip 2016/01/05 v6366 L3 Dimensions and skips +\c_zero_dim=\dimen141 +\c_max_dim=\dimen142 +\l_tmpa_dim=\dimen143 +\l_tmpb_dim=\dimen144 +\g_tmpa_dim=\dimen145 +\g_tmpb_dim=\dimen146 +\c_zero_skip=\skip146 +\c_max_skip=\skip147 +\l_tmpa_skip=\skip148 +\l_tmpb_skip=\skip149 +\g_tmpa_skip=\skip150 +\g_tmpb_skip=\skip151 +\c_zero_muskip=\muskip12 +\c_max_muskip=\muskip13 +\l_tmpa_muskip=\muskip14 +\l_tmpb_muskip=\muskip15 +\g_tmpa_muskip=\muskip16 +\g_tmpb_muskip=\muskip17 +L3 Module: l3keys 2015/11/17 v6284 L3 Key-value interfaces +\g__keyval_level_int=\count145 +\l_keys_choice_int=\count146 +L3 Module: l3fp 2015/08/25 v5890 L3 Floating points +\c__fp_leading_shift_int=\count147 +\c__fp_middle_shift_int=\count148 +\c__fp_trailing_shift_int=\count149 +\c__fp_big_leading_shift_int=\count150 +\c__fp_big_middle_shift_int=\count151 +\c__fp_big_trailing_shift_int=\count152 +\c__fp_Bigg_leading_shift_int=\count153 +\c__fp_Bigg_middle_shift_int=\count154 +\c__fp_Bigg_trailing_shift_int=\count155 +L3 Module: l3box 2015/08/09 v5822 L3 Experimental boxes +\c_empty_box=\box39 +\l_tmpa_box=\box40 +\l_tmpb_box=\box41 +\g_tmpa_box=\box42 +\g_tmpb_box=\box43 +L3 Module: l3coffins 2015/08/06 v5789 L3 Coffin code layer +\l__coffin_internal_box=\box44 +\l__coffin_internal_dim=\dimen147 +\l__coffin_offset_x_dim=\dimen148 +\l__coffin_offset_y_dim=\dimen149 +\l__coffin_x_dim=\dimen150 +\l__coffin_y_dim=\dimen151 +\l__coffin_x_prime_dim=\dimen152 +\l__coffin_y_prime_dim=\dimen153 +\c_empty_coffin=\box45 +\l__coffin_aligned_coffin=\box46 +\l__coffin_aligned_internal_coffin=\box47 +\l_tmpa_coffin=\box48 +\l_tmpb_coffin=\box49 +\l__coffin_display_coffin=\box50 +\l__coffin_display_coord_coffin=\box51 +\l__coffin_display_pole_coffin=\box52 +\l__coffin_display_offset_dim=\dimen154 +\l__coffin_display_x_dim=\dimen155 +\l__coffin_display_y_dim=\dimen156 +L3 Module: l3color 2014/08/23 v5354 L3 Experimental color support +L3 Module: l3sys 2015/09/25 v6087 L3 Experimental system/runtime functions +L3 Module: l3candidates 2016/01/14 v6376 L3 Experimental additions to l3kernel +\l__box_top_dim=\dimen157 +\l__box_bottom_dim=\dimen158 +\l__box_left_dim=\dimen159 +\l__box_right_dim=\dimen160 +\l__box_top_new_dim=\dimen161 +\l__box_bottom_new_dim=\dimen162 +\l__box_left_new_dim=\dimen163 +\l__box_right_new_dim=\dimen164 +\l__box_internal_box=\box53 +\l__coffin_bounding_shift_dim=\dimen165 +\l__coffin_left_corner_dim=\dimen166 +\l__coffin_right_corner_dim=\dimen167 +\l__coffin_bottom_corner_dim=\dimen168 +\l__coffin_top_corner_dim=\dimen169 +\l__coffin_scaled_total_height_dim=\dimen170 +\l__coffin_scaled_width_dim=\dimen171 +L3 Module: l3luatex 2015/11/11 v6250 L3 Experimental LuaTeX-specific functions +) (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def +File: l3xdvidpfmx.def 2015/11/11 v6250 L3 Experimental driver: xdvipdfmx +)) (/usr/share/texlive/texmf-dist/tex/latex/l3packages/xparse/xparse.sty +Package: xparse 2016/01/19 v6377 L3 Experimental document command parser +\l__xparse_current_arg_int=\count156 +\l__xparse_m_args_int=\count157 +\l__xparse_mandatory_args_int=\count158 +\l__xparse_processor_int=\count159 +\l__xparse_v_nesting_int=\count160 +) +Package: fontspec 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec-xetex.sty +Package: fontspec-xetex 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +\l_fontspec_script_int=\count161 +\l_fontspec_language_int=\count162 +\l_fontspec_strnum_int=\count163 +\l__fontspec_tmpa_dim=\dimen172 +\l__fontspec_tmpb_dim=\dimen173 +\l__fontspec_tmpc_dim=\dimen174 +\g__file_internal_ior=\read1 +(/usr/share/texlive/texmf-dist/tex/latex/base/fontenc.sty +Package: fontenc 2005/09/27 v1.99g Standard LaTeX package +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1enc.def +File: eu1enc.def 2010/05/27 v0.1h Experimental Unicode font encodings +) +LaTeX Font Info: Try loading font information for EU1+lmr on input line 105. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmr.fd +File: eu1lmr.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) (/usr/share/texlive/texmf-dist/tex/xelatex/xunicode/xunicode.sty +File: xunicode.sty 2011/09/09 v0.981 provides access to latin accents and many other characters in Unicode lower plane +(/usr/share/texmf/tex/latex/tipa/t3enc.def +File: t3enc.def 2001/12/31 T3 encoding +LaTeX Font Info: Try loading font information for EU1+lmss on input line 357. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmss.fd +File: eu1lmss.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) +\tipaTiiicode=\count164 +\tipasavetokens=\toks26 +\tipachecktokens=\toks27 +) +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \__fontspec_post_arg:w with sig. 'mmO{}' on line 353. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \fontspec with sig. 'om' on line 355. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmainfont with sig. 'om' on line 365. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setsansfont with sig. 'om' on line 375. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmonofont with sig. 'om' on line 385. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathrm with sig. 'om' on line 399. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setboldmathrm with sig. 'om' on line 407. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathsf with sig. 'om' on line 415. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathtt with sig. 'om' on line 423. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfamily with sig. 'mom' on line 437. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontface with sig. 'mom' on line 453. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \defaultfontfeatures with sig. 't+om' on line 467. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \addfontfeatures with sig. 'm' on line 529. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfeature with sig. 'mm' on line 540. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newAATfeature with sig. 'mmmm' on line 548. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newopentypefeature with sig. 'mmm' on line 556. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeature with sig. 'mm' on line 577. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeatureoption with sig. 'mmm' on line 586. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontscript with sig. 'mm' on line 590. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontlanguage with sig. 'mm' on line 594. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \DeclareFontsExtensions with sig. 'm' on line 599. +................................................. +\l__fontspec_tmp_int=\count165 +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.cfg) +LaTeX Info: Redefining \itshape on input line 2705. +LaTeX Info: Redefining \slshape on input line 2710. +LaTeX Info: Redefining \scshape on input line 2715. +LaTeX Info: Redefining \upshape on input line 2720. +\l__fontspec_em_int=\count166 +\l__fontspec_emdef_int=\count167 +LaTeX Info: Redefining \em on input line 2736. +LaTeX Info: Redefining \emph on input line 2742. +LaTeX Info: Redefining \- on input line 2746. +................................................. +. LaTeX info: "xparse/redefine-command" +. +. Redefining command \oldstylenums with sig. 'm' on line 2841. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \liningnums with sig. 'm' on line 2845. +................................................. +)) +Package hyperref Info: Option `colorlinks' set `true' on input line 87. +\px=\skip152 +\c@md@targetcount=\count168 +\mdcompactskip=\skip153 +\mdcompacttopsep=\skip154 +\dim@rem=\skip155 +\dim@ch=\skip156 +\md@height=\skip157 +\dim@marginbottom=\skip158 +\dim@paddingbottom=\skip159 +\md@interaction=\count169 +\mddefinitionsskip=\skip160 +\md@captionlen=\skip161 +\mdtoclevel=\count170 +\c@mdtoclevelbold=\count171 +\c@mdtocleveldots=\count172 +\mdtocskip=\skip162 +\mdpreskip=\skip163 +\presp=\skip164 +LaTeX Font Info: Try loading font information for EU1+lmtt on input line 801. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmtt.fd +File: eu1lmtt.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +\md@postskip=\skip165 +\ppresp=\skip166 +\md@thmcaption=\box54 +\md@defaultcolwidth=\skip167 +\mdtabularskip=\skip168 +\mdbibindentunit=\skip169 +\c@md@authorcount=\count173 +\c@mdx@authorcount=\count174 +\c@@mdTargetCount=\count175 +\@snippetBox=\box55 +\@snippetWidth=\skip170 +\@snippetHeight=\skip171 +\@snippetDepth=\skip172 +\c@snippets=\count176 +) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty +Package: geometry 2010/09/12 v5.6 Page Geometry +\Gm@cnth=\count177 +\Gm@cntv=\count178 +\c@Gm@tempcnt=\count179 +\Gm@bindingoffset=\dimen175 +\Gm@wd@mp=\dimen176 +\Gm@odd@mp=\dimen177 +\Gm@even@mp=\dimen178 +\Gm@layoutwidth=\dimen179 +\Gm@layoutheight=\dimen180 +\Gm@layouthoffset=\dimen181 +\Gm@layoutvoffset=\dimen182 +\Gm@dimlist=\toks28 +) (/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +\fancy@headwidth=\skip173 +\f@ncyO@elh=\skip174 +\f@ncyO@erh=\skip175 +\f@ncyO@olh=\skip176 +\f@ncyO@orh=\skip177 +\f@ncyO@elf=\skip178 +\f@ncyO@erf=\skip179 +\f@ncyO@olf=\skip180 +\f@ncyO@orf=\skip181 +) (build/P4Runtime-Spec.aux + +LaTeX Warning: Label `sec-example' multiply defined. + +) +\openout1 = `P4Runtime-Spec.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for TS1+cmr on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1cmr.fd +File: ts1cmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions +) +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for EU1/lmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T3/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for T3+cmr on input line 14. +(/usr/share/texmf/tex/latex/tipa/t3cmr.fd +File: t3cmr.fd 2001/12/31 TIPA font definitions +) +LaTeX Font Info: ... okay on input line 14. +\AtBeginShipoutBox=\box56 +Package hyperref Info: Link coloring ON on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2012/10/27 v2.43 Cross-referencing by name of section +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO) +) +\c@section@level=\count180 +) +LaTeX Info: Redefining \ref on input line 14. +LaTeX Info: Redefining \pageref on input line 14. +LaTeX Info: Redefining \nameref on input line 14. +................................................. +. fontspec info: "setup-math" +. +. Adjusting the maths setup (use [no-math] to avoid this). +................................................. +\symlegacymaths=\mathgroup7 +LaTeX Font Info: Overwriting symbol font `legacymaths' in version `bold' +(Font) OT1/cmr/m/n --> OT1/cmr/bx/n on input line 14. +LaTeX Font Info: Redeclaring math accent \acute on input line 14. +LaTeX Font Info: Redeclaring math accent \grave on input line 14. +LaTeX Font Info: Redeclaring math accent \ddot on input line 14. +LaTeX Font Info: Redeclaring math accent \tilde on input line 14. +LaTeX Font Info: Redeclaring math accent \bar on input line 14. +LaTeX Font Info: Redeclaring math accent \breve on input line 14. +LaTeX Font Info: Redeclaring math accent \check on input line 14. +LaTeX Font Info: Redeclaring math accent \hat on input line 14. +LaTeX Font Info: Redeclaring math accent \dot on input line 14. +LaTeX Font Info: Redeclaring math accent \mathring on input line 14. +LaTeX Font Info: Redeclaring math symbol \Gamma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Delta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Theta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Lambda on input line 14. +LaTeX Font Info: Redeclaring math symbol \Xi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Pi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Sigma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Upsilon on input line 14. +LaTeX Font Info: Redeclaring math symbol \Phi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Psi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Omega on input line 14. +LaTeX Font Info: Redeclaring math symbol \mathdollar on input line 14. +LaTeX Font Info: Redeclaring symbol font `operators' on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `normal' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/cmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `bold' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/cmr/bx/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) EU1/lmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/cmr/m/it --> EU1/lmr/m/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/cmr/bx/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/cmss/m/n --> EU1/lmss/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/cmtt/m/n --> EU1/lmtt/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) EU1/lmr/m/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' +(Font) OT1/cmr/bx/it --> EU1/lmr/bx/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/cmss/bx/n --> EU1/lmss/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/cmtt/m/n --> EU1/lmtt/bx/n on input line 14. +*geometry* driver: auto-detecting +*geometry* detected driver: xetex +*geometry* verbose mode - [ preamble ] result: +* driver: xetex +* paper: +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: +* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt) +* v-part:(T,H,B)=(72.26999pt, 632.3625pt, 90.3375pt) +* \paperwidth=614.295pt +* \paperheight=794.96999pt +* \textwidth=469.75502pt +* \textheight=632.3625pt +* \oddsidemargin=0.0pt +* \evensidemargin=0.0pt +* \topmargin=-37.0pt +* \headheight=30.0pt +* \headsep=25.0pt +* \topskip=11.0pt +* \footskip=30.0pt +* \marginparwidth=59.0pt +* \marginparsep=10.0pt +* \columnsep=10.0pt +* \skip\footins=10.0pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +resolve font stack: UtopiaStd-Regular + +\g__fontspec_family_UtopiaStd-Regular_int=\count181 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'UtopiaStd-Regular(0)' created for font 'UtopiaStd-Regular' with +. options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;" +. - 'small caps' (m/sc) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;+smcp;" +................................................. + +resolved font stack 'UtopiaStd-Regular' to: UtopiaStd-Regular +LaTeX Font Info: Try loading font information for U+msa on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Try loading font information for U+msb on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Try loading font information for U+stmry on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/Ustmry.fd) + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/bx/n' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 35. + +resolve font stack: LuxiMono + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +\g__fontspec_family_LuxiMono_int=\count182 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'LuxiMono(0)' created for font 'LuxiMono' with options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: <->"LuxiMono/OT:" +. - 'small caps' (m/sc) with NFSS spec.: +................................................. + +resolved font stack 'LuxiMono' to: LuxiMono +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/se-ascii-print.def +File: se-ascii-print.def 2011/12/02 v1.10 stringenc: Printable ASCII characters +) [1 + +] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[2] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <10.95> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 295. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Font Warning: Font shape `EU1/LuxiMono(0)/bx/n' undefined +(Font) using `EU1/LuxiMono(0)/m/n' instead on input line 295. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[3] + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/m/it' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 503. + +[4] [5] [6] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[7] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/reference-architecture.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[8] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[9] +File: build/single-embedded-controller.png Graphic file (type QTm) + [10] +File: build/single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-controllers.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-ha-controllers.png Graphic file (type QTm) + [11] [12] [13] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[14] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[15] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <12> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 1487. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1487. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[16] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[17] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (53.84203pt too wide) in paragraph at lines 1784--1787 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For all slave controllers, \EU1/LuxiMono(0)/bx/n/8.2125 status \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set to non-OK (with \EU1/LuxiMono(0)/bx/n/8.2125 status.code \EU1/UtopiaStd-Regular(0)/m/it/10.95 set to \EU1/LuxiMono(0)/bx/n/8.2125 google.rpc.ALREADY_EXISTS\EU1/UtopiaStd-Regular(0)/m/it/10.95 ). + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[18] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1821. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1845. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[19] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1886. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1931. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[20] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[21] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[22] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (12.45624pt too wide) in paragraph at lines 2155--2168 + [] + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2184. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[23] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[24] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2372. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2430. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[25] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2503. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2584. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[26] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.59204pt too wide) in paragraph at lines 2638--2640 +[]\EU1/LuxiMono(0)/bx/n/8.2125 BYTES\EU1/UtopiaStd-Regular(0)/m/it/10.95 , which signifies that this meter can be configured with rates expressed in bytes/second. + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2663. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (18.74199pt too wide) in paragraph at lines 2680--2687 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 carrying P4 standard annotations \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_in") \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_out")\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[27] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[28] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2821. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[29] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[30] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[31] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3044. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3091. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3129. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[32] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[33] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[34] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[35] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[36] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[37] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1629) in paragraph at lines 3733--3735 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For example, the following P4$[]$ objects involve complex types that need to be exposed in + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[38] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1454) in paragraph at lines 3781--3790 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 ification for all the named types in the P4$[]$ program. These named types are \EU1/LuxiMono(0)/bx/n/8.2125 struct\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 header\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + + +Underfull \hbox (badness 1831) in paragraph at lines 3781--3790 +\EU1/LuxiMono(0)/bx/n/8.2125 header_union\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 enum \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 serializable_enum\EU1/UtopiaStd-Regular(0)/m/it/10.95 ; for each of these we have a type specification mes- + [] + + +Underfull \hbox (badness 1845) in paragraph at lines 3781--3790 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 sage, respectively \EU1/LuxiMono(0)/bx/n/8.2125 P4StructTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnionTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4EnumTypeSpec \EU1/UtopiaStd-Regular(0)/m/it/10.95 and + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[39] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (33.06564pt too wide) in paragraph at lines 3816--3823 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 “binary string” types (\EU1/LuxiMono(0)/bx/n/8.2125 bit\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 int\EU1/UtopiaStd-Regular(0)/m/it/10.95 , and \EU1/LuxiMono(0)/bx/n/8.2125 varbit\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) are grouped together in the \EU1/LuxiMono(0)/bx/n/8.2125 P4BitstringLikeTypeSpec + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3833. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.46094pt too wide) in paragraph at lines 3870--3873 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 An invalid header union (i.e. all headers in the union are invalid) is represented by a \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnion + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[40] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[41] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4007. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[42] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (24.68944pt too wide) in paragraph at lines 4089--4094 +[]\EU1/LuxiMono(0)/bx/n/8.2125 translated_type\EU1/UtopiaStd-Regular(0)/m/it/10.95 , if and only if the P4 \EU1/LuxiMono(0)/bx/n/8.2125 type \EU1/UtopiaStd-Regular(0)/m/it/10.95 declaration was annotated with \EU1/LuxiMono(0)/bx/n/8.2125 @p4runtime_translation\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[43] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4176. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[44] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[45] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[46] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[47] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.53593pt too wide) in paragraph at lines 4590--4593 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 If the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 does not match the table description in the P4Info (e.g. the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 is \EU1/LuxiMono(0)/bx/n/8.2125 action_profile_member_id + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[48] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[49] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[50] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[51] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[52] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[53] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5156. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[54] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[55] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[56] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (9.29865pt too wide) in paragraph at lines 5404--5406 + []\EU1/lmr/bx/n/10.95 9.2.2.1.| Rules on Setting \EU1/LuxiMono(0)/bx/n/8.2125 max_size[] \EU1/UtopiaStd-Regular(0)/m/it/10.95 The valid values for \EU1/LuxiMono(0)/bx/n/8.2125 max_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 depend on the static \EU1/LuxiMono(0)/bx/n/8.2125 max_group_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[57] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[58] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[59] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[60] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5679. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5719. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1331) in paragraph at lines 5722--5729 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 A direct counter is a direct resource associated with a \EU1/LuxiMono(0)/bx/n/8.2125 TableEntry \EU1/UtopiaStd-Regular(0)/m/it/10.95 (see [][]Direct Resources[][]). The + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[61] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5796. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5889. + +[62] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5920. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[63] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5997. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6093. + +[64] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6103. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[65] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6227. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[66] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.93839pt too wide) in paragraph at lines 6338--6340 +[]\EU1/LuxiMono(0)/bx/n/8.2125 MODIFY\EU1/UtopiaStd-Regular(0)/m/it/10.95 : Modify the attributes of a given clone session entry, indexed by the given \EU1/LuxiMono(0)/bx/n/8.2125 clone_session_id\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +[67] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6376. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[68] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[69] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6512. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6556. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[70] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[71] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6754. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[72] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/error-report.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[73] +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <14.4> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 6878. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6878. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: Hyper reference `wildcard-reads' on page 74 undefined on input line 6900. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[74] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6980. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[75] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[76] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[77] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (34.34796pt too wide) in paragraph at lines 7258--7263 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If an error is encountered before even trying to attempt individual batch updates, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +[78] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.66206pt too wide) in paragraph at lines 7267--7278 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 Otherwise, if one or more updates in the batch (\EU1/LuxiMono(0)/bx/n/8.2125 WriteRequest.updates\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) failed, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7314. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7314. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7314. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7314. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7314. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7314. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7314. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7314. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7314. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7314. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7314. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7314. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7314. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[79] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[80] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.4752pt too wide) in paragraph at lines 7543--7547 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 responding to \EU1/LuxiMono(0)/bx/n/8.2125 a \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 c\EU1/UtopiaStd-Regular(0)/m/it/10.95 , followed by a status \EU1/LuxiMono(0)/bx/n/8.2125 {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[81] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7629. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7629. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7629. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7629. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7629. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7629. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7629. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7629. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7629. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7629. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7629. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7629. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7629. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 7656. + + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 7656. + +[82] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[83] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7752. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7752. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7752. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7752. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7752. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7752. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7752. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7752. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7752. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7752. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7752. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7752. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7752. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[84] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 7850--7853 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If a P4Runtime server supports both \EU1/LuxiMono(0)/bx/n/8.2125 SetForwardingPipelineConfig \EU1/UtopiaStd-Regular(0)/m/it/10.95 as well as returning the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[85] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[86] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[87] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[88] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8212. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[89] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8280. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8280. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8280. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8280. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8280. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8280. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8280. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8280. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8280. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8280. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8280. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8280. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8280. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[90] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/psa-metadata-translation.png Graphic file (type QTm) + [91] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[92] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[93] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[94] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[95] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[96] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 8788--8795 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 p4info-ext should include a Protobuf message definition for every extern type that can + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[97] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 4036) in paragraph at lines 8843--8850 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 P4Runtime also supports streaming arbitrary Protobuf messages between the server and the + [] + + +Underfull \hbox (badness 1629) in paragraph at lines 8843--8850 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 client, by including an \EU1/LuxiMono(0)/bx/n/8.2125 Any \EU1/UtopiaStd-Regular(0)/m/it/10.95 Protobuf field [[][]30[][]] named \EU1/LuxiMono(0)/bx/n/8.2125 other \EU1/UtopiaStd-Regular(0)/m/it/10.95 in both \EU1/LuxiMono(0)/bx/n/8.2125 p4.v1.StreamMessageRequest + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[98] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[99] +Underfull \hbox (badness 1997) in paragraph at lines 9049--9051 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 Table [][]7[][] lists P4$[]$ annotations introduced primarily for the purpose of adding features for the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[100] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[101] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.61781pt too wide) in paragraph at lines 9196--9203 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 In gRPC, the status of a RPC request is sent as metadata, whose size is limited by the \EU1/LuxiMono(0)/bx/n/8.2125 grpc.max_metadata_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[102] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 10000) in paragraph at lines 9287--9288 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Complex Types in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 0. html# sec- p4- + [] + + +Underfull \hbox (badness 4001) in paragraph at lines 9299--9300 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Google Cloud APIs Versioning - Backwards-Compatibility.” [][]\EU1/lmtt/m/n/10.95 https:// cloud. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9308--9309 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “gRPC Streaming RPCs in C++.” [][]\EU1/lmtt/m/n/10.95 https:// grpc. io/ docs/ tutorials/ basic/ c. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9317--9318 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “P4 Concurrency Model.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 0. html# sec- + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9320--9321 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” + [] + +[103] +Underfull \hbox (badness 10000) in paragraph at lines 9335--9336 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Protobuf OneOf Backwards-Compatibility Issues.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9341--9342 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Action Selector.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# sec- action- + [] + + +Underfull \hbox (badness 2409) in paragraph at lines 9350--9351 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Empty Group Action Appendix.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9353--9354 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Select Expressions in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 0. html# sec- + [] + + +Underfull \hbox (badness 1668) in paragraph at lines 9368--9369 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Any Protobuf Message.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ protocol- buffers/ docs/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9374--9375 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC C++ Error Details Library.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ grpc/ grpc/ blob/ master/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9377--9378 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC Canonical Status Codes.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ maps- booking/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9383--9384 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Protobuf MessageDifferencer in the C++ API.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + +[104] +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 9395. +[105] +Package atveryend Info: Empty hook `AfterLastShipout' on input line 9395. +(build/P4Runtime-Spec.aux) +Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 9395. +Package atveryend Info: Empty hook `AtEndAfterFileList' on input line 9395. + +LaTeX Font Warning: Some font shapes were not available, defaults substituted. + + +LaTeX Warning: There were undefined references. + + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 27536 strings out of 493638 + 517692 string characters out of 6146796 + 565365 words of memory out of 5000000 + 30638 multiletter control sequences out of 15000+600000 + 14633 words of font info for 98 fonts, out of 8000000 for 9000 + 1328 hyphenation exceptions out of 8191 + 48i,19n,81p,10429b,767s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on build/P4Runtime-Spec.pdf (105 pages). diff --git a/spec/v1.1.0-rc.1/P4Runtime-Spec.pdf b/spec/v1.1.0-rc.1/P4Runtime-Spec.pdf new file mode 100644 index 00000000..3ab8667d Binary files /dev/null and b/spec/v1.1.0-rc.1/P4Runtime-Spec.pdf differ diff --git a/spec/v1.1.0-rc.1/P4Runtime-Spec.tex b/spec/v1.1.0-rc.1/P4Runtime-Spec.tex new file mode 100644 index 00000000..1f4dfb76 --- /dev/null +++ b/spec/v1.1.0-rc.1/P4Runtime-Spec.tex @@ -0,0 +1,9395 @@ +\documentclass[11pt]{article} +% generated by Madoko, version 1.1.4 +%mdk-data-line={1} + + +\usepackage[heading-base={2},section-num={False},bib-label={hide},fontspec={True}]{madoko2} +\usepackage[top=1in, bottom=1.25in, left=1in, right=1in]{geometry} +\usepackage{fancyhdr} +%mdk-data-line={11} + + \setlength{\headheight}{30pt} + \setlength{\emergencystretch}{2em} + +\begin{document} + + + +{\mdfontfamily{UtopiaStd-Regular} +%mdk-data-line={203} +\mdxtitleblockstart{} +%mdk-data-line={203} +\mdxtitle{{\sffamily{\bfseries\mdline{203}P4Runtime Specification}}}%mdk + +%mdk-data-line={206} +\mdxtitlenote{{\sffamily{\bfseries\mdline{206}version 1.1.0-rc.1}}}%mdk +\mdxauthorstart{} +%mdk-data-line={211} +\mdxauthorname{\mdline{211}The P4.org API Working Group}%mdk +\mdxauthorend +%mdk-data-line={220} +\mdxtitlefooter{{\sffamily{\bfseries\mdline{220}2019-12-12}}}%mdk +\mdtitleauthorrunning{}{}\mdxtitleblockend%mdk + +%mdk-data-line={205} +\begin{abstract}%mdk + +%mdk-data-line={206} +\noindent\mdline{206}P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.%mdk +%mdk +\end{abstract}%mdk +\mdline{214} +\begin{mdtoc}%mdk + +\section*{Contents}\label{sec-contents}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-introduction-and-scope}{\mdref{sec-introduction-and-scope}{1.\hspace*{0.5em}Introduction and Scope}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-language-version-applicability}{\mdref{sec-p4-language-version-applicability}{1.1.\hspace*{0.5em}P4 Language Version Applicability}}%mdk + +\mdtocitemx{sec-in-scope}{\mdref{sec-in-scope}{1.2.\hspace*{0.5em}In Scope}}%mdk + +\mdtocitemx{sec-not-in-scope}{\mdref{sec-not-in-scope}{1.3.\hspace*{0.5em}Not In Scope}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-terms-and-definitions}{\mdref{sec-terms-and-definitions}{2.\hspace*{0.5em}Terms and Definitions}}%mdk + +\mdtocitemx{sec-reference-architecture}{\mdref{sec-reference-architecture}{3.\hspace*{0.5em}Reference Architecture}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-idealized-workflow}{\mdref{sec-idealized-workflow}{3.1.\hspace*{0.5em}Idealized Workflow}}%mdk + +\mdtocitemx{sec-p4-as-behavioral-description-language}{\mdref{sec-p4-as-behavioral-description-language}{3.2.\hspace*{0.5em}P4 as a Behavioral Description Language}}%mdk + +\mdtocitemx{sec-alternative-workflows}{\mdref{sec-alternative-workflows}{3.3.\hspace*{0.5em}Alternative Workflows}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{\mdref{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{3.3.1.\hspace*{0.5em}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}}%mdk + +\mdtocitemx{sec-no-p4-source-available-p4info-available}{\mdref{sec-no-p4-source-available-p4info-available}{3.3.2.\hspace*{0.5em}No P4 Source Available, P4Info Available}}%mdk + +\mdtocitemx{sec-partial-p4info-and-p4-source-are-available}{\mdref{sec-partial-p4info-and-p4-source-are-available}{3.3.3.\hspace*{0.5em}Partial P4Info and P4 Source are Available}}%mdk + +\mdtocitemx{sec-p4info-role-based-subsets}{\mdref{sec-p4info-role-based-subsets}{3.3.4.\hspace*{0.5em}P4Info Role-Based Subsets}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-restarts}{\mdref{sec-restarts}{3.4.\hspace*{0.5em}P4Runtime State Across Restarts}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-controller-use-cases}{\mdref{sec-controller-use-cases}{4.\hspace*{0.5em}Controller Use-cases}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-single-embedded-controller}{\mdref{sec-single-embedded-controller}{4.1.\hspace*{0.5em}Single Embedded Controller}}%mdk + +\mdtocitemx{sec-single-remote-controller}{\mdref{sec-single-remote-controller}{4.2.\hspace*{0.5em}Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-single-remote-controller}{\mdref{sec-embedded-single-remote-controller}{4.3.\hspace*{0.5em}Embedded + Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-two-remote-controllers}{\mdref{sec-embedded-two-remote-controllers}{4.4.\hspace*{0.5em}Embedded + Two Remote Controllers}}%mdk + +\mdtocitemx{sec-embedded-controller-two-high-availability-remote-controllers}{\mdref{sec-embedded-controller-two-high-availability-remote-controllers}{4.5.\hspace*{0.5em}Embedded Controller + Two High-Availability Remote Controllers}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-master-slave-arbitration-and-controller-replication}{\mdref{sec-master-slave-arbitration-and-controller-replication}{5.\hspace*{0.5em}Master-Slave Arbitration and Controller Replication}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-default-role}{\mdref{sec-default-role}{5.1.\hspace*{0.5em}Default Role}}%mdk + +\mdtocitemx{sec-arbitration-role-config}{\mdref{sec-arbitration-role-config}{5.2.\hspace*{0.5em}Role Config}}%mdk + +\mdtocitemx{sec-mastership-updates}{\mdref{sec-mastership-updates}{5.3.\hspace*{0.5em}Rules for Handling \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}} Messages Received from Controllers}}%mdk + +\mdtocitemx{sec-mastership-notification}{\mdref{sec-mastership-notification}{5.4.\hspace*{0.5em}Mastership Notifications}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-the-p4info-message}{\mdref{sec-the-p4info-message}{6.\hspace*{0.5em}The P4Info Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-common-messages}{\mdref{sec-common-messages}{6.1.\hspace*{0.5em}Common Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-documentation-message}{\mdref{sec-documentation-message}{6.1.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}} Message}}%mdk + +\mdtocitemx{sec-preamble-message}{\mdref{sec-preamble-message}{6.1.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}} Message}}%mdk + +\mdtocitemx{sec-annotating-p4-entities-with-documentation}{\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3.\hspace*{0.5em}Annotating P4 Entities with \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-pkginfo-message}{\mdref{sec-pkginfo-message}{6.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}} Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-annotating-p4-code-with-pkginfo}{\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1.\hspace*{0.5em}Annotating P4 code with PkgInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-id-allocation}{\mdref{sec-id-allocation}{6.3.\hspace*{0.5em}ID Allocation for P4Info Objects}}%mdk + +\mdtocitemx{sec-p4info-objects}{\mdref{sec-p4info-objects}{6.4.\hspace*{0.5em}P4Info Objects}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table}{\mdref{sec-table}{6.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}}%mdk + +\mdtocitemx{sec-action}{\mdref{sec-action}{6.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}}%mdk + +\mdtocitemx{sec-p4info-action-profile}{\mdref{sec-p4info-action-profile}{6.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}}%mdk + +\mdtocitemx{sec-counter-directcounter}{\mdref{sec-counter-directcounter}{6.4.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}}%mdk + +\mdtocitemx{sec-meter-directmeter}{\mdref{sec-meter-directmeter}{6.4.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}}%mdk + +\mdtocitemx{sec-controller-packet-meta}{\mdref{sec-controller-packet-meta}{6.4.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}}%mdk + +\mdtocitemx{sec-valueset}{\mdref{sec-valueset}{6.4.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}}%mdk + +\mdtocitemx{sec-register}{\mdref{sec-register}{6.4.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}}%mdk + +\mdtocitemx{sec-digest}{\mdref{sec-digest}{6.4.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}}%mdk + +\mdtocitemx{sec-p4info-extern}{\mdref{sec-p4info-extern}{6.4.10.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{\mdref{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{6.5.\hspace*{0.5em}Support for Arbitrary P4 Types with P4TypeInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-fwd-pipe-config}{\mdref{sec-p4-fwd-pipe-config}{7.\hspace*{0.5em}P4 Forwarding-Pipeline Configuration}}%mdk + +\mdtocitemx{sec-general-principles-for-message-formatting}{\mdref{sec-general-principles-for-message-formatting}{8.\hspace*{0.5em}General Principles for Message Formatting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-set-unset-protobuf-field}{\mdref{sec-set-unset-protobuf-field}{8.1.\hspace*{0.5em}Set / Unset Protobuf Field}}%mdk + +\mdtocitemx{sec-read-write-symmetry}{\mdref{sec-read-write-symmetry}{8.2.\hspace*{0.5em}Read-Write Symmetry}}%mdk + +\mdtocitemx{sec-zero-as-reserved-value}{\mdref{sec-zero-as-reserved-value}{8.3.\hspace*{0.5em}Zero as Reserved Value}}%mdk + +\mdtocitemx{sec-bytestrings}{\mdref{sec-bytestrings}{8.4.\hspace*{0.5em}Bytestrings}}%mdk + +\mdtocitemx{sec-representation-of-arbitrary-p4-types}{\mdref{sec-representation-of-arbitrary-p4-types}{8.5.\hspace*{0.5em}Representation of Arbitrary P4 Types}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-problem-statement}{\mdref{sec-problem-statement}{8.5.1.\hspace*{0.5em}Problem Statement}}%mdk + +\mdtocitemx{sec-p4-type-specifications-in-p4infoproto}{\mdref{sec-p4-type-specifications-in-p4infoproto}{8.5.2.\hspace*{0.5em}P4 Type Specifications in p4info.proto}}%mdk + +\mdtocitemx{sec-p4data-in-p4runtime-proto}{\mdref{sec-p4data-in-p4runtime-proto}{8.5.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}} in p4runtime.proto}}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{8.5.4.\hspace*{0.5em}Example}}%mdk + +\mdtocitemx{sec-enum-serializable-enum-and-error}{\mdref{sec-enum-serializable-enum-and-error}{8.5.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}, serializable \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}}%mdk + +\mdtocitemx{sec-user-defined-types}{\mdref{sec-user-defined-types}{8.5.6.\hspace*{0.5em}User-defined types}}%mdk + +\mdtocitemx{sec-trade-off-for-v10-release}{\mdref{sec-trade-off-for-v10-release}{8.5.7.\hspace*{0.5em}Trade-off for v1.0 Release}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-entity-msgs}{\mdref{sec-p4-entity-msgs}{9.\hspace*{0.5em}P4 Entity Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table-entry}{\mdref{sec-table-entry}{9.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-match-format}{\mdref{sec-match-format}{9.1.1.\hspace*{0.5em}Match Format}}%mdk + +\mdtocitemx{sec-action-specification}{\mdref{sec-action-specification}{9.1.2.\hspace*{0.5em}Action Specification}}%mdk + +\mdtocitemx{sec-default-entry}{\mdref{sec-default-entry}{9.1.3.\hspace*{0.5em}Default Entry}}%mdk + +\mdtocitemx{sec-constant-tables}{\mdref{sec-constant-tables}{9.1.4.\hspace*{0.5em}Constant Tables}}%mdk + +\mdtocitemx{sec-table-wildcard-reads}{\mdref{sec-table-wildcard-reads}{9.1.5.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-direct-resources}{\mdref{sec-direct-resources}{9.1.6.\hspace*{0.5em}Direct Resources}}%mdk + +\mdtocitemx{sec-idle-timeout}{\mdref{sec-idle-timeout}{9.1.7.\hspace*{0.5em}Idle-timeout}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-and-group}{\mdref{sec-action-profile-member-and-group}{9.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-programming}{\mdref{sec-action-profile-member-programming}{9.2.1.\hspace*{0.5em}Action Profile Member Programming}}%mdk + +\mdtocitemx{sec-action-profile-group-programming}{\mdref{sec-action-profile-group-programming}{9.2.2.\hspace*{0.5em}Action Profile Group Programming}}%mdk + +\mdtocitemx{sec-oneshot}{\mdref{sec-oneshot}{9.2.3.\hspace*{0.5em}One Shot Action Selector Programming}}%mdk + +\mdtocitemx{sec-constraints-on-action-selector-programming}{\mdref{sec-constraints-on-action-selector-programming}{9.2.4.\hspace*{0.5em}Constraints on action selector programming}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-counterentry-directcounterentry}{\mdref{sec-counterentry-directcounterentry}{9.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directcounterentry}{\mdref{sec-directcounterentry}{9.3.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\mdtocitemx{sec-counterentry}{\mdref{sec-counterentry}{9.3.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-meterentry-directmeterentry}{\mdref{sec-meterentry-directmeterentry}{9.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directmeterentry}{\mdref{sec-directmeterentry}{9.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\mdtocitemx{sec-meterentry}{\mdref{sec-meterentry}{9.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-packetreplicationengineentry}{\mdref{sec-packetreplicationengineentry}{9.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-multicastgroupentry}{\mdref{sec-multicastgroupentry}{9.5.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}}%mdk + +\mdtocitemx{sec-clonesessionentry}{\mdref{sec-clonesessionentry}{9.5.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-valuesetentry}{\mdref{sec-valuesetentry}{9.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}}%mdk + +\mdtocitemx{sec-registerentry}{\mdref{sec-registerentry}{9.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}}%mdk + +\mdtocitemx{sec-digestentry}{\mdref{sec-digestentry}{9.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}}%mdk + +\mdtocitemx{sec-extern-entry}{\mdref{sec-extern-entry}{9.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-error-reporting-messages}{\mdref{sec-error-reporting-messages}{10.\hspace*{0.5em}Error Reporting Messages}}%mdk + +\mdtocitemx{sec-atomicity-of-individual-write-and-read-operations}{\mdref{sec-atomicity-of-individual-write-and-read-operations}{11.\hspace*{0.5em}Atomicity of Individual \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} Operations}}%mdk + +\mdtocitemx{sec-write-rpc}{\mdref{sec-write-rpc}{12.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-batching-and-ordering-of-updates}{\mdref{sec-batching-and-ordering-of-updates}{12.1.\hspace*{0.5em}Batching and Ordering of Updates}}%mdk + +\mdtocitemx{sec-batch-atomicity}{\mdref{sec-batch-atomicity}{12.2.\hspace*{0.5em}Batch Atomicity}}%mdk + +\mdtocitemx{sec-error-reporting}{\mdref{sec-error-reporting}{12.3.\hspace*{0.5em}Error Reporting}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-read-rpc}{\mdref{sec-read-rpc}{13.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-nomenclature}{\mdref{sec-nomenclature}{13.1.\hspace*{0.5em}Nomenclature}}%mdk + +\mdtocitemx{sec-wildcard-reads}{\mdref{sec-wildcard-reads}{13.2.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-batch-processing}{\mdref{sec-batch-processing}{13.3.\hspace*{0.5em}Batch Processing}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{13.3.1.\hspace*{0.5em}Example}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-parallelism-of-read-and-write-requests}{\mdref{sec-parallelism-of-read-and-write-requests}{13.4.\hspace*{0.5em}Parallelism of Read and Write Requests}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-setforwardingpipelineconfig-rpc}{\mdref{sec-setforwardingpipelineconfig-rpc}{14.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-getforwardingpipelineconfig-rpc}{\mdref{sec-getforwardingpipelineconfig-rpc}{15.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-p4runtime-stream-messages}{\mdref{sec-p4runtime-stream-messages}{16.\hspace*{0.5em}P4Runtime Stream Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-packet-i_o}{\mdref{sec-packet-i_o}{16.1.\hspace*{0.5em}Packet I/O}}%mdk + +\mdtocitemx{sec-master-arbitration-update}{\mdref{sec-master-arbitration-update}{16.2.\hspace*{0.5em}Master Arbitration Update}}%mdk + +\mdtocitemx{sec-digest-messages}{\mdref{sec-digest-messages}{16.3.\hspace*{0.5em}Digest Messages}}%mdk + +\mdtocitemx{sec-table-idle-timeout-notification}{\mdref{sec-table-idle-timeout-notification}{16.4.\hspace*{0.5em}Table Idle Timeout Notification}}%mdk + +\mdtocitemx{sec-architecture-specific-notifications}{\mdref{sec-architecture-specific-notifications}{16.5.\hspace*{0.5em}Architecture-Specific Notifications}}%mdk + +\mdtocitemx{sec-stream-error-reporting}{\mdref{sec-stream-error-reporting}{16.6.\hspace*{0.5em}Stream Error Reporting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-examples-of-streamerror-messages}{\mdref{sec-examples-of-streamerror-messages}{16.6.1.\hspace*{0.5em}Examples of \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}} Messages}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-capabilities-rpc}{\mdref{sec-capabilities-rpc}{17.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}} RPC}}%mdk + +\mdtocitemx{sec-portability-considerations}{\mdref{sec-portability-considerations}{18.\hspace*{0.5em}Portability Considerations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-psa-metadata-translation}{\mdref{sec-psa-metadata-translation}{18.1.\hspace*{0.5em}PSA Metadata Translation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-translation-of-port-numbers}{\mdref{sec-translation-of-port-numbers}{18.1.1.\hspace*{0.5em}Translation of Port Numbers}}%mdk + +\mdtocitemx{sec-translation-of-packet-io-header-fields}{\mdref{sec-translation-of-packet-io-header-fields}{18.1.2.\hspace*{0.5em}Translation of Packet-IO Header Fields}}%mdk + +\mdtocitemx{sec-translation-of-match-fields}{\mdref{sec-translation-of-match-fields}{18.1.3.\hspace*{0.5em}Translation of Match Fields}}%mdk + +\mdtocitemx{sec-translation-of-action-parameters}{\mdref{sec-translation-of-action-parameters}{18.1.4.\hspace*{0.5em}Translation of Action Parameters}}%mdk + +\mdtocitemx{sec-port-translation-for-psa-extern-apis}{\mdref{sec-port-translation-for-psa-extern-apis}{18.1.5.\hspace*{0.5em}Port Translation for PSA Extern APIs}}%mdk + +\mdtocitemx{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{\mdref{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{18.1.6.\hspace*{0.5em}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-versioning}{\mdref{sec-p4runtime-versioning}{19.\hspace*{0.5em}P4Runtime Versioning}}%mdk + +\mdtocitemx{sec-extending-p4runtime}{\mdref{sec-extending-p4runtime}{20.\hspace*{0.5em}Extending P4Runtime for non-PSA Architectures}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-p4runtime-for-architecture-specific-externs}{\mdref{sec-extending-p4runtime-for-architecture-specific-externs}{20.1.\hspace*{0.5em}Extending P4Runtime for Architecture-Specific Externs}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-the-p4info-message}{\mdref{sec-extending-the-p4info-message}{20.1.1.\hspace*{0.5em}Extending the P4Info message}}%mdk + +\mdtocitemx{sec-extending-the-p4runtime-service}{\mdref{sec-extending-the-p4runtime-service}{20.1.2.\hspace*{0.5em}Extending the P4Runtime Service}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-architecture-specific-table-extensions}{\mdref{sec-architecture-specific-table-extensions}{20.2.\hspace*{0.5em}Architecture-Specific Table Extensions}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-new-match-types}{\mdref{sec-new-match-types}{20.2.1.\hspace*{0.5em}New Match Types}}%mdk + +\mdtocitemx{sec-new-table-properties}{\mdref{sec-new-table-properties}{20.2.2.\hspace*{0.5em}New Table Properties}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-known-limitations-of-current-p4runtime-version}{\mdref{sec-known-limitations-of-current-p4runtime-version}{21.\hspace*{0.5em}Known Limitations of Current P4Runtime Version}}%mdk + +\mdtocitemx{sec-security-concerns-for-p4runtime}{\mdref{sec-security-concerns-for-p4runtime}{22.\hspace*{0.5em}Security concerns for P4Runtime}}%mdk + +\mdtocitemx{sec-appendix}{\mdref{sec-appendix}{A.\hspace*{0.5em}Appendix}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-revision-history}{\mdref{sec-revision-history}{A.1.\hspace*{0.5em}Revision History}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-changes-in-v110}{\mdref{sec-changes-in-v110}{A.1.1.\hspace*{0.5em}Changes in v1.1.0}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-annotations}{\mdref{sec-p4-annotations}{A.2.\hspace*{0.5em}P4 Annotations}}%mdk + +\mdtocitemx{sec-value-set-example}{\mdref{sec-value-set-example}{A.3.\hspace*{0.5em}A More Complex Value Set Example}}%mdk + +\mdtocitemx{sec-guidelines-for-implementations}{\mdref{sec-guidelines-for-implementations}{A.4.\hspace*{0.5em}Guidelines for Implementations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-grpc-metadata-maximum-size}{\mdref{sec-grpc-metadata-maximum-size}{A.4.1.\hspace*{0.5em}gRPC Metadata Maximum Size}}%mdk + +\mdtocitemx{sec-grpc-server-maximum-receive-message-size}{\mdref{sec-grpc-server-maximum-receive-message-size}{A.4.2.\hspace*{0.5em}gRPC Server Maximum Receive Message Size}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-bibliography}{\mdref{sec-bibliography}{References}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{215} +\begin{mdtoc}%mdk + +\section*{Figures}\label{sec-figures}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{fig-reference-architecture}{\mdref{fig-reference-architecture}{\mdcaptionlabel{1}. P4Runtime Reference Architecture.}}%mdk + +\mdtocitemx{fig-single-embedded-controller}{\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}. Use-Case: Single Embedded Controller}}%mdk + +\mdtocitemx{fig-single-remote-controller}{\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}. Use-Case: Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-single-remote-controller}{\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}. Use-Case: Embedded Plus Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-controllers}{\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}. Use-Case: Embedded Plus Two Remote Controllers}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-ha-controllers}{\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}. Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk + +\mdtocitemx{fig-error-report}{\mdref{fig-error-report}{\mdcaptionlabel{7}. P4Runtime Error Report Message Format}}%mdk + +\mdtocitemx{fig-psa-metadata-translation}{\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}. P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{216} +\begin{mdtoc}%mdk + +\section*{Tables}\label{sec-tables}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{tab-mapping-p4-obj-ids}{\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}. Mapping of P4Info object type to 8-bit ID prefix value}}%mdk + +\mdtocitemx{tab-format-p4-obj-ids}{\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}. Format of P4Info object IDs}}%mdk + +\mdtocitemx{tab-exmpl-p4-obj-ids}{\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}. Example of statically-assigned P4Info object IDs}}%mdk + +\mdtocitemx{tab-valid-bytestring-encoding}{\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}. Examples of Valid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-invalid-bytestring-encoding}{\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}. Examples of Invalid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-p4-type-usage}{\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}. P4 Type Usage}}%mdk + +\mdtocitemx{tab-p4-annotations}{\mdref{tab-p4-annotations}{\mdcaptionlabel{7}. P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk + +%mdk-data-line={218} +\section{\mdline{218}1.\hspace*{0.5em}\mdline{218}Introduction and Scope}\label{sec-introduction-and-scope}%mdk%mdk + +%mdk-data-line={220} +\noindent\mdline{220}This document is published by the \mdline{220}\emph{P4.org API Working Group}\mdline{220}, which was +chartered\mdline{221}~[\mdcite{p4apiwgcharter}{16}]\mdline{221} to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called \mdline{223}\emph{P4Runtime}\mdline{223}. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +\mdline{226}\href{https://github.com/p4lang/p4runtime/tree/v1.1.0-rc.1/proto}{https://github.com/p4lang/p4runtime/tree/v1.1.0-rc.1/proto}\mdline{226}.%mdk + +%mdk-data-line={228} +\subsection{\mdline{228}1.1.\hspace*{0.5em}\mdline{228}P4 Language Version Applicability}\label{sec-p4-language-version-applicability}%mdk%mdk + +%mdk-data-line={230} +\noindent\mdline{230}P4Runtime is designed to be implemented in conjunction with the P4\mdline{230}\mdsub{16}\mdline{230} language +version or later. P4\mdline{231}\mdsub{14}\mdline{231} programs should be translated into P4\mdline{231}\mdsub{16}\mdline{231} to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P4\mdline{233}\mdsub{16}\mdline{233} 1.0, but were introduced in P4\mdline{233}\mdsub{16}\mdline{233} 1.1.0\mdline{233}~[\mdcite{p4revisions110}{28}]\mdline{233}. For +this version of P4Runtime, we recommend using P4\mdline{234}\mdsub{16}\mdline{234} 1.2.0\mdline{234}~[\mdcite{p4spec}{1}]\mdline{234}.%mdk + +%mdk-data-line={236} +\subsection{\mdline{236}1.2.\hspace*{0.5em}\mdline{236}In Scope}\label{sec-in-scope}%mdk%mdk + +%mdk-data-line={238} +\noindent\mdline{238}This specification document defines the \mdline{238}\emph{semantics}\mdline{238} of \mdline{238}\emph{P4Runtime}\mdline{238} messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime:%mdk + +%mdk-data-line={242} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={242} +\item\mdline{242}Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA)\mdline{243}~[\mdcite{psa}{18}]\mdline{243} externs (\mdline{243}e.g.\mdline{243} Counters, Meters, Action +Profiles, \mdline{244}\dots{}\mdline{244}). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0.%mdk + +%mdk-data-line={246} +\item\mdline{246}Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism.%mdk + +%mdk-data-line={248} +\item\mdline{248}Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy.%mdk + +%mdk-data-line={251} +\item\mdline{251}Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities.%mdk + +%mdk-data-line={253} +\item\mdline{253}Packet I/O to enable streaming packets to \mdline{253}\&\mdline{253} from the control plane.%mdk + +%mdk-data-line={254} +\item\mdline{254}Batching support, with different atomicity guarantees.%mdk + +%mdk-data-line={255} +\item\mdline{255}In-the-field device-reconfiguration with a new P4 data plane.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={257} +\noindent\mdline{257}The following are in the scope of this specification document:%mdk + +%mdk-data-line={259} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={259} +\item\mdline{259}Rationale for the P4Runtime design.%mdk + +%mdk-data-line={260} +\item\mdline{260}Reference architecture and use-cases for deploying a P4Runtime service.%mdk + +%mdk-data-line={261} +\item\mdline{261}Detailed description of the API semantics.%mdk + +%mdk-data-line={262} +\item\mdline{262}Requirements for conformant implementations of the API.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={264} +\subsection{\mdline{264}1.3.\hspace*{0.5em}\mdline{264}Not In Scope}\label{sec-not-in-scope}%mdk%mdk + +%mdk-data-line={266} +\noindent\mdline{266}The following are not in scope of P4Runtime:%mdk + +%mdk-data-line={268} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={268} +\item\mdline{268}Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +\mdline{273}[\mdcite{openconfig}{34}]\mdline{273}. An open source implementation of these APIs is also in progress +as part of the Stratum project\mdline{274}~[\mdcite{stratum}{36}]\mdline{274}.%mdk + +%mdk-data-line={275} +\item\mdline{275}Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={280} +\noindent\mdline{280}The following are not in scope of this specification document:%mdk + +%mdk-data-line={282} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={282} +\item\mdline{282}Description of the P4 programming language; it is assumed that the reader is +already familiar with P4\mdline{283}\mdsub{16}\mdline{283}~[\mdcite{p4spec}{1}]\mdline{283}.%mdk + +%mdk-data-line={284} +\item\mdline{284}Descriptions of gRPC and Protobuf files in general.%mdk + +%mdk-data-line={285} +\item\mdline{285}Controller\mdline{285}~\mdref{sec-arbitration-role-config}{role}\mdline{285} definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={289} +\section{\mdline{289}2.\hspace*{0.5em}\mdline{289}Terms and Definitions}\label{sec-terms-and-definitions}%mdk%mdk + +%mdk-data-line={291} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries arbitration}}%mdk + +%mdk-data-line={291} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{291}Refers to the process through which P4Runtime ensures that at any given +time, there is a single master (\mdline{292}i.e.\mdline{292} a client with write access) for a given +role. Also referred to as \mdline{293}\textquotedblleft{}master-slave arbitration\textquotedblright{}\mdline{293}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries client}}%mdk + +%mdk-data-line={295} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{295}The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries COS}}%mdk + +%mdk-data-line={299} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{299}Class of Service. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries device}}%mdk + +%mdk-data-line={301} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{301}Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries entity}}%mdk + +%mdk-data-line={305} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{305}An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries gRPC}}%mdk + +%mdk-data-line={308} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{308}gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +\mdline{309}[\mdcite{grpc}{9}]\mdline{309}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries HA}}%mdk + +%mdk-data-line={311} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{311}High-Availability. Refers to a redundancy architecture. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Instrumentation}}%mdk + +%mdk-data-line={313} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{313}The part of the P4Runtime server which implements the calls to the device or +target native \mdline{314}\textquotedblleft{}SDK\textquotedblright{}\mdline{314} or backend. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries IPC}}%mdk + +%mdk-data-line={316} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{316}Inter-Process Communication. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Blob}}%mdk + +%mdk-data-line={318} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{318}A more colloquial term for P4 Device Config (Blob = Binary Large Object). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Device Config}}%mdk + +%mdk-data-line={320} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{320}The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its \mdline{322}\textquotedblleft{}program.\textquotedblright{}\mdline{322} +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4Info}}%mdk + +%mdk-data-line={324} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{324}Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4RT}}%mdk + +%mdk-data-line={328} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{328}Abbreviation for P4Runtime. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Protobuf (Protocol Buffers)}}%mdk + +%mdk-data-line={330} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{330}The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See\mdline{331}~[\mdcite{proto}{20}]\mdline{331}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries PSA}}%mdk + +%mdk-data-line={333} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{333}Portable Switch Architecture\mdline{333}~[\mdcite{psa}{18}]\mdline{333}; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RPC}}%mdk + +%mdk-data-line={337} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{337}Remote Procedure Call. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RTT}}%mdk + +%mdk-data-line={339} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{339}Round-trip time. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN}}%mdk + +%mdk-data-line={341} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{341}Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network \mdline{346}\emph{controller}\mdline{346}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN port}}%mdk + +%mdk-data-line={348} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{348}A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries server}}%mdk + +%mdk-data-line={352} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{352}The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries stream}}%mdk + +%mdk-data-line={356} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{356}Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (\mdline{357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{357}), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and master-slave arbitration, among other +things. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries switch config}}%mdk + +%mdk-data-line={362} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{362}Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries target}}%mdk + +%mdk-data-line={367} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{367}The hardware or software entity which \mdline{367}\textquotedblleft{}executes\textquotedblright{}\mdline{367} the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with \mdline{368}\textquotedblleft{}device\textquotedblright{}\mdline{368}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries URI}}%mdk + +%mdk-data-line={370} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{370}Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={374} +\section{\mdline{374}3.\hspace*{0.5em}\mdline{374}Reference Architecture}\label{sec-reference-architecture}%mdk%mdk + +%mdk-data-line={376} +\noindent\mdline{376}Figure\mdline{376}~\mdref{fig-reference-architecture}{\mdcaptionlabel{1}}\mdline{376} represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. A multi-master protocol allows more than +one controller to participate, and a role-based arbitration scheme ensures only +one controller has write access to each read/write entity, or the pipeline +config itself. Any controller may perform read access to any entity or the +pipeline config. Later sections describe this in detail. For the sake of +brevity, the term controller may refer to one or more controllers.%mdk + +%mdk-data-line={385} +\mdline{385}The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +\mdline{388}[\mdcite{p4runtimerepo}{14}]\mdline{388}. It may be compiled via protoc\mdline{388} \mdline{388}\textemdash{}\mdline{388} the Protobuf compiler\mdline{388} \mdline{388}\textemdash{}\mdline{388} +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server.%mdk + +%mdk-data-line={393} +\mdline{393}Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository\mdline{394}~[\mdcite{pirepo}{15}]\mdline{394}. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, \mdline{396}e.g.\mdline{396} via callbacks, thus reducing the burden of implementing +P4Runtime.%mdk + +%mdk-data-line={399} +\mdline{399}The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard.%mdk + +%mdk-data-line={403} +\mdline{403}The controller can also set the \mdline{403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{403}, which amounts to +installing and running the compiled P4 program output, which is included in the +\mdline{405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{405} Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +\mdline{407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{407} to retrieve the device config and the P4Info.%mdk + +%mdk-data-line={410} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={411} +\noindent\mdline{411}\includegraphics[keepaspectratio=true,height=7cm]{build/reference-architecture}{}\mdline{411}%mdk + +%mdk-data-line={412} +\mdhr{}%mdk + +%mdk-data-line={413} +\noindent\mdline{413}\mdcaption{\textbf{Figure~\mdcaptionlabel{1}.}~\mdcaptiontext{P4Runtime Reference Architecture.}}%mdk +%mdk +\end{mdcenter}\label{fig-reference-architecture}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={417} +\subsection{\mdline{417}3.1.\hspace*{0.5em}\mdline{417}Idealized Workflow}\label{sec-idealized-workflow}%mdk%mdk + +%mdk-data-line={419} +\noindent\mdline{419}In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the \mdline{420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{420} +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a \mdline{422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{422} +RPC. Metadata in the P4Info describes both the overall program itself +(\mdline{424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{424}) as well as all entity instances derived from the P4 program\mdline{424} \mdline{424}\textemdash{}\mdline{424} +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise \mdline{426}\textquotedblleft{}handle\textquotedblright{}\mdline{426} used in API +calls.%mdk + +%mdk-data-line={429} +\mdline{429}In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible.%mdk + +%mdk-data-line={435} +\mdline{435}In some use cases, it is expected that a controller will store a +collection of multiple P4 \mdline{436}\textquotedblleft{}packages\textquotedblright{}\mdline{436}, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the \mdline{438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{438} from the target via the +\mdline{439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineRequest}}}\mdline{439} RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state.%mdk + +%mdk-data-line={443} +\subsection{\mdline{443}3.2.\hspace*{0.5em}\mdline{443}P4 as a Behavioral Description Language}\label{sec-p4-as-behavioral-description-language}%mdk%mdk + +%mdk-data-line={445} +\noindent\mdline{445}P4 can be considered a behavioral description of a switching device which may or +may not execute \mdline{446}\textquotedblleft{}P4\textquotedblright{}\mdline{446} natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a \mdline{448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineRequest}}}\mdline{448} to +change its pipeline \mdline{449}\textquotedblleft{}program\textquotedblright{}\mdline{449}, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device.%mdk + +%mdk-data-line={455} +\mdline{455}While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API.%mdk + +%mdk-data-line={464} +\mdline{464}In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the \mdline{465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{465} +message as well as the embedded \mdline{466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{466} fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections.%mdk + +%mdk-data-line={470} +\subsection{\mdline{470}3.3.\hspace*{0.5em}\mdline{470}Alternative Workflows}\label{sec-alternative-workflows}%mdk%mdk + +%mdk-data-line={472} +\noindent\mdline{472}Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary.%mdk + +%mdk-data-line={476} +\subsubsection{\mdline{476}3.3.1.\hspace*{0.5em}\mdline{476}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}\label{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}%mdk%mdk + +%mdk-data-line={478} +\noindent\mdline{478}In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +\mdline{480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{480}. The device\mdline{480}'\mdline{480}s configuration might be derived via some other +means to implement the P4 source code\mdline{481}'\mdline{481}s intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane.%mdk + +%mdk-data-line={485} +\subsubsection{\mdline{485}3.3.2.\hspace*{0.5em}\mdline{485}No P4 Source Available, P4Info Available}\label{sec-no-p4-source-available-p4info-available}%mdk%mdk + +%mdk-data-line={487} +\noindent\mdline{487}In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are:%mdk + +%mdk-data-line={490} +\begin{enumerate}%mdk + +%mdk-data-line={490} +\item{} +%mdk-data-line={490} +\mdline{490}The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security.%mdk%mdk + +%mdk-data-line={493} +\item{} +%mdk-data-line={493} +\mdline{493}The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={496} +\noindent\mdline{496}As discussed in Section\mdline{496}~\mdref{sec-p4-as-behavioral-description-language}{3.2}\mdline{496}, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, \mdline{499}e.g.\mdline{499} documentation.%mdk + +%mdk-data-line={501} +\subsubsection{\mdline{501}3.3.3.\hspace*{0.5em}\mdline{501}Partial P4Info and P4 Source are Available}\label{sec-partial-p4info-and-p4-source-are-available}%mdk%mdk + +%mdk-data-line={503} +\noindent\mdline{503}In this situation, a subset of the target\mdline{503}'\mdline{503}s pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code.%mdk + +%mdk-data-line={510} +\subsubsection{\mdline{510}3.3.4.\hspace*{0.5em}\mdline{510}P4Info Role-Based Subsets}\label{sec-p4info-role-based-subsets}%mdk%mdk + +%mdk-data-line={512} +\noindent\mdline{512}In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more.%mdk + +%mdk-data-line={516} +\subsection{\mdline{516}3.4.\hspace*{0.5em}\mdline{516}P4Runtime State Across Restarts}\label{sec-restarts}%mdk%mdk + +%mdk-data-line={518} +\noindent\mdline{518}All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade.%mdk + +%mdk-data-line={524} +\section{\mdline{524}4.\hspace*{0.5em}\mdline{524}Controller Use-cases}\label{sec-controller-use-cases}%mdk%mdk + +%mdk-data-line={526} +\noindent\mdline{526}P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +\mdline{528}\mdref{sec-master-slave-arbitration-and-controller-replication}{section}\mdline{528}. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime\mdline{530}'\mdline{530}s flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex.%mdk + +%mdk-data-line={533} +\subsection{\mdline{533}4.1.\hspace*{0.5em}\mdline{533}Single Embedded Controller}\label{sec-single-embedded-controller}%mdk%mdk + +%mdk-data-line={535} +\noindent\mdline{535}Figure\mdline{535}~\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}}\mdline{535} shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases.%mdk + +%mdk-data-line={540} +\mdline{540}P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC.%mdk + +%mdk-data-line={545} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={546} +\noindent\mdline{546}\includegraphics[keepaspectratio=true,height=6cm]{build/single-embedded-controller}{}\mdline{546}%mdk + +%mdk-data-line={547} +\mdhr{}%mdk + +%mdk-data-line={548} +\noindent\mdline{548}\mdcaption{\textbf{Figure~\mdcaptionlabel{2}.}~\mdcaptiontext{Use-Case: Single Embedded Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-embedded-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={552} +\subsection{\mdline{552}4.2.\hspace*{0.5em}\mdline{552}Single Remote Controller}\label{sec-single-remote-controller}%mdk%mdk + +%mdk-data-line={554} +\noindent\mdline{554}Figure\mdline{554}~\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}}\mdline{554} shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections.%mdk + +%mdk-data-line={559} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={560} +\noindent\mdline{560}\includegraphics[keepaspectratio=true,height=7cm]{build/single-remote-controller}{}\mdline{560}%mdk + +%mdk-data-line={561} +\mdhr{}%mdk + +%mdk-data-line={562} +\noindent\mdline{562}\mdcaption{\textbf{Figure~\mdcaptionlabel{3}.}~\mdcaptiontext{Use-Case: Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={566} +\subsection{\mdline{566}4.3.\hspace*{0.5em}\mdline{566}Embedded\mdline{566} \mdline{566}+ Single Remote Controller}\label{sec-embedded-single-remote-controller}%mdk%mdk + +%mdk-data-line={568} +\noindent\mdline{568}Figure\mdline{568}~\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}}\mdline{568} illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller.%mdk + +%mdk-data-line={575} +\mdline{575}For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables.%mdk + +%mdk-data-line={579} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={580} +\noindent\mdline{580}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-single-remote-controller}{}\mdline{580}%mdk + +%mdk-data-line={581} +\mdhr{}%mdk + +%mdk-data-line={582} +\noindent\mdline{582}\mdcaption{\textbf{Figure~\mdcaptionlabel{4}.}~\mdcaptiontext{Use-Case: Embedded Plus Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={587} +\subsection{\mdline{587}4.4.\hspace*{0.5em}\mdline{587}Embedded\mdline{587} \mdline{587}+ Two Remote Controllers}\label{sec-embedded-two-remote-controllers}%mdk%mdk + +%mdk-data-line={589} +\noindent\mdline{589}Figure\mdline{589}~\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}}\mdline{589} illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +\mdline{592}e.g.\mdline{592} routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership.%mdk + +%mdk-data-line={595} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={596} +\noindent\mdline{596}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-controllers}{}\mdline{596}%mdk + +%mdk-data-line={597} +\mdhr{}%mdk + +%mdk-data-line={598} +\noindent\mdline{598}\mdcaption{\textbf{Figure~\mdcaptionlabel{5}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={603} +\subsection{\mdline{603}4.5.\hspace*{0.5em}\mdline{603}Embedded Controller\mdline{603} \mdline{603}+ Two High-Availability Remote Controllers}\label{sec-embedded-controller-two-high-availability-remote-controllers}%mdk%mdk + +%mdk-data-line={605} +\noindent\mdline{605}Figure\mdline{605}~\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}}\mdline{605} illustrates a single +embedded controller plus two remote controllers in an active-standby HA +(High-Availability) configuration. Controller \mdline{607}\#\mdline{607}1 is the active controller and is +in charge of some entities. If it fails, Controller \mdline{608}\#\mdline{608}2 takes over and manages +the tables formerly owned by Controller \mdline{609}\#\mdline{609}1. The mechanics of HA architectures +are beyond the scope of this document, but the P4Runtime multi-master +arbitration scheme supports it.%mdk + +%mdk-data-line={613} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={614} +\noindent\mdline{614}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-ha-controllers}{}\mdline{614}%mdk + +%mdk-data-line={615} +\mdhr{}%mdk + +%mdk-data-line={616} +\noindent\mdline{616}\mdcaption{\textbf{Figure~\mdcaptionlabel{6}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-ha-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={621} +\section{\mdline{621}5.\hspace*{0.5em}\mdline{621}Master-Slave Arbitration and Controller Replication}\label{sec-master-slave-arbitration-and-controller-replication}%mdk%mdk + +%mdk-data-line={624} +\noindent\mdline{624}The P4Runtime interface allows multiple controllers to be connected to the +P4Runtime server running on the device at the same time for the following +reasons:%mdk + +%mdk-data-line={628} +\begin{enumerate}%mdk + +%mdk-data-line={628} +\item{} +%mdk-data-line={628} +\mdline{628}Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, \mdline{629}\textquotedblleft{}roles\textquotedblright{}\mdline{629} (or \mdline{629}\textquotedblleft{}realms\textquotedblright{}\mdline{629}) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +master and the rest are slaves. Role definition, \mdline{632}i.e.\mdline{632} how P4 entities get +assigned to each role, is \mdline{633}\textbf{out-of-scope}\mdline{633} of this document.%mdk%mdk + +%mdk-data-line={635} +\item{} +%mdk-data-line={635} +\mdline{635}Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby slave controllers. These can already have a connection +open, which can help them become master more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={641} +\noindent\mdline{641}To support multiple controllers, P4Runtime uses the streaming channel (available +via \mdline{642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{642} RPC) for session management. The workflow is described as +follows:%mdk + +%mdk-data-line={645} +\begin{itemize}%mdk + +%mdk-data-line={645} +\item{} +%mdk-data-line={645} +\mdline{645}Each controller instance (\mdline{645}e.g.\mdline{645} a controller process) can participate in one or +more roles. For each (\mdline{646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{646}, \mdline{646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{646}), the controller receives an +\mdline{647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{647}. This \mdline{647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{647} can be the same for different roles and/or +devices, as long as the tuple (\mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{648}, \mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{648}, \mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{648}) is +unique. For each (\mdline{649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{649}, \mdline{649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{649}) that the controller wishes to +control, it establishes a \mdline{650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{650} with the P4Runtime server +responsible for that device, and sends a \mdline{651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{651} message +containing that tuple of (\mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{652}, \mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{652}, \mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{652}) values. The +P4Runtime server selects a master independently for each (\mdline{653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{653}, +\mdline{654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{654}) pair. The master is the client that has the highest \mdline{654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{654} +that the device has ever received for the same (\mdline{655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{655}, +\mdline{656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{656}) values. A connection between a controller instance and a device id +\mdline{657}\textemdash{}\mdline{657} which involves a persistent \mdline{657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{657} \mdline{657}\textemdash{}\mdline{657} can be referred to as a +P4Runtime client.%mdk + +%mdk-data-line={660} +\mdline{660}Note that the P4Runtime server does not assign a \mdline{660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{660} or \mdline{660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{660} to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the \mdline{662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{662} values used for each +\mdline{663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{663}. The P4Runtime server only keeps track of the (\mdline{663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{663}, +\mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{664}, \mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{664}) of each \mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{664} that has sent a successful +\mdline{665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{665} message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +\mdline{667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{667} message to identify which client is making the \mdline{667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{667}, +not only the \mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{668}. This enables controllers to re-use the same +numeric \mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{669} values across different (\mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{669}, \mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{669}) +pairs. P4Runtime does not require \mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{670} values be reused across such +different (\mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{671}, \mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{671}) pairs; it allows it.%mdk%mdk + +%mdk-data-line={673} +\item{} +%mdk-data-line={673} +\mdline{673}To start a controller session, a controller first opens a bidirectional stream +channel to the server via the \mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{674} RPC for each device. This stream +will be used for two purposes:%mdk + +%mdk-data-line={677} +\begin{itemize}%mdk + +%mdk-data-line={677} +\item{} +%mdk-data-line={677} +\mdline{677}\textbf{Session management:}\mdline{677} As soon as the controller opens the stream +channel, it sends a \mdline{678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{678} message to the switch. The +controller populates the \mdline{679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{679} field in this message +using its \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{680} and \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{680}, as well as the \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{680} of the +device. Note that the \mdline{681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{681} field in the \mdline{681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{681} is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below.%mdk%mdk + +%mdk-data-line={685} +\item{} +%mdk-data-line={685} +\mdline{685}\textbf{Streaming of notifications (e.g. digests) and packet I/O:}\mdline{685} The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the master controller can participate in packet +I/O. This feature is explained in more details in the\mdline{689}~\mdref{sec-packet-i_o}{Packet +I/O}\mdline{690} section.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={692} +\mdline{692}Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state.%mdk%mdk + +%mdk-data-line={695} +\item{} +%mdk-data-line={695} +\mdline{695}Note that the stream is opened per device. In case a switching platform has +multiple devices (\mdline{696}e.g.\mdline{696} multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different masters for different +devices. In this case, it is the responsibility of the P4Runtime server to +keep track of the master for each device (and role). More specifically, the +P4Runtime server will know which stream corresponds to the master controller +for each pair of (\mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{701}, \mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{701}) at any point of time.%mdk%mdk + +%mdk-data-line={703} +\item{} +%mdk-data-line={703} +\mdline{703}The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered \mdline{704}\textquotedblleft{}offline\textquotedblright{}\mdline{704} or +\mdline{705}\textquotedblleft{}dead\textquotedblright{}\mdline{705} as soon as its stream channel to the switch is broken. When a master +channel gets broken: (i) an advisory message is sent to all other controllers +for that \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{707} and \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{707}, as described in the +\mdline{708}\mdref{sec-mastership-notification}{following section}\mdline{708} (ii) the P4Runtime server +will be without a master, until a client sends a successful +\mdline{710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{710} (as per the rules in a +\mdline{711}\mdref{sec-mastership-updates}{later section}\mdline{711}).%mdk%mdk + +%mdk-data-line={713} +\item{} +%mdk-data-line={713} +\mdline{713}The mechanism via which the controller receives the P4Runtime server details +which includes the \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{714}, \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip}}}\mdline{714} and \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{714}, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +\mdline{718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{718}) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={723} +\noindent\mdline{723}gRPC enables the server to identify which client originated each message in the +\mdline{724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{724} stream. For example, the C++ gRPC library\mdline{724}~[\mdcite{grpcstreamc}{10}]\mdline{724} in +synchronous mode enables a server process to cause a function to be called when +a new client creates a \mdline{726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{726} stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +\mdline{728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{728} is closed normally (or broken, \mdline{728}e.g.\mdline{728} because a client process +unexpectedly terminated). Thus the server can easily associate all +\mdline{730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{730} messages received from the same client, because they are +processed within the context of the same function call.%mdk + +%mdk-data-line={733} +\mdline{733}A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{738}, \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{738}, and \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{738} in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods\mdline{740}~[\mdcite{grpcauth}{8}]\mdline{740} that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server.%mdk + +%mdk-data-line={744} +\subsection{\mdline{744}5.1.\hspace*{0.5em}\mdline{744}Default Role}\label{sec-default-role}%mdk%mdk + +%mdk-data-line={746} +\noindent\mdline{746}A controller can omit the role message in \mdline{746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{746}. This +implies the \mdline{747}\textquotedblleft{}default role\textquotedblright{}\mdline{747}, which corresponds to \mdline{747}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{747}. This +also implies that a default role has a \mdline{748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{748} of 0 (default). If using a +default role, all RPCs from the controller (\mdline{749}e.g.\mdline{749} \mdline{749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{749}) must set the \mdline{749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{749} +to 0.%mdk + +%mdk-data-line={752} +\subsection{\mdline{752}5.2.\hspace*{0.5em}\mdline{752}Role Config}\label{sec-arbitration-role-config}%mdk%mdk + +%mdk-data-line={754} +\noindent\mdline{754}The \mdline{754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{754} field in the \mdline{754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{754} message sent by the +controller describes the role configuration, \mdline{755}i.e.\mdline{755} which operations are in the +scope of a given role. In particular, the definition of a role may include the +following:%mdk + +%mdk-data-line={759} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={759} +\item\mdline{759}A list of P4 entities for which the controller may issue \mdline{759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{759} updates and +receive notification messages (\mdline{760}e.g.\mdline{760} \mdline{760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{760} and +\mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{761}).%mdk + +%mdk-data-line={762} +\item\mdline{762}Whether the controller is able to receive \mdline{762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{762} messages, along with a +filtering mechanism based on the values of the \mdline{763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{763} fields to +select which \mdline{764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{764} messages should be sent to the controller.%mdk + +%mdk-data-line={765} +\item\mdline{765}Whether the controller is able to send \mdline{765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{765} messages, along with a +filtering mechanism based on the values of the \mdline{766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{766} fields to +select which \mdline{767}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{767} messages are allowed to be sent by the controller.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={769} +\noindent\mdline{769}An unset \mdline{769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{769} implies \mdline{769}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{769} (similar to the default +role explained above). In order to support different role definition schemes, +\mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{771} is defined as an \mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{771} Protobuf message\mdline{771}~[\mdcite{protoany}{30}]\mdline{771}. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion.%mdk + +%mdk-data-line={776} +\mdline{776}It is the job of the P4Runtime server to remember the \mdline{776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{776} for every +\mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{777} and \mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{777} pair.%mdk + +%mdk-data-line={779} +\subsection{\mdline{779}5.3.\hspace*{0.5em}\mdline{779}Rules for Handling \mdline{779}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{779} Messages Received from Controllers}\label{sec-mastership-updates}%mdk%mdk + +%mdk-data-line={781} +\begin{enumerate}%mdk + +%mdk-data-line={781} +\item{} +%mdk-data-line={781} +\mdline{781}If the \mdline{781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{781} message is received for the first time on +this particular channel (\mdline{782}i.e.\mdline{782} for a newly connected controller):%mdk + +%mdk-data-line={784} +\begin{enumerate}%mdk + +%mdk-data-line={784} +\item{} +%mdk-data-line={784} +\mdline{784}If \mdline{784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{784} does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +\mdline{786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{786} error.%mdk%mdk + +%mdk-data-line={788} +\item{} +%mdk-data-line={788} +\mdline{788}If the \mdline{788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{788} is set and is already used by another controller for +the same (\mdline{789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{789}, \mdline{789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{789}), the P4Runtime server shall terminate +the stream by returning an \mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{790} error.%mdk%mdk + +%mdk-data-line={792} +\item{} +%mdk-data-line={792} +\mdline{792}If \mdline{792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{792} does not match the \mdline{792}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{792} scheme previously +agreed upon, the server must return an \mdline{793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{793} error.%mdk%mdk + +%mdk-data-line={795} +\item{} +%mdk-data-line={795} +\mdline{795}If the number of open streams for the given (\mdline{795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{795}, \mdline{795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{795}) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a \mdline{797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{797} error.%mdk%mdk + +%mdk-data-line={799} +\item{} +%mdk-data-line={799} +\mdline{799}Otherwise, the controller is added to a list of connected controllers for +the given (\mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{800}, \mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{800}) and the server remembers the +controllers \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{801}, \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{801} and \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{801} for this gRPC +channel. See below for the rules to determine if this controller becomes +a master or slave, and what notifications are sent as a consequence.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={805} +\item{} +%mdk-data-line={805} +\mdline{805}Otherwise, if the \mdline{805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{805} message is received from an +already connected controller:%mdk + +%mdk-data-line={808} +\begin{enumerate}%mdk + +%mdk-data-line={808} +\item{} +%mdk-data-line={808} +\mdline{808}If the \mdline{808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{808} does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{810} error.%mdk%mdk + +%mdk-data-line={812} +\item{} +%mdk-data-line={812} +\mdline{812}If the \mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{812} does not match the current \mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{812} assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{814} error. If the controller wishes to change its role, +it must close the current stream channel and open a new one.%mdk%mdk + +%mdk-data-line={817} +\item{} +%mdk-data-line={817} +\mdline{817}If \mdline{817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{817} does not match the \mdline{817}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{817} scheme previously +agreed upon, the server must return an \mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{818} error.%mdk%mdk + +%mdk-data-line={820} +\item{} +%mdk-data-line={820} +\mdline{820}If the \mdline{820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{820} is set and is already used by another controller +(excluding the controller making the request) for the same +(\mdline{822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{822}, \mdline{822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{822}), the P4Runtime server shall terminate the stream +by returning an \mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{823} error.%mdk%mdk + +%mdk-data-line={825} +\item{} +%mdk-data-line={825} +\mdline{825}If the \mdline{825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{825} matches the one assigned to this stream:%mdk + +%mdk-data-line={827} +\begin{enumerate}%mdk + +%mdk-data-line={827} +\item{} +%mdk-data-line={827} +\mdline{827}If the controller for this channel is the master, then the server +updates the \mdline{828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{828} to the one specified in the +\mdline{829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{829}. An advisory mastership message is sent to +all controllers for this \mdline{830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{830} and \mdline{830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{830} informing +them of the new \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{831}. Since the format of \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{831} is +out of scope for the P4Runtime specification, the server will send +the advisory message for every update, even if the master sets the +same \mdline{834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{834} as it has before. See the +\mdline{835}\mdref{sec-mastership-notification}{following section}\mdline{835} for the format of +the advisory message.%mdk%mdk + +%mdk-data-line={838} +\item{} +%mdk-data-line={838} +\mdline{838}If the controller is a slave, this is a no-op and the \mdline{838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{838} +is ignored. No response is sent to any controller.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={841} +\item{} +%mdk-data-line={841} +\mdline{841}Otherwise, the server updates the \mdline{841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{841} it has stored for this +controller. This change might cause a change in mastership (this +controller might become master, or the controller might have downgraded +itself to a slave, see below), as well as notifications being sent to one +or more controllers.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={847} +\noindent\mdline{847}If the \mdline{847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{847} is accepted by either of the two steps above +(cases 1.5. and 2.6. above), then the server determines if there are changes in +mastership. Let \mdline{849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{849} be the highest election ID the server has +ever seen for the given \mdline{850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{850} and \mdline{850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{850} (including the one of the +current master if there is one).%mdk + +%mdk-data-line={853} +\begin{enumerate}%mdk + +%mdk-data-line={853} +\item{} +%mdk-data-line={853} +\mdline{853}If \mdline{853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{853} is greater than or equal to \mdline{853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{853}, then the +controller becomes master. The server updates the role configuration to +\mdline{855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{855} for the given \mdline{855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{855}. Furthermore:%mdk + +%mdk-data-line={857} +\begin{enumerate}%mdk + +%mdk-data-line={857} +\item{} +%mdk-data-line={857} +\mdline{857}If there was no master for this \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{857} and \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{857} before and +there are no \mdline{858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{858} requests still processing from a previous master, +then the server immediately sends an advisory notification to all +controllers for this \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{860} and \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{860}. See the +\mdline{861}\mdref{sec-mastership-notification}{following section}\mdline{861} for the format of the +advisory message.%mdk%mdk + +%mdk-data-line={864} +\item{} +%mdk-data-line={864} +\mdline{864}If there was a previous master or \mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{864} requests in flight, then the +server carries out the following steps (in this order):%mdk + +%mdk-data-line={867} +\begin{enumerate}%mdk + +%mdk-data-line={867} +\item{} +%mdk-data-line={867} +\mdline{867}The server stops accepting \mdline{867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{867} requests from the previous master +(if there is one). At this point, the server will reject all \mdline{868}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{868} +requests with \mdline{869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{869}.%mdk%mdk + +%mdk-data-line={871} +\item{} +%mdk-data-line={871} +\mdline{871}The server notifies all controllers other than the new master of the +mastership change by sending the advisory notification described in +the\mdline{873}~\mdref{sec-mastership-notification}{following section}\mdline{873}.%mdk%mdk + +%mdk-data-line={875} +\item{} +%mdk-data-line={875} +\mdline{875}The server will finish processing any \mdline{875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{875} requests that have +already started. If there are errors, they are reported as usual to +the previous master. If the previous master has already disconnected, +any possible errors are dropped and not reported.%mdk%mdk + +%mdk-data-line={880} +\item{} +%mdk-data-line={880} +\mdline{880}The server now accepts the current controller as the new master, thus +accepting \mdline{881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{881} requests from this controller. The server updates +the highest election ID (\mdline{882}i.e.\mdline{882} \mdline{882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{882}) it has seen for +this \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{883} and \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{883} to \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{883}.%mdk%mdk + +%mdk-data-line={885} +\item{} +%mdk-data-line={885} +\mdline{885}The server notifies the new master by sending the advisory message +described in the\mdline{886}~\mdref{sec-mastership-notification}{following section}\mdline{886}.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={888} +\item{} +%mdk-data-line={888} +\mdline{888}Otherwise, the controller becomes a slave. If the controller was previously a +master (and downgraded itself), then an advisory message is sent to all +controllers for this \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{890} and \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{890}. Otherwise, the advisory +message is only sent to the controller that sent the initial +\mdline{892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{892}. See the +\mdline{893}\mdref{sec-mastership-notification}{following section}\mdline{893} for the format of the +advisory message.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={896} +\subsection{\mdline{896}5.4.\hspace*{0.5em}\mdline{896}Mastership Notifications}\label{sec-mastership-notification}%mdk%mdk + +%mdk-data-line={898} +\noindent\mdline{898}For any given \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{898} and \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{898}, any time a new master is chosen, a +master downgrades its status to a slave, a master disconnects, or the +\mdline{900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{900} is updated by the master, all controllers for that +(\mdline{901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{901}, \mdline{901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{901}) are informed of this by sending a +\mdline{902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{902}. The \mdline{902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{902} is populated as follows:%mdk + +%mdk-data-line={904} +\begin{itemize}%mdk + +%mdk-data-line={904} +\item{} +%mdk-data-line={904} +\mdline{904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{904} and \mdline{904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{904} as given.%mdk%mdk + +%mdk-data-line={906} +\item{} +%mdk-data-line={906} +\mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{906} is set to the role configuration the server received most +recently in a \mdline{907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{907} from a master.%mdk%mdk + +%mdk-data-line={909} +\item{} +%mdk-data-line={909} +\mdline{909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{909} is populated as follows:%mdk + +%mdk-data-line={911} +\begin{itemize}%mdk + +%mdk-data-line={911} +\item{} +%mdk-data-line={911} +\mdline{911}If there has not been any master at all, the election\mdline{911}\_\mdline{911}id is left unset.%mdk%mdk + +%mdk-data-line={913} +\item{} +%mdk-data-line={913} +\mdline{913}Otherwise, \mdline{913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{913} is set to the highest election ID that the server +has seen for this \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{914} and \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{914} (which is the \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{914} of +the current master if there is any).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={917} +\item{} +%mdk-data-line={917} +\mdline{917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{917} is set differently based on whether the notification is sent to the +master or a slave controller:%mdk + +%mdk-data-line={920} +\begin{itemize}%mdk + +%mdk-data-line={920} +\item{} +%mdk-data-line={920} +\mdline{920}If there is a master:%mdk + +%mdk-data-line={922} +\begin{itemize}%mdk + +%mdk-data-line={922} +\item{} +%mdk-data-line={922} +\mdline{922}For the master, \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{922} is OK (with \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{922} set to +\mdline{923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.OK}}}\mdline{923}).%mdk%mdk + +%mdk-data-line={925} +\item{} +%mdk-data-line={925} +\mdline{925}For all slave controllers, \mdline{925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{925} is set to non-OK (with +\mdline{926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{926} set to \mdline{926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.ALREADY\_EXISTS}}}\mdline{926}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={928} +\item{} +%mdk-data-line={928} +\mdline{928}Otherwise, if there is no master currently, for all slave controllers, +\mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{929} is set to non-OK (with \mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{929} set to +\mdline{930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.NOT\_FOUND}}}\mdline{930}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={932} +\noindent\mdline{932}Note that on mastership changes with outstanding \mdline{932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{932} request, some +notifications might be delayed, see the +\mdline{934}\mdref{sec-mastership-updates}{previous section}\mdline{934} for details.%mdk + +%mdk-data-line={936} +\section{\mdline{936}6.\hspace*{0.5em}\mdline{936}The P4Info Message}\label{sec-the-p4info-message}%mdk%mdk + +%mdk-data-line={938} +\noindent\mdline{938}The purpose of P4Info was described under +\mdline{939}\mdref{sec-reference-architecture}{Reference Architecture}\mdline{939}. +Here we describe the various +components.%mdk + +%mdk-data-line={943} +\subsection{\mdline{943}6.1.\hspace*{0.5em}\mdline{943}Common Messages}\label{sec-common-messages}%mdk%mdk + +%mdk-data-line={945} +\noindent\mdline{945}These messages appear nested within many other messages.%mdk + +%mdk-data-line={947} +\subsubsection{\mdline{947}6.1.1.\hspace*{0.5em}\mdline{947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{947} Message}\label{sec-documentation-message}%mdk%mdk + +%mdk-data-line={949} +\noindent\mdline{949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{949} is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers.%mdk + +%mdk-data-line={953} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={954} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Documentation~\{\\ +~~{\mdcolor{darkgreen}//~A~brief~description~of~something,~e.g.~one~sentence}\\ +~~{\bfseries{\mdcolor{navy}string}}~brief~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~A~more~verbose~description~of~something.}\\ +~~{\mdcolor{darkgreen}//~Multiline~is~accepted.~Markup~format~(if~any)~is~TBD.}\\ +~~{\bfseries{\mdcolor{navy}string}}~description~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={962} +\subsubsection{\mdline{962}6.1.2.\hspace*{0.5em}\mdline{962}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{962} Message}\label{sec-preamble-message}%mdk%mdk + +%mdk-data-line={964} +\noindent\mdline{964}The preamble serves as the \mdline{964}\textquotedblleft{}descriptor\textquotedblright{}\mdline{964} for each entity and contains the unique +instance ID, name, alias, annotations and documentation.%mdk + +%mdk-data-line={967} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={968} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Preamble~\{\\ +~~{\mdcolor{darkgreen}//~ids~share~the~same~number-space;~e.g.~table~ids~cannot~overlap~with~counter}\\ +~~{\mdcolor{darkgreen}//~ids.~Even~though~this~is~irrelevant~to~this~proto~definition,~the~ids~are}\\ +~~{\mdcolor{darkgreen}//~allocated~in~such~a~way~that~it~is~possible~based~on~an~id~to~deduce~the}\\ +~~{\mdcolor{darkgreen}//~resource~type~(e.g.~table,~action,~counter,~...).~This~means~that~code}\\ +~~{\mdcolor{darkgreen}//~using~these~ids~can~detect~if~the~wrong~resource~type~is~used}\\ +~~{\mdcolor{darkgreen}//~somewhere.~This~also~means~that~ids~of~different~types~can~be~mixed}\\ +~~{\mdcolor{darkgreen}//~(e.g.~direct~resource~list~for~a~table)~without~ambiguity.~Note~that~id~0}\\ +~~{\mdcolor{darkgreen}//~is~reserved~and~means~"invalid~id".}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name~of~the~P4~object,~e.g.~c1.c2.ipv4\_lpm}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~an~alias~(alternative~name)~for~the~P4~object,~probably~shorter~than~its}\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name.~The~only~constraint~is~for~it~to~be~unique~with}\\ +~~{\mdcolor{darkgreen}//~respect~to~other~P4~objects~of~the~same~type.~By~default,~the~compiler~uses}\\ +~~{\mdcolor{darkgreen}//~the~shortest~suffix~of~the~name~that~uniquely~identifies~the~object.~For}\\ +~~{\mdcolor{darkgreen}//~example~if~the~P4~program~contains~two~tables~with~names~s.c1.t~and~s.c2.t,}\\ +~~{\mdcolor{darkgreen}//~the~default~aliases~will~respectively~be~c1.t~and~c2.t.~In~the~future,~the}\\ +~~{\mdcolor{darkgreen}//~P4~programmer~may~also~be~able~to~override~the~default~alias~for~any~P4}\\ +~~{\mdcolor{darkgreen}//~object~(TBD).}\\ +~~{\bfseries{\mdcolor{navy}string}}~alias~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~Documentation~of~the~entity}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={995} +\subsubsection{\mdline{995}6.1.3.\hspace*{0.5em}\mdline{995}Annotating P4 Entities with \mdline{995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}\label{sec-annotating-p4-entities-with-documentation}%mdk%mdk + +%mdk-data-line={997} +\noindent\mdline{997}P4 entities may be annotated using the following annotations:%mdk + +%mdk-data-line={999} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1000} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}(string...)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}(string...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1004} +\noindent\mdline{1004}Attaching either or both of these annotations to an entity will generate a +P4Info\mdline{1005}~\mdref{sec-documentation-message}{Documentation Message}\mdline{1005}, which in turn will +appear in the\mdline{1006}~\mdref{sec-preamble-message}{Preamble Message}\mdline{1006} for the entity.%mdk + +%mdk-data-line={1008} +\mdline{1008}The P4 compiler should not emit \mdline{1008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation}}}\mdline{1008} messages in the P4Info for these +specific cases; instead, it should generate the \mdline{1009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1009} messages as +described.%mdk + +%mdk-data-line={1012} +\mdline{1012}The following example shows documentation annotations for a \mdline{1012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table}}}\mdline{1012} entity:%mdk + +%mdk-data-line={1014} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1015} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port.~\textbackslash{}}\\ +Uses~LPM~match~{\bfseries{\mdcolor{navy}type}}.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}table~my\_ipv4\_lkup~\{}\\ +{\mdcolor{maroon}~~...}\\ +{\mdcolor{maroon}\}}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1023} +\subsection{\mdline{1023}6.2.\hspace*{0.5em}\mdline{1023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1023} Message}\label{sec-pkginfo-message}%mdk%mdk + +%mdk-data-line={1025} +\noindent\mdline{1025}The \mdline{1025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1025} message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. \mdline{1026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1026} can be extracted +and used to facilitate \mdline{1027}\textquotedblleft{}browsing\textquotedblright{}\mdline{1027} of available P4 programs from a +library. Although all fields are technically \mdline{1028}\textquotedblleft{}optional,\textquotedblright{}\mdline{1028} every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included.%mdk + +%mdk-data-line={1032} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1033} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Can~be~used~to~manage~multiple~P4~packages.}\\ +{\bfseries{\mdcolor{navy}message}}~PkgInfo~\{\\ +~~{\mdcolor{darkgreen}//~a~definitive~name~for~this~configuration,~e.g.~switch.p4\_v1.0}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~configuration~version,~free-format~string}\\ +~~{\bfseries{\mdcolor{navy}string}}~version~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~brief~and~detailed~descriptions}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~free-form;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~the~target~architecture,~e.g.~"psa"}\\ +~~{\bfseries{\mdcolor{navy}string}}~arch~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\mdcolor{darkgreen}//~organization~which~produced~the~configuration,~e.g.~"p4.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~organization~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~{\mdcolor{darkgreen}//~contact~info~for~support,e.g.~"tech-support@acme.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~contact~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~url~for~more~information,~e.g.~"http://support.p4.org/ref/p4/switch.p4\_v1.0"}\\ +~~{\bfseries{\mdcolor{navy}string}}~url~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}8};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1054} +\subsubsection{\mdline{1054}6.2.1.\hspace*{0.5em}\mdline{1054}Annotating P4 code with PkgInfo}\label{sec-annotating-p4-code-with-pkginfo}%mdk%mdk + +%mdk-data-line={1056} +\noindent\mdline{1056}A P4 progam\mdline{1056}'\mdline{1056}s \mdline{1056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1056} may be declared using one or more of the following +annotations, attached to the \mdline{1057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1057} block only:%mdk + +%mdk-data-line={1059} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1060} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value{}[,key=value,...])}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("A~brief~description")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("A~longer\textbackslash{}}\\ +description{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@custom\_annotation(...)}\\ +{\mdcolor{maroon}@another\_custom\_annotation(...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1069} +\noindent\mdline{1069}Above we see several different types of annotations:%mdk + +%mdk-data-line={1071} +\begin{itemize}%mdk + +%mdk-data-line={1071} +\item{} +%mdk-data-line={1071} +\mdline{1071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1071} \mdline{1071}- This is used to populate a specific field within the \mdline{1071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1071} +message. Multiple \mdline{1072}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1072} annotations are allowed. For compactness, +multiple key-value pairs can appear in a single \mdline{1073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1073} annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The \mdline{1075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{1075}s must be from +among the message fields inside \mdline{1076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1076}, for example, \mdline{1076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1076}, \mdline{1076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}version}}}\mdline{1076}, +etc. Each key-value pair assigns a value to the corresponding field inside the +single \mdline{1078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1078} message for the program\mdline{1078}'\mdline{1078}s P4Info. One exception is that the +\mdline{1079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1079} field of \mdline{1079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1079} must be expressed as individual +\mdline{1080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1080} and \mdline{1080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1080} annotations, see next bullets. The key \mdline{1080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}arch}}}\mdline{1080} will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself.%mdk%mdk + +%mdk-data-line={1084} +\item{} +%mdk-data-line={1084} +\mdline{1084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1084} \mdline{1084}- This will populate the \mdline{1084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.brief}}}\mdline{1084} message field.%mdk%mdk + +%mdk-data-line={1086} +\item{} +%mdk-data-line={1086} +\mdline{1086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1086} \mdline{1086}- This will populate the \mdline{1086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.description}}}\mdline{1086} message +field%mdk%mdk + +%mdk-data-line={1089} +\item{} +%mdk-data-line={1089} +\mdline{1089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@\textless{}anything~else\textgreater{}}}}\mdline{1089} \mdline{1089}- This will create a \mdline{1089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotation}}}\mdline{1089} entry%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1091} +\noindent\mdline{1091}Declaring one or more of these annotations on \mdline{1091}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1091} will +generate a single corresponding \mdline{1092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1092} message in the P4Info as described in +\mdline{1093}\mdref{sec-pkginfo-message}{PkgInfo Message}\mdline{1093}.%mdk + +%mdk-data-line={1095} +\mdline{1095}The following example shows \mdline{1095}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1095} annotations using a mixture of single and +multiple key-value pairs. It also shows \mdline{1096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1096} and \mdline{1096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1096} annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the \mdline{1098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1098} message. The custom annotations will +be appended to the \mdline{1099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotations}}}\mdline{1099} list.%mdk + +%mdk-data-line={1101} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1102} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(name="switch.p4",version="2")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(organization="p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(contact="info@p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(url="www.p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("L2/L3~switch")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("L2/L3~switch.\textbackslash{}}\\ +Built~for~data-center~profile.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@my\_annotation1(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}@my\_annotation2(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}PSA\_Switch(IgPipeline,~PacketReplicationEngine(),~EgPipeline,}\\ +{\mdcolor{maroon}~~~~~~~~~~~BufferingQueueingEngine())~main;}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1115} +\subsection{\mdline{1115}6.3.\hspace*{0.5em}\mdline{1115}ID Allocation for P4Info Objects}\label{sec-id-allocation}%mdk%mdk + +%mdk-data-line={1117} +\noindent\mdline{1117}P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(\mdline{1121}e.g.\mdline{1121} table, action, counter, \mdline{1121}\dots{}\mdline{1121}). The most significant 8 bits of the ID +encodes the object type (as per Table\mdline{1122}~\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}}\mdline{1122}). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (\mdline{1124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.P4Ids.Prefix}}}\mdline{1124}). These values must +be used (\mdline{1125}e.g.\mdline{1125} by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table\mdline{1127}~\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}}\mdline{1127} shows the ID +layout.%mdk + +%mdk-data-line={1130} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1132} 8-bit prefix value}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1132} P4 object type}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{1134} 0x00}&\multicolumn{1}{|l|}{\mdline{1134} Reserved (unspecified)}\\ +\multicolumn{1}{|l}{\mdline{1135} 0x01}&\multicolumn{1}{|l|}{\mdline{1135} Action}\\ +\multicolumn{1}{|l}{\mdline{1136} 0x02}&\multicolumn{1}{|l|}{\mdline{1136} Table}\\ +\multicolumn{1}{|l}{\mdline{1137} 0x03}&\multicolumn{1}{|l|}{\mdline{1137} Value-set}\\ +\multicolumn{1}{|l}{\mdline{1138} 0x04}&\multicolumn{1}{|l|}{\mdline{1138} Controller header (header type with \mdline{1138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1138} annotation)}\\ +\multicolumn{1}{|l}{\mdline{1139} 0x05\mdline{1139}\dots{}\mdline{1139}0x0f}&\multicolumn{1}{|l|}{\mdline{1139} Reserved (for future P4 built-in objects)}\\ +\multicolumn{1}{|l}{\mdline{1140} 0x10}&\multicolumn{1}{|l|}{\mdline{1140} Reserved (start of PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1141} 0x11}&\multicolumn{1}{|l|}{\mdline{1141} PSA Action profiles / selectors}\\ +\multicolumn{1}{|l}{\mdline{1142} 0x12}&\multicolumn{1}{|l|}{\mdline{1142} PSA Counter}\\ +\multicolumn{1}{|l}{\mdline{1143} 0x13}&\multicolumn{1}{|l|}{\mdline{1143} PSA Direct counter}\\ +\multicolumn{1}{|l}{\mdline{1144} 0x14}&\multicolumn{1}{|l|}{\mdline{1144} PSA Meter}\\ +\multicolumn{1}{|l}{\mdline{1145} 0x15}&\multicolumn{1}{|l|}{\mdline{1145} PSA Direct meter}\\ +\multicolumn{1}{|l}{\mdline{1146} 0x16}&\multicolumn{1}{|l|}{\mdline{1146} PSA Register}\\ +\multicolumn{1}{|l}{\mdline{1147} 0x17}&\multicolumn{1}{|l|}{\mdline{1147} PSA Digest}\\ +\multicolumn{1}{|l}{\mdline{1148} 0x18\mdline{1148}\dots{}\mdline{1148}0x7f}&\multicolumn{1}{|l|}{\mdline{1148} Reserved (for future PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1149} 0x80}&\multicolumn{1}{|l|}{\mdline{1149} Reserved (start of vendor-specific extern types)}\\ +\multicolumn{1}{|l}{\mdline{1150} 0x81\mdline{1150}\dots{}\mdline{1150}0xfe}&\multicolumn{1}{|l|}{\mdline{1150} Vendor-specific extern types}\\ +\multicolumn{1}{|l}{\mdline{1151} 0xff}&\multicolumn{1}{|l|}{\mdline{1151} Reserved (max prefix value)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1153} +\mdhr{}%mdk + +%mdk-data-line={1154} +\noindent\mdline{1154}\mdcaption{\textbf{Table~\mdcaptionlabel{1}.}~\mdcaptiontext{Mapping of P4Info object type to 8-bit ID prefix value}}%mdk +%mdk +\end{mdcenter}\label{tab-mapping-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1157} +\begin{table}[h!]%mdk +\begin{mdblock}{text-align=center,breakable=true}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{cc}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1159} MSB bit 31 \mdline{1159}\dots{}\mdline{1159}\dots{}\mdline{1159}.. bit 24}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1159} bit 23 \mdline{1159}\dots{}\mdline{1159}\dots{}\mdline{1159}\dots{}\mdline{1159}\dots{}\mdline{1159}\dots{}\mdline{1159}\dots{}\mdline{1159}\dots{}\mdline{1159}.. bit 0 LSB}}\\ + +\midrule +\multicolumn{1}{|c}{\mdline{1161} Object type prefix}&\multicolumn{1}{|c|}{\mdline{1161} Generated suffix (\mdline{1161}e.g.\mdline{1161} by the compiler)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1163} +\mdhr{}%mdk + +%mdk-data-line={1164} +\noindent\mdline{1164}\mdcaption{\textbf{Table~\mdcaptionlabel{2}.}~\mdcaptiontext{Format of P4Info object IDs}}%mdk%mdk +\end{mdblock}\label{tab-format-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1168} +\mdline{1168}It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with \mdline{1169}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1169} (see Table +\mdline{1170}\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}}\mdline{1170}). The compiler must honor the \mdline{1170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1170} annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (\mdline{1172}i.e.\mdline{1172} if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same \mdline{1174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1174} value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type.%mdk + +%mdk-data-line={1178} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth-7cm)/1}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{\mdinline{width=7cm}{{\bfseries\mdline{1180} P4 declaration(s)}}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1180} Compiler-allocated ID(s)}}\\ + +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1182} \mdline{1182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1182}}}&\multicolumn{1}{|l|}{\mdline{1182} 0x0212ab34}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1184} \mdline{1184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1184}}}&\multicolumn{1}{|l|}{\mdline{1184} \mdline{1184}\textbf{Error}\mdline{1184}(same ID suffixes for 2 objects of the same type)}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1185} \mdline{1185}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tB...}}}\mdline{1185}}}&\multicolumn{1}{|l|}{\mdline{1185}}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1187} \mdline{1187}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1187}}}&\multicolumn{1}{|l|}{\mdline{1187} 0x0212ab34}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1188} \mdline{1188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~action~act1...}}}\mdline{1188}}}&\multicolumn{1}{|l|}{\mdline{1188} 0x0112ab34}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1190} +\mdhr{}%mdk + +%mdk-data-line={1191} +\noindent\mdline{1191}\mdcaption{\textbf{Table~\mdcaptionlabel{3}.}~\mdcaptiontext{Example of statically-assigned P4Info object IDs}}%mdk +%mdk +\end{mdcenter}\label{tab-exmpl-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1194} +\subsection{\mdline{1194}6.4.\hspace*{0.5em}\mdline{1194}P4Info Objects}\label{sec-p4info-objects}%mdk%mdk + +%mdk-data-line={1196} +\subsubsection{\mdline{1196}6.4.1.\hspace*{0.5em}\mdline{1196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}\label{sec-table}%mdk%mdk + +%mdk-data-line={1198} +\noindent\mdline{1198}Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields:%mdk + +%mdk-data-line={1201} +\begin{itemize}%mdk + +%mdk-data-line={1201} +\item{} +%mdk-data-line={1201} +\mdline{1201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1201}, a \mdline{1201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1201} message with the ID, name, and alias of this table.%mdk%mdk + +%mdk-data-line={1203} +\item{} +%mdk-data-line={1203} +\mdline{1203}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1203}, a repeated field of type \mdline{1203}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1203} representing the data to +be used to construct the lookup key matched in this table. Each \mdline{1204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1204} +message is defined with the following fields:%mdk + +%mdk-data-line={1207} +\begin{itemize}%mdk + +%mdk-data-line={1207} +\item{} +%mdk-data-line={1207} +\mdline{1207}id, the \mdline{1207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1207} identifier of this \mdline{1207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1207}, unique in the scope of +this table. No rules are prescribed on the way \mdline{1208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1208} IDs should be +allocated, as long as two \mdline{1209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1209} of the same table do not have the +same ID. Nonetheless, we recommend that the IDs be assigned incrementally, +starting from 1, in the same order as in the P4 key declaration.%mdk%mdk + +%mdk-data-line={1213} +\item{} +%mdk-data-line={1213} +\mdline{1213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1213}, the string representing the name of this \mdline{1213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1213}.%mdk%mdk + +%mdk-data-line={1215} +\item{} +%mdk-data-line={1215} +\mdline{1215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1215}, a repeated field of strings, each one representing a P4 +annotation associated to this match field.%mdk%mdk + +%mdk-data-line={1218} +\item{} +%mdk-data-line={1218} +\mdline{1218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1218}, an \mdline{1218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1218} value set to the size in bits of this match field.%mdk%mdk + +%mdk-data-line={1220} +\item{} +%mdk-data-line={1220} +\mdline{1220}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1220}, a \mdline{1220}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{1220} describing the match behavior for this field; it can be +either:%mdk + +%mdk-data-line={1222} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1222} +\item\mdline{1222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1222}, an enum field of type \mdline{1222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchType}}}\mdline{1222}, which includes all +possible PSA match kinds.%mdk + +%mdk-data-line={1224} +\item\mdline{1224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_match\_type}}}\mdline{1224}, a string field which can be used to encode any +architecture-specific match type.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1227} +\item{} +%mdk-data-line={1227} +\mdline{1227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1227}, a \mdline{1227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1227} message describing this match field.%mdk%mdk + +%mdk-data-line={1229} +\item{} +%mdk-data-line={1229} +\mdline{1229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1229}, which indicates whether the match field has a\mdline{1229}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1230}; this is useful for +\mdline{1231}\mdref{sec-psa-metadata-translation}{translation}\mdline{1231}.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1233} +\item{} +%mdk-data-line={1233} +\mdline{1233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_refs}}}\mdline{1233}, a repeated \mdline{1233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1233} field representing the set of possible +actions for this table. The \mdline{1234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1234} message is used to reference an action +specified in the same P4Info message and it includes the following fields:%mdk + +%mdk-data-line={1236} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1236} +\item\mdline{1236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1236}, the \mdline{1236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1236} identifier of the action.%mdk + +%mdk-data-line={1237} +\item\mdline{1237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1237}, an enum value which can take one of three values: + \mdline{1238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1238}, \mdline{1238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1238} and \mdline{1238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1238}. The \mdline{1238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1238} of the + action is determined by the use of the P4 standard annotations + \mdline{1240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1240} and \mdline{1240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1240}~[\mdcite{p4actionannotations}{17}]\mdline{1240}. \mdline{1240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1240} + (\mdline{1241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1241} annotation) means that the action can only appear within + the table, and never as the default action. \mdline{1242}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1242} + (\mdline{1243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1243} annotation) means that the action can only be used as the + default action. \mdline{1244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1244} is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action.%mdk + +%mdk-data-line={1247} +\item\mdline{1247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1247}, a repeated string field, each one representing a P4 +annotation associated to the action \mdline{1248}\emph{reference}\mdline{1248} in this table.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1250} +\item{} +%mdk-data-line={1250} +\mdline{1250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\_default\_action\_id}}}\mdline{1250}, if this table has a constant default action, this +field will carry the \mdline{1251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1251} identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action\mdline{1254}'\mdline{1254}s +arguments.%mdk%mdk + +%mdk-data-line={1257} +\item{} +%mdk-data-line={1257} +\mdline{1257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation\_id}}}\mdline{1257}, the \mdline{1257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1257} identifier of the \mdline{1257}\textquotedblleft{}implementation\textquotedblright{}\mdline{1257} of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (\mdline{1260}e.g.\mdline{1260} a PSA \mdline{1260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1260} or \mdline{1260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{1260} +instance). The table is then referred to as an indirect match table.%mdk%mdk + +%mdk-data-line={1263} +\item{} +%mdk-data-line={1263} +\mdline{1263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_resource\_ids}}}\mdline{1263}, repeated \mdline{1263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1263} identifiers for all the direct +resources attached to this table, such as \mdline{1264}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1264} and \mdline{1264}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1264} +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2.%mdk%mdk + +%mdk-data-line={1270} +\item{} +%mdk-data-line={1270} +\mdline{1270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1270}, an \mdline{1270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1270} describing the desired number of table entries that the +target should support for the table. See the \mdline{1271}\textquotedblleft{}Size\textquotedblright{}\mdline{1271} subsection within the +\mdline{1272}\textquotedblleft{}Table Properties\textquotedblright{}\mdline{1272} section of the P4\mdline{1272}\mdsub{16}\mdline{1272} language specification for details +\mdline{1273}[\mdcite{p4tableproperties}{29}]\mdline{1273}.%mdk%mdk + +%mdk-data-line={1275} +\item{} +%mdk-data-line={1275} +\mdline{1275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_behavior}}}\mdline{1275}, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +\mdline{1277}\mdref{sec-idle-timeout}{Idle-Timeout}\mdline{1277} section). Value can be any of the +\mdline{1278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutBehavior}}}\mdline{1278} enum:%mdk + +%mdk-data-line={1279} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1279} +\item\mdline{1279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NO\_TIMEOUT}}}\mdline{1279} (default value), which means that idle timeout is not +supported for this table.%mdk + +%mdk-data-line={1281} +\item\mdline{1281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOTIFY\_CONTROL}}}\mdline{1281}, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +\mdline{1283}\mdref{sec-table-idle-timeout-notification}{Table Idle Timeout Notifications}\mdline{1283}).%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1285} +\item{} +%mdk-data-line={1285} +\mdline{1285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{1285}, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime.%mdk%mdk + +%mdk-data-line={1288} +\item{} +%mdk-data-line={1288} +\mdline{1288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{1288}, an \mdline{1288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1288} Protobuf message\mdline{1288}~[\mdcite{protoany}{30}]\mdline{1288} to embed +architecture-specific table properties\mdline{1289}~[\mdcite{p4tableproperties}{29}]\mdline{1289} which are not part +of the core P4 language or of the PSA architecture.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1292} +\subsubsection{\mdline{1292}6.4.2.\hspace*{0.5em}\mdline{1292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}\label{sec-action}%mdk%mdk + +%mdk-data-line={1294} +\noindent\mdline{1294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1294} messages are used to specify all possible actions of all match-action +tables.%mdk + +%mdk-data-line={1297} +\mdline{1297}The \mdline{1297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1297} message defines the following fields:%mdk + +%mdk-data-line={1299} +\begin{itemize}%mdk + +%mdk-data-line={1299} +\item{} +%mdk-data-line={1299} +\mdline{1299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1299}, a \mdline{1299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1299} message with the ID, name, and alias of this action%mdk%mdk + +%mdk-data-line={1301} +\item{} +%mdk-data-line={1301} +\mdline{1301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{1301}, a repeated field of \mdline{1301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1301} messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each \mdline{1303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1303} message contains the +following fields:%mdk + +%mdk-data-line={1305} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1305} +\item\mdline{1305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1305}, the \mdline{1305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1305} identifier of this parameter. No rules are prescribed +on the way \mdline{1306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1306} IDs should be allocated, as long as two \mdline{1306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1306} of the +same action do not have the same ID. Nonetheless, we recommend that the +IDs be assigned incrementally, starting from 1, in the same order as in +the P4 action declaration.%mdk + +%mdk-data-line={1310} +\item\mdline{1310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1310}, the string representing the name of this parameter.%mdk + +%mdk-data-line={1311} +\item\mdline{1311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1311}, a repeated field of strings, each one representing a P4 +annotation associated to this parameter.%mdk + +%mdk-data-line={1313} +\item\mdline{1313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1313}, an \mdline{1313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1313} value set to the size in bits of this parameter.%mdk + +%mdk-data-line={1314} +\item\mdline{1314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1314}, which describes this parameter using a \mdline{1314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1314} message.%mdk + +%mdk-data-line={1315} +\item\mdline{1315}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1315}, which indicates whether the action parameter has a +\mdline{1316}\mdref{sec-user-defined-types}{user-defined type}\mdline{1316}; this is useful for +\mdline{1317}\mdref{sec-psa-metadata-translation}{translation}\mdline{1317}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1319} +\subsubsection{\mdline{1319}6.4.3.\hspace*{0.5em}\mdline{1319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}\label{sec-p4info-action-profile}%mdk%mdk + +%mdk-data-line={1321} +\noindent\mdline{1321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1321} messages are used to specify all available instances of Action +Profile and Action Selector PSA externs.%mdk + +%mdk-data-line={1324} +\mdline{1324}PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile \mdline{1328}\emph{member}\mdline{1328}, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime.%mdk + +%mdk-data-line={1332} +\mdline{1332}PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into \mdline{1333}\emph{groups}\mdline{1333}. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime.%mdk + +%mdk-data-line={1342} +\mdline{1342}While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same \mdline{1343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1343} message to describe both.%mdk + +%mdk-data-line={1345} +\mdline{1345}The \mdline{1345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1345} message includes the following fields:%mdk + +%mdk-data-line={1347} +\begin{itemize}%mdk + +%mdk-data-line={1347} +\item{} +%mdk-data-line={1347} +\mdline{1347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1347}, a \mdline{1347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1347} message with the ID, name, and alias of this Action +Profile or Selector.%mdk%mdk + +%mdk-data-line={1350} +\item{} +%mdk-data-line={1350} +\mdline{1350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_ids}}}\mdline{1350}, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector.%mdk%mdk + +%mdk-data-line={1353} +\item{} +%mdk-data-line={1353} +\mdline{1353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}with\_selector}}}\mdline{1353}, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern.%mdk%mdk + +%mdk-data-line={1356} +\item{} +%mdk-data-line={1356} +\mdline{1356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1356}, an \mdline{1356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1356} representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups.%mdk%mdk + +%mdk-data-line={1360} +\item{} +%mdk-data-line={1360} +\mdline{1360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1360}, an \mdline{1360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1360} representing the maximum sum of all member +weights within any given selector group, in the case of an Action Selector, or +0 for an Action Profile. PSA programs can use the \mdline{1362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{1362} annotation +to provide this value for Action Selectors. If the annotation is omitted, the +P4Info field will default to 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1366} +\subsubsection{\mdline{1366}6.4.4.\hspace*{0.5em}\mdline{1366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1366} \mdline{1366}\&\mdline{1366} \mdline{1366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}\label{sec-counter-directcounter}%mdk%mdk + +%mdk-data-line={1368} +\noindent\mdline{1368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1368} and \mdline{1368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1368} messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is:%mdk + +%mdk-data-line={1374} +\begin{itemize}%mdk + +%mdk-data-line={1374} +\item{} +%mdk-data-line={1374} +\mdline{1374}Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index.%mdk%mdk + +%mdk-data-line={1378} +\item{} +%mdk-data-line={1378} +\mdline{1378}Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1381} +\noindent\mdline{1381}Both \mdline{1381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1381} and \mdline{1381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1381} messages share the following fields:%mdk + +%mdk-data-line={1383} +\begin{itemize}%mdk + +%mdk-data-line={1383} +\item{} +%mdk-data-line={1383} +\mdline{1383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1383}, a \mdline{1383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1383} message with the ID, name, and alias of this counter +extern instance.%mdk%mdk + +%mdk-data-line={1386} +\item{} +%mdk-data-line={1386} +\mdline{1386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1386}, a message of of type \mdline{1386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1386} used to describe the compile-time +configuration of this counter. Currently, the \mdline{1387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1387} message is used to +carry only the counter unit, which can be any of the \mdline{1388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec.Unit}}}\mdline{1388} enum +values:%mdk + +%mdk-data-line={1390} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1390} +\item\mdline{1390}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1390}: reserved value.%mdk + +%mdk-data-line={1391} +\item\mdline{1391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1391}: byte counter.%mdk + +%mdk-data-line={1392} +\item\mdline{1392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1392}: packet counter.%mdk + +%mdk-data-line={1393} +\item\mdline{1393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BOTH}}}\mdline{1393}: combination of both byte and packet counter.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1395} +\noindent\mdline{1395}For indexed counters, the \mdline{1395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1395} message contains also a \mdline{1395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1395} field, an +\mdline{1396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1396} representing the maximum number of independent values that can be held +by this counter array. Conversely, the \mdline{1397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1397} message contains a +\mdline{1398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1398} field that carries the \mdline{1398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}unit32}}}\mdline{1398} identifier of the table to +which this direct counter is attached.%mdk + +%mdk-data-line={1401} +\mdline{1401}For indexed counters, the \mdline{1401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1401} message contains also an \mdline{1401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1401} +field, which indicates whether the index has a\mdline{1402}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1403}. This is useful for +\mdline{1404}\mdref{sec-psa-metadata-translation}{translation}\mdline{1404}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1405}).%mdk + +%mdk-data-line={1407} +\subsubsection{\mdline{1407}6.4.5.\hspace*{0.5em}\mdline{1407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1407} \mdline{1407}\&\mdline{1407} \mdline{1407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}\label{sec-meter-directmeter}%mdk%mdk + +%mdk-data-line={1409} +\noindent\mdline{1409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1409} and \mdline{1409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1409} messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is:%mdk + +%mdk-data-line={1415} +\begin{itemize}%mdk + +%mdk-data-line={1415} +\item{} +%mdk-data-line={1415} +\mdline{1415}Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +\mdline{1417}e.g.\mdline{1417} to set the rate threshold.%mdk%mdk + +%mdk-data-line={1419} +\item{} +%mdk-data-line={1419} +\mdline{1419}Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1422} +\noindent\mdline{1422}Both \mdline{1422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1422} and \mdline{1422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1422} messages share the following fields:%mdk + +%mdk-data-line={1424} +\begin{itemize}%mdk + +%mdk-data-line={1424} +\item{} +%mdk-data-line={1424} +\mdline{1424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1424}, a \mdline{1424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1424} message with the ID, name, and alias of this meter +extern instance.%mdk%mdk + +%mdk-data-line={1427} +\item{} +%mdk-data-line={1427} +\mdline{1427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1427}, a message of type \mdline{1427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1427} used to describe the capabilities of +this meter extern instance. Currently, the \mdline{1428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1428} message is used to +carry only the meter unit, which can be any of the \mdline{1429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Unit}}}\mdline{1429} enum +values:%mdk + +%mdk-data-line={1431} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1431} +\item\mdline{1431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1431}: reserved value.%mdk + +%mdk-data-line={1432} +\item\mdline{1432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1432}, which signifies that this meter can be configured with rates +expressed in bytes/second.%mdk + +%mdk-data-line={1434} +\item\mdline{1434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1434}, for rates expressed in packets/second.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1436} +\noindent\mdline{1436}For indexed meters, the \mdline{1436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1436} message contains also a \mdline{1436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1436} field, an \mdline{1436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1436} +representing the maximum number of independent cells that can be held by this +meter. Conversely, the \mdline{1438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1438} message contains a \mdline{1438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1438} field +that carries the \mdline{1439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1439} identifier of the table to which this direct meter is +attached.%mdk + +%mdk-data-line={1442} +\mdline{1442}For indexed meters, the \mdline{1442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1442} message contains also an \mdline{1442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1442} +field, which indicates whether the index has a\mdline{1443}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1444}. This is useful for +\mdline{1445}\mdref{sec-psa-metadata-translation}{translation}\mdline{1445}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1446}).%mdk + +%mdk-data-line={1448} +\subsubsection{\mdline{1448}6.4.6.\hspace*{0.5em}\mdline{1448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\label{sec-controller-packet-meta}%mdk%mdk + +%mdk-data-line={1450} +\noindent\mdline{1450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1450} messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server.%mdk + +%mdk-data-line={1456} +\mdline{1456}When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet.%mdk + +%mdk-data-line={1462} +\mdline{1462}Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +\mdline{1464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_in")}}}\mdline{1464} and \mdline{1464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_out")}}}\mdline{1464}, +respectively. \mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1465} messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages).%mdk + +%mdk-data-line={1470} +\mdline{1470}A P4Info message can contain at most two \mdline{1470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata~messages}}}\mdline{1470}, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields:%mdk + +%mdk-data-line={1474} +\begin{itemize}%mdk + +%mdk-data-line={1474} +\item{} +%mdk-data-line={1474} +\mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1474}, a \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1474} message where \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble.name}}}\mdline{1474} is set to \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_in"}}}\mdline{1474} +and \mdline{1475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_out"}}}\mdline{1475} for packet-in and packet-out metadata, respectively.%mdk%mdk + +%mdk-data-line={1477} +\item{} +%mdk-data-line={1477} +\mdline{1477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{1477}, a repeated field of type \mdline{1477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1477}, where each \mdline{1477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1477} message +includes the following fields:%mdk + +%mdk-data-line={1479} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1479} +\item\mdline{1479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1479}, a \mdline{1479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1479} identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two \mdline{1480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1480} of the +same \mdline{1481}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1481} message do not have the same +ID. Nonetheless, if the P4Info message was generated from a P4 compiler, +we recommend that the IDs be assigned incrementally, starting from 1, in +the same order as the fields in the P4 header declaration.%mdk + +%mdk-data-line={1485} +\item\mdline{1485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1485}, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below).%mdk + +%mdk-data-line={1489} +\item\mdline{1489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1489}, a repeated field of strings, each one representing a P4 +annotation associated to this metadata.%mdk + +%mdk-data-line={1491} +\item\mdline{1491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1491}, an \mdline{1491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1491} representing the size in bits of this metadata.%mdk + +%mdk-data-line={1492} +\item\mdline{1492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1492}, which indicates whether the metadata field has a +\mdline{1493}\mdref{sec-user-defined-types}{user-defined type}\mdline{1493}; this is useful for +\mdline{1494}\mdref{sec-psa-metadata-translation}{translation}\mdline{1494}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1496} +\noindent\mdline{1496}As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding \mdline{1497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1497} +messages.%mdk + +%mdk-data-line={1500} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1501} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~egress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~port~where~the~packet}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~should~be~sent~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~queue\_id;~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~queue~ID~}{\mdcolor{darkgreen}*/}\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~ingress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~data~plane~port~ID~where}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~the~original~packet~was~received~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}1}\textgreater{}~is\_clone;~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~1~if~this~is~a~clone~of~the}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~original~packet~}{\mdcolor{darkgreen}*/}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1516} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1517} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868916615}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_out}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_out}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}egress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}queue\_id}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~\}\\ +\}\\ +\\ +controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868941301}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_in}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_in}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ingress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}is\_clone}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}1}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1554} +\noindent\mdline{1554}Note that the use of \mdline{1554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1554} is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages.%mdk + +%mdk-data-line={1560} +\subsubsection{\mdline{1560}6.4.7.\hspace*{0.5em}\mdline{1560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}\label{sec-valueset}%mdk%mdk + +%mdk-data-line={1562} +\noindent\mdline{1562}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1562} messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P4\mdline{1565}\mdsub{16}\mdline{1565} +specification\mdline{1566}~[\mdcite{p4valuesets}{37}]\mdline{1566}.%mdk + +%mdk-data-line={1568} +\mdline{1568}The \mdline{1568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1568} message defines the following fields:%mdk + +%mdk-data-line={1570} +\begin{itemize}%mdk + +%mdk-data-line={1570} +\item{} +%mdk-data-line={1570} +\mdline{1570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1570}, a \mdline{1570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1570} message with the ID, name, and alias of this Value +Set.%mdk%mdk + +%mdk-data-line={1573} +\item{} +%mdk-data-line={1573} +\mdline{1573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1573}, a repeated field of \mdline{1573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1573} messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the \mdline{1576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1576} repeated field in the +\mdline{1577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{1577} message.%mdk%mdk + +%mdk-data-line={1579} +\item{} +%mdk-data-line={1579} +\mdline{1579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1579}, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +\mdline{1581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set}}}\mdline{1581} constructor call.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1583} +\noindent\mdline{1583}According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of \mdline{1586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1586}, +\mdline{1587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1587}, or \mdline{1587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1587}~[\mdcite{p4selectexpr}{25}]\mdline{1587}. The rest of this section looks at all 3 of +these cases and gives an example \mdline{1588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1588} message when appropriate.%mdk + +%mdk-data-line={1590} +\begin{enumerate}%mdk + +%mdk-data-line={1590} +\item{} +%mdk-data-line={1590} +\mdline{1590}If the type parameter is \mdline{1590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1590}, \mdline{1590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1590} will include exactly one +\mdline{1591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1591} message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used):%mdk + +%mdk-data-line={1594} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1594} +\item\mdline{1594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1594}: set to 1%mdk + +%mdk-data-line={1595} +\item\mdline{1595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1595}: set to the value of \mdline{1595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1595}%mdk + +%mdk-data-line={1596} +\item\mdline{1596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1596}: set to \mdline{1596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1596}%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1598} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1599} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}bit\textless{}8\textgreater{}~\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(hdr.f8)~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1602} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1603} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1617} +\begin{enumerate}[,start=2]%mdk + +%mdk-data-line={1617} +\item{} +%mdk-data-line={1617} +\mdline{1617}If the type parameter is a \mdline{1617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1617}, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program.%mdk%mdk + +%mdk-data-line={1622} +\item{} +%mdk-data-line={1622} +\mdline{1622}If the type parameter is a \mdline{1622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1622}, this version of P4Runtime requires that +all the fields of the struct be of type \mdline{1623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1623} (where \mdline{1623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1623} can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +\mdline{1626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1626} field will include one \mdline{1626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1626} message for each field in the +struct, with the following fields:%mdk + +%mdk-data-line={1629} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1629} +\item\mdline{1629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1629}: must be unique with respect to the other \mdline{1629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1629} entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration.%mdk + +%mdk-data-line={1633} +\item\mdline{1633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1633}: set to the name of the corresponding struct field.%mdk + +%mdk-data-line={1634} +\item\mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1634}: set to the list of P4 annotations associated with the struct +field, except for the \mdline{1635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1635} annotation, if present (see the \mdline{1635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1635} field +below).%mdk + +%mdk-data-line={1637} +\item\mdline{1637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1637}: set to the value of \mdline{1637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1637} for the corresponding struct field.%mdk + +%mdk-data-line={1638} +\item\mdline{1638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1638}, which indicates whether the struct field has a\mdline{1638}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1639}; this is useful for +\mdline{1640}\mdref{sec-psa-metadata-translation}{translation}\mdline{1640}.%mdk + +%mdk-data-line={1641} +\item\mdline{1641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1641}: by default \mdline{1641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1641} is set to \mdline{1641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1641}; the P4 programmer can +specify a different match type by using the \mdline{1642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1642} annotation +\mdline{1643}[\mdcite{p4selectexpr}{25}]\mdline{1643}.%mdk + +%mdk-data-line={1644} +\item\mdline{1644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1644}: documentation associated with the struct field.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1646} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1647} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1655} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1656} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1683} +\noindent\mdline{1683}Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a\mdline{1684}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1685} that resolves to a \mdline{1685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1685}, or a \mdline{1685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1685} where +one or more fields is a\mdline{1686}~\mdref{sec-user-defined-types}{user-defined type}\mdline{1686} that +resolves to a \mdline{1687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1687}. For each \mdline{1687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1687} that corresponds to a user-defined +type, the \mdline{1688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1688} field must be set to the appropriate value (\mdline{1688}i.e.\mdline{1688} the name +of the type).%mdk + +%mdk-data-line={1691} +\subsubsection{\mdline{1691}6.4.8.\hspace*{0.5em}\mdline{1691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}\label{sec-register}%mdk%mdk + +%mdk-data-line={1693} +\noindent\mdline{1693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1693} messages are used to specify all possible instances of Register PSA +externs.%mdk + +%mdk-data-line={1696} +\mdline{1696}Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime.%mdk + +%mdk-data-line={1700} +\mdline{1700}The \mdline{1700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1700} message defines the following fields:%mdk + +%mdk-data-line={1702} +\begin{itemize}%mdk + +%mdk-data-line={1702} +\item{} +%mdk-data-line={1702} +\mdline{1702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1702}, a \mdline{1702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1702} message with the ID, name, and alias of this register +instance.%mdk%mdk + +%mdk-data-line={1705} +\item{} +%mdk-data-line={1705} +\mdline{1705}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1705}, which specifies the data type stored by this register, expressed +using a \mdline{1706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1706} message (see section on\mdline{1706}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary +P4 Types}\mdline{1707}).%mdk%mdk + +%mdk-data-line={1709} +\item{} +%mdk-data-line={1709} +\mdline{1709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1709}, an \mdline{1709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1709} value representing the total number of independent register +cells available.%mdk%mdk + +%mdk-data-line={1712} +\item{} +%mdk-data-line={1712} +\mdline{1712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1712}, which indicates whether the register index has a +\mdline{1713}\mdref{sec-user-defined-types}{user-defined type}\mdline{1713}. This is useful for +\mdline{1714}\mdref{sec-psa-metadata-translation}{translation}\mdline{1714}. The underlying built-in type +must be a fixed-width unsigned bitstring (\mdline{1715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1715}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1717} +\subsubsection{\mdline{1717}6.4.9.\hspace*{0.5em}\mdline{1717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}\label{sec-digest}%mdk%mdk + +%mdk-data-line={1719} +\noindent\mdline{1719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1719} messages are used to specify all possible instances of Packet Digest +PSA externs.%mdk + +%mdk-data-line={1722} +\mdline{1722}A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages.%mdk + +%mdk-data-line={1731} +\mdline{1731}The \mdline{1731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1731} message defines the following fields:%mdk + +%mdk-data-line={1733} +\begin{itemize}%mdk + +%mdk-data-line={1733} +\item{} +%mdk-data-line={1733} +\mdline{1733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1733}, a \mdline{1733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1733} message with the ID, name, and alias of this digest +instance.%mdk%mdk + +%mdk-data-line={1736} +\item{} +%mdk-data-line={1736} +\mdline{1736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1736}, which specifies the data type of an individual digest +notification using a \mdline{1737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1737} message (see section on\mdline{1737}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation +of Arbitrary P4 Types}\mdline{1738}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1740} +\subsubsection{\mdline{1740}6.4.10.\hspace*{0.5em}\mdline{1740}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}\label{sec-p4info-extern}%mdk%mdk + +%mdk-data-line={1742} +\noindent\mdline{1742}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1742} messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one \mdline{1745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1745} message instance in P4Info. The \mdline{1745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1745} message defines +the following fields:%mdk + +%mdk-data-line={1748} +\begin{itemize}%mdk + +%mdk-data-line={1748} +\item{} +%mdk-data-line={1748} +\mdline{1748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{1748}, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the\mdline{1749}~\mdref{sec-id-allocation}{reserved +range}\mdline{1750} \mdline{1750}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{}[0x81,~0xfe]}}}\mdline{1750}. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture.%mdk%mdk + +%mdk-data-line={1755} +\item{} +%mdk-data-line={1755} +\mdline{1755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_name}}}\mdline{1755}, which specifies the fully-qualified P4 name of the extern +type.%mdk%mdk + +%mdk-data-line={1758} +\item{} +%mdk-data-line={1758} +\mdline{1758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instances}}}\mdline{1758}, a repeated field of \mdline{1758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{1758} Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +\mdline{1760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{1760} in turn defines the following fields:%mdk + +%mdk-data-line={1762} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1762} +\item\mdline{1762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1762}, a \mdline{1762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1762} message with the ID, name, and alias of this digest +instance.%mdk + +%mdk-data-line={1764} +\item\mdline{1764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{1764}, an \mdline{1764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1764} Protobuf message\mdline{1764}~[\mdcite{protoany}{30}]\mdline{1764} which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for \mdline{1766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{1766} should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on\mdline{1768}~\mdref{sec-extending-p4runtime}{Extending +P4Runtime for non-PSA Architectures}\mdline{1769} for more +information.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1772} +\noindent\mdline{1772}If the P4 program does not include any instance of a given extern type, the +\mdline{1773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1773} message instance for that type should be omitted from the P4Info.%mdk + +%mdk-data-line={1775} +\subsection{\mdline{1775}6.5.\hspace*{0.5em}\mdline{1775}Support for Arbitrary P4 Types with P4TypeInfo}\label{sec-support-for-arbitrary-p4-types-with-p4typeinfo}%mdk%mdk + +%mdk-data-line={1777} +\noindent\mdline{1777}See section on\mdline{1777}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary P4 +Types}\mdline{1778}.%mdk + +%mdk-data-line={1780} +\section{\mdline{1780}7.\hspace*{0.5em}\mdline{1780}P4 Forwarding-Pipeline Configuration}\label{sec-p4-fwd-pipe-config}%mdk%mdk + +%mdk-data-line={1782} +\noindent\mdline{1782}The \mdline{1782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{1782} captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the \mdline{1784}\textquotedblleft{}Device Configuration\textquotedblright{}\mdline{1784} and sometimes also referred to as +the \mdline{1785}\textquotedblleft{}P4 Blob\textquotedblright{}\mdline{1785}. It is defined as:%mdk + +%mdk-data-line={1787} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1788} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ForwardingPipelineConfig~\{\\ +~~config.P{\mdcolor{purple}4}Info~p4info~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~p4\_device\_config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}message}}~Cookie~\{\\ +~~~~{\bfseries{\mdcolor{navy}uint64}}~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~\}\\ +~~Cookie~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1798} +\noindent\mdline{1798}The \mdline{1798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{1798} field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic.%mdk + +%mdk-data-line={1801} +\mdline{1801}The \mdline{1801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{1801} is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new \mdline{1803}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{1803} on that target.%mdk + +%mdk-data-line={1805} +\mdline{1805}The \mdline{1805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{1805} field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a \mdline{1810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{1810} RPC. +When writing the config via a \mdline{1811}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{1811} RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present.%mdk + +%mdk-data-line={1815} +\section{\mdline{1815}8.\hspace*{0.5em}\mdline{1815}General Principles for Message Formatting}\label{sec-general-principles-for-message-formatting}%mdk%mdk + +%mdk-data-line={1817} +\subsection{\mdline{1817}8.1.\hspace*{0.5em}\mdline{1817}Set / Unset Protobuf Field}\label{sec-set-unset-protobuf-field}%mdk%mdk + +%mdk-data-line={1819} +\noindent\mdline{1819}In Protobuf version 3 (\mdline{1819}\emph{proto3}\mdline{1819}), the default value for a message field is +\mdline{1820}\textquotedblleft{}unset\textquotedblright{}\mdline{1820}~[\mdcite{protodefaults}{4}]\mdline{1820}. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +\mdline{1825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{1825} message, an \mdline{1825}\textquotedblleft{}unset\textquotedblright{}\mdline{1825} \mdline{1825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1825} field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the \mdline{1827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1827} message field is +set, a single entry will be read.%mdk + +%mdk-data-line={1830} +\mdline{1830}Let\mdline{1830}'\mdline{1830}s look at the counter example in more details. Based on this specification +document, the C++ server code which processes \mdline{1831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{1831} messages may look +like this:%mdk + +%mdk-data-line={1833} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1834} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}auto}}~*counter\_entry~=~...\\ +{\bfseries{\mdcolor{navy}if}}~(counter\_entry-\textgreater{}has\_index())~\{\\ +~~{\bfseries{\mdcolor{navy}auto}}~index~=~counter\_entry-\textgreater{}index().index();\\ +~~read\_one\_entry(counter\_entry-\textgreater{}id(),~index);\\ +\}~{\bfseries{\mdcolor{navy}else}}~\{\\ +~~read\_all\_entries(counter\_entry-\textgreater{}id());\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1843} +\begin{enumerate}%mdk + +%mdk-data-line={1843} +\item{} +%mdk-data-line={1843} +\mdline{1843}Reading a single counter entry at index 0 in the counter array with id +\mdline{1844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textless{}id\textgreater{}}}}\mdline{1844}:%mdk + +%mdk-data-line={1845} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1845} +\item\mdline{1845}Here is the C++ client code: + +%mdk-data-line={1846} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1847} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});\\ +entry.mutable\_index();\\ +{\mdcolor{darkgreen}//~The~above~line~sets~the~index~field;~it~is~equivalent~to:}\\ +{\mdcolor{darkgreen}//~auto~*index~=~entry.mutable\_index();}\\ +{\mdcolor{darkgreen}//~index-\textgreater{}set\_index(0);}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={1854} +\item\mdline{1854}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={1855} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1856} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}\\ +index~\{\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={1859} +\item\mdline{1859}\textbf{Expected behavior}\mdline{1859}: Counter entry at index 0 is read. Notice that the +\mdline{1860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1860} subfield is missing under the \mdline{1860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1860} field message of +\mdline{1861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{1861} in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1866} +\item{} +%mdk-data-line={1866} +\mdline{1866}Reading all counter entries by leaving the \mdline{1866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1866} field unset%mdk + +%mdk-data-line={1867} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1867} +\item\mdline{1867}Here is the C++ client code: + +%mdk-data-line={1868} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1869} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={1872} +\item\mdline{1872}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={1873} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1874} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={1876} +\item\mdline{1876}\textbf{Expected behavior}\mdline{1876}: All counter entries for the provided counter +instance are read. Notice that the \mdline{1877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1877} message field is unset (default +value) and is therefore omitted from the textual representation of the +message.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1881} +\subsection{\mdline{1881}8.2.\hspace*{0.5em}\mdline{1881}Read-Write Symmetry}\label{sec-read-write-symmetry}%mdk%mdk + +%mdk-data-line={1883} +\noindent\mdline{1883}The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example:%mdk + +%mdk-data-line={1889} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1890} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}intended\_value~=~value\\ +\\ +status~=~server.write(intended\_value,~p4\_entity)\\ +observed\_value~=~server.read(p4\_entity)\\ +\\ +assert(intended\_value~==~observed\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1898} +\noindent\mdline{1898}To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If \mdline{1902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{1902} RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol\mdline{1905}'\mdline{1905}s complexities to the client implementations.%mdk + +%mdk-data-line={1907} +\mdline{1907}In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the \mdline{1910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1910} fields in a \mdline{1910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{1910} message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +\mdline{1913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MessageDifferencer}}}\mdline{1913} class\mdline{1913}~[\mdcite{protomessagedifferencer}{35}]\mdline{1913} included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance.%mdk + +%mdk-data-line={1918} +\subsection{\mdline{1918}8.3.\hspace*{0.5em}\mdline{1918}Zero as Reserved Value}\label{sec-zero-as-reserved-value}%mdk%mdk + +%mdk-data-line={1920} +\noindent\mdline{1920}p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a \mdline{1921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1921}. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a \mdline{1924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{1924} or a \mdline{1924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfigRequest}}}\mdline{1924}.%mdk + +%mdk-data-line={1926} +\subsection{\mdline{1926}8.4.\hspace*{0.5em}\mdline{1926}Bytestrings}\label{sec-bytestrings}%mdk%mdk + +%mdk-data-line={1928} +\noindent\mdline{1928}P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (\mdline{1930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1930}) or signed (\mdline{1930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1930}), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +\mdline{1933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{1933} Protobuf type. The correct bitwidth\mdline{1933} \mdline{1933}\textemdash{}\mdline{1933} as per the P4 program\mdline{1933} \mdline{1933}\textemdash{}\mdline{1933} of +each integer variable exposed through P4Runtime is specified in the P4Info +message.%mdk + +%mdk-data-line={1937} +\mdline{1937}The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals:%mdk + +%mdk-data-line={1940} +\begin{itemize}%mdk + +%mdk-data-line={1940} +\item{} +%mdk-data-line={1940} +\mdline{1940}It ensures that a properly encoded binary string\mdline{1940}'\mdline{1940}s integer value conforms +to the P4Info-specified bitwidth.%mdk%mdk + +%mdk-data-line={1943} +\item{} +%mdk-data-line={1943} +\mdline{1943}It supports\mdline{1943}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{1943}.%mdk%mdk + +%mdk-data-line={1945} +\item{} +%mdk-data-line={1945} +\mdline{1945}It helps facilitate non-disruptive P4 program updates.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1947} +\noindent\mdline{1947}In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type \mdline{1952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1952} and/or \mdline{1952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1952}.%mdk + +%mdk-data-line={1954} +\mdline{1954}Note that this representation does \mdline{1954}\emph{not}\mdline{1954} make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range.%mdk + +%mdk-data-line={1963} +\mdline{1963}In the P4Runtime API version 1.0, values of table key fields, action parameters, +and fields in packet-in and packet-out headers between a device and the +controller (see\mdline{1965}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{1965}), may not be of type \mdline{1965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1965}. +The rules for encoding signed values thus only apply to messages of type +\mdline{1967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{1967} (see\mdline{1967}~\mdref{sec-p4data-in-p4runtime-proto}{8.5.3}\mdline{1967}).%mdk + +%mdk-data-line={1969} +\mdline{1969}For a value of type \mdline{1969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1969}, the fewest number of bits required to represent +the integer value \mdline{1970}$V > 0$\mdline{1970} is the smallest integer \mdline{1970}$A$\mdline{1970} such that \mdline{1970}$V \leq 2^A -1$\mdline{1971}.%mdk + +%mdk-data-line={1973} +\mdline{1973}For a value of type \mdline{1973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1973}, the fewest number of bits required to represent +the integer value \mdline{1974}$V \neq 0$\mdline{1974} in 2\mdline{1974}'\mdline{1974}s complement form is the smallest integer \mdline{1974}$A$\mdline{1974} +such that \mdline{1975}$-2^{A-1} \leq V \leq 2^{A-1} - 1$\mdline{1975}.%mdk + +%mdk-data-line={1977} +\mdline{1977}As a special case, define that the value \mdline{1977}$V=0$\mdline{1977} requires at least \mdline{1977}$A=1$\mdline{1977} bit to +represent, regardless of whether it is signed or unsigned.%mdk + +%mdk-data-line={1980} +\mdline{1980}The shortest possible binary string for an integer \mdline{1980}$V$\mdline{1980} that needs \mdline{1980}$A$\mdline{1980} bits to +represent it is computed as:%mdk + +%mdk-data-line={1982} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1983} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size~=~floor(({\mdcolor{teal}A}~+~{\mdcolor{purple}7})~/~{\mdcolor{purple}8})}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1986} +\noindent\mdline{1986}Binary strings with the byte length computed as \mdline{1986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{1986} promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies.%mdk + +%mdk-data-line={1990} +\mdline{1990}Any additional bits in the bytes sent for an unsigned integer value (type +\mdline{1991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1991}) must be 0. If additional bytes are transmitted above the +\mdline{1992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{1992} minimum required, they must be filled with 0.%mdk + +%mdk-data-line={1994} +\mdline{1994}Any additional bits in the bytes sent for a signed integer value (type \mdline{1994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1994}) +must be copies of the sign bit, \mdline{1995}i.e.\mdline{1995} 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +\mdline{1997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{1997} minimum required, they must be filled with copies of the +sign bit, \mdline{1998}i.e.\mdline{1998} 0 for non-negative values, or 0xff for negative values. In 2\mdline{1998}'\mdline{1998}s +complement representation, this is called \mdline{1999}\textquotedblleft{}sign extension\textquotedblright{}\mdline{1999}, and leaves the +numeric value represented unchanged.%mdk + +%mdk-data-line={2002} +\mdline{2002}Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value.%mdk + +%mdk-data-line={2008} +\mdline{2008}For a received bitstring expected to fit within a \mdline{2008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2008} type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring\mdline{2010}'\mdline{2010}s width is \mdline{2010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2010} bits or less.%mdk + +%mdk-data-line={2012} +\mdline{2012}For a received bitstring expected to fit within an \mdline{2012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2012} type, the value it +represents is in range if, after \mdline{2013}\textquotedblleft{}undoing sign extension\textquotedblright{}\mdline{2013}, the remaining bit +string\mdline{2014}'\mdline{2014}s width is \mdline{2014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2014} bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other.%mdk + +%mdk-data-line={2020} +\mdline{2020}If the string\mdline{2020}'\mdline{2020}s byte length is zero, the server always rejects the string.%mdk + +%mdk-data-line={2022} +\mdline{2022}When the server rejects a binary string due to any of the previous criteria, +it returns an \mdline{2023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2023} error.%mdk + +%mdk-data-line={2025} +\mdline{2025}For all binary strings, P4Runtime uses big-endian (\mdline{2025}i.e.\mdline{2025} network) byte-order. +For signed integer values (\mdline{2026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2026} P4 type), P4Runtime uses the same two\mdline{2026}'\mdline{2026}s +complement bitwise representation as P4. Table\mdline{2027}~\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}}\mdline{2027} +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above.%mdk + +%mdk-data-line={2031} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2033} P4 type}}&\multicolumn{1}{|c}{{\bfseries\mdline{2033} Integer value}}&\multicolumn{1}{|c}{{\bfseries\mdline{2033} P4Runtime binary string}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2033} Read-write symmetry}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2035} \mdline{2035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2035}}&\multicolumn{1}{|l}{\mdline{2035} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2035} \mdline{2035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2035}}&\multicolumn{1}{|l|}{\mdline{2035} yes}\\ +\multicolumn{1}{|l}{\mdline{2036} \mdline{2036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2036}}&\multicolumn{1}{|l}{\mdline{2036} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2036} \mdline{2036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2036}}&\multicolumn{1}{|l|}{\mdline{2036} no}\\ +\multicolumn{1}{|l}{\mdline{2037} \mdline{2037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2037}}&\multicolumn{1}{|l}{\mdline{2037} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2037} \mdline{2037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2037}}&\multicolumn{1}{|l|}{\mdline{2037} yes}\\ +\multicolumn{1}{|l}{\mdline{2038} \mdline{2038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2038}}&\multicolumn{1}{|l}{\mdline{2038} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2038} \mdline{2038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x30\textbackslash{}x64}}}\mdline{2038}}&\multicolumn{1}{|l|}{\mdline{2038} yes}\\ +\multicolumn{1}{|l}{\mdline{2039} \mdline{2039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2039}}&\multicolumn{1}{|l}{\mdline{2039} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2039} \mdline{2039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x30\textbackslash{}x64}}}\mdline{2039}}&\multicolumn{1}{|l|}{\mdline{2039} no}\\ +\multicolumn{1}{|l}{\mdline{2040} \mdline{2040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2040}}&\multicolumn{1}{|l}{\mdline{2040} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2040} \mdline{2040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2040}}&\multicolumn{1}{|l|}{\mdline{2040} no}\\ +\multicolumn{1}{|l}{\mdline{2041} \mdline{2041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2041}}&\multicolumn{1}{|l}{\mdline{2041} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2041} \mdline{2041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2041}}&\multicolumn{1}{|l|}{\mdline{2041} yes}\\ +\multicolumn{1}{|l}{\mdline{2042} \mdline{2042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2042}}&\multicolumn{1}{|l}{\mdline{2042} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2042} \mdline{2042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00\textbackslash{}x63}}}\mdline{2042}}&\multicolumn{1}{|l|}{\mdline{2042} no}\\ +\multicolumn{1}{|l}{\mdline{2043} \mdline{2043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2043}}&\multicolumn{1}{|l}{\mdline{2043} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2043} \mdline{2043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2043}}&\multicolumn{1}{|l|}{\mdline{2043} yes}\\ +\multicolumn{1}{|l}{\mdline{2044} \mdline{2044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2044}}&\multicolumn{1}{|l}{\mdline{2044} \mdline{2044}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2044} \mdline{2044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x9d}}}\mdline{2044}}&\multicolumn{1}{|l|}{\mdline{2044} yes}\\ +\multicolumn{1}{|l}{\mdline{2045} \mdline{2045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2045}}&\multicolumn{1}{|l}{\mdline{2045} \mdline{2045}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2045} \mdline{2045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xff\textbackslash{}x9d}}}\mdline{2045}}&\multicolumn{1}{|l|}{\mdline{2045} no}\\ +\multicolumn{1}{|l}{\mdline{2046} \mdline{2046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2046}}&\multicolumn{1}{|l}{\mdline{2046} \mdline{2046}-739 (-0x2e3)}&\multicolumn{1}{|l}{\mdline{2046} \mdline{2046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xfd\textbackslash{}x1d}}}\mdline{2046}}&\multicolumn{1}{|l|}{\mdline{2046} yes}\\ +\multicolumn{1}{|l}{\mdline{2047} \mdline{2047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2047}}&\multicolumn{1}{|l}{\mdline{2047} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2047} \mdline{2047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00}}}\mdline{2047}}&\multicolumn{1}{|l|}{\mdline{2047} no}\\ +\multicolumn{1}{|l}{\mdline{2048} \mdline{2048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2048}}&\multicolumn{1}{|l}{\mdline{2048} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2048} \mdline{2048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00}}}\mdline{2048}}&\multicolumn{1}{|l|}{\mdline{2048} yes}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2050} +\mdhr{}%mdk + +%mdk-data-line={2051} +\noindent\mdline{2051}\mdcaption{\textbf{Table~\mdcaptionlabel{4}.}~\mdcaptiontext{Examples of Valid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-valid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2053} +\mdline{2053}Table\mdline{2053}~\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}}\mdline{2053} shows some examples of invalid +P4Runtime binary strings:%mdk + +%mdk-data-line={2056} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2058} P4 type}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2058} P4Runtime binary string}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2060} \mdline{2060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2060}}&\multicolumn{1}{|l|}{\mdline{2060} \mdline{2060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x63}}}\mdline{2060}}\\ +\multicolumn{1}{|l}{\mdline{2061} \mdline{2061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2061}}&\multicolumn{1}{|l|}{\mdline{2061} \mdline{2061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2061}}\\ +\multicolumn{1}{|l}{\mdline{2062} \mdline{2062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2062}}&\multicolumn{1}{|l|}{\mdline{2062} \mdline{2062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2062}}\\ +\multicolumn{1}{|l}{\mdline{2063} \mdline{2063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2063}}&\multicolumn{1}{|l|}{\mdline{2063} \mdline{2063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x10\textbackslash{}x63}}}\mdline{2063}}\\ +\multicolumn{1}{|l}{\mdline{2064} \mdline{2064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2064}}&\multicolumn{1}{|l|}{\mdline{2064} \mdline{2064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2064}}\\ +\multicolumn{1}{|l}{\mdline{2065} \mdline{2065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2065}}&\multicolumn{1}{|l|}{\mdline{2065} \mdline{2065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x40\textbackslash{}x63}}}\mdline{2065}}\\ +\multicolumn{1}{|l}{\mdline{2066} \mdline{2066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2066}}&\multicolumn{1}{|l|}{\mdline{2066} \mdline{2066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x9d}}}\mdline{2066}}\\ +\multicolumn{1}{|l}{\mdline{2067} \mdline{2067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2067}}&\multicolumn{1}{|l|}{\mdline{2067} \mdline{2067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x8d\textbackslash{}x1d}}}\mdline{2067}}\\ +\multicolumn{1}{|l}{\mdline{2068} \mdline{2068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2068}}&\multicolumn{1}{|l|}{\mdline{2068} \mdline{2068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2068}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2070} +\mdhr{}%mdk + +%mdk-data-line={2071} +\noindent\mdline{2071}\mdcaption{\textbf{Table~\mdcaptionlabel{5}.}~\mdcaptiontext{Examples of Invalid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-invalid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2073} +\mdline{2073}As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from \mdline{2078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2078} to \mdline{2078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2078}, a server +running the \mdline{2079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2079} version of the P4 program will accept requests from +clients that remain on the \mdline{2080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2080} P4Runtime version.%mdk + +%mdk-data-line={2082} +\mdline{2082}Despite the server\mdline{2082}'\mdline{2082}s binary string flexibility for P4 program update support, +the client and server must both remain aware of the +\mdline{2084}\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2084} +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values.%mdk + +%mdk-data-line={2089} +\mdline{2089}Representation of variable-length integer values (\mdline{2089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2089} P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the \mdline{2091}\emph{dynamic-length}\mdline{2091} of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an \mdline{2094}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2094} error code otherwise.%mdk + +%mdk-data-line={2096} +\subsection{\mdline{2096}8.5.\hspace*{0.5em}\mdline{2096}Representation of Arbitrary P4 Types}\label{sec-representation-of-arbitrary-p4-types}%mdk%mdk + +%mdk-data-line={2098} +\subsubsection{\mdline{2098}8.5.1.\hspace*{0.5em}\mdline{2098}Problem Statement}\label{sec-problem-statement}%mdk%mdk + +%mdk-data-line={2100} +\noindent\mdline{2100}The P4\mdline{2100}\mdsub{16}\mdline{2100} language includes more complex types than just binary strings +\mdline{2101}[\mdcite{p4complextypes}{3}]\mdline{2101}. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table\mdline{2104}~\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}}\mdline{2104} shows the different +P4\mdline{2105}\mdsub{16}\mdline{2105} types and how they are allowed to be used, as per the P4\mdline{2105}\mdsub{16}\mdline{2105} +specification.%mdk + +%mdk-data-line={2108} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|l}{{\bfseries\mdline{2110}}}&\multicolumn{3}{|c|}{{\bfseries\mdline{2110} Container type}}\\ +\cmidrule{2-2}\cmidrule{3-3}\cmidrule{4-4} +\multicolumn{1}{|l}{{\bfseries\mdline{2112} Element type}}&\multicolumn{1}{|l}{{\bfseries\mdline{2112} header}}&\multicolumn{1}{|l}{{\bfseries\mdline{2112} header\mdline{2112}\_\mdline{2112}union}}&\multicolumn{1}{|l|}{{\bfseries\mdline{2112} struct or tuple}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2114} \mdline{2114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2114}}&\multicolumn{1}{|l}{\mdline{2114} allowed}&\multicolumn{1}{|l}{\mdline{2114} error}&\multicolumn{1}{|l|}{\mdline{2114} allowed}\\ +\multicolumn{1}{|l}{\mdline{2115} \mdline{2115}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2115}}&\multicolumn{1}{|l}{\mdline{2115} allowed}&\multicolumn{1}{|l}{\mdline{2115} error}&\multicolumn{1}{|l|}{\mdline{2115} allowed}\\ +\multicolumn{1}{|l}{\mdline{2116} \mdline{2116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2116}}&\multicolumn{1}{|l}{\mdline{2116} allowed}&\multicolumn{1}{|l}{\mdline{2116} error}&\multicolumn{1}{|l|}{\mdline{2116} allowed}\\ +\multicolumn{1}{|l}{\mdline{2117} \mdline{2117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int}}}\mdline{2117}}&\multicolumn{1}{|l}{\mdline{2117} error}&\multicolumn{1}{|l}{\mdline{2117} error}&\multicolumn{1}{|l|}{\mdline{2117} error}\\ +\multicolumn{1}{|l}{\mdline{2118} \mdline{2118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}void}}}\mdline{2118}}&\multicolumn{1}{|l}{\mdline{2118} error}&\multicolumn{1}{|l}{\mdline{2118} error}&\multicolumn{1}{|l|}{\mdline{2118} error}\\ +\multicolumn{1}{|l}{\mdline{2119} \mdline{2119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2119}}&\multicolumn{1}{|l}{\mdline{2119} error}&\multicolumn{1}{|l}{\mdline{2119} error}&\multicolumn{1}{|l|}{\mdline{2119} allowed}\\ +\multicolumn{1}{|l}{\mdline{2120} \mdline{2120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_kind}}}\mdline{2120}}&\multicolumn{1}{|l}{\mdline{2120} error}&\multicolumn{1}{|l}{\mdline{2120} error}&\multicolumn{1}{|l|}{\mdline{2120} error}\\ +\multicolumn{1}{|l}{\mdline{2121} \mdline{2121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2121}}&\multicolumn{1}{|l}{\mdline{2121} error}&\multicolumn{1}{|l}{\mdline{2121} error}&\multicolumn{1}{|l|}{\mdline{2121} allowed}\\ +\multicolumn{1}{|l}{\mdline{2122} \mdline{2122}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2122}}&\multicolumn{1}{|l}{\mdline{2122} allowed\mdline{2122}\mdfootnote{1}{%mdk-data-line={2132} +%mdk-data-line={2132} +\noindent\mdline{2132}an \mdline{2132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2132} type used as a field in a \mdline{2132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2132} must specify a +underlying type and representation for \mdline{2133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2133} elements.%mdk +\label{fn-enum_header}%mdk%mdk +}\mdline{2122}}&\multicolumn{1}{|l}{\mdline{2122} error}&\multicolumn{1}{|l|}{\mdline{2122} allowed}\\ +\multicolumn{1}{|l}{\mdline{2123} \mdline{2123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2123}}&\multicolumn{1}{|l}{\mdline{2123} error}&\multicolumn{1}{|l}{\mdline{2123} allowed}&\multicolumn{1}{|l|}{\mdline{2123} allowed}\\ +\multicolumn{1}{|l}{\mdline{2124} header stack}&\multicolumn{1}{|l}{\mdline{2124} error}&\multicolumn{1}{|l}{\mdline{2124} error}&\multicolumn{1}{|l|}{\mdline{2124} allowed}\\ +\multicolumn{1}{|l}{\mdline{2125} \mdline{2125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2125}}&\multicolumn{1}{|l}{\mdline{2125} error}&\multicolumn{1}{|l}{\mdline{2125} error}&\multicolumn{1}{|l|}{\mdline{2125} allowed}\\ +\multicolumn{1}{|l}{\mdline{2126} \mdline{2126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2126}}&\multicolumn{1}{|l}{\mdline{2126} error}&\multicolumn{1}{|l}{\mdline{2126} error}&\multicolumn{1}{|l|}{\mdline{2126} allowed}\\ +\multicolumn{1}{|l}{\mdline{2127} \mdline{2127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2127}}&\multicolumn{1}{|l}{\mdline{2127} error}&\multicolumn{1}{|l}{\mdline{2127} error}&\multicolumn{1}{|l|}{\mdline{2127} allowed}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2129} +\mdhr{}%mdk + +%mdk-data-line={2130} +\noindent\mdline{2130}\mdcaption{\textbf{Table~\mdcaptionlabel{6}.}~\mdcaptiontext{P4 Type Usage}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-type-usage}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2135} +\mdline{2135}For example, the following P4\mdline{2135}\mdsub{16}\mdline{2135} objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects.%mdk + +%mdk-data-line={2138} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2139} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}{\bfseries{\mdcolor{navy}tuple}}\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}4}\textgreater{},~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~\textgreater{}~\textgreater{}()~digest\_complex;\\ +digest\_complex.pack(\{~hdr.ipv4.version,~hdr.ipv4.protocol~\});\\ +{\mdcolor{darkgreen}//~...}\\ +{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2149} +\noindent\mdline{2149}One solution would be to use only binary string (\mdline{2149}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2149} type) in +p4runtime.proto and to define a custom serialization format for complex P4\mdline{2150}\mdsub{16}\mdline{2150} +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P4\mdline{2157}\mdsub{16}\mdline{2157} types.%mdk + +%mdk-data-line={2159} +\subsubsection{\mdline{2159}8.5.2.\hspace*{0.5em}\mdline{2159}P4 Type Specifications in p4info.proto}\label{sec-p4-type-specifications-in-p4infoproto}%mdk%mdk + +%mdk-data-line={2161} +\noindent\mdline{2161}In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type \mdline{2165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip\_t}}}\mdline{2165}, which is a header union with 2 possible headers: +\mdline{2166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4}}}\mdline{2166} with type \mdline{2166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4\_t}}}\mdline{2166} and \mdline{2166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6}}}\mdline{2166} with type \mdline{2166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6\_t}}}\mdline{2166}. Similarly, they need to +know the field layout for both of these header types.%mdk + +%mdk-data-line={2169} +\mdline{2169}To achieve this we introduce 2 main Protobuf messages: \mdline{2169}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2169} and +\mdline{2170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2170}.%mdk + +%mdk-data-line={2172} +\mdline{2172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2172} is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P4\mdline{2173}\mdsub{16}\mdline{2173} program. These +named types are \mdline{2174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2174}, \mdline{2174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2174}, \mdline{2174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2174}, \mdline{2174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2174} and +\mdline{2175}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2175}; for each of these we have a type specification message, +respectively \mdline{2176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructTypeSpec}}}\mdline{2176}, \mdline{2176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderTypeSpec}}}\mdline{2176}, \mdline{2176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionTypeSpec}}}\mdline{2176}, +\mdline{2177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4EnumTypeSpec}}}\mdline{2177} and \mdline{2177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4SerializableEnumTypeSpec}}}\mdline{2177}. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. \mdline{2179}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2179} also includes the list of parser errors for the program, as +a \mdline{2180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4ErrorTypeSpec}}}\mdline{2180} message.%mdk + +%mdk-data-line={2182} +\mdline{2182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2182} is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each \mdline{2184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2184} message corresponds to a compile-time type in the +original P4\mdline{2185}\mdsub{16}\mdline{2185} program (\mdline{2185}e.g.\mdline{2185} the type parameter of an extern). This +compile-time type is represented as a Protobuf \mdline{2186}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2186}, which can be:%mdk + +%mdk-data-line={2188} +\begin{itemize}%mdk + +%mdk-data-line={2188} +\item{} +%mdk-data-line={2188} +\mdline{2188}a string representing the name of the type in case of a named type (\mdline{2188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2188}, +\mdline{2189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2189}, \mdline{2189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2189}, \mdline{2189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2189}, \mdline{2189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2189} or user-defined \mdline{2189}\textquotedblleft{}new\textquotedblright{}\mdline{2189} +\mdline{2190}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2190}),%mdk%mdk + +%mdk-data-line={2192} +\item{} +%mdk-data-line={2192} +\mdline{2192}an empty Protobuf message for \mdline{2192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2192} and \mdline{2192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2192}, or%mdk%mdk + +%mdk-data-line={2194} +\item{} +%mdk-data-line={2194} +\mdline{2194}a Protobuf message for other anonymous types (\mdline{2194}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2194}, \mdline{2194}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2194}, \mdline{2194}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2194}, +\mdline{2195}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2195} or stack). The \mdline{2195}\textquotedblleft{}binary string\textquotedblright{}\mdline{2195} types (\mdline{2195}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2195}, \mdline{2195}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2195}, and +\mdline{2196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2196}) are grouped together in the \mdline{2196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4BitstringLikeTypeSpec}}}\mdline{2196} message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf \mdline{2198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2198} +type).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2201} +\noindent\mdline{2201}For all P4\mdline{2201}\mdsub{16}\mdline{2201} compound types (\mdline{2201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2201}, \mdline{2201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2201}, \mdline{2201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2201}, and \mdline{2201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2201}), +the order of \mdline{2202}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2202} in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P4\mdline{2204}\mdsub{16}\mdline{2204} declaration. The same goes for the order of members of an \mdline{2204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2204} +(serializable or not) or members of \mdline{2205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2205}.%mdk + +%mdk-data-line={2207} +\subsubsection{\mdline{2207}8.5.3.\hspace*{0.5em}\mdline{2207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2207} in p4runtime.proto}\label{sec-p4data-in-p4runtime-proto}%mdk%mdk + +%mdk-data-line={2209} +\noindent\mdline{2209}P4Runtime uses the \mdline{2209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2209} message to represent values of arbitrary types. The +P4Runtime client must generate correct \mdline{2210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2210} messages based on the type +specification information included in P4Info. The \mdline{2211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2211} message was designed +to introduce little overhead compared to using binary strings in the most common +case (P4\mdline{2213}\mdsub{16}\mdline{2213} \mdline{2213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2213} type).%mdk + +%mdk-data-line={2215} +\mdline{2215}Just like its P4Info counterpart\mdline{2215} \mdline{2215}- \mdline{2215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2215} \mdline{2215}-, \mdline{2215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2215} uses a Protobuf +\mdline{2216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2216} to represent all possible values.%mdk + +%mdk-data-line={2218} +\mdline{2218}We define a canonical representation for \mdline{2218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2218} messages\mdline{2218} \mdline{2218}\textemdash{}\mdline{2218} therefore +guaranteeing read-write symmetry\mdline{2219} \mdline{2219}\textemdash{}\mdline{2219} by introducing the following requirements:%mdk + +%mdk-data-line={2221} +\begin{itemize}%mdk + +%mdk-data-line={2221} +\item{} +%mdk-data-line={2221} +\mdline{2221}The order of \mdline{2221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2221} in \mdline{2221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructLike}}}\mdline{2221} and the order of \mdline{2221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2221} in +\mdline{2222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2222} must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P4\mdline{2223}\mdsub{16}\mdline{2223} type +declaration.%mdk%mdk + +%mdk-data-line={2226} +\item{} +%mdk-data-line={2226} +\mdline{2226}An invalid header is represented by a \mdline{2226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2226} message where the \mdline{2226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_valid}}}\mdline{2226} +field is false and the \mdline{2227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2227} repeated field is empty.%mdk%mdk + +%mdk-data-line={2229} +\item{} +%mdk-data-line={2229} +\mdline{2229}An invalid header union (\mdline{2229}i.e.\mdline{2229} all headers in the union are invalid) is +represented by a \mdline{2230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnion}}}\mdline{2230} message where the \mdline{2230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header\_name}}}\mdline{2230} is the +empty string (default value for the field) and the \mdline{2231}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header}}}\mdline{2231} is unset.%mdk%mdk + +%mdk-data-line={2233} +\item{} +%mdk-data-line={2233} +\mdline{2233}The order of \mdline{2233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2233} in \mdline{2233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStack}}}\mdline{2233} and \mdline{2233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStack}}}\mdline{2233} is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the \mdline{2235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2235} field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding \mdline{2237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStackTypeSpec}}}\mdline{2237} or +\mdline{2238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStackTypeSpec}}}\mdline{2238} message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2240} +\subsubsection{\mdline{2240}8.5.4.\hspace*{0.5em}\mdline{2240}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={2242} +\noindent\mdline{2242}Let\mdline{2242}'\mdline{2242}s look at the Register example again:%mdk + +%mdk-data-line={2244} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2245} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2252} +\noindent\mdline{2252}Here\mdline{2252}'\mdline{2252}s the corresponding entry in the P4Info message:%mdk + +%mdk-data-line={2254} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2255} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}registers~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}369119267}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~\}\\ +~~type\_spec~\{\\ +~~~~header\_union~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~size:~{\mdcolor{purple}128}\\ +\}\\ +type\_info~\{\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~header\_unions~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2311} +\noindent\mdline{2311}Here\mdline{2311}'\mdline{2311}s a \mdline{2311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.WriteRequest}}}\mdline{2311} to set the value of \mdline{2311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_ip{}[12]}}}\mdline{2311}:%mdk + +%mdk-data-line={2313} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2314} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}update~\{\\ +~~type:~INSERT\\ +~~entity~\{\\ +~~~~register\_entry~\{\\ +~~~~~~register\_id:~{\mdcolor{purple}369119267}\\ +~~~~~~index~\{\\ +~~~~~~~~index:~{\mdcolor{purple}12}\\ +~~~~~~\}\\ +~~~~~~data~\{\\ +~~~~~~~~header\_union~\{\\ +~~~~~~~~~~valid\_header\_name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~~~valid\_header~\{\\ +~~~~~~~~~~~~is\_valid:~true\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x04}{\mdcolor{maroon}"}\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{darkgreen}\#~...}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2337} +\subsubsection{\mdline{2337}8.5.5.\hspace*{0.5em}\mdline{2337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2337}, serializable \mdline{2337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2337} and \mdline{2337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}\label{sec-enum-serializable-enum-and-error}%mdk%mdk + +%mdk-data-line={2339} +\noindent\mdline{2339}P4\mdline{2339}\mdsub{16}\mdline{2339} supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or \mdline{2340}\textquotedblleft{}unsafe\textquotedblright{}\mdline{2340} enum) +\mdline{2341}[\mdcite{p4enums}{5}]\mdline{2341}. For \mdline{2341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2341} types with no underlying type\mdline{2341} \mdline{2341}\textemdash{}\mdline{2341} as well as \mdline{2341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2341} \mdline{2341}\textemdash{}\mdline{2341} +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in \mdline{2344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2344} to represent \mdline{2344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2344} and +\mdline{2345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2345} values.%mdk + +%mdk-data-line={2347} +\mdline{2347}Serializable \mdline{2347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2347} types have an underlying fixed-width unsigned integer +representation (\mdline{2348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2348}). All named enum members must be assigned an integer +value by the P4 programmer, but \mdline{2349}\emph{not all}\mdline{2349} valid numeric values for the +underlying type need to have a corresponding name. \mdline{2350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2350} includes the +mapping between entry name and entry value. When providing serializable enum +values through \mdline{2352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2352}, one must use the assigned integer value (\mdline{2352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum\_value}}}\mdline{2352} +bytestring field). P4Runtime does not provide a way for the client to use the +name\mdline{2354} \mdline{2354}\textemdash{}\mdline{2354} even when the enum member has one\mdline{2354} \mdline{2354}\textemdash{}\mdline{2354} instead of the value, as it makes +it easier for the server to respect the\mdline{2355}~\mdref{sec-read-write-symmetry}{read-write +symmetry}\mdline{2356} principle.%mdk + +%mdk-data-line={2358} +\subsubsection{\mdline{2358}8.5.6.\hspace*{0.5em}\mdline{2358}User-defined types}\label{sec-user-defined-types}%mdk%mdk + +%mdk-data-line={2360} +\noindent\mdline{2360}P4\mdline{2360}\mdsub{16}\mdline{2360} enables programmers to introduce new types\mdline{2360}~[\mdcite{p4newtypes}{11}]\mdline{2360}. While similar +to \mdline{2361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{2361}, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +\mdline{2364}\mdref{sec-psa-metadata-translation}{translation}\mdline{2364}. When introducing a new type, the +declaration can be annotated with \mdline{2365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2365} to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for\mdline{2367}~\mdref{sec-translation-of-port-numbers}{port numbers}\mdline{2367}, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. \mdline{2370}\textbf{The \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}} annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}})}\mdline{2372} and the type exposed to the control plane will also be a +fixed-width unsigned bitstring, with a potentially different bitwidth. It takes +two parameters: a \mdline{2374}\emph{URI}\mdline{2374} (Uniform Resource Identifier) which uniquely identifies +the translation being performed on entities of the new type to the P4Runtime +server and the \mdline{2376}\emph{bitwidth}\mdline{2376} of the bitstring type exposed to the control plane. It +is recommended that the URI includes at least the P4 architecture name and the +type name.%mdk + +%mdk-data-line={2380} +\mdline{2380}A \mdline{2380}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2380} annotation need not have any effect if it is used to +annotate anything in a P4 program other than a \mdline{2381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2381} declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect.%mdk + +%mdk-data-line={2385} +\mdline{2385}User-defined types are specified using the \mdline{2385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{2385} message, which has +the following fields:%mdk + +%mdk-data-line={2388} +\begin{itemize}%mdk + +%mdk-data-line={2388} +\item{} +%mdk-data-line={2388} +\mdline{2388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}representation}}}\mdline{2388}, a Protobuf \mdline{2388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2388} specifying how values of this type are +exchanged between client and server; it can be either:%mdk + +%mdk-data-line={2391} +\begin{itemize}%mdk + +%mdk-data-line={2391} +\item{} +%mdk-data-line={2391} +\mdline{2391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2391}, if and only if no \mdline{2391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2391} annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 \mdline{2393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2393} declaration is itself a +user-defined type, \mdline{2394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2394} is obtained by \mdline{2394}\textquotedblleft{}walking\textquotedblright{}\mdline{2394} the chain of +\mdline{2395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2395} declarations recursively until a built-in type (\mdline{2395}e.g.\mdline{2395} \mdline{2395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2395}) is +found.%mdk%mdk + +%mdk-data-line={2398} +\item{} +%mdk-data-line={2398} +\mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}translated\_type}}}\mdline{2398}, if and only if the P4 \mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2398} declaration was annotated +with \mdline{2399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2399}. It is of type \mdline{2399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeTranslation}}}\mdline{2399}, which +itself has two fields\mdline{2400} \mdline{2400}\textemdash{}\mdline{2400} \mdline{2400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uri}}}\mdline{2400} and \mdline{2400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_bitwidth}}}\mdline{2400} \mdline{2400}\textemdash{}\mdline{2400}, which map to the +two input parameters to the annotation.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2403} +\item{} +%mdk-data-line={2403} +\mdline{2403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{2403}, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2406} +\noindent\mdline{2406}For example, an architecture\mdline{2406} \mdline{2406}\textemdash{}\mdline{2406} in this case PSA\mdline{2406} \mdline{2406}\textemdash{}\mdline{2406} may introduce a new type +for port numbers:%mdk + +%mdk-data-line={2408} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2409} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2413} +\noindent\mdline{2413}In this case, the P4Info message would include the following \mdline{2413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2413} +message:%mdk + +%mdk-data-line={2416} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2417} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2430} +\noindent\mdline{2430}Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (\mdline{2431}e.g.\mdline{2431} through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2433} to enable users +to overwrite annotations included as part of the P4 architecture definition.%mdk + +%mdk-data-line={2436} +\subsubsection{\mdline{2436}8.5.7.\hspace*{0.5em}\mdline{2436}Trade-off for v1.0 Release}\label{sec-trade-off-for-v10-release}%mdk%mdk + +%mdk-data-line={2438} +\noindent\mdline{2438}For the v1.0 release of P4Runtime, it was decided not to replace occurrences of +\mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2439} with \mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2439} in the \mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{2439} message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-release +implementations of P4Runtime. Similarly it has been decided to keep using +\mdline{2442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2442} to provide action parameter values. However \mdline{2442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2442} is used whenever +appropriate for PSA externs and we encourage the use of \mdline{2443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2443} in +architecture-specific extensions.%mdk + +%mdk-data-line={2446} +\mdline{2446}In order to support\mdline{2446}~\mdref{sec-psa-metadata-translation}{translation}\mdline{2446} for action +parameters and match fields, we include a \mdline{2447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2447} field in +\mdline{2448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{2448} and \mdline{2448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Action.Param}}}\mdline{2448}.%mdk + +%mdk-data-line={2450} +\section{\mdline{2450}9.\hspace*{0.5em}\mdline{2450}P4 Entity Messages}\label{sec-p4-entity-msgs}%mdk%mdk + +%mdk-data-line={2452} +\noindent\mdline{2452}P4Runtime covers P4 entities that are either part of the P4\mdline{2452}\mdsub{16}\mdline{2452} language, or +defined as PSA externs. The sections below describe the messages for each +supported entity.%mdk + +%mdk-data-line={2456} +\subsection{\mdline{2456}9.1.\hspace*{0.5em}\mdline{2456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}\label{sec-table-entry}%mdk%mdk + +%mdk-data-line={2458} +\noindent\mdline{2458}The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action\mdline{2460}'\mdline{2460}s +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification.%mdk + +%mdk-data-line={2466} +\mdline{2466}P4Runtime supports inserting, modifying, deleting and reading table entries with +the \mdline{2467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2467} entity, which has the following fields:%mdk + +%mdk-data-line={2469} +\begin{itemize}%mdk + +%mdk-data-line={2469} +\item{} +%mdk-data-line={2469} +\mdline{2469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2469}, which identifies the table instance; the \mdline{2469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2469} is determined +by the P4Info message.%mdk%mdk + +%mdk-data-line={2472} +\item{} +%mdk-data-line={2472} +\mdline{2472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2472}, a repeated field of \mdline{2472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2472} messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration.%mdk%mdk + +%mdk-data-line={2476} +\item{} +%mdk-data-line={2476} +\mdline{2476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2476}, which indicates which of the table\mdline{2476}'\mdline{2476}s actions to execute in case of +match and with which argument values.%mdk%mdk + +%mdk-data-line={2479} +\item{} +%mdk-data-line={2479} +\mdline{2479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2479}, a 32-bit integer used to order entries when the table\mdline{2479}'\mdline{2479}s match key +includes a ternary or range match.%mdk%mdk + +%mdk-data-line={2482} +\item{} +%mdk-data-line={2482} +\mdline{2482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2482}, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry.%mdk%mdk + +%mdk-data-line={2487} +\item{} +%mdk-data-line={2487} +\mdline{2487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2487}, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See\mdline{2488}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2489} section for more information.%mdk%mdk + +%mdk-data-line={2491} +\item{} +%mdk-data-line={2491} +\mdline{2491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2491}, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See\mdline{2492}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2493} section for more information.%mdk%mdk + +%mdk-data-line={2495} +\item{} +%mdk-data-line={2495} +\mdline{2495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2495}, a boolean flag which indicates whether the table entry is +the default entry for the table. See\mdline{2496}~\mdref{sec-default-entry}{Default entry}\mdline{2496} +section for more information.%mdk%mdk + +%mdk-data-line={2499} +\item{} +%mdk-data-line={2499} +\mdline{2499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2499} and \mdline{2499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2499}, which are two fields used to +implement idle-timeout support for the table, if applicable. See +\mdline{2501}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{2501} section for more information.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2503} +\noindent\mdline{2503}The \mdline{2503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2503} field must be set to a non-zero value if the match key includes a +ternary match (\mdline{2504}i.e.\mdline{2504} in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has a \mdline{2505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2505} or \mdline{2505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2505} match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches.%mdk + +%mdk-data-line={2514} +\mdline{2514}The \mdline{2514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2514} and \mdline{2514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2514} fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for \mdline{2516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2516} and \mdline{2516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{2516} updates. When deleting +an entry, these key fields (along with \mdline{2517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2517}) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a \mdline{2519}\emph{keyless}\mdline{2519} +table (the table has an empty match key), the server must reject all attempts to +\mdline{2521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2521} a match entry and return an \mdline{2521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2521} error.%mdk + +%mdk-data-line={2523} +\mdline{2523}The number of match entries that a table \mdline{2523}\emph{should}\mdline{2523} support is indicated in P4Info +(\mdline{2524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2524} field of \mdline{2524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{2524} message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P4\mdline{2525}\mdsub{16}\mdline{2525} specification for the +\mdline{2526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2526} property\mdline{2526}~[\mdcite{p4tableproperties}{29}]\mdline{2526}. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +\mdline{2530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{2530} when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached.%mdk + +%mdk-data-line={2535} +\subsubsection{\mdline{2535}9.1.1.\hspace*{0.5em}\mdline{2535}Match Format}\label{sec-match-format}%mdk%mdk + +%mdk-data-line={2537} +\noindent\mdline{2537}The bytes fields in the \mdline{2537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2537} message follow the format described in +\mdline{2538}\mdref{sec-bytestrings}{Bytestrings}\mdline{2538}.%mdk + +%mdk-data-line={2540} +\mdline{2540}For \mdline{2540}\textquotedblleft{}don't care\textquotedblright{}\mdline{2540} matches, the P4Runtime client must omit the field\mdline{2540}'\mdline{2540}s entire +\mdline{2541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2541} entry when building the \mdline{2541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2541} repeated field of the \mdline{2541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2541} +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for \mdline{2543}\textquotedblleft{}don't care\textquotedblright{}\mdline{2543} matches, which is needed +to ensure\mdline{2544}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2544}. For PSA match types, +a \mdline{2545}\textquotedblleft{}don't care\textquotedblright{}\mdline{2545} match for a specific match key field is defined as follows:%mdk + +%mdk-data-line={2547} +\begin{itemize}%mdk + +%mdk-data-line={2547} +\item{} +%mdk-data-line={2547} +\mdline{2547}For a \mdline{2547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2547} match, it is logically equivalent to a mask of zeros.%mdk%mdk + +%mdk-data-line={2549} +\item{} +%mdk-data-line={2549} +\mdline{2549}For an \mdline{2549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2549} match, it is logically equivalent to a prefix\mdline{2549}\_\mdline{2549}len of zero.%mdk%mdk + +%mdk-data-line={2551} +\item{} +%mdk-data-line={2551} +\mdline{2551}For a \mdline{2551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2551} match, it is logically equivalent to a range which includes all +possible values for the field.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2554} +\noindent\mdline{2554}Note that there is no \mdline{2554}\textquotedblleft{}don't care\textquotedblright{}\mdline{2554} value for \mdline{2554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2554} matches and therefore exact +match fields can never be omitted from the \mdline{2555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2555} message.%mdk + +%mdk-data-line={2557} +\mdline{2557}The following example shows a P4Runtime message that treats a \mdline{2557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2557} field +as a \mdline{2558}\textquotedblleft{}don't care\textquotedblright{}\mdline{2558} match. The P4 program defines table \mdline{2558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{2558} with \mdline{2558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2558} +and \mdline{2559}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2559} fields in its match key:%mdk + +%mdk-data-line={2561} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2562} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~ternary;\\ +~~~~istd.ingress\_port:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2573} +\noindent\mdline{2573}In this P4Runtime request, the client omits the table\mdline{2573}'\mdline{2573}s \mdline{2573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2573} field +from the repeated \mdline{2574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2574} field to indicate a \mdline{2574}\textquotedblleft{}don't care\textquotedblright{}\mdline{2574} match. As shown +below, the \mdline{2575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2575} specifies only the \mdline{2575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2575} field given by \mdline{2575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id:~2}}}\mdline{2575}.%mdk + +%mdk-data-line={2577} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2578} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}33554439}~~{\mdcolor{darkgreen}\#~Table~t's~ID.}\\ +~~~~match~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~field\_id~1~is~not~present~to~use~the~don't~care~ternary~value.}\\ +~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~exact~\{\\ +~~~~~~~~value:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x20}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~action~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~Action~selection~goes~here.}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2596} +\noindent\mdline{2596}For every member of the \mdline{2596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2596} repeated \mdline{2596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2596} field, \mdline{2596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id}}}\mdline{2596} must be +a valid id for the table, as per the P4Info, and one of the fields in +\mdline{2598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{2598} must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an \mdline{2600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2600} error code.%mdk + +%mdk-data-line={2602} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2602} +\item\mdline{2602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2602} match + +%mdk-data-line={2603} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2603} +\item\mdline{2603}The binary string encoding of the value must conform to the +\mdline{2604}\mdref{sec-bytestrings}{Bytestrings}\mdline{2604} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2606} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2607} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.exact().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2610} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2610} +\item\mdline{2610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2610} match + +%mdk-data-line={2611} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2611} +\item\mdline{2611}The binary string encoding of the value (when present) must conform to the +\mdline{2612}\mdref{sec-bytestrings}{Bytestrings}\mdline{2612} requirements.%mdk + +%mdk-data-line={2613} +\item\mdline{2613}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2613} match must be omitted.%mdk + +%mdk-data-line={2614} +\item\mdline{2614}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2614} bits must be 0 in value.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2616} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2617} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.lpm().value()))\\ +\\ +pLen~=~match.lpm().prefix\_len()\\ +assert(pLen~\textgreater{}~0)\\ +\\ +trailing\_zeros~=~countTrailingZeros(match.lpm().value())\\ +assert(trailing\_zeros~\textgreater{}=~field\_bits~-~pLen)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2626} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2626} +\item\mdline{2626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2626} match + +%mdk-data-line={2627} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2627} +\item\mdline{2627}The binary string encoding of the value (when present) and mask (when +present) must conform to the\mdline{2628}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2628} requirements.%mdk + +%mdk-data-line={2629} +\item\mdline{2629}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2629} match must be omitted.%mdk + +%mdk-data-line={2630} +\item\mdline{2630}Masked bits must be 0 in value. This constraint taken together +with the\mdline{2631}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2631} requirements means that the +value\mdline{2632}'\mdline{2632}s binary string is never longer than the mask\mdline{2632}'\mdline{2632}s binary string. +When the value\mdline{2633}'\mdline{2633}s string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2637} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2638} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.ternary().value()))\\ +assert(BytestringValid(match.ternary().mask()))\\ +assert(match.ternary().value().size()~\textless{}=~match.ternary().mask().size());\\ +\\ +value~=~parseInteger(match.ternary().value())\\ +mask~=~parseInteger(match.ternary().mask())\\ +\\ +assert(mask~!=~0)\\ +\\ +assert(value~\&~mask~==~value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2650} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2650} +\item\mdline{2650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2650} match + +%mdk-data-line={2651} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2651} +\item\mdline{2651}The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the\mdline{2652}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2652} +requirements.%mdk + +%mdk-data-line={2654} +\item\mdline{2654}Low bound must be less than or equal to the high bound.%mdk + +%mdk-data-line={2655} +\item\mdline{2655}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2655} match must be omitted.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2657} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2658} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.range().low()))\\ +assert(BytestringValid(match.range().high()))\\ +\\ +low~=~parseInteger(match.range().low())\\ +high~=~parseInteger(match.range().high())\\ +\\ +assert(low~\textless{}=~high)\\ +\\ +assert(low~!=~min\_field\_value~\textbar{}\textbar{}~high~!=~max\_field\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2669} +\subsubsection{\mdline{2669}9.1.2.\hspace*{0.5em}\mdline{2669}Action Specification}\label{sec-action-specification}%mdk%mdk + +%mdk-data-line={2671} +\noindent\mdline{2671}The \mdline{2671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2671} \mdline{2671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2671} field must be set for every \mdline{2671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2671} update but may be +left unset for \mdline{2672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2672} updates, in which case the action specification for the +table entry will not be modified (if a \mdline{2673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2673} update has an unset action field +and does not modify any direct resource attached to the table then the \mdline{2674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2674} +update is a no-op). Based on the implementation property value of the P4 table, +the \mdline{2676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2676} in the \mdline{2676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{2676} message will either be:%mdk + +%mdk-data-line={2678} +\begin{itemize}%mdk + +%mdk-data-line={2678} +\item{} +%mdk-data-line={2678} +\mdline{2678}an \mdline{2678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{2678} specification for direct tables (with no P4 \mdline{2678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2678} +property)%mdk%mdk + +%mdk-data-line={2681} +\item{} +%mdk-data-line={2681} +\mdline{2681}an action profile member id for indirect tables for which the \mdline{2681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2681} +property is an action profile with no selector.%mdk%mdk + +%mdk-data-line={2684} +\item{} +%mdk-data-line={2684} +\mdline{2684}an action profile member id or group id for indirect tables for which the +\mdline{2685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2685} property is an action profile with selector.%mdk%mdk + +%mdk-data-line={2687} +\item{} +%mdk-data-line={2687} +\mdline{2687}an \mdline{2687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{2687} specification for indirect tables for +which the \mdline{2688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2688} property is an action profile with +selector. This usage is described in\mdline{2689}~\mdref{sec-oneshot}{One Shot Action Selector +Programming}\mdline{2690}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2692} +\noindent\mdline{2692}If the \mdline{2692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2692} does not match the table description in the P4Info (\mdline{2692}e.g.\mdline{2692} the +\mdline{2693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2693} is \mdline{2693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member\_id}}}\mdline{2693} for a direct table), the server must +return an \mdline{2694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2694} error code.%mdk + +%mdk-data-line={2696} +\mdline{2696}The \mdline{2696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{2696} Protobuf message has the following fields:%mdk + +%mdk-data-line={2698} +\begin{itemize}%mdk + +%mdk-data-line={2698} +\item{} +%mdk-data-line={2698} +\mdline{2698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{2698}, which identifies the action instance; the \mdline{2698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{2698} is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an \mdline{2700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2700} error +code. If the client uses a valid \mdline{2701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{2701} for the table but does not +respect the action scope specified in P4Info (\mdline{2702}e.g.\mdline{2702} tries to set a \mdline{2702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{2702} +action as the default action), the server must return a \mdline{2703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{2703} +error code.%mdk%mdk + +%mdk-data-line={2706} +\item{} +%mdk-data-line={2706} +\mdline{2706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{2706}: a repeated Protobuf field of action parameter values, each encoded +as a \mdline{2707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{2707} message. For each parameter, \mdline{2707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}param\_id}}}\mdline{2707} must be valid for the +action (as per the P4Info) and value must follow the format described in +\mdline{2709}\mdref{sec-bytestrings}{Bytestrings}\mdline{2709}. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an \mdline{2711}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2711} error code +if a parameter id is missing, if an extra parameter\mdline{2712} \mdline{2712}\textemdash{}\mdline{2712} id not found in the +P4Info\mdline{2713} \mdline{2713}\textemdash{}\mdline{2713} was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +\mdline{2715}\mdref{sec-bytestrings}{Bytestrings}\mdline{2715} format.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2717} +\noindent\mdline{2717}For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a \mdline{2719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{2719} error code.%mdk + +%mdk-data-line={2721} +\subsubsection{\mdline{2721}9.1.3.\hspace*{0.5em}\mdline{2721}Default Entry}\label{sec-default-entry}%mdk%mdk + +%mdk-data-line={2723} +\noindent\mdline{2723}According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer\mdline{2724} \mdline{2724}\textemdash{}\mdline{2724} or defaults to \mdline{2724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{2724} +(which is a no-op) otherwise\mdline{2725} \mdline{2725}\textemdash{}\mdline{2725} and assuming it is not declared as \mdline{2725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{2725}, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow \mdline{2727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2727} and \mdline{2727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{2727} updates on the default entry and the +P4Runtime server must return an \mdline{2728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2728} error code if the client +attempts one.%mdk + +%mdk-data-line={2731} +\mdline{2731}The default entry is identified by setting the \mdline{2731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2731} boolean field +to true. When this flag is set to true, the repeated \mdline{2732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2732} field must be empty +and the \mdline{2733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2733} field must be set to zero, otherwise the P4Runtime server +must return an \mdline{2734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2734} error code. When performing a \mdline{2734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2734} update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its \mdline{2738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2738} value as well as the configurations for its +\mdline{2739}\mdref{sec-direct-resources}{direct resources}\mdline{2739} will be reset to their defaults. If +the default entry is constant (as indicated by the P4 program and the P4Info +message), the server must return a \mdline{2741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{2741} error code if the client +attempts to modify it.%mdk + +%mdk-data-line={2744} +\mdline{2744}Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to\mdline{2745}~\mdref{sec-direct-resources}{direct resources}\mdline{2745}.%mdk + +%mdk-data-line={2747} +\mdline{2747}In this P4Runtime release, we have decided to restrict the default entry for +indirect tables\mdline{2748} \mdline{2748}\textemdash{}\mdline{2748} tables with an ActionProfile or ActionSelector +\mdline{2749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2749} property\mdline{2749} \mdline{2749}\textemdash{}\mdline{2749} to a constant \mdline{2749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{2749} action entry, with the +hope that it would simplify the implementation of the P4Runtime service.%mdk + +%mdk-data-line={2752} +\subsubsection{\mdline{2752}9.1.4.\hspace*{0.5em}\mdline{2752}Constant Tables}\label{sec-constant-tables}%mdk%mdk + +%mdk-data-line={2754} +\noindent\mdline{2754}Constant tables are defined as tables whose match entries are immutable. They +are identified by the \mdline{2755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{2755} flag in P4Info.%mdk + +%mdk-data-line={2757} +\mdline{2757}The only write updates which are allowed for constant tables are \mdline{2757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2757} +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +\mdline{2761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{2761} error. Just like any table entry \mdline{2761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2761} request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a \mdline{2765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{2765} error.%mdk + +%mdk-data-line={2767} +\mdline{2767}The contents of const tables can be queried by the client through a +\mdline{2768}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2768}. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: \mdline{2769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2769}, \mdline{2769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2769}, \mdline{2769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2769}, +\mdline{2770}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2770}, and \mdline{2770}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2770} (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the \mdline{2773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2773} field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P4\mdline{2775}\mdsub{16}\mdline{2775} does not support assigning explicit priorities to static +entries. When a priority value is required (\mdline{2776}e.g.\mdline{2776} for tables including \mdline{2776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2776} +and / or \mdline{2777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2777} matches in the case of PSA), it is inferred based on the +order in which entries appear in the table declaration.%mdk + +%mdk-data-line={2780} +\subsubsection{\mdline{2780}9.1.5.\hspace*{0.5em}\mdline{2780}Wildcard Reads}\label{sec-table-wildcard-reads}%mdk%mdk + +%mdk-data-line={2782} +\noindent\mdline{2782}When performing a \mdline{2782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2782}, the P4Runtime client can select all entries +from one or all tables on the target and use several of the \mdline{2783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2783} fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as \mdline{2787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2787} and \mdline{2787}\textquotedblleft{}unset\textquotedblright{}\mdline{2787} for message fields such as \mdline{2787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2787}. The following +fields may be used to select and filter results:%mdk + +%mdk-data-line={2790} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2790} +\item\mdline{2790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2790}: If default (0), entries from all tables\mdline{2790} \mdline{2790}\textemdash{}\mdline{2790} including constant +tables\mdline{2791} \mdline{2791}\textemdash{}\mdline{2791} will be selected and no other filter can be used. Otherwise only +the specified table will be considered.%mdk + +%mdk-data-line={2793} +\item\mdline{2793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2793}: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned.%mdk + +%mdk-data-line={2797} +\item\mdline{2797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2797}: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an \mdline{2798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{2798} (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id.%mdk + +%mdk-data-line={2804} +\item\mdline{2804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2804}: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value.%mdk + +%mdk-data-line={2807} +\item\mdline{2807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2807}: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +\mdline{2809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2809} value.%mdk + +%mdk-data-line={2810} +\item\mdline{2810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2810}: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2814} +\noindent\mdline{2814}For example, in order to read all entries from all tables from device 3, the +client can use the following \mdline{2815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2815} message.%mdk + +%mdk-data-line={2817} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2818} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0}\\ +~~~~priority:~{\mdcolor{purple}0}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2828} +\noindent\mdline{2828}In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following \mdline{2829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2829} +message:%mdk + +%mdk-data-line={2832} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2833} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~priority:~{\mdcolor{purple}11}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2843} +\noindent\mdline{2843}The canonical representation of \mdline{2843}\textquotedblleft{}don't care\textquotedblright{}\mdline{2843} matches, combined with the ability +to do a wildcard read on all table entries by leaving the \mdline{2844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2844} field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single \mdline{2846}\textquotedblleft{}don't care\textquotedblright{}\mdline{2846} entry or to do a wildcard +read. If a table has no fields with match kind \mdline{2847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2847}, it is possible via +P4Runtime to add an entry that is \mdline{2848}\textquotedblleft{}don't care\textquotedblright{}\mdline{2848} for all fields (\mdline{2848}i.e.\mdline{2848} has an empty +\mdline{2849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2849} field) but is not the default entry (\mdline{2849}i.e.\mdline{2849} \mdline{2849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2849} is +false). When reading this entry from the table, there is no way to read \mdline{2850}\emph{only}\mdline{2850} +that entry from the table, because it would require providing an unset \mdline{2851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2851} +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single \mdline{2854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2854} match:%mdk + +%mdk-data-line={2856} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2857} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;~fwd;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2867} +\noindent\mdline{2867}The following \mdline{2867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{2867} message can be used to add 2 entries:%mdk + +%mdk-data-line={2868} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2869} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{~{\mdcolor{darkgreen}\#~don't~care~entry}\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +~~table~entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~match~\{\\ +~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~lpm~\{\\ +~~~~~~~~value:~{\mdcolor{purple}0x0a000000}\\ +~~~~~~~~prefix\_len:~{\mdcolor{purple}8}\\ +~~~~~~\}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2888} +\noindent\mdline{2888}The first entry is a \mdline{2888}\textquotedblleft{}don't care\textquotedblright{}\mdline{2888} entry, while the second one matches all +\mdline{2889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}10.0.0.0/8}}}\mdline{2889} addresses. The second entry has higher priority than the first one.%mdk + +%mdk-data-line={2891} +\mdline{2891}The following \mdline{2891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2891} message will return \mdline{2891}\emph{all}\mdline{2891} entries in the table, not +just the \mdline{2892}\textquotedblleft{}don't care\textquotedblright{}\mdline{2892} entry.%mdk + +%mdk-data-line={2893} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2894} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2902} +\noindent\mdline{2902}This issue also exists for tables with \mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2902} and / or \mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2902} +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the \mdline{2905}\textquotedblleft{}don't care\textquotedblright{}\mdline{2905} entry will be returned to the +client. If the client uses distinct priority values for all entries\mdline{2906} \mdline{2906}\textemdash{}\mdline{2906} which is +strongly recommended to achieve\mdline{2907}~\mdref{sec-table-entry}{deterministic behavior}\mdline{2907} \mdline{2907}\textemdash{}\mdline{2907}, +then there is no ambiguity because the wildcard read will actually return a +single entry (the \mdline{2909}\textquotedblleft{}don't care\textquotedblright{}\mdline{2909} entry) as long as the \mdline{2909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2909} field is set to +the correct value.%mdk + +%mdk-data-line={2912} +\subsubsection{\mdline{2912}9.1.6.\hspace*{0.5em}\mdline{2912}Direct Resources}\label{sec-direct-resources}%mdk%mdk + +%mdk-data-line={2914} +\noindent\mdline{2914}In addition to the \mdline{2914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{2914} and \mdline{2914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{2914} entities, +P4Runtime support reading and writing direct resources as part of the +\mdline{2916}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2916} message. This is convenient for two reasons:%mdk + +%mdk-data-line={2918} +\begin{itemize}%mdk + +%mdk-data-line={2918} +\item{} +%mdk-data-line={2918} +\mdline{2918}A table entry and its direct resources can be read with a single entity when +doing a \mdline{2919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{2919} RPC call%mdk%mdk + +%mdk-data-line={2921} +\item{} +%mdk-data-line={2921} +\mdline{2921}The initial configuration for an entry\mdline{2921}'\mdline{2921}s direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can \mdline{2926}\textquotedblleft{}hit\textquotedblright{}\mdline{2926} the table entry without +executing the appropriate meter entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2929} +\noindent\mdline{2929}Once the table entry has been inserted, the P4Runtime client is free to use the +\mdline{2930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{2930} and \mdline{2930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{2930} messages for read and write +operations on \mdline{2931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{2931} and \mdline{2931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{2931} instances. For example, it is +usually more convenient as well as more efficient to use \mdline{2932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{2932} to +query a counter entry value rather than use \mdline{2933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2933}, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry.%mdk + +%mdk-data-line={2937} +\mdline{2937}The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does \mdline{2938}\emph{not}\mdline{2938} need to be \mdline{2938}\textquotedblleft{}executed\textquotedblright{}\mdline{2938} in +every action bound to the table. It is an error to provide a direct resource +configuration in a \mdline{2940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2940} message when programming an action that does not +execute the direct resource, and the server must return an \mdline{2941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2941} +error code.%mdk + +%mdk-data-line={2944} +\mdline{2944}We leverage Protobuf\mdline{2944}'\mdline{2944}s ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the \mdline{2946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2946} message. The list below describes how +the server must handle the \mdline{2947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2947} and \mdline{2947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2947} fields for read and +write requests, based on whether the fields are set or not. We do not cover +error cases in the list, \mdline{2949}i.e.\mdline{2949} we assume that we are dealing with a table which +is assigned a direct counter / a direct meter, and that the action being used +for the table entry \mdline{2951}\textquotedblleft{}executes\textquotedblright{}\mdline{2951} the direct resource appropriately.%mdk + +%mdk-data-line={2953} +\begin{itemize}%mdk + +%mdk-data-line={2953} +\item{} +%mdk-data-line={2953} +\mdline{2953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2953} field%mdk + +%mdk-data-line={2954} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2954} +\item\mdline{2954}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{2954} + +%mdk-data-line={2955} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2955} +\item\mdline{2955}if \mdline{2955}\textbf{unset}\mdline{2955}: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets).%mdk + +%mdk-data-line={2957} +\item\mdline{2957}if \mdline{2957}\textbf{set}\mdline{2957}: The initial configuration for the meter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2959} +\item\mdline{2959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{2959} + +%mdk-data-line={2960} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2960} +\item\mdline{2960}if \mdline{2960}\textbf{unset}\mdline{2960}: The meter entry\mdline{2960}'\mdline{2960}s configuration is reset to the default +(meter returns GREEN for all packets).%mdk + +%mdk-data-line={2962} +\item\mdline{2962}if \mdline{2962}\textbf{set}\mdline{2962}: The value provided by the client is used to re-configure +the meter entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2964} +\item\mdline{2964}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2964} + +%mdk-data-line={2965} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2965} +\item\mdline{2965}if \mdline{2965}\textbf{unset}\mdline{2965}: The response does not include the meter entry\mdline{2965}'\mdline{2965}s +configuration (\mdline{2966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2966} is unset in the response).%mdk + +%mdk-data-line={2967} +\item\mdline{2967}if \mdline{2967}\textbf{set}\mdline{2967}: If the meter entry\mdline{2967}'\mdline{2967}s configuration is the default +configuration, \mdline{2968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2968} is unset in the response. Otherwise, the +response includes the meter entry\mdline{2969}'\mdline{2969}s configuration that was written by +the client earlier. This respects the \mdline{2970}\textquotedblleft{}read-write symmetry\textquotedblright{}\mdline{2970} principle.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2972} +\item{} +%mdk-data-line={2972} +\mdline{2972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2972} field%mdk + +%mdk-data-line={2973} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2973} +\item\mdline{2973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{2973} + +%mdk-data-line={2974} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2974} +\item\mdline{2974}if \mdline{2974}\textbf{unset}\mdline{2974}: The initial value for the counter entry is the default +(0).%mdk + +%mdk-data-line={2976} +\item\mdline{2976}if \mdline{2976}\textbf{set}\mdline{2976}: The initial value for the counter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2978} +\item\mdline{2978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{2978} + +%mdk-data-line={2979} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2979} +\item\mdline{2979}if \mdline{2979}\textbf{unset}\mdline{2979}: The counter entry\mdline{2979}'\mdline{2979}s value is not changed.%mdk + +%mdk-data-line={2980} +\item\mdline{2980}if \mdline{2980}\textbf{set}\mdline{2980}: The value provided by the client is written to the counter +entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2982} +\item\mdline{2982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2982} + +%mdk-data-line={2983} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2983} +\item\mdline{2983}if \mdline{2983}\textbf{unset}\mdline{2983}: The response does not include the counter entry\mdline{2983}'\mdline{2983}s value +(\mdline{2984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2984} is unset in the response).%mdk + +%mdk-data-line={2985} +\item\mdline{2985}if \mdline{2985}\textbf{set}\mdline{2985}: The response includes the counter entry\mdline{2985}'\mdline{2985}s value read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2988} +\noindent\mdline{2988}In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +\mdline{2990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2990} field unset when inserting \mdline{2990}\textbf{or modifying}\mdline{2990} a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the \mdline{2992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2992} message +(\mdline{2993}i.e.\mdline{2993} the \mdline{2993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2993} field must be set to match the existing configuration).%mdk + +%mdk-data-line={2995} +\subsubsection{\mdline{2995}9.1.7.\hspace*{0.5em}\mdline{2995}Idle-timeout}\label{sec-idle-timeout}%mdk%mdk + +%mdk-data-line={2997} +\noindent\mdline{2997}P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not \mdline{2999}\textquotedblleft{}hit\textquotedblright{}\mdline{2999} (\mdline{2999}i.e.\mdline{2999} not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification\mdline{3001} \mdline{3001}\textemdash{}\mdline{3001} using the +\mdline{3002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3002} message\mdline{3002} \mdline{3002}\textemdash{}\mdline{3002} to the master client, which can then take +action, such as remove the idle table entry.%mdk + +%mdk-data-line={3005} +\mdline{3005}Two fields of the \mdline{3005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3005} Protobuf message are used to implement idle +timeout:%mdk + +%mdk-data-line={3008} +\begin{itemize}%mdk + +%mdk-data-line={3008} +\item{} +%mdk-data-line={3008} +\mdline{3008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3008}: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, \mdline{3009}i.e.\mdline{3009} no +\mdline{3010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3010} message will ever be generated for this entry. When +a client reads a \mdline{3011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3011}, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry.%mdk%mdk + +%mdk-data-line={3015} +\item{} +%mdk-data-line={3015} +\mdline{3015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3015}: a Protobuf message with a single field (\mdline{3015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{3015}) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The \mdline{3017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3017} field must be unset for a +\mdline{3018}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3018} write. When reading a table entry, \mdline{3018}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3018} must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3023} +\noindent\mdline{3023}These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an \mdline{3025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3025} error code if at least one of these +conditions is met:%mdk + +%mdk-data-line={3028} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3028} +\item\mdline{3028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3028} is set to a non-zero value, or%mdk + +%mdk-data-line={3029} +\item\mdline{3029}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3029} is set%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3031} +\noindent\mdline{3031}The target should do its best to approximate the \mdline{3031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3031} value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the \mdline{3034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3034} write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for \mdline{3036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3036}.%mdk + +%mdk-data-line={3038} +\mdline{3038}P4Runtime does not support idle timeout for default entries. When the +\mdline{3039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3039} flag is set in a \mdline{3039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3039} message, \mdline{3039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3039} +must be set to 0 (default) and \mdline{3040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3040} must be unset. If the +server receives a \mdline{3041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3041} message which violates this, it must return an +\mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3042} error.%mdk + +%mdk-data-line={3044} +\mdline{3044}For more information about idle timeout, in particular regarding +\mdline{3045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3045}, please refer to the\mdline{3045}~\mdref{sec-table-idle-timeout-notification}{Table idle timeout +notifications}\mdline{3046} section.%mdk + +%mdk-data-line={3048} +\subsection{\mdline{3048}9.2.\hspace*{0.5em}\mdline{3048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3048} \mdline{3048}\&\mdline{3048} \mdline{3048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}\label{sec-action-profile-member-and-group}%mdk%mdk + +%mdk-data-line={3050} +\noindent\mdline{3050}P4Runtime defines an API for programming a PSA ActionProfile extern using +\mdline{3051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3051} messages. A PSA ActionSelector extern can be programmed +using both \mdline{3052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3052} and \mdline{3052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3052} messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table \mdline{3056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3056} for L3 routing, implemented with an action +selector \mdline{3057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3057}.%mdk + +%mdk-data-line={3059} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3060} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector(HashAlgorithm.crc32,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}size~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w1024,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}output\_width~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w10)~as;\\ +\\ +{\bfseries{\mdcolor{navy}action}}~set\_nhop(PortId\_t~p,~EthAddr~smac,~EthAddr~dmac)~\{\\ +~~istd.egress\_port~=~p;\\ +~~hdr.ethernet.smac~=~smac;\\ +~~hdr.ethernet.dmac~=~dmac;\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;~~{\mdcolor{darkgreen}//~LPM~on~destination~IP~address}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~set\_nhop;\\ +~~\}\\ +~~implementation~=~as;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3081} +\noindent\mdline{3081}When programming table \mdline{3081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3081} in the example above, a P4Runtime client should +specify the \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3082} in the \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3082} to be a reference to either an +action profile member or group. The reference is a \mdline{3083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3083} identifier that +uniquely identifies a member or group programmed in the action selector \mdline{3084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3084}.%mdk + +%mdk-data-line={3086} +\mdline{3086}If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata.%mdk + +%mdk-data-line={3091} +\mdline{3091}If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata.%mdk + +%mdk-data-line={3102} +\subsubsection{\mdline{3102}9.2.1.\hspace*{0.5em}\mdline{3102}Action Profile Member Programming}\label{sec-action-profile-member-programming}%mdk%mdk + +%mdk-data-line={3104} +\noindent\mdline{3104}Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a \mdline{3105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3105} identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the \mdline{3107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3107} +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the \mdline{3109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3109} attributes of the +tables \mdline{3110}\emph{must have an identical list of P4 actions}\mdline{3110}. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector.%mdk + +%mdk-data-line={3114} +\mdline{3114}An \mdline{3114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3114} entity update message has the following fields:%mdk + +%mdk-data-line={3116} +\begin{itemize}%mdk + +%mdk-data-line={3116} +\item{} +%mdk-data-line={3116} +\mdline{3116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3116} is the \mdline{3116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3116} identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3119} +\item{} +%mdk-data-line={3119} +\mdline{3119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3119} is the \mdline{3119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3119} identifier of the action profile member entry +being updated.%mdk%mdk + +%mdk-data-line={3122} +\item{} +%mdk-data-line={3122} +\mdline{3122}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3122} is the specification of the P4 action instance bound to the action +profile member entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3125} +\noindent\mdline{3125}An action profile member may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3128} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3128} +\item\mdline{3128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3128}: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an \mdline{3130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3130} error +code. The action specification must be provided, or the server must return +\mdline{3132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3132}. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return \mdline{3134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3134}.%mdk + +%mdk-data-line={3135} +\item\mdline{3135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3135}: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return \mdline{3136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3136}, +and the action specification must be provided, or the server must return +\mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3138}.%mdk + +%mdk-data-line={3139} +\item\mdline{3139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3139}: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a \mdline{3140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3140} error code. The member +must not be part of an action profile group, or the server must return +\mdline{3142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3142}. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return \mdline{3145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3145}. \mdline{3145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3145} is the only field which is +considered when performing a \mdline{3146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3146} and every other field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3148} +\subsubsection{\mdline{3148}9.2.2.\hspace*{0.5em}\mdline{3148}Action Profile Group Programming}\label{sec-action-profile-group-programming}%mdk%mdk + +%mdk-data-line={3150} +\noindent\mdline{3150}Action profile groups are entries in an ActionSelector and are referenced by a +\mdline{3151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3151} identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type.%mdk + +%mdk-data-line={3155} +\mdline{3155}An \mdline{3155}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3155} entity update message has the following fields:%mdk + +%mdk-data-line={3157} +\begin{itemize}%mdk + +%mdk-data-line={3157} +\item{} +%mdk-data-line={3157} +\mdline{3157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3157} is the \mdline{3157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3157} identifier of the PSA ActionSelector +extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3160} +\item{} +%mdk-data-line={3160} +\mdline{3160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3160} is the \mdline{3160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3160} identifier of the action profile group entry being +updated.%mdk%mdk + +%mdk-data-line={3163} +\item{} +%mdk-data-line={3163} +\mdline{3163}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3163} is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields:%mdk + +%mdk-data-line={3166} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3166} +\item\mdline{3166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3166} for looking up the member table in the selector.%mdk + +%mdk-data-line={3167} +\item\mdline{3167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3167} specifying the probability of the member\mdline{3167}'\mdline{3167}s selection at +runtime. 0 is not a valid \mdline{3168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3168} value and the server must return +\mdline{3169}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3169} if the client attempts to use it.%mdk + +%mdk-data-line={3170} +\item\mdline{3170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3170} is the controller-defined 32-bit port number that the member\mdline{3170}'\mdline{3170}s +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3174} +\item{} +%mdk-data-line={3174} +\mdline{3174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3174} is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +\mdline{3176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3176} update. See the subsection below for the\mdline{3176}~\mdref{sec-max-size-rules}{rules on setting +\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\mdline{3177}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3179} +\noindent\mdline{3179}An action profile group may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3182} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3182} +\item\mdline{3182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3182}: Add a new group entry bound to a set of existing action profile +members. \mdline{3183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}The~group\_id}}}\mdline{3183} must be different from ids of already programmed +groups for that selector, or the server must return an \mdline{3184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3184} error +code. All members specified in the group must exist in the selector, or the +server must return \mdline{3186}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3186}. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target.%mdk + +%mdk-data-line={3188} +\item\mdline{3188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3188}: Modify the member set specification of an existing group entry. An +entry with the \mdline{3189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3189} must exist, or the server must return +\mdline{3190}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3190}. All members specified in the group entry must exist in the +selector, or the server must return \mdline{3191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3191}. The value of \mdline{3191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3191} must +be identical to the value used when inserting the group, otherwise an +\mdline{3193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3193} error is returned.%mdk + +%mdk-data-line={3194} +\item\mdline{3194}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3194}: Delete the group entry and deallocate the \mdline{3194}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3194}. The group must +not be referenced in the table action of any table entry, or the server must +return a \mdline{3196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3196} error code. If the \mdline{3196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3196} is invalid, the +server must return \mdline{3197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3197}. \mdline{3197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3197} is the only field which is +considered when performing a \mdline{3198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3198} and every other field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3200} +\noindent\mdline{3200}When setting the group membership with \mdline{3200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3200} or \mdline{3200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3200}, the \mdline{3200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3200} +repeated field must not include duplicates, \mdline{3201}i.e.\mdline{3201} members with the same +\mdline{3202}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3202}. The \mdline{3202}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3202} field is used instead to logically \mdline{3202}\textquotedblleft{}repeat\textquotedblright{}\mdline{3202} the member +inside the group.%mdk + +%mdk-data-line={3205} +\mdline{3205}It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation \mdline{3206}\textquotedblleft{}stores\textquotedblright{}\mdline{3206} the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made.%mdk + +%mdk-data-line={3210} +\paragraph{\mdline{3210}9.2.2.1.\hspace*{0.5em}\mdline{3210}Rules on Setting \mdline{3210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\label{sec-max-size-rules}%mdk%mdk + +%mdk-data-line={3212} +\noindent\mdline{3212}The valid values for \mdline{3212}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3212} depend on the static \mdline{3212}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3212} included +in the P4Info message:%mdk + +%mdk-data-line={3215} +\begin{itemize}%mdk + +%mdk-data-line={3215} +\item{} +%mdk-data-line={3215} +\mdline{3215}If \mdline{3215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3215} is greater than 0, then \mdline{3215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3215} must be greater than 0, +and less than or equal to \mdline{3216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3216}. We assume that the target can +support selector groups for which the sum of all member weights is up to +\mdline{3218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3218}, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If \mdline{3219}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3219} is greater than \mdline{3219}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3219}, the server +must return \mdline{3220}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3220}.%mdk%mdk + +%mdk-data-line={3222} +\item{} +%mdk-data-line={3222} +\mdline{3222}Otherwise (\mdline{3222}i.e.\mdline{3222} if \mdline{3222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3222} is 0), the P4Runtime client can set +\mdline{3223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3223} to any value greater than or equal to 0.%mdk + +%mdk-data-line={3225} +\begin{itemize}%mdk + +%mdk-data-line={3225} +\item{} +%mdk-data-line={3225} +\mdline{3225}A \mdline{3225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3225} of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (\mdline{3228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3228} or \mdline{3228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3228}), the target must return a +\mdline{3229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3229} error.%mdk%mdk + +%mdk-data-line={3231} +\item{} +%mdk-data-line={3231} +\mdline{3231}If \mdline{3231}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3231} is greater than 0 and the value is not supported by the +target, the server must return a \mdline{3232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3232} error at +group-creation time.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3235} +\subsubsection{\mdline{3235}9.2.3.\hspace*{0.5em}\mdline{3235}One Shot Action Selector Programming}\label{sec-oneshot}%mdk%mdk + +%mdk-data-line={3237} +\noindent\mdline{3237}P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids.%mdk + +%mdk-data-line={3243} +\mdline{3243}One shots are programmed by choosing the \mdline{3243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3243} message as the +\mdline{3244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3244}. The \mdline{3244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3244} message consists of a set of +\mdline{3245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3245} messages, which in turn have the following fields:%mdk + +%mdk-data-line={3247} +\begin{itemize}%mdk + +%mdk-data-line={3247} +\item{} +%mdk-data-line={3247} +\mdline{3247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3247} is one of the actions specified by the table that is being +programmed.%mdk%mdk + +%mdk-data-line={3250} +\item{} +%mdk-data-line={3250} +\mdline{3250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3250} specifying the probability of the action\mdline{3250}'\mdline{3250}s selection at runtime. 0 is +not a valid \mdline{3251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3251} value and the server must return \mdline{3251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3251} if +the client attempts to use it. The sum of all weights across all +\mdline{3253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3253} messages for that \mdline{3253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3253} message must +not exceed the \mdline{3254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3254} specificed in the P4Info (if greater than 0), +or the server must return \mdline{3255}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3255}.%mdk%mdk + +%mdk-data-line={3257} +\item{} +%mdk-data-line={3257} +\mdline{3257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3257} is the controller-defined 32-bit port number that the action\mdline{3257}'\mdline{3257}s +liveness depends on. At runtime, the action must be excluded from selection if +the watch port is down.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3261} +\noindent\mdline{3261}Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics.%mdk + +%mdk-data-line={3266} +\mdline{3266}To preserve read-write symmetry, an implementation must answer \mdline{3266}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3266}s +with the original one shot messages. It may not return a desugared version of +the one shot message.%mdk + +%mdk-data-line={3270} +\mdline{3270}For example, consider the action selector table defined +\mdline{3271}\mdref{sec-action-profile-member-and-group}{here}\mdline{3271}. This table could be programmed +with the following one shot update:%mdk + +%mdk-data-line={3274} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3275} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{\\ +~~~~action\_profile\_action\_set~\{\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}1}\\ +~~~~~~~~watch:~{\mdcolor{purple}1}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}2}\\ +~~~~~~~~watch:~{\mdcolor{purple}2}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}3}\\ +~~~~~~~~watch:~{\mdcolor{purple}3}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3300} +\noindent\mdline{3300}Which would be equivalent to the following updates, where \mdline{3300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GROUP\_ID}}}\mdline{3300}, +\mdline{3301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_1}}}\mdline{3301}, \mdline{3301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_2}}}\mdline{3301}, and \mdline{3301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_3}}}\mdline{3301} are unused ids:%mdk + +%mdk-data-line={3303} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3304} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_1\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_2\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_3\\ +~~action~\{~~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +\}\\ +action\_profile\_group~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~group\_id:~GROUP\_ID\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_1\\ +~~~~weight:~{\mdcolor{purple}1}\\ +~~~~watch:~{\mdcolor{purple}1}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_2\\ +~~~~weight:~{\mdcolor{purple}2}\\ +~~~~watch:~{\mdcolor{purple}2}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_3\\ +~~~~weight:~{\mdcolor{purple}3}\\ +~~~~watch:~{\mdcolor{purple}3}\\ +~~\}\\ +\}\\ +table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{~action\_profile\_group\_id:~GROUP\_ID~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3345} +\noindent\mdline{3345}Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure\mdline{3346}~\mdref{sec-batching-and-ordering-of-updates}{correct ordering between the dependent +updates}\mdline{3347}. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct \mdline{3349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3349} batches are required.%mdk + +%mdk-data-line={3351} +\mdline{3351}It is possible to include several \mdline{3351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3351} messages with the same +exact \mdline{3352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3352} specification in one \mdline{3352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3352} message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the \mdline{3354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3354} field. Note that to preserve read-write symmetry, the server +must not coalesce multiple \mdline{3355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3355} messages with the same \mdline{3355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3355} +specification into one.%mdk + +%mdk-data-line={3358} +\mdline{3358}All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with \mdline{3359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3359} and +\mdline{3360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3360} messages. Programming some entries with one shots, and +other entries with \mdline{3361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3361} and \mdline{3361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3361} messages is +not allowed, and the server must return the error code \mdline{3362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3362} in +that case.%mdk + +%mdk-data-line={3365} +\mdline{3365}A P4Runtime server \mdline{3365}\emph{must}\mdline{3365} support the one shot style of programming tables with +an action selector implementation. Support for the \mdline{3366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3366} and +\mdline{3367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3367} style is \mdline{3367}\emph{optional}\mdline{3367}. If \mdline{3367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3367} and +\mdline{3368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3368} are not supported by a server, it must return an +\mdline{3369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3369} error for every \mdline{3369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3369} or \mdline{3369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3369} +message that it receives.%mdk + +%mdk-data-line={3372} +\subsubsection{\mdline{3372}9.2.4.\hspace*{0.5em}\mdline{3372}Constraints on action selector programming}\label{sec-constraints-on-action-selector-programming}%mdk%mdk + +%mdk-data-line={3374} +\noindent\mdline{3374}The PSA specification states that the following features are \mdline{3374}\emph{optional}\mdline{3374} in +action selector implementations\mdline{3375}~[\mdcite{psaactionselector}{21}]\mdline{3375}:%mdk + +%mdk-data-line={3377} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3377} +\item\mdline{3377}Support for non-empty groups where in the same group, different members are +bound to different actions.%mdk + +%mdk-data-line={3379} +\item\mdline{3379}Predictable data plane behavior when a matched table entry points to an empty +group.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={3382} +\noindent\mdline{3382}For 1., if a client tries to \mdline{3382}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3382} or \mdline{3382}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3382} a group with members bound to +different actions, the server should return \mdline{3383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3383} if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return \mdline{3389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3389} (modifying the action parameter values must be +supported, however).%mdk + +%mdk-data-line={3392} +\mdline{3392}PSA 1.1 introduces the \mdline{3392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3392} table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. \mdline{3396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3396} is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of \mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3399} at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +\mdline{3401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3401}. Even when \mdline{3401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3401} is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of \mdline{3405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3405} mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming.%mdk + +%mdk-data-line={3410} +\mdline{3410}The PSA specification includes a discussion on how to implement +\mdline{3411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3411} in software in the P4Runtime server +\mdline{3412}[\mdcite{psaemptygroupactionappendix}{24}]\mdline{3412}.%mdk + +%mdk-data-line={3414} +\subsection{\mdline{3414}9.3.\hspace*{0.5em}\mdline{3414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3414} \mdline{3414}\&\mdline{3414} \mdline{3414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-counterentry-directcounterentry}%mdk%mdk + +%mdk-data-line={3416} +\noindent\mdline{3416}PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The \mdline{3418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3418} +P4Runtime message can be used for all three types of PSA counters\mdline{3419} \mdline{3419}\textemdash{}\mdline{3419} \mdline{3419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{3419}, +\mdline{3420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{3420} and \mdline{3420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3420} \mdline{3420}\textemdash{}\mdline{3420} and consists of the following fields:%mdk + +%mdk-data-line={3422} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3422} +\item\mdline{3422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3422} is an \mdline{3422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3422}, corresponding to the number of octets.%mdk + +%mdk-data-line={3423} +\item\mdline{3423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3423} is an \mdline{3423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3423}, corresponding to the number of packets.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3425} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3426} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterData~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~byte\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}int64}}~packet\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3432} +\noindent\mdline{3432}P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of \mdline{3433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3433} and \mdline{3433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3433} fields, which +is equivalent to specifying the counter type \mdline{3434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3434}. Counters may +be defined as direct or indirect (indexed) instances.%mdk + +%mdk-data-line={3437} +\subsubsection{\mdline{3437}9.3.1.\hspace*{0.5em}\mdline{3437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-directcounterentry}%mdk%mdk + +%mdk-data-line={3439} +\noindent\mdline{3439}A direct counter is a direct resource associated with a \mdline{3439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3439} (see +\mdline{3440}\mdref{sec-direct-resources}{Direct Resources}\mdline{3440}). The \mdline{3440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3440} field of the +\mdline{3441}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3441} message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +\mdline{3444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3444} message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed.%mdk + +%mdk-data-line={3447} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3448} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectCounterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3454} +\noindent\mdline{3454}A \mdline{3454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3454} may only include an \mdline{3454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3454} message of type \mdline{3454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3454} with a +\mdline{3455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3455}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3457} +\begin{itemize}%mdk + +%mdk-data-line={3457} +\item{} +%mdk-data-line={3457} +\mdline{3457}the \mdline{3457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3457} field must match \mdline{3457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry.match}}}\mdline{3457} of the table entry +to which this direct counter entry is associated. If a matching \mdline{3458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3458} +is not found, the server returns the error code \mdline{3459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3459}.%mdk%mdk + +%mdk-data-line={3461} +\item{} +%mdk-data-line={3461} +\mdline{3461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3461} is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3465} +\noindent\mdline{3465}Specifying \mdline{3465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3465} in an \mdline{3465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3465} message of type \mdline{3465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3465} or +\mdline{3466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3466} is not allowed, and the server must return the error code +\mdline{3467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3467} in that case.%mdk + +%mdk-data-line={3469} +\mdline{3469}A client may use \mdline{3469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3469} in two ways to read the contents of a +\mdline{3470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3470}:%mdk + +%mdk-data-line={3472} +\begin{itemize}%mdk + +%mdk-data-line={3472} +\item{} +%mdk-data-line={3472} +\mdline{3472}As a direct resource associated with a table entry, request the server to +return the counter value in the \mdline{3473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3473} field of the \mdline{3473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3473} message +(see\mdline{3474}~\mdref{sec-direct-resources}{Direct resources}\mdline{3474}).%mdk%mdk + +%mdk-data-line={3476} +\item{} +%mdk-data-line={3476} +\mdline{3476}Explicitly request the counter value by including the \mdline{3476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3476} in +the \mdline{3477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3477}. The \mdline{3477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3477} field must match the \mdline{3477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3477} +whose counter is being read. If no such entry is found, the server returns the +error code \mdline{3479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3479}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3481} +\subsubsection{\mdline{3481}9.3.2.\hspace*{0.5em}\mdline{3481}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}\label{sec-counterentry}%mdk%mdk + +%mdk-data-line={3483} +\noindent\mdline{3483}An indirect or indexed counter is not associated with a specific \mdline{3483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3483} +and may be updated independently of any action. It may be read or written using +the P4Runtime \mdline{3485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3485} message whose fields are defined as follows:%mdk + +%mdk-data-line={3487} +\begin{itemize}%mdk + +%mdk-data-line={3487} +\item{} +%mdk-data-line={3487} +\mdline{3487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3487} is a \mdline{3487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3487}, the unique identifier for the counter.%mdk%mdk + +%mdk-data-line={3489} +\item{} +%mdk-data-line={3489} +\mdline{3489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3489} is a Protobuf message that encapsulates an \mdline{3489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3489}, used to index into +the counter array.%mdk%mdk + +%mdk-data-line={3492} +\item{} +%mdk-data-line={3492} +\mdline{3492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3492} is a Protobuf message of type \mdline{3492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3492}, which represents the +counter value.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3495} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3496} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~counter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3503} +\noindent\mdline{3503}The \mdline{3503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3503} can only be used in a \mdline{3503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3503} with the \mdline{3503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3503} update +type. The P4Runtime server must return an \mdline{3504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3504} error code for +update types \mdline{3505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3505} and \mdline{3505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3505}. By default all the counter entries in the +array have default value 0.%mdk + +%mdk-data-line={3508} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3508} +\item\mdline{3508}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3508}: Server returns the error code \mdline{3508}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3508}.%mdk + +%mdk-data-line={3509} +\item\mdline{3509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3509}: Modify an indirect counter instance whose unique id is \mdline{3509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3509} +and array index is specified by \mdline{3510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3510}. The counter value is set to the value +specified by the client in the \mdline{3511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3511} field. Note that the counter value is +not modified if this Protobuf field is not set. If \mdline{3512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3512} is omitted all +counter values in the array will be set to the value provided by the +client. The server must return \mdline{3514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3514} for a negative index value +and \mdline{3515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3515} if the index value exceeds the size of the counter array.%mdk + +%mdk-data-line={3516} +\item\mdline{3516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3516}: Server returns the error code \mdline{3516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3516}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3518} +\noindent\mdline{3518}A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a \mdline{3519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3519} by including a \mdline{3519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3519} +entity for each of the instances, specifying the \mdline{3520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3520} and +\mdline{3521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3521}. Wildcard reads are also supported as follows.%mdk + +%mdk-data-line={3523} +\begin{itemize}%mdk + +%mdk-data-line={3523} +\item{} +%mdk-data-line={3523} +\mdline{3523}If the \mdline{3523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3523} field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the \mdline{3524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3524}.%mdk%mdk + +%mdk-data-line={3526} +\item{} +%mdk-data-line={3526} +\mdline{3526}If the \mdline{3526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3526} field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id \mdline{3527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3527}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3529} +\subsection{\mdline{3529}9.4.\hspace*{0.5em}\mdline{3529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3529} \mdline{3529}\&\mdline{3529} \mdline{3529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-meterentry-directmeterentry}%mdk%mdk + +%mdk-data-line={3531} +\noindent\mdline{3531}Meters are an advanced mechanism for keeping statistics, involving stateful +\mdline{3532}\textquotedblleft{}marking\textquotedblright{}\mdline{3532} and usually \mdline{3532}\textquotedblleft{}throttling\textquotedblright{}\mdline{3532} of packets based on configured rates of +traffic. The PSA metering function is based on the \mdline{3533}\emph{Two Rate Three Color Marker}\mdline{3533} +(trTCM) defined in RFC 2698\mdline{3534}~[\mdcite{rfc2698}{2}]\mdline{3534}. The trTCM meters an arbitrary packet +stream using two configured rates\mdline{3535} \mdline{3535}\textemdash{}\mdline{3535} the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes\mdline{3536} \mdline{3536}\textemdash{}\mdline{3536} and +\mdline{3537}\textquotedblleft{}marks\textquotedblright{}\mdline{3537} its packets as GREEN, YELLOW or RED based on the observed rate.%mdk + +%mdk-data-line={3539} +\mdline{3539}A meter may be configured as a direct or indirect instance, similar to a +counter. The \mdline{3540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{3540} P4Runtime message represents meter configuration.%mdk + +%mdk-data-line={3542} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3543} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterConfig~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~cir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~Committed~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~cburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};~~{\mdcolor{darkgreen}//~Committed~Burst~Size}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};~~{\mdcolor{darkgreen}//~Peak~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};~~{\mdcolor{darkgreen}//~Peak~Burst~Size}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3551} +\subsubsection{\mdline{3551}9.4.1.\hspace*{0.5em}\mdline{3551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-directmeterentry}%mdk%mdk + +%mdk-data-line={3553} +\noindent\mdline{3553}A direct meter is a direct resource associated with a \mdline{3553}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3553} (see\mdline{3553}~\mdref{sec-direct-resources}{Direct +resources}\mdline{3554}). The \mdline{3554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3554} field of the \mdline{3554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3554} +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +\mdline{3558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3558} message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed.%mdk + +%mdk-data-line={3561} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3562} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectMeterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3568} +\noindent\mdline{3568}A \mdline{3568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3568} may only include an \mdline{3568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3568} message of type \mdline{3568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3568} with a +\mdline{3569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3569}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3571} +\begin{itemize}%mdk + +%mdk-data-line={3571} +\item{} +%mdk-data-line={3571} +\mdline{3571}the \mdline{3571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3571} field must match the match key of the \mdline{3571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3571} +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching \mdline{3573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3573} is not found, +the server returns the error code \mdline{3574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3574}.%mdk%mdk + +%mdk-data-line={3576} +\item{} +%mdk-data-line={3576} +\mdline{3576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3576} is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3580} +\noindent\mdline{3580}Specifying \mdline{3580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3580} in an \mdline{3580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3580} message of type \mdline{3580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3580} or +\mdline{3581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3581} is not allowed, and the server must return the error code +\mdline{3582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3582} in that case.%mdk + +%mdk-data-line={3584} +\mdline{3584}A client may use \mdline{3584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3584} in two ways to read a \mdline{3584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3584} config.%mdk + +%mdk-data-line={3586} +\begin{itemize}%mdk + +%mdk-data-line={3586} +\item{} +%mdk-data-line={3586} +\mdline{3586}As a direct resource associated with a table entry, request the server to +return the meter config in the \mdline{3587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3587} field of the \mdline{3587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3587} +message (see\mdline{3588}~\mdref{sec-direct-resources}{Direct resources}\mdline{3588}).%mdk%mdk + +%mdk-data-line={3590} +\item{} +%mdk-data-line={3590} +\mdline{3590}Explicitly request the meter configuration by including the \mdline{3590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3590} +in the \mdline{3591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3591}. The \mdline{3591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3591} field must match the +\mdline{3592}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3592} whose meter config is being read. If no such entry is found, the +server returns the error code \mdline{3593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3593}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3595} +\subsubsection{\mdline{3595}9.4.2.\hspace*{0.5em}\mdline{3595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}\label{sec-meterentry}%mdk%mdk + +%mdk-data-line={3597} +\noindent\mdline{3597}An indirect or indexed meter is not associated with a specific \mdline{3597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3597} and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime \mdline{3599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3599} message whose fields are defined as +follows:%mdk + +%mdk-data-line={3602} +\begin{itemize}%mdk + +%mdk-data-line={3602} +\item{} +%mdk-data-line={3602} +\mdline{3602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3602} is a \mdline{3602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3602}, the unique identifier for the meter.%mdk%mdk + +%mdk-data-line={3604} +\item{} +%mdk-data-line={3604} +\mdline{3604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3604} is a Protobuf message that encapsulates an \mdline{3604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3604}, used to index into +a meter array.%mdk%mdk + +%mdk-data-line={3607} +\item{} +%mdk-data-line={3607} +\mdline{3607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3607} is a Protobuf message of type \mdline{3607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{3607}, which represents the +meter configuration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3610} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3611} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~meter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3618} +\noindent\mdline{3618}The \mdline{3618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3618} can only be used in a \mdline{3618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3618} with the \mdline{3618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3618} update +type. The P4Runtime server must return an \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3619} error code for +update types \mdline{3620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3620} and \mdline{3620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3620}. By default all the meter entries in the +array have a default configuration (GREEN for all packets).%mdk + +%mdk-data-line={3623} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3623} +\item\mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3623}: Server returns the error code \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3623}.%mdk + +%mdk-data-line={3624} +\item\mdline{3624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3624}: Modify an indirect meter instance whose unique id is \mdline{3624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3624} and +array index is specified by \mdline{3625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3625}. The meter is reconfigured using the +\mdline{3626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3626} field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the \mdline{3628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3628} field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if \mdline{3630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3630} is unset). The server must return \mdline{3630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3630} for a +negative index value and \mdline{3631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3631} if the index value exceeds the size of +the meter array.%mdk + +%mdk-data-line={3633} +\item\mdline{3633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3633}: Server returns the error code \mdline{3633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3633}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3635} +\noindent\mdline{3635}A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a \mdline{3636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3636} by including a \mdline{3636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3636} entity for each +of the instances, specifying the \mdline{3637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3637} and \mdline{3637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3637}. Wildcard reads are also +supported as follows:%mdk + +%mdk-data-line={3640} +\begin{itemize}%mdk + +%mdk-data-line={3640} +\item{} +%mdk-data-line={3640} +\mdline{3640}If the \mdline{3640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3640} field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the \mdline{3641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3641}.%mdk%mdk + +%mdk-data-line={3643} +\item{} +%mdk-data-line={3643} +\mdline{3643}If the \mdline{3643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3643} field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id \mdline{3644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3644}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3646} +\subsection{\mdline{3646}9.5.\hspace*{0.5em}\mdline{3646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}\label{sec-packetreplicationengineentry}%mdk%mdk + +%mdk-data-line={3648} +\noindent\mdline{3648}The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets.%mdk + +%mdk-data-line={3654} +\subsubsection{\mdline{3654}9.5.1.\hspace*{0.5em}\mdline{3654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}\label{sec-multicastgroupentry}%mdk%mdk + +%mdk-data-line={3656} +\noindent\mdline{3656}Multicasting is achieved in PSA programs by setting the \mdline{3656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{3656} +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the \mdline{3659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{3659} API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example.%mdk + +%mdk-data-line={3664} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3665} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~arp\_multicast({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ethernet.isValid()~\&\&\\ +~~~~~~~~hdr.ethernet.eth\_type~==~ETH\_TYPE\_ARP)~\{\\ +~~~~~~smeta.multicast\_group~=~(MulticastGroup\_t)~{\mdcolor{purple}1};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3675} +\noindent\mdline{3675}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={3678} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3679} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~multicast\_group\_entry~\{\\ +~~~~~~multicast\_group\_id:~{\mdcolor{purple}1}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}5}~instance:~{\mdcolor{purple}1}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}12}~instance:~{\mdcolor{purple}2}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}18}~instance:~{\mdcolor{purple}3}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}24}~instance:~{\mdcolor{purple}4}~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3693} +\noindent\mdline{3693}As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +\mdline{3698}\mdref{sec-translation-of-port-numbers}{PSA Metadata Translation}\mdline{3698} section.%mdk + +%mdk-data-line={3700} +\mdline{3700}The egress packets may be distinguished for further processing in the egress +using the \mdline{3701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{3701} metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 \mdline{3703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{3703} metadata is set to a value that is not +programmed in the PRE, then the packet is dropped.%mdk + +%mdk-data-line={3706} +\mdline{3706}A multicast group may be inserted, modified or deleted as per the following +semantics.%mdk + +%mdk-data-line={3709} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3709} +\item\mdline{3709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3709}: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The \mdline{3710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3710} field is a \mdline{3710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3710} and must be greater +than 0 (see explanation\mdline{3711}~\mdref{sec-valid-values-for-mg-id}{below}\mdline{3711}), or the +P4Runtime server must return an \mdline{3712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3712} error. The replica +\mdline{3713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{3713} ID is also a \mdline{3713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3713}, and its value may not exceed the maximum +allowed by the target for the \mdline{3714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{3714} type (0 is allowed), or the +server must return an \mdline{3715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3715} error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of \mdline{3717}\emph{both}\mdline{3717} \mdline{3717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{3717} and \mdline{3717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{3717}, or the server +must return \mdline{3718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3718}.%mdk + +%mdk-data-line={3719} +\item\mdline{3719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3719}: Modify the set of replicas for a given multicast group entry, +indexed by the given \mdline{3720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3720}. Same restrictions as \mdline{3720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3720} apply +here.%mdk + +%mdk-data-line={3722} +\item\mdline{3722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3722}: Delete the multicast group indexed by the given +\mdline{3723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3723}. The replicas need not be provided for this +operation. Any packets with their \mdline{3724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{3724} metadata in the data plane +set to the deleted \mdline{3725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3725} will be dropped.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3727} +\noindent\mdline{3727}When reading a multicast group, only \mdline{3727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3727} is considered. All +other fields in \mdline{3728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{3728} are ignored. To perform a \mdline{3728}\emph{wildcard}\mdline{3728} +\mdline{3729}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{3729} on all configured multicast group entries, the \mdline{3729}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3729} field +must be set to 0, its default value.%mdk + +%mdk-data-line={3732} +\paragraph{\mdline{3732}9.5.1.1.\hspace*{0.5em}\mdline{3732}Valid Values for \mdline{3732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}}\label{sec-valid-values-for-mg-id}%mdk%mdk + +%mdk-data-line={3734} +\noindent\mdline{3734}The PSA specification states that the valid \mdline{3734}\emph{data plane}\mdline{3734} values for multicast +group ids (\mdline{3735}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroup\_t}}}\mdline{3735}) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target\mdline{3737}~[\mdcite{psatranslation}{23}]\mdline{3737}. This means that, in the absence of +translation, the client must set the \mdline{3738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3738} field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special \mdline{3740}\emph{wildcard}\mdline{3740} value which is used to read all the multicast groups +configured in the target, the \mdline{3741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3741} field must never be set to 0 +when performing a \mdline{3742}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{3742} RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value.%mdk + +%mdk-data-line={3747} +\subsubsection{\mdline{3747}9.5.2.\hspace*{0.5em}\mdline{3747}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}\label{sec-clonesessionentry}%mdk%mdk + +%mdk-data-line={3749} +\noindent\mdline{3749}PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +\mdline{3753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3753} identifier and a boolean flag \mdline{3753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone}}}\mdline{3753} in the packet +metadata. The \mdline{3754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3754} serves as a handle to the clone attributes, +namely a set \mdline{3755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}replicas}}}\mdline{3755} of \mdline{3755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(egress~port,~instance)}}}\mdline{3755} pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +\mdline{3758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{3758} API.%mdk + +%mdk-data-line={3760} +\mdline{3760}The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the \mdline{3763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_low\_ttl}}}\mdline{3763} control block is applied in the ingress +pipeline to create an ingress-to-egress clone.%mdk + +%mdk-data-line={3766} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3767} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~clone\_low\_ttl({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ipv4.isValid()~\&\&\\ +~~~~~~~~hdr.ipv4.ttl~\textless{}=~LOW\_TTL\_THRESHOLD)~\{\\ +~~~~~~smeta.clone\_session\_id~=~{\mdcolor{purple}10}w100;\\ +~~~~~~smeta.clone~=~{\bfseries{\mdcolor{navy}true}};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3779} +\noindent\mdline{3779}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={3782} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3783} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~clone\_session\_entry~\{\\ +~~~~~~session\_id:~{\mdcolor{purple}100}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}0xfffffffd}~instance:~{\mdcolor{purple}1}~\}~{\mdcolor{darkgreen}\#~to~CPU}\\ +~~~~~~class\_of\_service:~{\mdcolor{purple}2}\\ +~~~~~~packet\_length\_bytes:~{\mdcolor{purple}4096}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3796} +\noindent\mdline{3796}As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type \mdline{3800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{3800}~[\mdcite{psatranslation}{23}]\mdline{3800}). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes.%mdk + +%mdk-data-line={3805} +\mdline{3805}The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port \mdline{3806}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfffffffd}}}\mdline{3806}; see +\mdline{3807}\mdref{sec-translation-of-port-numbers}{Translation of Port Numbers}\mdline{3807}). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port.%mdk + +%mdk-data-line={3810} +\mdline{3810}If the \mdline{3810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3810} data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created.%mdk + +%mdk-data-line={3813} +\mdline{3813}A clone session may be inserted, modified or deleted as per the following +semantics:%mdk + +%mdk-data-line={3816} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3816} +\item\mdline{3816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3816}: Add a new clone session entry bound to a set of egress ports and +replica IDs. The \mdline{3817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{3817} is a \mdline{3817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3817} and must be greater than 0 (see +explanation\mdline{3818}~\mdref{sec-valid-values-for-session-id}{below}\mdline{3818}), or the P4Runtime +server must return an \mdline{3819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3819} error. The replica \mdline{3819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{3819} ID is +also a \mdline{3820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3820}, and its value may not exceed the maximum allowed by the +target for the \mdline{3821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{3821} type (0 is allowed), or the server must also +return an \mdline{3822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3822} error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (\mdline{3825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}class\_of\_service}}}\mdline{3825} field). This value must be a valid +value for the PSA \mdline{3826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ClassOfService\_t}}}\mdline{3826} type, which supports runtime translation +by default\mdline{3827}~[\mdcite{psatranslation}{23}]\mdline{3827}, or the server must return +\mdline{3828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3828}. See\mdline{3828}~\mdref{sec-translation-of-port-numbers}{PSA Metadata +Translation}\mdline{3829} for more information. The +\mdline{3830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{3830} field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +\mdline{3832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{3832} field is 0 (default), no truncation on the clone will be +performed.%mdk + +%mdk-data-line={3834} +\item\mdline{3834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3834}: Modify the attributes of a given clone session entry, indexed by the +given \mdline{3835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3835}. Same restrictions as \mdline{3835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3835} apply here.%mdk + +%mdk-data-line={3836} +\item\mdline{3836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3836}: Delete the clone session indexed by the given +\mdline{3837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3837}. Other fields need not be provided for this operation. Any +packet with their \mdline{3838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3838} metadata in the data plane set to the +deleted \mdline{3839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{3839} will no longer be cloned.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3841} +\noindent\mdline{3841}When reading a clone session, only \mdline{3841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{3841} is considered. All other fields +in \mdline{3842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{3842} are ignored. To perform a \mdline{3842}\emph{wildcard}\mdline{3842} \mdline{3842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{3842} on all +configured clone session entries, the \mdline{3843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{3843} field must be set to 0, its +default value. The \mdline{3844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{3844} field can never be equal to 0 in a \mdline{3844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{3844} +RPC. If it does, the server must return an \mdline{3845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3845} error.%mdk + +%mdk-data-line={3847} +\paragraph{\mdline{3847}9.5.2.1.\hspace*{0.5em}\mdline{3847}Valid Values for \mdline{3847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}}\label{sec-valid-values-for-session-id}%mdk%mdk + +%mdk-data-line={3849} +\noindent\mdline{3849}The PSA specification states that the valid \mdline{3849}\emph{data plane}\mdline{3849} values for clone +session ids (\mdline{3850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{3850}) range from 0 to the maximum value supported by +the target\mdline{3851}~[\mdcite{psatranslation}{23}]\mdline{3851}. Note that unlike for\mdline{3851}~\mdref{sec-valid-values-for-mg-id}{multicast group +ids}\mdline{3852}, 0 is a valid \mdline{3852}\emph{data plane}\mdline{3852} value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special \mdline{3854}\emph{wildcard}\mdline{3854} value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a \mdline{3855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{3855} +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is \mdline{3857}\emph{not}\mdline{3857} enabled, we effectively +\mdline{3858}\textquotedblleft{}lose\textquotedblright{}\mdline{3858} one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (\mdline{3859}e.g.\mdline{3859} because the target supports a very +limited number of clone sessions), one can enable translation on +\mdline{3861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{3861} and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id.%mdk + +%mdk-data-line={3864} +\subsection{\mdline{3864}9.6.\hspace*{0.5em}\mdline{3864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}\label{sec-valuesetentry}%mdk%mdk + +%mdk-data-line={3866} +\noindent\mdline{3866}Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the \mdline{3870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{3870} state.%mdk + +%mdk-data-line={3872} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3873} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}state}}~parse\_l2~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}(MAX\_TRILL\_TYPES)~trill\_types;}\\ +~~extract(hdr.ethernet);\\ +~~{\bfseries{\mdcolor{navy}select}}~(hdr.ethernet.eth\_type)~\{\\ +~~~~ETH\_TYPE\_IPV4:~parse\_ipv4;\\ +~~~~ETH\_TYPE\_IPV6:~parse\_ipv6;\\ +~~~~trill\_types:~~~parse\_trill\_types;\\ +~~~~\_:~~~~~~~~~~~~~reject;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3885} +\noindent\mdline{3885}The corresponding entry in the P4Info for this Value Set is:%mdk + +%mdk-data-line={3887} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3888} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}trill\_types}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~\textless{}MAX\_TRILL\_TYPES\textgreater{}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3902} +\noindent\mdline{3902}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={3905} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3906} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x22f3}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x893b}~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3924} +\noindent\mdline{3924}As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the \mdline{3926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{3926} state.%mdk + +%mdk-data-line={3928} +\mdline{3928}A \mdline{3928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{3928} entity update message has the following fields:%mdk + +%mdk-data-line={3930} +\begin{itemize}%mdk + +%mdk-data-line={3930} +\item{} +%mdk-data-line={3930} +\mdline{3930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{3930} is the \mdline{3930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3930} identifier of the Value Set instance, as +defined in P4Info.%mdk%mdk + +%mdk-data-line={3933} +\item{} +%mdk-data-line={3933} +\mdline{3933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3933} is a repeated field of type \mdline{3933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{3933}. When \mdline{3933}\textquotedblleft{}selecting\textquotedblright{}\mdline{3933} +against a Value Set, every member will be considered and if at least one +\mdline{3935}\textquotedblleft{}matches\textquotedblright{}\mdline{3935}, the corresponding parser transition will be taken. Each +\mdline{3936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{3936} contains a repeated field of \mdline{3936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3936} messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a \mdline{3938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{3938} if and only if +it matches all its \mdline{3939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3939} messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. \mdline{3941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3941} messages in a \mdline{3941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{3941} follow +the\mdline{3942}~\mdref{sec-match-format}{same rules}\mdline{3942} as in a \mdline{3942}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3942}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3944} +\noindent\mdline{3944}A \mdline{3944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{3944} may only be modified. If the update type is \mdline{3944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3944} or +\mdline{3945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3945}, the server must return an \mdline{3945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3945} error. If the update type +is \mdline{3946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3946}, the server writes the members given in the repeated field to the +Value Set entry indexed by the given \mdline{3947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{3947}. The maximum number of +matches must not exceed the maximum size given by the \mdline{3948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{3948} field in P4Info of +the Value Set, otherwise the server must return a \mdline{3949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3949} error. To +empty a Value Set (\mdline{3950}i.e.\mdline{3950} restore it to its initial state), the P4Runtime client +can perform a \mdline{3951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3951} update with an empty \mdline{3951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3951} repeated field.%mdk + +%mdk-data-line={3953} +\mdline{3953}To facilitate\mdline{3953}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{3953}, the server must +return an \mdline{3954}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3954} error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary and range matches: +overlapping entries do not need to be ordered and the parse state transition +is determined by whether or not the packet matches at least one entry in the +set.%mdk + +%mdk-data-line={3960} +\mdline{3960}See Appendix\mdline{3960}~\mdref{sec-value-set-example}{A.3}\mdline{3960} for a more complex Value Set example.%mdk + +%mdk-data-line={3962} +\subsection{\mdline{3962}9.7.\hspace*{0.5em}\mdline{3962}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}\label{sec-registerentry}%mdk%mdk + +%mdk-data-line={3964} +\noindent\mdline{3964}The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The \mdline{3965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3965} P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations.%mdk + +%mdk-data-line={3969} +\mdline{3969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3969} has the following fields:%mdk + +%mdk-data-line={3971} +\begin{itemize}%mdk + +%mdk-data-line={3971} +\item{} +%mdk-data-line={3971} +\mdline{3971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{3971}, which identifies the PSA Register extern instance which is +being accessed by the client; the \mdline{3972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{3972} is specified by the P4Info +message.%mdk%mdk + +%mdk-data-line={3975} +\item{} +%mdk-data-line={3975} +\mdline{3975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3975}, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the \mdline{3977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3977} message +used for the request. When an \mdline{3978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3978} is provided , the server must validate +its value, and return \mdline{3979}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3979} for a negative index or +\mdline{3980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3980} if the index exceeds the size of the register array.%mdk%mdk + +%mdk-data-line={3982} +\item{} +%mdk-data-line={3982} +\mdline{3982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3982}: the data to be written to the array (if \mdline{3982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3982} is part of a +\mdline{3983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3983} message) or the data read from the array (if \mdline{3983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3983} is +part of a \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3984} message). The \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3984} field is a \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{3984} message and +must match the format described by the \mdline{3985}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{3985} field of the corresponding +Register entry in the P4Info, or the server must return an \mdline{3986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3986} +error.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3989} +\subsection{\mdline{3989}9.8.\hspace*{0.5em}\mdline{3989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}\label{sec-digestentry}%mdk%mdk + +%mdk-data-line={3991} +\noindent\mdline{3991}A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly.%mdk + +%mdk-data-line={3996} +\mdline{3996}The \mdline{3996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{3996} P4Runtime entity is used to \mdline{3996}\textbf{configure}\mdline{3996} how the device must +generate digest messages. The \mdline{3997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{3997} Protobuf message is not used to +carry digest data, which is done on the \mdline{3998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{3998} bidirectional stream +using the \mdline{3999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{3999} (digest data sent by the target to the client) and +\mdline{4000}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4000} (digest data acknowledgments sent by the client to the target) +Protobuf messages.%mdk + +%mdk-data-line={4003} +\mdline{4003}In this section, we refer to the data learned by a single data plane call to +\mdline{4004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}T\textgreater{}::pack}}}\mdline{4004} as a \mdline{4004}\textquotedblleft{}digest message\textquotedblright{}\mdline{4004} and we use \mdline{4004}\textquotedblleft{}digest list\textquotedblright{}\mdline{4004} to designate +the list of digest messages bundled by the P4Runtime service in a single +\mdline{4006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4006} stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are \mdline{4008}\textquotedblleft{}duplicate\textquotedblright{}\mdline{4008} if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are \mdline{4009}\textquotedblleft{}distinct\textquotedblright{}\mdline{4009} +if they are not duplicate.%mdk + +%mdk-data-line={4012} +\mdline{4012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4012} has the following fields:%mdk + +%mdk-data-line={4014} +\begin{itemize}%mdk + +%mdk-data-line={4014} +\item{} +%mdk-data-line={4014} +\mdline{4014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4014}, which identifies the PSA Digest extern instance which emitted the +data; the \mdline{4015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4015} is determined by the P4Info message.%mdk%mdk + +%mdk-data-line={4017} +\item{} +%mdk-data-line={4017} +\mdline{4017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4017}, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +\mdline{4019}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4019}; these parameters are:%mdk + +%mdk-data-line={4021} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4021} +\item\mdline{4021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4021}: the maximum server buffering delay in nanoseconds for an +outstanding digest message.%mdk + +%mdk-data-line={4023} +\item\mdline{4023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4023}: the maximum digest list size\mdline{4023} \mdline{4023}\textemdash{}\mdline{4023} in number of digest +messages\mdline{4024} \mdline{4024}\textemdash{}\mdline{4024} sent by the server to the client as a single \mdline{4024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4024} +Protobuf message.%mdk + +%mdk-data-line={4026} +\item\mdline{4026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4026}: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4030} +\noindent\mdline{4030}Here is the significance of the different \mdline{4030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4030} types for \mdline{4030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4030}:%mdk + +%mdk-data-line={4032} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4032} +\item\mdline{4032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4032}: Enable server generation of \mdline{4032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4032} messages for given digest +instance and use provided configuration parameters.%mdk + +%mdk-data-line={4034} +\item\mdline{4034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4034}: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance.%mdk + +%mdk-data-line={4036} +\item\mdline{4036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4036}: Disable server generation of \mdline{4036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4036} messages for given digest +instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4039} +\noindent\mdline{4039}A server should buffer digest messages until either:%mdk + +%mdk-data-line={4041} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4041} +\item\mdline{4041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4041} time has passed since the first digest message was added to +the empty buffer, or%mdk + +%mdk-data-line={4043} +\item\mdline{4043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4043} \mdline{4043}\emph{distinct}\mdline{4043} digest messages have been received from the +data plane and added to the buffer%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4046} +\noindent\mdline{4046}At which point the server should, with best effort, generate a \mdline{4046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4046} +stream message with the buffer contents and send it to the master client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software.%mdk + +%mdk-data-line={4052} +\mdline{4052}To avoid sending duplicate digest messages across different \mdline{4052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4052} +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the master client indicates that it has received the +digest list and acted on it. The server must keep a \mdline{4055}\textquotedblleft{}cache\textquotedblright{}\mdline{4055} containing the set +of all digest messages that have been sent, but not acknowledged yet by the +master client, up-to \mdline{4057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4057} in the past. The server must delete all +cache entries for a given digest list when they are at least \mdline{4058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4058} +old or when a matching \mdline{4059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4059} message (\mdline{4059}i.e.\mdline{4059} with the same \mdline{4059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4059} +and \mdline{4060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}list\_id}}}\mdline{4060} fields as the \mdline{4060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4060} message) is received.%mdk + +%mdk-data-line={4062} +\mdline{4062}The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged \mdline{4067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4067} messages.%mdk + +%mdk-data-line={4069} +\mdline{4069}When \mdline{4069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4069} is set to 0 and / or \mdline{4069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4069} is set to 1, the +server should, with best effort, generate a \mdline{4070}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4070} message for every +digest message generated by the data plane which is not already in the cache. If +\mdline{4072}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4072} is set to 0, the cache must always be an empty set. If +\mdline{4073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4073} is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +\mdline{4075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4075} configuration parameter.%mdk + +%mdk-data-line={4077} +\mdline{4077}The P4Runtime server may empty the digest message cache in case of a client +mastership change.%mdk + +%mdk-data-line={4080} +\mdline{4080}Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server:%mdk + +%mdk-data-line={4083} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4084} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestStream~stream;\\ +DigestCache~cache;\\ +DigestBuffer~buffers;\\ +\\ +{\mdcolor{darkgreen}//~sends~digest~list~when~it~is~ready}\\ +send\_buffer(Id~digest\_id)~\{\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~stream.write(DigestList(buffer));\\ +~~cache.merge(buffer);~~{\mdcolor{darkgreen}//~updates~cache~with~new~digest~list}\\ +~~buffer.clear();\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~data~plane~digest~messages~from~device}\\ +handle\_dataplane\_digest(Digest~msg)~\{\\ +~~digest\_id~=~msg.digest\_id();\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~{\bfseries{\mdcolor{navy}if}}~(msg~in~cache~{\mdcolor{teal}OR}~msg~in~buffer)~{\bfseries{\mdcolor{navy}return}};\\ +~~buffer.enqueue(msg);\\ +~~{\bfseries{\mdcolor{navy}if}}~(buffer.length()~\textless{}~max\_list\_size(digest\_id))~{\bfseries{\mdcolor{navy}return}};\\ +~~send\_buffer(digest\_id);\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~ack~messages~received~on~the~stream}\\ +handle\_stream\_ack(DigestListAck~ack)~\{\\ +~~{\mdcolor{darkgreen}//~clear~all~cache~entries~matching~the~tuple~(digest\_id,~list\_id)}\\ +~~cache.erase(~(ack.digest\_id(),~ack.list\_id()~)\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~loop~to~enforce~timeouts}\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~now~=~now();\\ +~~{\mdcolor{darkgreen}//~check~for~buffers~that~need~to~be~sent}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~buffer)~in~buffers)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~buffer.first\_enq\_time()~\textgreater{}=~max\_timeout\_ns(digest\_id))\\ +~~~~~~send\_buffer(buffer\_id);\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~check~for~expired~entries~in~cache}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~list\_id,~sent\_time)~in~cache)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~sent\_time~\textgreater{}=~ack\_timeout\_ns(digest\_id))\\ +~~~~~~cache.erase(~(digest\_id,~list\_id)~);\\ +~~\}\\ +~~sleep({\mdcolor{teal}X});\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4129} +\subsection{\mdline{4129}9.9.\hspace*{0.5em}\mdline{4129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\label{sec-extern-entry}%mdk%mdk + +%mdk-data-line={4131} +\noindent\mdline{4131}This is used to support a P4 extern entity that is not part of PSA. It is +defined as:%mdk + +%mdk-data-line={4134} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4135} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ExternEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_type\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~google.protobuf.Any~entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4142} +\noindent\mdline{4142}Each \mdline{4142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4142} entity maps to an \mdline{4142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{4142} message in the +\mdline{4143}\mdref{sec-p4info-extern}{P4Info}\mdline{4143} and an \mdline{4143}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4143} message within that +message. The \mdline{4144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{4144} field must be equal to the one in +\mdline{4145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4145}. The \mdline{4145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_id}}}\mdline{4145} field must be equal to the ID included in the +\mdline{4146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{4146} of the corresponding \mdline{4146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4146} message.%mdk + +%mdk-data-line={4148} +\mdline{4148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entry}}}\mdline{4148} itself is embedded as an \mdline{4148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{4148} Protobuf message\mdline{4148}~[\mdcite{protoany}{30}]\mdline{4148} to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on\mdline{4152}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{4153} for more information.%mdk + +%mdk-data-line={4155} +\section{\mdline{4155}10.\hspace*{0.5em}\mdline{4155}Error Reporting Messages}\label{sec-error-reporting-messages}%mdk%mdk + +%mdk-data-line={4157} +\noindent\mdline{4157}P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case.%mdk + +%mdk-data-line={4161} +\mdline{4161}gRPC uses \mdline{4161}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4161}~[\mdcite{grpcstatus}{31}]\mdline{4161} to represent the status returned by an +RPC. It has 3 attributes:%mdk + +%mdk-data-line={4164} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4165} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StatusCode~code\_;\\ +{\mdcolor{navy}grpc::}string~error\_message\_;\\ +{\mdcolor{navy}grpc::}string~binary\_error\_details\_;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4170} +\noindent\mdline{4170}The \mdline{4170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4170} represents a canonical error\mdline{4170}~[\mdcite{grpcstatuscodes}{33}]\mdline{4170} and describes the +overall RPC status. The \mdline{4171}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4171} is a developer-facing error message, +which should be in English. The \mdline{4172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}binary\_error\_details\_}}}\mdline{4172} carries a serialized +\mdline{4173}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4173} message\mdline{4173}~[\mdcite{protostatus}{27}]\mdline{4173} message, which has 3 fields:%mdk + +%mdk-data-line={4175} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4176} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}int32}}~code~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~see~code.proto}\\ +{\bfseries{\mdcolor{navy}string}}~{\bfseries{\mdcolor{navy}message}}~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +{\bfseries{\mdcolor{navy}repeated}}~google.protobuf.Any~details~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4181} +\noindent\mdline{4181}The code and message fields must be the same as \mdline{4181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4181} and \mdline{4181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4181} +fields from \mdline{4182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4182} above. The \mdline{4182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{4182} field is a list that consists of +\mdline{4183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4183} messages that carry error details for individual elements inside +batch-request RPCs (\mdline{4184}e.g.\mdline{4184} \mdline{4184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4184} and \mdline{4184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4184}). \mdline{4184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4184} includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices\mdline{4188}~[\mdcite{grpcstatuscodes}{33}]\mdline{4188}.%mdk + +%mdk-data-line={4190} +\mdline{4190}Figure\mdline{4190}~\mdref{fig-error-report}{\mdcaptionlabel{7}}\mdline{4190} illustrates how these messages fit together.%mdk + +%mdk-data-line={4192} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={4193} +\noindent\mdline{4193}\includegraphics[keepaspectratio=true,width=\dimwidth{0.70}]{build/error-report}{}\mdline{4193}%mdk + +%mdk-data-line={4194} +\mdhr{}%mdk + +%mdk-data-line={4195} +\noindent\mdline{4195}\mdcaption{\textbf{Figure~\mdcaptionlabel{7}.}~\mdcaptiontext{P4Runtime Error Report Message Format}}%mdk +%mdk +\end{mdcenter}\label{fig-error-report}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={4197} +\noindent\mdline{4197}gRPC provides utility functions \mdline{4197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExtractErrorDetails()}}}\mdline{4197} and \mdline{4197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetErrorDetails()}}}\mdline{4197} +\mdline{4198}[\mdcite{grpcerrordetails}{32}]\mdline{4198} to easily convert between \mdline{4198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4198} and +\mdline{4199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4199}.%mdk + +%mdk-data-line={4201} +\mdline{4201}Please see sections on individual P4Runtime RPCs for details on how +\mdline{4202}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4202} is populated for reporting errors.%mdk + +%mdk-data-line={4204} +\mdline{4204}Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on\mdline{4207}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{4208} for more information.%mdk + +%mdk-data-line={4210} +\section{\mdline{4210}11.\hspace*{0.5em}\mdline{4210}Atomicity of Individual \mdline{4210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4210} and \mdline{4210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4210} Operations}\label{sec-atomicity-of-individual-write-and-read-operations}%mdk%mdk + +%mdk-data-line={4212} +\noindent\mdline{4212}Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane \mdline{4213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4213} +operation, and every single \mdline{4214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4214} operation on a table that inserts, deletes, +or modifies one table entry, the \mdline{4215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4215} operation should behave as if that +\mdline{4216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4216} operation has not yet occurred, or as if the \mdline{4216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4216} operation is +complete. The P4 program should never behave as if the \mdline{4217}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4217} operation is +partially complete. These guarantees also apply to extern instances: \mdline{4218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4218} and +\mdline{4219}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4219} operations on extern entities must execute atomically relative to extern +data plane methods.%mdk + +%mdk-data-line={4222} +\mdline{4222}The atomicity guarantees provided by P4Runtime for individual \mdline{4222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4222} and \mdline{4222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4222} +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification\mdline{4224}~[\mdcite{psaatomicityofcontrolplaneops}{22}]\mdline{4224}.%mdk + +%mdk-data-line={4226} +\mdline{4226}The P4\mdline{4226}\mdsub{16}\mdline{4226} language introduces an \mdline{4226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4226} annotation\mdline{4226}~[\mdcite{p4concurrency}{13}]\mdline{4226}, to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the \mdline{4228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4228} annotation for \mdline{4228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4228} +operations, as well as\mdline{4229}~\mdref{wildcard-reads}{non-wildcard \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} operations}\mdline{4229}, +relative to data plane execution. Consider the following P4 example written for +PSA:%mdk + +%mdk-data-line={4233} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4234} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024)~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\mdcolor{darkgreen}//~...}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~Value\_t~v~=~r1.read((Index\_t){\mdcolor{purple}1});\\ +~~~~~~~~v~=~v~+~{\mdcolor{purple}1};\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~v);\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4250} +\noindent\mdline{4250}If a P4Runtime server is processing messages which write to Register \mdline{4250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4250} at +index \mdline{4251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}1}}}\mdline{4251}, these writes must not happen between the data plane \mdline{4251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}read}}}\mdline{4251} and +\mdline{4252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}write}}}\mdline{4252}.%mdk + +%mdk-data-line={4254} +\mdline{4254}Now let\mdline{4254}'\mdline{4254}s consider the following example:%mdk + +%mdk-data-line={4256} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4257} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024,~(Value\_t){\mdcolor{purple}0}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~initial~value~}{\mdcolor{darkgreen}*/})~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}100});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}100});\\ +~~~~\}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}200});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}200});\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4275} +\noindent\mdline{4275}If a P4Runtime client issues a \mdline{4275}\emph{wildcard}\mdline{4275} \mdline{4275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4275} on Register \mdline{4275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4275}, there is no +guarantee that \mdline{4276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]~==~r1{}[2]}}}\mdline{4276} in the response, as the read for \mdline{4276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4276} may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for \mdline{4278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4278} may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read \mdline{4280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4280} and \mdline{4280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4280} separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +\mdline{4283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4283} message) of individual read requests. Similar to a batch +\mdline{4284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4284}, a wildcard read of a register can execute the reads of the +register array elements (\mdline{4285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4285}, \mdline{4285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4285}, \mdline{4285}\dots{}\mdline{4285}) in an arbitrary order relative +to each other.%mdk + +%mdk-data-line={4288} +\mdline{4288}If the \mdline{4288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4288} annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program.%mdk + +%mdk-data-line={4292} +\section{\mdline{4292}12.\hspace*{0.5em}\mdline{4292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4292} RPC}\label{sec-write-rpc}%mdk%mdk + +%mdk-data-line={4294} +\noindent\mdline{4294}The \mdline{4294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4294} RPC updates one or more P4 entities on the target. The request is +defined as follows:%mdk + +%mdk-data-line={4297} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4298} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~WriteRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint64}}~role\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Update~updates~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\bfseries{\mdcolor{navy}enum}}~Atomicity~\{\\ +~~~~CONTINUE\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~ROLLBACK\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~DATAPLANE\_ATOMIC~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~\}\\ +~~Atomicity~atomicity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4312} +\noindent\mdline{4312}The \mdline{4312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4312} uniquely identifies the target P4 device. The \mdline{4312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4312} and +\mdline{4313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4313} define the client role and election-id as described in the +\mdline{4314}\mdref{sec-master-slave-arbitration-and-controller-replication}{Master-Slave Arbitration and Controller +Replication}\mdline{4315} +section. The server is expected to perform the following checks (in this order) +before processing the \mdline{4317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}updates}}}\mdline{4317} list:%mdk + +%mdk-data-line={4319} +\begin{enumerate}%mdk + +%mdk-data-line={4319} +\item{} +%mdk-data-line={4319} +\mdline{4319}If \mdline{4319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4319} does not match any of the devices known to the P4Runtime +server or if \mdline{4320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4320} does not match any of the roles for the device, the +server must return a \mdline{4321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4321} error.%mdk%mdk + +%mdk-data-line={4323} +\item{} +%mdk-data-line={4323} +\mdline{4323}If the client is not the master for (\mdline{4323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4323}, \mdline{4323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4323}) according to the +\mdline{4324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4324} value, the server must return a \mdline{4324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4324} error.%mdk%mdk + +%mdk-data-line={4326} +\item{} +%mdk-data-line={4326} +\mdline{4326}If the \mdline{4326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4326} is attempted before a \mdline{4326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4326} has been set, +the server must return a \mdline{4327}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{4327} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4329} +\noindent\mdline{4329}The updates field is a list of P4 entity updates to be applied. Each update is +defined as:%mdk + +%mdk-data-line={4332} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4333} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Update~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Type~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~INSERT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~MODIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DELETE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~Type~type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Entity~entity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4345} +\noindent\mdline{4345}This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a \mdline{4346}\emph{logical}\mdline{4346} table (\mdline{4346}e.g.\mdline{4346} +\mdline{4347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4347}) or an actual table (\mdline{4347}e.g.\mdline{4347} \mdline{4347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4347}) in the P4 data +plane. Each entity in the container is uniquely identified by its \mdline{4348}\emph{key}\mdline{4348}. Please +refer to the\mdline{4349}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4349} section for details on +what parts of the entity specification make up the \mdline{4350}\emph{key}\mdline{4350} for each P4 entity.%mdk + +%mdk-data-line={4352} +\mdline{4352}An update can be one of the following types:%mdk + +%mdk-data-line={4354} +\begin{itemize}%mdk + +%mdk-data-line={4354} +\item{} +%mdk-data-line={4354} +\mdline{4354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4354}: Inserts the given P4 entity in the entity container. +The \mdline{4355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{4355} field always specifies the full state of the P4 entity. +If the entity already exists, an \mdline{4356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4356} error is returned, and +the existing entity remains unchanged. +If the entity is malformed, an \mdline{4358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4358} error is returned. +If the entity cannot be inserted because the container is already full, +a \mdline{4360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4360} error is returned.%mdk%mdk + +%mdk-data-line={4362} +\item{} +%mdk-data-line={4362} +\mdline{4362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4362}: Modifies the P4 entity to its new specified state. This uses +\mdline{4363}\emph{assign}\mdline{4363} or \mdline{4363}\emph{full-snapshot}\mdline{4363} semantics, \mdline{4363}i.e.\mdline{4363} the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an \mdline{4365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4365} error is usually returned (unless a +more specific error code applies\mdline{4366}~[\mdcite{grpcstatuscodes}{33}]\mdline{4366}). If the entity does not +exist, a \mdline{4367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4367} error is returned.%mdk%mdk + +%mdk-data-line={4369} +\item{} +%mdk-data-line={4369} +\mdline{4369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4369}: Deletes the specified P4 entity. If the entity does not exist, a +\mdline{4370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4370} error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4373} +\noindent\mdline{4373}If an update is not allowed under the given controller role, the server must +return a \mdline{4374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4374} error for this update.%mdk + +%mdk-data-line={4376} +\subsection{\mdline{4376}12.1.\hspace*{0.5em}\mdline{4376}Batching and Ordering of Updates}\label{sec-batching-and-ordering-of-updates}%mdk%mdk + +%mdk-data-line={4378} +\noindent\mdline{4378}P4Runtime supports batching of \mdline{4378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4378} operations. The list of updates in a +\mdline{4379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4379} is referred to as a \mdline{4379}\emph{batch}\mdline{4379}. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of \mdline{4381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4381} entities).%mdk + +%mdk-data-line={4383} +\mdline{4383}The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +\mdline{4385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4385}s can also be processed interleaved and/or in parallel. +However, \mdline{4386}\textbf{the processing of updates must be strictly serializable}\mdline{4386}. That +is, given a history \mdline{4387}$S$\mdline{4387} of \mdline{4387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4387}s including the responses to those +requests, there must exist an order \mdline{4388}$L$\mdline{4388} for all updates in \mdline{4388}$S$\mdline{4388}, such that:%mdk + +%mdk-data-line={4390} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4390} +\item\mdline{4390}For two updates \mdline{4390}$u_1$\mdline{4390} and \mdline{4390}$u_2$\mdline{4390}, if the write request containing \mdline{4390}$u_1$\mdline{4390} +completed before the write request of \mdline{4391}$u_2$\mdline{4391} was sent, then \mdline{4391}$u_1$\mdline{4391} must appear +before \mdline{4392}$u_2$\mdline{4392} in \mdline{4392}$L$\mdline{4392}.%mdk + +%mdk-data-line={4393} +\item\mdline{4393}Executing all updates in \mdline{4393}$L$\mdline{4393} sequentially must yield the same response for +every update as in \mdline{4394}$S$\mdline{4394}.%mdk + +%mdk-data-line={4395} +\item\mdline{4395}The observable state of the switch after \mdline{4395}$S$\mdline{4395} (\mdline{4395}e.g.\mdline{4395}, through the \mdline{4395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4395} RPC) +is identical to the one obtained by sequentially executing \mdline{4396}$L$\mdline{4396}.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4398} +\noindent\mdline{4398}The \mdline{4398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4398} RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the \mdline{4399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4399} RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, +with the exception of any operations that return an error status. +If two updates from the client depend on each other (\mdline{4402}e.g.\mdline{4402} inserting an +\mdline{4403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4403} followed by pointing a \mdline{4403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4403} to it) and the updates +are not split into separate batches, then the behavior may be non-deterministic. +Similarly, clients can invoke multiple outstanding \mdline{4405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4405} RPCs. If the updates +across these RPCs have dependencies, the observed behavior may be +non-deterministic. For this reason, most clients are advised to split dependent +updates across separate Write calls. Additionally, each Write call has to be +sent sequentially, waiting for the previous call to be acknowledged before +sending the next one.%mdk + +%mdk-data-line={4413} +\subsection{\mdline{4413}12.2.\hspace*{0.5em}\mdline{4413}Batch Atomicity}\label{sec-batch-atomicity}%mdk%mdk + +%mdk-data-line={4415} +\noindent\mdline{4415}A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the \mdline{4416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4416} +enum. A P4Runtime server is required to support only the modes marked as +\mdline{4418}\emph{Required}\mdline{4418} below:%mdk + +%mdk-data-line={4420} +\begin{itemize}%mdk + +%mdk-data-line={4420} +\item{} +%mdk-data-line={4420} +\mdline{4420}\emph{Required}\mdline{4420}: \mdline{4420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4420}: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that \mdline{4424}\emph{see}\mdline{4424} each of +these intermediate stages.%mdk%mdk + +%mdk-data-line={4427} +\item{} +%mdk-data-line={4427} +\mdline{4427}\emph{Optional}\mdline{4427}: \mdline{4427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ROLLBACK\_ON\_ERROR}}}\mdline{4427}: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is \mdline{4431}\emph{all-or-none}\mdline{4431}, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that \mdline{4435}\emph{see}\mdline{4435} each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure.%mdk + +%mdk-data-line={4440} +\mdline{4440}If a P4Runtime server does not support this option at all, an +\mdline{4441}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4441} error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (\mdline{4442}e.g.\mdline{4442} it is +more straightforward to implement batches that contain only \mdline{4443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4443} +operations, vs. those that contain \mdline{4444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4444} operations), an +\mdline{4445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4445} error is returned when the batch cannot be executed +in a data plane-atomic way.%mdk%mdk + +%mdk-data-line={4448} +\item{} +%mdk-data-line={4448} +\mdline{4448}\emph{Optional}\mdline{4448}: \mdline{4448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4448}: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +\mdline{4452}\emph{transaction}\mdline{4452}. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane\mdline{4454}'\mdline{4454}s table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table.%mdk + +%mdk-data-line={4461} +\mdline{4461}If a P4Runtime server does not support this option at all, an \mdline{4461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4461} +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4463} error is returned when the batch +cannot be executed in a data plane-atomic way.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4466} +\noindent\mdline{4466}There is no expectation that a given client must always use the same \mdline{4466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4466} +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use \mdline{4469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4469} at one time and default behavior +(\mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4470}) at other times.%mdk + +%mdk-data-line={4472} +\subsection{\mdline{4472}12.3.\hspace*{0.5em}\mdline{4472}Error Reporting}\label{sec-error-reporting}%mdk%mdk + +%mdk-data-line={4474} +\noindent\mdline{4474}Please see section\mdline{4474}~\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{4474} for +information on error reporting messages and guidelines. P4Runtime server will +populate \mdline{4476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4476} as follows:%mdk + +%mdk-data-line={4478} +\begin{enumerate}%mdk + +%mdk-data-line={4478} +\item{} +%mdk-data-line={4478} +\mdline{4478}If all batch updates succeeded, set \mdline{4478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4478} to \mdline{4478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4478} and do not +populate any other field.%mdk%mdk + +%mdk-data-line={4481} +\item{} +%mdk-data-line={4481} +\mdline{4481}If an error is encountered before even trying to attempt individual batch +updates, set \mdline{4482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4482} that best describes that RPC-wide +error. For example, use \mdline{4483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNAVAILABLE}}}\mdline{4483} if the P4Runtime service is not yet +ready to handle requests. Set \mdline{4484}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4484} to describe the issue. Do not +set \mdline{4485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_details}}}\mdline{4485} in this case.%mdk%mdk + +%mdk-data-line={4487} +\item{} +%mdk-data-line={4487} +\mdline{4487}Otherwise, if one or more updates in the batch (\mdline{4487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest.updates}}}\mdline{4487}) +failed, set \mdline{4488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4488} to \mdline{4488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{4488}. For example, one update in +the batch may fail with \mdline{4489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4489} and another with +\mdline{4490}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4490}. A \mdline{4490}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4490} message is used to capture the status of +each and every update in the batch. The number of \mdline{4491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4491} messages packed +into \mdline{4492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{4492} field should therefore always match the +number of updates in the \mdline{4493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4493}, and the order of +\mdline{4494}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4494} messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +\mdline{4496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4496} should set the code to \mdline{4496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4496} and omit other fields.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4498} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4499} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}\#~Example~of~a~grpc::Status~returned~for~a~Write~RPC~with~a~batch~of~3~updates.}\\ +{\mdcolor{darkgreen}\#~The~first~and~third~updates~encountered~an~error,~while~the~second~update}\\ +{\mdcolor{darkgreen}\#~succeeded.}\\ +code\_~=~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +error\_message\_~=~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +binary\_error\_details~\{\\ +~~code:~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}8}~~{\mdcolor{darkgreen}\#~RESOURCE\_EXHAUSTED}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Table~is~full.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}500}~~{\mdcolor{darkgreen}\#~ERR\_TABLE\_FULL}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}0}~~{\mdcolor{darkgreen}\#~OK}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}6}~~{\mdcolor{darkgreen}\#~ALREADY\_EXISTS}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Entity~already~exists.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}600}~~{\mdcolor{darkgreen}\#~ERR\_ENTITY\_ALREADY\_EXISTS}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4525} +\section{\mdline{4525}13.\hspace*{0.5em}\mdline{4525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4525} RPC}\label{sec-read-rpc}%mdk%mdk + +%mdk-data-line={4527} +\noindent\mdline{4527}The \mdline{4527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4527} RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as:%mdk + +%mdk-data-line={4530} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4531} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4537} +\noindent\mdline{4537}The \mdline{4537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4537} uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +\mdline{4539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4539} error. The \mdline{4539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{4539} repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server.%mdk + +%mdk-data-line={4542} +\mdline{4542}Since \mdline{4542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4542}s do not mutate any state on the switch, they do not +require an \mdline{4543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4543}, and they do not require the presence of an open +\mdline{4544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4544} between the server and client.%mdk + +%mdk-data-line={4546} +\mdline{4546}The \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read~}}}\mdline{4546}response consists of a sequence of messages (a gRPC \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}stream}}}\mdline{4546}) with +each message defined as:%mdk + +%mdk-data-line={4549} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4550} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadResponse~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4555} +\noindent\mdline{4555}The \mdline{4555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{4555} repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the \mdline{4559}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Finish()}}}\mdline{4559} method on the stream object +\mdline{4560}[\mdcite{grpcstreamc}{10}]\mdline{4560}).%mdk + +%mdk-data-line={4562} +\subsection{\mdline{4562}13.1.\hspace*{0.5em}\mdline{4562}Nomenclature}\label{sec-nomenclature}%mdk%mdk + +%mdk-data-line={4564} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries request}}%mdk + +%mdk-data-line={4564} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{4564}An element of the \mdline{4564}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{4564} repeated field. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries batch}}%mdk + +%mdk-data-line={4566} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{4566}Refers to the \mdline{4566}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{4566} repeated field.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={4569} +\noindent\mdline{4569}Each \mdline{4569}\emph{request}\mdline{4569} acts as a query filter for that entity type. If a \mdline{4569}\emph{request}\mdline{4569} fully +specifies the entity key, the \mdline{4570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4570} operation should retrieve a single P4 +entity. Please refer to the\mdline{4571}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4571} section +for details on what parts of the entity specification make up the entity \mdline{4572}\emph{key}\mdline{4572}.%mdk + +%mdk-data-line={4574} +\subsection{\mdline{4574}13.2.\hspace*{0.5em}\mdline{4574}Wildcard Reads}\label{sec-wildcard-reads}%mdk%mdk + +%mdk-data-line={4576} +\noindent\mdline{4576}P4Runtime allows wildcard read of P4 entities. A \mdline{4576}\emph{request}\mdline{4576} may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the\mdline{4578}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4578} section for details on +what parts of the entity can be wildcarded in a given \mdline{4579}\emph{request}\mdline{4579}.%mdk + +%mdk-data-line={4581} +\mdline{4581}For example, in a \mdline{4581}\emph{request}\mdline{4581} of type \mdline{4581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4581}:%mdk + +%mdk-data-line={4583} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4583} +\item\mdline{4583}A default \mdline{4583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4583} (0) implies a request to read all counter-entries for +all indirect counters.%mdk + +%mdk-data-line={4585} +\item\mdline{4585}A particular (non-default) \mdline{4585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4585} in conjunction with \mdline{4585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4585} unset +implies a request to read all counter-entries for the given indirect counter +ID.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4589} +\noindent\mdline{4589}To read the entire forwarding state for a given device, the P4Runtime client can +generate the following \mdline{4590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4590}:%mdk + +%mdk-data-line={4592} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4593} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~\textless{}ID\textgreater{}\\ +entities~\{\\ +~~extern\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~extern~instances~for~all~supported~extern~types}\\ +~~table\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~table~entries~for~all~tables}\\ +~~action\_profile\_member~\{~\}~~{\mdcolor{darkgreen}\#~read~all~members~for~all~action~profiles}\\ +~~action\_profile\_group~\{~\}~~{\mdcolor{darkgreen}\#~read~all~groups~for~all~action~profiles}\\ +~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4603} +\noindent\mdline{4603}The \mdline{4603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{4603} oneof field in the \mdline{4603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{4603} message must always be set, or the +server must return an \mdline{4604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4604} error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty \mdline{4606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{4606} message in the \mdline{4606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4606}. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the \mdline{4608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{4608} oneof\mdline{4608}~[\mdcite{protooneofbackwardscompatibility}{19}]\mdline{4608}.%mdk + +%mdk-data-line={4610} +\subsection{\mdline{4610}13.3.\hspace*{0.5em}\mdline{4610}Batch Processing}\label{sec-batch-processing}%mdk%mdk + +%mdk-data-line={4612} +\noindent\mdline{4612}A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type \mdline{4613}\emph{request}\mdline{4613} +appears only once in the batch.%mdk + +%mdk-data-line={4616} +\mdline{4616}A P4Runtime server will process the batch as follows:%mdk + +%mdk-data-line={4618} +\begin{enumerate}%mdk + +%mdk-data-line={4618} +\item{} +%mdk-data-line={4618} +\mdline{4618}Lock state (preventing new writes) and validate each \mdline{4618}\emph{request}\mdline{4618} in the batch:%mdk + +%mdk-data-line={4620} +\begin{enumerate}%mdk + +%mdk-data-line={4620} +\item{} +%mdk-data-line={4620} +\mdline{4620}If it is a valid \mdline{4620}\emph{request}\mdline{4620}, perform the read;%mdk + +%mdk-data-line={4622} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4622} +\item\mdline{4622}If the read was successful, return the entities read in +\mdline{4623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4623} stream.%mdk + +%mdk-data-line={4624} +\item\mdline{4624}If the read failed (exception / critical-error), prepare a \mdline{4624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4624} +with code set to \mdline{4625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INTERNAL}}}\mdline{4625}.%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={4627} +\item{} +%mdk-data-line={4627} +\mdline{4627}If the \mdline{4627}\emph{request}\mdline{4627} is invalid (invalid-argument, not-supported, etc.), +prepare a \mdline{4628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4628} with relevant canonical code to capture the error.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={4630} +\item{} +%mdk-data-line={4630} +\mdline{4630}Unlock the state (allowing new writes);%mdk%mdk + +%mdk-data-line={4632} +\item{} +%mdk-data-line={4632} +\mdline{4632}Close the \mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4632} stream and return a \mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4632} as follows:%mdk + +%mdk-data-line={4634} +\begin{enumerate}%mdk + +%mdk-data-line={4634} +\item{} +%mdk-data-line={4634} +\mdline{4634}If no errors were encountered, set code to \mdline{4634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4634} and do not populate any +other field.%mdk%mdk + +%mdk-data-line={4637} +\item{} +%mdk-data-line={4637} +\mdline{4637}Otherwise, the overall code should be set to \mdline{4637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{4637}. See section +\mdline{4638}\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{4638} for information +on error reporting messages and guidelines. Assemble a list of \mdline{4639}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4639} +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +\mdline{4643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{4643} field. This behavior also matches \mdline{4643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4643} +RPC.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4646} +\subsubsection{\mdline{4646}13.3.1.\hspace*{0.5em}\mdline{4646}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={4648} +\noindent\mdline{4648}If a client asked to read \mdline{4648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{a,b,c,d\}}}}\mdline{4648} and \mdline{4648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}b}}}\mdline{4648} and \mdline{4648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}d}}}\mdline{4648} \mdline{4648}\emph{requests}\mdline{4648} didn\mdline{4648}'\mdline{4648}t +validate, the server will return entities corresponding to \mdline{4649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{4649} and \mdline{4649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}c}}}\mdline{4649}, followed +by a status \mdline{4650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{p4.Error(OK),~p4.Error(xxx),~p4.Error(yyy),~p4.Error(OK)\}}}}\mdline{4650} in the +\mdline{4651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{4651} field.%mdk + +%mdk-data-line={4653} +\mdline{4653}The P4Runtime server is not required to perform any optimization (\mdline{4653}e.g.\mdline{4653} merge two +\mdline{4654}\emph{requests}\mdline{4654} in the \mdline{4654}\emph{batch}\mdline{4654} if one is a subset of other). As a result of this, it +is possible for the \mdline{4655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4655} to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging.%mdk + +%mdk-data-line={4658} +\mdline{4658}There is no requirement that each request in the batch will correspond to one +\mdline{4659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4659} message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit.%mdk + +%mdk-data-line={4664} +\mdline{4664}A P4Runtime server must be prepared to handle multiple concurrent \mdline{4664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4664} RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (\mdline{4669}e.g.\mdline{4669} in a single-threaded architecture), it may choose to serialize +\mdline{4670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4670} RPC processing.%mdk + +%mdk-data-line={4672} +\subsection{\mdline{4672}13.4.\hspace*{0.5em}\mdline{4672}Parallelism of Read and Write Requests}\label{sec-parallelism-of-read-and-write-requests}%mdk%mdk + +%mdk-data-line={4674} +\noindent\mdline{4674}A P4Runtime server may be implemented to serve at most one +\mdline{4675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4675} or \mdline{4675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4675} message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so.%mdk + +%mdk-data-line={4680} +\mdline{4680}For example, imagine a client that wanted to use \mdline{4680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4680} +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +\mdline{4684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4684} messages with only a few updates to an \mdline{4684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{4684} +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +\mdline{4687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4687} batch currently being processed, but it will not +complete for a significant amount of time.%mdk + +%mdk-data-line={4690} +\mdline{4690}The restrictions on which a client may rely are:%mdk + +%mdk-data-line={4692} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4692} +\item\mdline{4692}The processing of any two \mdline{4692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4692} messages \mdline{4692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W1}}}\mdline{4692} and \mdline{4692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W2}}}\mdline{4692} must +result in the same state as if one of them was completed before the +other began.%mdk + +%mdk-data-line={4695} +\item\mdline{4695}For any \mdline{4695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4695} \mdline{4695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{4695} and any \mdline{4695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4695} \mdline{4695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{4695}, \mdline{4695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{4695} must +return results consistent with a state where \mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{4696} has completed +processing, or \mdline{4697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{4697} has not yet begun processing.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4699} +\noindent\mdline{4699}For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a \mdline{4702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4702} message it acquired a write lock for each stateful +object affected by the \mdline{4703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4703}, and before starting the +processing of a \mdline{4704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4704} message it acquired a read lock for each +stateful object accessed by the \mdline{4705}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4705}, such an implementation +meets all of the requirements above.%mdk + +%mdk-data-line={4708} +\mdline{4708}It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, \mdline{4710}e.g.\mdline{4710} if the server somehow determined that two +\mdline{4711}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4711} messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly.%mdk + +%mdk-data-line={4717} +\section{\mdline{4717}14.\hspace*{0.5em}\mdline{4717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4717} RPC}\label{sec-setforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={4719} +\noindent\mdline{4719}A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the \mdline{4720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig~RPC}}}\mdline{4720}. The request is defined as:%mdk + +%mdk-data-line={4722} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4723} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~SetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Action~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~VERIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~VERIFY\_AND\_SAVE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~VERIFY\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~~~COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~~~RECONCILE\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint64}}~role\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~Action~action~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4740} +\noindent\mdline{4740}The server is expected to perform the following checks (in this order) +before performing the required \mdline{4741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{4741}:%mdk + +%mdk-data-line={4743} +\begin{enumerate}%mdk + +%mdk-data-line={4743} +\item{} +%mdk-data-line={4743} +\mdline{4743}If \mdline{4743}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4743} does not match any of the devices known to the P4Runtime +server or if \mdline{4744}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4744} does not match any of the roles for the device, the +server must return a \mdline{4745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4745} error.%mdk%mdk + +%mdk-data-line={4747} +\item{} +%mdk-data-line={4747} +\mdline{4747}If the client is not the master for (\mdline{4747}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4747}, \mdline{4747}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4747}) according to the +\mdline{4748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4748} value, the server must return a \mdline{4748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4748} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4750} +\noindent\mdline{4750}The action is the type of configuration action requested, it can be one of:%mdk + +%mdk-data-line={4752} +\begin{itemize}%mdk + +%mdk-data-line={4752} +\item{} +%mdk-data-line={4752} +\mdline{4752}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY}}}\mdline{4752}: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an \mdline{4753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4753} +error if config is not provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={4756} +\item{} +%mdk-data-line={4756} +\mdline{4756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{4756}: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent \mdline{4758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4758} / \mdline{4758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4758} requests must refer to fields in the new +config. Returns an \mdline{4759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4759} error if the forwarding config is not +provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={4762} +\item{} +%mdk-data-line={4762} +\mdline{4762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_COMMIT}}}\mdline{4762}: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an \mdline{4764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4764} error if the forwarding config is not provided of if the +provided config cannot be realized.%mdk%mdk + +%mdk-data-line={4767} +\item{} +%mdk-data-line={4767} +\mdline{4767}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COMMIT}}}\mdline{4767}: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a \mdline{4770}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4770} error if no saved config +is found, \mdline{4771}i.e.\mdline{4771} if no \mdline{4771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{4771} action preceded this one. Returns an +\mdline{4772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4772} error if a config is provided with this message.%mdk%mdk + +%mdk-data-line={4774} +\item{} +%mdk-data-line={4774} +\mdline{4774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RECONCILE\_AND\_COMMIT}}}\mdline{4774}: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an \mdline{4780}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4780} error. For targets that support this option, an +\mdline{4781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4781} error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4785} +\noindent\mdline{4785}The \mdline{4785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4785} field is a message of type \mdline{4785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4785} that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(\mdline{4787}e.g.\mdline{4787} generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the\mdline{4788}~\mdref{sec-p4-fwd-pipe-config}{Forwarding-Pipeline +Configuration}\mdline{4789} section for details.%mdk + +%mdk-data-line={4791} +\mdline{4791}A P4Runtime server running on a non-programmable device may not +support \mdline{4792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4792} (\mdline{4792}e.g.\mdline{4792} the forwarding-pipeline +config is part of the device\mdline{4793}'\mdline{4793}s software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +\mdline{4795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4795} error.%mdk + +%mdk-data-line={4797} +\section{\mdline{4797}15.\hspace*{0.5em}\mdline{4797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{4797} RPC}\label{sec-getforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={4799} +\noindent\mdline{4799}The forwarding-pipeline configuration of the target can be retrieved by invoking +the \mdline{4800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig~RPC}}}\mdline{4800}. The request is defined as:%mdk + +%mdk-data-line={4802} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4803} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~ResponseType~\{\\ +~~~~ALL~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~COOKIE\_ONLY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~P{\mdcolor{purple}4}INFO\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DEVICE\_CONFIG\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~ResponseType~response\_type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4815} +\noindent\mdline{4815}The \mdline{4815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4815} uniquely identifies the target P4 device. A \mdline{4815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4815} error is +returned if the \mdline{4816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4816} is not recognized by the P4Runtime server.%mdk + +%mdk-data-line={4818} +\mdline{4818}The \mdline{4818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{4818} is used to specify which fields to populate in the response, +its value can be one of:%mdk + +%mdk-data-line={4821} +\begin{itemize}%mdk + +%mdk-data-line={4821} +\item{} +%mdk-data-line={4821} +\mdline{4821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{4821}: returns a \mdline{4821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4821} with all fields +set as stored by the target. This is the default behaviour if the +\mdline{4823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{4823} field is not set.%mdk%mdk + +%mdk-data-line={4825} +\item{} +%mdk-data-line={4825} +\mdline{4825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COOKIE\_ONLY}}}\mdline{4825}: reply by setting only the \mdline{4825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{4825} field in the +\mdline{4826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4826}, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message.%mdk%mdk + +%mdk-data-line={4830} +\item{} +%mdk-data-line={4830} +\mdline{4830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4INFO\_AND\_COOKIE}}}\mdline{4830}: reply by setting the \mdline{4830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{4830} and \mdline{4830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{4830} fields.%mdk%mdk + +%mdk-data-line={4832} +\item{} +%mdk-data-line={4832} +\mdline{4832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEVICE\_CONFIG\_AND\_COOKIE}}}\mdline{4832}: reply by setting the \mdline{4832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{4832} and +\mdline{4833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{4833} fields.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4835} +\noindent\mdline{4835}The response contains the \mdline{4835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4835} for the specified device:%mdk + +%mdk-data-line={4837} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4838} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigResponse~\{\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4843} +\noindent\mdline{4843}If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level \mdline{4844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4844} field will be unset in the response. Examples are +(i) a server that only allows configuration via \mdline{4845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4845} +but this RPC hasn\mdline{4846}'\mdline{4846}t been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn\mdline{4847}'\mdline{4847}t yet occurred.%mdk + +%mdk-data-line={4849} +\mdline{4849}Once a forwarding-pipeline config is installed on the device (either via +\mdline{4850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4850} or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +\mdline{4852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.p4\_device\_config}}}\mdline{4852} will be empty / unset in the response, even if +\mdline{4853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{4853} in the request was set to \mdline{4853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{4853}. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the \mdline{4855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4855} RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +\mdline{4857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4857}, the value of \mdline{4857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.cookie}}}\mdline{4857} will be unset.%mdk + +%mdk-data-line={4859} +\mdline{4859}If a P4Runtime server supports both \mdline{4859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4859} as well as +returning the \mdline{4860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{4860}, there should be read-write symmetry between +\mdline{4861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4861} and \mdline{4861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{4861} RPCs.%mdk + +%mdk-data-line={4863} +\section{\mdline{4863}16.\hspace*{0.5em}\mdline{4863}P4Runtime Stream Messages}\label{sec-p4runtime-stream-messages}%mdk%mdk + +%mdk-data-line={4865} +\subsection{\mdline{4865}16.1.\hspace*{0.5em}\mdline{4865}Packet I/O}\label{sec-packet-i_o}%mdk%mdk + +%mdk-data-line={4867} +\noindent\mdline{4867}P4Runtime supports controller packet-in and packet-out by means of \mdline{4867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{4867} +and \mdline{4868}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4868} stream messages, respectively.%mdk + +%mdk-data-line={4870} +\mdline{4870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{4870} messages are sent by the P4Runtime server to the client. Conversely, +\mdline{4871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4871} messages are sent by the client to the server. Any \mdline{4871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4871} +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a \mdline{4874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{4874} message with the \mdline{4874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{4874} field set to +report the error to the client. See the section on\mdline{4875}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{4876} for more information on \mdline{4876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{4876}.%mdk + +%mdk-data-line={4878} +\mdline{4878}As introduced in the\mdline{4878}~\mdref{sec-controller-packet-meta}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\mdline{4878} +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with \mdline{4880}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{4880}. The expected metadata is described +in the P4Info using the \mdline{4881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{4881} messages.%mdk + +%mdk-data-line={4883} +\mdline{4883}Both \mdline{4883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{4883} and \mdline{4883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4883} stream messages share the same fields and are +defined as follows:%mdk + +%mdk-data-line={4886} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4887} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Packet~sent~from~the~controller~to~the~switch.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketOut~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~Packet~sent~from~the~switch~to~the~controller.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketIn~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~PacketMetadata~\{\\ +~~{\mdcolor{darkgreen}//~This~refers~to~Metadata.id~coming~from~P4Info~ControllerPacketMetadata.}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~metadata\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4906} +\begin{itemize}%mdk + +%mdk-data-line={4906} +\item{} +%mdk-data-line={4906} +\mdline{4906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}payload}}}\mdline{4906} is used to carry the full packet content, including the headers.%mdk%mdk + +%mdk-data-line={4908} +\item{} +%mdk-data-line={4908} +\mdline{4908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{4908} is a repeated field of \mdline{4908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{4908} messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +\mdline{4911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{4911}. Indeed, when a P4Runtime client (or server) +generates a \mdline{4912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4912} (or \mdline{4912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{4912}) message, it needs to populate the +\mdline{4913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{4913} field with as many values as in \mdline{4913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{4913} +for the packet-out (or packet-in) case. Each \mdline{4914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata.value}}}\mdline{4914} is a +binary string and must conform to the\mdline{4915}~\mdref{sec-bytestrings}{Bytestrings}\mdline{4915} +requirements based on the corresponding P4Info +\mdline{4917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{4917} specification. If the \mdline{4917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{4917} field +does not match the P4Info specification, the server must drop the \mdline{4918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4918} +message and may generate a \mdline{4919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{4919} message with the \mdline{4919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{4919} +field set to report the error to the client which issued the \mdline{4920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4920}. See +the section on\mdline{4921}~\mdref{sec-stream-error-reporting}{Stream Error Reporting}\mdline{4921} for more +information on \mdline{4922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{4922}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4924} +\subsection{\mdline{4924}16.2.\hspace*{0.5em}\mdline{4924}Master Arbitration Update}\label{sec-master-arbitration-update}%mdk%mdk + +%mdk-data-line={4926} +\noindent\mdline{4926}P4Runtime\mdline{4926}'\mdline{4926}s master arbitration mechanism ensures that only the current master +can modify state on the switch, and that the \mdline{4927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4927} is monotonically +increasing. For example, the switch must finish all previous write operations +before changing masters, and must only accept write requests from the current +master.%mdk + +%mdk-data-line={4932} +\mdline{4932}As explained earlier in this document, the controller uses the \mdline{4932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4932} +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via \mdline{4934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4934} RPC), +it needs to start a controller session and become a \mdline{4935}\textquotedblleft{}master\textquotedblright{}\mdline{4935}. To do so, the +controller first opens a bidirectional stream channel to the server via +\mdline{4937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4937} for each device and sends a \mdline{4937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{4937} message. The +controller populates the \mdline{4938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4938} field in this message using +its \mdline{4939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4939} and \mdline{4939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4939} and the \mdline{4939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4939} of the device, as explained +in detail in the\mdline{4940}~\mdref{sec-master-slave-arbitration-and-controller-replication}{Master-Slave Arbitration and Controller +Replication}\mdline{4941} +section. For any given \mdline{4942}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role\_id)}}}\mdline{4942}, the P4Runtime server keeps track +of the highest \mdline{4943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4943} that it has ever received. If a controller\mdline{4943}'\mdline{4943}s +\mdline{4944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4944} is equal to the highest \mdline{4944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4944} that the server has ever +received, that controller is the master. All other controllers are slaves. Note +that it is possible that all controllers are slaves, and that there is no +master. There can be at most one master, because for any given +\mdline{4948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role\_id)}}}\mdline{4948}, each connected controller has a unique \mdline{4948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4948}.%mdk + +%mdk-data-line={4950} +\mdline{4950}This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest \mdline{4951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4951} after such a restart. +However, across a\mdline{4952}~\mdref{sec-restarts}{full restart}\mdline{4952}, the \mdline{4952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4952} must be +reset. In fact, a full restart is the only way to reset the \mdline{4953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4953}.%mdk + +%mdk-data-line={4955} +\mdline{4955}The \mdline{4955}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4955} message is defined as follows:%mdk + +%mdk-data-line={4957} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4958} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Role~\{\\ +~~{\mdcolor{darkgreen}//~role\_id~for~this~role.~Defined~offline~in~agreement~across~the}\\ +~~{\mdcolor{darkgreen}//~entire~control~plane.}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Describes~the~role~configuration.}\\ +~~google.protobuf.Any~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~MasterArbitrationUpdate~\{\\ +~~{\mdcolor{darkgreen}//~Identifies~the~device~(aka~target~or~node~or~switching~chip).}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~The~role~for~which~the~mastership~is~being~arbitrated.}\\ +~~Role~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~The~election\_id~(unique~per~role).}\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Switch~populates~this~with~OK~for~the~client~that~is~the~master,}\\ +~~{\mdcolor{darkgreen}//~and~with~an~error~status~for~all~other~connected~clients~(at}\\ +~~{\mdcolor{darkgreen}//~every~mastership~change).~The~controller~does~not~populate~this}\\ +~~{\mdcolor{darkgreen}//~field.}\\ +~~google.{\bfseries{\mdcolor{navy}rpc}}.Status~status~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4981} +\noindent\mdline{4981}Note that the \mdline{4981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{4981} field in the \mdline{4981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4981} message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a \mdline{4983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{4983} message back to the controller, in which +it populates the \mdline{4984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4984} message using the \mdline{4984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4984}, +\mdline{4985}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{4985}, and \mdline{4985}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4985} it previously received from the controller. The server +also populates the \mdline{4986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{4986} field in the \mdline{4986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4986} according to +the rules in an\mdline{4987}~\mdref{sec-mastership-updates}{earlier section}\mdline{4987}.%mdk + +%mdk-data-line={4989} +\mdline{4989}The sender need not specify an \mdline{4989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4989}. If the \mdline{4989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4989} is not +specified, the sender\mdline{4990}'\mdline{4990}s \mdline{4990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4990} is considered lower than any +\mdline{4991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4991}, and the sender will thus never become master. This way, a +controller can choose to be a standby controller, in order to avoid master +\mdline{4993}\textquotedblleft{}flapping\textquotedblright{}\mdline{4993} (if a standby controller connects to the switch shortly before the +actual master controller, therefore becoming master temporarily).%mdk + +%mdk-data-line={4997} +\subsection{\mdline{4997}16.3.\hspace*{0.5em}\mdline{4997}Digest Messages}\label{sec-digest-messages}%mdk%mdk + +%mdk-data-line={4999} +\noindent\mdline{4999}See the\mdline{4999}~\mdref{sec-digestentry}{DigestEntry}\mdline{4999} section.%mdk + +%mdk-data-line={5001} +\subsection{\mdline{5001}16.4.\hspace*{0.5em}\mdline{5001}Table Idle Timeout Notification}\label{sec-table-idle-timeout-notification}%mdk%mdk + +%mdk-data-line={5003} +\noindent\mdline{5003}When a table supports idle timeout (as per the P4Info message), the master +client can specify a TTL value for each entry in the table (see +\mdline{5005}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{5005} section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an \mdline{5007}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5007} message on the +\mdline{5008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5008} bidirectional stream to the master client. The master client can +then take the action of its choice, most likely remove the idle entry.%mdk + +%mdk-data-line={5011} +\mdline{5011}The \mdline{5011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5011} Protobuf message has the following fields:%mdk + +%mdk-data-line={5013} +\begin{itemize}%mdk + +%mdk-data-line={5013} +\item{} +%mdk-data-line={5013} +\mdline{5013}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}timestamp}}}\mdline{5013}: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server\mdline{5014}'\mdline{5014}s local clock.%mdk%mdk + +%mdk-data-line={5016} +\item{} +%mdk-data-line={5016} +\mdline{5016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5016}: a repeated field of entries which have expired. Each individual +entry is identified by a single \mdline{5017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5017} message. For each \mdline{5017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5017}, +the \mdline{5018}\emph{key}\mdline{5018} fields (\mdline{5018}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{5018}, \mdline{5018}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{5018} and \mdline{5018}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{5018}) must be set, along with +the \mdline{5019}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{5019} field and the \mdline{5019}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{5019} field. Other fields +may be set by the server but should be ignored by the client.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5022} +\noindent\mdline{5022}Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +\mdline{5024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5024} message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an \mdline{5029}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5029} +message with an empty \mdline{5030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5030} repeated field.%mdk + +%mdk-data-line={5032} +\mdline{5032}After generating an idle notification, the P4Runtime server must \mdline{5032}\textquotedblleft{}reset\textquotedblright{}\mdline{5032} the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the master client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle.%mdk + +%mdk-data-line={5039} +\mdline{5039}Here is a reasonable pseudo-code implementation for idle timeout for table +entries:%mdk + +%mdk-data-line={5042} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5043} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutStream~stream;\\ +\\ +scanning\_interval~=~{\mdcolor{purple}10}ms;\\ +\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~{\mdcolor{darkgreen}//~iterate~over~all~tables~which~support~idle~timeout}\\ +~~{\bfseries{\mdcolor{navy}for}}~(table~in~tables)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(!table.idle\_timeout\_supported)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~{\mdcolor{darkgreen}//~we~coalesce~all~idle~notifications~for~the~same~table~in~one}\\ +~~~~{\mdcolor{darkgreen}//~message}\\ +~~~~IdleTimeoutNotification~msg;\\ +~~~~{\mdcolor{darkgreen}//~read~time\_since\_last\_hit~from~device}\\ +~~~~entries~=~device.load\_table\_entries\_from\_hw(table);\\ +~~~~{\bfseries{\mdcolor{navy}for}}~(entry~in~entries)~\{\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.idle\_timeout~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~TTL}\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.time\_since\_last\_hit~\textless{}~entry.idle\_timeout)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~~~msg.table\_entry\_add(entry);\\ +~~~~~~entry.reset\_time\_since\_last\_hit();\\ +~~~~\}\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(msg.table\_entry\_size()~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~notifications}\\ +~~~~msg.set\_timestamp(now());\\ +~~~~stream.write(msg);\\ +~~\}\\ +~~sleep(scanning\_interval);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5070} +\subsection{\mdline{5070}16.5.\hspace*{0.5em}\mdline{5070}Architecture-Specific Notifications}\label{sec-architecture-specific-notifications}%mdk%mdk + +%mdk-data-line={5072} +\noindent\mdline{5072}P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on \mdline{5073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5073}, by including an \mdline{5073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5073} Protobuf field\mdline{5073}~[\mdcite{protoany}{30}]\mdline{5073} +named \mdline{5074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5074} in both \mdline{5074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5074} and \mdline{5074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5074}. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the\mdline{5076}~\mdref{sec-digestentry}{PSA \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}} +extern}\mdline{5077}. See section on\mdline{5077}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{5078} for more information.%mdk + +%mdk-data-line={5080} +\subsection{\mdline{5080}16.6.\hspace*{0.5em}\mdline{5080}Stream Error Reporting}\label{sec-stream-error-reporting}%mdk%mdk + +%mdk-data-line={5082} +\noindent\mdline{5082}The P4Runtime server can asynchronously report errors which occur when +processing \mdline{5083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5083} messages, using the \mdline{5083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5083} message field (of +type \mdline{5084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5084}) in \mdline{5084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5084}. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature.%mdk + +%mdk-data-line={5088} +\mdline{5088}The \mdline{5088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5088} message has the following fields:%mdk + +%mdk-data-line={5090} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5090} +\item\mdline{5090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5090}, which must be set to the appropriate canonical error code +\mdline{5091}[\mdcite{grpcstatuscodes}{33}]\mdline{5091}.%mdk + +%mdk-data-line={5092} +\item\mdline{5092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{5092}, an optional developer-facing error message describing the error.%mdk + +%mdk-data-line={5093} +\item\mdline{5093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5093} and \mdline{5093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5093}, which are optional and can be used by vendors to provide +additional details on the error. \mdline{5094}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5094} is a numeric error code drawn from a +vendor\mdline{5095}'\mdline{5095}s chosen error \mdline{5095}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5095}.%mdk + +%mdk-data-line={5096} +\item\mdline{5096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5096}, which is a Protobuf \mdline{5096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5096} used to help the client identify which +\mdline{5097}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5097} triggered the error. The server is required to set the +appropriate field in the \mdline{5098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5098} so that the client can identify which type +of stream message is responsible for the error (\mdline{5099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5099}, +\mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_list\_ack}}}\mdline{5100} or \mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5100}), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid \mdline{5102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5102} message from the +client, the \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5103} field (of type \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError)}}}\mdline{5103} should be set in +the \mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5104} \mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5104}, and the server may additionally set the \mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5104} +field in the \mdline{5105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError}}}\mdline{5105} sub-message (by copying it from the invalid +\mdline{5106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5106} message received on the stream channel) so that the client can +know exactly what packet-out triggered the error.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5109} +\noindent\mdline{5109}The appropriate canonical error code\mdline{5109}~[\mdcite{grpcstatuscodes}{33}]\mdline{5109} should be used when +populating the \mdline{5110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5110} field. For example:%mdk + +%mdk-data-line={5112} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5112} +\item\mdline{5112}if a controller is not allowed to send a \mdline{5112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5112} message under its +current role definition, the code should be set to \mdline{5113}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5113}.%mdk + +%mdk-data-line={5114} +\item\mdline{5114}if the \mdline{5114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5114} repeated field in \mdline{5114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5114} does not match the P4Info +definition, the code should be set to \mdline{5115}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5115}. It may be useful +for the server to set the \mdline{5116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5116} field in this case, so that the client +can find out which set of metadata fields triggered the error.%mdk + +%mdk-data-line={5118} +\item\mdline{5118}if the \mdline{5118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{5118} field in \mdline{5118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{5118} does not match any \mdline{5118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{5118} entry +in P4Info, the code should be set to \mdline{5119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5119}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5121} +\noindent\mdline{5121}The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, \mdline{5122}e.g.\mdline{5122} because of a +burst of \mdline{5123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5123} messages.%mdk + +%mdk-data-line={5125} +\mdline{5125}Note that master-arbitration errors are never reported using the \mdline{5125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5125} +message. Invalid \mdline{5126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5126} messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section\mdline{5128}~\mdref{sec-mastership-updates}{5.3}\mdline{5128}.%mdk + +%mdk-data-line={5130} +\subsubsection{\mdline{5130}16.6.1.\hspace*{0.5em}\mdline{5130}Examples of \mdline{5130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5130} Messages}\label{sec-examples-of-streamerror-messages}%mdk%mdk + +%mdk-data-line={5132} +\begin{itemize}%mdk + +%mdk-data-line={5132} +\item{} +%mdk-data-line={5132} +\mdline{5132}\textbf{Malformed packet-out metadata.}\mdline{5132} If the server receives a \mdline{5132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5132} +message with a \mdline{5133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5133} field with id 7 which is not included in the P4Info +\mdline{5134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5134} message for \mdline{5134}\textquotedblleft{}packet\_out\textquotedblright{}\mdline{5134}, the server may send the +following \mdline{5135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5135} back to the client:%mdk + +%mdk-data-line={5136} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5137} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Unknown~metadata~field~id~7.}{\mdcolor{maroon}"}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~copied~from~the~PacketOut~message~received~from~the~client}\\ +~~~packet\_out~\{\\ +~~~~~payload:~...\\ +~~~~~metadata~\{\\ +~~~~~~~id:~{\mdcolor{purple}7}\\ +~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}I\_should\_not\_be\_here}{\mdcolor{maroon}"}\\ +~~~~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~~\}\\ +~~~~~{\mdcolor{darkgreen}\#~more~metadata}\\ +~~~\}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={5155} +\item{} +%mdk-data-line={5155} +\mdline{5155}\textbf{Packet-out which exceeds the MTU.}\mdline{5155} If the server receives a \mdline{5155}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5155} +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following \mdline{5158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5158}:%mdk + +%mdk-data-line={5159} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5160} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Packet~exceeds~the~MTU~for~port.}{\mdcolor{maroon}"}\\ +~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendor1}{\mdcolor{maroon}"}\\ +~code:~{\mdcolor{purple}123}~~{\mdcolor{darkgreen}\#~MTU\_EXCEEDED}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~we~do~not~set~the~packet\_out~field~as~it~does~not~provide~any}\\ +~~~{\mdcolor{darkgreen}\#~extra~information~to~the~client}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5172} +\section{\mdline{5172}17.\hspace*{0.5em}\mdline{5172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5172} RPC}\label{sec-capabilities-rpc}%mdk%mdk + +%mdk-data-line={5174} +\noindent\mdline{5174}The \mdline{5174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5174} RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the \mdline{5176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesRequest}}}\mdline{5176} message is empty and the \mdline{5176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5176} +message only includes the \mdline{5177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_api\_version}}}\mdline{5177} string field. This field must +be set to the full semantic version string\mdline{5178}~[\mdcite{semver}{26}]\mdline{5178} corresponding to the +version of the P4Runtime API implemented by the server, \mdline{5179}e.g.\mdline{5179} \mdline{5179}\textquotedblleft{}1.1.0-rc.1\textquotedblright{}\mdline{5179}.%mdk + +%mdk-data-line={5181} +\mdline{5181}Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three\mdline{5182}~\mdref{sec-batch-atomicity}{atomicity +modes}\mdline{5183} for \mdline{5183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5183} batches, two of them being +optional. In the future we may decide to leverage the \mdline{5184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5184} +message to enable the server to report to the client which subset of these +atomicity modes is supported.%mdk + +%mdk-data-line={5188} +\mdline{5188}The semantic version string included in \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5188} can be used by +the client to determine which exact feature set is implemented by the server, +since\mdline{5190}~\mdref{sec-p4runtime-versioning}{minor releases}\mdline{5190} may introduce new +functionality. However, because the \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5191} RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (\mdline{5193}i.e.\mdline{5193} an \mdline{5193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5193} error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0).%mdk + +%mdk-data-line={5197} +\section{\mdline{5197}18.\hspace*{0.5em}\mdline{5197}Portability Considerations}\label{sec-portability-considerations}%mdk%mdk + +%mdk-data-line={5199} +\subsection{\mdline{5199}18.1.\hspace*{0.5em}\mdline{5199}PSA Metadata Translation}\label{sec-psa-metadata-translation}%mdk%mdk + +%mdk-data-line={5201} +\noindent\mdline{5201}The \mdline{5201}\emph{Portable Switch Architecture}\mdline{5201} (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +\mdline{5205}[\mdcite{psatranslation}{23}]\mdline{5205}. For such metadata, a translation between the controller\mdline{5205}'\mdline{5205}s +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service.%mdk + +%mdk-data-line={5211} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={5212} +\noindent\mdline{5212}\includegraphics[keepaspectratio=true,height=7cm]{build/psa-metadata-translation}{}\mdline{5212}%mdk + +%mdk-data-line={5213} +\mdhr{}%mdk + +%mdk-data-line={5214} +\noindent\mdline{5214}\mdcaption{\textbf{Figure~\mdcaptionlabel{8}.}~\mdcaptiontext{P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdcenter}\label{fig-psa-metadata-translation}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={5218} +\noindent\mdline{5218}Figure\mdline{5218}~\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}}\mdline{5218} illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller\mdline{5224}'\mdline{5224}s 32 bit port +numbers to a target\mdline{5225}'\mdline{5225}s 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch.%mdk + +%mdk-data-line={5229} +\subsubsection{\mdline{5229}18.1.1.\hspace*{0.5em}\mdline{5229}Translation of Port Numbers}\label{sec-translation-of-port-numbers}%mdk%mdk + +%mdk-data-line={5231} +\noindent\mdline{5231}In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller\mdline{5232}'\mdline{5232}s space and the PSA device\mdline{5232}'\mdline{5232}s space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +\mdline{5236}\mdref{sec-user-defined-types}{user-defined P4 types}\mdline{5236}, namely \mdline{5236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5236} and +\mdline{5237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5237}, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in \mdline{5240}\emph{psa.p4}\mdline{5240} for +the PSA device in Switch 1.%mdk + +%mdk-data-line={5243} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5244} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~PortId\_t~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{};\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortIdInHeader\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~PortIdInHeader\_t~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5250} +\noindent\mdline{5250}The first argument to the \mdline{5250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5250} annotation is a URI that +indicates to the P4Runtime server which numerical mapping\mdline{5251} \mdline{5251}\textemdash{}\mdline{5251} provided by the +out-of-band switch configuration mechanism\mdline{5252} \mdline{5252}\textemdash{}\mdline{5252} to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports).%mdk + +%mdk-data-line={5256} +\mdline{5256}An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows:%mdk + +%mdk-data-line={5262} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5263} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}enum}}~SdnPort~\{\\ +~~SDN\_PORT\_UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +\\ +~~{\mdcolor{darkgreen}//~SDN~ports~are~numbered~starting~form~1.}\\ +~~SDN\_PORT\_MIN~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\\ +~~{\mdcolor{darkgreen}//~The~maximum~value~of~an~SDN~port~(physical~or~logical).}\\ +~~SDN\_PORT\_MAX~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffeff};\\ +\\ +~~{\mdcolor{darkgreen}//~Reserved~SDN~port~numbers~(0xfffffff0~-~0xffffffff)}\\ +\\ +~~SDN\_PORT\_RECIRCULATE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffa};\\ +~~SDN\_PORT\_CPU~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffd};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5279} +\noindent\mdline{5279}The switch config will map \mdline{5279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_RECIRCULATE}}}\mdline{5279} and \mdline{5279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_CPU}}}\mdline{5279} \mdline{5279}\textemdash{}\mdline{5279} as well +as any SDN port number corresponding to a \mdline{5280}\textquotedblleft{}regular\textquotedblright{}\mdline{5280} front-panel port\mdline{5280} \mdline{5280}\textemdash{}\mdline{5280} to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation.%mdk + +%mdk-data-line={5284} +\mdline{5284}The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs.%mdk + +%mdk-data-line={5287} +\subsubsection{\mdline{5287}18.1.2.\hspace*{0.5em}\mdline{5287}Translation of Packet-IO Header Fields}\label{sec-translation-of-packet-io-header-fields}%mdk%mdk + +%mdk-data-line={5289} +\noindent\mdline{5289}Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:.%mdk + +%mdk-data-line={5292} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5293} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~PortIdInHeader\_t~egress\_port;\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~PortIdInHeader\_t~ingress\_port;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5304} +\noindent\mdline{5304}The header-level annotation \mdline{5304}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5304} is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (\mdline{5308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5308}) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI\mdline{5312} \mdline{5312}\textemdash{}\mdline{5312} first argument to the \mdline{5312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5312} +annotation). Any subsequent reference to the \mdline{5313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5313} field in the +data plane will use the translated value. \mdline{5314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5314} is used in the +header definition instead of \mdline{5315}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5315} to guarantee byte-aligned headers in +case this is required by the target.%mdk + +%mdk-data-line={5318} +\mdline{5318}A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target\mdline{5320}'\mdline{5320}s PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the \mdline{5322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ingress\_port}}}\mdline{5322} field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller.%mdk + +%mdk-data-line={5328} +\subsubsection{\mdline{5328}18.1.3.\hspace*{0.5em}\mdline{5328}Translation of Match Fields}\label{sec-translation-of-match-fields}%mdk%mdk + +%mdk-data-line={5330} +\noindent\mdline{5330}Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table\mdline{5331}'\mdline{5331}s match key as shown in the example below:%mdk + +%mdk-data-line={5333} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5334} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~istd.ingress\_port:~exact;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~ingress~port}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5344} +\noindent\mdline{5344}Table \mdline{5344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5344} has an exact match on PSA standard metadata ingress port +(\mdline{5345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}istd.ingress\_port}}}\mdline{5345}). Since the field is of type \mdline{5345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5345}, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in \mdline{5348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5348} from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table \mdline{5353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5353} is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values.%mdk + +%mdk-data-line={5357} +\mdline{5357}Note that it may be infeasible to translate the value-mask pair for ternary +matches: \mdline{5358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5358}, \mdline{5358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5358} or \mdline{5358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5358} match kinds. The P4Runtime server may +require that for these match kinds the port match be either \mdline{5359}\emph{de facto}\mdline{5359} \mdline{5359}\textquotedblleft{}exact\textquotedblright{}\mdline{5359} +(0xffffffff mask for \mdline{5360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5360}, prefix-length of 32 for \mdline{5360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5360}, or same low and +high bounds for \mdline{5361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5361}) or \mdline{5361}\textquotedblleft{}don't care\textquotedblright{}\mdline{5361}.%mdk + +%mdk-data-line={5363} +\subsubsection{\mdline{5363}18.1.4.\hspace*{0.5em}\mdline{5363}Translation of Action Parameters}\label{sec-translation-of-action-parameters}%mdk%mdk + +%mdk-data-line={5365} +\noindent\mdline{5365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5365} type parameters can be part of a P4 action definition as shown in the +example below:%mdk + +%mdk-data-line={5368} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5369} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.h.f:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~a;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5383} +\noindent\mdline{5383}The controller may write entries in table \mdline{5383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5383} with action \mdline{5383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5383} to set the egress +port as shown in the P4 code above. The action parameter \mdline{5384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5384} is of type +\mdline{5385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5385}, which leads to a 32-bit bitwidth for \mdline{5385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5385} being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device.%mdk + +%mdk-data-line={5391} +\subsubsection{\mdline{5391}18.1.5.\hspace*{0.5em}\mdline{5391}Port Translation for PSA Extern APIs}\label{sec-port-translation-for-psa-extern-apis}%mdk%mdk + +%mdk-data-line={5393} +\noindent\mdline{5393}The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch field is +of type \mdline{5399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5399} to carry the 32-bit SDN representation of the port being +watched. The P4Runtime server will translate the given watch port number into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device.%mdk + +%mdk-data-line={5404} +\mdline{5404}The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type \mdline{5406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5406} to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane.%mdk + +%mdk-data-line={5410} +\subsubsection{\mdline{5410}18.1.6.\hspace*{0.5em}\mdline{5410}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}\label{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}%mdk%mdk + +%mdk-data-line={5412} +\noindent\mdline{5412}P4Runtime supports using a translated value (\mdline{5412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5412} or any other translated +type for which the underlying built-in type is \mdline{5413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5413}) as an index to a +register, indirect counter, or indirect meter.%mdk + +%mdk-data-line={5416} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5417} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~counter~entry~type~}{\mdcolor{darkgreen}*/},~PortId\_t~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~index~type~}{\mdcolor{darkgreen}*/}\textgreater{}(\\ +~~{\mdcolor{purple}32}w1024,~PSA\_CounterType\_t.PACKETS)~counter;\\ +{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +~~counter.count(p);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5425} +\noindent\mdline{5425}This P4 Counter declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={5428} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5429} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counters~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x12000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}counter}{\mdcolor{maroon}"}\\ +~~\}\\ +~~spec~\{\\ +~~~~unit:~PACKETS\\ +~~\}\\ +~~index\_type\_name~\{\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5443} +\noindent\mdline{5443}The controller may read and write counter values from indexed counter \mdline{5443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter}}}\mdline{5443} +using SDN port numbers as indices, and not device-specific port numbers. The +\mdline{5445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{5445} field in the P4Info message is a signal to the P4Runtime +server that translation is required.%mdk + +%mdk-data-line={5448} +\section{\mdline{5448}19.\hspace*{0.5em}\mdline{5448}P4Runtime Versioning}\label{sec-p4runtime-versioning}%mdk%mdk + +%mdk-data-line={5450} +\noindent\mdline{5450}P4Runtime follows the Google guidelines for versioning cloud APIs +\mdline{5451}[\mdcite{apiversioning}{6}]\mdline{5451}. We use a \mdline{5451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR.MINOR.PATCH}}}\mdline{5451} style version number scheme and +we increment the:%mdk + +%mdk-data-line={5454} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5454} +\item\mdline{5454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5454} version when we make incompatible API changes,%mdk + +%mdk-data-line={5455} +\item\mdline{5455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MINOR}}}\mdline{5455} version when we add functionality in a backwards-compatible manner,%mdk + +%mdk-data-line={5456} +\item\mdline{5456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PATCH}}}\mdline{5456} version when we make backwards-compatible bug fixes.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5458} +\noindent\mdline{5458}The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is \mdline{5460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1}}}\mdline{5460} and the package +name for P4Info is \mdline{5461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1}}}\mdline{5461}. Even though \mdline{5461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5461} and \mdline{5461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5461} are two +different Protobuf packages, \mdline{5462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5462} depends on \mdline{5462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5462} and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence.%mdk + +%mdk-data-line={5466} +\mdline{5466}As recommended in\mdline{5466}~[\mdcite{apiversioning}{6}]\mdline{5466}, we may consider using pre-GA release +suffixes (such as \mdline{5467}\emph{alpha}\mdline{5467} or \mdline{5467}\emph{beta}\mdline{5467}) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1).%mdk + +%mdk-data-line={5471} +\mdline{5471}Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner.\mdline{5472}~[\mdcite{apiversioningbackwardscompatibility}{7}]\mdline{5472} describes +what constitute a backwards-compatible change. We expect \mdline{5473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5473} version bumps +to be a \mdline{5474}\textbf{rare}\mdline{5474} event.%mdk + +%mdk-data-line={5476} +\mdline{5476}Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor\mdline{5481} \mdline{5481}+ patch version numbers in future releases.%mdk + +%mdk-data-line={5483} +\mdline{5483}All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository\mdline{5484}~[\mdcite{p4runtimerepo}{14}]\mdline{5484} and the version label follows +semantic versioning rules\mdline{5485}~[\mdcite{semver}{26}]\mdline{5485}.%mdk + +%mdk-data-line={5487} +\section{\mdline{5487}20.\hspace*{0.5em}\mdline{5487}Extending P4Runtime for non-PSA Architectures}\label{sec-extending-p4runtime}%mdk%mdk + +%mdk-data-line={5489} +\noindent\mdline{5489}P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place.%mdk + +%mdk-data-line={5497} +\mdline{5497}When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names:%mdk + +%mdk-data-line={5501} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5501} +\item\mdline{5501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/config/\textless{}major~version\textgreater{}/p4info.proto}}}\mdline{5501}%mdk + +%mdk-data-line={5502} +\item\mdline{5502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/\textless{}major~version\textgreater{}/p4runtime.proto}}}\mdline{5502}%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5504} +\noindent\mdline{5504}We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they \mdline{5505}\textquotedblleft{}extend\textquotedblright{}\mdline{5505}.%mdk + +%mdk-data-line={5507} +\mdline{5507}For the remainder of this section, we will refer to these two files as +\mdline{5508}\emph{p4info-ext}\mdline{5508} and \mdline{5508}\emph{p4runtime-ext}\mdline{5508} respectively.%mdk + +%mdk-data-line={5510} +\subsection{\mdline{5510}20.1.\hspace*{0.5em}\mdline{5510}Extending P4Runtime for Architecture-Specific Externs}\label{sec-extending-p4runtime-for-architecture-specific-externs}%mdk%mdk + +%mdk-data-line={5512} +\noindent\mdline{5512}Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both \mdline{5513}\emph{p4info-ext}\mdline{5513} and +\mdline{5514}\emph{p4runtime-ext}\mdline{5514}. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example:%mdk + +%mdk-data-line={5518} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5519} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~T~must~be~a~bit\textless{}W\textgreater{}~type,~it~indicates~the~width~of~each~counter~cell}\\ +{\bfseries{\mdcolor{navy}extern}}~MyNewPacketCounter\textless{}T\textgreater{}~\{\\ +~~counter({\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~size);\\ +~~increment({\bfseries{\mdcolor{navy}in}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~index);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5526} +\subsubsection{\mdline{5526}20.1.1.\hspace*{0.5em}\mdline{5526}Extending the P4Info message}\label{sec-extending-the-p4info-message}%mdk%mdk + +%mdk-data-line={5528} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5528} +\item\mdline{5528}Id prefixes \mdline{5528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0x81}}}\mdline{5528} through \mdline{5528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfe}}}\mdline{5528} are reserved for architecture-specific +externs. It is recommended that \mdline{5529}\emph{p4info-ext}\mdline{5529} include a \mdline{5529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Ids}}}\mdline{5529} message based +on the one in p4info.proto that the P4 compiler can refer to when\mdline{5530}~\mdref{sec-id-allocation}{assigning +IDs}\mdline{5531} to each extern instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5533} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5534} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~P{\mdcolor{purple}4}Ids~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Prefix~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~MY\_NEW\_PACKET\_COUNTER~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0x81};\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5542} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5542} +\item\mdline{5542}\emph{p4info-ext}\mdline{5542} should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +\mdline{5546}\mdref{sec-p4info-extern}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ExternInstance}}}}\mdline{5546} message as the \mdline{5546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{5546} +field, which is of type \mdline{5547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5547}~[\mdcite{protoany}{30}]\mdline{5547}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5549} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5550} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\mdcolor{darkgreen}//~corresponds~to~the~T~type~parameter~in~the~P4~extern~definition}\\ +~~p4.config.v1.P{\mdcolor{purple}4}DataTypeSpec~type\_spec~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~constructor~argument}\\ +~~{\bfseries{\mdcolor{navy}int64}}~size~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5558} +\subsubsection{\mdline{5558}20.1.2.\hspace*{0.5em}\mdline{5558}Extending the P4Runtime Service}\label{sec-extending-the-p4runtime-service}%mdk%mdk + +%mdk-data-line={5560} +\noindent\mdline{5560}Just like \mdline{5560}\emph{p4info-ext}\mdline{5560}, \mdline{5560}\emph{p4runtime-ext}\mdline{5560} should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an\mdline{5565}~\mdref{sec-extern-entry}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\mdline{5565} message generated by the +P4Runtime client.%mdk + +%mdk-data-line={5568} +\mdline{5568}Here is a possible Protobuf message for our \mdline{5568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyNewPacketCounter}}}\mdline{5568} P4 extern:%mdk + +%mdk-data-line={5569} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5570} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~This~message~enables~reading~/~writing~data~to~the~counter~at~the~provided}\\ +{\mdcolor{darkgreen}//~index}\\ +{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~p4.v1.P{\mdcolor{purple}4}Data~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5578} +\noindent\mdline{5578}P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an \mdline{5579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5579} Protobuf field\mdline{5579}~[\mdcite{protoany}{30}]\mdline{5579} named \mdline{5579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5579} +in both \mdline{5580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{5580} and +\mdline{5581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{5581}. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in \mdline{5583}\emph{p4runtime-ext}\mdline{5583} and embed instances of these messages in +\mdline{5584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{5584} and \mdline{5584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{5584} as appropriate.%mdk + +%mdk-data-line={5586} +\subsection{\mdline{5586}20.2.\hspace*{0.5em}\mdline{5586}Architecture-Specific Table Extensions}\label{sec-architecture-specific-table-extensions}%mdk%mdk + +%mdk-data-line={5588} +\subsubsection{\mdline{5588}20.2.1.\hspace*{0.5em}\mdline{5588}New Match Types}\label{sec-new-match-types}%mdk%mdk + +%mdk-data-line={5590} +\noindent\mdline{5590}An architecture may introduce new table match types\mdline{5590}~[\mdcite{p4matchtypes}{12}]\mdline{5590}. P4Runtime +accounts for this by providing the following hooks:%mdk + +%mdk-data-line={5593} +\begin{itemize}%mdk + +%mdk-data-line={5593} +\item{} +%mdk-data-line={5593} +\mdline{5593}The \mdline{5593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{5593} field in \mdline{5593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{5593} (p4info.proto) is a \mdline{5593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5593} +which can be either one of the default match types (\mdline{5594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{5594}, \mdline{5594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5594}, \mdline{5594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5594} +or \mdline{5595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5595}) or an architecture-specific match type encoded as a string.%mdk%mdk + +%mdk-data-line={5597} +\item{} +%mdk-data-line={5597} +\mdline{5597}The \mdline{5597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{5597} field in \mdline{5597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{5597} (p4runtime.proto) is a +\mdline{5598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5598} which includes an \mdline{5598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5598} Protobuf message\mdline{5598}~[\mdcite{protoany}{30}]\mdline{5598} field +(\mdline{5599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5599}). \mdline{5599}\emph{p4info-ext}\mdline{5599} should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in \mdline{5602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{5602} as the +\mdline{5603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5603} field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5606} +\subsubsection{\mdline{5606}20.2.2.\hspace*{0.5em}\mdline{5606}New Table Properties}\label{sec-new-table-properties}%mdk%mdk + +%mdk-data-line={5608} +\noindent\mdline{5608}An architecture may introduce additional table properties +\mdline{5609}[\mdcite{p4tableproperties}{29}]\mdline{5609}. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +\mdline{5611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Table}}}\mdline{5611} message includes the \mdline{5611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{5611} \mdline{5611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5611} Protobuf +field\mdline{5612}~[\mdcite{protoany}{30}]\mdline{5612}. At the moment, there is not any mechanism to extend the +\mdline{5613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.TableEntry}}}\mdline{5613} message based on the value of architecture-specific table +properties, but we may include on in future versions of the API.%mdk + +%mdk-data-line={5616} +\section{\mdline{5616}21.\hspace*{0.5em}\mdline{5616}Known Limitations of Current P4Runtime Version}\label{sec-known-limitations-of-current-p4runtime-version}%mdk%mdk + +%mdk-data-line={5618} +\begin{itemize}%mdk + +%mdk-data-line={5618} +\item{} +%mdk-data-line={5618} +\mdline{5618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{5618}, action \mdline{5618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{5618}, and controller packet metadata fields only +support unsigned bitstrings, \mdline{5619}i.e.\mdline{5619} values of one of the following types (not +the more general \mdline{5620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{5620}):%mdk + +%mdk-data-line={5621} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5621} +\item\mdline{5621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5621}%mdk + +%mdk-data-line={5622} +\item\mdline{5622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{5622}. Note that as far as the \mdline{5622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Info}}}\mdline{5622} message contents and +thus controller software is concerned, such fields of type \mdline{5623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{5623} +will be indistinguishable from those that have been declared with +type \mdline{5625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{5625}. P4Runtime server software will automatically +perform any conversion needed between the type \mdline{5626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{5626} values in +P4Runtime messages and the data plane representation.%mdk + +%mdk-data-line={5628} +\item\mdline{5628}an \mdline{5628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{5628} with underlying type \mdline{5628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5628}%mdk + +%mdk-data-line={5629} +\item\mdline{5629}a \mdline{5629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{5629} or \mdline{5629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{5629} with an underlying type that is one of the above (or +in general a \mdline{5630}\textquotedblleft{}chain\textquotedblright{}\mdline{5630} of \mdline{5630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{5630} and/or \mdline{5630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{5630} that eventually ends with +one of the types above)%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={5633} +\item{} +%mdk-data-line={5633} +\mdline{5633}Support for PSA Random \mdline{5633}\&\mdline{5633} Timestamp externs is postponed to a future minor +version update.%mdk%mdk + +%mdk-data-line={5636} +\item{} +%mdk-data-line={5636} +\mdline{5636}P4Info does not include information about which of a table\mdline{5636}'\mdline{5636}s actions execute +which direct resource(s).%mdk%mdk + +%mdk-data-line={5639} +\item{} +%mdk-data-line={5639} +\mdline{5639}The default action for indirect match tables is restricted to a \mdline{5639}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\\ +NoAction}}}\mdline{5640} known at compile-time.%mdk%mdk + +%mdk-data-line={5642} +\item{} +%mdk-data-line={5642} +\mdline{5642}There is no mechanism for changing the value of the \mdline{5642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{5642} +table property at runtime.%mdk%mdk + +%mdk-data-line={5645} +\item{} +%mdk-data-line={5645} +\mdline{5645}There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor\mdline{5646} \mdline{5646}+ +patch version numbers.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5649} +\section{\mdline{5649}22.\hspace*{0.5em}\mdline{5649}Security concerns for P4Runtime}\label{sec-security-concerns-for-p4runtime}%mdk%mdk + +%mdk-data-line={5651} +\noindent\mdline{5651}Appropriate measures and security best practices need to be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client.%mdk + +%mdk-data-line={5658} +\section{\mdline{5658}A.\hspace*{0.5em}\mdline{5658}Appendix}\label{sec-appendix}%mdk%mdk + +%mdk-data-line={5660} +\subsection{\mdline{5660}A.1.\hspace*{0.5em}\mdline{5660}Revision History}\label{sec-revision-history}%mdk%mdk + +%mdk-data-line={5662} +\subsubsection{\mdline{5662}A.1.1.\hspace*{0.5em}\mdline{5662}Changes in v1.1.0}\label{sec-changes-in-v110}%mdk%mdk + +%mdk-data-line={5664} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5664} +\item\mdline{5664}Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously.%mdk + +%mdk-data-line={5670} +\item\mdline{5670}Add \mdline{5670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5670} field to stream messages sent by the server.%mdk + +%mdk-data-line={5671} +\item\mdline{5671}Add \mdline{5671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5671} RPC to query the P4Runtime API version implemented by the +server.%mdk + +%mdk-data-line={5673} +\item\mdline{5673}Support wildcard reads for multicast groups and clone sessions.%mdk + +%mdk-data-line={5674} +\item\mdline{5674}Support for modifying direct resources of const tables.%mdk + +%mdk-data-line={5675} +\item\mdline{5675}Support P4 user-defined types for Packet IO metadata fields.%mdk + +%mdk-data-line={5676} +\item\mdline{5676}Clarify consistency requirements for \mdline{5676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5676} and \mdline{5676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5676} RPCs.%mdk + +%mdk-data-line={5677} +\item\mdline{5677}Add Appendix providing implementation advice for avoiding common pitfalls: + +%mdk-data-line={5678} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5678} +\item\mdline{5678}advice on setting gRPC Metadata Maximum Size%mdk + +%mdk-data-line={5679} +\item\mdline{5679}advice on setting gRPC Server Maximum Receive Message Size%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={5680} +\item\mdline{5680}Clarify limitations on supported types for \mdline{5680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{5680}, action \mdline{5680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{5680}, and +Packet IO metadata fields.%mdk + +%mdk-data-line={5682} +\item\mdline{5682}Clarify that reading entire forwarding state with empty \mdline{5682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5682} is not +supported.%mdk + +%mdk-data-line={5684} +\item\mdline{5684}Document that \mdline{5684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5684} need only be supported when applied to +type declarations in P4.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5687} +\subsection{\mdline{5687}A.2.\hspace*{0.5em}\mdline{5687}P4 Annotations}\label{sec-p4-annotations}%mdk%mdk + +%mdk-data-line={5689} +\noindent\mdline{5689}Table\mdline{5689}~\mdref{tab-p4-annotations}{\mdcaptionlabel{7}}\mdline{5689} lists P4\mdline{5689}\mdsub{16}\mdline{5689} annotations introduced primarily for +the purpose of adding features for the P4Runtime API.%mdk + +%mdk-data-line={5692} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{5694} Annotation}}&\multicolumn{1}{|c|}{{\bfseries\mdline{5694} Description}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{5696} \mdline{5696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{5696}}&\multicolumn{1}{|l|}{\mdline{5696} See section\mdline{5696}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{5696}}\\ +\multicolumn{1}{|l}{\mdline{5697} \mdline{5697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5697}}&\multicolumn{1}{|l|}{\mdline{5697} See section\mdline{5697}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{5697}}\\ +\multicolumn{1}{|l}{\mdline{5698} \mdline{5698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{5698}}&\multicolumn{1}{|l|}{\mdline{5698} See section\mdline{5698}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{5698}}\\ +\multicolumn{1}{|l}{\mdline{5699} \mdline{5699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{5699}}&\multicolumn{1}{|l|}{\mdline{5699} See section\mdline{5699}~\mdref{sec-id-allocation}{6.3}\mdline{5699}}\\ +\multicolumn{1}{|l}{\mdline{5700} \mdline{5700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{5700}}&\multicolumn{1}{|l|}{\mdline{5700} See sections\mdline{5700}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{5700},\mdline{5700}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{5700}}\\ +\multicolumn{1}{|l}{\mdline{5701} \mdline{5701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{5701}}&\multicolumn{1}{|l|}{\mdline{5701} See section\mdline{5701}~\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1}\mdline{5701}}\\ +\multicolumn{1}{|l}{\mdline{5702} \mdline{5702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5702}}&\multicolumn{1}{|l|}{\mdline{5702} See sections\mdline{5702}~\mdref{sec-user-defined-types}{8.5.6}\mdline{5702},\mdline{5702}~\mdref{sec-translation-of-port-numbers}{18.1.1}\mdline{5702}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={5704} +\mdhr{}%mdk + +%mdk-data-line={5705} +\noindent\mdline{5705}\mdcaption{\textbf{Table~\mdcaptionlabel{7}.}~\mdcaptiontext{P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-annotations}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={5708} +\subsection{\mdline{5708}A.3.\hspace*{0.5em}\mdline{5708}A More Complex Value Set Example}\label{sec-value-set-example}%mdk%mdk + +%mdk-data-line={5710} +\noindent\mdline{5710}This section includes a more complex Value Set example, with multiple matches of +different kinds.%mdk + +%mdk-data-line={5713} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5714} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5723} +\noindent\mdline{5723}This P4 Value Set declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={5726} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5727} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5754} +\noindent\mdline{5754}A P4Runtime client can set the membership for this Value Set with \mdline{5754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5754} +messages similar to this one:%mdk + +%mdk-data-line={5757} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5758} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xac}~\}\\ +~~~~~~\}\\ +~~~~~~{\mdcolor{darkgreen}\#~match~for~field\_id~2~is~missing~=\textgreater{}~don't~care~match}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xdc}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~~~ternary~\{~value:~{\mdcolor{purple}0x88}~mask:~{\mdcolor{purple}8}f~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5792} +\subsection{\mdline{5792}A.4.\hspace*{0.5em}\mdline{5792}Guidelines for Implementations}\label{sec-guidelines-for-implementations}%mdk%mdk + +%mdk-data-line={5794} +\noindent\mdline{5794}This section contains practical advice for implementing P4Runtime clients and +servers.%mdk + +%mdk-data-line={5797} +\subsubsection{\mdline{5797}A.4.1.\hspace*{0.5em}\mdline{5797}gRPC Metadata Maximum Size}\label{sec-grpc-metadata-maximum-size}%mdk%mdk + +%mdk-data-line={5799} +\noindent\mdline{5799}In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the \mdline{5800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{5800} gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the \mdline{5801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5801} P4Runtime RPC. The \mdline{5801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5801} RPC +returns an individual error for every item in a batch (see Section +\mdline{5803}\mdref{sec-write-rpc}{12}\mdline{5803}), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +\mdline{5805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{5805} error, without any of the individual errors.%mdk + +%mdk-data-line={5807} +\mdline{5807}To fix this problem, one can set the \mdline{5807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{5807} option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it\mdline{5809}'\mdline{5809}s +limit, as only the receiving side\mdline{5810}'\mdline{5810}s limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every \mdline{5812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5812}, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +\mdline{5814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}8192~+~MAX\_UPDATES\_PER\_WRITE~*~100}}}\mdline{5814} bytes of metadata.%mdk + +%mdk-data-line={5816} +\mdline{5816}For example, in C++, one can create a client channel as follows:%mdk + +%mdk-data-line={5817} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5818} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}~=~{\mdcolor{purple}100};\\ +::{\mdcolor{navy}grpc::}ChannelArguments~arguments;\\ +arguments{\bfseries{\mdcolor{navy}.}}SetInt({\mdcolor{teal}GRPC\_ARG\_MAX\_METADATA\_SIZE},~{\mdcolor{purple}8192}~+~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}*{\mdcolor{purple}100});\\ +{\bfseries{\mdcolor{navy}return}}~{\mdcolor{navy}grpc::}CreateCustomChannel(address,~credentials,~arguments);}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5824} +\subsubsection{\mdline{5824}A.4.2.\hspace*{0.5em}\mdline{5824}gRPC Server Maximum Receive Message Size}\label{sec-grpc-server-maximum-receive-message-size}%mdk%mdk + +%mdk-data-line={5826} +\noindent\mdline{5826}At the time of writing, the default maximum receive message size in gRPC is 4MB +\mdline{5827}\textemdash{}\mdline{5827} while the default maximum send message size is unlimited. This can be a +problem for the \mdline{5828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5828} RPC, since for some targets the +binary \mdline{5829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5829} can exceed 4MB, in which case by default the P4Runtime +server would return an \mdline{5830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5830} error. To a lesser extent, this may +affect the \mdline{5831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5831} RPC as well, in case of extremely large batches.%mdk + +%mdk-data-line={5833} +\mdline{5833}To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of \mdline{5835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5835} for their target(s). This can be done by +setting the \mdline{5836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_receive\_message\_length}}}\mdline{5836} when building the gRPC server.%mdk + +%mdk-data-line={5838} +\mdline{5838}For example, in C++, one can set the maximum receive message size as follows:%mdk + +%mdk-data-line={5839} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5840} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE}~=~{\mdcolor{purple}128}~*~{\mdcolor{purple}1024}~*~{\mdcolor{purple}1024};~~{\mdcolor{darkgreen}//~128MB}\\ +::{\mdcolor{navy}grpc::}ServerBuilder~server\_builder;\\ +builder{\bfseries{\mdcolor{navy}.}}AddListeningPort({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});\\ +builder{\bfseries{\mdcolor{navy}.}}RegisterService({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});~~{\mdcolor{darkgreen}//~register~P4Runtime~service}\\ +builder{\bfseries{\mdcolor{navy}.}}SetMaxReceiveMessageSize({\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE});\\ +builder{\bfseries{\mdcolor{navy}.}}BuildAndStart();}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5848} +\noindent\mdline{5848}On the client side, we recommend that P4Runtime clients do not use \mdline{5848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5848} +batches larger than the default maximum receive message size (4MB)\mdline{5849} \mdline{5849}\textemdash{}\mdline{5849} in case +the server did not deem necessary to increase the default value\mdline{5850} \mdline{5850}\textemdash{}\mdline{5850}, unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB).%mdk + +%mdk-data-line={5856;build/P4Runtime-Spec-bib.bbl.mdk:1} +%mdk-data-line={5856;build/P4Runtime-Spec-bib.bbl.mdk:2} +\mdsetrefname{References}%mdk +{\mdbibindent{0}%mdk +\begin{thebibliography}{37}%mdk +\label{sec-bibliography}%mdk + +%mdk-data-line={references.bib:68} +\bibitem{p4spec}\mdbibitemlabel{{}[1]}\textquotedblleft{}$P4_{16}$ 1.2.0 Specification.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html}}.\label{p4spec}%mdk%mdk + +%mdk-data-line={references.bib:134} +\bibitem{rfc2698}\mdbibitemlabel{{}[2]}\textquotedblleft{}A Two Rate Three Color Marker.\textquotedblright{} \href{https://tools.ietf.org/html/rfc2698}{{\ttfamily https://\hspace{0pt}tools.\hspace{0pt}ietf.\hspace{0pt}org/\hspace{0pt}html/\hspace{0pt}rfc2698}}.\label{rfc2698}%mdk%mdk + +%mdk-data-line={references.bib:32} +\bibitem{p4complextypes}\mdbibitemlabel{{}[3]}\textquotedblleft{}Complex Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-p4-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}p4-\hspace{0pt}type}}.\label{p4complextypes}%mdk%mdk + +%mdk-data-line={references.bib:37} +\bibitem{protodefaults}\mdbibitemlabel{{}[4]}\textquotedblleft{}Default Values for Protobuf 3 ($proto3$) Fields.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23default}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}default}}.\label{protodefaults}%mdk%mdk + +%mdk-data-line={references.bib:78} +\bibitem{p4enums}\mdbibitemlabel{{}[5]}\textquotedblleft{}Enums in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-enum-types}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}enum-\hspace{0pt}types}}.\label{p4enums}%mdk%mdk + +%mdk-data-line={references.bib:119} +\bibitem{apiversioning}\mdbibitemlabel{{}[6]}\textquotedblleft{}Google Cloud APIs Versioning.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning}}.\label{apiversioning}%mdk%mdk + +%mdk-data-line={references.bib:124} +\bibitem{apiversioningbackwardscompatibility}\mdbibitemlabel{{}[7]}\textquotedblleft{}Google Cloud APIs Versioning - Backwards-Compatibility.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning\%23backwards_compatibility}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning\#\hspace{0pt}backwards\_\hspace{0pt}compatibility}}.\label{apiversioningbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:149} +\bibitem{grpcauth}\mdbibitemlabel{{}[8]}\textquotedblleft{}gRPC Authentication.\textquotedblright{} \href{https://grpc.io/docs/guides/auth.html}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}guides/\hspace{0pt}auth.\hspace{0pt}html}}.\label{grpcauth}%mdk%mdk + +%mdk-data-line={references.bib:7} +\bibitem{grpc}\mdbibitemlabel{{}[9]}\textquotedblleft{}gRPC Main Site.\textquotedblright{} \href{https://grpc.io}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io}}.\label{grpc}%mdk%mdk + +%mdk-data-line={references.bib:144} +\bibitem{grpcstreamc}\mdbibitemlabel{{}[10]}\textquotedblleft{}gRPC Streaming RPCs in C++.\textquotedblright{} \href{https://grpc.io/docs/tutorials/basic/c.html\%23streaming-rpcs}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}tutorials/\hspace{0pt}basic/\hspace{0pt}c.\hspace{0pt}html\#\hspace{0pt}streaming-\hspace{0pt}rpcs}}.\label{grpcstreamc}%mdk%mdk + +%mdk-data-line={references.bib:114} +\bibitem{p4newtypes}\mdbibitemlabel{{}[11]}\textquotedblleft{}Introducing New Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-newtype}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}newtype}}.\label{p4newtypes}%mdk%mdk + +%mdk-data-line={references.bib:139} +\bibitem{p4matchtypes}\mdbibitemlabel{{}[12]}\textquotedblleft{}Match Types in P4.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-match-kind-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}match-\hspace{0pt}kind-\hspace{0pt}type}}.\label{p4matchtypes}%mdk%mdk + +%mdk-data-line={references.bib:174} +\bibitem{p4concurrency}\mdbibitemlabel{{}[13]}\textquotedblleft{}P4 Concurrency Model.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-concurrency}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}concurrency}}.\label{p4concurrency}%mdk%mdk + +%mdk-data-line={references.bib:1} +\bibitem{p4runtimerepo}\mdbibitemlabel{{}[14]}\textquotedblleft{}p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.\textquotedblright{} \href{https://github.com/p4lang/p4runtime}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4runtime}}.\label{p4runtimerepo}%mdk%mdk + +%mdk-data-line={references.bib:42} +\bibitem{pirepo}\mdbibitemlabel{{}[15]}\textquotedblleft{}p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.\textquotedblright{} \href{https://github.com/p4lang/PI}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}PI}}.\label{pirepo}%mdk%mdk + +%mdk-data-line={references.bib:109} +\bibitem{p4apiwgcharter}\mdbibitemlabel{{}[16]}\textquotedblleft{}P4.org API Working Group Charter.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4_API_WG_charter.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4\_\hspace{0pt}API\_\hspace{0pt}WG\_\hspace{0pt}charter.\hspace{0pt}html}}.\label{p4apiwgcharter}%mdk%mdk + +%mdk-data-line={references.bib:154} +\bibitem{p4actionannotations}\mdbibitemlabel{{}[17]}\textquotedblleft{}P4 Standard Annotations on Table Actions.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-table-action-anno}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}action-\hspace{0pt}anno}}.\label{p4actionannotations}%mdk%mdk + +%mdk-data-line={references.bib:73} +\bibitem{psa}\mdbibitemlabel{{}[18]}\textquotedblleft{}Portable Switch Architecture Specification (v1.1.0).\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html}}.\label{psa}%mdk%mdk + +%mdk-data-line={references.bib:189} +\bibitem{protooneofbackwardscompatibility}\mdbibitemlabel{{}[19]}\textquotedblleft{}Protobuf OneOf Backwards-Compatibility Issues.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23backwards-compatibility-issues}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}backwards-\hspace{0pt}compatibility-\hspace{0pt}issues}}.\label{protooneofbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:12} +\bibitem{proto}\mdbibitemlabel{{}[20]}\textquotedblleft{}Protocol Buffers Main Site.\textquotedblright{} \href{https://developers.google.com/protocol-buffers}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers}}.\label{proto}%mdk%mdk + +%mdk-data-line={references.bib:159} +\bibitem{psaactionselector}\mdbibitemlabel{{}[21]}\textquotedblleft{}PSA Action Selector.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-action-selector}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}action-\hspace{0pt}selector}}.\label{psaactionselector}%mdk%mdk + +%mdk-data-line={references.bib:169} +\bibitem{psaatomicityofcontrolplaneops}\mdbibitemlabel{{}[22]}\textquotedblleft{}PSA Atomicity of Control Plane Operations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-atomicity-of-control-plane-api-operations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}atomicity-\hspace{0pt}of-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}api-\hspace{0pt}operations}}.\label{psaatomicityofcontrolplaneops}%mdk%mdk + +%mdk-data-line={references.bib:179} +\bibitem{psatranslation}\mdbibitemlabel{{}[23]}\textquotedblleft{}PSA Data Plane vs Control Plane Types.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-data-plane-vs-control-plane-values}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}data-\hspace{0pt}plane-\hspace{0pt}vs-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}values}}.\label{psatranslation}%mdk%mdk + +%mdk-data-line={references.bib:164} +\bibitem{psaemptygroupactionappendix}\mdbibitemlabel{{}[24]}\textquotedblleft{}PSA Empty Group Action Appendix.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23appendix-empty-action-selector-groups}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}appendix-\hspace{0pt}empty-\hspace{0pt}action-\hspace{0pt}selector-\hspace{0pt}groups}}.\label{psaemptygroupactionappendix}%mdk%mdk + +%mdk-data-line={references.bib:58} +\bibitem{p4selectexpr}\mdbibitemlabel{{}[25]}\textquotedblleft{}Select Expressions in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-select}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}select}}.\label{p4selectexpr}%mdk%mdk + +%mdk-data-line={references.bib:129} +\bibitem{semver}\mdbibitemlabel{{}[26]}\textquotedblleft{}Semantic Versioning.\textquotedblright{} \href{https://semver.org/}{{\ttfamily https://\hspace{0pt}semver.\hspace{0pt}org/\hspace{0pt}}}.\label{semver}%mdk%mdk + +%mdk-data-line={references.bib:98} +\bibitem{protostatus}\mdbibitemlabel{{}[27]}\textquotedblleft{}Status.proto:the Protobuf Status Message.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}src/\hspace{0pt}proto/\hspace{0pt}grpc/\hspace{0pt}status/\hspace{0pt}status.\hspace{0pt}proto}}.\label{protostatus}%mdk%mdk + +%mdk-data-line={references.bib:63} +\bibitem{p4revisions110}\mdbibitemlabel{{}[28]}\textquotedblleft{}Summary of Changes Made in $P4_{16}$ Version 1.1.0.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-summary-of-changes-made-in-version-110}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}summary-\hspace{0pt}of-\hspace{0pt}changes-\hspace{0pt}made-\hspace{0pt}in-\hspace{0pt}version-\hspace{0pt}110}}.\label{p4revisions110}%mdk%mdk + +%mdk-data-line={references.bib:48} +\bibitem{p4tableproperties}\mdbibitemlabel{{}[29]}\textquotedblleft{}Table Properties in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-table-props}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}props}}.\label{p4tableproperties}%mdk%mdk + +%mdk-data-line={references.bib:83} +\bibitem{protoany}\mdbibitemlabel{{}[30]}\textquotedblleft{}The Any Protobuf Message.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23any}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}any}}.\label{protoany}%mdk%mdk + +%mdk-data-line={references.bib:88} +\bibitem{grpcstatus}\mdbibitemlabel{{}[31]}\textquotedblleft{}The gRPC $Status$ Class.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/status.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}impl/\hspace{0pt}codegen/\hspace{0pt}status.\hspace{0pt}h}}.\label{grpcstatus}%mdk%mdk + +%mdk-data-line={references.bib:104} +\bibitem{grpcerrordetails}\mdbibitemlabel{{}[32]}\textquotedblleft{}The gRPC C++ Error Details Library.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/support/error_details.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}support/\hspace{0pt}error\_\hspace{0pt}details.\hspace{0pt}h}}.\label{grpcerrordetails}%mdk%mdk + +%mdk-data-line={references.bib:93} +\bibitem{grpcstatuscodes}\mdbibitemlabel{{}[33]}\textquotedblleft{}The gRPC Canonical Status Codes.\textquotedblright{} \href{https://developers.google.com/maps-booking/reference/grpc-api/status_codes}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}maps-\hspace{0pt}booking/\hspace{0pt}reference/\hspace{0pt}grpc-\hspace{0pt}api/\hspace{0pt}status\_\hspace{0pt}codes}}.\label{grpcstatuscodes}%mdk%mdk + +%mdk-data-line={references.bib:22} +\bibitem{openconfig}\mdbibitemlabel{{}[34]}\textquotedblleft{}The OpenConfig Project.\textquotedblright{} \href{http://openconfig.net}{{\ttfamily http://\hspace{0pt}openconfig.\hspace{0pt}net}}.\label{openconfig}%mdk%mdk + +%mdk-data-line={references.bib:184} +\bibitem{protomessagedifferencer}\mdbibitemlabel{{}[35]}\textquotedblleft{}The Protobuf MessageDifferencer in the C++ API.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.util.message_differencer}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}reference/\hspace{0pt}cpp/\hspace{0pt}google.\hspace{0pt}protobuf.\hspace{0pt}util.\hspace{0pt}message\_\hspace{0pt}differencer}}.\label{protomessagedifferencer}%mdk%mdk + +%mdk-data-line={references.bib:27} +\bibitem{stratum}\mdbibitemlabel{{}[36]}\textquotedblleft{}The Stratum Project.\textquotedblright{} \href{https://stratumproject.org/}{{\ttfamily https://\hspace{0pt}stratumproject.\hspace{0pt}org/\hspace{0pt}}}.\label{stratum}%mdk%mdk + +%mdk-data-line={references.bib:53} +\bibitem{p4valuesets}\mdbibitemlabel{{}[37]}\textquotedblleft{}Value Sets in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-value-set}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}value-\hspace{0pt}set}}.\label{p4valuesets}%mdk%mdk +\par%mdk +\end{thebibliography}}%mdk%mdk +}%mdk + + +\end{document} diff --git a/spec/v1.1.0-rc.1/ellipse.sty b/spec/v1.1.0-rc.1/ellipse.sty new file mode 100644 index 00000000..7c0ecb3e --- /dev/null +++ b/spec/v1.1.0-rc.1/ellipse.sty @@ -0,0 +1,318 @@ +%% +%% This is file `ellipse.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ellipse.dtx (with options: `package') +%% +%% Copyright (C) 2015 +%% Daan Leijen +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". +%% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{ellipse} + [2004/11/05 v1.0 .dtx ellipse file] +\RequirePackage{pict2e} + +\providecommand*\pIIe@csedef[1]{\expandafter\edef\csname #1\endcsname} +\newcommand*\pIIe@ellip@csqrt[3]{% + \@ovxx=#1\relax + \ifdim\@ovxx<\z@\@ovxx-\@ovxx\fi + \@ovyy=#2\relax + \ifdim\@ovyy<\z@\@ovyy-\@ovyy\fi + \edef\pIIe@csname{@csqrt(\number\@ovxx,\number\@ovyy)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@ellip@csqrt@% + \pIIe@csedef{\pIIe@csname}{\the\dimen@}% + #3\dimen@ + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} +\newcommand*\pIIe@ellip@csqrt@{% + \@ovdx\@ovxx + \advance\@ovdx by \@ovyy + \dimen@0.7071067\@ovdx + \ifdim\dimen@<\@ovyy\dimen@\@ovyy\fi + \ifdim\dimen@<\@ovxx\dimen@\@ovxx\fi + \ifdim\@ovdx<128\p@ + \edef\@tempa{\strip@pt\@ovxx}% + \@ovxx\@tempa\@ovxx + \edef\@tempa{\strip@pt\@ovyy}% + \@ovyy\@tempa\@ovyy + \advance\@ovxx by \@ovyy + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \fi +} + +\newcommand*\pIIe@atan@{% + \@tempdima\dimen@ + \@tempdimb\@tempdima + \ifdim\@tempdimb<\z@\@tempdimb-\@tempdimb\fi + \dimen@0.0663\@tempdimb + \advance\dimen@ 0.2447pt\relax + \advance\@tempdimb -1pt\relax + \edef\@tempa{\strip@pt\@tempdimb}% + \dimen@\@tempa\dimen@ + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \dimen@-\dimen@ + \advance\dimen@ 0.7853\@tempdima +} + +\newcommand*\pIIe@atantwo[3]{% + \edef\pIIe@csname{@atan2(\number\dimexpr#1\relax,\number\dimexpr#2\relax)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@atantwo@{#1}{#2}{#3}% + \pIIe@csedef{\pIIe@csname}{\the\dimexpr#3\relax}% + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} + +\newcommand*\pIIe@atantwo@[3]{% + \@tempdima\dimexpr#2\relax + \@tempdimb\dimexpr#1\relax + \ifdim\@tempdima=\z@\relax + \ifdim\@tempdimb>\z@\relax\dimen@90\p@ + \else\ifdim\@tempdimb<\z@\relax\dimen@-90\p@ + \else\dimen@0\p@ + \fi\fi + \else + \@tempdimd\z@ + \ifdim\@tempdima<\z@\relax + \ifdim\@tempdimb<\z@\relax\@tempdimd-180\p@ + \else\@tempdimd180\p@ + \fi + \fi + \dimen@\dimexpr1pt * \@tempdimb/\@tempdima\relax + \@tempdimc\dimen@ + \ifdim\@tempdimc<\z@\relax\@tempdimc-\@tempdimc\fi + \ifdim\@tempdimc>\p@\relax + \dimen@\dimexpr1pt * \@tempdima/\@tempdimb\relax + \ifdim\dimen@<\z@\relax\def\@tempsign{-}\else\def\@tempsign{}\fi + \pIIe@atan@ + \dimen@-\dimen@ + \advance\dimen@ by \@tempsign1.5707pt\relax + \else + \pIIe@atan@ + \fi + \dimen@57.29578\dimen@ + \advance\dimen@ by \@tempdimd + \fi + #3\dimen@% +} + +\newcommand*\pIIe@noneto[2]{} +\newcommand*\pIIe@ellip@sincost@[2]{% + \CalculateSin{#1}% + \CalculateCos{#1}% + \@tempdima\UseSin{#1}\p@ + \@tempdimb\UseCos{#1}\p@ + \ifdim\@tempdima=\p@\relax + \pIIe@csedef{@ellipsin#2}{1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else\ifdim\@tempdima=-\p@\relax + \pIIe@csedef{@ellipsin#2}{-1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else + \@tempdimc\@ellipratio\dimexpr1pt * \@tempdima/\@tempdimb\relax + %\typeout{ i#2=\the\@tempdimc, sin(#1)=\the\@tempdima}% + \pIIe@ellip@csqrt{\p@}{\@tempdimc}\@tempdimd + \ifdim\@tempdimb<\z@\relax\@tempdimd-\@tempdimd\fi + \pIIe@csedef{@ellipsin#2}{\strip@pt\dimexpr1pt * \@tempdimc/\@tempdimd\relax}% + \pIIe@csedef{@ellipcos#2}{\strip@pt\dimexpr1pt * \p@/\@tempdimd\relax}% + \fi\fi +} + +\newcommand*\pIIe@ellip@sincost[2]{% + %\typeout{ calc sin cos: angles (#1,#2), radii: (\the\@ovro,\the\@ovri)}% + \edef\@ellipratio{\strip@pt\dimexpr1pt * \@ovro/\@ovri\relax}% + \pIIe@ellip@sincost@{#1}{one}% + \pIIe@ellip@sincost@{#2}{two}% + %\typeout{ sincos(a=#1)=(\@ellipsinone,\@ellipcosone), sincos(a=#2)=(\@ellipsintwo,\@ellipcostwo), }% +} +\newcommand*\pIIe@omega[3]{% + \@tempdima\csname @ellipcos#3\endcsname\@ovro + \advance\@tempdima by #1\relax + \@tempdimb\csname @ellipsin#3\endcsname\@ovri + \advance\@tempdimb by #2\relax +} + +\newcommand*\pIIe@omegai[1]{% + \@tempdimc\csname @ellipsin#1\endcsname\@ovro + \@tempdimc-\@tempdimc + \@tempdimd\csname @ellipcos#1\endcsname\@ovri +} + +\newcommand*\pIIe@ellip@kappa{% + \@ovyy\@ellipsinone\p@ + \@ovxx\@ellipcosone\p@ + \@tempdima\@ellipcostwo\@ovyy + \@tempdima-\@tempdima + \advance\@tempdima by \@ellipsintwo\@ovxx + \@tempdimb\@ellipcostwo\@ovxx + \advance\@tempdimb by \@ellipsintwo\@ovyy + \ifdim\@tempdima=\z@\relax + \edef\@ellipkappa{0}% + \else + \dimen@\dimexpr1pt - \@tempdimb\relax + \dimen@\dimexpr1pt * \dimen@/\@tempdima\relax + \pIIe@ellip@csqrt{2\p@}{1.73205\dimen@}{\dimen@}% + \advance\dimen@ by -\p@ + \divide\dimen@ by 3% + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \edef\@ellipkappa{\strip@pt\dimen@}% + \fi + %\typeout{ calculated kappa: \@ellipkappa}% +} + +\newcommand*\pIIe@elliparc@[5]{% + %\typeout{elliparc: #1, center: (#2, #3), radius (\the\@ovro, \the\@ovri),angle (#4, #5)}% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \pIIe@ellip@sincost{#4}{#5}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@t[5]{% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \CalculateSin{#4}\CalculateCos{#4}% + \edef\@ellipsinone{\UseSin{#4}}% + \edef\@ellipcosone{\UseCos{#4}}% + \CalculateSin{#5}\CalculateCos{#5}% + \edef\@ellipsintwo{\UseSin{#5}}% + \edef\@ellipcostwo{\UseCos{#5}}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@draw[2]{% + \pIIe@ellip@kappa% + \pIIe@omega{#1}{#2}{one}% + %\typeout{ point one: (\the\@tempdima,\the\@tempdimb)}% + \@ellip@startto\@tempdima\@tempdimb + \pIIe@omegai{one}% + \advance\@tempdima by \@ellipkappa\@tempdimc + \advance\@tempdimb by \@ellipkappa\@tempdimd + \pIIe@add@nums\@tempdima\@tempdimb + %\typeout{ control one: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@omega{#1}{#2}{two}% + \pIIe@omegai{two}% + \@tempdimc\@ellipkappa\@tempdimc + \@tempdimd\@ellipkappa\@tempdimd + \@tempdimc-\@tempdimc + \@tempdimd-\@tempdimd + \advance\@tempdimc by \@tempdima + \advance\@tempdimd by \@tempdimb + \pIIe@add@nums\@tempdimc\@tempdimd + %\typeout{ control two: (\the\@tempdimc,\the\@tempdimd)}% + \pIIe@add@CP\@tempdima\@tempdimb + %\typeout{ point two: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@addtoGraph\pIIe@curveto@op +} +\newcommand*\pIIe@elliparc[7][0]{% + \@ovro #4\relax + \@ovri #5\relax + \iffalse%dim\@ovro=\@ovri + \pIIe@arc[#1]{#2}{#3}{#4}{#6}{#7} + \else + \ifdim \@ovro<\z@ \pIIe@badcircarg\else + \ifdim \@ovri<\z@ \pIIe@badcircarg\else + \@arclen #7\p@ \advance\@arclen -#6\p@ + \ifdim \@arclen<\z@ \def\@tempsign{-}\else\def\@tempsign{}\fi + \ifdim \@tempsign\@arclen>720\p@ + \PackageWarning {ellipse}{The arc angle is reduced to -720..720}% + \@whiledim \@tempsign\@arclen>720\p@ \do {\advance\@arclen-\@tempsign360\p@}% + \@tempdima #6\p@ \advance\@tempdima \@arclen + \edef\@angleend{\strip@pt\@tempdima}% + \pIIe@@elliparc{#1}{#2}{#3}{#6}{\@angleend}% + \else + \pIIe@@elliparc{#1}{#2}{#3}{#6}{#7}% + \fi + \fi + \fi + \fi +} +\newcommand*\pIIe@@elliparc[5]{% + \begingroup + \ifdim \@tempsign\@arclen>90\p@ + \divide\@arclen 2% + \@tempdima #4\p@\advance\@tempdima by \@arclen + \edef\@anglemid{\strip@pt\@tempdima}% + \def\@tempa{\pIIe@@elliparc{#1}{#2}{#3}{#4}}% + \expandafter\@tempa\expandafter{\@anglemid}% + \def\@tempa{\pIIe@@elliparc{2}{#2}{#3}}% + \expandafter\@tempa\expandafter{\@anglemid}{#5}% + \else + \pIIe@elliparc@{#1}{#2}{#3}{#4}{#5}% + \fi + \endgroup +}% + +\newcommand*\pIIeelliparc[7][0]{% + \@killglue + \pIIe@elliparc[#1]{#2\unitlength}{#3\unitlength}{#4\unitlength}{#5\unitlength}{#6}{#7}% + \ignorespaces% +} +\ifx\undefined\elliparc\else + \PackageWarning{ellipse}{\protect\elliparc\space is redefined}% +\fi +\let\elliparc\pIIeelliparc + +\newcommand*\pIIeearc + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\newcommand*\pIIe@earc@[3][0,360]{\pIIe@earc@@(#1){#2}{#3}} +\def\pIIe@earc@@(#1,#2)#3#4{% + \if@tempswa + \pIIe@moveto\z@\z@ + \pIIe@elliparc{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@closepath\pIIe@fillGraph + \else + \pIIe@elliparc[1]{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@strokeGraph + \fi} +\ifx\undefined\earc\else + \PackageWarning{ellipse}{\protect\earc\space is redefined}% +\fi +\let\earc\pIIeearc + +\newcommand*\pIIeellipse + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\let\ellipse\pIIeellipse + +\endinput +%% +%% End of file `ellipse.sty'. diff --git a/spec/v1.1.0-rc.1/embedded-plus-single-remote-controller.png b/spec/v1.1.0-rc.1/embedded-plus-single-remote-controller.png new file mode 100644 index 00000000..2e0f1803 Binary files /dev/null and b/spec/v1.1.0-rc.1/embedded-plus-single-remote-controller.png differ diff --git a/spec/v1.1.0-rc.1/embedded-plus-single-remote-controller.svg b/spec/v1.1.0-rc.1/embedded-plus-single-remote-controller.svg new file mode 100644 index 00000000..9fe2ce9c --- /dev/null +++ b/spec/v1.1.0-rc.1/embedded-plus-single-remote-controller.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spec/v1.1.0-rc.1/embedded-plus-two-remote-controllers.png b/spec/v1.1.0-rc.1/embedded-plus-two-remote-controllers.png new file mode 100644 index 00000000..b6dc04fc Binary files /dev/null and b/spec/v1.1.0-rc.1/embedded-plus-two-remote-controllers.png differ diff --git a/spec/v1.1.0-rc.1/embedded-plus-two-remote-controllers.svg b/spec/v1.1.0-rc.1/embedded-plus-two-remote-controllers.svg new file mode 100644 index 00000000..0f97ba38 --- /dev/null +++ b/spec/v1.1.0-rc.1/embedded-plus-two-remote-controllers.svg @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + + + Entities + + + + + + + \ No newline at end of file diff --git a/spec/v1.1.0-rc.1/embedded-plus-two-remote-ha-controllers.png b/spec/v1.1.0-rc.1/embedded-plus-two-remote-ha-controllers.png new file mode 100644 index 00000000..f663e9bf Binary files /dev/null and b/spec/v1.1.0-rc.1/embedded-plus-two-remote-ha-controllers.png differ diff --git a/spec/v1.1.0-rc.1/embedded-plus-two-remote-ha-controllers.svg b/spec/v1.1.0-rc.1/embedded-plus-two-remote-ha-controllers.svg new file mode 100644 index 00000000..710111fa --- /dev/null +++ b/spec/v1.1.0-rc.1/embedded-plus-two-remote-ha-controllers.svg @@ -0,0 +1,510 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + Master (Active) + + + + + + Slave (Standby) + + + + + + + \ No newline at end of file diff --git a/spec/v1.1.0-rc.1/error-report.png b/spec/v1.1.0-rc.1/error-report.png new file mode 100644 index 00000000..766cb77f Binary files /dev/null and b/spec/v1.1.0-rc.1/error-report.png differ diff --git a/spec/v1.1.0-rc.1/error-report.svg b/spec/v1.1.0-rc.1/error-report.svg new file mode 100644 index 00000000..a2709a72 --- /dev/null +++ b/spec/v1.1.0-rc.1/error-report.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StatusCode error_code_; // canonical error codestring error_message_;string binary_error_details_; // serialized google.rpc.Status + + + + + + + + + + + + + google.rpc.Status + + + + + + int32 error_code; // canonical error codestring message;repeated Any details; // P4Error + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + + + p4.Error + + + + + + p4.Error + + + + + + + + + + + + + + + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + grpc::Status + + + + + + + \ No newline at end of file diff --git a/spec/v1.1.0-rc.1/longbox.sty b/spec/v1.1.0-rc.1/longbox.sty new file mode 100644 index 00000000..cab48934 --- /dev/null +++ b/spec/v1.1.0-rc.1/longbox.sty @@ -0,0 +1,853 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longbox}[2015/12/01, Daan Leijen, Provides basic longbox that can break over pages] +\RequirePackage{options} + +\@ifclassloaded{beamer}{% + \newcommand\lb@savefootnotes{}% + \newcommand\lb@restorefootnotes{}% +}% +{\RequirePackage{footnote}% + \newcommand\lb@savefootnotes{\savenotes}% + \newcommand\lb@restorefootnotes{\spewnotes}% +} + + +% -------------------------------------------------------- +% Debugging +% -------------------------------------------------------- + +\newcommand*\lb@debug[1]{% + \ontoggle{lb@debug}{\typeout{longbox debug: #1}}% +} +\newcommand*\lb@typeout[1]{% + \ontoggle{lb@verbose}{\typeout{longbox: #1}}% +} +\newcommand*\lb@warncannotsplit{% + \PackageWarning{longbox}{Cannot split box; it seems you are using a non-splittable contents}% +} +\newcommand*\lb@warnbadsplit[1]{% + \PackageWarning{longbox}{Bad split (underful vbox by \the#1)}% +} + + +% -------------------------------------------------------- +% Utilities for LaTeX internals +% -------------------------------------------------------- + +% Suppress the indentation on the following paragraph +\providecommand\nofirstindent{\@afterindentfalse\@afterheading} + +% Suppress the paragraph skip on the following paragraph +\providecommand\nofirstparskip{\addvskip{-\parskip}} + +% In contrast to addvspace, addvskip is not suppressed in a minipage +\providecommand\addvskip[1]{% + \ifvmode + \ifdim\lastskip=\z@ + \vskip #1\relax + \else + \@tempskipb#1\relax\@xaddvskip + \fi + \else\@noitemerr\fi +} + + +% Skip to 0.3\baselineskip multiple taking prevdepth into account. +\newskip\lb@prevdepth +\newcommand\lb@skiptobaseline{% + \global\lb@prevdepth=-\@m\p@\relax + \ifvmode + \ifdim\lastskip=\z@\relax + \ifdim\prevdepth=-\@m\p@\else + \dimen@\prevdepth + % Calculate the modulus of the previous depth with 0.3|\baselineskip| in |\dimen@|. + \@tempcnta\prevdepth + \@tempskipa=0.3\baselineskip\relax + \@tempcntb=\@tempskipa\relax + \divide \@tempcnta by \@tempcntb + \dimen@\prevdepth + \advance\dimen@ -\@tempcnta\@tempskipa + % Skip back by that amount, and then skip by 0.3|\baselineskip|. + \vskip -\dimen@ + \vskip \@tempskipa\relax + \global\lb@prevdepth=\@tempskipa\relax + \fi + \fi + \fi +} + +% unvbox a box, and return a vbox with a given background color +% \unvcolorbox{}{} +\newcommand\unvcolorbox[2]{% + \ifoptionblank{#1}{\vbox{\unvbox#2}}{% + \lb@debug{vcolorbox: #1}% + \vbox{\offinterlineskip + \hbox to \z@{\vbox to \z@{\optioncolor{#1}\hrule\@width\wd#2\@height\ht#2\@depth\dp#2\vss}\hss}% + \unvbox#2% + }% + }% +} + +% create a vbox with a given background color +\newcommand\vcolorbox[2]{% + \eifblank{#1}{\vbox{#2}}{% + \setbox\z@=\vbox{#2}\relax + \unvcolorbox{#1}{\z@}% + }% +}% + +% -------------------------------------------------------- +% The following macros come from mdframed +% -------------------------------------------------------- + +% Determine the amount of free space left on the current page +\newlength\lb@freevspace +\newcommand*\lb@setfreevspace@page{% + \lb@debug{ determine free space}% + \bgroup\@nobreakfalse\addpenalty\z@\egroup% + \penalty\@M\relax\vskip 2\baselineskip\relax% + \penalty9999\relax\vskip -2\baselineskip\relax% + \penalty9999% + \ifdim\pagegoal=\maxdimen\relax% + \lb@freevspace=\vsize% + \else + \lb@freevspace=\dimexpr\pagegoal-\pagetotal-\parskip\relax% + \fi + \lb@debug{free space: \the\lb@freevspace, in page: \the\textheight, vsize=\the\vsize}% +} + +\newcommand*\lb@shiftdim[2]{% + %\letoption{#1}\lb@list + \expandafter\lb@setheadtail@#1,\relax + \eifblank{\lb@head}{}{\option@invoke{/longbox/@breakat-previous}{\lb@head}}% + #2\option{/longbox/@breakat-previous}% + \eifblank{\lb@tail}{}{\let#1\lb@tail}% push back tail +} +\def\lb@comma{,}% +\def\lb@setheadtail@#1,#2\relax{% + \def\lb@head{#1}% + \def\lb@tail{#2}% adds commas! +} + +\newcommand*\lb@setfreevspace{% + \eifblank{\lb@breakat}{\lb@setfreevspace@page}{% + \def\lb@eject{\par}%no eject + \lb@extrasplit=\z@\relax% + \lb@shiftdim{\lb@breakat}\lb@freevspace + \ifdim\lb@freevspace>\z@\else\lb@setfreevspace@page\fi + }% +} + + +% Suppress overfull-underfull vbox messages +\newcommand*\lb@ignorevbadness{% + \edef\lb@currentvbadness{\the\vbadness}% + \edef\lb@currentvfuzz{\the\vfuzz}% + \vbadness=\@M\relax% + \vfuzz=\maxdimen\relax% + \afterassignment\lb@restorevbadness +} +\newcommand*\lb@restorevbadness{% + \vbadness=\lb@currentvbadness\relax + \vfuzz=\lb@currentvfuzz\relax +} + + +% -------------------------------------------------------- +% The 'long vbox' (lvbox) environment collects long material +% into a long \vbox, instead of a \hbox like a lrbox in latex. +% The collected box can contain any box, minipage, lrbox, fbox etc, +% but not outer-par material like a figure. Footnotes can be +% dealt with useing lb@savefootnotes. +% +% The material is typeset in a \vbox according to a given width. +% inside the environment, the boolean 'inlvbox' is true. +% +% \begin{lvbox}{}{} +% -------------------------------------------------------- + +\newif\ifinlvbox +\newcommand\lvbox[4]{% + \setbox#1\vbox\bgroup + \begingroup + \inlvboxtrue + % reset defaults + \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\par\@@par + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + % set margin and linewidth + \leftmargin=#2\relax\rightmargin=#4\relax + \@totalleftmargin=\leftmargin% + %\leftskip=#2\relax\rightskip=#4\relax\@rightskip=#4\relax + \linewidth=#3\relax + % set primitive tex margins + \leftskip=\@totalleftmargin% + \rightskip=\rightmargin% + \@rightskip=\rightmargin% + \hsize=\dimexpr\@totalleftmargin+\linewidth+\rightmargin\relax + \columnwidth\hsize + \textwidth\hsize + \nofirstindent + %\nofirstparskip +} +\def\endlvbox{\endgroup\egroup} + + + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + + +\newsavebox\lb@headbox +\newsavebox\lb@savebox +\newsavebox\lb@mainbox + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@setbaseline[1]{% + %\typeout{ set baseline, \the\dp#1,\the\ht#1}% + \ifcase\lb@baseline% + \relax%bottom + \or%middle + \setbox#1=\vbox{\hbox{\lower \dimexpr(\dp#1 + \ht#1)/2 - \dp#1\relax\vbox{\unvbox#1}}}% + \or%top + \setbox#1=\vtop{\unvbox#1}% + \fi + %\typeout{ .new dim: \the\dp#1, \the\ht#1}% +} + + +\@ifundefined{define@key}{}% + {\define@key{longbox}{options}{\options{#1}\option{/longbox/adjust-options}}}% + +\newcommand*\lb@render@breakbox{% + %\typeout{render breakbox entry (in output routine), height=\the\bb@height}% + \bb@restorekeys{longbox}% + \lb@skiptop=\ifbb@isfirst\option{/longbox/skip-top}\else\option{/longbox/skip-break-top}\fi\relax + \lb@skipbottom=\ifbb@islast\option{/longbox/skip-bottom}\else\option{/longbox/skip-break-bottom}\fi\relax + \lb@skipbreaktop=\ifbb@isfirst 0pt\else\option{/longbox/skip-break-top}\fi + \lb@skipbreakbottom=\ifbb@islast 0pt\else\option{/longbox/skip-break-bottom}\fi + %\typeout{ render: skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom, break-top=\the\dimexpr\option{/longbox/skip-bottom}}% + \options{% + /longbox/@part-height=\bb@height + \lb@skipbreaktop + \lb@skipbreakbottom, + /longbox/@part-width=\option{/longbox/width} + \option{/longbox/skip-left} + \option{/longbox/skip-right},%\bb@width, + /longbox/@part-depth=0pt, + /longbox/@part-needtop=\ifbb@isfirst true\else false\fi, + /longbox/@part-needbottom=\ifbb@islast true\else false\fi, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-depth=\option{/longbox/@part-depth}, + }% + %\typeout{breakbox: width=\expandafter\the\option{/longbox/width}, \the\bb@width, \the\dimexpr\option{/longbox/@part-width}}% + \vbox{% + \kern -\lb@skipbreaktop% todo: move to breakbox? + \option{/longbox/render}% + \kern -\lb@skipbreakbottom + }% +} + +\newcommand*\lb@render@vbox[1]{% + \lb@debug{render vbox entry}% + \lb@restoreoptions + \lb@skiptop=\dimexpr\iftoggle{/longbox/@part-needtop}{\option{/longbox/skip-top}}{\option{/longbox/skip-break-top}}\relax + \lb@skipbottom=\dimexpr\iftoggle{/longbox/@part-needbottom}{\option{/longbox/skip-bottom}}{\option{/longbox/skip-break-bottom}}\relax + %\typeout{ skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom}% + % add top skip while maintaining the baseline. + \ifdim\lb@skiptop=\z@\relax\else + \setbox\z@=\vtop{\unvcopy#1}% + \dimen@=\ht\z@ + \setbox#1=\vbox{\offinterlineskip + \hrule width \z@ height \dimexpr\dimen@ + \lb@skiptop\relax depth -\dimen@ + \unvbox#1% + }% + \fi + % add bottom skip while maintaining the baseline. + \ifdim\lb@skipbottom=\z@\relax\else + \dimen@=\dp#1% + \setbox#1=\vbox{\offinterlineskip\unvbox#1\hrule width \z@ height -\dimen@ depth \dimexpr\dimen@ + \lb@skipbottom\relax}% + \fi + \lb@setbaseline{#1}% + \options{% + /longbox/@part-height=\dimexpr\ht#1 + \dp#1\relax, + /longbox/@part-width=\dimexpr\wd#1 + \option{/longbox/skip-left} + \option{/longbox/skip-right}\relax, + /longbox/@part-depth=\dp#1, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-depth=\option{/longbox/@part-depth} - \lb@skipbottom, + }% + %\typeout{ longbox: height=\the\dimexpr\option{/longbox/@content-box-height}, outer height=\the\dimexpr\option{/longbox/@part-height}\relax}% + % lower the box depending on vertical alignment + \ifcase\option{/longbox/vertical-align/@ord}\relax + \@tempdima\z@ + \or + %bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%middle + \@tempdima\dimexpr0.5\option{/longbox/@part-height} - \option{/longbox/@part-depth}\relax + \or%top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%text-bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%text-top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%super + \@tempdima=-0.9ex% + \or%sub + \@tempdima=0.7ex% + \else + \@tempdima\z@ + \fi + \advance\@tempdima by -\option{/longbox/raise}% + \option@invoke{/longbox/@lower}{\@tempdima}% + \noindent\hbox{\lower \@tempdima\vbox{\offinterlineskip + \hbox to \z@{% + \vbox to \z@{% + \hbox{\lower \option{/longbox/@part-height}\vbox{\offinterlineskip{\option{/longbox/render}}}}% + \vss}% + \hss + }% + \hbox{% + \ifdim\option{/longbox/skip-left}=\z@\else\hskip\option{/longbox/skip-left}\fi + \box#1% + \ifdim\option{/longbox/skip-right}=\z@\else\hskip\option{/longbox/skip-right}\fi + %$\box#1% + }% + }}% +} + +\newcommand*\lb@single@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} +\newcommand*\lb@first@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@middle@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@last@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand*\lb@env@start{% + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore +} + +\newcount\lb@usevbox +\newlength\lb@width +\newlength\lb@height +\newlength\lb@skiptop +\newlength\lb@skipright +\newlength\lb@skipbottom +\newlength\lb@skipleft +\newlength\lb@skipbreaktop +\newlength\lb@skipbreakbottom +\newlength\lb@outerwidth +\newlength\lb@extrasplit +\newcount\lb@textalign +\newcount\lb@baseline +\newtoggle{lb@baselineskip}% +\newtoggle{lb@breakable}% +\newtoggle{lb@debug}% +\newtoggle{lb@verbose}% +\def\lb@breakat{}% +\def\lb@halign{}% +\def\lb@eject{}% +\def\lb@insertafter{} +\def\lb@insertbefore{} + +\newcommand*\lb@peekoptions[1]{% + % process options inside a group and just set necessary parameters + % this way, nested boxes don't influence each other's parameters + \begingroup + \options{#1}% + \option{/longbox/adjust-options}% + \protected@edef\lb@temp{\endgroup + \lb@width=\the\dimexpr\option{/longbox/width}\relax + \lb@height=\the\dimexpr\option{/longbox/height}\relax + \lb@textalign=\the\numexpr\option{/longbox/text-align/@ord}\relax + \lb@baseline=\the\numexpr\option{/longbox/baseline/@ord}\relax + \lb@skiptop=\the\dimexpr\option{/longbox/skip-top}\relax + \lb@skipright=\the\dimexpr\option{/longbox/skip-right}\relax + \lb@skipbottom=\the\dimexpr\option{/longbox/skip-bottom}\relax + \lb@skipleft=\the\dimexpr\option{/longbox/skip-left}\relax + \lb@skipbreaktop=\the\dimexpr\option{/longbox/skip-break-top}\relax + \lb@skipbreakbottom=\the\dimexpr\option{/longbox/skip-break-bottom}\relax + \lb@usevbox=\iftoggle{/longbox/use-vbox}{1}{0}\relax + \lb@outerwidth=\the\dimexpr\option{/longbox/outer-width}\relax + \lb@extrasplit=\the\dimexpr\option{/longbox/split-minimum}\relax + \def\noexpand\lb@insertafter{\option{/longbox/insert-after}}% + \def\noexpand\lb@insertbefore{\option{/longbox/insert-before}}% + \def\noexpand\lb@breakat{\option{/longbox/breakat}}% + \def\noexpand\lb@halign{\option{/longbox/height-align}}% + \def\noexpand\lb@eject{\option{/longbox/eject}}% + \noexpand\csname toggle\iftoggle{/longbox/baseline-skip}{true}{false}\endcsname{lb@baselineskip}% + \noexpand\csname toggle\iftoggle{/longbox/breakable}{true}{false}\endcsname{lb@breakable}% + \noexpand\csname toggle\iftoggle{/longbox/debug}{true}{false}\endcsname{lb@debug}% + \noexpand\csname toggle\iftoggle{/longbox/verbose}{true}{false}\endcsname{lb@verbose}% + }% + \lb@temp +} + +\newenvironment{longbox@env}[2]{% + % save options + \lb@peekoptions{#1,#2}% + % + \ifnum\lb@usevbox=0\relax + \lb@debug{start breakbox}% + \let\bb@render\lb@render@breakbox + \bb@savekeys{longbox}{options={#1,#2,outer-width=\the\lb@outerwidth}}% + \iftoggle{lb@baselineskip}{\typeout{**insert bskip}}{\typeout{**suppress bskip}\vskip 1pt}% + \begin{breakbox}% + \ifdim\lb@skiptop=\z@\relax\else\vspace{\lb@skiptop}\fi% + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \begin{bb@margins}{\lb@skipleft}{\dimen@}% + \else + \lb@debug{start vbox}% + \def\lb@restoreoptions{\options{#1,#2}\option{/longbox/adjust-options}}% + \lb@savefootnotes + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \lb@debug{ width=\the\lb@width, linewidth=\the\linewidth, skipleft=\the\lb@skipleft, right=\the\lb@skipright, total right=\the\dimen@}% + \iftoggle{lb@baselineskip}{\lb@skiptobaseline}{\lb@prevdepth=-\@m pt}% + \lvbox{\lb@mainbox}{0pt}{\lb@width}{0pt}%{\lb@skipleft}{\lb@width}{\lb@skipright}% + \prevdepth=\lb@prevdepth + \fi + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore + \begingroup +}{% + \par\unskip + \endgroup + \lb@insertafter + %\ifdim\lb@skipbottom=\z@\relax\else\vskip\lb@skipbottom\fi% + \ifnum\lb@usevbox=0\relax + \end{bb@margins}% + \ifdim\lb@skipbottom=\z@\relax\else\hrule width \z@ height \lb@skipbottom\fi%\vspace{\lb@skipbottom}\fi% + \iftoggle{lb@baselineskip}{}{\vskip 1sp}% + \end{breakbox}% + \lb@debug{end breakbox}% + \else + \ontoggle{lb@baselineskip}{\lb@skiptobaseline}% + \endlvbox% + \lb@debug{initial lvbox: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@processbox + %\setbox\lb@mainbox=\hbox{\lower \lb@skipbottom\vbox{\offinterlineskip\unvbox\lb@mainbox}}% + \lb@restorefootnotes + \lb@debug{end vbox}% + \fi +} + +\newcommand\longbox@cmd[3]{% + \begingroup + %\options{/options/collectunknown,/longbox/scoped,#2}% set scoped options first + %\option{/longbox/scoped/@adjust-options}% + \lb@peekoptions{#1,#2}% + \leavevmode + %\setbox\lb@mainbox=\hbox{% + % \begingroup + % #3% + % \endgroup + %}% + \setbox\lb@mainbox=\hbox{% + \begingroup + \ifcase\lb@textalign\relax + %default=left + \or%left + \or\hss%center + \or\hss%right + \else%justify + \fi + \lb@insertbefore + #3% + \lb@insertafter + \ifnum\lb@textalign<3\relax\hss\fi% default,left,center + \endgroup + }% + \options{#1,#2}% + \ifdim\option{/longbox/width}=-1sp\relax + \options{/longbox/width=\wd\lb@mainbox}%set to natural width + \fi + \option{/longbox/adjust-options}% + % make it a vbox + \setbox\lb@mainbox=\vbox{\offinterlineskip% + \hbox to \option{/longbox/width}{% + \unhbox\lb@mainbox + }% + }% + \def\lb@restoreoptions{}% + \letoption{/longbox/height-align}\lb@halign + \lb@height=\option{/longbox/height}\relax + \lb@baseline=\option{/longbox/baseline/@ord}\relax + \lb@processbox + \endgroup +} + +\newcommand\lb@processbox{% + \ifdim\lb@height<0pt\relax + \lb@setbaseline{\lb@mainbox}% + \else + \lb@restrictheight + \fi + \lb@typesetbox +} + +\newcommand\lb@typesetbox{% + \ifinlvbox + \iftoggle{lb@breakable}{% + %\lb@debug{disable breakable due to nesting of long-boxes}% + \togglefalse{lb@breakable}% + }{}% + \fi + \ifhmode\lb@single@{\lb@mainbox}\else\lb@typeset\fi +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@restrictheight{% + \lb@typeout{restrict height to \the\lb@height}% + \lb@splitheight=\lb@height% + %lb@debug{before height split: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + %split failed.. do nothing + \lb@debug{could not restrict height}% + \else + % store splitted off content in the mainbox (and discard the rest) + \setbox\lb@mainbox\vbox{\unvbox\lb@headbox}% + \lb@debug{restricted height to \the\ht\lb@mainbox}% + \fi + % set baseline + \lb@setbaseline{\lb@mainbox}% + % height align + %\letoption{/longbox/height-align}\lb@halign + \eifstrequal{\lb@halign}{bottom}% + {\setbox\lb@mainbox=\vbox{\hbox{\vbox to \lb@splitheight{\vss\unvbox\lb@mainbox}}}}% + {\eifstrequal{\lb@halign}{middle}% + {\dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\hbox{% + \lower \dimexpr0.5\dimen@ + \dp\lb@mainbox\relax% + \vbox to \lb@splitheight{\vss\unvbox\lb@mainbox\vss}}}}% + {% default is top + \dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\vtop to \lb@splitheight{\box\lb@mainbox\vss}}% + }% + }% +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newlength\lb@neededvspace +\newcommand\lb@typeset[1][0pt]{% + \iftoggle{lb@breakable}{% + \lb@setfreevspace + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skiptop+\lb@skipbottom\relax}% + \lb@debug{needed: \the\lb@neededvspace, available: \the\lb@freevspace}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@single@{\lb@mainbox}% + \else + \lb@typeout{longbox needs splitting}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skiptop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \ifdim\dimexpr\lb@freevspace + #1\relax<\textheight\relax % test if we were at a fresh page.. (and prevent infinite recursion) + \lb@debug{failed to split the box, inserting a page break}% + \hrule \@height\z@ \@width\hsize + \lb@eject% + \lb@typeset[\textheight]% try again, but pass \textheight to guard against infinite recursion + \else + % on a fresh page we should not fail anymore.. just output as is.. + % lb@warncannotsplit + \lb@single@{\lb@mainbox}% + \fi + \else + % first part success + \lb@typeout{first part splitted}% + \lb@first@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest + \fi + \fi + }{%\else + \lb@debug{unbreakable box}% + \lb@single@{\lb@mainbox}% always directly output an unbreakable box + }% +} + +\newcommand\lb@typesetrest{% + \lb@setfreevspace% + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skipbottom+\lb@skipbreaktop\relax}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@typeout{output last part of box}% + \lb@last@{\lb@mainbox}% + \else + \lb@debug{split box further}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skipbreaktop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \lb@typeout{failed to split box!}% + \lb@last@{\lb@mainbox}% + \else + % middle part success + \lb@typeout{output middle part of box}% + \lb@middle@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest% continue the iteration... + \fi + \fi +} + +% -------------------------------------------------------- +% Split a long vbox over multiple pages. +% This code is based on similar code in the mdframed package +% -------------------------------------------------------- + +\newlength\lb@splitheight +\newlength\lb@insurance % tiny extra space to ensure our box will really fit +\setlength\lb@insurance{1pt} + +% expects split target height in lb@splitheight, and splits off the start of lb@mainbox to lb@headbox +\newcommand\lb@splitbox{% + \ifdim\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax>\lb@splitheight\relax + % the main box is larger than our target split height.. + \ifdim\lb@extrasplit>\lb@splitheight\relax + % not enough space to bother + \lb@typeout{not enough space on page for a split}% + \setbox\lb@headbox=\vbox{}% empty head + \else + % try a split; lower the split height a bit so we are sure to fit + \advance\lb@splitheight -\lb@insurance\relax + \lb@debug{split: \the\lb@splitheight, from \the\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax}% + \setbox\lb@savebox=\vbox{\unvcopy\lb@mainbox}% save original + \lb@trysplit{\lb@splitheight}% + \ifdim\dimexpr\ht\lb@headbox + \dp\lb@headbox>\lb@splitheight\relax + % too big, bad split. Try other splits.. iterate N times with 1 or 5pt less before giving up + \dimen@=\lb@splitheight\relax + \@tempcnta=\z@\relax + \loop + \ifdim\dimexpr\ht\lb@headbox+\dp\lb@headbox\relax>\lb@splitheight\relax + \ifnum\@tempcnta<50% + \advance\dimen@ by -\p@\relax% try a slightly smaller height.. + \else + \advance\dimen@ by -5\p@\relax% try larger increase after 50pt.. + \fi + \advance\@tempcnta by \@ne\relax + \lb@ignorevbadness + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \lb@trysplit{\dimen@}% + \ifdim\lb@extrasplit<\dimen@\relax\else\lb@splitstop\fi % don't try to split too small + \ifnum\@tempcnta<100\relax\else\lb@splitstop\fi % and not more than N attempts + \repeat% + \ifnum\@tempcnta<100\relax + \dimen@=\dimexpr\lb@splitheight - \ht\lb@headbox - \dp\lb@headbox\relax + \ifdim\dimen@>\option{/longbox/split-badness}\relax + \lb@warnbadsplit{\dimen@}% + \fi + \fi + \fi + \fi + \else + % mainbox fits in our target lb@splitheight + \setbox\lb@headbox=\vbox{\unvbox\lb@mainbox}% + \setbox\lb@mainbox=\vbox{}% + \fi +} + +\newcommand\lb@splitstop{% + \lb@typeout{cannot find a good split}% + \let\iterate\relax + \lb@warncannotsplit + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \setbox\lb@headbox=\vbox{}% empty head + \@tempcnta=\@M\relax +} + +\newcommand\lb@trysplit[1]{% try to split at given height + \lb@typeout{try to split at: \the\dimexpr #1\relax}% + \lb@ignorevbadness + \setbox\lb@headbox=\vsplit\lb@mainbox to #1\relax% + \setbox\lb@headbox=\vbox{\unvbox\lb@headbox}% + \setbox\lb@mainbox=\vbox{\unvbox\lb@mainbox}% +} + +% -------------------------------------------------------- +% The longbox environment uses options to set its options +% -------------------------------------------------------- + + +% keys and styles that can be set once globally +\options{% + /longbox/.new family, +}% + +\options{/longbox,% + % computed + @part-needtop/.new toggle, + @part-needbottom/.new toggle, + @part-height/.new length, + @part-width/.new length, + @part-depth/.new length, + @content-box-height/.new length, + @content-box-width/.new length, + @content-box-depth/.new length, + @breakat-previous/.new length, + @lower/.new length, + % + debug/.new toggle, + verbose/.new toggle, + render/.new value =\lb@render@fbox, + adjust-options/.new value = {\longbox@adjustoptions}, + eject/.new value = {\protect\vfill\protect\eject}, + use-vbox/.new toggle = true, + split-minimum/.new length = {1.5\baselineskip}, + split-badness/.new length = \baselineskip, + % + height-align/.new choice= {top,middle,bottom}, + baseline/.new choice = {bottom,middle,top}, + text-align/.new choice = {default,left,center,right,justify}, + vertical-align/.new choice = {baseline,bottom,middle,top,text-bottom,text-top,super,sub}, + raise/.new length = {0pt}, + baseline-skip/.new toggle =true, + % + height/.new length = -1sp, + width/.new length = -1sp, + outer-height/.new length= -1sp, + outer-width/.new length = -1sp, + insert-before/.new value= {}, + insert-after/.new value = {}, + breakat/.new value = {}, + breakable/.new toggle = false, + skip/.new style = {skip-top=#1,skip-right=#1,skip-bottom=#1,skip-left=#1}, + skip-top/.new length, + skip-right/.new length, + skip-bottom/.new length, + skip-left/.new length, + skip-break-bottom/.new length, + skip-break-top/.new length, +} + +\newcommand\longbox@adjustoptions{% + %\typeout{ standard longbox adjustoptions}% + \lb@debug{ current width=\the\dimexpr\option{/longbox/width}, outer=\the\dimexpr\option{/longbox/outer-width}, linewidth=\the\linewidth}% + \ontoggle{/longbox/debug}{\option@invoke{/longbox/verbose}{true}}% + % adjust height + \ifdim\option{/longbox/height}=-1sp\relax + \ifdim\option{/longbox/outer-height}=-1sp\else + \option@invoke{/longbox/height}% + {\option{/longbox/outer-height}-\option{/longbox/skip-top}-\option{/longbox/skip-bottom}}% + \fi + \fi + % set width + \ifdim\option{/longbox/width}=-1sp\relax + \ifdim\option{/longbox/outer-width}=-1sp\relax + \option@invoke{/longbox/outer-width}{\linewidth}% + \fi + \dimen@=\dimexpr\option{/longbox/outer-width}-\option{/longbox/skip-left}-\option{/longbox/skip-right}\relax + \ifdim\dimen@<\z@\relax\dimen@=\z@\fi + \option@invoke{/longbox/width}{\dimen@}% + \fi + % use a breakbox whenever we are in external vertical mode and not width or height restricted. + \iftoggle{/longbox/use-vbox}{}{% + \ifinner\toggletrue{/longbox/use-vbox}\else + \ifhmode\toggletrue{/longbox/use-vbox}\else + \ifdim\option{/longbox/height}>-1sp\toggletrue{/longbox/use-vbox}\else + \iftoggle{/longbox/breakable}{}{\toggletrue{/longbox/use-vbox}}% + \ifoptionblank{/longbox/breakat}{}{\toggletrue{/longbox/use-vbox}}% + \fi\fi\fi + }% +} + +\newenvironment{longbox}[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \begin{longbox@env}{/longbox}{#1}% +}{\end{longbox@env}} + +\newcommand\lbox[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \longbox@cmd{/longbox}{#1}% +} + +\newcommand*\lb@render@fbox{% + %\typeout{render defaultbox: bgcolor=\bb@bgcolor, needtop=\iftoggle{/longbox/@part-needtop}{true}{false}}% + \@ovdx=\dimexpr\option{/longbox/@part-width} - 2\fboxrule\relax% + \@ovdy=\dimexpr\option{/longbox/@part-height}\relax% + \iftoggle{/longbox/@part-needbottom}% + {\@tempdima=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdima=\dimexpr\fboxrule + \bb@stickout\relax + \advance\bb@height by \@tempdima + \advance\@ovdy by \@tempdima}% + \iftoggle{/longbox/@part-needtop}% + {\@tempdimb=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdimb=\dimexpr\bb@stickout\relax + \advance\bb@height by \@tempdimb + \advance\@ovdy by \@tempdimb}% + % + \hbox{\lower \@tempdima\vbox{% + \vskip -\@tempdimb + \ontoggle{/longbox/@part-needtop}{\lb@debug{toprule wd=\expandafter\the\option{/longbox/width}}\hrule width \option{/longbox/@part-width} height \fboxrule}% + \hbox{% + \vrule width \fboxrule height \@ovdy% + \ifx\bb@bgcolor\@empty + \vrule width \@ovdx height \z@\relax + \else + {\color{\bb@bgcolor}\vrule width \@ovdx height \@ovdy}% + \fi + \vrule width \fboxrule height \@ovdy% + }% + \ontoggle{/longbox/@part-needbottom}{\hrule width \option{/longbox/@part-width} height \fboxrule}% + }}% +} \ No newline at end of file diff --git a/spec/v1.1.0-rc.1/longfbox.sty b/spec/v1.1.0-rc.1/longfbox.sty new file mode 100644 index 00000000..0df01331 --- /dev/null +++ b/spec/v1.1.0-rc.1/longfbox.sty @@ -0,0 +1,1344 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longfbox}[2015/12/01, Daan Leijen, Provides long fbox that can break over pages] + +\RequirePackage{options} +\RequirePackage{longbox} +\RequirePackage{pict2e} +\RequirePackage{ellipse} + +% -------------------------------------------------------- +% Dimension calulations +% -------------------------------------------------------- + +% dimmin/dimmax return minimum or maximum dimension +\providecommand\dim@min[2]{\ifdim#1>#2#2\else #1\fi} +\providecommand\dim@max[2]{\ifdim#1>#2#1\else #2\fi} + +\newcommand*\option@dimmin[2]{\dim@min{\option{#1}}{\option{#2}}} +\newcommand*\option@dimmax[2]{\dim@max{\option{#1}}{\option{#2}}} + + +% -------------------------------------------------------- +% Add a new 'sides' option type +% -------------------------------------------------------- + +\options{ + /handlers/new sides/.new handler = []{ + \ifblank{#2}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#1-top={##1}, #1-right={##2}, #1-bottom={##3}, #1-left={##4}}}}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#2}}}% + \optionsalso{ + #1/.new cmdx = {##1,##2,##3,##4,##5\relax}{,,,,\relax}{% + \ifblank{##2##3##4}{\option{#1/@cmd@sides}{##1}{##1}{##1}{##1}}% + {\ifblank{##3##4}{\option{#1/@cmd@sides}{##1}{##2}{##1}{##2}}% + {\ifblank{##4}{\option{#1/@cmd@sides}{##1}{##2}{##3}{##2}}% + {\option{#1/@cmd@sides}{##1}{##2}{##3}{##4}}% + }% + }% + }, + #1/.type = sides, + }% + },% +} + +\newcommand*\optionlengthlimit[3]{% len, min, max + \letoption{#1}\opt@temp + \ifdim\opt@temp<\dimexpr#2\relax + \option@invoke{#1}{#2}% + \else\ifdim\opt@temp>\dimexpr#3\relax + \option@invoke{#1}{#3}% + \fi\fi +} + +\newcommand*\optionradiuslimit[4]{% r1, r2, min, max + \letoption{#1}\opt@tempa + \letoption{#2}\opt@tempb + \ifdim\opt@tempa<\dimexpr#3\relax\option@invoke{#1}{#3}\fi + \ifdim\opt@tempb<\dimexpr#3\relax\option@invoke{#2}{#3}\fi + \ifdim\dimexpr\opt@tempa + \opt@tempb\relax=\z@\relax\else + \ifdim\dimexpr\opt@tempa+\opt@tempb\relax>\dimexpr#4\relax + \edef\opt@perc{\the\numexpr(\number\dimexpr#4\relax)/% + (\number\dimexpr(\opt@tempa+\opt@tempb)/100\relax)}% + %\typeout{scale:\the\opt@tempa,\the\opt@tempb, by \opt@perc percent to make \the\dimexpr#4\relax}% + \edef\opt@temp{\dimexpr\opt@perc\dimexpr\the\opt@tempa\relax / 100\relax}% + \option@einvoke{#1}{\opt@temp}% + \option@einvoke{#2}{\dimexpr#4 - \opt@temp\relax}% + %\typeout{ scaled to: \the\opt@temp,\the\dimexpr#4 - \opt@temp\relax}% + \fi + \fi +} + + +% \begin{macro}{\trig@atantan} +% \marg{a}\marg{b}\marg{$\alpha$}{dimen$_\mathit{reg}$}\\ +% Assigns $\atan_2(\frac{\sin(\alpha)}{b},\frac{\cos(\alpha)}{a})$ to dimension register \textit{dimen$_\mathit{reg}$}, +% where $a$ and $b$ are dimensions. +% Returns $\alpha$ when $a = b$, or when $a=0$ or $b=0$. +% \begin{macrocode} +\newcommand*\trig@atantan[4]{% + %\typeout{ atantan:(\the#1,\the#2,\the#3, #4)}% + \@tempdima\dimexpr#1\relax + \@tempdimb\dimexpr#2\relax +% \end{macrocode} +% If $a = b$, we have a circle and the result is $\alpha$. +% \begin{macrocode} + \ifdim\@tempdima=\@tempdimb + #4\dimexpr#3\relax + \else\ifdim\@tempdima=\z@ + #4\dimexpr#3\relax + \else\ifdim\@tempdimb=\z@ + #4\dimexpr#3\relax + \else + \edef\trig@temp{\strip@pt\dimexpr#3\relax}% + \CalculateSin{\trig@temp}\CalculateCos{\trig@temp}% + \@tempdimc\dimexpr1\p@ * \dimexpr\UseSin{\trig@temp}\p@\relax/\@tempdimb\relax + \@tempdimd\dimexpr1\p@ * \dimexpr\UseCos{\trig@temp}\p@\relax/\@tempdima\relax + \pIIe@atantwo{\@tempdimc}{\@tempdimd}\dimen@ + \ifdim\dimen@<\z@ + \ifdim\dimexpr#3\relax<\z@\else\advance\dimen@360\p@\fi + \fi + \@tempdima\dimexpr#3 - \dimen@\relax + \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi + \ifdim\@tempdima<360\p@\else\advance\dimen@360\p@\fi + %\typeout{atan: \the\dimexpr#3\relax versus. \the\dimen@ }% + #4\dimen@ + \fi\fi\fi +} +% \end{macrocode} +% \end{macro} + +% rough approximation of the perimeter; +% if |radius-x == radius-y| = 0 (a circle), the approximation is precise. +% otherwise, works best when |angle2-angle1| <= 45 and gets worse from there on. +\newcommand*\ellip@letarcperimeter[5]{% 'radius-x', 'radius-y', 'angle-1', 'angle-2', '\result' + \@tempdima\dimexpr#3\relax + \@tempdimb\dimexpr#4\relax + \@tempdimc\dimexpr\@tempdima - \@tempdimb\relax + \ifdim\@tempdimc<\z@\@tempdimc-\@tempdimc\fi + \ifdim#1=#2\relax% circle? + \edef\@tempa{\strip@pt\@tempdimc}% angle difference delta as factor + \dimen@\@tempa\dimexpr#1\relax% r*delta + \dimen@0.017453\dimen@% (2*pi/360) * r * delta = 2*pi*r * (delta/360) + \else% ellipse: take the distance between the points on the ellipse, works pretty good if delta <= 45, and ok'ish for delta <= 90 + \@ovro\dimexpr#1\relax + \@ovri\dimexpr#2\relax + \edef\fbox@tempa{\strip@pt\@tempdima}% + \edef\fbox@tempb{\strip@pt\@tempdimb}% + \pIIe@ellip@sincost{\fbox@tempa}{\fbox@tempb}% + \@tempdima\@ellipcosone\@ovro + \@tempdimb\@ellipsinone\@ovri + \@tempdimc\@ellipcostwo\@ovro + \@tempdimd\@ellipsintwo\@ovri + \advance\@tempdimc by -\@tempdima% + \advance\@tempdimd by -\@tempdimb% + \pIIe@ellip@csqrt{\@tempdimc}{\@tempdimd}{\dimen@}% + %\typeout{ distance: \the\dimen@, from (x,y)=(\the\@tempdimc,\the\@tempdimd), radii=(\the#1,\the#2), angles=(\the#3,\the#4)}% + \fi + \edef#5{\the\dimen@}% +} + + +% ------------------------------------------------------------------------------ +% Borders using the picture environment +% ------------------------------------------------------------------------------ + +\newcommand*\fbox@border@pict{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \begingroup + \hbox{% + \unitlength\p@ + \begin{picture}(0,0)(0,\optionunit{/fbox/@border-box-height})% bottom-left is origin + % markers + \ontoggle{/fbox/show-markers}{% + \linethickness{\option{/fbox/marker-width}}% + \optioncolor{/fbox/marker-color}% + \fbox@rect{0pt}{0pt}{\option{/fbox/@border-box-width}}{\option{/fbox/@border-box-height}}% + \fbox@rect{\option{/fbox/border-left-width}}{\option{/fbox/border-\fbox@bottom-width}}% + {\option{/fbox/@border-box-width}-\option{/fbox/border-right-width}}% + {\option{/fbox/@border-box-height}-\option{/fbox/border-\fbox@top-width}}%S + }% + %compute corner coordinates + \fbox@border@calccorners + %put down the background color + \fbox@border@colorbackground + \option{/fbox/picture-insert-before}% + %put down the sides + \fbox@border@side{3}{-2}{0}%top + \fbox@border@side{5}{-4}{3}%left + \fbox@border@side{-6}{7}{2}%bottom + \fbox@border@side{-8}{1}{1}%right + \end{picture}% + }% + \endgroup + \fi +} + +\newcommand*\fbox@border@pict@after{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \letoption{/fbox/picture-insert-after}\fbox@insertafter + \eifblank{\fbox@insertafter}{}{% + \begingroup + \hbox{% + \begin{picture}(0,0)(0,0)% bottom-left is origin + \fbox@insertafter + \end{picture}% + }% + \endgroup + }% + \fi +} + +\newcommand*\fbox@border@side[3]{% + \fbox@setoct@angles{#1}% + \edef\fbox@style{\option{/fbox/border-\fbox@side-style}}% + \optioncolor{/fbox/border-\fbox@side-color}% + \option{/fbox/picture-side-insert-before}% + \ifcsdef{fbox@border@pict@\fbox@style}% + {\csuse{fbox@border@pict@\fbox@style}{#1}{#2}{#3}}% + {\PackageWarning{longfbox}{Unknown style "\fbox@style". Using "solid" instead.}% + \fbox@border@pict@solid{#1}{#2}{#3}}% + \option{/fbox/picture-side-insert-after}% +} + +% ------------------------------------------------------------------------------ +% Define standard border styles for the picture environment +% +% a style has the form \fbox@border@pict@ + + + + + + +
+
+
+
P4Runtime Specification
+
version 1.1.0
+
+
+
The P4.org API Working Group
+
2020-02-03
+
+

Abstract. P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.

+ + +

1. Introduction and Scope

+

This document is published by the P4.org API Working Group, which was +chartered [16] to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called P4Runtime. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +https://github.com/p4lang/p4runtime/tree/v1.1.0/proto. +

1.1. P4 Language Version Applicability

+

P4Runtime is designed to be implemented in conjunction with the P416 language +version or later. P414 programs should be translated into P416 to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P416 1.0, but were introduced in P416 1.1.0 [28]. For +this version of P4Runtime, we recommend using P416 1.2.0 [1]. +

1.2. In Scope

+

This specification document defines the semantics of P4Runtime messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime: +

+
    +
  • Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA) [18] externs (e.g. Counters, Meters, Action +Profiles, ). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0. +
  • +
  • Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism. +
  • +
  • Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy. +
  • +
  • Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities. +
  • +
  • Packet I/O to enable streaming packets to & from the control plane. +
  • +
  • Batching support, with different atomicity guarantees. +
  • +
  • In-the-field device-reconfiguration with a new P4 data plane. +
+ +

The following are in the scope of this specification document: +

+
    +
  • Rationale for the P4Runtime design. +
  • +
  • Reference architecture and use-cases for deploying a P4Runtime service. +
  • +
  • Detailed description of the API semantics. +
  • +
  • Requirements for conformant implementations of the API. +
+

1.3. Not In Scope

+

The following are not in scope of P4Runtime: +

+
    +
  • Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +[34]. An open source implementation of these APIs is also in progress +as part of the Stratum project [36]. +
  • +
  • Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures. +
+ +

The following are not in scope of this specification document: +

+
    +
  • Description of the P4 programming language; it is assumed that the reader is +already familiar with P416 [1]. +
  • +
  • Descriptions of gRPC and Protobuf files in general. +
  • +
  • Controller role definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme. +
+

2. Terms and Definitions

+
+
arbitration
+
Refers to the process through which P4Runtime ensures that at any given +time, there is a single master (i.e. a client with write access) for a given +role. Also referred to as “master-slave arbitration”. +
+
client
+
The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +
+
COS
+
Class of Service. +
+
device
+
Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +
+
entity
+
An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +
+
gRPC
+
gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +[9]. +
+
HA
+
High-Availability. Refers to a redundancy architecture. +
+
Instrumentation
+
The part of the P4Runtime server which implements the calls to the device or +target native “SDK” or backend. +
+
IPC
+
Inter-Process Communication. +
+
P4 Blob
+
A more colloquial term for P4 Device Config (Blob = Binary Large Object). +
+
P4 Device Config
+
The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its “program.” +
+
P4Info
+
Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +
+
P4RT
+
Abbreviation for P4Runtime. +
+
Protobuf (Protocol Buffers)
+
The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See [20]. +
+
PSA
+
Portable Switch Architecture [18]; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +
+
RPC
+
Remote Procedure Call. +
+
RTT
+
Round-trip time. +
+
SDN
+
Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network controller. +
+
SDN port
+
A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +
+
server
+
The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +
+
stream
+
Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (StreamChannel), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and master-slave arbitration, among other +things. +
+
switch config
+
Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +
+
target
+
The hardware or software entity which “executes” the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with “device”. +
+
URI
+
Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.

3. Reference Architecture

+

Figure 1 represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. A multi-master protocol allows more than +one controller to participate, and a role-based arbitration scheme ensures only +one controller has write access to each read/write entity, or the pipeline +config itself. Any controller may perform read access to any entity or the +pipeline config. Later sections describe this in detail. For the sake of +brevity, the term controller may refer to one or more controllers. +

+

The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +[14]. It may be compiled via protoc the Protobuf compiler +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server. +

+

Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository [15]. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, e.g. via callbacks, thus reducing the burden of implementing +P4Runtime. +

+

The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard. +

+

The controller can also set the ForwardingPipelineConfig, which amounts to +installing and running the compiled P4 program output, which is included in the +p4_device_config Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +ForwardingPipelineConfig to retrieve the device config and the P4Info. +

+
+

reference-architecture +

+
+ +
Figure 1. P4Runtime Reference Architecture.

3.1. Idealized Workflow

+

In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the ForwardingPipelineConfig +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a SetForwardingPipelineConfig +RPC. Metadata in the P4Info describes both the overall program itself +(PkgInfo) as well as all entity instances derived from the P4 program +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise “handle” used in API +calls. +

+

In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible. +

+

In some use cases, it is expected that a controller will store a +collection of multiple P4 “packages”, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the ForwardingPipelineConfig from the target via the +GetForwardingPipelineRequest RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state. +

3.2. P4 as a Behavioral Description Language

+

P4 can be considered a behavioral description of a switching device which may or +may not execute “P4” natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a SetForwardingPipelineRequest to +change its pipeline “program”, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device. +

+

While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API. +

+

In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the PkgInfo +message as well as the embedded doc fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections. +

3.3. Alternative Workflows

+

Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary. +

3.3.1. P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config

+

In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +p4_device_config. The device's configuration might be derived via some other +means to implement the P4 source code's intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane. +

3.3.2. No P4 Source Available, P4Info Available

+

In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are: +

+
    +
  1. +

    The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security. +

  2. +
  3. +

    The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info. +

+ +

As discussed in Section 3.2, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, e.g. documentation. +

3.3.3. Partial P4Info and P4 Source are Available

+

In this situation, a subset of the target's pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code. +

3.3.4. P4Info Role-Based Subsets

+

In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more. +

3.4. P4Runtime State Across Restarts

+

All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade. +

4. Controller Use-cases

+

P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +section. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime's flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex. +

4.1. Single Embedded Controller

+

Figure 2 shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases. +

+

P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC. +

+
+

single-embedded-controller +

+
+ +
Figure 2. Use-Case: Single Embedded Controller

4.2. Single Remote Controller

+

Figure 3 shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections. +

+
+

single-remote-controller +

+
+ +
Figure 3. Use-Case: Single Remote Controller

4.3. Embedded + Single Remote Controller

+

Figure 4 illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller. +

+

For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables. +

+
+

embedded-plus-single-remote-controller +

+
+ +
Figure 4. Use-Case: Embedded Plus Single Remote Controller

4.4. Embedded + Two Remote Controllers

+

Figure 5 illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +e.g. routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership. +

+
+

embedded-plus-two-remote-controllers +

+
+ +
Figure 5. Use-Case: Embedded Plus Two Remote Controllers

4.5. Embedded Controller + Two High-Availability Remote Controllers

+

Figure 6 illustrates a single +embedded controller plus two remote controllers in an active-standby HA +(High-Availability) configuration. Controller #1 is the active controller and is +in charge of some entities. If it fails, Controller #2 takes over and manages +the tables formerly owned by Controller #1. The mechanics of HA architectures +are beyond the scope of this document, but the P4Runtime multi-master +arbitration scheme supports it. +

+
+

embedded-plus-two-remote-ha-controllers +

+
+ +
Figure 6. Use-Case: Embedded Plus Two Remote High-Availability Controllers

5. Master-Slave Arbitration and Controller Replication

+

The P4Runtime interface allows multiple controllers to be connected to the +P4Runtime server running on the device at the same time for the following +reasons: +

+
    +
  1. +

    Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, “roles” (or “realms”) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +master and the rest are slaves. Role definition, i.e. how P4 entities get +assigned to each role, is out-of-scope of this document. +

  2. +
  3. +

    Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby slave controllers. These can already have a connection +open, which can help them become master more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved. +

+ +

To support multiple controllers, P4Runtime uses the streaming channel (available +via StreamChannel RPC) for session management. The workflow is described as +follows: +

+
    +
  • +

    Each controller instance (e.g. a controller process) can participate in one or +more roles. For each (device_id, role_id), the controller receives an +election_id. This election_id can be the same for different roles and/or +devices, as long as the tuple (device_id, role_id, election_id) is +unique. For each (device_id, role_id) that the controller wishes to +control, it establishes a StreamChannel with the P4Runtime server +responsible for that device, and sends a MasterArbitrationUpdate message +containing that tuple of (device_id, role_id, election_id) values. The +P4Runtime server selects a master independently for each (device_id, +role_id) pair. The master is the client that has the highest election_id +that the device has ever received for the same (device_id, +role_id) values. A connection between a controller instance and a device id + which involves a persistent StreamChannel can be referred to as a +P4Runtime client. +

    +

    Note that the P4Runtime server does not assign a role_id or election_id to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the election_id values used for each +StreamChannel. The P4Runtime server only keeps track of the (device_id, +role_id, election_id) of each StreamChannel that has sent a successful +MasterArbitrationUpdate message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +WriteRequest message to identify which client is making the WriteRequest, +not only the election_id. This enables controllers to re-use the same +numeric election_id values across different (device_id, role_id) +pairs. P4Runtime does not require election_id values be reused across such +different (device_id, role_id) pairs; it allows it. +

  • +
  • +

    To start a controller session, a controller first opens a bidirectional stream +channel to the server via the StreamChannel RPC for each device. This stream +will be used for two purposes: +

    +
      +
    • +

      Session management: As soon as the controller opens the stream +channel, it sends a StreamMessageRequest message to the switch. The +controller populates the MasterArbitrationUpdate field in this message +using its role_id and election_id, as well as the device_id of the +device. Note that the status field in the MasterArbitrationUpdate is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below. +

    • +
    • +

      Streaming of notifications (e.g. digests) and packet I/O: The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the master controller can participate in packet +I/O. This feature is explained in more details in the Packet +I/O section. +

    + +

    Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state. +

  • +
  • +

    Note that the stream is opened per device. In case a switching platform has +multiple devices (e.g. multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different masters for different +devices. In this case, it is the responsibility of the P4Runtime server to +keep track of the master for each device (and role). More specifically, the +P4Runtime server will know which stream corresponds to the master controller +for each pair of (device_id, role_id) at any point of time. +

  • +
  • +

    The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered “offline” or +“dead” as soon as its stream channel to the switch is broken. When a master +channel gets broken: (i) an advisory message is sent to all other controllers +for that device_id and role_id, as described in the +following section (ii) the P4Runtime server +will be without a master, until a client sends a successful +MasterArbitrationUpdate (as per the rules in a +later section). +

  • +
  • +

    The mechanism via which the controller receives the P4Runtime server details +which includes the device_id, ip and port, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +device_id) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks. +

+ +

gRPC enables the server to identify which client originated each message in the +StreamChannel stream. For example, the C++ gRPC library [10] in +synchronous mode enables a server process to cause a function to be called when +a new client creates a StreamChannel stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +StreamChannel is closed normally (or broken, e.g. because a client process +unexpectedly terminated). Thus the server can easily associate all +StreamChannel messages received from the same client, because they are +processed within the context of the same function call. +

+

A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values device_id, role_id, and election_id in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods [8] that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server. +

5.1. Default Role

+

A controller can omit the role message in MasterArbitrationUpdate. This +implies the “default role”, which corresponds to “full pipeline access”. This +also implies that a default role has a role.id of 0 (default). If using a +default role, all RPCs from the controller (e.g. Write) must set the role_id +to 0. +

5.2. Role Config

+

The role.config field in the MasterArbitrationUpdate message sent by the +controller describes the role configuration, i.e. which operations are in the +scope of a given role. In particular, the definition of a role may include the +following: +

+
    +
  • A list of P4 entities for which the controller may issue Write updates and +receive notification messages (e.g. DigestList and +IdleTimeoutNotification). +
  • +
  • Whether the controller is able to receive PacketIn messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketIn messages should be sent to the controller. +
  • +
  • Whether the controller is able to send PacketOut messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketOut messages are allowed to be sent by the controller. +
+ +

An unset role.config implies “full pipeline access” (similar to the default +role explained above). In order to support different role definition schemes, +role.config is defined as an Any Protobuf message [30]. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion. +

+

It is the job of the P4Runtime server to remember the role.config for every +device_id and role_id pair. +

5.3. Rules for Handling MasterArbitrationUpdate Messages Received from Controllers

+
    +
  1. +

    If the MasterArbitrationUpdate message is received for the first time on +this particular channel (i.e. for a newly connected controller): +

    +
      +
    1. +

      If device_id does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +NOT_FOUND error. +

    2. +
    3. +

      If the election_id is set and is already used by another controller for +the same (device_id, role_id), the P4Runtime server shall terminate +the stream by returning an INVALID_ARGUMENT error. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the number of open streams for the given (device_id, role_id) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a RESOURCE_EXHAUSTED error. +

    8. +
    9. +

      Otherwise, the controller is added to a list of connected controllers for +the given (device_id, role_id) and the server remembers the +controllers device_id, role_id and election_id for this gRPC +channel. See below for the rules to determine if this controller becomes +a master or slave, and what notifications are sent as a consequence. +

    +
  2. +
  3. +

    Otherwise, if the MasterArbitrationUpdate message is received from an +already connected controller: +

    +
      +
    1. +

      If the device_id does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. +

    2. +
    3. +

      If the role.id does not match the current role_id assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. If the controller wishes to change its role, +it must close the current stream channel and open a new one. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the election_id is set and is already used by another controller +(excluding the controller making the request) for the same +(device_id, role_id), the P4Runtime server shall terminate the stream +by returning an INVALID_ARGUMENT error. +

    8. +
    9. +

      If the election_id matches the one assigned to this stream: +

      +
        +
      1. +

        If the controller for this channel is the master, then the server +updates the role.config to the one specified in the +MasterArbitrationUpdate. An advisory mastership message is sent to +all controllers for this device_id and role_id informing +them of the new role.config. Since the format of role.config is +out of scope for the P4Runtime specification, the server will send +the advisory message for every update, even if the master sets the +same role.config as it has before. See the +following section for the format of +the advisory message. +

      2. +
      3. +

        If the controller is a slave, this is a no-op and the role.config +is ignored. No response is sent to any controller. +

      +
    10. +
    11. +

      Otherwise, the server updates the election_id it has stored for this +controller. This change might cause a change in mastership (this +controller might become master, or the controller might have downgraded +itself to a slave, see below), as well as notifications being sent to one +or more controllers. +

    +
+ +

If the MasterArbitrationUpdate is accepted by either of the two steps above +(cases 1.5. and 2.6. above), then the server determines if there are changes in +mastership. Let election_id_past be the highest election ID the server has +ever seen for the given device_id and role_id (including the one of the +current master if there is one). +

+
    +
  1. +

    If election_id is greater than or equal to election_id_past, then the +controller becomes master. The server updates the role configuration to +role.config for the given role.id. Furthermore: +

    +
      +
    1. +

      If there was no master for this device_id and role_id before and +there are no Write requests still processing from a previous master, +then the server immediately sends an advisory notification to all +controllers for this device_id and role_id. See the +following section for the format of the +advisory message. +

    2. +
    3. +

      If there was a previous master or Write requests in flight, then the +server carries out the following steps (in this order): +

      +
        +
      1. +

        The server stops accepting Write requests from the previous master +(if there is one). At this point, the server will reject all Write +requests with PERMISSION_DENIED. +

      2. +
      3. +

        The server notifies all controllers other than the new master of the +mastership change by sending the advisory notification described in +the following section. +

      4. +
      5. +

        The server will finish processing any Write requests that have +already started. If there are errors, they are reported as usual to +the previous master. If the previous master has already disconnected, +any possible errors are dropped and not reported. +

      6. +
      7. +

        The server now accepts the current controller as the new master, thus +accepting Write requests from this controller. The server updates +the highest election ID (i.e. election_id_past) it has seen for +this device_id and role_id to election_id. +

      8. +
      9. +

        The server notifies the new master by sending the advisory message +described in the following section. +

      +
    +
  2. +
  3. +

    Otherwise, the controller becomes a slave. If the controller was previously a +master (and downgraded itself), then an advisory message is sent to all +controllers for this device_id and role_id. Otherwise, the advisory +message is only sent to the controller that sent the initial +MasterArbitrationUpdate. See the +following section for the format of the +advisory message. +

+

5.4. Mastership Notifications

+

For any given device_id and role_id, any time a new master is chosen, a +master downgrades its status to a slave, a master disconnects, or the +role.config is updated by the master, all controllers for that +(device_id, role_id) are informed of this by sending a +StreamMessageResponse. The MasterArbitrationUpdate is populated as follows: +

+
    +
  • +

    device_id and role.id as given. +

  • +
  • +

    role.config is set to the role configuration the server received most +recently in a MasterArbitrationUpdate from a master. +

  • +
  • +

    election_id is populated as follows: +

    +
      +
    • +

      If there has not been any master at all, the election_id is left unset. +

    • +
    • +

      Otherwise, election_id is set to the highest election ID that the server +has seen for this device_id and role_id (which is the election_id of +the current master if there is any). +

    +
  • +
  • +

    status is set differently based on whether the notification is sent to the +master or a slave controller: +

    +
      +
    • +

      If there is a master: +

      +
        +
      • +

        For the master, status is OK (with status.code set to +google.rpc.OK). +

      • +
      • +

        For all slave controllers, status is set to non-OK (with +status.code set to google.rpc.ALREADY_EXISTS). +

      +
    • +
    • +

      Otherwise, if there is no master currently, for all slave controllers, +status is set to non-OK (with status.code set to +google.rpc.NOT_FOUND). +

    +
+ +

Note that on mastership changes with outstanding Write request, some +notifications might be delayed, see the +previous section for details. +

6. The P4Info Message

+

The purpose of P4Info was described under +Reference Architecture. +Here we describe the various +components. +

6.1. Common Messages

+

These messages appear nested within many other messages. +

6.1.1. Documentation Message

+

Documentation is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers. +

+
+
+
message Documentation {
+  // A brief description of something, e.g. one sentence
+  string brief = 1;
+  // A more verbose description of something.
+  // Multiline is accepted. Markup format (if any) is TBD.
+  string description = 2;
+}

6.1.2. Preamble Message

+

The preamble serves as the “descriptor” for each entity and contains the unique +instance ID, name, alias, annotations and documentation. +

+
+
+
message Preamble {
+  // ids share the same number-space; e.g. table ids cannot overlap with counter
+  // ids. Even though this is irrelevant to this proto definition, the ids are
+  // allocated in such a way that it is possible based on an id to deduce the
+  // resource type (e.g. table, action, counter, ...). This means that code
+  // using these ids can detect if the wrong resource type is used
+  // somewhere. This also means that ids of different types can be mixed
+  // (e.g. direct resource list for a table) without ambiguity. Note that id 0
+  // is reserved and means "invalid id".
+  uint32 id = 1;
+  // fully qualified name of the P4 object, e.g. c1.c2.ipv4_lpm
+  string name = 2;
+  // an alias (alternative name) for the P4 object, probably shorter than its
+  // fully qualified name. The only constraint is for it to be unique with
+  // respect to other P4 objects of the same type. By default, the compiler uses
+  // the shortest suffix of the name that uniquely identifies the object. For
+  // example if the P4 program contains two tables with names s.c1.t and s.c2.t,
+  // the default aliases will respectively be c1.t and c2.t. In the future, the
+  // P4 programmer may also be able to override the default alias for any P4
+  // object (TBD).
+  string alias = 3;
+  repeated string annotations = 4;
+  // Documentation of the entity
+  Documentation doc = 5;
+}

6.1.3. Annotating P4 Entities with Documentation

+

P4 entities may be annotated using the following annotations: +

+
+
+
@brief(string...)
+@description(string...)
+

Attaching either or both of these annotations to an entity will generate a +P4Info Documentation Message, which in turn will +appear in the Preamble Message for the entity. +

+

The P4 compiler should not emit annotation messages in the P4Info for these +specific cases; instead, it should generate the Documentation messages as +described. +

+

The following example shows documentation annotations for a table entity: +

+
+
+
@brief("Match IPv4 addresses to next-hop MAC and port")
+@description("Match IPv4 addresses to next-hop MAC and port. \
+Uses LPM match type.")
+table my_ipv4_lkup {
+  ...
+}

6.2. PkgInfo Message

+

The PkgInfo message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. PkgInfo can be extracted +and used to facilitate “browsing” of available P4 programs from a +library. Although all fields are technically “optional,” every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included. +

+
+
+
// Can be used to manage multiple P4 packages.
+message PkgInfo {
+  // a definitive name for this configuration, e.g. switch.p4_v1.0
+  string name = 1;
+  // configuration version, free-format string
+  string version = 2;
+  // brief and detailed descriptions
+  Documentation doc = 3;
+  // Miscellaneous metadata, free-form; a way to extend PkgInfo
+  repeated string annotations = 4;
+  // the target architecture, e.g. "psa"
+  string arch = 5;
+  // organization which produced the configuration, e.g. "p4.org"
+  string organization = 6;
+  // contact info for support,e.g. "tech-support@acme.org"
+  string contact = 7;
+  // url for more information, e.g. "http://support.p4.org/ref/p4/switch.p4_v1.0"
+  string url = 8;
+}

6.2.1. Annotating P4 code with PkgInfo

+

A P4 progam's PkgInfo may be declared using one or more of the following +annotations, attached to the main block only: +

+
+
+
@pkginfo(key=value)
+@pkginfo(key=value[,key=value,...])
+@brief("A brief description")
+@description("A longer\
+description")
+@custom_annotation(...)
+@another_custom_annotation(...)
+

Above we see several different types of annotations: +

+
    +
  • +

    @pkginfo - This is used to populate a specific field within the PkgInfo +message. Multiple @pkginfo annotations are allowed. For compactness, +multiple key-value pairs can appear in a single @pkginfo annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The keys must be from +among the message fields inside PkgInfo, for example, name, version, +etc. Each key-value pair assigns a value to the corresponding field inside the +single PkgInfo message for the program's P4Info. One exception is that the +Documentation field of PkgInfo must be expressed as individual +@description and @brief annotations, see next bullets. The key arch will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself. +

  • +
  • +

    @brief - This will populate the PkgInfo.doc.brief message field. +

  • +
  • +

    @description - This will populate the PkgInfo.doc.description message +field +

  • +
  • +

    @<anything else> - This will create a PkgInfo.annotation entry +

+ +

Declaring one or more of these annotations on main will +generate a single corresponding PkgInfo message in the P4Info as described in +PkgInfo Message. +

+

The following example shows @pkginfo annotations using a mixture of single and +multiple key-value pairs. It also shows @brief and @description annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the PkgInfo message. The custom annotations will +be appended to the PkgInfo.annotations list. +

+
+
+
@pkginfo(name="switch.p4",version="2")
+@pkginfo(organization="p4.org")
+@pkginfo(contact="info@p4.org")
+@pkginfo(url="www.p4.org")
+@brief("L2/L3 switch")
+@description("L2/L3 switch.\
+Built for data-center profile.")
+@my_annotation1(...) // Not well-known, this will appear in PkgInfo annotations
+@my_annotation2(...) // Not well-known, this will appear in PkgInfo annotations
+PSA_Switch(IgPipeline, PacketReplicationEngine(), EgPipeline,
+           BufferingQueueingEngine()) main;

6.3. ID Allocation for P4Info Objects

+

P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(e.g. table, action, counter, ). The most significant 8 bits of the ID +encodes the object type (as per Table 1). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (p4.config.v1.P4Ids.Prefix). These values must +be used (e.g. by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table 2 shows the ID +layout. +

+
+ + + + + + + + + + + + + + + + + + + + + +
8-bit prefix value P4 object type
0x00 Reserved (unspecified)
0x01 Action
0x02 Table
0x03 Value-set
0x04 Controller header (header type with @controller_header annotation)
0x050x0f Reserved (for future P4 built-in objects)
0x10 Reserved (start of PSA extern types)
0x11 PSA Action profiles / selectors
0x12 PSA Counter
0x13 PSA Direct counter
0x14 PSA Meter
0x15 PSA Direct meter
0x16 PSA Register
0x17 PSA Digest
0x180x7f Reserved (for future PSA extern types)
0x80 Reserved (start of vendor-specific extern types)
0x810xfe Vendor-specific extern types
0xff Reserved (max prefix value)
+
+ +
Table 1. Mapping of P4Info object type to 8-bit ID prefix value
+
+ + + + +
MSB bit 31 .. bit 24 bit 23 .. bit 0 LSB
Object type prefix Generated suffix (e.g. by the compiler)
+
+ +
Table 2. Format of P4Info object IDs
+

It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with @id (see Table +3). The compiler must honor the @id annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (i.e. if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same @id value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. +

+
+ + + + + + + + + + +
P4 declaration(s) Compiler-allocated ID(s)
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) table tA... Error(same ID suffixes for 2 objects of the same type)
@id(0x12ab34) table tB...
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) action act1... 0x0112ab34
+
+ +
Table 3. Example of statically-assigned P4Info object IDs

6.4. P4Info Objects

6.4.1. Table

+

Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this table. +

  • +
  • +

    match_fields, a repeated field of type MatchField representing the data to +be used to construct the lookup key matched in this table. Each MatchField +message is defined with the following fields: +

    +
      +
    • +

      id, the uint32 identifier of this MatchField, unique in the scope of +this table. No rules are prescribed on the way MatchField IDs should be +allocated, as long as two MatchField of the same table do not have the +same ID. Nonetheless, we recommend that the IDs be assigned incrementally, +starting from 1, in the same order as in the P4 key declaration. +

    • +
    • +

      name, the string representing the name of this MatchField. +

    • +
    • +

      annotations, a repeated field of strings, each one representing a P4 +annotation associated to this match field. +

    • +
    • +

      bitwidth, an int32 value set to the size in bits of this match field. +

    • +
    • +

      match, a oneof describing the match behavior for this field; it can be +either: +

      +
        +
      • match_type, an enum field of type MatchType, which includes all +possible PSA match kinds. +
      • +
      • other_match_type, a string field which can be used to encode any +architecture-specific match type. +
      +
    • +
    • +

      doc, a Documentation message describing this match field. +

    • +
    • +

      type_name, which indicates whether the match field has a user-defined +type; this is useful for +translation. +

    +
  • +
  • +

    action_refs, a repeated ActionRef field representing the set of possible +actions for this table. The ActionRef message is used to reference an action +specified in the same P4Info message and it includes the following fields: +

    +
      +
    • id, the uint32 identifier of the action. +
    • +
    • scope, an enum value which can take one of three values: + TABLE_AND_DEFAULT, TABLE_ONLY and DEFAULT_ONLY. The scope of the + action is determined by the use of the P4 standard annotations + @tableonly and @defaultonly [17]. TABLE_ONLY + (@tableonly annotation) means that the action can only appear within + the table, and never as the default action. DEFAULT_ONLY + (@defaultonly annotation) means that the action can only be used as the + default action. TABLE_AND_DEFAULT is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action. +
    • +
    • annotations, a repeated string field, each one representing a P4 +annotation associated to the action reference in this table. +
    +
  • +
  • +

    const_default_action_id, if this table has a constant default action, this +field will carry the uint32 identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action's +arguments. +

  • +
  • +

    implementation_id, the uint32 identifier of the “implementation” of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (e.g. a PSA ActionProfile or ActionSelector +instance). The table is then referred to as an indirect match table. +

  • +
  • +

    direct_resource_ids, repeated uint32 identifiers for all the direct +resources attached to this table, such as DirectMeter and DirectCounter +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2. +

  • +
  • +

    size, an int64 describing the desired number of table entries that the +target should support for the table. See the “Size” subsection within the +“Table Properties” section of the P416 language specification for details +[29]. +

  • +
  • +

    idle_timeout_behavior, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +Idle-Timeout section). Value can be any of the +IdleTimeoutBehavior enum: +

    +
      +
    • NO_TIMEOUT (default value), which means that idle timeout is not +supported for this table. +
    • +
    • NOTIFY_CONTROL, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +Table Idle Timeout Notifications). +
    +
  • +
  • +

    is_const_table, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime. +

  • +
  • +

    other_properties, an Any Protobuf message [30] to embed +architecture-specific table properties [29] which are not part +of the core P4 language or of the PSA architecture. +

+

6.4.2. Action

+

Action messages are used to specify all possible actions of all match-action +tables. +

+

The Action message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this action +

  • +
  • +

    params, a repeated field of Param messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each Param message contains the +following fields: +

    +
      +
    • id, the uint32 identifier of this parameter. No rules are prescribed +on the way Param IDs should be allocated, as long as two Param of the +same action do not have the same ID. Nonetheless, we recommend that the +IDs be assigned incrementally, starting from 1, in the same order as in +the P4 action declaration. +
    • +
    • name, the string representing the name of this parameter. +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this parameter. +
    • +
    • bitwidth, an int32 value set to the size in bits of this parameter. +
    • +
    • doc, which describes this parameter using a Documentation message. +
    • +
    • type_name, which indicates whether the action parameter has a +user-defined type; this is useful for +translation. +
    +
+

6.4.3. ActionProfile

+

ActionProfile messages are used to specify all available instances of Action +Profile and Action Selector PSA externs. +

+

PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile member, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime. +

+

PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into groups. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime. +

+

While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same ActionProfile message to describe both. +

+

The ActionProfile message includes the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Action +Profile or Selector. +

  • +
  • +

    table_ids, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector. +

  • +
  • +

    with_selector, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern. +

  • +
  • +

    size, an int64 representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups. +

  • +
  • +

    max_group_size, an int32 representing the maximum sum of all member +weights within any given selector group, in the case of an Action Selector, or +0 for an Action Profile. PSA programs can use the @max_group_size annotation +to provide this value for Action Selectors. If the annotation is omitted, the +P4Info field will default to 0. +

+

6.4.4. Counter & DirectCounter

+

Counter and DirectCounter messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is: +

+
    +
  • +

    Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index. +

  • +
  • +

    Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table. +

+ +

Both Counter and DirectCounter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this counter +extern instance. +

  • +
  • +

    spec, a message of of type CounterSpec used to describe the compile-time +configuration of this counter. Currently, the CounterSpec message is used to +carry only the counter unit, which can be any of the CounterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES: byte counter. +
    • +
    • PACKETS: packet counter. +
    • +
    • BOTH: combination of both byte and packet counter. +
    +
+ +

For indexed counters, the Counter message contains also a size field, an +int64 representing the maximum number of independent values that can be held +by this counter array. Conversely, the DirectCounter message contains a +direct_table_id field that carries the unit32 identifier of the table to +which this direct counter is attached. +

+

For indexed counters, the Counter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.5. Meter & DirectMeter

+

Meter and DirectMeter messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is: +

+
    +
  • +

    Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +e.g. to set the rate threshold. +

  • +
  • +

    Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table. +

+ +

Both Meter and DirectMeter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this meter +extern instance. +

  • +
  • +

    spec, a message of type MeterSpec used to describe the capabilities of +this meter extern instance. Currently, the MeterSpec message is used to +carry only the meter unit, which can be any of the MeterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES, which signifies that this meter can be configured with rates +expressed in bytes/second. +
    • +
    • PACKETS, for rates expressed in packets/second. +
    +
+ +

For indexed meters, the Meter message contains also a size field, an int64 +representing the maximum number of independent cells that can be held by this +meter. Conversely, the DirectMeter message contains a direct_table_id field +that carries the uint32 identifier of the table to which this direct meter is +attached. +

+

For indexed meters, the Meter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.6. ControllerPacketMetadata

+

ControllerPacketMetadata messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server. +

+

When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet. +

+

Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +@controller_header("packet_in") and @controller_header("packet_out"), +respectively. ControllerPacketMetadata messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages). +

+

A P4Info message can contain at most two ControllerPacketMetadata messages, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message where preamble.name is set to "packet_in" +and "packet_out" for packet-in and packet-out metadata, respectively. +

  • +
  • +

    metadata, a repeated field of type Metadata, where each Metadata message +includes the following fields: +

    +
      +
    • id, a uint32 identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two Metadata of the +same ControllerPacketMetadata message do not have the same +ID. Nonetheless, if the P4Info message was generated from a P4 compiler, +we recommend that the IDs be assigned incrementally, starting from 1, in +the same order as the fields in the P4 header declaration. +
    • +
    • name, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below). +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this metadata. +
    • +
    • bitwidth, an int32 representing the size in bits of this metadata. +
    • +
    • type_name, which indicates whether the metadata field has a +user-defined type; this is useful for +translation. +
    +
+ +

As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding ControllerPacketMetadata +messages. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  bit<9> egress_port; /* suggested port where the packet
+                         should be sent */
+  bit<8> queue_id;    /* suggested queue ID */
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  bit<9> ingress_port; /* data plane port ID where
+                          the original packet was received */
+  bit<1> is_clone;     /* 1 if this is a clone of the
+                          original packet */
+}
+
+
+
controller_packet_metadata {
+  preamble {
+    id: 2868916615
+    name: "packet_out"
+    annotations: "@controller_header(\"packet_out\")"
+  }
+  metadata {
+    id: 1
+    name: "egress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "queue_id"
+    bitwidth: 8
+  }
+}
+
+controller_packet_metadata {
+  preamble {
+    id: 2868941301
+    name: "packet_in"
+    annotations: "@controller_header(\"packet_in\")"
+  }
+  metadata {
+    id: 1
+    name: "ingress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "is_clone"
+    bitwidth: 1
+  }
+}
+

Note that the use of @controller_header is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages. +

6.4.7. ValueSet

+

ValueSet messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P416 +specification [37]. +

+

The ValueSet message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Value +Set. +

  • +
  • +

    match, a repeated field of MatchField messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the match_fields repeated field in the +Table message. +

  • +
  • +

    size, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +value_set constructor call. +

+ +

According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of bit<W>, +tuple, or struct [25]. The rest of this section looks at all 3 of +these cases and gives an example ValueSet message when appropriate. +

+
    +
  1. +

    If the type parameter is bit<W>, match will include exactly one +MatchField message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used): +

    +
      +
    • id: set to 1 +
    • +
    • bitwidth: set to the value of W +
    • +
    • match_type: set to EXACT +
    +
+ +
+
+
@id(1) value_set<bit<8> >(4) pvs;
+select (hdr.f8) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    bitwidth: 8
+    match_type: EXACT
+  }
+  size: 4
+}
+
    +
  1. +

    If the type parameter is a tuple, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program. +

  2. +
  3. +

    If the type parameter is a struct, this version of P4Runtime requires that +all the fields of the struct be of type bit<W> (where W can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +match field will include one MatchField message for each field in the +struct, with the following fields: +

    +
      +
    • id: must be unique with respect to the other match entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. +
    • +
    • name: set to the name of the corresponding struct field. +
    • +
    • annotations: set to the list of P4 annotations associated with the struct +field, except for the @match annotation, if present (see the match field +below). +
    • +
    • bitwidth: set to the value of W for the corresponding struct field. +
    • +
    • type_name, which indicates whether the struct field has a user-defined +type; this is useful for +translation. +
    • +
    • match: by default match_type is set to EXACT; the P4 programmer can +specify a different match type by using the @match annotation +[25]. +
    • +
    • doc: documentation associated with the struct field. +
    +
+ +
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a user-defined +type that resolves to a bit<W>, or a struct where +one or more fields is a user-defined type that +resolves to a bit<W>. For each MatchField that corresponds to a user-defined +type, the type_name field must be set to the appropriate value (i.e. the name +of the type). +

6.4.8. Register

+

Register messages are used to specify all possible instances of Register PSA +externs. +

+

Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime. +

+

The Register message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this register +instance. +

  • +
  • +

    type_spec, which specifies the data type stored by this register, expressed +using a P4DataTypeSpec message (see section on Representation of Arbitrary +P4 Types). +

  • +
  • +

    size, an int32 value representing the total number of independent register +cells available. +

  • +
  • +

    index_type_name, which indicates whether the register index has a +user-defined type. This is useful for +translation. The underlying built-in type +must be a fixed-width unsigned bitstring (bit<W>). +

+

6.4.9. Digest

+

Digest messages are used to specify all possible instances of Packet Digest +PSA externs. +

+

A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages. +

+

The Digest message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this digest +instance. +

  • +
  • +

    type_spec, which specifies the data type of an individual digest +notification using a P4DataTypeSpec message (see section on Representation +of Arbitrary P4 Types). +

+

6.4.10. Extern

+

Extern messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one Extern message instance in P4Info. The Extern message defines +the following fields: +

+
    +
  • +

    extern_type_id, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the reserved +range [0x81, 0xfe]. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture. +

  • +
  • +

    extern_type_name, which specifies the fully-qualified P4 name of the extern +type. +

  • +
  • +

    instances, a repeated field of ExternInstance Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +ExternInstance in turn defines the following fields: +

    +
      +
    • preamble, a Preamble message with the ID, name, and alias of this digest +instance. +
    • +
    • info, an Any Protobuf message [30] which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for info should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on Extending +P4Runtime for non-PSA Architectures for more +information. +
    +
+ +

If the P4 program does not include any instance of a given extern type, the +Extern message instance for that type should be omitted from the P4Info. +

6.5. Support for Arbitrary P4 Types with P4TypeInfo

+

See section on Representation of Arbitrary P4 +Types. +

7. P4 Forwarding-Pipeline Configuration

+

The ForwardingPipelineConfig captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the “Device Configuration” and sometimes also referred to as +the “P4 Blob”. It is defined as: +

+
+
+
message ForwardingPipelineConfig {
+  config.P4Info p4info = 1;
+  bytes p4_device_config = 2;
+  message Cookie {
+    uint64 cookie = 1;
+  }
+  Cookie cookie = 3;
+}
+

The p4info field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic. +

+

The p4_device_config is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new ForwardingPipelineConfig on that target. +

+

The cookie field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a GetForwardingPipelineConfig RPC. +When writing the config via a SetForwardingPipelineConfig RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present. +

8. General Principles for Message Formatting

8.1. Set / Unset Protobuf Field

+

In Protobuf version 3 (proto3), the default value for a message field is +“unset” [4]. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +CounterEntry message, an “unset” index field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the index message field is +set, a single entry will be read. +

+

Let's look at the counter example in more details. Based on this specification +document, the C++ server code which processes CounterEntry messages may look +like this: +

+
+
+
auto *counter_entry = ...
+if (counter_entry->has_index()) {
+  auto index = counter_entry->index().index();
+  read_one_entry(counter_entry->id(), index);
+} else {
+  read_all_entries(counter_entry->id());
+}
+
    +
  1. +

    Reading a single counter entry at index 0 in the counter array with id +<id>: +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
      +entry.mutable_index();
      +// The above line sets the index field; it is equivalent to:
      +// auto *index = entry.mutable_index();
      +// index->set_index(0);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
      +index {}
    • +
    • Expected behavior: Counter entry at index 0 is read. Notice that the +index subfield is missing under the index field message of +CounterEntry in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages. +
    +
  2. +
  3. +

    Reading all counter entries by leaving the index field unset +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
    • +
    • Expected behavior: All counter entries for the provided counter +instance are read. Notice that the index message field is unset (default +value) and is therefore omitted from the textual representation of the +message. +
    +
+

8.2. Read-Write Symmetry

+

The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example: +

+
+
+
intended_value = value
+
+status = server.write(intended_value, p4_entity)
+observed_value = server.read(p4_entity)
+
+assert(intended_value == observed_value)
+

To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If Read RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol's complexities to the client implementations. +

+

In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the match fields in a TableEntry message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +MessageDifferencer class [35] included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance. +

8.3. Zero as Reserved Value

+

p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a uint32. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a WriteRequest or a SetForwardingPipelineConfigRequest. +

8.4. Bytestrings

+

P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (bit<W>) or signed (int<W>), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +bytes Protobuf type. The correct bitwidth as per the P4 program of +each integer variable exposed through P4Runtime is specified in the P4Info +message. +

+

The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals: +

+
    +
  • +

    It ensures that a properly encoded binary string's integer value conforms +to the P4Info-specified bitwidth. +

  • +
  • +

    It supports read-write symmetry. +

  • +
  • +

    It helps facilitate non-disruptive P4 program updates. +

+ +

In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type bit<W> and/or int<W>. +

+

Note that this representation does not make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range. +

+

In the P4Runtime API version 1.0, values of table key fields, action parameters, +and fields in packet-in and packet-out headers between a device and the +controller (see 6.4.6), may not be of type int<W>. +The rules for encoding signed values thus only apply to messages of type +P4Data (see 8.5.3). +

+

For a value of type bit<W>, the fewest number of bits required to represent +the integer value $V > 0$ is the smallest integer $A$ such that $V \leq 2^A -1$. +

+

For a value of type int<W>, the fewest number of bits required to represent +the integer value $V \neq 0$ in 2's complement form is the smallest integer $A$ +such that $-2^{A-1} \leq V \leq 2^{A-1} - 1$. +

+

As a special case, define that the value $V=0$ requires at least $A=1$ bit to +represent, regardless of whether it is signed or unsigned. +

+

The shortest possible binary string for an integer $V$ that needs $A$ bits to +represent it is computed as: +

+
+
+
minimum_string_size = floor((A + 7) / 8)
+

Binary strings with the byte length computed as minimum_string_size promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies. +

+

Any additional bits in the bytes sent for an unsigned integer value (type +bit<W>) must be 0. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with 0. +

+

Any additional bits in the bytes sent for a signed integer value (type int<W>) +must be copies of the sign bit, i.e. 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with copies of the +sign bit, i.e. 0 for non-negative values, or 0xff for negative values. In 2's +complement representation, this is called “sign extension”, and leaves the +numeric value represented unchanged. +

+

Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value. +

+

For a received bitstring expected to fit within a bit<W> type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring's width is W bits or less. +

+

For a received bitstring expected to fit within an int<W> type, the value it +represents is in range if, after “undoing sign extension”, the remaining bit +string's width is W bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other. +

+

If the string's byte length is zero, the server always rejects the string. +

+

When the server rejects a binary string due to any of the previous criteria, +it returns an OUT_OF_RANGE error. +

+

For all binary strings, P4Runtime uses big-endian (i.e. network) byte-order. +For signed integer values (int<W> P4 type), P4Runtime uses the same two's +complement bitwise representation as P4. Table 4 +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above. +

+
+ + + + + + + + + + + + + + + + + +
P4 type Integer value P4Runtime binary string Read-write symmetry
bit<8> 99 (0x63) \x63 yes
bit<16> 99 (0x63) \x00\x63 no
bit<16> 99 (0x63) \x63 yes
bit<16> 12388 (0x3064) \x30\x64 yes
bit<16> 12388 (0x3064) \x00\x30\x64 no
bit<12> 99 (0x63) \x00\x63 no
bit<12> 99 (0x63) \x63 yes
bit<12> 99 (0x63) \x00\x00\x63 no
int<8> 99 (0x63) \x63 yes
int<8> -99 (-0x63) \x9d yes
int<8> -99 (-0x63) \xff\x9d no
int<12> -739 (-0x2e3) \xfd\x1d yes
int<16> 0 (0x0) \x00\x00 no
int<16> 0 (0x0) \x00 yes
+
+ +
Table 4. Examples of Valid Bytestring Encoding
+

Table 5 shows some examples of invalid +P4Runtime binary strings: +

+
+ + + + + + + + + + + + +
P4 type P4Runtime binary string
bit<8> \x01\x63
bit<8> empty string
bit<16> \x01\x00\x63
bit<12> \x10\x63
bit<12> \x01\x00\x63
bit<12> \x00\x40\x63
int<8> \x00\x9d
int<12> \x8d\x1d
int<16> empty string
+
+ +
Table 5. Examples of Invalid Bytestring Encoding
+

As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from bit<8> to bit<9>, a server +running the bit<9> version of the P4 program will accept requests from +clients that remain on the bit<8> P4Runtime version. +

+

Despite the server's binary string flexibility for P4 program update support, +the client and server must both remain aware of the +read-write symmetry +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values. +

+

Representation of variable-length integer values (varbit<W> P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the dynamic-length of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an OUT_OF_RANGE error code otherwise. +

8.5. Representation of Arbitrary P4 Types

8.5.1. Problem Statement

+

The P416 language includes more complex types than just binary strings +[3]. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table 6 shows the different +P416 types and how they are allowed to be used, as per the P416 +specification. +

+
+ + + + + + + + + + + + + + + + + + + +
Container type
Element type header header_union struct or tuple
bit<W> allowed error allowed
int<W> allowed error allowed
varbit<W> allowed error allowed
int error error error
void error error error
error error error allowed
match_kind error error error
bool error error allowed
enum allowed1 error allowed
header error allowed allowed
header stack error error allowed
header_union error error allowed
struct error error allowed
tuple error error allowed
+
+ +
Table 6. P4 Type Usage
+

For example, the following P416 objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects. +

+
+
+
Digest<tuple<bit<4>, bit<8> > >() digest_complex;
+digest_complex.pack({ hdr.ipv4.version, hdr.ipv4.protocol });
+// ...
+header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

One solution would be to use only binary string (bytes type) in +p4runtime.proto and to define a custom serialization format for complex P416 +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P416 types. +

8.5.2. P4 Type Specifications in p4info.proto

+

In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type ip_t, which is a header union with 2 possible headers: +ipv4 with type ipv4_t and ipv6 with type ipv6_t. Similarly, they need to +know the field layout for both of these header types. +

+

To achieve this we introduce 2 main Protobuf messages: P4TypeInfo and +P4DataTypeSpec. +

+

P4TypeInfo is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P416 program. These +named types are struct, header, header_union, enum and +serializable_enum; for each of these we have a type specification message, +respectively P4StructTypeSpec, P4HeaderTypeSpec, P4HeaderUnionTypeSpec, +P4EnumTypeSpec and P4SerializableEnumTypeSpec. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. P4TypeInfo also includes the list of parser errors for the program, as +a P4ErrorTypeSpec message. +

+

P4DataTypeSpec is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each P4DataTypeSpec message corresponds to a compile-time type in the +original P416 program (e.g. the type parameter of an extern). This +compile-time type is represented as a Protobuf oneof, which can be: +

+
    +
  • +

    a string representing the name of the type in case of a named type (struct, +header, header_union, enum, serializable_enum or user-defined “new” +type), +

  • +
  • +

    an empty Protobuf message for bool and error, or +

  • +
  • +

    a Protobuf message for other anonymous types (bit<W>, int<W>, varbit<W>, +tuple or stack). The “binary string” types (bit<W>, int<W>, and +varbit<W>) are grouped together in the P4BitstringLikeTypeSpec message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf bytes +type). +

+ +

For all P416 compound types (tuple, struct, header, and header_union), +the order of members in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P416 declaration. The same goes for the order of members of an enum +(serializable or not) or members of error. +

8.5.3. P4Data in p4runtime.proto

+

P4Runtime uses the P4Data message to represent values of arbitrary types. The +P4Runtime client must generate correct P4Data messages based on the type +specification information included in P4Info. The P4Data message was designed +to introduce little overhead compared to using binary strings in the most common +case (P416 bit<W> type). +

+

Just like its P4Info counterpart - P4DataTypeSpec -, P4Data uses a Protobuf +oneof to represent all possible values. +

+

We define a canonical representation for P4Data messages therefore +guaranteeing read-write symmetry by introducing the following requirements: +

+
    +
  • +

    The order of members in P4StructLike and the order of bitstrings in +P4Header must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P416 type +declaration. +

  • +
  • +

    An invalid header is represented by a P4Header message where the is_valid +field is false and the bitstrings repeated field is empty. +

  • +
  • +

    An invalid header union (i.e. all headers in the union are invalid) is +represented by a P4HeaderUnion message where the valid_header_name is the +empty string (default value for the field) and the valid_header is unset. +

  • +
  • +

    The order of entries in P4HeaderStack and P4HeaderUnionStack is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the entries field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding P4HeaderStackTypeSpec or +P4HeaderUnionStackTypeSpec message. +

+

8.5.4. Example

+

Let's look at the Register example again: +

+
+
+
header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

Here's the corresponding entry in the P4Info message: +

+
+
+
registers {
+  preamble {
+    id: 369119267
+    name: "register_ip"
+    alias: "register_ip"
+  }
+  type_spec {
+    header_union {
+      name: "ip_t"
+    }
+  }
+  size: 128
+}
+type_info {
+  headers {
+    key: "ipv4_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  headers {
+    key: "ipv6_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  header_unions {
+    key: "ip_t"
+    value {
+      members {
+        name: "ipv4"
+        header {
+          name: "ipv4_t"
+        }
+      }
+      members {
+        name: "ipv6"
+        header {
+          name: "ipv6_t"
+        }
+      }
+    }
+  }
+}
+

Here's a p4.WriteRequest to set the value of register_ip[12]: +

+
+
+
update {
+  type: INSERT
+  entity {
+    register_entry {
+      register_id: 369119267
+      index {
+        index: 12
+      }
+      data {
+        header_union {
+          valid_header_name: "ipv4"
+          valid_header {
+            is_valid: true
+            bitstrings: "\x04"
+            bitstrings: # ...
+          }
+        }
+      }
+    }
+  }
+}

8.5.5. enum, serializable enum and error

+

P416 supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or “unsafe” enum) +[5]. For enum types with no underlying type as well as error +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in P4Data to represent enum and +error values. +

+

Serializable enum types have an underlying fixed-width unsigned integer +representation (bit<W>). All named enum members must be assigned an integer +value by the P4 programmer, but not all valid numeric values for the +underlying type need to have a corresponding name. P4TypeInfo includes the +mapping between entry name and entry value. When providing serializable enum +values through P4Data, one must use the assigned integer value (enum_value +bytestring field). P4Runtime does not provide a way for the client to use the +name even when the enum member has one instead of the value, as it makes +it easier for the server to respect the read-write +symmetry principle. +

8.5.6. User-defined types

+

P416 enables programmers to introduce new types [11]. While similar +to typedef, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +translation. When introducing a new type, the +declaration can be annotated with @p4runtime_translation to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for port numbers, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. The @p4runtime_translation annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (bit<W>) and the type exposed to the control plane will also be a +fixed-width unsigned bitstring, with a potentially different bitwidth. It takes +two parameters: a URI (Uniform Resource Identifier) which uniquely identifies +the translation being performed on entities of the new type to the P4Runtime +server and the bitwidth of the bitstring type exposed to the control plane. It +is recommended that the URI includes at least the P4 architecture name and the +type name. +

+

A @p4runtime_translation annotation need not have any effect if it is used to +annotate anything in a P4 program other than a type declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect. +

+

User-defined types are specified using the P4NewTypeSpec message, which has +the following fields: +

+
    +
  • +

    representation, a Protobuf oneof specifying how values of this type are +exchanged between client and server; it can be either: +

    +
      +
    • +

      original_type, if and only if no @p4runtime_translation annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 type declaration is itself a +user-defined type, original_type is obtained by “walking” the chain of +type declarations recursively until a built-in type (e.g. bit<W>) is +found. +

    • +
    • +

      translated_type, if and only if the P4 type declaration was annotated +with @p4runtime_translation. It is of type P4NewTypeTranslation, which +itself has two fields uri and sdn_bitwidth , which map to the +two input parameters to the annotation. +

    +
  • +
  • +

    annotations, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration. +

+ +

For example, an architecture in this case PSA may introduce a new type +for port numbers: +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type bit<9> PortId_t;
+

In this case, the P4Info message would include the following P4TypeInfo +message: +

+
+
+
type_info {
+  new_types {
+    key: "PortId_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+

Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (e.g. through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over @p4runtime_translation to enable users +to overwrite annotations included as part of the P4 architecture definition. +

8.5.7. Trade-off for v1.0 Release

+

For the v1.0 release of P4Runtime, it was decided not to replace occurrences of +bytes with P4Data in the p4.v1.FieldMatch message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-release +implementations of P4Runtime. Similarly it has been decided to keep using +bytes to provide action parameter values. However P4Data is used whenever +appropriate for PSA externs and we encourage the use of P4Data in +architecture-specific extensions. +

+

In order to support translation for action +parameters and match fields, we include a type_name field in +p4.config.v1.MatchField and p4.config.v1.Action.Param. +

9. P4 Entity Messages

+

P4Runtime covers P4 entities that are either part of the P416 language, or +defined as PSA externs. The sections below describe the messages for each +supported entity. +

9.1. TableEntry

+

The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action's +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification. +

+

P4Runtime supports inserting, modifying, deleting and reading table entries with +the TableEntry entity, which has the following fields: +

+
    +
  • +

    table_id, which identifies the table instance; the table_id is determined +by the P4Info message. +

  • +
  • +

    match, a repeated field of FieldMatch messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration. +

  • +
  • +

    action, which indicates which of the table's actions to execute in case of +match and with which argument values. +

  • +
  • +

    priority, a 32-bit integer used to order entries when the table's match key +includes a ternary or range match. +

  • +
  • +

    controller_metadata, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. +

  • +
  • +

    meter_config, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    counter_data, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    is_default_action, a boolean flag which indicates whether the table entry is +the default entry for the table. See Default entry +section for more information. +

  • +
  • +

    idle_timeout_ns and time_since_last_hit, which are two fields used to +implement idle-timeout support for the table, if applicable. See +Idle-timeout section for more information. +

+ +

The priority field must be set to a non-zero value if the match key includes a +ternary match (i.e. in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has a TERNARY or RANGE match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches. +

+

The match and priority fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for MODIFY and DELETE updates. When deleting +an entry, these key fields (along with is_default_action) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a keyless +table (the table has an empty match key), the server must reject all attempts to +INSERT a match entry and return an INVALID_ARGUMENT error. +

+

The number of match entries that a table should support is indicated in P4Info +(size field of Table message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P416 specification for the +size property [29]. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +RESOURCE_EXHAUSTED when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached. +

9.1.1. Match Format

+

The bytes fields in the FieldMatch message follow the format described in +Bytestrings. +

+

For “don't care” matches, the P4Runtime client must omit the field's entire +FieldMatch entry when building the match repeated field of the TableEntry +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for “don't care” matches, which is needed +to ensure read-write symmetry. For PSA match types, +a “don't care” match for a specific match key field is defined as follows: +

+
    +
  • +

    For a TERNARY match, it is logically equivalent to a mask of zeros. +

  • +
  • +

    For an LPM match, it is logically equivalent to a prefix_len of zero. +

  • +
  • +

    For a RANGE match, it is logically equivalent to a range which includes all +possible values for the field. +

+ +

Note that there is no “don't care” value for EXACT matches and therefore exact +match fields can never be omitted from the TableEntry message. +

+

The following example shows a P4Runtime message that treats a TERNARY field +as a “don't care” match. The P4 program defines table t with TERNARY +and EXACT fields in its match key: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: ternary;
+    istd.ingress_port: exact;
+  }
+  actions = {
+    drop;
+  }
+}
+

In this P4Runtime request, the client omits the table's TERNARY field +from the repeated match field to indicate a “don't care” match. As shown +below, the match specifies only the EXACT field given by field_id: 2. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 33554439  # Table t's ID.
+    match {
+      # field_id 1 is not present to use the don't care ternary value.
+      field_id: 2
+      exact {
+        value: "\x20"
+      }
+    }
+    action {
+      # Action selection goes here.
+    }
+  }
+}
+

For every member of the TableEntry repeated match field, field_id must be +a valid id for the table, as per the P4Info, and one of the fields in +field_match_type must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an INVALID_ARGUMENT error code. +

+
    +
  • EXACT match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.exact().value()))
+
    +
  • LPM match + +
      +
    • The binary string encoding of the value (when present) must conform to the +Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • “Don't care” bits must be 0 in value. +
+ +
+
+
assert(BytestringValid(match.lpm().value()))
+
+pLen = match.lpm().prefix_len()
+assert(pLen > 0)
+
+trailing_zeros = countTrailingZeros(match.lpm().value())
+assert(trailing_zeros >= field_bits - pLen)
+
    +
  • TERNARY match + +
      +
    • The binary string encoding of the value (when present) and mask (when +present) must conform to the Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • Masked bits must be 0 in value. This constraint taken together +with the Bytestrings requirements means that the +value's binary string is never longer than the mask's binary string. +When the value's string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask. +
+ +
+
+
assert(BytestringValid(match.ternary().value()))
+assert(BytestringValid(match.ternary().mask()))
+assert(match.ternary().value().size() <= match.ternary().mask().size());
+
+value = parseInteger(match.ternary().value())
+mask = parseInteger(match.ternary().mask())
+
+assert(mask != 0)
+
+assert(value & mask == value)
+
    +
  • RANGE match + +
      +
    • The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the Bytestrings +requirements. +
    • +
    • Low bound must be less than or equal to the high bound. +
    • +
    • “Don't care” match must be omitted. +
+ +
+
+
assert(BytestringValid(match.range().low()))
+assert(BytestringValid(match.range().high()))
+
+low = parseInteger(match.range().low())
+high = parseInteger(match.range().high())
+
+assert(low <= high)
+
+assert(low != min_field_value || high != max_field_value)

9.1.2. Action Specification

+

The TableEntry action field must be set for every INSERT update but may be +left unset for MODIFY updates, in which case the action specification for the +table entry will not be modified (if a MODIFY update has an unset action field +and does not modify any direct resource attached to the table then the MODIFY +update is a no-op). Based on the implementation property value of the P4 table, +the oneof in the TableAction message will either be: +

+
    +
  • +

    an Action specification for direct tables (with no P4 implementation +property) +

  • +
  • +

    an action profile member id for indirect tables for which the implementation +property is an action profile with no selector. +

  • +
  • +

    an action profile member id or group id for indirect tables for which the +implementation property is an action profile with selector. +

  • +
  • +

    an ActionProfileActionSet specification for indirect tables for +which the implementation property is an action profile with +selector. This usage is described in One Shot Action Selector +Programming +

+ +

If the oneof does not match the table description in the P4Info (e.g. the +oneof is action_profile_member_id for a direct table), the server must +return an INVALID_ARGUMENT error code. +

+

The Action Protobuf message has the following fields: +

+
    +
  • +

    action_id, which identifies the action instance; the action_id is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an INVALID_ARGUMENT error +code. If the client uses a valid action_id for the table but does not +respect the action scope specified in P4Info (e.g. tries to set a TABLE_ONLY +action as the default action), the server must return a PERMISSION_DENIED +error code. +

  • +
  • +

    params: a repeated Protobuf field of action parameter values, each encoded +as a Param message. For each parameter, param_id must be valid for the +action (as per the P4Info) and value must follow the format described in +Bytestrings. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an INVALID_ARGUMENT error code +if a parameter id is missing, if an extra parameter id not found in the +P4Info was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +Bytestrings format. +

+ +

For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a NOT_FOUND error code. +

9.1.3. Default Entry

+

According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer or defaults to NoAction +(which is a no-op) otherwise and assuming it is not declared as const, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow INSERT and DELETE updates on the default entry and the +P4Runtime server must return an INVALID_ARGUMENT error code if the client +attempts one. +

+

The default entry is identified by setting the is_default_action boolean field +to true. When this flag is set to true, the repeated match field must be empty +and the priority field must be set to zero, otherwise the P4Runtime server +must return an INVALID_ARGUMENT error code. When performing a MODIFY update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its controller_metadata value as well as the configurations for its +direct resources will be reset to their defaults. If +the default entry is constant (as indicated by the P4 program and the P4Info +message), the server must return a PERMISSION_DENIED error code if the client +attempts to modify it. +

+

Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to direct resources. +

+

In this P4Runtime release, we have decided to restrict the default entry for +indirect tables tables with an ActionProfile or ActionSelector +implementation property to a constant NoAction action entry, with the +hope that it would simplify the implementation of the P4Runtime service. +

9.1.4. Constant Tables

+

Constant tables are defined as tables whose match entries are immutable. They +are identified by the is_const_table flag in P4Info. +

+

The only write updates which are allowed for constant tables are MODIFY +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +PERMISSION_DENIED error. Just like any table entry MODIFY request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a PERMISSION_DENIED error. +

+

The contents of const tables can be queried by the client through a +ReadRequest. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: table_id, match, action, +is_default_action, and priority (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the priority field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P416 does not support assigning explicit priorities to static +entries. When a priority value is required (e.g. for tables including RANGE +and / or TERNARY matches in the case of PSA), it is inferred based on the +order in which entries appear in the table declaration. +

9.1.5. Wildcard Reads

+

When performing a ReadRequest, the P4Runtime client can select all entries +from one or all tables on the target and use several of the TableEntry fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as priority and “unset” for message fields such as match. The following +fields may be used to select and filter results: +

+
    +
  • table_id: If default (0), entries from all tables including constant +tables will be selected and no other filter can be used. Otherwise only +the specified table will be considered. +
  • +
  • match: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned. +
  • +
  • action: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an action_id (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id. +
  • +
  • priority: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value. +
  • +
  • controller_metadata: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +controller_metadata value. +
  • +
  • is_default_action: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered. +
+ +

For example, in order to read all entries from all tables from device 3, the +client can use the following ReadRequest message. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0
+    priority: 0
+    controller_metadata: 0
+  }
+}
+

In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following ReadRequest +message: +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+    priority: 11
+    controller_metadata: 0
+  }
+}
+

The canonical representation of “don't care” matches, combined with the ability +to do a wildcard read on all table entries by leaving the match field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single “don't care” entry or to do a wildcard +read. If a table has no fields with match kind EXACT, it is possible via +P4Runtime to add an entry that is “don't care” for all fields (i.e. has an empty +match field) but is not the default entry (i.e. is_default_action is +false). When reading this entry from the table, there is no way to read only +that entry from the table, because it would require providing an unset match +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single LPM match: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: lpm;
+  }
+  actions = {
+    drop; fwd;
+  }
+}
+

The following WriteRequest message can be used to add 2 entries: +

+
+
+
device_id: 3
+entities {
+  table_entry { # don't care entry
+    table_id: 0x0212ab34
+    # ...
+  }
+  table entry {
+    table_id: 0x0212ab34
+    match {
+      field_id: 1
+      lpm {
+        value: 0x0a000000
+        prefix_len: 8
+      }
+    # ...
+  }
+}
+

The first entry is a “don't care” entry, while the second one matches all +10.0.0.0/8 addresses. The second entry has higher priority than the first one. +

+

The following ReadRequest message will return all entries in the table, not +just the “don't care” entry. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+  }
+}
+

This issue also exists for tables with TERNARY and / or RANGE +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the “don't care” entry will be returned to the +client. If the client uses distinct priority values for all entries which is +strongly recommended to achieve deterministic behavior , +then there is no ambiguity because the wildcard read will actually return a +single entry (the “don't care” entry) as long as the priority field is set to +the correct value. +

9.1.6. Direct Resources

+

In addition to the DirectCounterEntry and DirectMeterEntry entities, +P4Runtime support reading and writing direct resources as part of the +TableEntry message. This is convenient for two reasons: +

+
    +
  • +

    A table entry and its direct resources can be read with a single entity when +doing a Read RPC call +

  • +
  • +

    The initial configuration for an entry's direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can “hit” the table entry without +executing the appropriate meter entry. +

+ +

Once the table entry has been inserted, the P4Runtime client is free to use the +DirectCounterEntry and DirectMeterEntry messages for read and write +operations on DirectCounter and DirectMeter instances. For example, it is +usually more convenient as well as more efficient to use DirectCounterEntry to +query a counter entry value rather than use TableEntry, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry. +

+

The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does not need to be “executed” in +every action bound to the table. It is an error to provide a direct resource +configuration in a TableEntry message when programming an action that does not +execute the direct resource, and the server must return an INVALID_ARGUMENT +error code. +

+

We leverage Protobuf's ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the TableEntry message. The list below describes how +the server must handle the meter_config and counter_data fields for read and +write requests, based on whether the fields are set or not. We do not cover +error cases in the list, i.e. we assume that we are dealing with a table which +is assigned a direct counter / a direct meter, and that the action being used +for the table entry “executes” the direct resource appropriately. +

+
    +
  • +

    meter_config field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets). +
      • +
      • if set: The initial configuration for the meter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The meter entry's configuration is reset to the default +(meter returns GREEN for all packets). +
      • +
      • if set: The value provided by the client is used to re-configure +the meter entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the meter entry's +configuration (meter_config is unset in the response). +
      • +
      • if set: If the meter entry's configuration is the default +configuration, meter_config is unset in the response. Otherwise, the +response includes the meter entry's configuration that was written by +the client earlier. This respects the “read-write symmetry” principle. +
    +
  • +
  • +

    counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for the counter entry is the default +(0). +
      • +
      • if set: The initial value for the counter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The counter entry's value is not changed. +
      • +
      • if set: The value provided by the client is written to the counter +entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the counter entry's value +(counter_data is unset in the response). +
      • +
      • if set: The response includes the counter entry's value read from +the target. +
    +
+ +

In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +meter_config field unset when inserting or modifying a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the TableEntry message +(i.e. the meter_config field must be set to match the existing configuration). +

9.1.7. Idle-timeout

+

P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not “hit” (i.e. not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification using the +IdleTimeoutNotification message to the master client, which can then take +action, such as remove the idle table entry. +

+

Two fields of the TableEntry Protobuf message are used to implement idle +timeout: +

+
    +
  • +

    idle_timeout_ns: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, i.e. no +IdleTimeoutNotification message will ever be generated for this entry. When +a client reads a TableEntry, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry. +

  • +
  • +

    time_since_last_hit: a Protobuf message with a single field (elapsed_ns) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The time_since_last_hit field must be unset for a +TableEntry write. When reading a table entry, time_since_last_hit must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0. +

+ +

These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an INVALID_ARGUMENT error code if at least one of these +conditions is met: +

+
    +
  • idle_timeout_ns is set to a non-zero value, or +
  • +
  • time_since_last_hit is set +
+ +

The target should do its best to approximate the idle_timeout_ns value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the TableEntry write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for time_since_last_hit. +

+

P4Runtime does not support idle timeout for default entries. When the +is_default_action flag is set in a TableEntry message, idle_timeout_ns +must be set to 0 (default) and time_since_last_hit must be unset. If the +server receives a TableEntry message which violates this, it must return an +INVALID_ARGUMENT error. +

+

For more information about idle timeout, in particular regarding +IdleTimeoutNotification, please refer to the Table idle timeout +notifications section. +

9.2. ActionProfileMember & ActionProfileGroup

+

P4Runtime defines an API for programming a PSA ActionProfile extern using +ActionProfileMember messages. A PSA ActionSelector extern can be programmed +using both ActionProfileMember and ActionProfileGroup messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table t for L3 routing, implemented with an action +selector as. +

+
+
+
ActionSelector(HashAlgorithm.crc32,
+               /*size = */ 32w1024,
+               /*output_width = */ 32w10) as;
+
+action set_nhop(PortId_t p, EthAddr smac, EthAddr dmac) {
+  istd.egress_port = p;
+  hdr.ethernet.smac = smac;
+  hdr.ethernet.dmac = dmac;
+}
+
+table t {
+  key = {
+    hdr.ipv4.dip: lpm;  // LPM on destination IP address
+  }
+  actions = {
+    set_nhop;
+  }
+  implementation = as;
+}
+

When programming table t in the example above, a P4Runtime client should +specify the TableAction in the TableEntry to be a reference to either an +action profile member or group. The reference is a uint32 identifier that +uniquely identifies a member or group programmed in the action selector as. +

+

If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata. +

+

If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata. +

9.2.1. Action Profile Member Programming

+

Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a uint32 identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the actions +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the actions attributes of the +tables must have an identical list of P4 actions. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector. +

+

An ActionProfileMember entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info. +

  • +
  • +

    member_id is the uint32 identifier of the action profile member entry +being updated. +

  • +
  • +

    action is the specification of the P4 action instance bound to the action +profile member entry. +

+ +

An action profile member may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an ALREADY_EXISTS error +code. The action specification must be provided, or the server must return +INVALID_ARGUMENT. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return RESOURCE_EXHAUSTED. +
  • +
  • MODIFY: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return NOT_FOUND, +and the action specification must be provided, or the server must return +INVALID_ARGUMENT. +
  • +
  • DELETE: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a NOT_FOUND error code. The member +must not be part of an action profile group, or the server must return +FAILED_PRECONDITION. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return FAILED_PRECONDITION. member_id is the only field which is +considered when performing a DELETE and every other field will be ignored. +
+

9.2.2. Action Profile Group Programming

+

Action profile groups are entries in an ActionSelector and are referenced by a +uint32 identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type. +

+

An ActionProfileGroup entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionSelector +extern instance, as defined in P4Info. +

  • +
  • +

    group_id is the uint32 identifier of the action profile group entry being +updated. +

  • +
  • +

    members is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields: +

    +
      +
    • member_id for looking up the member table in the selector. +
    • +
    • weight specifying the probability of the member's selection at +runtime. 0 is not a valid weight value and the server must return +INVALID_ARGUMENT if the client attempts to use it. +
    • +
    • watch is the controller-defined 32-bit port number that the member's +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. +
    +
  • +
  • +

    max_size is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +MODIFY update. See the subsection below for the rules on setting +max_size. +

+ +

An action profile group may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new group entry bound to a set of existing action profile +members. The group_id must be different from ids of already programmed +groups for that selector, or the server must return an ALREADY_EXISTS error +code. All members specified in the group must exist in the selector, or the +server must return NOT_FOUND. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target. +
  • +
  • MODIFY: Modify the member set specification of an existing group entry. An +entry with the group_id must exist, or the server must return +NOT_FOUND. All members specified in the group entry must exist in the +selector, or the server must return NOT_FOUND. The value of max_size must +be identical to the value used when inserting the group, otherwise an +INVALID_ARGUMENT error is returned. +
  • +
  • DELETE: Delete the group entry and deallocate the group_id. The group must +not be referenced in the table action of any table entry, or the server must +return a FAILED_PRECONDITION error code. If the group_id is invalid, the +server must return NOT_FOUND. group_id is the only field which is +considered when performing a DELETE and every other field will be ignored. +
+ +

When setting the group membership with INSERT or MODIFY, the members +repeated field must not include duplicates, i.e. members with the same +member_id. The weight field is used instead to logically “repeat” the member +inside the group. +

+

It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation “stores” the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made. +

9.2.2.1. Rules on Setting max_size
+

The valid values for max_size depend on the static max_group_size included +in the P4Info message: +

+
    +
  • +

    If max_group_size is greater than 0, then max_size must be greater than 0, +and less than or equal to max_group_size. We assume that the target can +support selector groups for which the sum of all member weights is up to +max_group_size, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If max_size is greater than max_group_size, the server +must return INVALID_ARGUMENT. +

  • +
  • +

    Otherwise (i.e. if max_group_size is 0), the P4Runtime client can set +max_size to any value greater than or equal to 0. +

    +
      +
    • +

      A max_size of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (INSERT or MODIFY), the target must return a +RESOURCE_EXHAUSTED error. +

    • +
    • +

      If max_size is greater than 0 and the value is not supported by the +target, the server must return a RESOURCE_EXHAUSTED error at +group-creation time. +

    +
+

9.2.3. One Shot Action Selector Programming

+

P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids. +

+

One shots are programmed by choosing the ActionProfileActionSet message as the +TableAction. The ActionProfileActionSet message consists of a set of +ActionProfileAction messages, which in turn have the following fields: +

+
    +
  • +

    action is one of the actions specified by the table that is being +programmed. +

  • +
  • +

    weight specifying the probability of the action's selection at runtime. 0 is +not a valid weight value and the server must return INVALID_ARGUMENT if +the client attempts to use it. The sum of all weights across all +ActionProfileAction messages for that ActionProfileActionSet message must +not exceed the max_group_size specificed in the P4Info (if greater than 0), +or the server must return INVALID_ARGUMENT. +

  • +
  • +

    watch is the controller-defined 32-bit port number that the action's +liveness depends on. At runtime, the action must be excluded from selection if +the watch port is down. +

+ +

Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics. +

+

To preserve read-write symmetry, an implementation must answer ReadRequests +with the original one shot messages. It may not return a desugared version of +the one shot message. +

+

For example, consider the action selector table defined +here. This table could be programmed +with the following one shot update: +

+
+
+
table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action {
+    action_profile_action_set {
+      action_profile_actions {
+        action { /* set nexthop 1 */ }
+        weight: 1
+        watch: 1
+      }
+      action_profile_actions {
+        action { /* set nexthop 2 */ }
+        weight: 2
+        watch: 2
+      }
+      action_profile_actions {
+        action { /* set nexthop 3 */ }
+        weight: 3
+        watch: 3
+      }
+    }
+  }
+}
+

Which would be equivalent to the following updates, where GROUP_ID, +MEMBER_ID_1, MEMBER_ID_2, and MEMBER_ID_3 are unused ids: +

+
+
+
action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_1
+  action { /* set nexthop 1 */ }
+}
+action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_2
+  action { /* set nexthop 2 */ }
+}
+action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_3
+  action {  /* set nexthop 3 */ }
+}
+action_profile_group {
+  action_profile_id: 0x11ab12cd
+  group_id: GROUP_ID
+  members {
+    member_id: MEMBER_ID_1
+    weight: 1
+    watch: 1
+  }
+  members {
+    member_id: MEMBER_ID_2
+    weight: 2
+    watch: 2
+  }
+  members {
+    member_id: MEMBER_ID_3
+    weight: 3
+    watch: 3
+  }
+}
+table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action { action_profile_group_id: GROUP_ID }
+}
+

Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure correct ordering between the dependent +updates. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct WriteRequest batches are required. +

+

It is possible to include several ActionProfileAction messages with the same +exact action specification in one ActionProfileActionSet message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the weight field. Note that to preserve read-write symmetry, the server +must not coalesce multiple ActionProfileAction messages with the same action +specification into one. +

+

All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with ActionProfileMember and +ActionProfileGroup messages. Programming some entries with one shots, and +other entries with ActionProfileMember and ActionProfileGroup messages is +not allowed, and the server must return the error code INVALID_ARGUMENT in +that case. +

+

A P4Runtime server must support the one shot style of programming tables with +an action selector implementation. Support for the ActionProfileMember and +ActionProfileGroup style is optional. If ActionProfileMember and +ActionProfileGroup are not supported by a server, it must return an +UNIMPLEMENTED error for every ActionProfileMember or ActionProfileGroup +message that it receives. +

9.2.4. Constraints on action selector programming

+

The PSA specification states that the following features are optional in +action selector implementations [21]: +

+
    +
  1. Support for non-empty groups where in the same group, different members are +bound to different actions. +
  2. +
  3. Predictable data plane behavior when a matched table entry points to an empty +group. +
+ +

For 1., if a client tries to INSERT or MODIFY a group with members bound to +different actions, the server should return UNIMPLEMENTED if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return UNIMPLEMENTED (modifying the action parameter values must be +supported, however). +

+

PSA 1.1 introduces the psa_empty_group_action table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. psa_empty_group_action is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of psa_empty_group_action at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +NoAction. Even when psa_empty_group_action is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of psa_empty_group_action mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming. +

+

The PSA specification includes a discussion on how to implement +psa_empty_group_action in software in the P4Runtime server +[24]. +

9.3. CounterEntry & DirectCounterEntry

+

PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The CounterData +P4Runtime message can be used for all three types of PSA counters PACKETS, +BYTES and PACKETS_AND_BYTES and consists of the following fields: +

+
    +
  • byte_count is an int64, corresponding to the number of octets. +
  • +
  • packet_count is an int64, corresponding to the number of packets. +
+ +
+
+
message CounterData {
+  int64 byte_count = 1;
+  int64 packet_count = 2;
+}
+

P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of byte_count and packet_count fields, which +is equivalent to specifying the counter type PACKETS_AND_BYTES. Counters may +be defined as direct or indirect (indexed) instances. +

9.3.1. DirectCounterEntry

+

A direct counter is a direct resource associated with a TableEntry (see +Direct Resources). The counter_data field of the +TableEntry message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +DirectCounterEntry message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed. +

+
+
+
message DirectCounterEntry {
+  TableEntry table_entry = 1;
+  CounterData data = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectCounterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match TableEntry.match of the table entry +to which this direct counter entry is associated. If a matching TableEntry +is not found, the server returns the error code NOT_FOUND. +

  • +
  • +

    data is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified. +

+ +

Specifying DirectCounterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read the contents of a +DirectCounter: +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the counter value in the counter_data field of the TableEntry message +(see Direct resources). +

  • +
  • +

    Explicitly request the counter value by including the DirectCounterEntry in +the ReadRequest. The table_entry.match field must match the TableEntry +whose counter is being read. If no such entry is found, the server returns the +error code NOT_FOUND. +

+

9.3.2. CounterEntry

+

An indirect or indexed counter is not associated with a specific TableEntry +and may be updated independently of any action. It may be read or written using +the P4Runtime CounterEntry message whose fields are defined as follows: +

+
    +
  • +

    counter_id is a uint32, the unique identifier for the counter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +the counter array. +

  • +
  • +

    data is a Protobuf message of type CounterData, which represents the +counter value. +

+ +
+
+
message CounterEntry {
+  uint32 counter_id = 1;
+  Index index = 2;
+  CounterData data = 3;
+}
+

The CounterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the counter entries in the +array have default value 0. +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect counter instance whose unique id is counter_id +and array index is specified by index. The counter value is set to the value +specified by the client in the data field. Note that the counter value is +not modified if this Protobuf field is not set. If index is omitted all +counter values in the array will be set to the value provided by the +client. The server must return INVALID_ARGUMENT for a negative index value +and OUT_OF_RANGE if the index value exceeds the size of the counter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a ReadRequest by including a CounterEntry +entity for each of the instances, specifying the counter_id and +index. Wildcard reads are also supported as follows. +

+
    +
  • +

    If the counter_id field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id counter_id. +

+

9.4. MeterEntry & DirectMeterEntry

+

Meters are an advanced mechanism for keeping statistics, involving stateful +“marking” and usually “throttling” of packets based on configured rates of +traffic. The PSA metering function is based on the Two Rate Three Color Marker +(trTCM) defined in RFC 2698 [2]. The trTCM meters an arbitrary packet +stream using two configured rates the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes and +“marks” its packets as GREEN, YELLOW or RED based on the observed rate. +

+

A meter may be configured as a direct or indirect instance, similar to a +counter. The MeterConfig P4Runtime message represents meter configuration. +

+
+
+
message MeterConfig {
+  int64 cir = 1;  // Committed Information Rate
+  int64 cburst = 2;  // Committed Burst Size
+  int64 pir = 3;  // Peak Information Rate
+  int64 pburst = 4;  // Peak Burst Size
+}

9.4.1. DirectMeterEntry

+

A direct meter is a direct resource associated with a TableEntry (see Direct +resources). The meter_config field of the TableEntry +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +DirectMeterEntry message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed. +

+
+
+
message DirectMeterEntry {
+  TableEntry table_entry = 1;
+  MeterConfig config = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectMeterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match the match key of the TableEntry +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching TableEntry is not found, +the server returns the error code NOT_FOUND. +

  • +
  • +

    config is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets). +

+ +

Specifying DirectMeterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read a DirectMeter config. +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the meter config in the meter_config field of the TableEntry +message (see Direct resources). +

  • +
  • +

    Explicitly request the meter configuration by including the DirectMeterEntry +in the ReadRequest. The table_entry.match field must match the +TableEntry whose meter config is being read. If no such entry is found, the +server returns the error code NOT_FOUND. +

+

9.4.2. MeterEntry

+

An indirect or indexed meter is not associated with a specific TableEntry and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime MeterEntry message whose fields are defined as +follows: +

+
    +
  • +

    meter_id is a uint32, the unique identifier for the meter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +a meter array. +

  • +
  • +

    config is a Protobuf message of type MeterConfig, which represents the +meter configuration. +

+ +
+
+
message MeterEntry {
+  uint32 meter_id = 1;
+  Index index = 2;
+  MeterConfig config = 3;
+}
+

The MeterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the meter entries in the +array have a default configuration (GREEN for all packets). +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect meter instance whose unique id is meter_id and +array index is specified by index. The meter is reconfigured using the +config field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the index field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if config is unset). The server must return INVALID_ARGUMENT for a +negative index value and OUT_OF_RANGE if the index value exceeds the size of +the meter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a ReadRequest by including a MeterEntry entity for each +of the instances, specifying the meter_id and index. Wildcard reads are also +supported as follows: +

+
    +
  • +

    If the meter_id field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id meter_id. +

+

9.5. PacketReplicationEngineEntry

+

The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets. +

9.5.1. MulticastGroupEntry

+

Multicasting is achieved in PSA programs by setting the multicast_group +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the MulticastGroupEntry API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example. +

+
+
+
control arp_multicast(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ethernet.isValid() &&
+        hdr.ethernet.eth_type == ETH_TYPE_ARP) {
+      smeta.multicast_group = (MulticastGroup_t) 1;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    multicast_group_entry {
+      multicast_group_id: 1
+      replicas { egress_port: 5 instance: 1 }
+      replicas { egress_port: 12 instance: 2 }
+      replicas { egress_port: 18 instance: 3 }
+      replicas { egress_port: 24 instance: 4 }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +PSA Metadata Translation section. +

+

The egress packets may be distinguished for further processing in the egress +using the instance metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 multicast_group metadata is set to a value that is not +programmed in the PRE, then the packet is dropped. +

+

A multicast group may be inserted, modified or deleted as per the following +semantics. +

+
    +
  • INSERT: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The multicast_group_id field is a uint32 and must be greater +than 0 (see explanation below), or the +P4Runtime server must return an INVALID_ARGUMENT error. The replica +instance ID is also a uint32, and its value may not exceed the maximum +allowed by the target for the EgressInstance_t type (0 is allowed), or the +server must return an INVALID_ARGUMENT error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of both egress_port and instance, or the server +must return INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify the set of replicas for a given multicast group entry, +indexed by the given multicast_group_id. Same restrictions as INSERT apply +here. +
  • +
  • DELETE: Delete the multicast group indexed by the given +multicast_group_id. The replicas need not be provided for this +operation. Any packets with their multicast_group metadata in the data plane +set to the deleted multicast_group_id will be dropped. +
+ +

When reading a multicast group, only multicast_group_id is considered. All +other fields in MulticastGroupEntry are ignored. To perform a wildcard +Read on all configured multicast group entries, the multicast_group_id field +must be set to 0, its default value. +

9.5.1.1. Valid Values for multicast_group_id
+

The PSA specification states that the valid data plane values for multicast +group ids (MulticastGroup_t) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target [23]. This means that, in the absence of +translation, the client must set the multicast_group_id field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special wildcard value which is used to read all the multicast groups +configured in the target, the multicast_group_id field must never be set to 0 +when performing a Write RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value. +

9.5.2. CloneSessionEntry

+

PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +clone_session_id identifier and a boolean flag clone in the packet +metadata. The clone_session_id serves as a handle to the clone attributes, +namely a set replicas of (egress port, instance) pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +CloneSessionEntry API. +

+

The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the clone_low_ttl control block is applied in the ingress +pipeline to create an ingress-to-egress clone. +

+
+
+
control clone_low_ttl(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ipv4.isValid() &&
+        hdr.ipv4.ttl <= LOW_TTL_THRESHOLD) {
+      smeta.clone_session_id = 10w100;
+      smeta.clone = true;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    clone_session_entry {
+      session_id: 100
+      replicas { egress_port: 0xfffffffd instance: 1 } # to CPU
+      class_of_service: 2
+      packet_length_bytes: 4096
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type CloneSessionId_t [23]). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes. +

+

The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port 0xfffffffd; see +Translation of Port Numbers). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port. +

+

If the clone_session_id data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created. +

+

A clone session may be inserted, modified or deleted as per the following +semantics: +

+
    +
  • INSERT: Add a new clone session entry bound to a set of egress ports and +replica IDs. The session_id is a uint32 and must be greater than 0 (see +explanation below), or the P4Runtime +server must return an INVALID_ARGUMENT error. The replica instance ID is +also a uint32, and its value may not exceed the maximum allowed by the +target for the EgressInstance_t type (0 is allowed), or the server must also +return an INVALID_ARGUMENT error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (class_of_service field). This value must be a valid +value for the PSA ClassOfService_t type, which supports runtime translation +by default [23], or the server must return +INVALID_ARGUMENT. See PSA Metadata +Translation for more information. The +packet_length_bytes field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +packet_length_bytes field is 0 (default), no truncation on the clone will be +performed. +
  • +
  • MODIFY: Modify the attributes of a given clone session entry, indexed by the +given clone_session_id. Same restrictions as INSERT apply here. +
  • +
  • DELETE: Delete the clone session indexed by the given +clone_session_id. Other fields need not be provided for this operation. Any +packet with their clone_session_id metadata in the data plane set to the +deleted session_id will no longer be cloned. +
+ +

When reading a clone session, only session_id is considered. All other fields +in CloneSessionEntry are ignored. To perform a wildcard Read on all +configured clone session entries, the session_id field must be set to 0, its +default value. The session_id field can never be equal to 0 in a Write +RPC. If it does, the server must return an INVALID_ARGUMENT error. +

9.5.2.1. Valid Values for session_id
+

The PSA specification states that the valid data plane values for clone +session ids (CloneSessionId_t) range from 0 to the maximum value supported by +the target [23]. Note that unlike for multicast group +ids, 0 is a valid data plane value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special wildcard value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a session_id +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is not enabled, we effectively +“lose” one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (e.g. because the target supports a very +limited number of clone sessions), one can enable translation on +CloneSessionId_t and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id. +

9.6. ValueSetEntry

+

Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the parse_trill_types state. +

+
+
+
state parse_l2 {
+  @id(1) value_set<ETH_TYPE_BITWIDTH>(MAX_TRILL_TYPES) trill_types;
+  extract(hdr.ethernet);
+  select (hdr.ethernet.eth_type) {
+    ETH_TYPE_IPV4: parse_ipv4;
+    ETH_TYPE_IPV6: parse_ipv6;
+    trill_types:   parse_trill_types;
+    _:             reject;
+  }
+}
+

The corresponding entry in the P4Info for this Value Set is: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "trill_types"
+  }
+  match {
+    id: 1
+    bitwidth: <ETH_TYPE_BITWIDTH>
+    match_type: EXACT
+  }
+  size: <MAX_TRILL_TYPES>
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0x22f3 }
+      }
+      match {
+        field_id: 1
+        exact { value: 0x893b }
+      }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the parse_trill_types state. +

+

A ValueSetEntry entity update message has the following fields: +

+
    +
  • +

    value_set_id is the uint32 identifier of the Value Set instance, as +defined in P4Info. +

  • +
  • +

    members is a repeated field of type ValueSetMember. When “selecting” +against a Value Set, every member will be considered and if at least one +“matches”, the corresponding parser transition will be taken. Each +ValueSetMember contains a repeated field of FieldMatch messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a ValueSetMember if and only if +it matches all its FieldMatch messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. FieldMatch messages in a ValueSetEntry follow +the same rules as in a TableEntry. +

+ +

A ValueSetEntry may only be modified. If the update type is INSERT or +DELETE, the server must return an INVALID_ARGUMENT error. If the update type +is MODIFY, the server writes the members given in the repeated field to the +Value Set entry indexed by the given value_set_id. The maximum number of +matches must not exceed the maximum size given by the size field in P4Info of +the Value Set, otherwise the server must return a RESOURCE_EXHAUSTED error. To +empty a Value Set (i.e. restore it to its initial state), the P4Runtime client +can perform a MODIFY update with an empty members repeated field. +

+

To facilitate read-write symmetry, the server must +return an ALREADY_EXISTS error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary and range matches: +overlapping entries do not need to be ordered and the parse state transition +is determined by whether or not the packet matches at least one entry in the +set. +

+

See Appendix A.3 for a more complex Value Set example. +

9.7. RegisterEntry

+

The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The RegisterEntry P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations. +

+

RegisterEntry has the following fields: +

+
    +
  • +

    register_id, which identifies the PSA Register extern instance which is +being accessed by the client; the register_id is specified by the P4Info +message. +

  • +
  • +

    index, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the RegisterEntry message +used for the request. When an index is provided , the server must validate +its value, and return INVALID_ARGUMENT for a negative index or +OUT_OF_RANGE if the index exceeds the size of the register array. +

  • +
  • +

    data: the data to be written to the array (if RegisterEntry is part of a +WriteRequest message) or the data read from the array (if RegisterEntry is +part of a ReadResponse message). The data field is a P4Data message and +must match the format described by the type_spec field of the corresponding +Register entry in the P4Info, or the server must return an INVALID_ARGUMENT +error. +

+

9.8. DigestEntry

+

A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly. +

+

The DigestEntry P4Runtime entity is used to configure how the device must +generate digest messages. The DigestEntry Protobuf message is not used to +carry digest data, which is done on the StreamChannel bidirectional stream +using the DigestList (digest data sent by the target to the client) and +DigestListAck (digest data acknowledgments sent by the client to the target) +Protobuf messages. +

+

In this section, we refer to the data learned by a single data plane call to +Digest<T>::pack as a “digest message” and we use “digest list” to designate +the list of digest messages bundled by the P4Runtime service in a single +DigestList stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are “duplicate” if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are “distinct” +if they are not duplicate. +

+

DigestEntry has the following fields: +

+
    +
  • +

    digest_id, which identifies the PSA Digest extern instance which emitted the +data; the digest_id is determined by the P4Info message. +

  • +
  • +

    config, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +digest_id; these parameters are: +

    +
      +
    • max_timeout_ns: the maximum server buffering delay in nanoseconds for an +outstanding digest message. +
    • +
    • max_list_size: the maximum digest list size in number of digest +messages sent by the server to the client as a single DigestList +Protobuf message. +
    • +
    • ack_timeout_ns: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data. +
    +
+ +

Here is the significance of the different Update types for DigestEntry: +

+
    +
  • INSERT: Enable server generation of DigestList messages for given digest +instance and use provided configuration parameters. +
  • +
  • MODIFY: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance. +
  • +
  • DELETE: Disable server generation of DigestList messages for given digest +instance. +
+ +

A server should buffer digest messages until either: +

+
    +
  • max_timeout_ns time has passed since the first digest message was added to +the empty buffer, or +
  • +
  • max_list_size distinct digest messages have been received from the +data plane and added to the buffer +
+ +

At which point the server should, with best effort, generate a DigestList +stream message with the buffer contents and send it to the master client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software. +

+

To avoid sending duplicate digest messages across different DigestList +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the master client indicates that it has received the +digest list and acted on it. The server must keep a “cache” containing the set +of all digest messages that have been sent, but not acknowledged yet by the +master client, up-to ack_timeout_ns in the past. The server must delete all +cache entries for a given digest list when they are at least ack_timeout_ns +old or when a matching DigestListAck message (i.e. with the same digest_id +and list_id fields as the DigestList message) is received. +

+

The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged DigestList messages. +

+

When max_timeout_ns is set to 0 and / or max_list_size is set to 1, the +server should, with best effort, generate a DigestList message for every +digest message generated by the data plane which is not already in the cache. If +ack_timeout_ns is set to 0, the cache must always be an empty set. If +max_list_size is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +max_timeout_ns configuration parameter. +

+

The P4Runtime server may empty the digest message cache in case of a client +mastership change. +

+

Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server: +

+
+
+
DigestStream stream;
+DigestCache cache;
+DigestBuffer buffers;
+
+// sends digest list when it is ready
+send_buffer(Id digest_id) {
+  buffer = buffers[digest_id];
+  stream.write(DigestList(buffer));
+  cache.merge(buffer);  // updates cache with new digest list
+  buffer.clear();
+}
+
+// callback which handles data plane digest messages from device
+handle_dataplane_digest(Digest msg) {
+  digest_id = msg.digest_id();
+  buffer = buffers[digest_id];
+  if (msg in cache OR msg in buffer) return;
+  buffer.enqueue(msg);
+  if (buffer.length() < max_list_size(digest_id)) return;
+  send_buffer(digest_id);
+}
+
+// callback which handles ack messages received on the stream
+handle_stream_ack(DigestListAck ack) {
+  // clear all cache entries matching the tuple (digest_id, list_id)
+  cache.erase( (ack.digest_id(), ack.list_id() )
+}
+
+// loop to enforce timeouts
+while (true) {
+  now = now();
+  // check for buffers that need to be sent
+  for ((digest_id, buffer) in buffers) {
+    if (now - buffer.first_enq_time() >= max_timeout_ns(digest_id))
+      send_buffer(buffer_id);
+  }
+  // check for expired entries in cache
+  for ((digest_id, list_id, sent_time) in cache) {
+    if (now - sent_time >= ack_timeout_ns(digest_id))
+      cache.erase( (digest_id, list_id) );
+  }
+  sleep(X);
+}

9.9. ExternEntry

+

This is used to support a P4 extern entity that is not part of PSA. It is +defined as: +

+
+
+
message ExternEntry {
+  uint32 extern_type_id = 1;
+  uint32 extern_id = 2;
+  google.protobuf.Any entry = 3;
+}
+

Each ExternEntry entity maps to an Extern message in the +P4Info and an ExternInstance message within that +message. The extern_type_id field must be equal to the one in +ExternEntry. The extern_id field must be equal to the ID included in the +preamble of the corresponding ExternInstance message. +

+

entry itself is embedded as an Any Protobuf message [30] to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on Extending P4Runtime for non-PSA +Architectures for more information. +

10. Error Reporting Messages

+

P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case. +

+

gRPC uses grpc::Status [31] to represent the status returned by an +RPC. It has 3 attributes: +

+
+
+
StatusCode code_;
+grpc::string error_message_;
+grpc::string binary_error_details_;
+

The code_ represents a canonical error [33] and describes the +overall RPC status. The error_message_ is a developer-facing error message, +which should be in English. The binary_error_details_ carries a serialized +google.rpc.Status message [27] message, which has 3 fields: +

+
+
+
int32 code = 1;  // see code.proto
+string message = 2;
+repeated google.protobuf.Any details = 3;
+

The code and message fields must be the same as code_ and error_message_ +fields from grpc::Status above. The details field is a list that consists of +p4.Error messages that carry error details for individual elements inside +batch-request RPCs (e.g. Write and Read). p4.Error includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices [33]. +

+

Figure 7 illustrates how these messages fit together. +

+
+

error-report +

+
+ +
Figure 7. P4Runtime Error Report Message Format
+

gRPC provides utility functions ExtractErrorDetails() and SetErrorDetails() +[32] to easily convert between grpc::Status and +google.rpc.Status. +

+

Please see sections on individual P4Runtime RPCs for details on how +grpc::Status is populated for reporting errors. +

+

Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on Stream Error +Reporting for more information. +

11. Atomicity of Individual Write and Read Operations

+

Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane apply +operation, and every single Write operation on a table that inserts, deletes, +or modifies one table entry, the apply operation should behave as if that +Write operation has not yet occurred, or as if the Write operation is +complete. The P4 program should never behave as if the Write operation is +partially complete. These guarantees also apply to extern instances: Read and +Write operations on extern entities must execute atomically relative to extern +data plane methods. +

+

The atomicity guarantees provided by P4Runtime for individual Read and Write +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification [22]. +

+

The P416 language introduces an @atomic annotation [13], to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the @atomic annotation for Write +operations, as well as non-wildcard Read operations, +relative to data plane execution. Consider the following P4 example written for +PSA: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024) r1;
+
+  apply {
+    // ...
+    @atomic {
+        Value_t v = r1.read((Index_t)1);
+        v = v + 1;
+        r1.write((Index_t)1, v);
+    }
+  }
+}
+

If a P4Runtime server is processing messages which write to Register r1 at +index 1, these writes must not happen between the data plane read and +write. +

+

Now let's consider the following example: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024, (Value_t)0 /* initial value */) r1;
+
+  apply {
+    @atomic {
+        r1.write((Index_t)1, (Value_t)100);
+        r1.write((Index_t)2, (Value_t)100);
+    }
+    @atomic {
+        r1.write((Index_t)1, (Value_t)200);
+        r1.write((Index_t)2, (Value_t)200);
+    }
+  }
+}
+

If a P4Runtime client issues a wildcard Read on Register r1, there is no +guarantee that r1[1] == r1[2] in the response, as the read for r1[1] may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for r1[2] may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read r1[1] and r1[2] separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +ReadRequest message) of individual read requests. Similar to a batch +ReadRequest, a wildcard read of a register can execute the reads of the +register array elements (r1[1], r1[2], ) in an arbitrary order relative +to each other. +

+

If the @atomic annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program. +

12. Write RPC

+

The Write RPC updates one or more P4 entities on the target. The request is +defined as follows: +

+
+
+
message WriteRequest {
+  uint64 device_id = 1;
+  uint64 role_id = 2;
+  Uint128 election_id = 3;
+  repeated Update updates = 4;
+  enum Atomicity {
+    CONTINUE_ON_ERROR = 0;
+    ROLLBACK_ON_ERROR = 1;
+    DATAPLANE_ATOMIC = 2;
+  }
+  Atomicity atomicity = 5;
+}
+

The device_id uniquely identifies the target P4 device. The role_id and +election_id define the client role and election-id as described in the +Master-Slave Arbitration and Controller +Replication +section. The server is expected to perform the following checks (in this order) +before processing the updates list: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role_id does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the master for (device_id, role_id) according to the +election_id value, the server must return a PERMISSION_DENIED error. +

  4. +
  5. +

    If the Write is attempted before a ForwardingPipelineConfig has been set, +the server must return a FAILED_PRECONDITION error. +

+ +

The updates field is a list of P4 entity updates to be applied. Each update is +defined as: +

+
+
+
message Update {
+  enum Type {
+    UNSPECIFIED = 0;
+    INSERT = 1;
+    MODIFY = 2;
+    DELETE = 3;
+  }
+  Type type = 1;
+  Entity entity = 2;
+}
+

This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a logical table (e.g. +CounterEntry) or an actual table (e.g. TableEntry) in the P4 data +plane. Each entity in the container is uniquely identified by its key. Please +refer to the P4 Entity Messages section for details on +what parts of the entity specification make up the key for each P4 entity. +

+

An update can be one of the following types: +

+
    +
  • +

    INSERT: Inserts the given P4 entity in the entity container. +The entity field always specifies the full state of the P4 entity. +If the entity already exists, an ALREADY_EXISTS error is returned, and +the existing entity remains unchanged. +If the entity is malformed, an INVALID_ARGUMENT error is returned. +If the entity cannot be inserted because the container is already full, +a RESOURCE_EXHAUSTED error is returned. +

  • +
  • +

    MODIFY: Modifies the P4 entity to its new specified state. This uses +assign or full-snapshot semantics, i.e. the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an INVALID_ARGUMENT error is usually returned (unless a +more specific error code applies [33]). If the entity does not +exist, a NOT_FOUND error is returned. +

  • +
  • +

    DELETE: Deletes the specified P4 entity. If the entity does not exist, a +NOT_FOUND error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored. +

+ +

If an update is not allowed under the given controller role, the server must +return a PERMISSION_DENIED error for this update. +

12.1. Batching and Ordering of Updates

+

P4Runtime supports batching of Write operations. The list of updates in a +WriteRequest is referred to as a batch. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of TableEntry entities). +

+

The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +WriteRequests can also be processed interleaved and/or in parallel. +However, the processing of requests must be strictly serializable. That +is, given a history $S$ of WriteRequests including the responses to those +requests, there must exist an order $L$ for all updates in $S$, such that: +

+
    +
  1. All updates from the same write request must appear as a contiguous +subsequence in $L$, but the order within that subsequence can be arbitrary. +
  2. +
  3. For two updates $u_1$ and $u_2$, if the write request containing $u_1$ +completed before the write request of $u_2$ was sent, then $u_1$ must appear +before $u_2$ in $L$. +
  4. +
  5. Executing all updates in $L$ sequentially must yield the same response for +every update as in $S$. +
  6. +
  7. The observable state of the switch after $S$ (e.g., through the Read RPC) +is identical to the one obtained by sequentially executing $L$. +
+ +

The Write RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the Write RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (e.g. inserting an ActionProfileMember +followed by pointing a TableEntry to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding Write RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate Write calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each Write call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one. +

12.2. Batch Atomicity

+

A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the Atomicity +enum. A P4Runtime server is required to support only the modes marked as +Required below: +

+
    +
  • +

    Required: CONTINUE_ON_ERROR: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that see each of +these intermediate stages. +

  • +
  • +

    Optional: ROLLBACK_ON_ERROR: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is all-or-none, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that see each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure. +

    +

    If a P4Runtime server does not support this option at all, an +UNIMPLEMENTED error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (e.g. it is +more straightforward to implement batches that contain only INSERT +operations, vs. those that contain DELETE operations), an +UNIMPLEMENTED error is returned when the batch cannot be executed +in a data plane-atomic way. +

  • +
  • +

    Optional: DATAPLANE_ATOMIC: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +transaction. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane's table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table. +

    +

    If a P4Runtime server does not support this option at all, an UNIMPLEMENTED +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an UNIMPLEMENTED error is returned when the batch +cannot be executed in a data plane-atomic way. +

+ +

There is no expectation that a given client must always use the same Atomicity +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use DATAPLANE_ATOMIC at one time and default behavior +(CONTINUE_ON_ERROR) at other times. +

12.3. Error Reporting

+

Please see section Error Reporting Messages for +information on error reporting messages and guidelines. P4Runtime server will +populate grpc::Status as follows: +

+
    +
  1. +

    If all batch updates succeeded, set grpc::Status::code_ to OK and do not +populate any other field. +

  2. +
  3. +

    If an error is encountered before even trying to attempt individual batch +updates, set grpc::Status::code_ that best describes that RPC-wide +error. For example, use UNAVAILABLE if the P4Runtime service is not yet +ready to handle requests. Set error_message_ to describe the issue. Do not +set error_details in this case. +

  4. +
  5. +

    Otherwise, if one or more updates in the batch (WriteRequest.updates) +failed, set grpc::Status::code_ to UNKNOWN. For example, one update in +the batch may fail with RESOURCE_EXHAUSTED and another with +INVALID_ARGUMENT. A p4.Error message is used to capture the status of +each and every update in the batch. The number of p4.Error messages packed +into google.rpc.Status.details field should therefore always match the +number of updates in the WriteRequest, and the order of +p4.Error messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +p4.Error should set the code to OK and omit other fields. +

+ +
+
+
# Example of a grpc::Status returned for a Write RPC with a batch of 3 updates.
+# The first and third updates encountered an error, while the second update
+# succeeded.
+code_ = 2  # UNKNOWN
+error_message_ = "Write failure."
+binary_error_details {
+  code: 2  # UNKNOWN
+  message: "Write failure."
+  details {
+    canonical_code: 8  # RESOURCE_EXHAUSTED
+    message: "Table is full."
+    space: "targetX-psa-vendorY"
+    code: 500  # ERR_TABLE_FULL
+  }
+  details {
+    canonical_code: 0  # OK
+  }
+  details {
+    canonical_code: 6  # ALREADY_EXISTS
+    message: "Entity already exists."
+    space: "targetX-psa-vendorY"
+    code: 600  # ERR_ENTITY_ALREADY_EXISTS
+  }
+}

13. Read RPC

+

The Read RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as: +

+
+
+
message ReadRequest {
+  uint64 device_id = 1;
+  repeated Entity entities = 2;
+}
+

The device_id uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +NOT_FOUND error. The entities repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server. +

+

Since ReadRequests do not mutate any state on the switch, they do not +require an election_id, and they do not require the presence of an open +StreamChannel between the server and client. +

+

The Read response consists of a sequence of messages (a gRPC stream) with +each message defined as: +

+
+
+
message ReadResponse {
+  repeated Entity entities = 1;
+}
+

The entities repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the Finish() method on the stream object +[10]). +

13.1. Nomenclature

+
+
request
+
An element of the p4.ReadRequest.entities repeated field. +
+
batch
+
Refers to the p4.ReadRequest.entities repeated field.
+

Each request acts as a query filter for that entity type. If a request fully +specifies the entity key, the Read operation should retrieve a single P4 +entity. Please refer to the P4 Entity Messages section +for details on what parts of the entity specification make up the entity key. +

13.2. Wildcard Reads

+

P4Runtime allows wildcard read of P4 entities. A request may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the P4 Entity Messages section for details on +what parts of the entity can be wildcarded in a given request. +

+

For example, in a request of type CounterEntry: +

+
    +
  • A default counter_id (0) implies a request to read all counter-entries for +all indirect counters. +
  • +
  • A particular (non-default) counter_id in conjunction with index unset +implies a request to read all counter-entries for the given indirect counter +ID. +
+ +

To read the entire forwarding state for a given device, the P4Runtime client can +generate the following ReadRequest: +

+
+
+
device_id: <ID>
+entities {
+  extern_entry { }  # read all extern instances for all supported extern types
+  table_entry { }  # read all table entries for all tables
+  action_profile_member { }  # read all members for all action profiles
+  action_profile_group { }  # read all groups for all action profiles
+  ...
+}
+

The entity oneof field in the Entity message must always be set, or the +server must return an INVALID_ARGUMENT error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty Entity message in the ReadRequest. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the entity oneof [19]. +

13.3. Batch Processing

+

A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type request +appears only once in the batch. +

+

A P4Runtime server will process the batch as follows: +

+
    +
  1. +

    Lock state (preventing new writes) and validate each request in the batch: +

    +
      +
    1. +

      If it is a valid request, perform the read; +

      +
        +
      1. If the read was successful, return the entities read in +ReadResponse stream. +
      2. +
      3. If the read failed (exception / critical-error), prepare a p4.Error +with code set to INTERNAL. +
      +
    2. +
    3. +

      If the request is invalid (invalid-argument, not-supported, etc.), +prepare a p4.Error with relevant canonical code to capture the error. +

    +
  2. +
  3. +

    Unlock the state (allowing new writes); +

  4. +
  5. +

    Close the ReadResponse stream and return a grpc::Status as follows: +

    +
      +
    1. +

      If no errors were encountered, set code to OK and do not populate any +other field. +

    2. +
    3. +

      Otherwise, the overall code should be set to UNKNOWN. See section +Error Reporting Messages for information +on error reporting messages and guidelines. Assemble a list of p4.Error +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +google.rpc.Status.details field. This behavior also matches Write +RPC. +

    +
+

13.3.1. Example

+

If a client asked to read {a,b,c,d} and b and d requests didn't +validate, the server will return entities corresponding to a and c, followed +by a status {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} in the +details field. +

+

The P4Runtime server is not required to perform any optimization (e.g. merge two +requests in the batch if one is a subset of other). As a result of this, it +is possible for the ReadResponse to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging. +

+

There is no requirement that each request in the batch will correspond to one +ReadResponse message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit. +

+

A P4Runtime server must be prepared to handle multiple concurrent Read RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (e.g. in a single-threaded architecture), it may choose to serialize +Read RPC processing. +

13.4. Parallelism of Read and Write Requests

+

A P4Runtime server may be implemented to serve at most one +ReadRequest or WriteRequest message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so. +

+

For example, imagine a client that wanted to use WriteRequest +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +WriteRequest messages with only a few updates to an ActionSelector +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +WriteRequest batch currently being processed, but it will not +complete for a significant amount of time. +

+

The restrictions on which a client may rely are: +

+
    +
  • The processing of any two WriteRequest messages W1 and W2 must +result in the same state as if one of them was completed before the +other began. +
  • +
  • For any WriteRequest W and any ReadRequest R, R must +return results consistent with a state where W has completed +processing, or W has not yet begun processing. +
+ +

For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a WriteRequest message it acquired a write lock for each stateful +object affected by the WriteRequest, and before starting the +processing of a ReadRequest message it acquired a read lock for each +stateful object accessed by the ReadRequest, such an implementation +meets all of the requirements above. +

+

It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, e.g. if the server somehow determined that two +WriteRequest messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly. +

14. SetForwardingPipelineConfig RPC

+

A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the SetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message SetForwardingPipelineConfigRequest {
+  enum Action {
+    UNSPECIFIED = 0;
+    VERIFY = 1;
+    VERIFY_AND_SAVE = 2;
+    VERIFY_AND_COMMIT = 3;
+    COMMIT = 4;
+    RECONCILE_AND_COMMIT = 5;
+  }
+  uint64 device_id = 1;
+  uint64 role_id = 2;
+  Uint128 election_id = 3;
+  Action action = 4;
+  ForwardingPipelineConfig config = 5;
+}
+

The server is expected to perform the following checks (in this order) +before performing the required action: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role_id does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the master for (device_id, role_id) according to the +election_id value, the server must return a PERMISSION_DENIED error. +

+ +

The action is the type of configuration action requested, it can be one of: +

+
    +
  • +

    VERIFY: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an INVALID_ARGUMENT +error if config is not provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_SAVE: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent Read / Write requests must refer to fields in the new +config. Returns an INVALID_ARGUMENT error if the forwarding config is not +provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_COMMIT: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an INVALID_ARGUMENT error if the forwarding config is not provided of if the +provided config cannot be realized. +

  • +
  • +

    COMMIT: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a NOT_FOUND error if no saved config +is found, i.e. if no VERIFY_AND_SAVE action preceded this one. Returns an +INVALID_ARGUMENT error if a config is provided with this message. +

  • +
  • +

    RECONCILE_AND_COMMIT: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an UNIMPLEMENTED error. For targets that support this option, an +INVALID_ARGUMENT error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target. +

+ +

The config field is a message of type ForwardingPipelineConfig that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(e.g. generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the Forwarding-Pipeline +Configuration section for details. +

+

A P4Runtime server running on a non-programmable device may not +support SetForwardingPipelineConfig (e.g. the forwarding-pipeline +config is part of the device's software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +UNIMPLEMENTED error. +

15. GetForwardingPipelineConfig RPC

+

The forwarding-pipeline configuration of the target can be retrieved by invoking +the GetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message GetForwardingPipelineConfigRequest {
+  enum ResponseType {
+    ALL = 0;
+    COOKIE_ONLY = 1;
+    P4INFO_AND_COOKIE = 2;
+    DEVICE_CONFIG_AND_COOKIE = 3;
+  }
+  uint64 device_id = 1;
+  ResponseType response_type = 2;
+}
+

The device_id uniquely identifies the target P4 device. A NOT_FOUND error is +returned if the device_id is not recognized by the P4Runtime server. +

+

The response_type is used to specify which fields to populate in the response, +its value can be one of: +

+
    +
  • +

    ALL: returns a ForwardingPipelineConfig with all fields +set as stored by the target. This is the default behaviour if the +response_type field is not set. +

  • +
  • +

    COOKIE_ONLY: reply by setting only the cookie field in the +ForwardingPipelineConfig, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message. +

  • +
  • +

    P4INFO_AND_COOKIE: reply by setting the p4info and cookie fields. +

  • +
  • +

    DEVICE_CONFIG_AND_COOKIE: reply by setting the p4_device_config and +cookie fields. +

+ +

The response contains the ForwardingPipelineConfig for the specified device: +

+
+
+
message GetForwardingPipelineConfigResponse {
+  ForwardingPipelineConfig config = 1;
+}
+

If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level config field will be unset in the response. Examples are +(i) a server that only allows configuration via SetForwardingPipelineConfig +but this RPC hasn't been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn't yet occurred. +

+

Once a forwarding-pipeline config is installed on the device (either via +SetForwardingPipelineConfig or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +config.p4_device_config will be empty / unset in the response, even if +response_type in the request was set to ALL. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the SetForwardingPipelineConfig RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +SetForwardingPipelineConfig, the value of config.cookie will be unset. +

+

If a P4Runtime server supports both SetForwardingPipelineConfig as well as +returning the p4_device_config, there should be read-write symmetry between +SetForwardingPipelineConfig and GetForwardingPipelineConfig RPCs. +

16. P4Runtime Stream Messages

16.1. Packet I/O

+

P4Runtime supports controller packet-in and packet-out by means of PacketIn +and PacketOut stream messages, respectively. +

+

PacketIn messages are sent by the P4Runtime server to the client. Conversely, +PacketOut messages are sent by the client to the server. Any PacketOut +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a StreamMessageResponse message with the error field set to +report the error to the client. See the section on Stream Error +Reporting for more information on error. +

+

As introduced in the ControllerPacketMetadata +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with @controller_header. The expected metadata is described +in the P4Info using the ControllerPacketMetadata messages. +

+

Both PacketIn and PacketOut stream messages share the same fields and are +defined as follows: +

+
+
+
// Packet sent from the controller to the switch.
+message PacketOut {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+// Packet sent from the switch to the controller.
+message PacketIn {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+message PacketMetadata {
+  // This refers to Metadata.id coming from P4Info ControllerPacketMetadata.
+  uint32 metadata_id = 1;
+  bytes value = 2;
+}
+
    +
  • +

    payload is used to carry the full packet content, including the headers. +

  • +
  • +

    metadata is a repeated field of PacketMetadata messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +ControllerPacketMetadata. Indeed, when a P4Runtime client (or server) +generates a PacketOut (or PacketIn) message, it needs to populate the +metadata field with as many values as in ControllerPacketMetadata.metadata +for the packet-out (or packet-in) case. Each PacketMetadata.value is a +binary string and must conform to the Bytestrings +requirements based on the corresponding P4Info +ControllerPacketMetadata.metadata specification. If the metadata field +does not match the P4Info specification, the server must drop the PacketOut +message and may generate a StreamMessageResponse message with the error +field set to report the error to the client which issued the PacketOut. See +the section on Stream Error Reporting for more +information on error. +

+

16.2. Master Arbitration Update

+

P4Runtime's master arbitration mechanism ensures that only the current master +can modify state on the switch, and that the election_id is monotonically +increasing. For example, the switch must finish all previous write operations +before changing masters, and must only accept write requests from the current +master. +

+

As explained earlier in this document, the controller uses the StreamChannel +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via Write RPC), +it needs to start a controller session and become a “master”. To do so, the +controller first opens a bidirectional stream channel to the server via +StreamChannel for each device and sends a StreamMessageRequest message. The +controller populates the MasterArbitrationUpdate field in this message using +its role_id and election_id and the device_id of the device, as explained +in detail in the Master-Slave Arbitration and Controller +Replication +section. For any given (device_id, role_id), the P4Runtime server keeps track +of the highest election_id that it has ever received. If a controller's +election_id is equal to the highest election_id that the server has ever +received, that controller is the master. All other controllers are slaves. Note +that it is possible that all controllers are slaves, and that there is no +master. There can be at most one master, because for any given +(device_id, role_id), each connected controller has a unique election_id. +

+

This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest election_id after such a restart. +However, across a full restart, the election_id must be +reset. In fact, a full restart is the only way to reset the election_id. +

+

The MasterArbitrationUpdate message is defined as follows: +

+
+
+
message Role {
+  // role_id for this role. Defined offline in agreement across the
+  // entire control plane.
+  uint64 id = 1;
+  // Describes the role configuration.
+  google.protobuf.Any config = 2;
+}
+
+message MasterArbitrationUpdate {
+  // Identifies the device (aka target or node or switching chip).
+  uint64 device_id = 1;
+  // The role for which the mastership is being arbitrated.
+  Role role = 2;
+  // The election_id (unique per role).
+  Uint128 election_id = 3;
+  // Switch populates this with OK for the client that is the master,
+  // and with an error status for all other connected clients (at
+  // every mastership change). The controller does not populate this
+  // field.
+  google.rpc.Status status = 4;
+}
+

Note that the status field in the MasterArbitrationUpdate message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a StreamMessageResponse message back to the controller, in which +it populates the MasterArbitrationUpdate message using the device_id, +role, and election_id it previously received from the controller. The server +also populates the status field in the MasterArbitrationUpdate according to +the rules in an earlier section. +

+

The sender need not specify an election_id. If the election_id is not +specified, the sender's election_id is considered lower than any +election_id, and the sender will thus never become master. This way, a +controller can choose to be a standby controller, in order to avoid master +“flapping” (if a standby controller connects to the switch shortly before the +actual master controller, therefore becoming master temporarily). +

16.3. Digest Messages

+

See the DigestEntry section. +

16.4. Table Idle Timeout Notification

+

When a table supports idle timeout (as per the P4Info message), the master +client can specify a TTL value for each entry in the table (see +Idle-timeout section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an IdleTimeoutNotification message on the +StreamChannel bidirectional stream to the master client. The master client can +then take the action of its choice, most likely remove the idle entry. +

+

The IdleTimeoutNotification Protobuf message has the following fields: +

+
    +
  • +

    timestamp: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server's local clock. +

  • +
  • +

    table_entry: a repeated field of entries which have expired. Each individual +entry is identified by a single TableEntry message. For each TableEntry, +the key fields (table_id, match and priority) must be set, along with +the controller_metadata field and the idle_timeout_ns field. Other fields +may be set by the server but should be ignored by the client. +

+ +

Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +IdleTimeoutNotification message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an IdleTimeoutNotification +message with an empty table_entry repeated field. +

+

After generating an idle notification, the P4Runtime server must “reset” the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the master client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle. +

+

Here is a reasonable pseudo-code implementation for idle timeout for table +entries: +

+
+
+
IdleTimeoutStream stream;
+
+scanning_interval = 10ms;
+
+while (true) {
+  // iterate over all tables which support idle timeout
+  for (table in tables) {
+    if (!table.idle_timeout_supported) continue;
+    // we coalesce all idle notifications for the same table in one
+    // message
+    IdleTimeoutNotification msg;
+    // read time_since_last_hit from device
+    entries = device.load_table_entries_from_hw(table);
+    for (entry in entries) {
+      if (entry.idle_timeout == 0) continue;  // no TTL
+      if (entry.time_since_last_hit < entry.idle_timeout) continue;
+      msg.table_entry_add(entry);
+      entry.reset_time_since_last_hit();
+    }
+    if (msg.table_entry_size() == 0) continue;  // no notifications
+    msg.set_timestamp(now());
+    stream.write(msg);
+  }
+  sleep(scanning_interval);
+}

16.5. Architecture-Specific Notifications

+

P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on StreamChannel, by including an Any Protobuf field [30] +named other in both StreamMessageRequest and StreamMessageResponse. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the PSA Digest +extern. See section on Extending P4Runtime for non-PSA +Architectures for more information. +

16.6. Stream Error Reporting

+

The P4Runtime server can asynchronously report errors which occur when +processing StreamMessageRequest messages, using the error message field (of +type StreamError) in StreamMessageResponse. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature. +

+

The StreamError message has the following fields: +

+
    +
  • canonical_code, which must be set to the appropriate canonical error code +[33]. +
  • +
  • message, an optional developer-facing error message describing the error. +
  • +
  • space and code, which are optional and can be used by vendors to provide +additional details on the error. code is a numeric error code drawn from a +vendor's chosen error space. +
  • +
  • details, which is a Protobuf oneof used to help the client identify which +StreamMessageRequest triggered the error. The server is required to set the +appropriate field in the oneof so that the client can identify which type +of stream message is responsible for the error (packet_out, +digest_list_ack or other), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid PacketOut message from the +client, the packet_out field (of type PacketOutError) should be set in +the details oneof, and the server may additionally set the packet_out +field in the PacketOutError sub-message (by copying it from the invalid +PacketOut message received on the stream channel) so that the client can +know exactly what packet-out triggered the error. +
+ +

The appropriate canonical error code [33] should be used when +populating the canonical_code field. For example: +

+
    +
  • if a controller is not allowed to send a PacketOut message under its +current role definition, the code should be set to PERMISSION_DENIED. +
  • +
  • if the metadata repeated field in PacketOut does not match the P4Info +definition, the code should be set to INVALID_ARGUMENT. It may be useful +for the server to set the packet_out field in this case, so that the client +can find out which set of metadata fields triggered the error. +
  • +
  • if the digest_id field in DigestListAck does not match any Digest entry +in P4Info, the code should be set to INVALID_ARGUMENT. +
+ +

The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, e.g. because of a +burst of PacketIn messages. +

+

Note that master-arbitration errors are never reported using the StreamError +message. Invalid MasterArbitrationUpdate messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section 5.3. +

16.6.1. Examples of StreamError Messages

+
    +
  • +

    Malformed packet-out metadata. If the server receives a PacketOut +message with a metadata field with id 7 which is not included in the P4Info +ControllerPacketMetadata message for “packet_out”, the server may send the +following StreamMessageResponse back to the client: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Unknown metadata field id 7."
    + packet_out {
    +   # copied from the PacketOut message received from the client
    +   packet_out {
    +     payload: ...
    +     metadata {
    +       id: 7
    +       name: "I_should_not_be_here"
    +       bitwidth: 32
    +     }
    +     # more metadata
    +   }
    + }
    +}
  • +
  • +

    Packet-out which exceeds the MTU. If the server receives a PacketOut +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following StreamMessageResponse: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Packet exceeds the MTU for port."
    + space: "targetX-psa-vendor1"
    + code: 123  # MTU_EXCEEDED
    + packet_out {
    +   # we do not set the packet_out field as it does not provide any
    +   # extra information to the client
    + }
    +}
+

17. Capabilities RPC

+

The Capabilities RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the CapabilitiesRequest message is empty and the CapabilitiesResponse +message only includes the p4runtime_api_version string field. This field must +be set to the full semantic version string [26] corresponding to the +version of the P4Runtime API implemented by the server, e.g. “1.1.0-rc.1”. +

+

Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three atomicity +modes for WriteRequest batches, two of them being +optional. In the future we may decide to leverage the CapabilitiesResponse +message to enable the server to report to the client which subset of these +atomicity modes is supported. +

+

The semantic version string included in CapabilitiesResponse can be used by +the client to determine which exact feature set is implemented by the server, +since minor releases may introduce new +functionality. However, because the Capabilities RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (i.e. an UNIMPLEMENTED error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0). +

18. Portability Considerations

18.1. PSA Metadata Translation

+

The Portable Switch Architecture (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +[23]. For such metadata, a translation between the controller's +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. +

+
+

psa-metadata-translation +

+
+ +
Figure 8. P4Runtime Metadata Translation for the Portable Switch Architecture
+

Figure 8 illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller's 32 bit port +numbers to a target's 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch. +

18.1.1. Translation of Port Numbers

+

In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller's space and the PSA device's space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +user-defined P4 types, namely PortId_t and +PortIdInHeader_t, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in psa.p4 for +the PSA device in Switch 1. +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type PortId_t bit<9>;
+@p4runtime_translation("p4.org/psa/v1/PortIdInHeader_t", 32)
+type PortIdInHeader_t bit<32>;
+

The first argument to the @p4runtime_translation annotation is a URI that +indicates to the P4Runtime server which numerical mapping provided by the +out-of-band switch configuration mechanism to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports). +

+

An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows: +

+
+
+
enum SdnPort {
+  SDN_PORT_UNSPECIFIED = 0;
+
+  // SDN ports are numbered starting form 1.
+  SDN_PORT_MIN = 1;
+
+  // The maximum value of an SDN port (physical or logical).
+  SDN_PORT_MAX = 0xfffffeff;
+
+  // Reserved SDN port numbers (0xfffffff0 - 0xffffffff)
+
+  SDN_PORT_RECIRCULATE = 0xfffffffa;
+  SDN_PORT_CPU = 0xfffffffd;
+}
+

The switch config will map SDN_PORT_RECIRCULATE and SDN_PORT_CPU as well +as any SDN port number corresponding to a “regular” front-panel port to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation. +

+

The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs. +

18.1.2. Translation of Packet-IO Header Fields

+

Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  PortIdInHeader_t egress_port;
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  PortIdInHeader_t ingress_port;
+}
+

The header-level annotation @controller_header is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (egress_port) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI first argument to the @p4runtime_translation +annotation). Any subsequent reference to the egress_port field in the +data plane will use the translated value. PortIdInHeader_t is used in the +header definition instead of PortId_t to guarantee byte-aligned headers in +case this is required by the target. +

+

A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target's PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the ingress_port field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller. +

18.1.3. Translation of Match Fields

+

Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table's match key as shown in the example below: +

+
+
+
table t {
+  key = {
+    istd.ingress_port: exact;  // PSA standard metadata ingress port
+  }
+  actions = {
+    drop;
+  }
+}
+

Table t has an exact match on PSA standard metadata ingress port +(istd.ingress_port). Since the field is of type PortId_t, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in t from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table t is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values. +

+

Note that it may be infeasible to translate the value-mask pair for ternary +matches: LPM, TERNARY or RANGE match kinds. The P4Runtime server may +require that for these match kinds the port match be either de facto “exact” +(0xffffffff mask for TERNARY, prefix-length of 32 for LPM, or same low and +high bounds for RANGE) or “don't care”. +

18.1.4. Translation of Action Parameters

+

PortId_t type parameters can be part of a P4 action definition as shown in the +example below: +

+
+
+
action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+}
+
+table t {
+  key = {
+    hdr.h.f: exact;
+  }
+  actions = {
+    a;
+  }
+}
+

The controller may write entries in table t with action a to set the egress +port as shown in the P4 code above. The action parameter p is of type +PortId_t, which leads to a 32-bit bitwidth for p being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device. +

18.1.5. Port Translation for PSA Extern APIs

+

The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch field is +of type uint32 to carry the 32-bit SDN representation of the port being +watched. The P4Runtime server will translate the given watch port number into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device. +

+

The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type uint32 to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane. +

18.1.6. Using Port as an Index to a Register, Indirect Counter or Indirect Meter

+

P4Runtime supports using a translated value (PortId_t or any other translated +type for which the underlying built-in type is bit<W>) as an index to a +register, indirect counter, or indirect meter. +

+
+
+
Counter<bit<32> /* counter entry type */, PortId_t /* index type */>(
+  32w1024, PSA_CounterType_t.PACKETS) counter;
+action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+  counter.count(p);
+}
+

This P4 Counter declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
counters {
+  preamble {
+    id: 0x12000001
+    name: "counter"
+  }
+  spec {
+    unit: PACKETS
+  }
+  index_type_name {
+    name: "PortId_t"
+  }
+}
+

The controller may read and write counter values from indexed counter counter +using SDN port numbers as indices, and not device-specific port numbers. The +index_type_name field in the P4Info message is a signal to the P4Runtime +server that translation is required. +

19. P4Runtime Versioning

+

P4Runtime follows the Google guidelines for versioning cloud APIs +[6]. We use a MAJOR.MINOR.PATCH style version number scheme and +we increment the: +

+
    +
  • MAJOR version when we make incompatible API changes, +
  • +
  • MINOR version when we add functionality in a backwards-compatible manner, +
  • +
  • PATCH version when we make backwards-compatible bug fixes. +
+ +

The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is p4.v1 and the package +name for P4Info is p4.config.v1. Even though p4 and p4.config are two +different Protobuf packages, p4 depends on p4.config and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence. +

+

As recommended in [6], we may consider using pre-GA release +suffixes (such as alpha or beta) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1). +

+

Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner. [7] describes +what constitute a backwards-compatible change. We expect MAJOR version bumps +to be a rare event. +

+

Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor + patch version numbers in future releases. +

+

All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository [14] and the version label follows +semantic versioning rules [26]. +

20. Extending P4Runtime for non-PSA Architectures

+

P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place. +

+

When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names: +

+
    +
  • p4/[organization]/arch/config/<major version>/p4info.proto +
  • +
  • p4/[organization]/arch/<major version>/p4runtime.proto +
+ +

We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they “extend”. +

+

For the remainder of this section, we will refer to these two files as +p4info-ext and p4runtime-ext respectively. +

20.1. Extending P4Runtime for Architecture-Specific Externs

+

Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both p4info-ext and +p4runtime-ext. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example: +

+
+
+
// T must be a bit<W> type, it indicates the width of each counter cell
+extern MyNewPacketCounter<T> {
+  counter(bit<32> size);
+  increment(in bit<32> index);
+}

20.1.1. Extending the P4Info message

+
    +
  • Id prefixes 0x81 through 0xfe are reserved for architecture-specific +externs. It is recommended that p4info-ext include a P4Ids message based +on the one in p4info.proto that the P4 compiler can refer to when assigning +IDs to each extern instance. +
+ +
+
+
message P4Ids {
+  enum Prefix {
+    UNSPECIFIED = 0;
+    MY_NEW_PACKET_COUNTER = 0x81;
+  }
+}
+
    +
  • p4info-ext should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +p4.config.v1.ExternInstance message as the info +field, which is of type Any [30]. +
+ +
+
+
message MyNewPacketCounter {
+  // corresponds to the T type parameter in the P4 extern definition
+  p4.config.v1.P4DataTypeSpec type_spec = 1;
+  // constructor argument
+  int64 size = 2;
+}

20.1.2. Extending the P4Runtime Service

+

Just like p4info-ext, p4runtime-ext should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an ExternEntry message generated by the +P4Runtime client. +

+

Here is a possible Protobuf message for our MyNewPacketCounter P4 extern: +

+
+
+
// This message enables reading / writing data to the counter at the provided
+// index
+message MyNewPacketCounter {
+  int64 index = 1;
+  p4.v1.P4Data data = 2;
+}
+

P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an Any Protobuf field [30] named other +in both p4.v1.StreamMessageRequest and +p4.v1.StreamMessageResponse. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in p4runtime-ext and embed instances of these messages in +p4.v1.StreamMessageRequest and p4.v1.StreamMessageResponse as appropriate. +

20.2. Architecture-Specific Table Extensions

20.2.1. New Match Types

+

An architecture may introduce new table match types [12]. P4Runtime +accounts for this by providing the following hooks: +

+
    +
  • +

    The match field in p4.config.v1.MatchField (p4info.proto) is a oneof +which can be either one of the default match types (EXACT, LPM, TERNARY +or RANGE) or an architecture-specific match type encoded as a string. +

  • +
  • +

    The field_match_type field in p4.v1.FieldMatch (p4runtime.proto) is a +oneof which includes an Any Protobuf message [30] field +(other). p4info-ext should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in p4.v1.FieldMatch as the +other field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info. +

+

20.2.2. New Table Properties

+

An architecture may introduce additional table properties +[29]. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +p4.config.v1.Table message includes the other_properties Any Protobuf +field [30]. At the moment, there is not any mechanism to extend the +p4.v1.TableEntry message based on the value of architecture-specific table +properties, but we may include on in future versions of the API. +

21. Known Limitations of Current P4Runtime Version

+
    +
  • +

    FieldMatch, action Param, and controller packet metadata fields only +support unsigned bitstrings, i.e. values of one of the following types (not +the more general P4Data): +

    +
      +
    • bit<W> +
    • +
    • bool. Note that as far as the P4Info message contents and +thus controller software is concerned, such fields of type bool +will be indistinguishable from those that have been declared with +type bit<1>. P4Runtime server software will automatically +perform any conversion needed between the type bit<1> values in +P4Runtime messages and the data plane representation. +
    • +
    • an enum with underlying type bit<W> +
    • +
    • a type or typedef with an underlying type that is one of the above (or +in general a “chain” of type and/or typedef that eventually ends with +one of the types above) +
    +
  • +
  • +

    Support for PSA Random & Timestamp externs is postponed to a future minor +version update. +

  • +
  • +

    P4Info does not include information about which of a table's actions execute +which direct resource(s). +

  • +
  • +

    The default action for indirect match tables is restricted to a const +NoAction known at compile-time. +

  • +
  • +

    There is no mechanism for changing the value of the psa_empty_group_action +table property at runtime. +

  • +
  • +

    There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor + +patch version numbers. +

+

22. Security concerns for P4Runtime

+

Appropriate measures and security best practices need to be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. +

A. Appendix

A.1. Revision History

A.1.1. Changes in v1.1.0

+
    +
  • Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously. +
  • +
  • Add error field to stream messages sent by the server. +
  • +
  • Add Capabilities RPC to query the P4Runtime API version implemented by the +server. +
  • +
  • Support wildcard reads for multicast groups and clone sessions. +
  • +
  • Support for modifying direct resources of const tables. +
  • +
  • Support P4 user-defined types for Packet IO metadata fields. +
  • +
  • Clarify consistency requirements for Write and Read RPCs. +
  • +
  • Add Appendix providing implementation advice for avoiding common pitfalls: + +
      +
    • advice on setting gRPC Metadata Maximum Size +
    • +
    • advice on setting gRPC Server Maximum Receive Message Size +
  • +
  • Clarify limitations on supported types for FieldMatch, action Param, and +Packet IO metadata fields. +
  • +
  • Clarify that reading entire forwarding state with empty entity is not +supported. +
  • +
  • Document that @p4runtime_translation need only be supported when applied to +type declarations in P4. +
+

A.2. P4 Annotations

+

Table 7 lists P416 annotations introduced primarily for +the purpose of adding features for the P4Runtime API. +

+
+ + + + + + + + + + +
Annotation Description
@brief See section 6.1.3
@controller_header See section 6.4.6
@description See section 6.1.3
@id See section 6.3
@max_group_size See sections 6.4.3, 9.2.2
@pkginfo See section 6.2.1
@p4runtime_translation See sections 8.5.6, 18.1.1
+
+ +
Table 7. P4 annotations introduced by P4Runtime

A.3. A More Complex Value Set Example

+

This section includes a more complex Value Set example, with multiple matches of +different kinds. +

+
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+

This P4 Value Set declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

A P4Runtime client can set the membership for this Value Set with WriteRequest +messages similar to this one: +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xac }
+      }
+      # match for field_id 2 is missing => don't care match
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xdc }
+      }
+      match {
+        field_id: 2
+        ternary { value: 0x88 mask: 8f }
+      }
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+  }
+}

A.4. Guidelines for Implementations

+

This section contains practical advice for implementing P4Runtime clients and +servers. +

A.4.1. gRPC Metadata Maximum Size

+

In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the grpc.max_metadata_size gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the Write P4Runtime RPC. The Write RPC +returns an individual error for every item in a batch (see Section +12), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +RESOURCE_EXHAUSTED error, without any of the individual errors. +

+

To fix this problem, one can set the grpc.max_metadata_size option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it's +limit, as only the receiving side's limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every p4.Error, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +8192 + MAX_UPDATES_PER_WRITE * 100 bytes of metadata. +

+

For example, in C++, one can create a client channel as follows: +

+
+
+
const int MAX_UPDATES_PER_WRITE = 100;
+::grpc::ChannelArguments arguments;
+arguments.SetInt(GRPC_ARG_MAX_METADATA_SIZE, 8192 + MAX_UPDATES_PER_WRITE*100);
+return grpc::CreateCustomChannel(address, credentials, arguments);

A.4.2. gRPC Server Maximum Receive Message Size

+

At the time of writing, the default maximum receive message size in gRPC is 4MB + while the default maximum send message size is unlimited. This can be a +problem for the SetForwardingPipelineConfig RPC, since for some targets the +binary p4_device_config can exceed 4MB, in which case by default the P4Runtime +server would return an INVALID_ARGUMENT error. To a lesser extent, this may +affect the Write RPC as well, in case of extremely large batches. +

+

To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of p4_device_config for their target(s). This can be done by +setting the grpc.max_receive_message_length when building the gRPC server. +

+

For example, in C++, one can set the maximum receive message size as follows: +

+
+
+
const int MAX_RECEIVE_MESSAGE_SIZE = 128 * 1024 * 1024;  // 128MB
+::grpc::ServerBuilder server_builder;
+builder.AddListeningPort(/*...*/);
+builder.RegisterService(/*...*/);  // register P4Runtime service
+builder.SetMaxReceiveMessageSize(MAX_RECEIVE_MESSAGE_SIZE);
+builder.BuildAndStart();
+

On the client side, we recommend that P4Runtime clients do not use Write +batches larger than the default maximum receive message size (4MB) in case +the server did not deem necessary to increase the default value , unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB). +

+

References

+
+ +
[2]“A Two Rate Three Color Marker.” https://​tools.​ietf.​org/​html/​rfc2698.
+ + + + +
[7]“Google Cloud APIs Versioning - Backwards-Compatibility.” https://​cloud.​google.​com/​apis/​design/​versioning#​backwards_​compatibility.
+ +
[9]“gRPC Main Site.” https://​grpc.​io.
+ + + + +
[14]“p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” https://​github.​com/​p4lang/​p4runtime.
+
[15]“p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.” https://​github.​com/​p4lang/​PI.
+ + +
[18]“Portable Switch Architecture Specification (v1.1.0).” https://​p4.​org/​p4-​spec/​docs/​PSA-​v1.​1.​0.​html.
+ + + + + + + +
[26]“Semantic Versioning.” https://​semver.​org/​.
+ + + + + + + +
[34]“The OpenConfig Project.” http://​openconfig.​net.
+ +
[36]“The Stratum Project.” https://​stratumproject.​org/​.
+
+
+
+ +
+

1.an enum type used as a field in a header must specify a +underlying type and representation for enum elements. +

+ + + diff --git a/spec/v1.1.0/P4Runtime-Spec.log b/spec/v1.1.0/P4Runtime-Spec.log new file mode 100644 index 00000000..ce174ce9 --- /dev/null +++ b/spec/v1.1.0/P4Runtime-Spec.log @@ -0,0 +1,13978 @@ +This is XeTeX, Version 3.14159265-2.6-0.99992 (TeX Live 2015/Debian) (preloaded format=xelatex 2018.8.17) 3 FEB 2020 18:59 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**build/P4Runtime-Spec.tex +(./build/P4Runtime-Spec.tex +LaTeX2e <2016/02/01> +Babel <3.9q> and hyphenation patterns for 81 language(s) loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2014/09/29 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo +File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@section=\count80 +\c@subsection=\count81 +\c@subsubsection=\count82 +\c@paragraph=\count83 +\c@subparagraph=\count84 +\c@figure=\count85 +\c@table=\count86 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) (build/madoko2.sty (/usr/share/texlive/texmf-dist/tex/latex/colortbl/colortbl.sty +Package: colortbl 2012/02/13 v1.0a Color table columns (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty +Package: array 2014/10/28 v2.4c Tabular extension package (FMi) +\col@sep=\dimen103 +\extrarowheight=\dimen104 +\NC@list=\toks14 +\extratabsurround=\skip43 +\backup@length=\skip44 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty +Package: color 2016/01/03 v1.1b Standard LaTeX Color (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package color Info: Driver file: xetex.def on input line 143. +(/usr/share/texlive/texmf-dist/tex/xelatex/xetex-def/xetex.def +File: xetex.def 2015/09/11 v4.06 LaTeX color/graphics driver for XeTeX (TeX Live/RRM/JK) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +))) +\everycr=\toks15 +\minrowclearance=\skip45 +) (/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: xetex.def on input line 225. +LaTeX Info: Redefining \color on input line 702. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) (build/options.sty +Package: options 2015/03/01, Daan Leijen, Provides convenient path-value (or key-value) options +(/usr/share/texlive/texmf-dist/tex/latex/etoolbox/etoolbox.sty +Package: etoolbox 2015/08/02 v2.2a e-TeX tools for LaTeX (JAW) +\etb@tempcnta=\count87 +) +\opt@nesting=\count88 +\opt@idx=\count89 +\opt@choiceord=\count90 +) (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty +Package: iftex 2013/04/04 v0.2 Provides if(tex) conditional for PDFTeX, XeTeX, and LuaTeX +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2014/10/28 v1.0g Enhanced LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks16 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2016/01/03 v1.0q Standard LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2016/01/03 v1.10 sin cos tan (DPC) +) (/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg +File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live +) +Package graphics Info: Driver file: xetex.def on input line 95. +) +\Gin@req@height=\dimen105 +\Gin@req@width=\dimen106 +) (build/longfbox.sty +Package: longfbox 2015/12/01, Daan Leijen, Provides long fbox that can break over pages +(build/longbox.sty +Package: longbox 2015/12/01, Daan Leijen, Provides basic longbox that can break over pages +(/usr/share/texlive/texmf-dist/tex/latex/mdwtools/footnote.sty +Package: footnote 1997/01/28 1.13 Save footnotes around boxes +\fn@notes=\box26 +\fn@width=\dimen107 +) +\lb@prevdepth=\skip46 +\lb@freevspace=\skip47 +\lb@headbox=\box27 +\lb@savebox=\box28 +\lb@mainbox=\box29 +\lb@usevbox=\count91 +\lb@width=\skip48 +\lb@height=\skip49 +\lb@skiptop=\skip50 +\lb@skipright=\skip51 +\lb@skipbottom=\skip52 +\lb@skipleft=\skip53 +\lb@skipbreaktop=\skip54 +\lb@skipbreakbottom=\skip55 +\lb@outerwidth=\skip56 +\lb@extrasplit=\skip57 +\lb@textalign=\count92 +\lb@baseline=\count93 +\lb@neededvspace=\skip58 +\lb@splitheight=\skip59 +\lb@insurance=\skip60 +\/longbox/@part-height=\skip61 +\/longbox/@part-width=\skip62 +\/longbox/@part-depth=\skip63 +\/longbox/@content-box-height=\skip64 +\/longbox/@content-box-width=\skip65 +\/longbox/@content-box-depth=\skip66 +\/longbox/@breakat-previous=\skip67 +\/longbox/@lower=\skip68 +\/longbox/split-minimum=\skip69 +\/longbox/split-badness=\skip70 +\/longbox/raise=\skip71 +\/longbox/height=\skip72 +\/longbox/width=\skip73 +\/longbox/outer-height=\skip74 +\/longbox/outer-width=\skip75 +\/longbox/skip-top=\skip76 +\/longbox/skip-right=\skip77 +\/longbox/skip-bottom=\skip78 +\/longbox/skip-left=\skip79 +\/longbox/skip-break-bottom=\skip80 +\/longbox/skip-break-top=\skip81 +) (/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.sty +Package: pict2e 2016/02/05 v0.3b Improved picture commands (HjG,RN,JT) +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.cfg +File: pict2e.cfg 2016/02/05 v0.1u pict2e configuration for teTeX/TeXLive +) +Package pict2e Info: Driver file: xetex.def on input line 119. +Package pict2e Info: Driver file for pict2e: p2e-xetex.def on input line 121. +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/p2e-xetex.def +File: p2e-xetex.def 2016/02/05 v0.1u Driver-dependant file (RN,HjG,JT) +) +\pIIe@GRAPH=\toks17 +\@arclen=\dimen108 +\@arcrad=\dimen109 +\@tempdimd=\dimen110 +) (build/ellipse.sty +Package: ellipse 2004/11/05 v1.0 .dtx ellipse file +) +\fbox@oct=\count94 +\fbox@quad=\count95 +\fbox@diaq=\count96 +\fbox@sign=\count97 +\fbox@anglestart=\skip82 +\fbox@angleend=\skip83 +\fbox@dash=\skip84 +\fbox@dashskip=\skip85 +\fbox@anglecur=\skip86 +\fbox@dashangle=\skip87 +\fbox@dashskipangle=\skip88 +\fbox@delta=\skip89 +\fbox@from=\skip90 +\fbox@to=\skip91 +\/fbox/padding-top=\skip92 +\/fbox/padding-right=\skip93 +\/fbox/padding-bottom=\skip94 +\/fbox/padding-left=\skip95 +\/fbox/padding-break-top=\skip96 +\/fbox/padding-break-bottom=\skip97 +\/fbox/margin-top=\skip98 +\/fbox/margin-right=\skip99 +\/fbox/margin-bottom=\skip100 +\/fbox/margin-left=\skip101 +\/fbox/margin-break-top=\skip102 +\/fbox/margin-break-bottom=\skip103 +\/fbox/border-top-width=\skip104 +\/fbox/border-right-width=\skip105 +\/fbox/border-bottom-width=\skip106 +\/fbox/border-left-width=\skip107 +\/fbox/border-break-top-width=\skip108 +\/fbox/border-break-bottom-width=\skip109 +\/fbox/@lower=\skip110 +\/fbox/@padding-box-height=\skip111 +\/fbox/@padding-box-depth=\skip112 +\/fbox/@padding-box-width=\skip113 +\/fbox/@border-box-width=\skip114 +\/fbox/@border-box-height=\skip115 +\/fbox/@border-box-depth=\skip116 +\/fbox/@border-top-left-radius-x=\skip117 +\/fbox/@border-top-right-radius-x=\skip118 +\/fbox/@border-bottom-left-radius-x=\skip119 +\/fbox/@border-bottom-right-radius-x=\skip120 +\/fbox/@border-top-left-radius-y=\skip121 +\/fbox/@border-top-right-radius-y=\skip122 +\/fbox/@border-bottom-left-radius-y=\skip123 +\/fbox/@border-bottom-right-radius-y=\skip124 +\/fbox/@border-top-left-ix=\skip125 +\/fbox/@border-top-left-iy=\skip126 +\/fbox/@border-top-right-ix=\skip127 +\/fbox/@border-top-right-iy=\skip128 +\/fbox/@border-bottom-left-ix=\skip129 +\/fbox/@border-bottom-left-iy=\skip130 +\/fbox/@border-bottom-right-ix=\skip131 +\/fbox/@border-bottom-right-iy=\skip132 +\/fbox/@border-top-left-phi=\skip133 +\/fbox/@border-top-right-phi=\skip134 +\/fbox/@border-bottom-left-phi=\skip135 +\/fbox/@border-bottom-right-phi=\skip136 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2016/03/03 v2.15a AMS math features +\@mathmargin=\skip137 +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2000/06/29 v2.01 AMS text +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen111 +)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen112 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 1999/12/14 v2.01 operator names +) +\inf@bad=\count98 +LaTeX Info: Redefining \frac on input line 199. +\uproot@=\count99 +\leftroot@=\count100 +LaTeX Info: Redefining \overline on input line 297. +\classnum@=\count101 +\DOTSCASE@=\count102 +LaTeX Info: Redefining \ldots on input line 394. +LaTeX Info: Redefining \dots on input line 397. +LaTeX Info: Redefining \cdots on input line 518. +\Mathstrutbox@=\box30 +\strutbox@=\box31 +\big@size=\dimen113 +LaTeX Font Info: Redeclaring font encoding OML on input line 630. +LaTeX Font Info: Redeclaring font encoding OMS on input line 631. +\macc@depth=\count103 +\c@MaxMatrixCols=\count104 +\dotsspace@=\muskip10 +\c@parentequation=\count105 +\dspbrk@lvl=\count106 +\tag@help=\toks19 +\row@=\count107 +\column@=\count108 +\maxfields@=\count109 +\andhelp@=\toks20 +\eqnshift@=\dimen114 +\alignsep@=\dimen115 +\tagshift@=\dimen116 +\tagwidth@=\dimen117 +\totwidth@=\dimen118 +\lineht@=\dimen119 +\@envbody=\toks21 +\multlinegap=\skip138 +\multlinetaggap=\skip139 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2735. +LaTeX Info: Redefining \] on input line 2736. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +) (/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/stmaryrd.sty +Package: stmaryrd 1994/03/03 St Mary's Road symbol package +\symstmry=\mathgroup6 +LaTeX Font Info: Overwriting symbol font `stmry' in version `bold' +(Font) U/stmry/m/n --> U/stmry/b/n on input line 89. +) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty +Package: textcomp 2005/09/27 v1.99g Standard LaTeX package +Package textcomp Info: Sub-encoding information: +(textcomp) 5 = only ISO-Adobe without \textcurrency +(textcomp) 4 = 5 + \texteuro +(textcomp) 3 = 4 + \textohm +(textcomp) 2 = 3 + \textestimated + \textcurrency +(textcomp) 1 = TS1 - \textcircled - \t +(textcomp) 0 = TS1 (full) +(textcomp) Font families with sub-encoding setting implement +(textcomp) only a restricted character set as indicated. +(textcomp) Family '?' is the default used for unknown fonts. +(textcomp) See the documentation for details. +Package textcomp Info: Setting ? sub-encoding to TS1/1 on input line 79. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +) +LaTeX Info: Redefining \oldstylenums on input line 334. +Package textcomp Info: Setting cmr sub-encoding to TS1/0 on input line 349. +Package textcomp Info: Setting cmss sub-encoding to TS1/0 on input line 350. +Package textcomp Info: Setting cmtt sub-encoding to TS1/0 on input line 351. +Package textcomp Info: Setting cmvtt sub-encoding to TS1/0 on input line 352. +Package textcomp Info: Setting cmbr sub-encoding to TS1/0 on input line 353. +Package textcomp Info: Setting cmtl sub-encoding to TS1/0 on input line 354. +Package textcomp Info: Setting ccr sub-encoding to TS1/0 on input line 355. +Package textcomp Info: Setting ptm sub-encoding to TS1/4 on input line 356. +Package textcomp Info: Setting pcr sub-encoding to TS1/4 on input line 357. +Package textcomp Info: Setting phv sub-encoding to TS1/4 on input line 358. +Package textcomp Info: Setting ppl sub-encoding to TS1/3 on input line 359. +Package textcomp Info: Setting pag sub-encoding to TS1/4 on input line 360. +Package textcomp Info: Setting pbk sub-encoding to TS1/4 on input line 361. +Package textcomp Info: Setting pnc sub-encoding to TS1/4 on input line 362. +Package textcomp Info: Setting pzc sub-encoding to TS1/4 on input line 363. +Package textcomp Info: Setting bch sub-encoding to TS1/4 on input line 364. +Package textcomp Info: Setting put sub-encoding to TS1/5 on input line 365. +Package textcomp Info: Setting uag sub-encoding to TS1/5 on input line 366. +Package textcomp Info: Setting ugq sub-encoding to TS1/5 on input line 367. +Package textcomp Info: Setting ul8 sub-encoding to TS1/4 on input line 368. +Package textcomp Info: Setting ul9 sub-encoding to TS1/4 on input line 369. +Package textcomp Info: Setting augie sub-encoding to TS1/5 on input line 370. +Package textcomp Info: Setting dayrom sub-encoding to TS1/3 on input line 371. +Package textcomp Info: Setting dayroms sub-encoding to TS1/3 on input line 372. +Package textcomp Info: Setting pxr sub-encoding to TS1/0 on input line 373. +Package textcomp Info: Setting pxss sub-encoding to TS1/0 on input line 374. +Package textcomp Info: Setting pxtt sub-encoding to TS1/0 on input line 375. +Package textcomp Info: Setting txr sub-encoding to TS1/0 on input line 376. +Package textcomp Info: Setting txss sub-encoding to TS1/0 on input line 377. +Package textcomp Info: Setting txtt sub-encoding to TS1/0 on input line 378. +Package textcomp Info: Setting lmr sub-encoding to TS1/0 on input line 379. +Package textcomp Info: Setting lmdh sub-encoding to TS1/0 on input line 380. +Package textcomp Info: Setting lmss sub-encoding to TS1/0 on input line 381. +Package textcomp Info: Setting lmssq sub-encoding to TS1/0 on input line 382. +Package textcomp Info: Setting lmvtt sub-encoding to TS1/0 on input line 383. +Package textcomp Info: Setting lmtt sub-encoding to TS1/0 on input line 384. +Package textcomp Info: Setting qhv sub-encoding to TS1/0 on input line 385. +Package textcomp Info: Setting qag sub-encoding to TS1/0 on input line 386. +Package textcomp Info: Setting qbk sub-encoding to TS1/0 on input line 387. +Package textcomp Info: Setting qcr sub-encoding to TS1/0 on input line 388. +Package textcomp Info: Setting qcs sub-encoding to TS1/0 on input line 389. +Package textcomp Info: Setting qpl sub-encoding to TS1/0 on input line 390. +Package textcomp Info: Setting qtm sub-encoding to TS1/0 on input line 391. +Package textcomp Info: Setting qzc sub-encoding to TS1/0 on input line 392. +Package textcomp Info: Setting qhvc sub-encoding to TS1/0 on input line 393. +Package textcomp Info: Setting futs sub-encoding to TS1/4 on input line 394. +Package textcomp Info: Setting futx sub-encoding to TS1/4 on input line 395. +Package textcomp Info: Setting futj sub-encoding to TS1/4 on input line 396. +Package textcomp Info: Setting hlh sub-encoding to TS1/3 on input line 397. +Package textcomp Info: Setting hls sub-encoding to TS1/3 on input line 398. +Package textcomp Info: Setting hlst sub-encoding to TS1/3 on input line 399. +Package textcomp Info: Setting hlct sub-encoding to TS1/5 on input line 400. +Package textcomp Info: Setting hlx sub-encoding to TS1/5 on input line 401. +Package textcomp Info: Setting hlce sub-encoding to TS1/5 on input line 402. +Package textcomp Info: Setting hlcn sub-encoding to TS1/5 on input line 403. +Package textcomp Info: Setting hlcw sub-encoding to TS1/5 on input line 404. +Package textcomp Info: Setting hlcf sub-encoding to TS1/5 on input line 405. +Package textcomp Info: Setting pplx sub-encoding to TS1/3 on input line 406. +Package textcomp Info: Setting pplj sub-encoding to TS1/3 on input line 407. +Package textcomp Info: Setting ptmx sub-encoding to TS1/4 on input line 408. +Package textcomp Info: Setting ptmj sub-encoding to TS1/4 on input line 409. +) (/usr/share/texlive/texmf-dist/tex/latex/psnfss/pifont.sty +Package: pifont 2005/04/12 PSNFSS-v9.2a Pi font support (SPQR) +LaTeX Font Info: Try loading font information for U+pzd on input line 63. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upzd.fd +File: upzd.fd 2001/06/04 font definitions for U/pzd. +) +LaTeX Font Info: Try loading font information for U+psy on input line 64. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upsy.fd +File: upsy.fd 2001/06/04 font definitions for U/psy. +)) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2012/11/06 v6.83m Hypertext links for LaTeX +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO) +Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO) +Package hobsub Info: Skipping package `infwarerr' (already loaded). +Package hobsub Info: Skipping package `ltxcmds' (already loaded). +Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO) +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is not detected. +Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) +Package etexcmds Info: Could not find \expanded. +(etexcmds) That can mean that you are not using pdfTeX 1.50 or +(etexcmds) that some package has redefined \expanded. +(etexcmds) In the latter case, load this package earlier. +Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) +Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO) +Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: pdfTeX >= 1.30 not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode not found. +Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO) +Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO) +Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO) +Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO) +Package: xcolor-patch 2011/01/30 xcolor patch +Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO) +Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO) +Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO) +Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2011/03/04 v1.3 Hooks for auxiliary files (HO) +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) +) +\@linkdim=\dimen120 +\Hy@linkcounter=\count110 +\Hy@pagecounter=\count111 +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count112 +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Hyper figures OFF on input line 4443. +Package hyperref Info: Link nesting OFF on input line 4448. +Package hyperref Info: Hyper index ON on input line 4451. +Package hyperref Info: Plain pages OFF on input line 4458. +Package hyperref Info: Backreferencing OFF on input line 4463. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4688. +\c@Hy@tempcnt=\count113 +(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip11 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 5041. +\XeTeXLinkMargin=\dimen121 +\Fld@menulength=\count114 +\Field@Width=\dimen122 +\Fld@charsize=\dimen123 +Package hyperref Info: Hyper figures OFF on input line 6295. +Package hyperref Info: Link nesting OFF on input line 6300. +Package hyperref Info: Hyper index ON on input line 6303. +Package hyperref Info: backreferencing OFF on input line 6310. +Package hyperref Info: Link coloring OFF on input line 6315. +Package hyperref Info: Link coloring with OCG OFF on input line 6320. +Package hyperref Info: PDF/A mode OFF on input line 6325. +LaTeX Info: Redefining \ref on input line 6365. +LaTeX Info: Redefining \pageref on input line 6369. +\Hy@abspage=\count115 +\c@Item=\count116 +\c@Hfootnote=\count117 +) + +Package hyperref Message: Driver (autodetected): hxetex. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hxetex.def +File: hxetex.def 2012/11/06 v6.83m Hyperref driver for XeTeX +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def +File: puenc.def 2012/11/06 v6.83m Hyperref: PDF Unicode definition (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/stringenc.sty +Package: stringenc 2011/12/02 v1.10 Convert strings between diff. encodings (HO) +) +\pdfm@box=\box32 +\c@Hy@AnnotLevel=\count118 +\HyField@AnnotCount=\count119 +\Fld@listcount=\count120 +\c@bookmark@seq@number=\count121 +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO) +Package rerunfilecheck Info: Feature \pdfmdfivesum is not available +(rerunfilecheck) (e.g. pdfTeX or LuaTeX with package `pdftexcmds'). +(rerunfilecheck) Therefore file contents cannot be checked efficiently +(rerunfilecheck) and the loading of the package is aborted. +) +\Hy@SectionHShift=\skip140 +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bookmark.sty +Package: bookmark 2011/12/02 v1.24 PDF bookmarks (HO) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bkm-dvipdfm.def +File: bkm-dvipdfm.def 2011/12/02 v1.24 bookmark driver for dvipdfm (HO) +\BKM@id=\count122 +)) (/usr/share/texlive/texmf-dist/tex/latex/booktabs/booktabs.sty +Package: booktabs 2005/04/14 v1.61803 publication quality tables +\heavyrulewidth=\dimen124 +\lightrulewidth=\dimen125 +\cmidrulewidth=\dimen126 +\belowrulesep=\dimen127 +\belowbottomsep=\dimen128 +\aboverulesep=\dimen129 +\abovetopsep=\dimen130 +\cmidrulesep=\dimen131 +\cmidrulekern=\dimen132 +\defaultaddspace=\dimen133 +\@cmidla=\count123 +\@cmidlb=\count124 +\@aboverulesep=\dimen134 +\@belowrulesep=\dimen135 +\@thisruleclass=\count125 +\@lastruleclass=\count126 +\@thisrulewidth=\dimen136 +) (/usr/share/texlive/texmf-dist/tex/latex/tools/longtable.sty +Package: longtable 2014/10/28 v4.11 Multi-page Table package (DPC) +\LTleft=\skip141 +\LTright=\skip142 +\LTpre=\skip143 +\LTpost=\skip144 +\LTchunksize=\count127 +\LTcapwidth=\dimen137 +\LT@head=\box33 +\LT@firsthead=\box34 +\LT@foot=\box35 +\LT@lastfoot=\box36 +\LT@cols=\count128 +\LT@rows=\count129 +\c@LT@tables=\count130 +\c@LT@chunks=\count131 +\LT@p@ftn=\toks23 +) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Package: anyfontsize 2007/11/22 anyfontsize.sty by pts +) (/usr/share/texlive/texmf-dist/tex/latex/enumitem/enumitem.sty +Package: enumitem 2011/09/28 v3.5.2 Customized lists +\labelindent=\skip145 +\enit@outerparindent=\dimen138 +\enit@toks=\toks24 +\enit@inbox=\box37 +\enitdp@description=\count132 +) (/usr/share/texlive/texmf-dist/tex/latex/wrapfig/wrapfig.sty +\wrapoverhang=\dimen139 +\WF@size=\dimen140 +\c@WF@wrappedlines=\count133 +\WF@box=\box38 +\WF@everypar=\toks25 +Package: wrapfig 2003/01/31 v 3.6 +) (/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.sty (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty +Package: expl3 2016/01/19 v6377 L3 programming layer (loader) +(/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3-code.tex +Package: expl3 2016/01/19 v6377 L3 programming layer (code) +L3 Module: l3bootstrap 2016/01/01 v6339 L3 Bootstrap code +L3 Module: l3names 2015/12/21 v6328 L3 Namespace for primitives +L3 Module: l3basics 2015/11/22 v6315 L3 Basic definitions +L3 Module: l3expan 2015/09/10 v5983 L3 Argument expansion +L3 Module: l3tl 2015/09/29 v6121 L3 Token lists +L3 Module: l3str 2016/01/03 v6357 L3 Strings +L3 Module: l3seq 2015/08/05 v5777 L3 Sequences and stacks +L3 Module: l3int 2016/01/05 v6366 L3 Integers +\c_max_int=\count134 +\l_tmpa_int=\count135 +\l_tmpb_int=\count136 +\g_tmpa_int=\count137 +\g_tmpb_int=\count138 +L3 Module: l3quark 2015/08/17 v5855 L3 Quarks +L3 Module: l3prg 2015/11/01 v6216 L3 Control structures +\g__prg_map_int=\count139 +L3 Module: l3clist 2015/09/02 v5901 L3 Comma separated lists +L3 Module: l3token 2015/11/11 v6249 L3 Experimental token manipulation +L3 Module: l3prop 2016/01/05 v6366 L3 Property lists +L3 Module: l3msg 2015/09/28 v6113 L3 Messages +L3 Module: l3file 2015/12/03 v6317 L3 File and I/O operations +\l_iow_line_count_int=\count140 +\l__iow_target_count_int=\count141 +\l__iow_current_line_int=\count142 +\l__iow_current_word_int=\count143 +\l__iow_current_indentation_int=\count144 +L3 Module: l3skip 2016/01/05 v6366 L3 Dimensions and skips +\c_zero_dim=\dimen141 +\c_max_dim=\dimen142 +\l_tmpa_dim=\dimen143 +\l_tmpb_dim=\dimen144 +\g_tmpa_dim=\dimen145 +\g_tmpb_dim=\dimen146 +\c_zero_skip=\skip146 +\c_max_skip=\skip147 +\l_tmpa_skip=\skip148 +\l_tmpb_skip=\skip149 +\g_tmpa_skip=\skip150 +\g_tmpb_skip=\skip151 +\c_zero_muskip=\muskip12 +\c_max_muskip=\muskip13 +\l_tmpa_muskip=\muskip14 +\l_tmpb_muskip=\muskip15 +\g_tmpa_muskip=\muskip16 +\g_tmpb_muskip=\muskip17 +L3 Module: l3keys 2015/11/17 v6284 L3 Key-value interfaces +\g__keyval_level_int=\count145 +\l_keys_choice_int=\count146 +L3 Module: l3fp 2015/08/25 v5890 L3 Floating points +\c__fp_leading_shift_int=\count147 +\c__fp_middle_shift_int=\count148 +\c__fp_trailing_shift_int=\count149 +\c__fp_big_leading_shift_int=\count150 +\c__fp_big_middle_shift_int=\count151 +\c__fp_big_trailing_shift_int=\count152 +\c__fp_Bigg_leading_shift_int=\count153 +\c__fp_Bigg_middle_shift_int=\count154 +\c__fp_Bigg_trailing_shift_int=\count155 +L3 Module: l3box 2015/08/09 v5822 L3 Experimental boxes +\c_empty_box=\box39 +\l_tmpa_box=\box40 +\l_tmpb_box=\box41 +\g_tmpa_box=\box42 +\g_tmpb_box=\box43 +L3 Module: l3coffins 2015/08/06 v5789 L3 Coffin code layer +\l__coffin_internal_box=\box44 +\l__coffin_internal_dim=\dimen147 +\l__coffin_offset_x_dim=\dimen148 +\l__coffin_offset_y_dim=\dimen149 +\l__coffin_x_dim=\dimen150 +\l__coffin_y_dim=\dimen151 +\l__coffin_x_prime_dim=\dimen152 +\l__coffin_y_prime_dim=\dimen153 +\c_empty_coffin=\box45 +\l__coffin_aligned_coffin=\box46 +\l__coffin_aligned_internal_coffin=\box47 +\l_tmpa_coffin=\box48 +\l_tmpb_coffin=\box49 +\l__coffin_display_coffin=\box50 +\l__coffin_display_coord_coffin=\box51 +\l__coffin_display_pole_coffin=\box52 +\l__coffin_display_offset_dim=\dimen154 +\l__coffin_display_x_dim=\dimen155 +\l__coffin_display_y_dim=\dimen156 +L3 Module: l3color 2014/08/23 v5354 L3 Experimental color support +L3 Module: l3sys 2015/09/25 v6087 L3 Experimental system/runtime functions +L3 Module: l3candidates 2016/01/14 v6376 L3 Experimental additions to l3kernel +\l__box_top_dim=\dimen157 +\l__box_bottom_dim=\dimen158 +\l__box_left_dim=\dimen159 +\l__box_right_dim=\dimen160 +\l__box_top_new_dim=\dimen161 +\l__box_bottom_new_dim=\dimen162 +\l__box_left_new_dim=\dimen163 +\l__box_right_new_dim=\dimen164 +\l__box_internal_box=\box53 +\l__coffin_bounding_shift_dim=\dimen165 +\l__coffin_left_corner_dim=\dimen166 +\l__coffin_right_corner_dim=\dimen167 +\l__coffin_bottom_corner_dim=\dimen168 +\l__coffin_top_corner_dim=\dimen169 +\l__coffin_scaled_total_height_dim=\dimen170 +\l__coffin_scaled_width_dim=\dimen171 +L3 Module: l3luatex 2015/11/11 v6250 L3 Experimental LuaTeX-specific functions +) (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def +File: l3xdvidpfmx.def 2015/11/11 v6250 L3 Experimental driver: xdvipdfmx +)) (/usr/share/texlive/texmf-dist/tex/latex/l3packages/xparse/xparse.sty +Package: xparse 2016/01/19 v6377 L3 Experimental document command parser +\l__xparse_current_arg_int=\count156 +\l__xparse_m_args_int=\count157 +\l__xparse_mandatory_args_int=\count158 +\l__xparse_processor_int=\count159 +\l__xparse_v_nesting_int=\count160 +) +Package: fontspec 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec-xetex.sty +Package: fontspec-xetex 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +\l_fontspec_script_int=\count161 +\l_fontspec_language_int=\count162 +\l_fontspec_strnum_int=\count163 +\l__fontspec_tmpa_dim=\dimen172 +\l__fontspec_tmpb_dim=\dimen173 +\l__fontspec_tmpc_dim=\dimen174 +\g__file_internal_ior=\read1 +(/usr/share/texlive/texmf-dist/tex/latex/base/fontenc.sty +Package: fontenc 2005/09/27 v1.99g Standard LaTeX package +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1enc.def +File: eu1enc.def 2010/05/27 v0.1h Experimental Unicode font encodings +) +LaTeX Font Info: Try loading font information for EU1+lmr on input line 105. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmr.fd +File: eu1lmr.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) (/usr/share/texlive/texmf-dist/tex/xelatex/xunicode/xunicode.sty +File: xunicode.sty 2011/09/09 v0.981 provides access to latin accents and many other characters in Unicode lower plane +(/usr/share/texmf/tex/latex/tipa/t3enc.def +File: t3enc.def 2001/12/31 T3 encoding +LaTeX Font Info: Try loading font information for EU1+lmss on input line 357. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmss.fd +File: eu1lmss.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) +\tipaTiiicode=\count164 +\tipasavetokens=\toks26 +\tipachecktokens=\toks27 +) +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \__fontspec_post_arg:w with sig. 'mmO{}' on line 353. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \fontspec with sig. 'om' on line 355. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmainfont with sig. 'om' on line 365. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setsansfont with sig. 'om' on line 375. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmonofont with sig. 'om' on line 385. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathrm with sig. 'om' on line 399. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setboldmathrm with sig. 'om' on line 407. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathsf with sig. 'om' on line 415. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathtt with sig. 'om' on line 423. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfamily with sig. 'mom' on line 437. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontface with sig. 'mom' on line 453. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \defaultfontfeatures with sig. 't+om' on line 467. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \addfontfeatures with sig. 'm' on line 529. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfeature with sig. 'mm' on line 540. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newAATfeature with sig. 'mmmm' on line 548. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newopentypefeature with sig. 'mmm' on line 556. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeature with sig. 'mm' on line 577. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeatureoption with sig. 'mmm' on line 586. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontscript with sig. 'mm' on line 590. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontlanguage with sig. 'mm' on line 594. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \DeclareFontsExtensions with sig. 'm' on line 599. +................................................. +\l__fontspec_tmp_int=\count165 +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.cfg) +LaTeX Info: Redefining \itshape on input line 2705. +LaTeX Info: Redefining \slshape on input line 2710. +LaTeX Info: Redefining \scshape on input line 2715. +LaTeX Info: Redefining \upshape on input line 2720. +\l__fontspec_em_int=\count166 +\l__fontspec_emdef_int=\count167 +LaTeX Info: Redefining \em on input line 2736. +LaTeX Info: Redefining \emph on input line 2742. +LaTeX Info: Redefining \- on input line 2746. +................................................. +. LaTeX info: "xparse/redefine-command" +. +. Redefining command \oldstylenums with sig. 'm' on line 2841. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \liningnums with sig. 'm' on line 2845. +................................................. +)) +Package hyperref Info: Option `colorlinks' set `true' on input line 87. +\px=\skip152 +\c@md@targetcount=\count168 +\mdcompactskip=\skip153 +\mdcompacttopsep=\skip154 +\dim@rem=\skip155 +\dim@ch=\skip156 +\md@height=\skip157 +\dim@marginbottom=\skip158 +\dim@paddingbottom=\skip159 +\md@interaction=\count169 +\mddefinitionsskip=\skip160 +\md@captionlen=\skip161 +\mdtoclevel=\count170 +\c@mdtoclevelbold=\count171 +\c@mdtocleveldots=\count172 +\mdtocskip=\skip162 +\mdpreskip=\skip163 +\presp=\skip164 +LaTeX Font Info: Try loading font information for EU1+lmtt on input line 801. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmtt.fd +File: eu1lmtt.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +\md@postskip=\skip165 +\ppresp=\skip166 +\md@thmcaption=\box54 +\md@defaultcolwidth=\skip167 +\mdtabularskip=\skip168 +\mdbibindentunit=\skip169 +\c@md@authorcount=\count173 +\c@mdx@authorcount=\count174 +\c@@mdTargetCount=\count175 +\@snippetBox=\box55 +\@snippetWidth=\skip170 +\@snippetHeight=\skip171 +\@snippetDepth=\skip172 +\c@snippets=\count176 +) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty +Package: geometry 2010/09/12 v5.6 Page Geometry +\Gm@cnth=\count177 +\Gm@cntv=\count178 +\c@Gm@tempcnt=\count179 +\Gm@bindingoffset=\dimen175 +\Gm@wd@mp=\dimen176 +\Gm@odd@mp=\dimen177 +\Gm@even@mp=\dimen178 +\Gm@layoutwidth=\dimen179 +\Gm@layoutheight=\dimen180 +\Gm@layouthoffset=\dimen181 +\Gm@layoutvoffset=\dimen182 +\Gm@dimlist=\toks28 +) (/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +\fancy@headwidth=\skip173 +\f@ncyO@elh=\skip174 +\f@ncyO@erh=\skip175 +\f@ncyO@olh=\skip176 +\f@ncyO@orh=\skip177 +\f@ncyO@elf=\skip178 +\f@ncyO@erf=\skip179 +\f@ncyO@olf=\skip180 +\f@ncyO@orf=\skip181 +) (build/P4Runtime-Spec.aux + +LaTeX Warning: Label `sec-example' multiply defined. + +) +\openout1 = `P4Runtime-Spec.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for TS1+cmr on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1cmr.fd +File: ts1cmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions +) +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for EU1/lmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T3/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for T3+cmr on input line 14. +(/usr/share/texmf/tex/latex/tipa/t3cmr.fd +File: t3cmr.fd 2001/12/31 TIPA font definitions +) +LaTeX Font Info: ... okay on input line 14. +\AtBeginShipoutBox=\box56 +Package hyperref Info: Link coloring ON on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2012/10/27 v2.43 Cross-referencing by name of section +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO) +) +\c@section@level=\count180 +) +LaTeX Info: Redefining \ref on input line 14. +LaTeX Info: Redefining \pageref on input line 14. +LaTeX Info: Redefining \nameref on input line 14. +................................................. +. fontspec info: "setup-math" +. +. Adjusting the maths setup (use [no-math] to avoid this). +................................................. +\symlegacymaths=\mathgroup7 +LaTeX Font Info: Overwriting symbol font `legacymaths' in version `bold' +(Font) OT1/cmr/m/n --> OT1/cmr/bx/n on input line 14. +LaTeX Font Info: Redeclaring math accent \acute on input line 14. +LaTeX Font Info: Redeclaring math accent \grave on input line 14. +LaTeX Font Info: Redeclaring math accent \ddot on input line 14. +LaTeX Font Info: Redeclaring math accent \tilde on input line 14. +LaTeX Font Info: Redeclaring math accent \bar on input line 14. +LaTeX Font Info: Redeclaring math accent \breve on input line 14. +LaTeX Font Info: Redeclaring math accent \check on input line 14. +LaTeX Font Info: Redeclaring math accent \hat on input line 14. +LaTeX Font Info: Redeclaring math accent \dot on input line 14. +LaTeX Font Info: Redeclaring math accent \mathring on input line 14. +LaTeX Font Info: Redeclaring math symbol \Gamma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Delta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Theta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Lambda on input line 14. +LaTeX Font Info: Redeclaring math symbol \Xi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Pi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Sigma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Upsilon on input line 14. +LaTeX Font Info: Redeclaring math symbol \Phi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Psi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Omega on input line 14. +LaTeX Font Info: Redeclaring math symbol \mathdollar on input line 14. +LaTeX Font Info: Redeclaring symbol font `operators' on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `normal' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/cmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `bold' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/cmr/bx/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) EU1/lmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/cmr/m/it --> EU1/lmr/m/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/cmr/bx/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/cmss/m/n --> EU1/lmss/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/cmtt/m/n --> EU1/lmtt/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) EU1/lmr/m/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' +(Font) OT1/cmr/bx/it --> EU1/lmr/bx/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/cmss/bx/n --> EU1/lmss/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/cmtt/m/n --> EU1/lmtt/bx/n on input line 14. +*geometry* driver: auto-detecting +*geometry* detected driver: xetex +*geometry* verbose mode - [ preamble ] result: +* driver: xetex +* paper: +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: +* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt) +* v-part:(T,H,B)=(72.26999pt, 632.3625pt, 90.3375pt) +* \paperwidth=614.295pt +* \paperheight=794.96999pt +* \textwidth=469.75502pt +* \textheight=632.3625pt +* \oddsidemargin=0.0pt +* \evensidemargin=0.0pt +* \topmargin=-37.0pt +* \headheight=30.0pt +* \headsep=25.0pt +* \topskip=11.0pt +* \footskip=30.0pt +* \marginparwidth=59.0pt +* \marginparsep=10.0pt +* \columnsep=10.0pt +* \skip\footins=10.0pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +resolve font stack: UtopiaStd-Regular + +\g__fontspec_family_UtopiaStd-Regular_int=\count181 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'UtopiaStd-Regular(0)' created for font 'UtopiaStd-Regular' with +. options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;" +. - 'small caps' (m/sc) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;+smcp;" +................................................. + +resolved font stack 'UtopiaStd-Regular' to: UtopiaStd-Regular +LaTeX Font Info: Try loading font information for U+msa on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Try loading font information for U+msb on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Try loading font information for U+stmry on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/Ustmry.fd) + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/bx/n' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 35. + +resolve font stack: LuxiMono + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +\g__fontspec_family_LuxiMono_int=\count182 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'LuxiMono(0)' created for font 'LuxiMono' with options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: <->"LuxiMono/OT:" +. - 'small caps' (m/sc) with NFSS spec.: +................................................. + +resolved font stack 'LuxiMono' to: LuxiMono +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/se-ascii-print.def +File: se-ascii-print.def 2011/12/02 v1.10 stringenc: Printable ASCII characters +) [1 + +] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[2] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <10.95> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 295. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Font Warning: Font shape `EU1/LuxiMono(0)/bx/n' undefined +(Font) using `EU1/LuxiMono(0)/m/n' instead on input line 295. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[3] + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/m/it' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 503. + +[4] [5] [6] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[7] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/reference-architecture.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[8] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[9] +File: build/single-embedded-controller.png Graphic file (type QTm) + [10] +File: build/single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-controllers.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-ha-controllers.png Graphic file (type QTm) + [11] [12] [13] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[14] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[15] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <12> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 1487. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1487. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1487. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[16] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[17] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (53.84203pt too wide) in paragraph at lines 1784--1787 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For all slave controllers, \EU1/LuxiMono(0)/bx/n/8.2125 status \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set to non-OK (with \EU1/LuxiMono(0)/bx/n/8.2125 status.code \EU1/UtopiaStd-Regular(0)/m/it/10.95 set to \EU1/LuxiMono(0)/bx/n/8.2125 google.rpc.ALREADY_EXISTS\EU1/UtopiaStd-Regular(0)/m/it/10.95 ). + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[18] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1821. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1845. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[19] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1886. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1931. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[20] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[21] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[22] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (12.45624pt too wide) in paragraph at lines 2155--2168 + [] + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2184. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2184. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[23] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[24] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2372. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2430. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[25] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2503. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2503. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2584. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2584. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[26] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.59204pt too wide) in paragraph at lines 2638--2640 +[]\EU1/LuxiMono(0)/bx/n/8.2125 BYTES\EU1/UtopiaStd-Regular(0)/m/it/10.95 , which signifies that this meter can be configured with rates expressed in bytes/second. + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2663. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2663. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (18.74199pt too wide) in paragraph at lines 2680--2687 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 carrying P4 standard annotations \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_in") \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_out")\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[27] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[28] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2821. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2821. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[29] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[30] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[31] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3044. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3044. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3091. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3091. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3129. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3129. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[32] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[33] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[34] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[35] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[36] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[37] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1629) in paragraph at lines 3733--3735 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For example, the following P4$[]$ objects involve complex types that need to be exposed in + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[38] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1454) in paragraph at lines 3781--3790 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 ification for all the named types in the P4$[]$ program. These named types are \EU1/LuxiMono(0)/bx/n/8.2125 struct\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 header\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + + +Underfull \hbox (badness 1831) in paragraph at lines 3781--3790 +\EU1/LuxiMono(0)/bx/n/8.2125 header_union\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 enum \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 serializable_enum\EU1/UtopiaStd-Regular(0)/m/it/10.95 ; for each of these we have a type specification mes- + [] + + +Underfull \hbox (badness 1845) in paragraph at lines 3781--3790 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 sage, respectively \EU1/LuxiMono(0)/bx/n/8.2125 P4StructTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnionTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4EnumTypeSpec \EU1/UtopiaStd-Regular(0)/m/it/10.95 and + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[39] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (33.06564pt too wide) in paragraph at lines 3816--3823 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 “binary string” types (\EU1/LuxiMono(0)/bx/n/8.2125 bit\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 int\EU1/UtopiaStd-Regular(0)/m/it/10.95 , and \EU1/LuxiMono(0)/bx/n/8.2125 varbit\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) are grouped together in the \EU1/LuxiMono(0)/bx/n/8.2125 P4BitstringLikeTypeSpec + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3833. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3833. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.46094pt too wide) in paragraph at lines 3870--3873 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 An invalid header union (i.e. all headers in the union are invalid) is represented by a \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnion + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[40] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[41] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4007. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4007. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[42] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (24.68944pt too wide) in paragraph at lines 4089--4094 +[]\EU1/LuxiMono(0)/bx/n/8.2125 translated_type\EU1/UtopiaStd-Regular(0)/m/it/10.95 , if and only if the P4 \EU1/LuxiMono(0)/bx/n/8.2125 type \EU1/UtopiaStd-Regular(0)/m/it/10.95 declaration was annotated with \EU1/LuxiMono(0)/bx/n/8.2125 @p4runtime_translation\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[43] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4176. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4176. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[44] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[45] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[46] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[47] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.53593pt too wide) in paragraph at lines 4590--4593 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 If the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 does not match the table description in the P4Info (e.g. the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 is \EU1/LuxiMono(0)/bx/n/8.2125 action_profile_member_id + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[48] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[49] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[50] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[51] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[52] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[53] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5156. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5156. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[54] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[55] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[56] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (9.29865pt too wide) in paragraph at lines 5404--5406 + []\EU1/lmr/bx/n/10.95 9.2.2.1.| Rules on Setting \EU1/LuxiMono(0)/bx/n/8.2125 max_size[] \EU1/UtopiaStd-Regular(0)/m/it/10.95 The valid values for \EU1/LuxiMono(0)/bx/n/8.2125 max_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 depend on the static \EU1/LuxiMono(0)/bx/n/8.2125 max_group_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[57] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[58] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[59] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[60] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5679. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5679. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5719. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5719. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1331) in paragraph at lines 5722--5729 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 A direct counter is a direct resource associated with a \EU1/LuxiMono(0)/bx/n/8.2125 TableEntry \EU1/UtopiaStd-Regular(0)/m/it/10.95 (see [][]Direct Resources[][]). The + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[61] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5796. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5889. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5889. + +[62] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5920. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5920. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[63] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5997. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5997. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6093. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6093. + +[64] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6103. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[65] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6227. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6227. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[66] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.93839pt too wide) in paragraph at lines 6338--6340 +[]\EU1/LuxiMono(0)/bx/n/8.2125 MODIFY\EU1/UtopiaStd-Regular(0)/m/it/10.95 : Modify the attributes of a given clone session entry, indexed by the given \EU1/LuxiMono(0)/bx/n/8.2125 clone_session_id\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +[67] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6376. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6376. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[68] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[69] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6512. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6512. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6556. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6556. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[70] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[71] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6754. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6754. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[72] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/error-report.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[73] +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <14.4> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 6878. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6878. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: Hyper reference `wildcard-reads' on page 74 undefined on input line 6900. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[74] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6980. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6980. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[75] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[76] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[77] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[78] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (34.34796pt too wide) in paragraph at lines 7264--7269 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If an error is encountered before even trying to attempt individual batch updates, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.66206pt too wide) in paragraph at lines 7273--7284 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 Otherwise, if one or more updates in the batch (\EU1/LuxiMono(0)/bx/n/8.2125 WriteRequest.updates\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) failed, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7320. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7320. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7320. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7320. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7320. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7320. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7320. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7320. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7320. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7320. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7320. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7320. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7320. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[79] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[80] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.4752pt too wide) in paragraph at lines 7549--7553 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 responding to \EU1/LuxiMono(0)/bx/n/8.2125 a \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 c\EU1/UtopiaStd-Regular(0)/m/it/10.95 , followed by a status \EU1/LuxiMono(0)/bx/n/8.2125 {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} + [] + +[81] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7635. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7635. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7635. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7635. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7635. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7635. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7635. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7635. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7635. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7635. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7635. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7635. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7635. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[82] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[83] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7758. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7758. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7758. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7758. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7758. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7758. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7758. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7758. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7758. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7758. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7758. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7758. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7758. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[84] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 7856--7859 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If a P4Runtime server supports both \EU1/LuxiMono(0)/bx/n/8.2125 SetForwardingPipelineConfig \EU1/UtopiaStd-Regular(0)/m/it/10.95 as well as returning the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[85] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[86] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[87] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[88] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8218. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[89] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8286. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8286. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8286. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8286. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8286. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8286. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8286. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8286. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8286. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8286. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8286. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8286. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8286. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[90] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/psa-metadata-translation.png Graphic file (type QTm) + [91] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[92] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[93] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[94] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[95] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[96] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 8794--8801 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 p4info-ext should include a Protobuf message definition for every extern type that can + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[97] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 4036) in paragraph at lines 8849--8856 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 P4Runtime also supports streaming arbitrary Protobuf messages between the server and the + [] + + +Underfull \hbox (badness 1629) in paragraph at lines 8849--8856 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 client, by including an \EU1/LuxiMono(0)/bx/n/8.2125 Any \EU1/UtopiaStd-Regular(0)/m/it/10.95 Protobuf field [[][]30[][]] named \EU1/LuxiMono(0)/bx/n/8.2125 other \EU1/UtopiaStd-Regular(0)/m/it/10.95 in both \EU1/LuxiMono(0)/bx/n/8.2125 p4.v1.StreamMessageRequest + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[98] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[99] +Underfull \hbox (badness 1997) in paragraph at lines 9055--9057 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 Table [][]7[][] lists P4$[]$ annotations introduced primarily for the purpose of adding features for the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[100] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[101] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.61781pt too wide) in paragraph at lines 9202--9209 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 In gRPC, the status of a RPC request is sent as metadata, whose size is limited by the \EU1/LuxiMono(0)/bx/n/8.2125 grpc.max_metadata_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[102] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 10000) in paragraph at lines 9293--9294 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Complex Types in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 0. html# sec- p4- + [] + + +Underfull \hbox (badness 4001) in paragraph at lines 9305--9306 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Google Cloud APIs Versioning - Backwards-Compatibility.” [][]\EU1/lmtt/m/n/10.95 https:// cloud. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9314--9315 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “gRPC Streaming RPCs in C++.” [][]\EU1/lmtt/m/n/10.95 https:// grpc. io/ docs/ tutorials/ basic/ c. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9323--9324 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “P4 Concurrency Model.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 0. html# sec- + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9326--9327 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” + [] + +[103] +Underfull \hbox (badness 10000) in paragraph at lines 9341--9342 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Protobuf OneOf Backwards-Compatibility Issues.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9347--9348 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Action Selector.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# sec- action- + [] + + +Underfull \hbox (badness 2409) in paragraph at lines 9356--9357 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Empty Group Action Appendix.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9359--9360 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Select Expressions in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 0. html# sec- + [] + + +Underfull \hbox (badness 1668) in paragraph at lines 9374--9375 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Any Protobuf Message.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ protocol- buffers/ docs/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9380--9381 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC C++ Error Details Library.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ grpc/ grpc/ blob/ master/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9383--9384 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC Canonical Status Codes.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ maps- booking/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9389--9390 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Protobuf MessageDifferencer in the C++ API.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + +[104] +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 9401. +[105] +Package atveryend Info: Empty hook `AfterLastShipout' on input line 9401. +(build/P4Runtime-Spec.aux) +Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 9401. +Package atveryend Info: Empty hook `AtEndAfterFileList' on input line 9401. + +LaTeX Font Warning: Some font shapes were not available, defaults substituted. + + +LaTeX Warning: There were undefined references. + + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 27536 strings out of 493638 + 517692 string characters out of 6146796 + 565360 words of memory out of 5000000 + 30638 multiletter control sequences out of 15000+600000 + 14633 words of font info for 98 fonts, out of 8000000 for 9000 + 1328 hyphenation exceptions out of 8191 + 48i,19n,81p,10429b,767s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on build/P4Runtime-Spec.pdf (105 pages). diff --git a/spec/v1.1.0/P4Runtime-Spec.pdf b/spec/v1.1.0/P4Runtime-Spec.pdf new file mode 100644 index 00000000..8db7cac1 Binary files /dev/null and b/spec/v1.1.0/P4Runtime-Spec.pdf differ diff --git a/spec/v1.1.0/P4Runtime-Spec.tex b/spec/v1.1.0/P4Runtime-Spec.tex new file mode 100644 index 00000000..3329d63f --- /dev/null +++ b/spec/v1.1.0/P4Runtime-Spec.tex @@ -0,0 +1,9401 @@ +\documentclass[11pt]{article} +% generated by Madoko, version 1.1.4 +%mdk-data-line={1} + + +\usepackage[heading-base={2},section-num={False},bib-label={hide},fontspec={True}]{madoko2} +\usepackage[top=1in, bottom=1.25in, left=1in, right=1in]{geometry} +\usepackage{fancyhdr} +%mdk-data-line={11} + + \setlength{\headheight}{30pt} + \setlength{\emergencystretch}{2em} + +\begin{document} + + + +{\mdfontfamily{UtopiaStd-Regular} +%mdk-data-line={203} +\mdxtitleblockstart{} +%mdk-data-line={203} +\mdxtitle{{\sffamily{\bfseries\mdline{203}P4Runtime Specification}}}%mdk + +%mdk-data-line={206} +\mdxtitlenote{{\sffamily{\bfseries\mdline{206}version 1.1.0}}}%mdk +\mdxauthorstart{} +%mdk-data-line={211} +\mdxauthorname{\mdline{211}The P4.org API Working Group}%mdk +\mdxauthorend +%mdk-data-line={220} +\mdxtitlefooter{{\sffamily{\bfseries\mdline{220}2020-02-03}}}%mdk +\mdtitleauthorrunning{}{}\mdxtitleblockend%mdk + +%mdk-data-line={205} +\begin{abstract}%mdk + +%mdk-data-line={206} +\noindent\mdline{206}P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.%mdk +%mdk +\end{abstract}%mdk +\mdline{214} +\begin{mdtoc}%mdk + +\section*{Contents}\label{sec-contents}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-introduction-and-scope}{\mdref{sec-introduction-and-scope}{1.\hspace*{0.5em}Introduction and Scope}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-language-version-applicability}{\mdref{sec-p4-language-version-applicability}{1.1.\hspace*{0.5em}P4 Language Version Applicability}}%mdk + +\mdtocitemx{sec-in-scope}{\mdref{sec-in-scope}{1.2.\hspace*{0.5em}In Scope}}%mdk + +\mdtocitemx{sec-not-in-scope}{\mdref{sec-not-in-scope}{1.3.\hspace*{0.5em}Not In Scope}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-terms-and-definitions}{\mdref{sec-terms-and-definitions}{2.\hspace*{0.5em}Terms and Definitions}}%mdk + +\mdtocitemx{sec-reference-architecture}{\mdref{sec-reference-architecture}{3.\hspace*{0.5em}Reference Architecture}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-idealized-workflow}{\mdref{sec-idealized-workflow}{3.1.\hspace*{0.5em}Idealized Workflow}}%mdk + +\mdtocitemx{sec-p4-as-behavioral-description-language}{\mdref{sec-p4-as-behavioral-description-language}{3.2.\hspace*{0.5em}P4 as a Behavioral Description Language}}%mdk + +\mdtocitemx{sec-alternative-workflows}{\mdref{sec-alternative-workflows}{3.3.\hspace*{0.5em}Alternative Workflows}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{\mdref{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{3.3.1.\hspace*{0.5em}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}}%mdk + +\mdtocitemx{sec-no-p4-source-available-p4info-available}{\mdref{sec-no-p4-source-available-p4info-available}{3.3.2.\hspace*{0.5em}No P4 Source Available, P4Info Available}}%mdk + +\mdtocitemx{sec-partial-p4info-and-p4-source-are-available}{\mdref{sec-partial-p4info-and-p4-source-are-available}{3.3.3.\hspace*{0.5em}Partial P4Info and P4 Source are Available}}%mdk + +\mdtocitemx{sec-p4info-role-based-subsets}{\mdref{sec-p4info-role-based-subsets}{3.3.4.\hspace*{0.5em}P4Info Role-Based Subsets}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-restarts}{\mdref{sec-restarts}{3.4.\hspace*{0.5em}P4Runtime State Across Restarts}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-controller-use-cases}{\mdref{sec-controller-use-cases}{4.\hspace*{0.5em}Controller Use-cases}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-single-embedded-controller}{\mdref{sec-single-embedded-controller}{4.1.\hspace*{0.5em}Single Embedded Controller}}%mdk + +\mdtocitemx{sec-single-remote-controller}{\mdref{sec-single-remote-controller}{4.2.\hspace*{0.5em}Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-single-remote-controller}{\mdref{sec-embedded-single-remote-controller}{4.3.\hspace*{0.5em}Embedded + Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-two-remote-controllers}{\mdref{sec-embedded-two-remote-controllers}{4.4.\hspace*{0.5em}Embedded + Two Remote Controllers}}%mdk + +\mdtocitemx{sec-embedded-controller-two-high-availability-remote-controllers}{\mdref{sec-embedded-controller-two-high-availability-remote-controllers}{4.5.\hspace*{0.5em}Embedded Controller + Two High-Availability Remote Controllers}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-master-slave-arbitration-and-controller-replication}{\mdref{sec-master-slave-arbitration-and-controller-replication}{5.\hspace*{0.5em}Master-Slave Arbitration and Controller Replication}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-default-role}{\mdref{sec-default-role}{5.1.\hspace*{0.5em}Default Role}}%mdk + +\mdtocitemx{sec-arbitration-role-config}{\mdref{sec-arbitration-role-config}{5.2.\hspace*{0.5em}Role Config}}%mdk + +\mdtocitemx{sec-mastership-updates}{\mdref{sec-mastership-updates}{5.3.\hspace*{0.5em}Rules for Handling \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}} Messages Received from Controllers}}%mdk + +\mdtocitemx{sec-mastership-notification}{\mdref{sec-mastership-notification}{5.4.\hspace*{0.5em}Mastership Notifications}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-the-p4info-message}{\mdref{sec-the-p4info-message}{6.\hspace*{0.5em}The P4Info Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-common-messages}{\mdref{sec-common-messages}{6.1.\hspace*{0.5em}Common Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-documentation-message}{\mdref{sec-documentation-message}{6.1.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}} Message}}%mdk + +\mdtocitemx{sec-preamble-message}{\mdref{sec-preamble-message}{6.1.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}} Message}}%mdk + +\mdtocitemx{sec-annotating-p4-entities-with-documentation}{\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3.\hspace*{0.5em}Annotating P4 Entities with \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-pkginfo-message}{\mdref{sec-pkginfo-message}{6.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}} Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-annotating-p4-code-with-pkginfo}{\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1.\hspace*{0.5em}Annotating P4 code with PkgInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-id-allocation}{\mdref{sec-id-allocation}{6.3.\hspace*{0.5em}ID Allocation for P4Info Objects}}%mdk + +\mdtocitemx{sec-p4info-objects}{\mdref{sec-p4info-objects}{6.4.\hspace*{0.5em}P4Info Objects}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table}{\mdref{sec-table}{6.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}}%mdk + +\mdtocitemx{sec-action}{\mdref{sec-action}{6.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}}%mdk + +\mdtocitemx{sec-p4info-action-profile}{\mdref{sec-p4info-action-profile}{6.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}}%mdk + +\mdtocitemx{sec-counter-directcounter}{\mdref{sec-counter-directcounter}{6.4.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}}%mdk + +\mdtocitemx{sec-meter-directmeter}{\mdref{sec-meter-directmeter}{6.4.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}}%mdk + +\mdtocitemx{sec-controller-packet-meta}{\mdref{sec-controller-packet-meta}{6.4.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}}%mdk + +\mdtocitemx{sec-valueset}{\mdref{sec-valueset}{6.4.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}}%mdk + +\mdtocitemx{sec-register}{\mdref{sec-register}{6.4.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}}%mdk + +\mdtocitemx{sec-digest}{\mdref{sec-digest}{6.4.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}}%mdk + +\mdtocitemx{sec-p4info-extern}{\mdref{sec-p4info-extern}{6.4.10.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{\mdref{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{6.5.\hspace*{0.5em}Support for Arbitrary P4 Types with P4TypeInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-fwd-pipe-config}{\mdref{sec-p4-fwd-pipe-config}{7.\hspace*{0.5em}P4 Forwarding-Pipeline Configuration}}%mdk + +\mdtocitemx{sec-general-principles-for-message-formatting}{\mdref{sec-general-principles-for-message-formatting}{8.\hspace*{0.5em}General Principles for Message Formatting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-set-unset-protobuf-field}{\mdref{sec-set-unset-protobuf-field}{8.1.\hspace*{0.5em}Set / Unset Protobuf Field}}%mdk + +\mdtocitemx{sec-read-write-symmetry}{\mdref{sec-read-write-symmetry}{8.2.\hspace*{0.5em}Read-Write Symmetry}}%mdk + +\mdtocitemx{sec-zero-as-reserved-value}{\mdref{sec-zero-as-reserved-value}{8.3.\hspace*{0.5em}Zero as Reserved Value}}%mdk + +\mdtocitemx{sec-bytestrings}{\mdref{sec-bytestrings}{8.4.\hspace*{0.5em}Bytestrings}}%mdk + +\mdtocitemx{sec-representation-of-arbitrary-p4-types}{\mdref{sec-representation-of-arbitrary-p4-types}{8.5.\hspace*{0.5em}Representation of Arbitrary P4 Types}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-problem-statement}{\mdref{sec-problem-statement}{8.5.1.\hspace*{0.5em}Problem Statement}}%mdk + +\mdtocitemx{sec-p4-type-specifications-in-p4infoproto}{\mdref{sec-p4-type-specifications-in-p4infoproto}{8.5.2.\hspace*{0.5em}P4 Type Specifications in p4info.proto}}%mdk + +\mdtocitemx{sec-p4data-in-p4runtime-proto}{\mdref{sec-p4data-in-p4runtime-proto}{8.5.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}} in p4runtime.proto}}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{8.5.4.\hspace*{0.5em}Example}}%mdk + +\mdtocitemx{sec-enum-serializable-enum-and-error}{\mdref{sec-enum-serializable-enum-and-error}{8.5.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}, serializable \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}}%mdk + +\mdtocitemx{sec-user-defined-types}{\mdref{sec-user-defined-types}{8.5.6.\hspace*{0.5em}User-defined types}}%mdk + +\mdtocitemx{sec-trade-off-for-v10-release}{\mdref{sec-trade-off-for-v10-release}{8.5.7.\hspace*{0.5em}Trade-off for v1.0 Release}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-entity-msgs}{\mdref{sec-p4-entity-msgs}{9.\hspace*{0.5em}P4 Entity Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table-entry}{\mdref{sec-table-entry}{9.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-match-format}{\mdref{sec-match-format}{9.1.1.\hspace*{0.5em}Match Format}}%mdk + +\mdtocitemx{sec-action-specification}{\mdref{sec-action-specification}{9.1.2.\hspace*{0.5em}Action Specification}}%mdk + +\mdtocitemx{sec-default-entry}{\mdref{sec-default-entry}{9.1.3.\hspace*{0.5em}Default Entry}}%mdk + +\mdtocitemx{sec-constant-tables}{\mdref{sec-constant-tables}{9.1.4.\hspace*{0.5em}Constant Tables}}%mdk + +\mdtocitemx{sec-table-wildcard-reads}{\mdref{sec-table-wildcard-reads}{9.1.5.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-direct-resources}{\mdref{sec-direct-resources}{9.1.6.\hspace*{0.5em}Direct Resources}}%mdk + +\mdtocitemx{sec-idle-timeout}{\mdref{sec-idle-timeout}{9.1.7.\hspace*{0.5em}Idle-timeout}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-and-group}{\mdref{sec-action-profile-member-and-group}{9.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-programming}{\mdref{sec-action-profile-member-programming}{9.2.1.\hspace*{0.5em}Action Profile Member Programming}}%mdk + +\mdtocitemx{sec-action-profile-group-programming}{\mdref{sec-action-profile-group-programming}{9.2.2.\hspace*{0.5em}Action Profile Group Programming}}%mdk + +\mdtocitemx{sec-oneshot}{\mdref{sec-oneshot}{9.2.3.\hspace*{0.5em}One Shot Action Selector Programming}}%mdk + +\mdtocitemx{sec-constraints-on-action-selector-programming}{\mdref{sec-constraints-on-action-selector-programming}{9.2.4.\hspace*{0.5em}Constraints on action selector programming}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-counterentry-directcounterentry}{\mdref{sec-counterentry-directcounterentry}{9.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directcounterentry}{\mdref{sec-directcounterentry}{9.3.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\mdtocitemx{sec-counterentry}{\mdref{sec-counterentry}{9.3.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-meterentry-directmeterentry}{\mdref{sec-meterentry-directmeterentry}{9.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directmeterentry}{\mdref{sec-directmeterentry}{9.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\mdtocitemx{sec-meterentry}{\mdref{sec-meterentry}{9.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-packetreplicationengineentry}{\mdref{sec-packetreplicationengineentry}{9.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-multicastgroupentry}{\mdref{sec-multicastgroupentry}{9.5.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}}%mdk + +\mdtocitemx{sec-clonesessionentry}{\mdref{sec-clonesessionentry}{9.5.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-valuesetentry}{\mdref{sec-valuesetentry}{9.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}}%mdk + +\mdtocitemx{sec-registerentry}{\mdref{sec-registerentry}{9.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}}%mdk + +\mdtocitemx{sec-digestentry}{\mdref{sec-digestentry}{9.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}}%mdk + +\mdtocitemx{sec-extern-entry}{\mdref{sec-extern-entry}{9.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-error-reporting-messages}{\mdref{sec-error-reporting-messages}{10.\hspace*{0.5em}Error Reporting Messages}}%mdk + +\mdtocitemx{sec-atomicity-of-individual-write-and-read-operations}{\mdref{sec-atomicity-of-individual-write-and-read-operations}{11.\hspace*{0.5em}Atomicity of Individual \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} Operations}}%mdk + +\mdtocitemx{sec-write-rpc}{\mdref{sec-write-rpc}{12.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-batching-and-ordering-of-updates}{\mdref{sec-batching-and-ordering-of-updates}{12.1.\hspace*{0.5em}Batching and Ordering of Updates}}%mdk + +\mdtocitemx{sec-batch-atomicity}{\mdref{sec-batch-atomicity}{12.2.\hspace*{0.5em}Batch Atomicity}}%mdk + +\mdtocitemx{sec-error-reporting}{\mdref{sec-error-reporting}{12.3.\hspace*{0.5em}Error Reporting}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-read-rpc}{\mdref{sec-read-rpc}{13.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-nomenclature}{\mdref{sec-nomenclature}{13.1.\hspace*{0.5em}Nomenclature}}%mdk + +\mdtocitemx{sec-wildcard-reads}{\mdref{sec-wildcard-reads}{13.2.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-batch-processing}{\mdref{sec-batch-processing}{13.3.\hspace*{0.5em}Batch Processing}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{13.3.1.\hspace*{0.5em}Example}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-parallelism-of-read-and-write-requests}{\mdref{sec-parallelism-of-read-and-write-requests}{13.4.\hspace*{0.5em}Parallelism of Read and Write Requests}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-setforwardingpipelineconfig-rpc}{\mdref{sec-setforwardingpipelineconfig-rpc}{14.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-getforwardingpipelineconfig-rpc}{\mdref{sec-getforwardingpipelineconfig-rpc}{15.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-p4runtime-stream-messages}{\mdref{sec-p4runtime-stream-messages}{16.\hspace*{0.5em}P4Runtime Stream Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-packet-i_o}{\mdref{sec-packet-i_o}{16.1.\hspace*{0.5em}Packet I/O}}%mdk + +\mdtocitemx{sec-master-arbitration-update}{\mdref{sec-master-arbitration-update}{16.2.\hspace*{0.5em}Master Arbitration Update}}%mdk + +\mdtocitemx{sec-digest-messages}{\mdref{sec-digest-messages}{16.3.\hspace*{0.5em}Digest Messages}}%mdk + +\mdtocitemx{sec-table-idle-timeout-notification}{\mdref{sec-table-idle-timeout-notification}{16.4.\hspace*{0.5em}Table Idle Timeout Notification}}%mdk + +\mdtocitemx{sec-architecture-specific-notifications}{\mdref{sec-architecture-specific-notifications}{16.5.\hspace*{0.5em}Architecture-Specific Notifications}}%mdk + +\mdtocitemx{sec-stream-error-reporting}{\mdref{sec-stream-error-reporting}{16.6.\hspace*{0.5em}Stream Error Reporting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-examples-of-streamerror-messages}{\mdref{sec-examples-of-streamerror-messages}{16.6.1.\hspace*{0.5em}Examples of \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}} Messages}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-capabilities-rpc}{\mdref{sec-capabilities-rpc}{17.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}} RPC}}%mdk + +\mdtocitemx{sec-portability-considerations}{\mdref{sec-portability-considerations}{18.\hspace*{0.5em}Portability Considerations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-psa-metadata-translation}{\mdref{sec-psa-metadata-translation}{18.1.\hspace*{0.5em}PSA Metadata Translation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-translation-of-port-numbers}{\mdref{sec-translation-of-port-numbers}{18.1.1.\hspace*{0.5em}Translation of Port Numbers}}%mdk + +\mdtocitemx{sec-translation-of-packet-io-header-fields}{\mdref{sec-translation-of-packet-io-header-fields}{18.1.2.\hspace*{0.5em}Translation of Packet-IO Header Fields}}%mdk + +\mdtocitemx{sec-translation-of-match-fields}{\mdref{sec-translation-of-match-fields}{18.1.3.\hspace*{0.5em}Translation of Match Fields}}%mdk + +\mdtocitemx{sec-translation-of-action-parameters}{\mdref{sec-translation-of-action-parameters}{18.1.4.\hspace*{0.5em}Translation of Action Parameters}}%mdk + +\mdtocitemx{sec-port-translation-for-psa-extern-apis}{\mdref{sec-port-translation-for-psa-extern-apis}{18.1.5.\hspace*{0.5em}Port Translation for PSA Extern APIs}}%mdk + +\mdtocitemx{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{\mdref{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{18.1.6.\hspace*{0.5em}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-versioning}{\mdref{sec-p4runtime-versioning}{19.\hspace*{0.5em}P4Runtime Versioning}}%mdk + +\mdtocitemx{sec-extending-p4runtime}{\mdref{sec-extending-p4runtime}{20.\hspace*{0.5em}Extending P4Runtime for non-PSA Architectures}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-p4runtime-for-architecture-specific-externs}{\mdref{sec-extending-p4runtime-for-architecture-specific-externs}{20.1.\hspace*{0.5em}Extending P4Runtime for Architecture-Specific Externs}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-the-p4info-message}{\mdref{sec-extending-the-p4info-message}{20.1.1.\hspace*{0.5em}Extending the P4Info message}}%mdk + +\mdtocitemx{sec-extending-the-p4runtime-service}{\mdref{sec-extending-the-p4runtime-service}{20.1.2.\hspace*{0.5em}Extending the P4Runtime Service}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-architecture-specific-table-extensions}{\mdref{sec-architecture-specific-table-extensions}{20.2.\hspace*{0.5em}Architecture-Specific Table Extensions}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-new-match-types}{\mdref{sec-new-match-types}{20.2.1.\hspace*{0.5em}New Match Types}}%mdk + +\mdtocitemx{sec-new-table-properties}{\mdref{sec-new-table-properties}{20.2.2.\hspace*{0.5em}New Table Properties}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-known-limitations-of-current-p4runtime-version}{\mdref{sec-known-limitations-of-current-p4runtime-version}{21.\hspace*{0.5em}Known Limitations of Current P4Runtime Version}}%mdk + +\mdtocitemx{sec-security-concerns-for-p4runtime}{\mdref{sec-security-concerns-for-p4runtime}{22.\hspace*{0.5em}Security concerns for P4Runtime}}%mdk + +\mdtocitemx{sec-appendix}{\mdref{sec-appendix}{A.\hspace*{0.5em}Appendix}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-revision-history}{\mdref{sec-revision-history}{A.1.\hspace*{0.5em}Revision History}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-changes-in-v110}{\mdref{sec-changes-in-v110}{A.1.1.\hspace*{0.5em}Changes in v1.1.0}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-annotations}{\mdref{sec-p4-annotations}{A.2.\hspace*{0.5em}P4 Annotations}}%mdk + +\mdtocitemx{sec-value-set-example}{\mdref{sec-value-set-example}{A.3.\hspace*{0.5em}A More Complex Value Set Example}}%mdk + +\mdtocitemx{sec-guidelines-for-implementations}{\mdref{sec-guidelines-for-implementations}{A.4.\hspace*{0.5em}Guidelines for Implementations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-grpc-metadata-maximum-size}{\mdref{sec-grpc-metadata-maximum-size}{A.4.1.\hspace*{0.5em}gRPC Metadata Maximum Size}}%mdk + +\mdtocitemx{sec-grpc-server-maximum-receive-message-size}{\mdref{sec-grpc-server-maximum-receive-message-size}{A.4.2.\hspace*{0.5em}gRPC Server Maximum Receive Message Size}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-bibliography}{\mdref{sec-bibliography}{References}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{215} +\begin{mdtoc}%mdk + +\section*{Figures}\label{sec-figures}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{fig-reference-architecture}{\mdref{fig-reference-architecture}{\mdcaptionlabel{1}. P4Runtime Reference Architecture.}}%mdk + +\mdtocitemx{fig-single-embedded-controller}{\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}. Use-Case: Single Embedded Controller}}%mdk + +\mdtocitemx{fig-single-remote-controller}{\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}. Use-Case: Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-single-remote-controller}{\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}. Use-Case: Embedded Plus Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-controllers}{\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}. Use-Case: Embedded Plus Two Remote Controllers}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-ha-controllers}{\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}. Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk + +\mdtocitemx{fig-error-report}{\mdref{fig-error-report}{\mdcaptionlabel{7}. P4Runtime Error Report Message Format}}%mdk + +\mdtocitemx{fig-psa-metadata-translation}{\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}. P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{216} +\begin{mdtoc}%mdk + +\section*{Tables}\label{sec-tables}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{tab-mapping-p4-obj-ids}{\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}. Mapping of P4Info object type to 8-bit ID prefix value}}%mdk + +\mdtocitemx{tab-format-p4-obj-ids}{\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}. Format of P4Info object IDs}}%mdk + +\mdtocitemx{tab-exmpl-p4-obj-ids}{\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}. Example of statically-assigned P4Info object IDs}}%mdk + +\mdtocitemx{tab-valid-bytestring-encoding}{\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}. Examples of Valid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-invalid-bytestring-encoding}{\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}. Examples of Invalid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-p4-type-usage}{\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}. P4 Type Usage}}%mdk + +\mdtocitemx{tab-p4-annotations}{\mdref{tab-p4-annotations}{\mdcaptionlabel{7}. P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk + +%mdk-data-line={218} +\section{\mdline{218}1.\hspace*{0.5em}\mdline{218}Introduction and Scope}\label{sec-introduction-and-scope}%mdk%mdk + +%mdk-data-line={220} +\noindent\mdline{220}This document is published by the \mdline{220}\emph{P4.org API Working Group}\mdline{220}, which was +chartered\mdline{221}~[\mdcite{p4apiwgcharter}{16}]\mdline{221} to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called \mdline{223}\emph{P4Runtime}\mdline{223}. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +\mdline{226}\href{https://github.com/p4lang/p4runtime/tree/v1.1.0/proto}{https://github.com/p4lang/p4runtime/tree/v1.1.0/proto}\mdline{226}.%mdk + +%mdk-data-line={228} +\subsection{\mdline{228}1.1.\hspace*{0.5em}\mdline{228}P4 Language Version Applicability}\label{sec-p4-language-version-applicability}%mdk%mdk + +%mdk-data-line={230} +\noindent\mdline{230}P4Runtime is designed to be implemented in conjunction with the P4\mdline{230}\mdsub{16}\mdline{230} language +version or later. P4\mdline{231}\mdsub{14}\mdline{231} programs should be translated into P4\mdline{231}\mdsub{16}\mdline{231} to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P4\mdline{233}\mdsub{16}\mdline{233} 1.0, but were introduced in P4\mdline{233}\mdsub{16}\mdline{233} 1.1.0\mdline{233}~[\mdcite{p4revisions110}{28}]\mdline{233}. For +this version of P4Runtime, we recommend using P4\mdline{234}\mdsub{16}\mdline{234} 1.2.0\mdline{234}~[\mdcite{p4spec}{1}]\mdline{234}.%mdk + +%mdk-data-line={236} +\subsection{\mdline{236}1.2.\hspace*{0.5em}\mdline{236}In Scope}\label{sec-in-scope}%mdk%mdk + +%mdk-data-line={238} +\noindent\mdline{238}This specification document defines the \mdline{238}\emph{semantics}\mdline{238} of \mdline{238}\emph{P4Runtime}\mdline{238} messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime:%mdk + +%mdk-data-line={242} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={242} +\item\mdline{242}Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA)\mdline{243}~[\mdcite{psa}{18}]\mdline{243} externs (\mdline{243}e.g.\mdline{243} Counters, Meters, Action +Profiles, \mdline{244}\dots{}\mdline{244}). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0.%mdk + +%mdk-data-line={246} +\item\mdline{246}Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism.%mdk + +%mdk-data-line={248} +\item\mdline{248}Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy.%mdk + +%mdk-data-line={251} +\item\mdline{251}Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities.%mdk + +%mdk-data-line={253} +\item\mdline{253}Packet I/O to enable streaming packets to \mdline{253}\&\mdline{253} from the control plane.%mdk + +%mdk-data-line={254} +\item\mdline{254}Batching support, with different atomicity guarantees.%mdk + +%mdk-data-line={255} +\item\mdline{255}In-the-field device-reconfiguration with a new P4 data plane.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={257} +\noindent\mdline{257}The following are in the scope of this specification document:%mdk + +%mdk-data-line={259} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={259} +\item\mdline{259}Rationale for the P4Runtime design.%mdk + +%mdk-data-line={260} +\item\mdline{260}Reference architecture and use-cases for deploying a P4Runtime service.%mdk + +%mdk-data-line={261} +\item\mdline{261}Detailed description of the API semantics.%mdk + +%mdk-data-line={262} +\item\mdline{262}Requirements for conformant implementations of the API.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={264} +\subsection{\mdline{264}1.3.\hspace*{0.5em}\mdline{264}Not In Scope}\label{sec-not-in-scope}%mdk%mdk + +%mdk-data-line={266} +\noindent\mdline{266}The following are not in scope of P4Runtime:%mdk + +%mdk-data-line={268} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={268} +\item\mdline{268}Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +\mdline{273}[\mdcite{openconfig}{34}]\mdline{273}. An open source implementation of these APIs is also in progress +as part of the Stratum project\mdline{274}~[\mdcite{stratum}{36}]\mdline{274}.%mdk + +%mdk-data-line={275} +\item\mdline{275}Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={280} +\noindent\mdline{280}The following are not in scope of this specification document:%mdk + +%mdk-data-line={282} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={282} +\item\mdline{282}Description of the P4 programming language; it is assumed that the reader is +already familiar with P4\mdline{283}\mdsub{16}\mdline{283}~[\mdcite{p4spec}{1}]\mdline{283}.%mdk + +%mdk-data-line={284} +\item\mdline{284}Descriptions of gRPC and Protobuf files in general.%mdk + +%mdk-data-line={285} +\item\mdline{285}Controller\mdline{285}~\mdref{sec-arbitration-role-config}{role}\mdline{285} definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={289} +\section{\mdline{289}2.\hspace*{0.5em}\mdline{289}Terms and Definitions}\label{sec-terms-and-definitions}%mdk%mdk + +%mdk-data-line={291} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries arbitration}}%mdk + +%mdk-data-line={291} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{291}Refers to the process through which P4Runtime ensures that at any given +time, there is a single master (\mdline{292}i.e.\mdline{292} a client with write access) for a given +role. Also referred to as \mdline{293}\textquotedblleft{}master-slave arbitration\textquotedblright{}\mdline{293}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries client}}%mdk + +%mdk-data-line={295} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{295}The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries COS}}%mdk + +%mdk-data-line={299} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{299}Class of Service. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries device}}%mdk + +%mdk-data-line={301} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{301}Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries entity}}%mdk + +%mdk-data-line={305} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{305}An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries gRPC}}%mdk + +%mdk-data-line={308} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{308}gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +\mdline{309}[\mdcite{grpc}{9}]\mdline{309}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries HA}}%mdk + +%mdk-data-line={311} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{311}High-Availability. Refers to a redundancy architecture. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Instrumentation}}%mdk + +%mdk-data-line={313} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{313}The part of the P4Runtime server which implements the calls to the device or +target native \mdline{314}\textquotedblleft{}SDK\textquotedblright{}\mdline{314} or backend. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries IPC}}%mdk + +%mdk-data-line={316} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{316}Inter-Process Communication. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Blob}}%mdk + +%mdk-data-line={318} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{318}A more colloquial term for P4 Device Config (Blob = Binary Large Object). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Device Config}}%mdk + +%mdk-data-line={320} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{320}The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its \mdline{322}\textquotedblleft{}program.\textquotedblright{}\mdline{322} +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4Info}}%mdk + +%mdk-data-line={324} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{324}Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4RT}}%mdk + +%mdk-data-line={328} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{328}Abbreviation for P4Runtime. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Protobuf (Protocol Buffers)}}%mdk + +%mdk-data-line={330} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{330}The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See\mdline{331}~[\mdcite{proto}{20}]\mdline{331}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries PSA}}%mdk + +%mdk-data-line={333} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{333}Portable Switch Architecture\mdline{333}~[\mdcite{psa}{18}]\mdline{333}; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RPC}}%mdk + +%mdk-data-line={337} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{337}Remote Procedure Call. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RTT}}%mdk + +%mdk-data-line={339} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{339}Round-trip time. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN}}%mdk + +%mdk-data-line={341} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{341}Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network \mdline{346}\emph{controller}\mdline{346}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN port}}%mdk + +%mdk-data-line={348} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{348}A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries server}}%mdk + +%mdk-data-line={352} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{352}The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries stream}}%mdk + +%mdk-data-line={356} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{356}Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (\mdline{357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{357}), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and master-slave arbitration, among other +things. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries switch config}}%mdk + +%mdk-data-line={362} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{362}Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries target}}%mdk + +%mdk-data-line={367} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{367}The hardware or software entity which \mdline{367}\textquotedblleft{}executes\textquotedblright{}\mdline{367} the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with \mdline{368}\textquotedblleft{}device\textquotedblright{}\mdline{368}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries URI}}%mdk + +%mdk-data-line={370} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{370}Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={374} +\section{\mdline{374}3.\hspace*{0.5em}\mdline{374}Reference Architecture}\label{sec-reference-architecture}%mdk%mdk + +%mdk-data-line={376} +\noindent\mdline{376}Figure\mdline{376}~\mdref{fig-reference-architecture}{\mdcaptionlabel{1}}\mdline{376} represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. A multi-master protocol allows more than +one controller to participate, and a role-based arbitration scheme ensures only +one controller has write access to each read/write entity, or the pipeline +config itself. Any controller may perform read access to any entity or the +pipeline config. Later sections describe this in detail. For the sake of +brevity, the term controller may refer to one or more controllers.%mdk + +%mdk-data-line={385} +\mdline{385}The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +\mdline{388}[\mdcite{p4runtimerepo}{14}]\mdline{388}. It may be compiled via protoc\mdline{388} \mdline{388}\textemdash{}\mdline{388} the Protobuf compiler\mdline{388} \mdline{388}\textemdash{}\mdline{388} +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server.%mdk + +%mdk-data-line={393} +\mdline{393}Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository\mdline{394}~[\mdcite{pirepo}{15}]\mdline{394}. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, \mdline{396}e.g.\mdline{396} via callbacks, thus reducing the burden of implementing +P4Runtime.%mdk + +%mdk-data-line={399} +\mdline{399}The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard.%mdk + +%mdk-data-line={403} +\mdline{403}The controller can also set the \mdline{403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{403}, which amounts to +installing and running the compiled P4 program output, which is included in the +\mdline{405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{405} Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +\mdline{407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{407} to retrieve the device config and the P4Info.%mdk + +%mdk-data-line={410} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={411} +\noindent\mdline{411}\includegraphics[keepaspectratio=true,height=7cm]{build/reference-architecture}{}\mdline{411}%mdk + +%mdk-data-line={412} +\mdhr{}%mdk + +%mdk-data-line={413} +\noindent\mdline{413}\mdcaption{\textbf{Figure~\mdcaptionlabel{1}.}~\mdcaptiontext{P4Runtime Reference Architecture.}}%mdk +%mdk +\end{mdcenter}\label{fig-reference-architecture}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={417} +\subsection{\mdline{417}3.1.\hspace*{0.5em}\mdline{417}Idealized Workflow}\label{sec-idealized-workflow}%mdk%mdk + +%mdk-data-line={419} +\noindent\mdline{419}In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the \mdline{420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{420} +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a \mdline{422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{422} +RPC. Metadata in the P4Info describes both the overall program itself +(\mdline{424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{424}) as well as all entity instances derived from the P4 program\mdline{424} \mdline{424}\textemdash{}\mdline{424} +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise \mdline{426}\textquotedblleft{}handle\textquotedblright{}\mdline{426} used in API +calls.%mdk + +%mdk-data-line={429} +\mdline{429}In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible.%mdk + +%mdk-data-line={435} +\mdline{435}In some use cases, it is expected that a controller will store a +collection of multiple P4 \mdline{436}\textquotedblleft{}packages\textquotedblright{}\mdline{436}, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the \mdline{438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{438} from the target via the +\mdline{439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineRequest}}}\mdline{439} RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state.%mdk + +%mdk-data-line={443} +\subsection{\mdline{443}3.2.\hspace*{0.5em}\mdline{443}P4 as a Behavioral Description Language}\label{sec-p4-as-behavioral-description-language}%mdk%mdk + +%mdk-data-line={445} +\noindent\mdline{445}P4 can be considered a behavioral description of a switching device which may or +may not execute \mdline{446}\textquotedblleft{}P4\textquotedblright{}\mdline{446} natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a \mdline{448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineRequest}}}\mdline{448} to +change its pipeline \mdline{449}\textquotedblleft{}program\textquotedblright{}\mdline{449}, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device.%mdk + +%mdk-data-line={455} +\mdline{455}While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API.%mdk + +%mdk-data-line={464} +\mdline{464}In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the \mdline{465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{465} +message as well as the embedded \mdline{466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{466} fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections.%mdk + +%mdk-data-line={470} +\subsection{\mdline{470}3.3.\hspace*{0.5em}\mdline{470}Alternative Workflows}\label{sec-alternative-workflows}%mdk%mdk + +%mdk-data-line={472} +\noindent\mdline{472}Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary.%mdk + +%mdk-data-line={476} +\subsubsection{\mdline{476}3.3.1.\hspace*{0.5em}\mdline{476}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}\label{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}%mdk%mdk + +%mdk-data-line={478} +\noindent\mdline{478}In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +\mdline{480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{480}. The device\mdline{480}'\mdline{480}s configuration might be derived via some other +means to implement the P4 source code\mdline{481}'\mdline{481}s intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane.%mdk + +%mdk-data-line={485} +\subsubsection{\mdline{485}3.3.2.\hspace*{0.5em}\mdline{485}No P4 Source Available, P4Info Available}\label{sec-no-p4-source-available-p4info-available}%mdk%mdk + +%mdk-data-line={487} +\noindent\mdline{487}In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are:%mdk + +%mdk-data-line={490} +\begin{enumerate}%mdk + +%mdk-data-line={490} +\item{} +%mdk-data-line={490} +\mdline{490}The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security.%mdk%mdk + +%mdk-data-line={493} +\item{} +%mdk-data-line={493} +\mdline{493}The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={496} +\noindent\mdline{496}As discussed in Section\mdline{496}~\mdref{sec-p4-as-behavioral-description-language}{3.2}\mdline{496}, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, \mdline{499}e.g.\mdline{499} documentation.%mdk + +%mdk-data-line={501} +\subsubsection{\mdline{501}3.3.3.\hspace*{0.5em}\mdline{501}Partial P4Info and P4 Source are Available}\label{sec-partial-p4info-and-p4-source-are-available}%mdk%mdk + +%mdk-data-line={503} +\noindent\mdline{503}In this situation, a subset of the target\mdline{503}'\mdline{503}s pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code.%mdk + +%mdk-data-line={510} +\subsubsection{\mdline{510}3.3.4.\hspace*{0.5em}\mdline{510}P4Info Role-Based Subsets}\label{sec-p4info-role-based-subsets}%mdk%mdk + +%mdk-data-line={512} +\noindent\mdline{512}In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more.%mdk + +%mdk-data-line={516} +\subsection{\mdline{516}3.4.\hspace*{0.5em}\mdline{516}P4Runtime State Across Restarts}\label{sec-restarts}%mdk%mdk + +%mdk-data-line={518} +\noindent\mdline{518}All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade.%mdk + +%mdk-data-line={524} +\section{\mdline{524}4.\hspace*{0.5em}\mdline{524}Controller Use-cases}\label{sec-controller-use-cases}%mdk%mdk + +%mdk-data-line={526} +\noindent\mdline{526}P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +\mdline{528}\mdref{sec-master-slave-arbitration-and-controller-replication}{section}\mdline{528}. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime\mdline{530}'\mdline{530}s flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex.%mdk + +%mdk-data-line={533} +\subsection{\mdline{533}4.1.\hspace*{0.5em}\mdline{533}Single Embedded Controller}\label{sec-single-embedded-controller}%mdk%mdk + +%mdk-data-line={535} +\noindent\mdline{535}Figure\mdline{535}~\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}}\mdline{535} shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases.%mdk + +%mdk-data-line={540} +\mdline{540}P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC.%mdk + +%mdk-data-line={545} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={546} +\noindent\mdline{546}\includegraphics[keepaspectratio=true,height=6cm]{build/single-embedded-controller}{}\mdline{546}%mdk + +%mdk-data-line={547} +\mdhr{}%mdk + +%mdk-data-line={548} +\noindent\mdline{548}\mdcaption{\textbf{Figure~\mdcaptionlabel{2}.}~\mdcaptiontext{Use-Case: Single Embedded Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-embedded-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={552} +\subsection{\mdline{552}4.2.\hspace*{0.5em}\mdline{552}Single Remote Controller}\label{sec-single-remote-controller}%mdk%mdk + +%mdk-data-line={554} +\noindent\mdline{554}Figure\mdline{554}~\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}}\mdline{554} shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections.%mdk + +%mdk-data-line={559} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={560} +\noindent\mdline{560}\includegraphics[keepaspectratio=true,height=7cm]{build/single-remote-controller}{}\mdline{560}%mdk + +%mdk-data-line={561} +\mdhr{}%mdk + +%mdk-data-line={562} +\noindent\mdline{562}\mdcaption{\textbf{Figure~\mdcaptionlabel{3}.}~\mdcaptiontext{Use-Case: Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={566} +\subsection{\mdline{566}4.3.\hspace*{0.5em}\mdline{566}Embedded\mdline{566} \mdline{566}+ Single Remote Controller}\label{sec-embedded-single-remote-controller}%mdk%mdk + +%mdk-data-line={568} +\noindent\mdline{568}Figure\mdline{568}~\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}}\mdline{568} illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller.%mdk + +%mdk-data-line={575} +\mdline{575}For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables.%mdk + +%mdk-data-line={579} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={580} +\noindent\mdline{580}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-single-remote-controller}{}\mdline{580}%mdk + +%mdk-data-line={581} +\mdhr{}%mdk + +%mdk-data-line={582} +\noindent\mdline{582}\mdcaption{\textbf{Figure~\mdcaptionlabel{4}.}~\mdcaptiontext{Use-Case: Embedded Plus Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={587} +\subsection{\mdline{587}4.4.\hspace*{0.5em}\mdline{587}Embedded\mdline{587} \mdline{587}+ Two Remote Controllers}\label{sec-embedded-two-remote-controllers}%mdk%mdk + +%mdk-data-line={589} +\noindent\mdline{589}Figure\mdline{589}~\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}}\mdline{589} illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +\mdline{592}e.g.\mdline{592} routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership.%mdk + +%mdk-data-line={595} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={596} +\noindent\mdline{596}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-controllers}{}\mdline{596}%mdk + +%mdk-data-line={597} +\mdhr{}%mdk + +%mdk-data-line={598} +\noindent\mdline{598}\mdcaption{\textbf{Figure~\mdcaptionlabel{5}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={603} +\subsection{\mdline{603}4.5.\hspace*{0.5em}\mdline{603}Embedded Controller\mdline{603} \mdline{603}+ Two High-Availability Remote Controllers}\label{sec-embedded-controller-two-high-availability-remote-controllers}%mdk%mdk + +%mdk-data-line={605} +\noindent\mdline{605}Figure\mdline{605}~\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}}\mdline{605} illustrates a single +embedded controller plus two remote controllers in an active-standby HA +(High-Availability) configuration. Controller \mdline{607}\#\mdline{607}1 is the active controller and is +in charge of some entities. If it fails, Controller \mdline{608}\#\mdline{608}2 takes over and manages +the tables formerly owned by Controller \mdline{609}\#\mdline{609}1. The mechanics of HA architectures +are beyond the scope of this document, but the P4Runtime multi-master +arbitration scheme supports it.%mdk + +%mdk-data-line={613} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={614} +\noindent\mdline{614}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-ha-controllers}{}\mdline{614}%mdk + +%mdk-data-line={615} +\mdhr{}%mdk + +%mdk-data-line={616} +\noindent\mdline{616}\mdcaption{\textbf{Figure~\mdcaptionlabel{6}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-ha-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={621} +\section{\mdline{621}5.\hspace*{0.5em}\mdline{621}Master-Slave Arbitration and Controller Replication}\label{sec-master-slave-arbitration-and-controller-replication}%mdk%mdk + +%mdk-data-line={624} +\noindent\mdline{624}The P4Runtime interface allows multiple controllers to be connected to the +P4Runtime server running on the device at the same time for the following +reasons:%mdk + +%mdk-data-line={628} +\begin{enumerate}%mdk + +%mdk-data-line={628} +\item{} +%mdk-data-line={628} +\mdline{628}Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, \mdline{629}\textquotedblleft{}roles\textquotedblright{}\mdline{629} (or \mdline{629}\textquotedblleft{}realms\textquotedblright{}\mdline{629}) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +master and the rest are slaves. Role definition, \mdline{632}i.e.\mdline{632} how P4 entities get +assigned to each role, is \mdline{633}\textbf{out-of-scope}\mdline{633} of this document.%mdk%mdk + +%mdk-data-line={635} +\item{} +%mdk-data-line={635} +\mdline{635}Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby slave controllers. These can already have a connection +open, which can help them become master more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={641} +\noindent\mdline{641}To support multiple controllers, P4Runtime uses the streaming channel (available +via \mdline{642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{642} RPC) for session management. The workflow is described as +follows:%mdk + +%mdk-data-line={645} +\begin{itemize}%mdk + +%mdk-data-line={645} +\item{} +%mdk-data-line={645} +\mdline{645}Each controller instance (\mdline{645}e.g.\mdline{645} a controller process) can participate in one or +more roles. For each (\mdline{646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{646}, \mdline{646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{646}), the controller receives an +\mdline{647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{647}. This \mdline{647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{647} can be the same for different roles and/or +devices, as long as the tuple (\mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{648}, \mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{648}, \mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{648}) is +unique. For each (\mdline{649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{649}, \mdline{649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{649}) that the controller wishes to +control, it establishes a \mdline{650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{650} with the P4Runtime server +responsible for that device, and sends a \mdline{651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{651} message +containing that tuple of (\mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{652}, \mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{652}, \mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{652}) values. The +P4Runtime server selects a master independently for each (\mdline{653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{653}, +\mdline{654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{654}) pair. The master is the client that has the highest \mdline{654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{654} +that the device has ever received for the same (\mdline{655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{655}, +\mdline{656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{656}) values. A connection between a controller instance and a device id +\mdline{657}\textemdash{}\mdline{657} which involves a persistent \mdline{657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{657} \mdline{657}\textemdash{}\mdline{657} can be referred to as a +P4Runtime client.%mdk + +%mdk-data-line={660} +\mdline{660}Note that the P4Runtime server does not assign a \mdline{660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{660} or \mdline{660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{660} to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the \mdline{662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{662} values used for each +\mdline{663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{663}. The P4Runtime server only keeps track of the (\mdline{663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{663}, +\mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{664}, \mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{664}) of each \mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{664} that has sent a successful +\mdline{665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{665} message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +\mdline{667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{667} message to identify which client is making the \mdline{667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{667}, +not only the \mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{668}. This enables controllers to re-use the same +numeric \mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{669} values across different (\mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{669}, \mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{669}) +pairs. P4Runtime does not require \mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{670} values be reused across such +different (\mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{671}, \mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{671}) pairs; it allows it.%mdk%mdk + +%mdk-data-line={673} +\item{} +%mdk-data-line={673} +\mdline{673}To start a controller session, a controller first opens a bidirectional stream +channel to the server via the \mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{674} RPC for each device. This stream +will be used for two purposes:%mdk + +%mdk-data-line={677} +\begin{itemize}%mdk + +%mdk-data-line={677} +\item{} +%mdk-data-line={677} +\mdline{677}\textbf{Session management:}\mdline{677} As soon as the controller opens the stream +channel, it sends a \mdline{678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{678} message to the switch. The +controller populates the \mdline{679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{679} field in this message +using its \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{680} and \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{680}, as well as the \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{680} of the +device. Note that the \mdline{681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{681} field in the \mdline{681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{681} is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below.%mdk%mdk + +%mdk-data-line={685} +\item{} +%mdk-data-line={685} +\mdline{685}\textbf{Streaming of notifications (e.g. digests) and packet I/O:}\mdline{685} The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the master controller can participate in packet +I/O. This feature is explained in more details in the\mdline{689}~\mdref{sec-packet-i_o}{Packet +I/O}\mdline{690} section.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={692} +\mdline{692}Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state.%mdk%mdk + +%mdk-data-line={695} +\item{} +%mdk-data-line={695} +\mdline{695}Note that the stream is opened per device. In case a switching platform has +multiple devices (\mdline{696}e.g.\mdline{696} multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different masters for different +devices. In this case, it is the responsibility of the P4Runtime server to +keep track of the master for each device (and role). More specifically, the +P4Runtime server will know which stream corresponds to the master controller +for each pair of (\mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{701}, \mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{701}) at any point of time.%mdk%mdk + +%mdk-data-line={703} +\item{} +%mdk-data-line={703} +\mdline{703}The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered \mdline{704}\textquotedblleft{}offline\textquotedblright{}\mdline{704} or +\mdline{705}\textquotedblleft{}dead\textquotedblright{}\mdline{705} as soon as its stream channel to the switch is broken. When a master +channel gets broken: (i) an advisory message is sent to all other controllers +for that \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{707} and \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{707}, as described in the +\mdline{708}\mdref{sec-mastership-notification}{following section}\mdline{708} (ii) the P4Runtime server +will be without a master, until a client sends a successful +\mdline{710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{710} (as per the rules in a +\mdline{711}\mdref{sec-mastership-updates}{later section}\mdline{711}).%mdk%mdk + +%mdk-data-line={713} +\item{} +%mdk-data-line={713} +\mdline{713}The mechanism via which the controller receives the P4Runtime server details +which includes the \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{714}, \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip}}}\mdline{714} and \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{714}, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +\mdline{718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{718}) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={723} +\noindent\mdline{723}gRPC enables the server to identify which client originated each message in the +\mdline{724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{724} stream. For example, the C++ gRPC library\mdline{724}~[\mdcite{grpcstreamc}{10}]\mdline{724} in +synchronous mode enables a server process to cause a function to be called when +a new client creates a \mdline{726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{726} stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +\mdline{728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{728} is closed normally (or broken, \mdline{728}e.g.\mdline{728} because a client process +unexpectedly terminated). Thus the server can easily associate all +\mdline{730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{730} messages received from the same client, because they are +processed within the context of the same function call.%mdk + +%mdk-data-line={733} +\mdline{733}A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{738}, \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{738}, and \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{738} in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods\mdline{740}~[\mdcite{grpcauth}{8}]\mdline{740} that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server.%mdk + +%mdk-data-line={744} +\subsection{\mdline{744}5.1.\hspace*{0.5em}\mdline{744}Default Role}\label{sec-default-role}%mdk%mdk + +%mdk-data-line={746} +\noindent\mdline{746}A controller can omit the role message in \mdline{746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{746}. This +implies the \mdline{747}\textquotedblleft{}default role\textquotedblright{}\mdline{747}, which corresponds to \mdline{747}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{747}. This +also implies that a default role has a \mdline{748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{748} of 0 (default). If using a +default role, all RPCs from the controller (\mdline{749}e.g.\mdline{749} \mdline{749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{749}) must set the \mdline{749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{749} +to 0.%mdk + +%mdk-data-line={752} +\subsection{\mdline{752}5.2.\hspace*{0.5em}\mdline{752}Role Config}\label{sec-arbitration-role-config}%mdk%mdk + +%mdk-data-line={754} +\noindent\mdline{754}The \mdline{754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{754} field in the \mdline{754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{754} message sent by the +controller describes the role configuration, \mdline{755}i.e.\mdline{755} which operations are in the +scope of a given role. In particular, the definition of a role may include the +following:%mdk + +%mdk-data-line={759} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={759} +\item\mdline{759}A list of P4 entities for which the controller may issue \mdline{759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{759} updates and +receive notification messages (\mdline{760}e.g.\mdline{760} \mdline{760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{760} and +\mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{761}).%mdk + +%mdk-data-line={762} +\item\mdline{762}Whether the controller is able to receive \mdline{762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{762} messages, along with a +filtering mechanism based on the values of the \mdline{763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{763} fields to +select which \mdline{764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{764} messages should be sent to the controller.%mdk + +%mdk-data-line={765} +\item\mdline{765}Whether the controller is able to send \mdline{765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{765} messages, along with a +filtering mechanism based on the values of the \mdline{766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{766} fields to +select which \mdline{767}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{767} messages are allowed to be sent by the controller.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={769} +\noindent\mdline{769}An unset \mdline{769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{769} implies \mdline{769}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{769} (similar to the default +role explained above). In order to support different role definition schemes, +\mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{771} is defined as an \mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{771} Protobuf message\mdline{771}~[\mdcite{protoany}{30}]\mdline{771}. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion.%mdk + +%mdk-data-line={776} +\mdline{776}It is the job of the P4Runtime server to remember the \mdline{776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{776} for every +\mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{777} and \mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{777} pair.%mdk + +%mdk-data-line={779} +\subsection{\mdline{779}5.3.\hspace*{0.5em}\mdline{779}Rules for Handling \mdline{779}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{779} Messages Received from Controllers}\label{sec-mastership-updates}%mdk%mdk + +%mdk-data-line={781} +\begin{enumerate}%mdk + +%mdk-data-line={781} +\item{} +%mdk-data-line={781} +\mdline{781}If the \mdline{781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{781} message is received for the first time on +this particular channel (\mdline{782}i.e.\mdline{782} for a newly connected controller):%mdk + +%mdk-data-line={784} +\begin{enumerate}%mdk + +%mdk-data-line={784} +\item{} +%mdk-data-line={784} +\mdline{784}If \mdline{784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{784} does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +\mdline{786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{786} error.%mdk%mdk + +%mdk-data-line={788} +\item{} +%mdk-data-line={788} +\mdline{788}If the \mdline{788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{788} is set and is already used by another controller for +the same (\mdline{789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{789}, \mdline{789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{789}), the P4Runtime server shall terminate +the stream by returning an \mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{790} error.%mdk%mdk + +%mdk-data-line={792} +\item{} +%mdk-data-line={792} +\mdline{792}If \mdline{792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{792} does not match the \mdline{792}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{792} scheme previously +agreed upon, the server must return an \mdline{793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{793} error.%mdk%mdk + +%mdk-data-line={795} +\item{} +%mdk-data-line={795} +\mdline{795}If the number of open streams for the given (\mdline{795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{795}, \mdline{795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{795}) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a \mdline{797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{797} error.%mdk%mdk + +%mdk-data-line={799} +\item{} +%mdk-data-line={799} +\mdline{799}Otherwise, the controller is added to a list of connected controllers for +the given (\mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{800}, \mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{800}) and the server remembers the +controllers \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{801}, \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{801} and \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{801} for this gRPC +channel. See below for the rules to determine if this controller becomes +a master or slave, and what notifications are sent as a consequence.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={805} +\item{} +%mdk-data-line={805} +\mdline{805}Otherwise, if the \mdline{805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{805} message is received from an +already connected controller:%mdk + +%mdk-data-line={808} +\begin{enumerate}%mdk + +%mdk-data-line={808} +\item{} +%mdk-data-line={808} +\mdline{808}If the \mdline{808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{808} does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{810} error.%mdk%mdk + +%mdk-data-line={812} +\item{} +%mdk-data-line={812} +\mdline{812}If the \mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{812} does not match the current \mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{812} assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{814} error. If the controller wishes to change its role, +it must close the current stream channel and open a new one.%mdk%mdk + +%mdk-data-line={817} +\item{} +%mdk-data-line={817} +\mdline{817}If \mdline{817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{817} does not match the \mdline{817}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{817} scheme previously +agreed upon, the server must return an \mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{818} error.%mdk%mdk + +%mdk-data-line={820} +\item{} +%mdk-data-line={820} +\mdline{820}If the \mdline{820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{820} is set and is already used by another controller +(excluding the controller making the request) for the same +(\mdline{822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{822}, \mdline{822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{822}), the P4Runtime server shall terminate the stream +by returning an \mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{823} error.%mdk%mdk + +%mdk-data-line={825} +\item{} +%mdk-data-line={825} +\mdline{825}If the \mdline{825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{825} matches the one assigned to this stream:%mdk + +%mdk-data-line={827} +\begin{enumerate}%mdk + +%mdk-data-line={827} +\item{} +%mdk-data-line={827} +\mdline{827}If the controller for this channel is the master, then the server +updates the \mdline{828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{828} to the one specified in the +\mdline{829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{829}. An advisory mastership message is sent to +all controllers for this \mdline{830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{830} and \mdline{830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{830} informing +them of the new \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{831}. Since the format of \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{831} is +out of scope for the P4Runtime specification, the server will send +the advisory message for every update, even if the master sets the +same \mdline{834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{834} as it has before. See the +\mdline{835}\mdref{sec-mastership-notification}{following section}\mdline{835} for the format of +the advisory message.%mdk%mdk + +%mdk-data-line={838} +\item{} +%mdk-data-line={838} +\mdline{838}If the controller is a slave, this is a no-op and the \mdline{838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{838} +is ignored. No response is sent to any controller.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={841} +\item{} +%mdk-data-line={841} +\mdline{841}Otherwise, the server updates the \mdline{841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{841} it has stored for this +controller. This change might cause a change in mastership (this +controller might become master, or the controller might have downgraded +itself to a slave, see below), as well as notifications being sent to one +or more controllers.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={847} +\noindent\mdline{847}If the \mdline{847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{847} is accepted by either of the two steps above +(cases 1.5. and 2.6. above), then the server determines if there are changes in +mastership. Let \mdline{849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{849} be the highest election ID the server has +ever seen for the given \mdline{850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{850} and \mdline{850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{850} (including the one of the +current master if there is one).%mdk + +%mdk-data-line={853} +\begin{enumerate}%mdk + +%mdk-data-line={853} +\item{} +%mdk-data-line={853} +\mdline{853}If \mdline{853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{853} is greater than or equal to \mdline{853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{853}, then the +controller becomes master. The server updates the role configuration to +\mdline{855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{855} for the given \mdline{855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{855}. Furthermore:%mdk + +%mdk-data-line={857} +\begin{enumerate}%mdk + +%mdk-data-line={857} +\item{} +%mdk-data-line={857} +\mdline{857}If there was no master for this \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{857} and \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{857} before and +there are no \mdline{858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{858} requests still processing from a previous master, +then the server immediately sends an advisory notification to all +controllers for this \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{860} and \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{860}. See the +\mdline{861}\mdref{sec-mastership-notification}{following section}\mdline{861} for the format of the +advisory message.%mdk%mdk + +%mdk-data-line={864} +\item{} +%mdk-data-line={864} +\mdline{864}If there was a previous master or \mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{864} requests in flight, then the +server carries out the following steps (in this order):%mdk + +%mdk-data-line={867} +\begin{enumerate}%mdk + +%mdk-data-line={867} +\item{} +%mdk-data-line={867} +\mdline{867}The server stops accepting \mdline{867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{867} requests from the previous master +(if there is one). At this point, the server will reject all \mdline{868}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{868} +requests with \mdline{869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{869}.%mdk%mdk + +%mdk-data-line={871} +\item{} +%mdk-data-line={871} +\mdline{871}The server notifies all controllers other than the new master of the +mastership change by sending the advisory notification described in +the\mdline{873}~\mdref{sec-mastership-notification}{following section}\mdline{873}.%mdk%mdk + +%mdk-data-line={875} +\item{} +%mdk-data-line={875} +\mdline{875}The server will finish processing any \mdline{875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{875} requests that have +already started. If there are errors, they are reported as usual to +the previous master. If the previous master has already disconnected, +any possible errors are dropped and not reported.%mdk%mdk + +%mdk-data-line={880} +\item{} +%mdk-data-line={880} +\mdline{880}The server now accepts the current controller as the new master, thus +accepting \mdline{881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{881} requests from this controller. The server updates +the highest election ID (\mdline{882}i.e.\mdline{882} \mdline{882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{882}) it has seen for +this \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{883} and \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{883} to \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{883}.%mdk%mdk + +%mdk-data-line={885} +\item{} +%mdk-data-line={885} +\mdline{885}The server notifies the new master by sending the advisory message +described in the\mdline{886}~\mdref{sec-mastership-notification}{following section}\mdline{886}.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={888} +\item{} +%mdk-data-line={888} +\mdline{888}Otherwise, the controller becomes a slave. If the controller was previously a +master (and downgraded itself), then an advisory message is sent to all +controllers for this \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{890} and \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{890}. Otherwise, the advisory +message is only sent to the controller that sent the initial +\mdline{892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{892}. See the +\mdline{893}\mdref{sec-mastership-notification}{following section}\mdline{893} for the format of the +advisory message.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={896} +\subsection{\mdline{896}5.4.\hspace*{0.5em}\mdline{896}Mastership Notifications}\label{sec-mastership-notification}%mdk%mdk + +%mdk-data-line={898} +\noindent\mdline{898}For any given \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{898} and \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{898}, any time a new master is chosen, a +master downgrades its status to a slave, a master disconnects, or the +\mdline{900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{900} is updated by the master, all controllers for that +(\mdline{901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{901}, \mdline{901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{901}) are informed of this by sending a +\mdline{902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{902}. The \mdline{902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{902} is populated as follows:%mdk + +%mdk-data-line={904} +\begin{itemize}%mdk + +%mdk-data-line={904} +\item{} +%mdk-data-line={904} +\mdline{904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{904} and \mdline{904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{904} as given.%mdk%mdk + +%mdk-data-line={906} +\item{} +%mdk-data-line={906} +\mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{906} is set to the role configuration the server received most +recently in a \mdline{907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{907} from a master.%mdk%mdk + +%mdk-data-line={909} +\item{} +%mdk-data-line={909} +\mdline{909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{909} is populated as follows:%mdk + +%mdk-data-line={911} +\begin{itemize}%mdk + +%mdk-data-line={911} +\item{} +%mdk-data-line={911} +\mdline{911}If there has not been any master at all, the election\mdline{911}\_\mdline{911}id is left unset.%mdk%mdk + +%mdk-data-line={913} +\item{} +%mdk-data-line={913} +\mdline{913}Otherwise, \mdline{913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{913} is set to the highest election ID that the server +has seen for this \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{914} and \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{914} (which is the \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{914} of +the current master if there is any).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={917} +\item{} +%mdk-data-line={917} +\mdline{917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{917} is set differently based on whether the notification is sent to the +master or a slave controller:%mdk + +%mdk-data-line={920} +\begin{itemize}%mdk + +%mdk-data-line={920} +\item{} +%mdk-data-line={920} +\mdline{920}If there is a master:%mdk + +%mdk-data-line={922} +\begin{itemize}%mdk + +%mdk-data-line={922} +\item{} +%mdk-data-line={922} +\mdline{922}For the master, \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{922} is OK (with \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{922} set to +\mdline{923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.OK}}}\mdline{923}).%mdk%mdk + +%mdk-data-line={925} +\item{} +%mdk-data-line={925} +\mdline{925}For all slave controllers, \mdline{925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{925} is set to non-OK (with +\mdline{926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{926} set to \mdline{926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.ALREADY\_EXISTS}}}\mdline{926}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={928} +\item{} +%mdk-data-line={928} +\mdline{928}Otherwise, if there is no master currently, for all slave controllers, +\mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{929} is set to non-OK (with \mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{929} set to +\mdline{930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.NOT\_FOUND}}}\mdline{930}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={932} +\noindent\mdline{932}Note that on mastership changes with outstanding \mdline{932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{932} request, some +notifications might be delayed, see the +\mdline{934}\mdref{sec-mastership-updates}{previous section}\mdline{934} for details.%mdk + +%mdk-data-line={936} +\section{\mdline{936}6.\hspace*{0.5em}\mdline{936}The P4Info Message}\label{sec-the-p4info-message}%mdk%mdk + +%mdk-data-line={938} +\noindent\mdline{938}The purpose of P4Info was described under +\mdline{939}\mdref{sec-reference-architecture}{Reference Architecture}\mdline{939}. +Here we describe the various +components.%mdk + +%mdk-data-line={943} +\subsection{\mdline{943}6.1.\hspace*{0.5em}\mdline{943}Common Messages}\label{sec-common-messages}%mdk%mdk + +%mdk-data-line={945} +\noindent\mdline{945}These messages appear nested within many other messages.%mdk + +%mdk-data-line={947} +\subsubsection{\mdline{947}6.1.1.\hspace*{0.5em}\mdline{947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{947} Message}\label{sec-documentation-message}%mdk%mdk + +%mdk-data-line={949} +\noindent\mdline{949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{949} is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers.%mdk + +%mdk-data-line={953} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={954} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Documentation~\{\\ +~~{\mdcolor{darkgreen}//~A~brief~description~of~something,~e.g.~one~sentence}\\ +~~{\bfseries{\mdcolor{navy}string}}~brief~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~A~more~verbose~description~of~something.}\\ +~~{\mdcolor{darkgreen}//~Multiline~is~accepted.~Markup~format~(if~any)~is~TBD.}\\ +~~{\bfseries{\mdcolor{navy}string}}~description~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={962} +\subsubsection{\mdline{962}6.1.2.\hspace*{0.5em}\mdline{962}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{962} Message}\label{sec-preamble-message}%mdk%mdk + +%mdk-data-line={964} +\noindent\mdline{964}The preamble serves as the \mdline{964}\textquotedblleft{}descriptor\textquotedblright{}\mdline{964} for each entity and contains the unique +instance ID, name, alias, annotations and documentation.%mdk + +%mdk-data-line={967} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={968} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Preamble~\{\\ +~~{\mdcolor{darkgreen}//~ids~share~the~same~number-space;~e.g.~table~ids~cannot~overlap~with~counter}\\ +~~{\mdcolor{darkgreen}//~ids.~Even~though~this~is~irrelevant~to~this~proto~definition,~the~ids~are}\\ +~~{\mdcolor{darkgreen}//~allocated~in~such~a~way~that~it~is~possible~based~on~an~id~to~deduce~the}\\ +~~{\mdcolor{darkgreen}//~resource~type~(e.g.~table,~action,~counter,~...).~This~means~that~code}\\ +~~{\mdcolor{darkgreen}//~using~these~ids~can~detect~if~the~wrong~resource~type~is~used}\\ +~~{\mdcolor{darkgreen}//~somewhere.~This~also~means~that~ids~of~different~types~can~be~mixed}\\ +~~{\mdcolor{darkgreen}//~(e.g.~direct~resource~list~for~a~table)~without~ambiguity.~Note~that~id~0}\\ +~~{\mdcolor{darkgreen}//~is~reserved~and~means~"invalid~id".}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name~of~the~P4~object,~e.g.~c1.c2.ipv4\_lpm}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~an~alias~(alternative~name)~for~the~P4~object,~probably~shorter~than~its}\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name.~The~only~constraint~is~for~it~to~be~unique~with}\\ +~~{\mdcolor{darkgreen}//~respect~to~other~P4~objects~of~the~same~type.~By~default,~the~compiler~uses}\\ +~~{\mdcolor{darkgreen}//~the~shortest~suffix~of~the~name~that~uniquely~identifies~the~object.~For}\\ +~~{\mdcolor{darkgreen}//~example~if~the~P4~program~contains~two~tables~with~names~s.c1.t~and~s.c2.t,}\\ +~~{\mdcolor{darkgreen}//~the~default~aliases~will~respectively~be~c1.t~and~c2.t.~In~the~future,~the}\\ +~~{\mdcolor{darkgreen}//~P4~programmer~may~also~be~able~to~override~the~default~alias~for~any~P4}\\ +~~{\mdcolor{darkgreen}//~object~(TBD).}\\ +~~{\bfseries{\mdcolor{navy}string}}~alias~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~Documentation~of~the~entity}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={995} +\subsubsection{\mdline{995}6.1.3.\hspace*{0.5em}\mdline{995}Annotating P4 Entities with \mdline{995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}\label{sec-annotating-p4-entities-with-documentation}%mdk%mdk + +%mdk-data-line={997} +\noindent\mdline{997}P4 entities may be annotated using the following annotations:%mdk + +%mdk-data-line={999} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1000} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}(string...)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}(string...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1004} +\noindent\mdline{1004}Attaching either or both of these annotations to an entity will generate a +P4Info\mdline{1005}~\mdref{sec-documentation-message}{Documentation Message}\mdline{1005}, which in turn will +appear in the\mdline{1006}~\mdref{sec-preamble-message}{Preamble Message}\mdline{1006} for the entity.%mdk + +%mdk-data-line={1008} +\mdline{1008}The P4 compiler should not emit \mdline{1008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation}}}\mdline{1008} messages in the P4Info for these +specific cases; instead, it should generate the \mdline{1009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1009} messages as +described.%mdk + +%mdk-data-line={1012} +\mdline{1012}The following example shows documentation annotations for a \mdline{1012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table}}}\mdline{1012} entity:%mdk + +%mdk-data-line={1014} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1015} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port.~\textbackslash{}}\\ +Uses~LPM~match~{\bfseries{\mdcolor{navy}type}}.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}table~my\_ipv4\_lkup~\{}\\ +{\mdcolor{maroon}~~...}\\ +{\mdcolor{maroon}\}}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1023} +\subsection{\mdline{1023}6.2.\hspace*{0.5em}\mdline{1023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1023} Message}\label{sec-pkginfo-message}%mdk%mdk + +%mdk-data-line={1025} +\noindent\mdline{1025}The \mdline{1025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1025} message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. \mdline{1026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1026} can be extracted +and used to facilitate \mdline{1027}\textquotedblleft{}browsing\textquotedblright{}\mdline{1027} of available P4 programs from a +library. Although all fields are technically \mdline{1028}\textquotedblleft{}optional,\textquotedblright{}\mdline{1028} every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included.%mdk + +%mdk-data-line={1032} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1033} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Can~be~used~to~manage~multiple~P4~packages.}\\ +{\bfseries{\mdcolor{navy}message}}~PkgInfo~\{\\ +~~{\mdcolor{darkgreen}//~a~definitive~name~for~this~configuration,~e.g.~switch.p4\_v1.0}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~configuration~version,~free-format~string}\\ +~~{\bfseries{\mdcolor{navy}string}}~version~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~brief~and~detailed~descriptions}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~free-form;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~the~target~architecture,~e.g.~"psa"}\\ +~~{\bfseries{\mdcolor{navy}string}}~arch~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\mdcolor{darkgreen}//~organization~which~produced~the~configuration,~e.g.~"p4.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~organization~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~{\mdcolor{darkgreen}//~contact~info~for~support,e.g.~"tech-support@acme.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~contact~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~url~for~more~information,~e.g.~"http://support.p4.org/ref/p4/switch.p4\_v1.0"}\\ +~~{\bfseries{\mdcolor{navy}string}}~url~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}8};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1054} +\subsubsection{\mdline{1054}6.2.1.\hspace*{0.5em}\mdline{1054}Annotating P4 code with PkgInfo}\label{sec-annotating-p4-code-with-pkginfo}%mdk%mdk + +%mdk-data-line={1056} +\noindent\mdline{1056}A P4 progam\mdline{1056}'\mdline{1056}s \mdline{1056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1056} may be declared using one or more of the following +annotations, attached to the \mdline{1057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1057} block only:%mdk + +%mdk-data-line={1059} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1060} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value{}[,key=value,...])}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("A~brief~description")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("A~longer\textbackslash{}}\\ +description{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@custom\_annotation(...)}\\ +{\mdcolor{maroon}@another\_custom\_annotation(...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1069} +\noindent\mdline{1069}Above we see several different types of annotations:%mdk + +%mdk-data-line={1071} +\begin{itemize}%mdk + +%mdk-data-line={1071} +\item{} +%mdk-data-line={1071} +\mdline{1071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1071} \mdline{1071}- This is used to populate a specific field within the \mdline{1071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1071} +message. Multiple \mdline{1072}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1072} annotations are allowed. For compactness, +multiple key-value pairs can appear in a single \mdline{1073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1073} annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The \mdline{1075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{1075}s must be from +among the message fields inside \mdline{1076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1076}, for example, \mdline{1076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1076}, \mdline{1076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}version}}}\mdline{1076}, +etc. Each key-value pair assigns a value to the corresponding field inside the +single \mdline{1078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1078} message for the program\mdline{1078}'\mdline{1078}s P4Info. One exception is that the +\mdline{1079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1079} field of \mdline{1079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1079} must be expressed as individual +\mdline{1080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1080} and \mdline{1080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1080} annotations, see next bullets. The key \mdline{1080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}arch}}}\mdline{1080} will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself.%mdk%mdk + +%mdk-data-line={1084} +\item{} +%mdk-data-line={1084} +\mdline{1084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1084} \mdline{1084}- This will populate the \mdline{1084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.brief}}}\mdline{1084} message field.%mdk%mdk + +%mdk-data-line={1086} +\item{} +%mdk-data-line={1086} +\mdline{1086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1086} \mdline{1086}- This will populate the \mdline{1086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.description}}}\mdline{1086} message +field%mdk%mdk + +%mdk-data-line={1089} +\item{} +%mdk-data-line={1089} +\mdline{1089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@\textless{}anything~else\textgreater{}}}}\mdline{1089} \mdline{1089}- This will create a \mdline{1089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotation}}}\mdline{1089} entry%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1091} +\noindent\mdline{1091}Declaring one or more of these annotations on \mdline{1091}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1091} will +generate a single corresponding \mdline{1092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1092} message in the P4Info as described in +\mdline{1093}\mdref{sec-pkginfo-message}{PkgInfo Message}\mdline{1093}.%mdk + +%mdk-data-line={1095} +\mdline{1095}The following example shows \mdline{1095}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1095} annotations using a mixture of single and +multiple key-value pairs. It also shows \mdline{1096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1096} and \mdline{1096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1096} annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the \mdline{1098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1098} message. The custom annotations will +be appended to the \mdline{1099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotations}}}\mdline{1099} list.%mdk + +%mdk-data-line={1101} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1102} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(name="switch.p4",version="2")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(organization="p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(contact="info@p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(url="www.p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("L2/L3~switch")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("L2/L3~switch.\textbackslash{}}\\ +Built~for~data-center~profile.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@my\_annotation1(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}@my\_annotation2(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}PSA\_Switch(IgPipeline,~PacketReplicationEngine(),~EgPipeline,}\\ +{\mdcolor{maroon}~~~~~~~~~~~BufferingQueueingEngine())~main;}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1115} +\subsection{\mdline{1115}6.3.\hspace*{0.5em}\mdline{1115}ID Allocation for P4Info Objects}\label{sec-id-allocation}%mdk%mdk + +%mdk-data-line={1117} +\noindent\mdline{1117}P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(\mdline{1121}e.g.\mdline{1121} table, action, counter, \mdline{1121}\dots{}\mdline{1121}). The most significant 8 bits of the ID +encodes the object type (as per Table\mdline{1122}~\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}}\mdline{1122}). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (\mdline{1124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.P4Ids.Prefix}}}\mdline{1124}). These values must +be used (\mdline{1125}e.g.\mdline{1125} by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table\mdline{1127}~\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}}\mdline{1127} shows the ID +layout.%mdk + +%mdk-data-line={1130} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1132} 8-bit prefix value}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1132} P4 object type}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{1134} 0x00}&\multicolumn{1}{|l|}{\mdline{1134} Reserved (unspecified)}\\ +\multicolumn{1}{|l}{\mdline{1135} 0x01}&\multicolumn{1}{|l|}{\mdline{1135} Action}\\ +\multicolumn{1}{|l}{\mdline{1136} 0x02}&\multicolumn{1}{|l|}{\mdline{1136} Table}\\ +\multicolumn{1}{|l}{\mdline{1137} 0x03}&\multicolumn{1}{|l|}{\mdline{1137} Value-set}\\ +\multicolumn{1}{|l}{\mdline{1138} 0x04}&\multicolumn{1}{|l|}{\mdline{1138} Controller header (header type with \mdline{1138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1138} annotation)}\\ +\multicolumn{1}{|l}{\mdline{1139} 0x05\mdline{1139}\dots{}\mdline{1139}0x0f}&\multicolumn{1}{|l|}{\mdline{1139} Reserved (for future P4 built-in objects)}\\ +\multicolumn{1}{|l}{\mdline{1140} 0x10}&\multicolumn{1}{|l|}{\mdline{1140} Reserved (start of PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1141} 0x11}&\multicolumn{1}{|l|}{\mdline{1141} PSA Action profiles / selectors}\\ +\multicolumn{1}{|l}{\mdline{1142} 0x12}&\multicolumn{1}{|l|}{\mdline{1142} PSA Counter}\\ +\multicolumn{1}{|l}{\mdline{1143} 0x13}&\multicolumn{1}{|l|}{\mdline{1143} PSA Direct counter}\\ +\multicolumn{1}{|l}{\mdline{1144} 0x14}&\multicolumn{1}{|l|}{\mdline{1144} PSA Meter}\\ +\multicolumn{1}{|l}{\mdline{1145} 0x15}&\multicolumn{1}{|l|}{\mdline{1145} PSA Direct meter}\\ +\multicolumn{1}{|l}{\mdline{1146} 0x16}&\multicolumn{1}{|l|}{\mdline{1146} PSA Register}\\ +\multicolumn{1}{|l}{\mdline{1147} 0x17}&\multicolumn{1}{|l|}{\mdline{1147} PSA Digest}\\ +\multicolumn{1}{|l}{\mdline{1148} 0x18\mdline{1148}\dots{}\mdline{1148}0x7f}&\multicolumn{1}{|l|}{\mdline{1148} Reserved (for future PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1149} 0x80}&\multicolumn{1}{|l|}{\mdline{1149} Reserved (start of vendor-specific extern types)}\\ +\multicolumn{1}{|l}{\mdline{1150} 0x81\mdline{1150}\dots{}\mdline{1150}0xfe}&\multicolumn{1}{|l|}{\mdline{1150} Vendor-specific extern types}\\ +\multicolumn{1}{|l}{\mdline{1151} 0xff}&\multicolumn{1}{|l|}{\mdline{1151} Reserved (max prefix value)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1153} +\mdhr{}%mdk + +%mdk-data-line={1154} +\noindent\mdline{1154}\mdcaption{\textbf{Table~\mdcaptionlabel{1}.}~\mdcaptiontext{Mapping of P4Info object type to 8-bit ID prefix value}}%mdk +%mdk +\end{mdcenter}\label{tab-mapping-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1157} +\begin{table}[h!]%mdk +\begin{mdblock}{text-align=center,breakable=true}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{cc}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1159} MSB bit 31 \mdline{1159}\dots{}\mdline{1159}\dots{}\mdline{1159}.. bit 24}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1159} bit 23 \mdline{1159}\dots{}\mdline{1159}\dots{}\mdline{1159}\dots{}\mdline{1159}\dots{}\mdline{1159}\dots{}\mdline{1159}\dots{}\mdline{1159}\dots{}\mdline{1159}.. bit 0 LSB}}\\ + +\midrule +\multicolumn{1}{|c}{\mdline{1161} Object type prefix}&\multicolumn{1}{|c|}{\mdline{1161} Generated suffix (\mdline{1161}e.g.\mdline{1161} by the compiler)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1163} +\mdhr{}%mdk + +%mdk-data-line={1164} +\noindent\mdline{1164}\mdcaption{\textbf{Table~\mdcaptionlabel{2}.}~\mdcaptiontext{Format of P4Info object IDs}}%mdk%mdk +\end{mdblock}\label{tab-format-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1168} +\mdline{1168}It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with \mdline{1169}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1169} (see Table +\mdline{1170}\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}}\mdline{1170}). The compiler must honor the \mdline{1170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1170} annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (\mdline{1172}i.e.\mdline{1172} if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same \mdline{1174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1174} value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type.%mdk + +%mdk-data-line={1178} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth-7cm)/1}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{\mdinline{width=7cm}{{\bfseries\mdline{1180} P4 declaration(s)}}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1180} Compiler-allocated ID(s)}}\\ + +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1182} \mdline{1182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1182}}}&\multicolumn{1}{|l|}{\mdline{1182} 0x0212ab34}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1184} \mdline{1184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1184}}}&\multicolumn{1}{|l|}{\mdline{1184} \mdline{1184}\textbf{Error}\mdline{1184}(same ID suffixes for 2 objects of the same type)}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1185} \mdline{1185}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tB...}}}\mdline{1185}}}&\multicolumn{1}{|l|}{\mdline{1185}}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1187} \mdline{1187}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1187}}}&\multicolumn{1}{|l|}{\mdline{1187} 0x0212ab34}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1188} \mdline{1188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~action~act1...}}}\mdline{1188}}}&\multicolumn{1}{|l|}{\mdline{1188} 0x0112ab34}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1190} +\mdhr{}%mdk + +%mdk-data-line={1191} +\noindent\mdline{1191}\mdcaption{\textbf{Table~\mdcaptionlabel{3}.}~\mdcaptiontext{Example of statically-assigned P4Info object IDs}}%mdk +%mdk +\end{mdcenter}\label{tab-exmpl-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1194} +\subsection{\mdline{1194}6.4.\hspace*{0.5em}\mdline{1194}P4Info Objects}\label{sec-p4info-objects}%mdk%mdk + +%mdk-data-line={1196} +\subsubsection{\mdline{1196}6.4.1.\hspace*{0.5em}\mdline{1196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}\label{sec-table}%mdk%mdk + +%mdk-data-line={1198} +\noindent\mdline{1198}Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields:%mdk + +%mdk-data-line={1201} +\begin{itemize}%mdk + +%mdk-data-line={1201} +\item{} +%mdk-data-line={1201} +\mdline{1201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1201}, a \mdline{1201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1201} message with the ID, name, and alias of this table.%mdk%mdk + +%mdk-data-line={1203} +\item{} +%mdk-data-line={1203} +\mdline{1203}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1203}, a repeated field of type \mdline{1203}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1203} representing the data to +be used to construct the lookup key matched in this table. Each \mdline{1204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1204} +message is defined with the following fields:%mdk + +%mdk-data-line={1207} +\begin{itemize}%mdk + +%mdk-data-line={1207} +\item{} +%mdk-data-line={1207} +\mdline{1207}id, the \mdline{1207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1207} identifier of this \mdline{1207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1207}, unique in the scope of +this table. No rules are prescribed on the way \mdline{1208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1208} IDs should be +allocated, as long as two \mdline{1209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1209} of the same table do not have the +same ID. Nonetheless, we recommend that the IDs be assigned incrementally, +starting from 1, in the same order as in the P4 key declaration.%mdk%mdk + +%mdk-data-line={1213} +\item{} +%mdk-data-line={1213} +\mdline{1213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1213}, the string representing the name of this \mdline{1213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1213}.%mdk%mdk + +%mdk-data-line={1215} +\item{} +%mdk-data-line={1215} +\mdline{1215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1215}, a repeated field of strings, each one representing a P4 +annotation associated to this match field.%mdk%mdk + +%mdk-data-line={1218} +\item{} +%mdk-data-line={1218} +\mdline{1218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1218}, an \mdline{1218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1218} value set to the size in bits of this match field.%mdk%mdk + +%mdk-data-line={1220} +\item{} +%mdk-data-line={1220} +\mdline{1220}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1220}, a \mdline{1220}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{1220} describing the match behavior for this field; it can be +either:%mdk + +%mdk-data-line={1222} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1222} +\item\mdline{1222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1222}, an enum field of type \mdline{1222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchType}}}\mdline{1222}, which includes all +possible PSA match kinds.%mdk + +%mdk-data-line={1224} +\item\mdline{1224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_match\_type}}}\mdline{1224}, a string field which can be used to encode any +architecture-specific match type.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1227} +\item{} +%mdk-data-line={1227} +\mdline{1227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1227}, a \mdline{1227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1227} message describing this match field.%mdk%mdk + +%mdk-data-line={1229} +\item{} +%mdk-data-line={1229} +\mdline{1229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1229}, which indicates whether the match field has a\mdline{1229}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1230}; this is useful for +\mdline{1231}\mdref{sec-psa-metadata-translation}{translation}\mdline{1231}.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1233} +\item{} +%mdk-data-line={1233} +\mdline{1233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_refs}}}\mdline{1233}, a repeated \mdline{1233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1233} field representing the set of possible +actions for this table. The \mdline{1234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1234} message is used to reference an action +specified in the same P4Info message and it includes the following fields:%mdk + +%mdk-data-line={1236} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1236} +\item\mdline{1236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1236}, the \mdline{1236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1236} identifier of the action.%mdk + +%mdk-data-line={1237} +\item\mdline{1237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1237}, an enum value which can take one of three values: + \mdline{1238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1238}, \mdline{1238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1238} and \mdline{1238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1238}. The \mdline{1238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1238} of the + action is determined by the use of the P4 standard annotations + \mdline{1240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1240} and \mdline{1240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1240}~[\mdcite{p4actionannotations}{17}]\mdline{1240}. \mdline{1240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1240} + (\mdline{1241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1241} annotation) means that the action can only appear within + the table, and never as the default action. \mdline{1242}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1242} + (\mdline{1243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1243} annotation) means that the action can only be used as the + default action. \mdline{1244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1244} is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action.%mdk + +%mdk-data-line={1247} +\item\mdline{1247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1247}, a repeated string field, each one representing a P4 +annotation associated to the action \mdline{1248}\emph{reference}\mdline{1248} in this table.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1250} +\item{} +%mdk-data-line={1250} +\mdline{1250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\_default\_action\_id}}}\mdline{1250}, if this table has a constant default action, this +field will carry the \mdline{1251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1251} identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action\mdline{1254}'\mdline{1254}s +arguments.%mdk%mdk + +%mdk-data-line={1257} +\item{} +%mdk-data-line={1257} +\mdline{1257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation\_id}}}\mdline{1257}, the \mdline{1257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1257} identifier of the \mdline{1257}\textquotedblleft{}implementation\textquotedblright{}\mdline{1257} of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (\mdline{1260}e.g.\mdline{1260} a PSA \mdline{1260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1260} or \mdline{1260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{1260} +instance). The table is then referred to as an indirect match table.%mdk%mdk + +%mdk-data-line={1263} +\item{} +%mdk-data-line={1263} +\mdline{1263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_resource\_ids}}}\mdline{1263}, repeated \mdline{1263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1263} identifiers for all the direct +resources attached to this table, such as \mdline{1264}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1264} and \mdline{1264}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1264} +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2.%mdk%mdk + +%mdk-data-line={1270} +\item{} +%mdk-data-line={1270} +\mdline{1270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1270}, an \mdline{1270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1270} describing the desired number of table entries that the +target should support for the table. See the \mdline{1271}\textquotedblleft{}Size\textquotedblright{}\mdline{1271} subsection within the +\mdline{1272}\textquotedblleft{}Table Properties\textquotedblright{}\mdline{1272} section of the P4\mdline{1272}\mdsub{16}\mdline{1272} language specification for details +\mdline{1273}[\mdcite{p4tableproperties}{29}]\mdline{1273}.%mdk%mdk + +%mdk-data-line={1275} +\item{} +%mdk-data-line={1275} +\mdline{1275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_behavior}}}\mdline{1275}, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +\mdline{1277}\mdref{sec-idle-timeout}{Idle-Timeout}\mdline{1277} section). Value can be any of the +\mdline{1278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutBehavior}}}\mdline{1278} enum:%mdk + +%mdk-data-line={1279} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1279} +\item\mdline{1279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NO\_TIMEOUT}}}\mdline{1279} (default value), which means that idle timeout is not +supported for this table.%mdk + +%mdk-data-line={1281} +\item\mdline{1281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOTIFY\_CONTROL}}}\mdline{1281}, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +\mdline{1283}\mdref{sec-table-idle-timeout-notification}{Table Idle Timeout Notifications}\mdline{1283}).%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1285} +\item{} +%mdk-data-line={1285} +\mdline{1285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{1285}, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime.%mdk%mdk + +%mdk-data-line={1288} +\item{} +%mdk-data-line={1288} +\mdline{1288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{1288}, an \mdline{1288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1288} Protobuf message\mdline{1288}~[\mdcite{protoany}{30}]\mdline{1288} to embed +architecture-specific table properties\mdline{1289}~[\mdcite{p4tableproperties}{29}]\mdline{1289} which are not part +of the core P4 language or of the PSA architecture.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1292} +\subsubsection{\mdline{1292}6.4.2.\hspace*{0.5em}\mdline{1292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}\label{sec-action}%mdk%mdk + +%mdk-data-line={1294} +\noindent\mdline{1294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1294} messages are used to specify all possible actions of all match-action +tables.%mdk + +%mdk-data-line={1297} +\mdline{1297}The \mdline{1297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1297} message defines the following fields:%mdk + +%mdk-data-line={1299} +\begin{itemize}%mdk + +%mdk-data-line={1299} +\item{} +%mdk-data-line={1299} +\mdline{1299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1299}, a \mdline{1299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1299} message with the ID, name, and alias of this action%mdk%mdk + +%mdk-data-line={1301} +\item{} +%mdk-data-line={1301} +\mdline{1301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{1301}, a repeated field of \mdline{1301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1301} messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each \mdline{1303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1303} message contains the +following fields:%mdk + +%mdk-data-line={1305} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1305} +\item\mdline{1305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1305}, the \mdline{1305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1305} identifier of this parameter. No rules are prescribed +on the way \mdline{1306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1306} IDs should be allocated, as long as two \mdline{1306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1306} of the +same action do not have the same ID. Nonetheless, we recommend that the +IDs be assigned incrementally, starting from 1, in the same order as in +the P4 action declaration.%mdk + +%mdk-data-line={1310} +\item\mdline{1310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1310}, the string representing the name of this parameter.%mdk + +%mdk-data-line={1311} +\item\mdline{1311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1311}, a repeated field of strings, each one representing a P4 +annotation associated to this parameter.%mdk + +%mdk-data-line={1313} +\item\mdline{1313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1313}, an \mdline{1313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1313} value set to the size in bits of this parameter.%mdk + +%mdk-data-line={1314} +\item\mdline{1314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1314}, which describes this parameter using a \mdline{1314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1314} message.%mdk + +%mdk-data-line={1315} +\item\mdline{1315}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1315}, which indicates whether the action parameter has a +\mdline{1316}\mdref{sec-user-defined-types}{user-defined type}\mdline{1316}; this is useful for +\mdline{1317}\mdref{sec-psa-metadata-translation}{translation}\mdline{1317}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1319} +\subsubsection{\mdline{1319}6.4.3.\hspace*{0.5em}\mdline{1319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}\label{sec-p4info-action-profile}%mdk%mdk + +%mdk-data-line={1321} +\noindent\mdline{1321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1321} messages are used to specify all available instances of Action +Profile and Action Selector PSA externs.%mdk + +%mdk-data-line={1324} +\mdline{1324}PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile \mdline{1328}\emph{member}\mdline{1328}, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime.%mdk + +%mdk-data-line={1332} +\mdline{1332}PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into \mdline{1333}\emph{groups}\mdline{1333}. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime.%mdk + +%mdk-data-line={1342} +\mdline{1342}While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same \mdline{1343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1343} message to describe both.%mdk + +%mdk-data-line={1345} +\mdline{1345}The \mdline{1345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1345} message includes the following fields:%mdk + +%mdk-data-line={1347} +\begin{itemize}%mdk + +%mdk-data-line={1347} +\item{} +%mdk-data-line={1347} +\mdline{1347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1347}, a \mdline{1347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1347} message with the ID, name, and alias of this Action +Profile or Selector.%mdk%mdk + +%mdk-data-line={1350} +\item{} +%mdk-data-line={1350} +\mdline{1350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_ids}}}\mdline{1350}, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector.%mdk%mdk + +%mdk-data-line={1353} +\item{} +%mdk-data-line={1353} +\mdline{1353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}with\_selector}}}\mdline{1353}, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern.%mdk%mdk + +%mdk-data-line={1356} +\item{} +%mdk-data-line={1356} +\mdline{1356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1356}, an \mdline{1356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1356} representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups.%mdk%mdk + +%mdk-data-line={1360} +\item{} +%mdk-data-line={1360} +\mdline{1360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1360}, an \mdline{1360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1360} representing the maximum sum of all member +weights within any given selector group, in the case of an Action Selector, or +0 for an Action Profile. PSA programs can use the \mdline{1362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{1362} annotation +to provide this value for Action Selectors. If the annotation is omitted, the +P4Info field will default to 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1366} +\subsubsection{\mdline{1366}6.4.4.\hspace*{0.5em}\mdline{1366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1366} \mdline{1366}\&\mdline{1366} \mdline{1366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}\label{sec-counter-directcounter}%mdk%mdk + +%mdk-data-line={1368} +\noindent\mdline{1368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1368} and \mdline{1368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1368} messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is:%mdk + +%mdk-data-line={1374} +\begin{itemize}%mdk + +%mdk-data-line={1374} +\item{} +%mdk-data-line={1374} +\mdline{1374}Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index.%mdk%mdk + +%mdk-data-line={1378} +\item{} +%mdk-data-line={1378} +\mdline{1378}Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1381} +\noindent\mdline{1381}Both \mdline{1381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1381} and \mdline{1381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1381} messages share the following fields:%mdk + +%mdk-data-line={1383} +\begin{itemize}%mdk + +%mdk-data-line={1383} +\item{} +%mdk-data-line={1383} +\mdline{1383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1383}, a \mdline{1383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1383} message with the ID, name, and alias of this counter +extern instance.%mdk%mdk + +%mdk-data-line={1386} +\item{} +%mdk-data-line={1386} +\mdline{1386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1386}, a message of of type \mdline{1386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1386} used to describe the compile-time +configuration of this counter. Currently, the \mdline{1387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1387} message is used to +carry only the counter unit, which can be any of the \mdline{1388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec.Unit}}}\mdline{1388} enum +values:%mdk + +%mdk-data-line={1390} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1390} +\item\mdline{1390}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1390}: reserved value.%mdk + +%mdk-data-line={1391} +\item\mdline{1391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1391}: byte counter.%mdk + +%mdk-data-line={1392} +\item\mdline{1392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1392}: packet counter.%mdk + +%mdk-data-line={1393} +\item\mdline{1393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BOTH}}}\mdline{1393}: combination of both byte and packet counter.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1395} +\noindent\mdline{1395}For indexed counters, the \mdline{1395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1395} message contains also a \mdline{1395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1395} field, an +\mdline{1396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1396} representing the maximum number of independent values that can be held +by this counter array. Conversely, the \mdline{1397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1397} message contains a +\mdline{1398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1398} field that carries the \mdline{1398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}unit32}}}\mdline{1398} identifier of the table to +which this direct counter is attached.%mdk + +%mdk-data-line={1401} +\mdline{1401}For indexed counters, the \mdline{1401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1401} message contains also an \mdline{1401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1401} +field, which indicates whether the index has a\mdline{1402}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1403}. This is useful for +\mdline{1404}\mdref{sec-psa-metadata-translation}{translation}\mdline{1404}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1405}).%mdk + +%mdk-data-line={1407} +\subsubsection{\mdline{1407}6.4.5.\hspace*{0.5em}\mdline{1407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1407} \mdline{1407}\&\mdline{1407} \mdline{1407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}\label{sec-meter-directmeter}%mdk%mdk + +%mdk-data-line={1409} +\noindent\mdline{1409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1409} and \mdline{1409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1409} messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is:%mdk + +%mdk-data-line={1415} +\begin{itemize}%mdk + +%mdk-data-line={1415} +\item{} +%mdk-data-line={1415} +\mdline{1415}Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +\mdline{1417}e.g.\mdline{1417} to set the rate threshold.%mdk%mdk + +%mdk-data-line={1419} +\item{} +%mdk-data-line={1419} +\mdline{1419}Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1422} +\noindent\mdline{1422}Both \mdline{1422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1422} and \mdline{1422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1422} messages share the following fields:%mdk + +%mdk-data-line={1424} +\begin{itemize}%mdk + +%mdk-data-line={1424} +\item{} +%mdk-data-line={1424} +\mdline{1424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1424}, a \mdline{1424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1424} message with the ID, name, and alias of this meter +extern instance.%mdk%mdk + +%mdk-data-line={1427} +\item{} +%mdk-data-line={1427} +\mdline{1427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1427}, a message of type \mdline{1427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1427} used to describe the capabilities of +this meter extern instance. Currently, the \mdline{1428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1428} message is used to +carry only the meter unit, which can be any of the \mdline{1429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Unit}}}\mdline{1429} enum +values:%mdk + +%mdk-data-line={1431} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1431} +\item\mdline{1431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1431}: reserved value.%mdk + +%mdk-data-line={1432} +\item\mdline{1432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1432}, which signifies that this meter can be configured with rates +expressed in bytes/second.%mdk + +%mdk-data-line={1434} +\item\mdline{1434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1434}, for rates expressed in packets/second.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1436} +\noindent\mdline{1436}For indexed meters, the \mdline{1436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1436} message contains also a \mdline{1436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1436} field, an \mdline{1436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1436} +representing the maximum number of independent cells that can be held by this +meter. Conversely, the \mdline{1438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1438} message contains a \mdline{1438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1438} field +that carries the \mdline{1439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1439} identifier of the table to which this direct meter is +attached.%mdk + +%mdk-data-line={1442} +\mdline{1442}For indexed meters, the \mdline{1442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1442} message contains also an \mdline{1442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1442} +field, which indicates whether the index has a\mdline{1443}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1444}. This is useful for +\mdline{1445}\mdref{sec-psa-metadata-translation}{translation}\mdline{1445}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1446}).%mdk + +%mdk-data-line={1448} +\subsubsection{\mdline{1448}6.4.6.\hspace*{0.5em}\mdline{1448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\label{sec-controller-packet-meta}%mdk%mdk + +%mdk-data-line={1450} +\noindent\mdline{1450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1450} messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server.%mdk + +%mdk-data-line={1456} +\mdline{1456}When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet.%mdk + +%mdk-data-line={1462} +\mdline{1462}Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +\mdline{1464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_in")}}}\mdline{1464} and \mdline{1464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_out")}}}\mdline{1464}, +respectively. \mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1465} messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages).%mdk + +%mdk-data-line={1470} +\mdline{1470}A P4Info message can contain at most two \mdline{1470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata~messages}}}\mdline{1470}, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields:%mdk + +%mdk-data-line={1474} +\begin{itemize}%mdk + +%mdk-data-line={1474} +\item{} +%mdk-data-line={1474} +\mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1474}, a \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1474} message where \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble.name}}}\mdline{1474} is set to \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_in"}}}\mdline{1474} +and \mdline{1475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_out"}}}\mdline{1475} for packet-in and packet-out metadata, respectively.%mdk%mdk + +%mdk-data-line={1477} +\item{} +%mdk-data-line={1477} +\mdline{1477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{1477}, a repeated field of type \mdline{1477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1477}, where each \mdline{1477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1477} message +includes the following fields:%mdk + +%mdk-data-line={1479} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1479} +\item\mdline{1479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1479}, a \mdline{1479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1479} identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two \mdline{1480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1480} of the +same \mdline{1481}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1481} message do not have the same +ID. Nonetheless, if the P4Info message was generated from a P4 compiler, +we recommend that the IDs be assigned incrementally, starting from 1, in +the same order as the fields in the P4 header declaration.%mdk + +%mdk-data-line={1485} +\item\mdline{1485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1485}, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below).%mdk + +%mdk-data-line={1489} +\item\mdline{1489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1489}, a repeated field of strings, each one representing a P4 +annotation associated to this metadata.%mdk + +%mdk-data-line={1491} +\item\mdline{1491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1491}, an \mdline{1491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1491} representing the size in bits of this metadata.%mdk + +%mdk-data-line={1492} +\item\mdline{1492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1492}, which indicates whether the metadata field has a +\mdline{1493}\mdref{sec-user-defined-types}{user-defined type}\mdline{1493}; this is useful for +\mdline{1494}\mdref{sec-psa-metadata-translation}{translation}\mdline{1494}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1496} +\noindent\mdline{1496}As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding \mdline{1497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1497} +messages.%mdk + +%mdk-data-line={1500} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1501} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~egress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~port~where~the~packet}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~should~be~sent~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~queue\_id;~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~queue~ID~}{\mdcolor{darkgreen}*/}\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~ingress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~data~plane~port~ID~where}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~the~original~packet~was~received~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}1}\textgreater{}~is\_clone;~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~1~if~this~is~a~clone~of~the}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~original~packet~}{\mdcolor{darkgreen}*/}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1516} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1517} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868916615}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_out}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_out}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}egress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}queue\_id}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~\}\\ +\}\\ +\\ +controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868941301}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_in}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_in}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ingress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}is\_clone}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}1}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1554} +\noindent\mdline{1554}Note that the use of \mdline{1554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1554} is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages.%mdk + +%mdk-data-line={1560} +\subsubsection{\mdline{1560}6.4.7.\hspace*{0.5em}\mdline{1560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}\label{sec-valueset}%mdk%mdk + +%mdk-data-line={1562} +\noindent\mdline{1562}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1562} messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P4\mdline{1565}\mdsub{16}\mdline{1565} +specification\mdline{1566}~[\mdcite{p4valuesets}{37}]\mdline{1566}.%mdk + +%mdk-data-line={1568} +\mdline{1568}The \mdline{1568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1568} message defines the following fields:%mdk + +%mdk-data-line={1570} +\begin{itemize}%mdk + +%mdk-data-line={1570} +\item{} +%mdk-data-line={1570} +\mdline{1570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1570}, a \mdline{1570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1570} message with the ID, name, and alias of this Value +Set.%mdk%mdk + +%mdk-data-line={1573} +\item{} +%mdk-data-line={1573} +\mdline{1573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1573}, a repeated field of \mdline{1573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1573} messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the \mdline{1576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1576} repeated field in the +\mdline{1577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{1577} message.%mdk%mdk + +%mdk-data-line={1579} +\item{} +%mdk-data-line={1579} +\mdline{1579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1579}, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +\mdline{1581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set}}}\mdline{1581} constructor call.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1583} +\noindent\mdline{1583}According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of \mdline{1586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1586}, +\mdline{1587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1587}, or \mdline{1587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1587}~[\mdcite{p4selectexpr}{25}]\mdline{1587}. The rest of this section looks at all 3 of +these cases and gives an example \mdline{1588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1588} message when appropriate.%mdk + +%mdk-data-line={1590} +\begin{enumerate}%mdk + +%mdk-data-line={1590} +\item{} +%mdk-data-line={1590} +\mdline{1590}If the type parameter is \mdline{1590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1590}, \mdline{1590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1590} will include exactly one +\mdline{1591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1591} message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used):%mdk + +%mdk-data-line={1594} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1594} +\item\mdline{1594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1594}: set to 1%mdk + +%mdk-data-line={1595} +\item\mdline{1595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1595}: set to the value of \mdline{1595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1595}%mdk + +%mdk-data-line={1596} +\item\mdline{1596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1596}: set to \mdline{1596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1596}%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1598} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1599} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}bit\textless{}8\textgreater{}~\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(hdr.f8)~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1602} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1603} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1617} +\begin{enumerate}[,start=2]%mdk + +%mdk-data-line={1617} +\item{} +%mdk-data-line={1617} +\mdline{1617}If the type parameter is a \mdline{1617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1617}, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program.%mdk%mdk + +%mdk-data-line={1622} +\item{} +%mdk-data-line={1622} +\mdline{1622}If the type parameter is a \mdline{1622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1622}, this version of P4Runtime requires that +all the fields of the struct be of type \mdline{1623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1623} (where \mdline{1623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1623} can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +\mdline{1626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1626} field will include one \mdline{1626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1626} message for each field in the +struct, with the following fields:%mdk + +%mdk-data-line={1629} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1629} +\item\mdline{1629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1629}: must be unique with respect to the other \mdline{1629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1629} entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration.%mdk + +%mdk-data-line={1633} +\item\mdline{1633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1633}: set to the name of the corresponding struct field.%mdk + +%mdk-data-line={1634} +\item\mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1634}: set to the list of P4 annotations associated with the struct +field, except for the \mdline{1635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1635} annotation, if present (see the \mdline{1635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1635} field +below).%mdk + +%mdk-data-line={1637} +\item\mdline{1637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1637}: set to the value of \mdline{1637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1637} for the corresponding struct field.%mdk + +%mdk-data-line={1638} +\item\mdline{1638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1638}, which indicates whether the struct field has a\mdline{1638}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1639}; this is useful for +\mdline{1640}\mdref{sec-psa-metadata-translation}{translation}\mdline{1640}.%mdk + +%mdk-data-line={1641} +\item\mdline{1641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1641}: by default \mdline{1641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1641} is set to \mdline{1641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1641}; the P4 programmer can +specify a different match type by using the \mdline{1642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1642} annotation +\mdline{1643}[\mdcite{p4selectexpr}{25}]\mdline{1643}.%mdk + +%mdk-data-line={1644} +\item\mdline{1644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1644}: documentation associated with the struct field.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1646} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1647} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1655} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1656} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1683} +\noindent\mdline{1683}Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a\mdline{1684}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1685} that resolves to a \mdline{1685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1685}, or a \mdline{1685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1685} where +one or more fields is a\mdline{1686}~\mdref{sec-user-defined-types}{user-defined type}\mdline{1686} that +resolves to a \mdline{1687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1687}. For each \mdline{1687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1687} that corresponds to a user-defined +type, the \mdline{1688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1688} field must be set to the appropriate value (\mdline{1688}i.e.\mdline{1688} the name +of the type).%mdk + +%mdk-data-line={1691} +\subsubsection{\mdline{1691}6.4.8.\hspace*{0.5em}\mdline{1691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}\label{sec-register}%mdk%mdk + +%mdk-data-line={1693} +\noindent\mdline{1693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1693} messages are used to specify all possible instances of Register PSA +externs.%mdk + +%mdk-data-line={1696} +\mdline{1696}Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime.%mdk + +%mdk-data-line={1700} +\mdline{1700}The \mdline{1700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1700} message defines the following fields:%mdk + +%mdk-data-line={1702} +\begin{itemize}%mdk + +%mdk-data-line={1702} +\item{} +%mdk-data-line={1702} +\mdline{1702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1702}, a \mdline{1702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1702} message with the ID, name, and alias of this register +instance.%mdk%mdk + +%mdk-data-line={1705} +\item{} +%mdk-data-line={1705} +\mdline{1705}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1705}, which specifies the data type stored by this register, expressed +using a \mdline{1706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1706} message (see section on\mdline{1706}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary +P4 Types}\mdline{1707}).%mdk%mdk + +%mdk-data-line={1709} +\item{} +%mdk-data-line={1709} +\mdline{1709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1709}, an \mdline{1709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1709} value representing the total number of independent register +cells available.%mdk%mdk + +%mdk-data-line={1712} +\item{} +%mdk-data-line={1712} +\mdline{1712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1712}, which indicates whether the register index has a +\mdline{1713}\mdref{sec-user-defined-types}{user-defined type}\mdline{1713}. This is useful for +\mdline{1714}\mdref{sec-psa-metadata-translation}{translation}\mdline{1714}. The underlying built-in type +must be a fixed-width unsigned bitstring (\mdline{1715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1715}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1717} +\subsubsection{\mdline{1717}6.4.9.\hspace*{0.5em}\mdline{1717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}\label{sec-digest}%mdk%mdk + +%mdk-data-line={1719} +\noindent\mdline{1719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1719} messages are used to specify all possible instances of Packet Digest +PSA externs.%mdk + +%mdk-data-line={1722} +\mdline{1722}A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages.%mdk + +%mdk-data-line={1731} +\mdline{1731}The \mdline{1731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1731} message defines the following fields:%mdk + +%mdk-data-line={1733} +\begin{itemize}%mdk + +%mdk-data-line={1733} +\item{} +%mdk-data-line={1733} +\mdline{1733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1733}, a \mdline{1733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1733} message with the ID, name, and alias of this digest +instance.%mdk%mdk + +%mdk-data-line={1736} +\item{} +%mdk-data-line={1736} +\mdline{1736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1736}, which specifies the data type of an individual digest +notification using a \mdline{1737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1737} message (see section on\mdline{1737}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation +of Arbitrary P4 Types}\mdline{1738}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1740} +\subsubsection{\mdline{1740}6.4.10.\hspace*{0.5em}\mdline{1740}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}\label{sec-p4info-extern}%mdk%mdk + +%mdk-data-line={1742} +\noindent\mdline{1742}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1742} messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one \mdline{1745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1745} message instance in P4Info. The \mdline{1745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1745} message defines +the following fields:%mdk + +%mdk-data-line={1748} +\begin{itemize}%mdk + +%mdk-data-line={1748} +\item{} +%mdk-data-line={1748} +\mdline{1748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{1748}, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the\mdline{1749}~\mdref{sec-id-allocation}{reserved +range}\mdline{1750} \mdline{1750}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{}[0x81,~0xfe]}}}\mdline{1750}. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture.%mdk%mdk + +%mdk-data-line={1755} +\item{} +%mdk-data-line={1755} +\mdline{1755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_name}}}\mdline{1755}, which specifies the fully-qualified P4 name of the extern +type.%mdk%mdk + +%mdk-data-line={1758} +\item{} +%mdk-data-line={1758} +\mdline{1758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instances}}}\mdline{1758}, a repeated field of \mdline{1758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{1758} Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +\mdline{1760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{1760} in turn defines the following fields:%mdk + +%mdk-data-line={1762} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1762} +\item\mdline{1762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1762}, a \mdline{1762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1762} message with the ID, name, and alias of this digest +instance.%mdk + +%mdk-data-line={1764} +\item\mdline{1764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{1764}, an \mdline{1764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1764} Protobuf message\mdline{1764}~[\mdcite{protoany}{30}]\mdline{1764} which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for \mdline{1766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{1766} should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on\mdline{1768}~\mdref{sec-extending-p4runtime}{Extending +P4Runtime for non-PSA Architectures}\mdline{1769} for more +information.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1772} +\noindent\mdline{1772}If the P4 program does not include any instance of a given extern type, the +\mdline{1773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1773} message instance for that type should be omitted from the P4Info.%mdk + +%mdk-data-line={1775} +\subsection{\mdline{1775}6.5.\hspace*{0.5em}\mdline{1775}Support for Arbitrary P4 Types with P4TypeInfo}\label{sec-support-for-arbitrary-p4-types-with-p4typeinfo}%mdk%mdk + +%mdk-data-line={1777} +\noindent\mdline{1777}See section on\mdline{1777}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary P4 +Types}\mdline{1778}.%mdk + +%mdk-data-line={1780} +\section{\mdline{1780}7.\hspace*{0.5em}\mdline{1780}P4 Forwarding-Pipeline Configuration}\label{sec-p4-fwd-pipe-config}%mdk%mdk + +%mdk-data-line={1782} +\noindent\mdline{1782}The \mdline{1782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{1782} captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the \mdline{1784}\textquotedblleft{}Device Configuration\textquotedblright{}\mdline{1784} and sometimes also referred to as +the \mdline{1785}\textquotedblleft{}P4 Blob\textquotedblright{}\mdline{1785}. It is defined as:%mdk + +%mdk-data-line={1787} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1788} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ForwardingPipelineConfig~\{\\ +~~config.P{\mdcolor{purple}4}Info~p4info~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~p4\_device\_config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}message}}~Cookie~\{\\ +~~~~{\bfseries{\mdcolor{navy}uint64}}~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~\}\\ +~~Cookie~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1798} +\noindent\mdline{1798}The \mdline{1798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{1798} field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic.%mdk + +%mdk-data-line={1801} +\mdline{1801}The \mdline{1801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{1801} is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new \mdline{1803}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{1803} on that target.%mdk + +%mdk-data-line={1805} +\mdline{1805}The \mdline{1805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{1805} field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a \mdline{1810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{1810} RPC. +When writing the config via a \mdline{1811}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{1811} RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present.%mdk + +%mdk-data-line={1815} +\section{\mdline{1815}8.\hspace*{0.5em}\mdline{1815}General Principles for Message Formatting}\label{sec-general-principles-for-message-formatting}%mdk%mdk + +%mdk-data-line={1817} +\subsection{\mdline{1817}8.1.\hspace*{0.5em}\mdline{1817}Set / Unset Protobuf Field}\label{sec-set-unset-protobuf-field}%mdk%mdk + +%mdk-data-line={1819} +\noindent\mdline{1819}In Protobuf version 3 (\mdline{1819}\emph{proto3}\mdline{1819}), the default value for a message field is +\mdline{1820}\textquotedblleft{}unset\textquotedblright{}\mdline{1820}~[\mdcite{protodefaults}{4}]\mdline{1820}. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +\mdline{1825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{1825} message, an \mdline{1825}\textquotedblleft{}unset\textquotedblright{}\mdline{1825} \mdline{1825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1825} field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the \mdline{1827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1827} message field is +set, a single entry will be read.%mdk + +%mdk-data-line={1830} +\mdline{1830}Let\mdline{1830}'\mdline{1830}s look at the counter example in more details. Based on this specification +document, the C++ server code which processes \mdline{1831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{1831} messages may look +like this:%mdk + +%mdk-data-line={1833} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1834} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}auto}}~*counter\_entry~=~...\\ +{\bfseries{\mdcolor{navy}if}}~(counter\_entry-\textgreater{}has\_index())~\{\\ +~~{\bfseries{\mdcolor{navy}auto}}~index~=~counter\_entry-\textgreater{}index().index();\\ +~~read\_one\_entry(counter\_entry-\textgreater{}id(),~index);\\ +\}~{\bfseries{\mdcolor{navy}else}}~\{\\ +~~read\_all\_entries(counter\_entry-\textgreater{}id());\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1843} +\begin{enumerate}%mdk + +%mdk-data-line={1843} +\item{} +%mdk-data-line={1843} +\mdline{1843}Reading a single counter entry at index 0 in the counter array with id +\mdline{1844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textless{}id\textgreater{}}}}\mdline{1844}:%mdk + +%mdk-data-line={1845} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1845} +\item\mdline{1845}Here is the C++ client code: + +%mdk-data-line={1846} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1847} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});\\ +entry.mutable\_index();\\ +{\mdcolor{darkgreen}//~The~above~line~sets~the~index~field;~it~is~equivalent~to:}\\ +{\mdcolor{darkgreen}//~auto~*index~=~entry.mutable\_index();}\\ +{\mdcolor{darkgreen}//~index-\textgreater{}set\_index(0);}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={1854} +\item\mdline{1854}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={1855} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1856} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}\\ +index~\{\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={1859} +\item\mdline{1859}\textbf{Expected behavior}\mdline{1859}: Counter entry at index 0 is read. Notice that the +\mdline{1860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1860} subfield is missing under the \mdline{1860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1860} field message of +\mdline{1861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{1861} in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1866} +\item{} +%mdk-data-line={1866} +\mdline{1866}Reading all counter entries by leaving the \mdline{1866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1866} field unset%mdk + +%mdk-data-line={1867} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1867} +\item\mdline{1867}Here is the C++ client code: + +%mdk-data-line={1868} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1869} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={1872} +\item\mdline{1872}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={1873} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1874} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={1876} +\item\mdline{1876}\textbf{Expected behavior}\mdline{1876}: All counter entries for the provided counter +instance are read. Notice that the \mdline{1877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{1877} message field is unset (default +value) and is therefore omitted from the textual representation of the +message.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1881} +\subsection{\mdline{1881}8.2.\hspace*{0.5em}\mdline{1881}Read-Write Symmetry}\label{sec-read-write-symmetry}%mdk%mdk + +%mdk-data-line={1883} +\noindent\mdline{1883}The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example:%mdk + +%mdk-data-line={1889} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1890} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}intended\_value~=~value\\ +\\ +status~=~server.write(intended\_value,~p4\_entity)\\ +observed\_value~=~server.read(p4\_entity)\\ +\\ +assert(intended\_value~==~observed\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1898} +\noindent\mdline{1898}To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If \mdline{1902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{1902} RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol\mdline{1905}'\mdline{1905}s complexities to the client implementations.%mdk + +%mdk-data-line={1907} +\mdline{1907}In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the \mdline{1910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1910} fields in a \mdline{1910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{1910} message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +\mdline{1913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MessageDifferencer}}}\mdline{1913} class\mdline{1913}~[\mdcite{protomessagedifferencer}{35}]\mdline{1913} included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance.%mdk + +%mdk-data-line={1918} +\subsection{\mdline{1918}8.3.\hspace*{0.5em}\mdline{1918}Zero as Reserved Value}\label{sec-zero-as-reserved-value}%mdk%mdk + +%mdk-data-line={1920} +\noindent\mdline{1920}p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a \mdline{1921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1921}. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a \mdline{1924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{1924} or a \mdline{1924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfigRequest}}}\mdline{1924}.%mdk + +%mdk-data-line={1926} +\subsection{\mdline{1926}8.4.\hspace*{0.5em}\mdline{1926}Bytestrings}\label{sec-bytestrings}%mdk%mdk + +%mdk-data-line={1928} +\noindent\mdline{1928}P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (\mdline{1930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1930}) or signed (\mdline{1930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1930}), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +\mdline{1933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{1933} Protobuf type. The correct bitwidth\mdline{1933} \mdline{1933}\textemdash{}\mdline{1933} as per the P4 program\mdline{1933} \mdline{1933}\textemdash{}\mdline{1933} of +each integer variable exposed through P4Runtime is specified in the P4Info +message.%mdk + +%mdk-data-line={1937} +\mdline{1937}The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals:%mdk + +%mdk-data-line={1940} +\begin{itemize}%mdk + +%mdk-data-line={1940} +\item{} +%mdk-data-line={1940} +\mdline{1940}It ensures that a properly encoded binary string\mdline{1940}'\mdline{1940}s integer value conforms +to the P4Info-specified bitwidth.%mdk%mdk + +%mdk-data-line={1943} +\item{} +%mdk-data-line={1943} +\mdline{1943}It supports\mdline{1943}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{1943}.%mdk%mdk + +%mdk-data-line={1945} +\item{} +%mdk-data-line={1945} +\mdline{1945}It helps facilitate non-disruptive P4 program updates.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1947} +\noindent\mdline{1947}In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type \mdline{1952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1952} and/or \mdline{1952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1952}.%mdk + +%mdk-data-line={1954} +\mdline{1954}Note that this representation does \mdline{1954}\emph{not}\mdline{1954} make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range.%mdk + +%mdk-data-line={1963} +\mdline{1963}In the P4Runtime API version 1.0, values of table key fields, action parameters, +and fields in packet-in and packet-out headers between a device and the +controller (see\mdline{1965}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{1965}), may not be of type \mdline{1965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1965}. +The rules for encoding signed values thus only apply to messages of type +\mdline{1967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{1967} (see\mdline{1967}~\mdref{sec-p4data-in-p4runtime-proto}{8.5.3}\mdline{1967}).%mdk + +%mdk-data-line={1969} +\mdline{1969}For a value of type \mdline{1969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1969}, the fewest number of bits required to represent +the integer value \mdline{1970}$V > 0$\mdline{1970} is the smallest integer \mdline{1970}$A$\mdline{1970} such that \mdline{1970}$V \leq 2^A -1$\mdline{1971}.%mdk + +%mdk-data-line={1973} +\mdline{1973}For a value of type \mdline{1973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1973}, the fewest number of bits required to represent +the integer value \mdline{1974}$V \neq 0$\mdline{1974} in 2\mdline{1974}'\mdline{1974}s complement form is the smallest integer \mdline{1974}$A$\mdline{1974} +such that \mdline{1975}$-2^{A-1} \leq V \leq 2^{A-1} - 1$\mdline{1975}.%mdk + +%mdk-data-line={1977} +\mdline{1977}As a special case, define that the value \mdline{1977}$V=0$\mdline{1977} requires at least \mdline{1977}$A=1$\mdline{1977} bit to +represent, regardless of whether it is signed or unsigned.%mdk + +%mdk-data-line={1980} +\mdline{1980}The shortest possible binary string for an integer \mdline{1980}$V$\mdline{1980} that needs \mdline{1980}$A$\mdline{1980} bits to +represent it is computed as:%mdk + +%mdk-data-line={1982} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={1983} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size~=~floor(({\mdcolor{teal}A}~+~{\mdcolor{purple}7})~/~{\mdcolor{purple}8})}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1986} +\noindent\mdline{1986}Binary strings with the byte length computed as \mdline{1986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{1986} promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies.%mdk + +%mdk-data-line={1990} +\mdline{1990}Any additional bits in the bytes sent for an unsigned integer value (type +\mdline{1991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1991}) must be 0. If additional bytes are transmitted above the +\mdline{1992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{1992} minimum required, they must be filled with 0.%mdk + +%mdk-data-line={1994} +\mdline{1994}Any additional bits in the bytes sent for a signed integer value (type \mdline{1994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{1994}) +must be copies of the sign bit, \mdline{1995}i.e.\mdline{1995} 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +\mdline{1997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{1997} minimum required, they must be filled with copies of the +sign bit, \mdline{1998}i.e.\mdline{1998} 0 for non-negative values, or 0xff for negative values. In 2\mdline{1998}'\mdline{1998}s +complement representation, this is called \mdline{1999}\textquotedblleft{}sign extension\textquotedblright{}\mdline{1999}, and leaves the +numeric value represented unchanged.%mdk + +%mdk-data-line={2002} +\mdline{2002}Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value.%mdk + +%mdk-data-line={2008} +\mdline{2008}For a received bitstring expected to fit within a \mdline{2008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2008} type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring\mdline{2010}'\mdline{2010}s width is \mdline{2010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2010} bits or less.%mdk + +%mdk-data-line={2012} +\mdline{2012}For a received bitstring expected to fit within an \mdline{2012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2012} type, the value it +represents is in range if, after \mdline{2013}\textquotedblleft{}undoing sign extension\textquotedblright{}\mdline{2013}, the remaining bit +string\mdline{2014}'\mdline{2014}s width is \mdline{2014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2014} bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other.%mdk + +%mdk-data-line={2020} +\mdline{2020}If the string\mdline{2020}'\mdline{2020}s byte length is zero, the server always rejects the string.%mdk + +%mdk-data-line={2022} +\mdline{2022}When the server rejects a binary string due to any of the previous criteria, +it returns an \mdline{2023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2023} error.%mdk + +%mdk-data-line={2025} +\mdline{2025}For all binary strings, P4Runtime uses big-endian (\mdline{2025}i.e.\mdline{2025} network) byte-order. +For signed integer values (\mdline{2026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2026} P4 type), P4Runtime uses the same two\mdline{2026}'\mdline{2026}s +complement bitwise representation as P4. Table\mdline{2027}~\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}}\mdline{2027} +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above.%mdk + +%mdk-data-line={2031} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2033} P4 type}}&\multicolumn{1}{|c}{{\bfseries\mdline{2033} Integer value}}&\multicolumn{1}{|c}{{\bfseries\mdline{2033} P4Runtime binary string}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2033} Read-write symmetry}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2035} \mdline{2035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2035}}&\multicolumn{1}{|l}{\mdline{2035} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2035} \mdline{2035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2035}}&\multicolumn{1}{|l|}{\mdline{2035} yes}\\ +\multicolumn{1}{|l}{\mdline{2036} \mdline{2036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2036}}&\multicolumn{1}{|l}{\mdline{2036} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2036} \mdline{2036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2036}}&\multicolumn{1}{|l|}{\mdline{2036} no}\\ +\multicolumn{1}{|l}{\mdline{2037} \mdline{2037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2037}}&\multicolumn{1}{|l}{\mdline{2037} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2037} \mdline{2037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2037}}&\multicolumn{1}{|l|}{\mdline{2037} yes}\\ +\multicolumn{1}{|l}{\mdline{2038} \mdline{2038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2038}}&\multicolumn{1}{|l}{\mdline{2038} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2038} \mdline{2038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x30\textbackslash{}x64}}}\mdline{2038}}&\multicolumn{1}{|l|}{\mdline{2038} yes}\\ +\multicolumn{1}{|l}{\mdline{2039} \mdline{2039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2039}}&\multicolumn{1}{|l}{\mdline{2039} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2039} \mdline{2039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x30\textbackslash{}x64}}}\mdline{2039}}&\multicolumn{1}{|l|}{\mdline{2039} no}\\ +\multicolumn{1}{|l}{\mdline{2040} \mdline{2040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2040}}&\multicolumn{1}{|l}{\mdline{2040} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2040} \mdline{2040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2040}}&\multicolumn{1}{|l|}{\mdline{2040} no}\\ +\multicolumn{1}{|l}{\mdline{2041} \mdline{2041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2041}}&\multicolumn{1}{|l}{\mdline{2041} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2041} \mdline{2041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2041}}&\multicolumn{1}{|l|}{\mdline{2041} yes}\\ +\multicolumn{1}{|l}{\mdline{2042} \mdline{2042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2042}}&\multicolumn{1}{|l}{\mdline{2042} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2042} \mdline{2042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00\textbackslash{}x63}}}\mdline{2042}}&\multicolumn{1}{|l|}{\mdline{2042} no}\\ +\multicolumn{1}{|l}{\mdline{2043} \mdline{2043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2043}}&\multicolumn{1}{|l}{\mdline{2043} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2043} \mdline{2043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2043}}&\multicolumn{1}{|l|}{\mdline{2043} yes}\\ +\multicolumn{1}{|l}{\mdline{2044} \mdline{2044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2044}}&\multicolumn{1}{|l}{\mdline{2044} \mdline{2044}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2044} \mdline{2044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x9d}}}\mdline{2044}}&\multicolumn{1}{|l|}{\mdline{2044} yes}\\ +\multicolumn{1}{|l}{\mdline{2045} \mdline{2045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2045}}&\multicolumn{1}{|l}{\mdline{2045} \mdline{2045}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2045} \mdline{2045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xff\textbackslash{}x9d}}}\mdline{2045}}&\multicolumn{1}{|l|}{\mdline{2045} no}\\ +\multicolumn{1}{|l}{\mdline{2046} \mdline{2046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2046}}&\multicolumn{1}{|l}{\mdline{2046} \mdline{2046}-739 (-0x2e3)}&\multicolumn{1}{|l}{\mdline{2046} \mdline{2046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xfd\textbackslash{}x1d}}}\mdline{2046}}&\multicolumn{1}{|l|}{\mdline{2046} yes}\\ +\multicolumn{1}{|l}{\mdline{2047} \mdline{2047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2047}}&\multicolumn{1}{|l}{\mdline{2047} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2047} \mdline{2047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00}}}\mdline{2047}}&\multicolumn{1}{|l|}{\mdline{2047} no}\\ +\multicolumn{1}{|l}{\mdline{2048} \mdline{2048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2048}}&\multicolumn{1}{|l}{\mdline{2048} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2048} \mdline{2048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00}}}\mdline{2048}}&\multicolumn{1}{|l|}{\mdline{2048} yes}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2050} +\mdhr{}%mdk + +%mdk-data-line={2051} +\noindent\mdline{2051}\mdcaption{\textbf{Table~\mdcaptionlabel{4}.}~\mdcaptiontext{Examples of Valid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-valid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2053} +\mdline{2053}Table\mdline{2053}~\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}}\mdline{2053} shows some examples of invalid +P4Runtime binary strings:%mdk + +%mdk-data-line={2056} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2058} P4 type}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2058} P4Runtime binary string}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2060} \mdline{2060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2060}}&\multicolumn{1}{|l|}{\mdline{2060} \mdline{2060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x63}}}\mdline{2060}}\\ +\multicolumn{1}{|l}{\mdline{2061} \mdline{2061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2061}}&\multicolumn{1}{|l|}{\mdline{2061} \mdline{2061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2061}}\\ +\multicolumn{1}{|l}{\mdline{2062} \mdline{2062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2062}}&\multicolumn{1}{|l|}{\mdline{2062} \mdline{2062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2062}}\\ +\multicolumn{1}{|l}{\mdline{2063} \mdline{2063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2063}}&\multicolumn{1}{|l|}{\mdline{2063} \mdline{2063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x10\textbackslash{}x63}}}\mdline{2063}}\\ +\multicolumn{1}{|l}{\mdline{2064} \mdline{2064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2064}}&\multicolumn{1}{|l|}{\mdline{2064} \mdline{2064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2064}}\\ +\multicolumn{1}{|l}{\mdline{2065} \mdline{2065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2065}}&\multicolumn{1}{|l|}{\mdline{2065} \mdline{2065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x40\textbackslash{}x63}}}\mdline{2065}}\\ +\multicolumn{1}{|l}{\mdline{2066} \mdline{2066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2066}}&\multicolumn{1}{|l|}{\mdline{2066} \mdline{2066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x9d}}}\mdline{2066}}\\ +\multicolumn{1}{|l}{\mdline{2067} \mdline{2067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2067}}&\multicolumn{1}{|l|}{\mdline{2067} \mdline{2067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x8d\textbackslash{}x1d}}}\mdline{2067}}\\ +\multicolumn{1}{|l}{\mdline{2068} \mdline{2068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2068}}&\multicolumn{1}{|l|}{\mdline{2068} \mdline{2068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2068}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2070} +\mdhr{}%mdk + +%mdk-data-line={2071} +\noindent\mdline{2071}\mdcaption{\textbf{Table~\mdcaptionlabel{5}.}~\mdcaptiontext{Examples of Invalid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-invalid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2073} +\mdline{2073}As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from \mdline{2078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2078} to \mdline{2078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2078}, a server +running the \mdline{2079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2079} version of the P4 program will accept requests from +clients that remain on the \mdline{2080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2080} P4Runtime version.%mdk + +%mdk-data-line={2082} +\mdline{2082}Despite the server\mdline{2082}'\mdline{2082}s binary string flexibility for P4 program update support, +the client and server must both remain aware of the +\mdline{2084}\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2084} +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values.%mdk + +%mdk-data-line={2089} +\mdline{2089}Representation of variable-length integer values (\mdline{2089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2089} P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the \mdline{2091}\emph{dynamic-length}\mdline{2091} of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an \mdline{2094}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2094} error code otherwise.%mdk + +%mdk-data-line={2096} +\subsection{\mdline{2096}8.5.\hspace*{0.5em}\mdline{2096}Representation of Arbitrary P4 Types}\label{sec-representation-of-arbitrary-p4-types}%mdk%mdk + +%mdk-data-line={2098} +\subsubsection{\mdline{2098}8.5.1.\hspace*{0.5em}\mdline{2098}Problem Statement}\label{sec-problem-statement}%mdk%mdk + +%mdk-data-line={2100} +\noindent\mdline{2100}The P4\mdline{2100}\mdsub{16}\mdline{2100} language includes more complex types than just binary strings +\mdline{2101}[\mdcite{p4complextypes}{3}]\mdline{2101}. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table\mdline{2104}~\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}}\mdline{2104} shows the different +P4\mdline{2105}\mdsub{16}\mdline{2105} types and how they are allowed to be used, as per the P4\mdline{2105}\mdsub{16}\mdline{2105} +specification.%mdk + +%mdk-data-line={2108} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|l}{{\bfseries\mdline{2110}}}&\multicolumn{3}{|c|}{{\bfseries\mdline{2110} Container type}}\\ +\cmidrule{2-2}\cmidrule{3-3}\cmidrule{4-4} +\multicolumn{1}{|l}{{\bfseries\mdline{2112} Element type}}&\multicolumn{1}{|l}{{\bfseries\mdline{2112} header}}&\multicolumn{1}{|l}{{\bfseries\mdline{2112} header\mdline{2112}\_\mdline{2112}union}}&\multicolumn{1}{|l|}{{\bfseries\mdline{2112} struct or tuple}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2114} \mdline{2114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2114}}&\multicolumn{1}{|l}{\mdline{2114} allowed}&\multicolumn{1}{|l}{\mdline{2114} error}&\multicolumn{1}{|l|}{\mdline{2114} allowed}\\ +\multicolumn{1}{|l}{\mdline{2115} \mdline{2115}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2115}}&\multicolumn{1}{|l}{\mdline{2115} allowed}&\multicolumn{1}{|l}{\mdline{2115} error}&\multicolumn{1}{|l|}{\mdline{2115} allowed}\\ +\multicolumn{1}{|l}{\mdline{2116} \mdline{2116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2116}}&\multicolumn{1}{|l}{\mdline{2116} allowed}&\multicolumn{1}{|l}{\mdline{2116} error}&\multicolumn{1}{|l|}{\mdline{2116} allowed}\\ +\multicolumn{1}{|l}{\mdline{2117} \mdline{2117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int}}}\mdline{2117}}&\multicolumn{1}{|l}{\mdline{2117} error}&\multicolumn{1}{|l}{\mdline{2117} error}&\multicolumn{1}{|l|}{\mdline{2117} error}\\ +\multicolumn{1}{|l}{\mdline{2118} \mdline{2118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}void}}}\mdline{2118}}&\multicolumn{1}{|l}{\mdline{2118} error}&\multicolumn{1}{|l}{\mdline{2118} error}&\multicolumn{1}{|l|}{\mdline{2118} error}\\ +\multicolumn{1}{|l}{\mdline{2119} \mdline{2119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2119}}&\multicolumn{1}{|l}{\mdline{2119} error}&\multicolumn{1}{|l}{\mdline{2119} error}&\multicolumn{1}{|l|}{\mdline{2119} allowed}\\ +\multicolumn{1}{|l}{\mdline{2120} \mdline{2120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_kind}}}\mdline{2120}}&\multicolumn{1}{|l}{\mdline{2120} error}&\multicolumn{1}{|l}{\mdline{2120} error}&\multicolumn{1}{|l|}{\mdline{2120} error}\\ +\multicolumn{1}{|l}{\mdline{2121} \mdline{2121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2121}}&\multicolumn{1}{|l}{\mdline{2121} error}&\multicolumn{1}{|l}{\mdline{2121} error}&\multicolumn{1}{|l|}{\mdline{2121} allowed}\\ +\multicolumn{1}{|l}{\mdline{2122} \mdline{2122}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2122}}&\multicolumn{1}{|l}{\mdline{2122} allowed\mdline{2122}\mdfootnote{1}{%mdk-data-line={2132} +%mdk-data-line={2132} +\noindent\mdline{2132}an \mdline{2132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2132} type used as a field in a \mdline{2132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2132} must specify a +underlying type and representation for \mdline{2133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2133} elements.%mdk +\label{fn-enum_header}%mdk%mdk +}\mdline{2122}}&\multicolumn{1}{|l}{\mdline{2122} error}&\multicolumn{1}{|l|}{\mdline{2122} allowed}\\ +\multicolumn{1}{|l}{\mdline{2123} \mdline{2123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2123}}&\multicolumn{1}{|l}{\mdline{2123} error}&\multicolumn{1}{|l}{\mdline{2123} allowed}&\multicolumn{1}{|l|}{\mdline{2123} allowed}\\ +\multicolumn{1}{|l}{\mdline{2124} header stack}&\multicolumn{1}{|l}{\mdline{2124} error}&\multicolumn{1}{|l}{\mdline{2124} error}&\multicolumn{1}{|l|}{\mdline{2124} allowed}\\ +\multicolumn{1}{|l}{\mdline{2125} \mdline{2125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2125}}&\multicolumn{1}{|l}{\mdline{2125} error}&\multicolumn{1}{|l}{\mdline{2125} error}&\multicolumn{1}{|l|}{\mdline{2125} allowed}\\ +\multicolumn{1}{|l}{\mdline{2126} \mdline{2126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2126}}&\multicolumn{1}{|l}{\mdline{2126} error}&\multicolumn{1}{|l}{\mdline{2126} error}&\multicolumn{1}{|l|}{\mdline{2126} allowed}\\ +\multicolumn{1}{|l}{\mdline{2127} \mdline{2127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2127}}&\multicolumn{1}{|l}{\mdline{2127} error}&\multicolumn{1}{|l}{\mdline{2127} error}&\multicolumn{1}{|l|}{\mdline{2127} allowed}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2129} +\mdhr{}%mdk + +%mdk-data-line={2130} +\noindent\mdline{2130}\mdcaption{\textbf{Table~\mdcaptionlabel{6}.}~\mdcaptiontext{P4 Type Usage}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-type-usage}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2135} +\mdline{2135}For example, the following P4\mdline{2135}\mdsub{16}\mdline{2135} objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects.%mdk + +%mdk-data-line={2138} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2139} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}{\bfseries{\mdcolor{navy}tuple}}\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}4}\textgreater{},~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~\textgreater{}~\textgreater{}()~digest\_complex;\\ +digest\_complex.pack(\{~hdr.ipv4.version,~hdr.ipv4.protocol~\});\\ +{\mdcolor{darkgreen}//~...}\\ +{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2149} +\noindent\mdline{2149}One solution would be to use only binary string (\mdline{2149}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2149} type) in +p4runtime.proto and to define a custom serialization format for complex P4\mdline{2150}\mdsub{16}\mdline{2150} +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P4\mdline{2157}\mdsub{16}\mdline{2157} types.%mdk + +%mdk-data-line={2159} +\subsubsection{\mdline{2159}8.5.2.\hspace*{0.5em}\mdline{2159}P4 Type Specifications in p4info.proto}\label{sec-p4-type-specifications-in-p4infoproto}%mdk%mdk + +%mdk-data-line={2161} +\noindent\mdline{2161}In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type \mdline{2165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip\_t}}}\mdline{2165}, which is a header union with 2 possible headers: +\mdline{2166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4}}}\mdline{2166} with type \mdline{2166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4\_t}}}\mdline{2166} and \mdline{2166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6}}}\mdline{2166} with type \mdline{2166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6\_t}}}\mdline{2166}. Similarly, they need to +know the field layout for both of these header types.%mdk + +%mdk-data-line={2169} +\mdline{2169}To achieve this we introduce 2 main Protobuf messages: \mdline{2169}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2169} and +\mdline{2170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2170}.%mdk + +%mdk-data-line={2172} +\mdline{2172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2172} is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P4\mdline{2173}\mdsub{16}\mdline{2173} program. These +named types are \mdline{2174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2174}, \mdline{2174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2174}, \mdline{2174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2174}, \mdline{2174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2174} and +\mdline{2175}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2175}; for each of these we have a type specification message, +respectively \mdline{2176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructTypeSpec}}}\mdline{2176}, \mdline{2176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderTypeSpec}}}\mdline{2176}, \mdline{2176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionTypeSpec}}}\mdline{2176}, +\mdline{2177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4EnumTypeSpec}}}\mdline{2177} and \mdline{2177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4SerializableEnumTypeSpec}}}\mdline{2177}. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. \mdline{2179}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2179} also includes the list of parser errors for the program, as +a \mdline{2180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4ErrorTypeSpec}}}\mdline{2180} message.%mdk + +%mdk-data-line={2182} +\mdline{2182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2182} is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each \mdline{2184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2184} message corresponds to a compile-time type in the +original P4\mdline{2185}\mdsub{16}\mdline{2185} program (\mdline{2185}e.g.\mdline{2185} the type parameter of an extern). This +compile-time type is represented as a Protobuf \mdline{2186}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2186}, which can be:%mdk + +%mdk-data-line={2188} +\begin{itemize}%mdk + +%mdk-data-line={2188} +\item{} +%mdk-data-line={2188} +\mdline{2188}a string representing the name of the type in case of a named type (\mdline{2188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2188}, +\mdline{2189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2189}, \mdline{2189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2189}, \mdline{2189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2189}, \mdline{2189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2189} or user-defined \mdline{2189}\textquotedblleft{}new\textquotedblright{}\mdline{2189} +\mdline{2190}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2190}),%mdk%mdk + +%mdk-data-line={2192} +\item{} +%mdk-data-line={2192} +\mdline{2192}an empty Protobuf message for \mdline{2192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2192} and \mdline{2192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2192}, or%mdk%mdk + +%mdk-data-line={2194} +\item{} +%mdk-data-line={2194} +\mdline{2194}a Protobuf message for other anonymous types (\mdline{2194}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2194}, \mdline{2194}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2194}, \mdline{2194}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2194}, +\mdline{2195}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2195} or stack). The \mdline{2195}\textquotedblleft{}binary string\textquotedblright{}\mdline{2195} types (\mdline{2195}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2195}, \mdline{2195}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2195}, and +\mdline{2196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2196}) are grouped together in the \mdline{2196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4BitstringLikeTypeSpec}}}\mdline{2196} message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf \mdline{2198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2198} +type).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2201} +\noindent\mdline{2201}For all P4\mdline{2201}\mdsub{16}\mdline{2201} compound types (\mdline{2201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2201}, \mdline{2201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2201}, \mdline{2201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2201}, and \mdline{2201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2201}), +the order of \mdline{2202}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2202} in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P4\mdline{2204}\mdsub{16}\mdline{2204} declaration. The same goes for the order of members of an \mdline{2204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2204} +(serializable or not) or members of \mdline{2205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2205}.%mdk + +%mdk-data-line={2207} +\subsubsection{\mdline{2207}8.5.3.\hspace*{0.5em}\mdline{2207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2207} in p4runtime.proto}\label{sec-p4data-in-p4runtime-proto}%mdk%mdk + +%mdk-data-line={2209} +\noindent\mdline{2209}P4Runtime uses the \mdline{2209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2209} message to represent values of arbitrary types. The +P4Runtime client must generate correct \mdline{2210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2210} messages based on the type +specification information included in P4Info. The \mdline{2211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2211} message was designed +to introduce little overhead compared to using binary strings in the most common +case (P4\mdline{2213}\mdsub{16}\mdline{2213} \mdline{2213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2213} type).%mdk + +%mdk-data-line={2215} +\mdline{2215}Just like its P4Info counterpart\mdline{2215} \mdline{2215}- \mdline{2215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2215} \mdline{2215}-, \mdline{2215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2215} uses a Protobuf +\mdline{2216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2216} to represent all possible values.%mdk + +%mdk-data-line={2218} +\mdline{2218}We define a canonical representation for \mdline{2218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2218} messages\mdline{2218} \mdline{2218}\textemdash{}\mdline{2218} therefore +guaranteeing read-write symmetry\mdline{2219} \mdline{2219}\textemdash{}\mdline{2219} by introducing the following requirements:%mdk + +%mdk-data-line={2221} +\begin{itemize}%mdk + +%mdk-data-line={2221} +\item{} +%mdk-data-line={2221} +\mdline{2221}The order of \mdline{2221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2221} in \mdline{2221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructLike}}}\mdline{2221} and the order of \mdline{2221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2221} in +\mdline{2222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2222} must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P4\mdline{2223}\mdsub{16}\mdline{2223} type +declaration.%mdk%mdk + +%mdk-data-line={2226} +\item{} +%mdk-data-line={2226} +\mdline{2226}An invalid header is represented by a \mdline{2226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2226} message where the \mdline{2226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_valid}}}\mdline{2226} +field is false and the \mdline{2227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2227} repeated field is empty.%mdk%mdk + +%mdk-data-line={2229} +\item{} +%mdk-data-line={2229} +\mdline{2229}An invalid header union (\mdline{2229}i.e.\mdline{2229} all headers in the union are invalid) is +represented by a \mdline{2230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnion}}}\mdline{2230} message where the \mdline{2230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header\_name}}}\mdline{2230} is the +empty string (default value for the field) and the \mdline{2231}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header}}}\mdline{2231} is unset.%mdk%mdk + +%mdk-data-line={2233} +\item{} +%mdk-data-line={2233} +\mdline{2233}The order of \mdline{2233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2233} in \mdline{2233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStack}}}\mdline{2233} and \mdline{2233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStack}}}\mdline{2233} is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the \mdline{2235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2235} field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding \mdline{2237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStackTypeSpec}}}\mdline{2237} or +\mdline{2238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStackTypeSpec}}}\mdline{2238} message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2240} +\subsubsection{\mdline{2240}8.5.4.\hspace*{0.5em}\mdline{2240}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={2242} +\noindent\mdline{2242}Let\mdline{2242}'\mdline{2242}s look at the Register example again:%mdk + +%mdk-data-line={2244} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2245} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2252} +\noindent\mdline{2252}Here\mdline{2252}'\mdline{2252}s the corresponding entry in the P4Info message:%mdk + +%mdk-data-line={2254} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2255} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}registers~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}369119267}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~\}\\ +~~type\_spec~\{\\ +~~~~header\_union~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~size:~{\mdcolor{purple}128}\\ +\}\\ +type\_info~\{\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~header\_unions~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2311} +\noindent\mdline{2311}Here\mdline{2311}'\mdline{2311}s a \mdline{2311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.WriteRequest}}}\mdline{2311} to set the value of \mdline{2311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_ip{}[12]}}}\mdline{2311}:%mdk + +%mdk-data-line={2313} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2314} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}update~\{\\ +~~type:~INSERT\\ +~~entity~\{\\ +~~~~register\_entry~\{\\ +~~~~~~register\_id:~{\mdcolor{purple}369119267}\\ +~~~~~~index~\{\\ +~~~~~~~~index:~{\mdcolor{purple}12}\\ +~~~~~~\}\\ +~~~~~~data~\{\\ +~~~~~~~~header\_union~\{\\ +~~~~~~~~~~valid\_header\_name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~~~valid\_header~\{\\ +~~~~~~~~~~~~is\_valid:~true\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x04}{\mdcolor{maroon}"}\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{darkgreen}\#~...}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2337} +\subsubsection{\mdline{2337}8.5.5.\hspace*{0.5em}\mdline{2337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2337}, serializable \mdline{2337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2337} and \mdline{2337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}\label{sec-enum-serializable-enum-and-error}%mdk%mdk + +%mdk-data-line={2339} +\noindent\mdline{2339}P4\mdline{2339}\mdsub{16}\mdline{2339} supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or \mdline{2340}\textquotedblleft{}unsafe\textquotedblright{}\mdline{2340} enum) +\mdline{2341}[\mdcite{p4enums}{5}]\mdline{2341}. For \mdline{2341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2341} types with no underlying type\mdline{2341} \mdline{2341}\textemdash{}\mdline{2341} as well as \mdline{2341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2341} \mdline{2341}\textemdash{}\mdline{2341} +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in \mdline{2344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2344} to represent \mdline{2344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2344} and +\mdline{2345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2345} values.%mdk + +%mdk-data-line={2347} +\mdline{2347}Serializable \mdline{2347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2347} types have an underlying fixed-width unsigned integer +representation (\mdline{2348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2348}). All named enum members must be assigned an integer +value by the P4 programmer, but \mdline{2349}\emph{not all}\mdline{2349} valid numeric values for the +underlying type need to have a corresponding name. \mdline{2350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2350} includes the +mapping between entry name and entry value. When providing serializable enum +values through \mdline{2352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2352}, one must use the assigned integer value (\mdline{2352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum\_value}}}\mdline{2352} +bytestring field). P4Runtime does not provide a way for the client to use the +name\mdline{2354} \mdline{2354}\textemdash{}\mdline{2354} even when the enum member has one\mdline{2354} \mdline{2354}\textemdash{}\mdline{2354} instead of the value, as it makes +it easier for the server to respect the\mdline{2355}~\mdref{sec-read-write-symmetry}{read-write +symmetry}\mdline{2356} principle.%mdk + +%mdk-data-line={2358} +\subsubsection{\mdline{2358}8.5.6.\hspace*{0.5em}\mdline{2358}User-defined types}\label{sec-user-defined-types}%mdk%mdk + +%mdk-data-line={2360} +\noindent\mdline{2360}P4\mdline{2360}\mdsub{16}\mdline{2360} enables programmers to introduce new types\mdline{2360}~[\mdcite{p4newtypes}{11}]\mdline{2360}. While similar +to \mdline{2361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{2361}, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +\mdline{2364}\mdref{sec-psa-metadata-translation}{translation}\mdline{2364}. When introducing a new type, the +declaration can be annotated with \mdline{2365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2365} to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for\mdline{2367}~\mdref{sec-translation-of-port-numbers}{port numbers}\mdline{2367}, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. \mdline{2370}\textbf{The \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}} annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}})}\mdline{2372} and the type exposed to the control plane will also be a +fixed-width unsigned bitstring, with a potentially different bitwidth. It takes +two parameters: a \mdline{2374}\emph{URI}\mdline{2374} (Uniform Resource Identifier) which uniquely identifies +the translation being performed on entities of the new type to the P4Runtime +server and the \mdline{2376}\emph{bitwidth}\mdline{2376} of the bitstring type exposed to the control plane. It +is recommended that the URI includes at least the P4 architecture name and the +type name.%mdk + +%mdk-data-line={2380} +\mdline{2380}A \mdline{2380}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2380} annotation need not have any effect if it is used to +annotate anything in a P4 program other than a \mdline{2381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2381} declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect.%mdk + +%mdk-data-line={2385} +\mdline{2385}User-defined types are specified using the \mdline{2385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{2385} message, which has +the following fields:%mdk + +%mdk-data-line={2388} +\begin{itemize}%mdk + +%mdk-data-line={2388} +\item{} +%mdk-data-line={2388} +\mdline{2388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}representation}}}\mdline{2388}, a Protobuf \mdline{2388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2388} specifying how values of this type are +exchanged between client and server; it can be either:%mdk + +%mdk-data-line={2391} +\begin{itemize}%mdk + +%mdk-data-line={2391} +\item{} +%mdk-data-line={2391} +\mdline{2391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2391}, if and only if no \mdline{2391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2391} annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 \mdline{2393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2393} declaration is itself a +user-defined type, \mdline{2394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2394} is obtained by \mdline{2394}\textquotedblleft{}walking\textquotedblright{}\mdline{2394} the chain of +\mdline{2395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2395} declarations recursively until a built-in type (\mdline{2395}e.g.\mdline{2395} \mdline{2395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2395}) is +found.%mdk%mdk + +%mdk-data-line={2398} +\item{} +%mdk-data-line={2398} +\mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}translated\_type}}}\mdline{2398}, if and only if the P4 \mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2398} declaration was annotated +with \mdline{2399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2399}. It is of type \mdline{2399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeTranslation}}}\mdline{2399}, which +itself has two fields\mdline{2400} \mdline{2400}\textemdash{}\mdline{2400} \mdline{2400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uri}}}\mdline{2400} and \mdline{2400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_bitwidth}}}\mdline{2400} \mdline{2400}\textemdash{}\mdline{2400}, which map to the +two input parameters to the annotation.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2403} +\item{} +%mdk-data-line={2403} +\mdline{2403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{2403}, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2406} +\noindent\mdline{2406}For example, an architecture\mdline{2406} \mdline{2406}\textemdash{}\mdline{2406} in this case PSA\mdline{2406} \mdline{2406}\textemdash{}\mdline{2406} may introduce a new type +for port numbers:%mdk + +%mdk-data-line={2408} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2409} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2413} +\noindent\mdline{2413}In this case, the P4Info message would include the following \mdline{2413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2413} +message:%mdk + +%mdk-data-line={2416} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2417} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2430} +\noindent\mdline{2430}Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (\mdline{2431}e.g.\mdline{2431} through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2433} to enable users +to overwrite annotations included as part of the P4 architecture definition.%mdk + +%mdk-data-line={2436} +\subsubsection{\mdline{2436}8.5.7.\hspace*{0.5em}\mdline{2436}Trade-off for v1.0 Release}\label{sec-trade-off-for-v10-release}%mdk%mdk + +%mdk-data-line={2438} +\noindent\mdline{2438}For the v1.0 release of P4Runtime, it was decided not to replace occurrences of +\mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2439} with \mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2439} in the \mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{2439} message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-release +implementations of P4Runtime. Similarly it has been decided to keep using +\mdline{2442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2442} to provide action parameter values. However \mdline{2442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2442} is used whenever +appropriate for PSA externs and we encourage the use of \mdline{2443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2443} in +architecture-specific extensions.%mdk + +%mdk-data-line={2446} +\mdline{2446}In order to support\mdline{2446}~\mdref{sec-psa-metadata-translation}{translation}\mdline{2446} for action +parameters and match fields, we include a \mdline{2447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2447} field in +\mdline{2448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{2448} and \mdline{2448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Action.Param}}}\mdline{2448}.%mdk + +%mdk-data-line={2450} +\section{\mdline{2450}9.\hspace*{0.5em}\mdline{2450}P4 Entity Messages}\label{sec-p4-entity-msgs}%mdk%mdk + +%mdk-data-line={2452} +\noindent\mdline{2452}P4Runtime covers P4 entities that are either part of the P4\mdline{2452}\mdsub{16}\mdline{2452} language, or +defined as PSA externs. The sections below describe the messages for each +supported entity.%mdk + +%mdk-data-line={2456} +\subsection{\mdline{2456}9.1.\hspace*{0.5em}\mdline{2456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}\label{sec-table-entry}%mdk%mdk + +%mdk-data-line={2458} +\noindent\mdline{2458}The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action\mdline{2460}'\mdline{2460}s +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification.%mdk + +%mdk-data-line={2466} +\mdline{2466}P4Runtime supports inserting, modifying, deleting and reading table entries with +the \mdline{2467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2467} entity, which has the following fields:%mdk + +%mdk-data-line={2469} +\begin{itemize}%mdk + +%mdk-data-line={2469} +\item{} +%mdk-data-line={2469} +\mdline{2469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2469}, which identifies the table instance; the \mdline{2469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2469} is determined +by the P4Info message.%mdk%mdk + +%mdk-data-line={2472} +\item{} +%mdk-data-line={2472} +\mdline{2472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2472}, a repeated field of \mdline{2472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2472} messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration.%mdk%mdk + +%mdk-data-line={2476} +\item{} +%mdk-data-line={2476} +\mdline{2476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2476}, which indicates which of the table\mdline{2476}'\mdline{2476}s actions to execute in case of +match and with which argument values.%mdk%mdk + +%mdk-data-line={2479} +\item{} +%mdk-data-line={2479} +\mdline{2479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2479}, a 32-bit integer used to order entries when the table\mdline{2479}'\mdline{2479}s match key +includes a ternary or range match.%mdk%mdk + +%mdk-data-line={2482} +\item{} +%mdk-data-line={2482} +\mdline{2482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2482}, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry.%mdk%mdk + +%mdk-data-line={2487} +\item{} +%mdk-data-line={2487} +\mdline{2487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2487}, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See\mdline{2488}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2489} section for more information.%mdk%mdk + +%mdk-data-line={2491} +\item{} +%mdk-data-line={2491} +\mdline{2491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2491}, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See\mdline{2492}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2493} section for more information.%mdk%mdk + +%mdk-data-line={2495} +\item{} +%mdk-data-line={2495} +\mdline{2495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2495}, a boolean flag which indicates whether the table entry is +the default entry for the table. See\mdline{2496}~\mdref{sec-default-entry}{Default entry}\mdline{2496} +section for more information.%mdk%mdk + +%mdk-data-line={2499} +\item{} +%mdk-data-line={2499} +\mdline{2499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2499} and \mdline{2499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2499}, which are two fields used to +implement idle-timeout support for the table, if applicable. See +\mdline{2501}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{2501} section for more information.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2503} +\noindent\mdline{2503}The \mdline{2503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2503} field must be set to a non-zero value if the match key includes a +ternary match (\mdline{2504}i.e.\mdline{2504} in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has a \mdline{2505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2505} or \mdline{2505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2505} match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches.%mdk + +%mdk-data-line={2514} +\mdline{2514}The \mdline{2514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2514} and \mdline{2514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2514} fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for \mdline{2516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2516} and \mdline{2516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{2516} updates. When deleting +an entry, these key fields (along with \mdline{2517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2517}) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a \mdline{2519}\emph{keyless}\mdline{2519} +table (the table has an empty match key), the server must reject all attempts to +\mdline{2521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2521} a match entry and return an \mdline{2521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2521} error.%mdk + +%mdk-data-line={2523} +\mdline{2523}The number of match entries that a table \mdline{2523}\emph{should}\mdline{2523} support is indicated in P4Info +(\mdline{2524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2524} field of \mdline{2524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{2524} message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P4\mdline{2525}\mdsub{16}\mdline{2525} specification for the +\mdline{2526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2526} property\mdline{2526}~[\mdcite{p4tableproperties}{29}]\mdline{2526}. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +\mdline{2530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{2530} when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached.%mdk + +%mdk-data-line={2535} +\subsubsection{\mdline{2535}9.1.1.\hspace*{0.5em}\mdline{2535}Match Format}\label{sec-match-format}%mdk%mdk + +%mdk-data-line={2537} +\noindent\mdline{2537}The bytes fields in the \mdline{2537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2537} message follow the format described in +\mdline{2538}\mdref{sec-bytestrings}{Bytestrings}\mdline{2538}.%mdk + +%mdk-data-line={2540} +\mdline{2540}For \mdline{2540}\textquotedblleft{}don't care\textquotedblright{}\mdline{2540} matches, the P4Runtime client must omit the field\mdline{2540}'\mdline{2540}s entire +\mdline{2541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2541} entry when building the \mdline{2541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2541} repeated field of the \mdline{2541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2541} +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for \mdline{2543}\textquotedblleft{}don't care\textquotedblright{}\mdline{2543} matches, which is needed +to ensure\mdline{2544}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2544}. For PSA match types, +a \mdline{2545}\textquotedblleft{}don't care\textquotedblright{}\mdline{2545} match for a specific match key field is defined as follows:%mdk + +%mdk-data-line={2547} +\begin{itemize}%mdk + +%mdk-data-line={2547} +\item{} +%mdk-data-line={2547} +\mdline{2547}For a \mdline{2547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2547} match, it is logically equivalent to a mask of zeros.%mdk%mdk + +%mdk-data-line={2549} +\item{} +%mdk-data-line={2549} +\mdline{2549}For an \mdline{2549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2549} match, it is logically equivalent to a prefix\mdline{2549}\_\mdline{2549}len of zero.%mdk%mdk + +%mdk-data-line={2551} +\item{} +%mdk-data-line={2551} +\mdline{2551}For a \mdline{2551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2551} match, it is logically equivalent to a range which includes all +possible values for the field.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2554} +\noindent\mdline{2554}Note that there is no \mdline{2554}\textquotedblleft{}don't care\textquotedblright{}\mdline{2554} value for \mdline{2554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2554} matches and therefore exact +match fields can never be omitted from the \mdline{2555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2555} message.%mdk + +%mdk-data-line={2557} +\mdline{2557}The following example shows a P4Runtime message that treats a \mdline{2557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2557} field +as a \mdline{2558}\textquotedblleft{}don't care\textquotedblright{}\mdline{2558} match. The P4 program defines table \mdline{2558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{2558} with \mdline{2558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2558} +and \mdline{2559}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2559} fields in its match key:%mdk + +%mdk-data-line={2561} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2562} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~ternary;\\ +~~~~istd.ingress\_port:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2573} +\noindent\mdline{2573}In this P4Runtime request, the client omits the table\mdline{2573}'\mdline{2573}s \mdline{2573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2573} field +from the repeated \mdline{2574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2574} field to indicate a \mdline{2574}\textquotedblleft{}don't care\textquotedblright{}\mdline{2574} match. As shown +below, the \mdline{2575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2575} specifies only the \mdline{2575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2575} field given by \mdline{2575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id:~2}}}\mdline{2575}.%mdk + +%mdk-data-line={2577} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2578} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}33554439}~~{\mdcolor{darkgreen}\#~Table~t's~ID.}\\ +~~~~match~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~field\_id~1~is~not~present~to~use~the~don't~care~ternary~value.}\\ +~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~exact~\{\\ +~~~~~~~~value:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x20}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~action~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~Action~selection~goes~here.}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2596} +\noindent\mdline{2596}For every member of the \mdline{2596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2596} repeated \mdline{2596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2596} field, \mdline{2596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id}}}\mdline{2596} must be +a valid id for the table, as per the P4Info, and one of the fields in +\mdline{2598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{2598} must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an \mdline{2600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2600} error code.%mdk + +%mdk-data-line={2602} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2602} +\item\mdline{2602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2602} match + +%mdk-data-line={2603} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2603} +\item\mdline{2603}The binary string encoding of the value must conform to the +\mdline{2604}\mdref{sec-bytestrings}{Bytestrings}\mdline{2604} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2606} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2607} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.exact().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2610} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2610} +\item\mdline{2610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2610} match + +%mdk-data-line={2611} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2611} +\item\mdline{2611}The binary string encoding of the value (when present) must conform to the +\mdline{2612}\mdref{sec-bytestrings}{Bytestrings}\mdline{2612} requirements.%mdk + +%mdk-data-line={2613} +\item\mdline{2613}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2613} match must be omitted.%mdk + +%mdk-data-line={2614} +\item\mdline{2614}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2614} bits must be 0 in value.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2616} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2617} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.lpm().value()))\\ +\\ +pLen~=~match.lpm().prefix\_len()\\ +assert(pLen~\textgreater{}~0)\\ +\\ +trailing\_zeros~=~countTrailingZeros(match.lpm().value())\\ +assert(trailing\_zeros~\textgreater{}=~field\_bits~-~pLen)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2626} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2626} +\item\mdline{2626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2626} match + +%mdk-data-line={2627} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2627} +\item\mdline{2627}The binary string encoding of the value (when present) and mask (when +present) must conform to the\mdline{2628}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2628} requirements.%mdk + +%mdk-data-line={2629} +\item\mdline{2629}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2629} match must be omitted.%mdk + +%mdk-data-line={2630} +\item\mdline{2630}Masked bits must be 0 in value. This constraint taken together +with the\mdline{2631}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2631} requirements means that the +value\mdline{2632}'\mdline{2632}s binary string is never longer than the mask\mdline{2632}'\mdline{2632}s binary string. +When the value\mdline{2633}'\mdline{2633}s string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2637} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2638} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.ternary().value()))\\ +assert(BytestringValid(match.ternary().mask()))\\ +assert(match.ternary().value().size()~\textless{}=~match.ternary().mask().size());\\ +\\ +value~=~parseInteger(match.ternary().value())\\ +mask~=~parseInteger(match.ternary().mask())\\ +\\ +assert(mask~!=~0)\\ +\\ +assert(value~\&~mask~==~value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2650} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2650} +\item\mdline{2650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2650} match + +%mdk-data-line={2651} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2651} +\item\mdline{2651}The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the\mdline{2652}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2652} +requirements.%mdk + +%mdk-data-line={2654} +\item\mdline{2654}Low bound must be less than or equal to the high bound.%mdk + +%mdk-data-line={2655} +\item\mdline{2655}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2655} match must be omitted.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2657} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2658} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.range().low()))\\ +assert(BytestringValid(match.range().high()))\\ +\\ +low~=~parseInteger(match.range().low())\\ +high~=~parseInteger(match.range().high())\\ +\\ +assert(low~\textless{}=~high)\\ +\\ +assert(low~!=~min\_field\_value~\textbar{}\textbar{}~high~!=~max\_field\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2669} +\subsubsection{\mdline{2669}9.1.2.\hspace*{0.5em}\mdline{2669}Action Specification}\label{sec-action-specification}%mdk%mdk + +%mdk-data-line={2671} +\noindent\mdline{2671}The \mdline{2671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2671} \mdline{2671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2671} field must be set for every \mdline{2671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2671} update but may be +left unset for \mdline{2672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2672} updates, in which case the action specification for the +table entry will not be modified (if a \mdline{2673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2673} update has an unset action field +and does not modify any direct resource attached to the table then the \mdline{2674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2674} +update is a no-op). Based on the implementation property value of the P4 table, +the \mdline{2676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2676} in the \mdline{2676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{2676} message will either be:%mdk + +%mdk-data-line={2678} +\begin{itemize}%mdk + +%mdk-data-line={2678} +\item{} +%mdk-data-line={2678} +\mdline{2678}an \mdline{2678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{2678} specification for direct tables (with no P4 \mdline{2678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2678} +property)%mdk%mdk + +%mdk-data-line={2681} +\item{} +%mdk-data-line={2681} +\mdline{2681}an action profile member id for indirect tables for which the \mdline{2681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2681} +property is an action profile with no selector.%mdk%mdk + +%mdk-data-line={2684} +\item{} +%mdk-data-line={2684} +\mdline{2684}an action profile member id or group id for indirect tables for which the +\mdline{2685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2685} property is an action profile with selector.%mdk%mdk + +%mdk-data-line={2687} +\item{} +%mdk-data-line={2687} +\mdline{2687}an \mdline{2687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{2687} specification for indirect tables for +which the \mdline{2688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2688} property is an action profile with +selector. This usage is described in\mdline{2689}~\mdref{sec-oneshot}{One Shot Action Selector +Programming}\mdline{2690}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2692} +\noindent\mdline{2692}If the \mdline{2692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2692} does not match the table description in the P4Info (\mdline{2692}e.g.\mdline{2692} the +\mdline{2693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2693} is \mdline{2693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member\_id}}}\mdline{2693} for a direct table), the server must +return an \mdline{2694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2694} error code.%mdk + +%mdk-data-line={2696} +\mdline{2696}The \mdline{2696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{2696} Protobuf message has the following fields:%mdk + +%mdk-data-line={2698} +\begin{itemize}%mdk + +%mdk-data-line={2698} +\item{} +%mdk-data-line={2698} +\mdline{2698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{2698}, which identifies the action instance; the \mdline{2698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{2698} is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an \mdline{2700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2700} error +code. If the client uses a valid \mdline{2701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{2701} for the table but does not +respect the action scope specified in P4Info (\mdline{2702}e.g.\mdline{2702} tries to set a \mdline{2702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{2702} +action as the default action), the server must return a \mdline{2703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{2703} +error code.%mdk%mdk + +%mdk-data-line={2706} +\item{} +%mdk-data-line={2706} +\mdline{2706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{2706}: a repeated Protobuf field of action parameter values, each encoded +as a \mdline{2707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{2707} message. For each parameter, \mdline{2707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}param\_id}}}\mdline{2707} must be valid for the +action (as per the P4Info) and value must follow the format described in +\mdline{2709}\mdref{sec-bytestrings}{Bytestrings}\mdline{2709}. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an \mdline{2711}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2711} error code +if a parameter id is missing, if an extra parameter\mdline{2712} \mdline{2712}\textemdash{}\mdline{2712} id not found in the +P4Info\mdline{2713} \mdline{2713}\textemdash{}\mdline{2713} was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +\mdline{2715}\mdref{sec-bytestrings}{Bytestrings}\mdline{2715} format.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2717} +\noindent\mdline{2717}For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a \mdline{2719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{2719} error code.%mdk + +%mdk-data-line={2721} +\subsubsection{\mdline{2721}9.1.3.\hspace*{0.5em}\mdline{2721}Default Entry}\label{sec-default-entry}%mdk%mdk + +%mdk-data-line={2723} +\noindent\mdline{2723}According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer\mdline{2724} \mdline{2724}\textemdash{}\mdline{2724} or defaults to \mdline{2724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{2724} +(which is a no-op) otherwise\mdline{2725} \mdline{2725}\textemdash{}\mdline{2725} and assuming it is not declared as \mdline{2725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{2725}, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow \mdline{2727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2727} and \mdline{2727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{2727} updates on the default entry and the +P4Runtime server must return an \mdline{2728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2728} error code if the client +attempts one.%mdk + +%mdk-data-line={2731} +\mdline{2731}The default entry is identified by setting the \mdline{2731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2731} boolean field +to true. When this flag is set to true, the repeated \mdline{2732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2732} field must be empty +and the \mdline{2733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2733} field must be set to zero, otherwise the P4Runtime server +must return an \mdline{2734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2734} error code. When performing a \mdline{2734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2734} update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its \mdline{2738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2738} value as well as the configurations for its +\mdline{2739}\mdref{sec-direct-resources}{direct resources}\mdline{2739} will be reset to their defaults. If +the default entry is constant (as indicated by the P4 program and the P4Info +message), the server must return a \mdline{2741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{2741} error code if the client +attempts to modify it.%mdk + +%mdk-data-line={2744} +\mdline{2744}Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to\mdline{2745}~\mdref{sec-direct-resources}{direct resources}\mdline{2745}.%mdk + +%mdk-data-line={2747} +\mdline{2747}In this P4Runtime release, we have decided to restrict the default entry for +indirect tables\mdline{2748} \mdline{2748}\textemdash{}\mdline{2748} tables with an ActionProfile or ActionSelector +\mdline{2749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{2749} property\mdline{2749} \mdline{2749}\textemdash{}\mdline{2749} to a constant \mdline{2749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{2749} action entry, with the +hope that it would simplify the implementation of the P4Runtime service.%mdk + +%mdk-data-line={2752} +\subsubsection{\mdline{2752}9.1.4.\hspace*{0.5em}\mdline{2752}Constant Tables}\label{sec-constant-tables}%mdk%mdk + +%mdk-data-line={2754} +\noindent\mdline{2754}Constant tables are defined as tables whose match entries are immutable. They +are identified by the \mdline{2755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{2755} flag in P4Info.%mdk + +%mdk-data-line={2757} +\mdline{2757}The only write updates which are allowed for constant tables are \mdline{2757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2757} +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +\mdline{2761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{2761} error. Just like any table entry \mdline{2761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2761} request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a \mdline{2765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{2765} error.%mdk + +%mdk-data-line={2767} +\mdline{2767}The contents of const tables can be queried by the client through a +\mdline{2768}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2768}. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: \mdline{2769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2769}, \mdline{2769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2769}, \mdline{2769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2769}, +\mdline{2770}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2770}, and \mdline{2770}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2770} (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the \mdline{2773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2773} field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P4\mdline{2775}\mdsub{16}\mdline{2775} does not support assigning explicit priorities to static +entries. When a priority value is required (\mdline{2776}e.g.\mdline{2776} for tables including \mdline{2776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2776} +and / or \mdline{2777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2777} matches in the case of PSA), it is inferred based on the +order in which entries appear in the table declaration.%mdk + +%mdk-data-line={2780} +\subsubsection{\mdline{2780}9.1.5.\hspace*{0.5em}\mdline{2780}Wildcard Reads}\label{sec-table-wildcard-reads}%mdk%mdk + +%mdk-data-line={2782} +\noindent\mdline{2782}When performing a \mdline{2782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2782}, the P4Runtime client can select all entries +from one or all tables on the target and use several of the \mdline{2783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2783} fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as \mdline{2787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2787} and \mdline{2787}\textquotedblleft{}unset\textquotedblright{}\mdline{2787} for message fields such as \mdline{2787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2787}. The following +fields may be used to select and filter results:%mdk + +%mdk-data-line={2790} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2790} +\item\mdline{2790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2790}: If default (0), entries from all tables\mdline{2790} \mdline{2790}\textemdash{}\mdline{2790} including constant +tables\mdline{2791} \mdline{2791}\textemdash{}\mdline{2791} will be selected and no other filter can be used. Otherwise only +the specified table will be considered.%mdk + +%mdk-data-line={2793} +\item\mdline{2793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2793}: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned.%mdk + +%mdk-data-line={2797} +\item\mdline{2797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2797}: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an \mdline{2798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{2798} (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id.%mdk + +%mdk-data-line={2804} +\item\mdline{2804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2804}: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value.%mdk + +%mdk-data-line={2807} +\item\mdline{2807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2807}: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +\mdline{2809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2809} value.%mdk + +%mdk-data-line={2810} +\item\mdline{2810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2810}: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2814} +\noindent\mdline{2814}For example, in order to read all entries from all tables from device 3, the +client can use the following \mdline{2815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2815} message.%mdk + +%mdk-data-line={2817} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2818} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0}\\ +~~~~priority:~{\mdcolor{purple}0}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2828} +\noindent\mdline{2828}In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following \mdline{2829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2829} +message:%mdk + +%mdk-data-line={2832} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2833} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~priority:~{\mdcolor{purple}11}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2843} +\noindent\mdline{2843}The canonical representation of \mdline{2843}\textquotedblleft{}don't care\textquotedblright{}\mdline{2843} matches, combined with the ability +to do a wildcard read on all table entries by leaving the \mdline{2844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2844} field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single \mdline{2846}\textquotedblleft{}don't care\textquotedblright{}\mdline{2846} entry or to do a wildcard +read. If a table has no fields with match kind \mdline{2847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2847}, it is possible via +P4Runtime to add an entry that is \mdline{2848}\textquotedblleft{}don't care\textquotedblright{}\mdline{2848} for all fields (\mdline{2848}i.e.\mdline{2848} has an empty +\mdline{2849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2849} field) but is not the default entry (\mdline{2849}i.e.\mdline{2849} \mdline{2849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2849} is +false). When reading this entry from the table, there is no way to read \mdline{2850}\emph{only}\mdline{2850} +that entry from the table, because it would require providing an unset \mdline{2851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2851} +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single \mdline{2854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2854} match:%mdk + +%mdk-data-line={2856} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2857} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;~fwd;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2867} +\noindent\mdline{2867}The following \mdline{2867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{2867} message can be used to add 2 entries:%mdk + +%mdk-data-line={2868} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2869} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{~{\mdcolor{darkgreen}\#~don't~care~entry}\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +~~table~entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~match~\{\\ +~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~lpm~\{\\ +~~~~~~~~value:~{\mdcolor{purple}0x0a000000}\\ +~~~~~~~~prefix\_len:~{\mdcolor{purple}8}\\ +~~~~~~\}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2888} +\noindent\mdline{2888}The first entry is a \mdline{2888}\textquotedblleft{}don't care\textquotedblright{}\mdline{2888} entry, while the second one matches all +\mdline{2889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}10.0.0.0/8}}}\mdline{2889} addresses. The second entry has higher priority than the first one.%mdk + +%mdk-data-line={2891} +\mdline{2891}The following \mdline{2891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2891} message will return \mdline{2891}\emph{all}\mdline{2891} entries in the table, not +just the \mdline{2892}\textquotedblleft{}don't care\textquotedblright{}\mdline{2892} entry.%mdk + +%mdk-data-line={2893} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2894} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2902} +\noindent\mdline{2902}This issue also exists for tables with \mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2902} and / or \mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2902} +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the \mdline{2905}\textquotedblleft{}don't care\textquotedblright{}\mdline{2905} entry will be returned to the +client. If the client uses distinct priority values for all entries\mdline{2906} \mdline{2906}\textemdash{}\mdline{2906} which is +strongly recommended to achieve\mdline{2907}~\mdref{sec-table-entry}{deterministic behavior}\mdline{2907} \mdline{2907}\textemdash{}\mdline{2907}, +then there is no ambiguity because the wildcard read will actually return a +single entry (the \mdline{2909}\textquotedblleft{}don't care\textquotedblright{}\mdline{2909} entry) as long as the \mdline{2909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2909} field is set to +the correct value.%mdk + +%mdk-data-line={2912} +\subsubsection{\mdline{2912}9.1.6.\hspace*{0.5em}\mdline{2912}Direct Resources}\label{sec-direct-resources}%mdk%mdk + +%mdk-data-line={2914} +\noindent\mdline{2914}In addition to the \mdline{2914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{2914} and \mdline{2914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{2914} entities, +P4Runtime support reading and writing direct resources as part of the +\mdline{2916}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2916} message. This is convenient for two reasons:%mdk + +%mdk-data-line={2918} +\begin{itemize}%mdk + +%mdk-data-line={2918} +\item{} +%mdk-data-line={2918} +\mdline{2918}A table entry and its direct resources can be read with a single entity when +doing a \mdline{2919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{2919} RPC call%mdk%mdk + +%mdk-data-line={2921} +\item{} +%mdk-data-line={2921} +\mdline{2921}The initial configuration for an entry\mdline{2921}'\mdline{2921}s direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can \mdline{2926}\textquotedblleft{}hit\textquotedblright{}\mdline{2926} the table entry without +executing the appropriate meter entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2929} +\noindent\mdline{2929}Once the table entry has been inserted, the P4Runtime client is free to use the +\mdline{2930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{2930} and \mdline{2930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{2930} messages for read and write +operations on \mdline{2931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{2931} and \mdline{2931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{2931} instances. For example, it is +usually more convenient as well as more efficient to use \mdline{2932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{2932} to +query a counter entry value rather than use \mdline{2933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2933}, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry.%mdk + +%mdk-data-line={2937} +\mdline{2937}The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does \mdline{2938}\emph{not}\mdline{2938} need to be \mdline{2938}\textquotedblleft{}executed\textquotedblright{}\mdline{2938} in +every action bound to the table. It is an error to provide a direct resource +configuration in a \mdline{2940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2940} message when programming an action that does not +execute the direct resource, and the server must return an \mdline{2941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2941} +error code.%mdk + +%mdk-data-line={2944} +\mdline{2944}We leverage Protobuf\mdline{2944}'\mdline{2944}s ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the \mdline{2946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2946} message. The list below describes how +the server must handle the \mdline{2947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2947} and \mdline{2947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2947} fields for read and +write requests, based on whether the fields are set or not. We do not cover +error cases in the list, \mdline{2949}i.e.\mdline{2949} we assume that we are dealing with a table which +is assigned a direct counter / a direct meter, and that the action being used +for the table entry \mdline{2951}\textquotedblleft{}executes\textquotedblright{}\mdline{2951} the direct resource appropriately.%mdk + +%mdk-data-line={2953} +\begin{itemize}%mdk + +%mdk-data-line={2953} +\item{} +%mdk-data-line={2953} +\mdline{2953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2953} field%mdk + +%mdk-data-line={2954} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2954} +\item\mdline{2954}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{2954} + +%mdk-data-line={2955} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2955} +\item\mdline{2955}if \mdline{2955}\textbf{unset}\mdline{2955}: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets).%mdk + +%mdk-data-line={2957} +\item\mdline{2957}if \mdline{2957}\textbf{set}\mdline{2957}: The initial configuration for the meter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2959} +\item\mdline{2959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{2959} + +%mdk-data-line={2960} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2960} +\item\mdline{2960}if \mdline{2960}\textbf{unset}\mdline{2960}: The meter entry\mdline{2960}'\mdline{2960}s configuration is reset to the default +(meter returns GREEN for all packets).%mdk + +%mdk-data-line={2962} +\item\mdline{2962}if \mdline{2962}\textbf{set}\mdline{2962}: The value provided by the client is used to re-configure +the meter entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2964} +\item\mdline{2964}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2964} + +%mdk-data-line={2965} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2965} +\item\mdline{2965}if \mdline{2965}\textbf{unset}\mdline{2965}: The response does not include the meter entry\mdline{2965}'\mdline{2965}s +configuration (\mdline{2966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2966} is unset in the response).%mdk + +%mdk-data-line={2967} +\item\mdline{2967}if \mdline{2967}\textbf{set}\mdline{2967}: If the meter entry\mdline{2967}'\mdline{2967}s configuration is the default +configuration, \mdline{2968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2968} is unset in the response. Otherwise, the +response includes the meter entry\mdline{2969}'\mdline{2969}s configuration that was written by +the client earlier. This respects the \mdline{2970}\textquotedblleft{}read-write symmetry\textquotedblright{}\mdline{2970} principle.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2972} +\item{} +%mdk-data-line={2972} +\mdline{2972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2972} field%mdk + +%mdk-data-line={2973} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2973} +\item\mdline{2973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{2973} + +%mdk-data-line={2974} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2974} +\item\mdline{2974}if \mdline{2974}\textbf{unset}\mdline{2974}: The initial value for the counter entry is the default +(0).%mdk + +%mdk-data-line={2976} +\item\mdline{2976}if \mdline{2976}\textbf{set}\mdline{2976}: The initial value for the counter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2978} +\item\mdline{2978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{2978} + +%mdk-data-line={2979} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2979} +\item\mdline{2979}if \mdline{2979}\textbf{unset}\mdline{2979}: The counter entry\mdline{2979}'\mdline{2979}s value is not changed.%mdk + +%mdk-data-line={2980} +\item\mdline{2980}if \mdline{2980}\textbf{set}\mdline{2980}: The value provided by the client is written to the counter +entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2982} +\item\mdline{2982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{2982} + +%mdk-data-line={2983} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2983} +\item\mdline{2983}if \mdline{2983}\textbf{unset}\mdline{2983}: The response does not include the counter entry\mdline{2983}'\mdline{2983}s value +(\mdline{2984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2984} is unset in the response).%mdk + +%mdk-data-line={2985} +\item\mdline{2985}if \mdline{2985}\textbf{set}\mdline{2985}: The response includes the counter entry\mdline{2985}'\mdline{2985}s value read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2988} +\noindent\mdline{2988}In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +\mdline{2990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2990} field unset when inserting \mdline{2990}\textbf{or modifying}\mdline{2990} a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the \mdline{2992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2992} message +(\mdline{2993}i.e.\mdline{2993} the \mdline{2993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2993} field must be set to match the existing configuration).%mdk + +%mdk-data-line={2995} +\subsubsection{\mdline{2995}9.1.7.\hspace*{0.5em}\mdline{2995}Idle-timeout}\label{sec-idle-timeout}%mdk%mdk + +%mdk-data-line={2997} +\noindent\mdline{2997}P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not \mdline{2999}\textquotedblleft{}hit\textquotedblright{}\mdline{2999} (\mdline{2999}i.e.\mdline{2999} not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification\mdline{3001} \mdline{3001}\textemdash{}\mdline{3001} using the +\mdline{3002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3002} message\mdline{3002} \mdline{3002}\textemdash{}\mdline{3002} to the master client, which can then take +action, such as remove the idle table entry.%mdk + +%mdk-data-line={3005} +\mdline{3005}Two fields of the \mdline{3005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3005} Protobuf message are used to implement idle +timeout:%mdk + +%mdk-data-line={3008} +\begin{itemize}%mdk + +%mdk-data-line={3008} +\item{} +%mdk-data-line={3008} +\mdline{3008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3008}: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, \mdline{3009}i.e.\mdline{3009} no +\mdline{3010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3010} message will ever be generated for this entry. When +a client reads a \mdline{3011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3011}, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry.%mdk%mdk + +%mdk-data-line={3015} +\item{} +%mdk-data-line={3015} +\mdline{3015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3015}: a Protobuf message with a single field (\mdline{3015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{3015}) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The \mdline{3017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3017} field must be unset for a +\mdline{3018}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3018} write. When reading a table entry, \mdline{3018}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3018} must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3023} +\noindent\mdline{3023}These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an \mdline{3025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3025} error code if at least one of these +conditions is met:%mdk + +%mdk-data-line={3028} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3028} +\item\mdline{3028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3028} is set to a non-zero value, or%mdk + +%mdk-data-line={3029} +\item\mdline{3029}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3029} is set%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3031} +\noindent\mdline{3031}The target should do its best to approximate the \mdline{3031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3031} value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the \mdline{3034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3034} write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for \mdline{3036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3036}.%mdk + +%mdk-data-line={3038} +\mdline{3038}P4Runtime does not support idle timeout for default entries. When the +\mdline{3039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3039} flag is set in a \mdline{3039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3039} message, \mdline{3039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3039} +must be set to 0 (default) and \mdline{3040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3040} must be unset. If the +server receives a \mdline{3041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3041} message which violates this, it must return an +\mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3042} error.%mdk + +%mdk-data-line={3044} +\mdline{3044}For more information about idle timeout, in particular regarding +\mdline{3045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3045}, please refer to the\mdline{3045}~\mdref{sec-table-idle-timeout-notification}{Table idle timeout +notifications}\mdline{3046} section.%mdk + +%mdk-data-line={3048} +\subsection{\mdline{3048}9.2.\hspace*{0.5em}\mdline{3048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3048} \mdline{3048}\&\mdline{3048} \mdline{3048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}\label{sec-action-profile-member-and-group}%mdk%mdk + +%mdk-data-line={3050} +\noindent\mdline{3050}P4Runtime defines an API for programming a PSA ActionProfile extern using +\mdline{3051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3051} messages. A PSA ActionSelector extern can be programmed +using both \mdline{3052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3052} and \mdline{3052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3052} messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table \mdline{3056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3056} for L3 routing, implemented with an action +selector \mdline{3057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3057}.%mdk + +%mdk-data-line={3059} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3060} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector(HashAlgorithm.crc32,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}size~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w1024,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}output\_width~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w10)~as;\\ +\\ +{\bfseries{\mdcolor{navy}action}}~set\_nhop(PortId\_t~p,~EthAddr~smac,~EthAddr~dmac)~\{\\ +~~istd.egress\_port~=~p;\\ +~~hdr.ethernet.smac~=~smac;\\ +~~hdr.ethernet.dmac~=~dmac;\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;~~{\mdcolor{darkgreen}//~LPM~on~destination~IP~address}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~set\_nhop;\\ +~~\}\\ +~~implementation~=~as;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3081} +\noindent\mdline{3081}When programming table \mdline{3081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3081} in the example above, a P4Runtime client should +specify the \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3082} in the \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3082} to be a reference to either an +action profile member or group. The reference is a \mdline{3083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3083} identifier that +uniquely identifies a member or group programmed in the action selector \mdline{3084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3084}.%mdk + +%mdk-data-line={3086} +\mdline{3086}If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata.%mdk + +%mdk-data-line={3091} +\mdline{3091}If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata.%mdk + +%mdk-data-line={3102} +\subsubsection{\mdline{3102}9.2.1.\hspace*{0.5em}\mdline{3102}Action Profile Member Programming}\label{sec-action-profile-member-programming}%mdk%mdk + +%mdk-data-line={3104} +\noindent\mdline{3104}Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a \mdline{3105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3105} identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the \mdline{3107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3107} +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the \mdline{3109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3109} attributes of the +tables \mdline{3110}\emph{must have an identical list of P4 actions}\mdline{3110}. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector.%mdk + +%mdk-data-line={3114} +\mdline{3114}An \mdline{3114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3114} entity update message has the following fields:%mdk + +%mdk-data-line={3116} +\begin{itemize}%mdk + +%mdk-data-line={3116} +\item{} +%mdk-data-line={3116} +\mdline{3116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3116} is the \mdline{3116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3116} identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3119} +\item{} +%mdk-data-line={3119} +\mdline{3119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3119} is the \mdline{3119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3119} identifier of the action profile member entry +being updated.%mdk%mdk + +%mdk-data-line={3122} +\item{} +%mdk-data-line={3122} +\mdline{3122}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3122} is the specification of the P4 action instance bound to the action +profile member entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3125} +\noindent\mdline{3125}An action profile member may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3128} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3128} +\item\mdline{3128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3128}: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an \mdline{3130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3130} error +code. The action specification must be provided, or the server must return +\mdline{3132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3132}. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return \mdline{3134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3134}.%mdk + +%mdk-data-line={3135} +\item\mdline{3135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3135}: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return \mdline{3136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3136}, +and the action specification must be provided, or the server must return +\mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3138}.%mdk + +%mdk-data-line={3139} +\item\mdline{3139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3139}: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a \mdline{3140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3140} error code. The member +must not be part of an action profile group, or the server must return +\mdline{3142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3142}. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return \mdline{3145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3145}. \mdline{3145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3145} is the only field which is +considered when performing a \mdline{3146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3146} and every other field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3148} +\subsubsection{\mdline{3148}9.2.2.\hspace*{0.5em}\mdline{3148}Action Profile Group Programming}\label{sec-action-profile-group-programming}%mdk%mdk + +%mdk-data-line={3150} +\noindent\mdline{3150}Action profile groups are entries in an ActionSelector and are referenced by a +\mdline{3151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3151} identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type.%mdk + +%mdk-data-line={3155} +\mdline{3155}An \mdline{3155}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3155} entity update message has the following fields:%mdk + +%mdk-data-line={3157} +\begin{itemize}%mdk + +%mdk-data-line={3157} +\item{} +%mdk-data-line={3157} +\mdline{3157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3157} is the \mdline{3157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3157} identifier of the PSA ActionSelector +extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3160} +\item{} +%mdk-data-line={3160} +\mdline{3160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3160} is the \mdline{3160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3160} identifier of the action profile group entry being +updated.%mdk%mdk + +%mdk-data-line={3163} +\item{} +%mdk-data-line={3163} +\mdline{3163}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3163} is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields:%mdk + +%mdk-data-line={3166} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3166} +\item\mdline{3166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3166} for looking up the member table in the selector.%mdk + +%mdk-data-line={3167} +\item\mdline{3167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3167} specifying the probability of the member\mdline{3167}'\mdline{3167}s selection at +runtime. 0 is not a valid \mdline{3168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3168} value and the server must return +\mdline{3169}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3169} if the client attempts to use it.%mdk + +%mdk-data-line={3170} +\item\mdline{3170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3170} is the controller-defined 32-bit port number that the member\mdline{3170}'\mdline{3170}s +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3174} +\item{} +%mdk-data-line={3174} +\mdline{3174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3174} is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +\mdline{3176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3176} update. See the subsection below for the\mdline{3176}~\mdref{sec-max-size-rules}{rules on setting +\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\mdline{3177}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3179} +\noindent\mdline{3179}An action profile group may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3182} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3182} +\item\mdline{3182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3182}: Add a new group entry bound to a set of existing action profile +members. \mdline{3183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}The~group\_id}}}\mdline{3183} must be different from ids of already programmed +groups for that selector, or the server must return an \mdline{3184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3184} error +code. All members specified in the group must exist in the selector, or the +server must return \mdline{3186}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3186}. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target.%mdk + +%mdk-data-line={3188} +\item\mdline{3188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3188}: Modify the member set specification of an existing group entry. An +entry with the \mdline{3189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3189} must exist, or the server must return +\mdline{3190}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3190}. All members specified in the group entry must exist in the +selector, or the server must return \mdline{3191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3191}. The value of \mdline{3191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3191} must +be identical to the value used when inserting the group, otherwise an +\mdline{3193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3193} error is returned.%mdk + +%mdk-data-line={3194} +\item\mdline{3194}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3194}: Delete the group entry and deallocate the \mdline{3194}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3194}. The group must +not be referenced in the table action of any table entry, or the server must +return a \mdline{3196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3196} error code. If the \mdline{3196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3196} is invalid, the +server must return \mdline{3197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3197}. \mdline{3197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3197} is the only field which is +considered when performing a \mdline{3198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3198} and every other field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3200} +\noindent\mdline{3200}When setting the group membership with \mdline{3200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3200} or \mdline{3200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3200}, the \mdline{3200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3200} +repeated field must not include duplicates, \mdline{3201}i.e.\mdline{3201} members with the same +\mdline{3202}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3202}. The \mdline{3202}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3202} field is used instead to logically \mdline{3202}\textquotedblleft{}repeat\textquotedblright{}\mdline{3202} the member +inside the group.%mdk + +%mdk-data-line={3205} +\mdline{3205}It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation \mdline{3206}\textquotedblleft{}stores\textquotedblright{}\mdline{3206} the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made.%mdk + +%mdk-data-line={3210} +\paragraph{\mdline{3210}9.2.2.1.\hspace*{0.5em}\mdline{3210}Rules on Setting \mdline{3210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\label{sec-max-size-rules}%mdk%mdk + +%mdk-data-line={3212} +\noindent\mdline{3212}The valid values for \mdline{3212}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3212} depend on the static \mdline{3212}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3212} included +in the P4Info message:%mdk + +%mdk-data-line={3215} +\begin{itemize}%mdk + +%mdk-data-line={3215} +\item{} +%mdk-data-line={3215} +\mdline{3215}If \mdline{3215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3215} is greater than 0, then \mdline{3215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3215} must be greater than 0, +and less than or equal to \mdline{3216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3216}. We assume that the target can +support selector groups for which the sum of all member weights is up to +\mdline{3218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3218}, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If \mdline{3219}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3219} is greater than \mdline{3219}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3219}, the server +must return \mdline{3220}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3220}.%mdk%mdk + +%mdk-data-line={3222} +\item{} +%mdk-data-line={3222} +\mdline{3222}Otherwise (\mdline{3222}i.e.\mdline{3222} if \mdline{3222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3222} is 0), the P4Runtime client can set +\mdline{3223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3223} to any value greater than or equal to 0.%mdk + +%mdk-data-line={3225} +\begin{itemize}%mdk + +%mdk-data-line={3225} +\item{} +%mdk-data-line={3225} +\mdline{3225}A \mdline{3225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3225} of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (\mdline{3228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3228} or \mdline{3228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3228}), the target must return a +\mdline{3229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3229} error.%mdk%mdk + +%mdk-data-line={3231} +\item{} +%mdk-data-line={3231} +\mdline{3231}If \mdline{3231}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3231} is greater than 0 and the value is not supported by the +target, the server must return a \mdline{3232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3232} error at +group-creation time.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3235} +\subsubsection{\mdline{3235}9.2.3.\hspace*{0.5em}\mdline{3235}One Shot Action Selector Programming}\label{sec-oneshot}%mdk%mdk + +%mdk-data-line={3237} +\noindent\mdline{3237}P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids.%mdk + +%mdk-data-line={3243} +\mdline{3243}One shots are programmed by choosing the \mdline{3243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3243} message as the +\mdline{3244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3244}. The \mdline{3244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3244} message consists of a set of +\mdline{3245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3245} messages, which in turn have the following fields:%mdk + +%mdk-data-line={3247} +\begin{itemize}%mdk + +%mdk-data-line={3247} +\item{} +%mdk-data-line={3247} +\mdline{3247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3247} is one of the actions specified by the table that is being +programmed.%mdk%mdk + +%mdk-data-line={3250} +\item{} +%mdk-data-line={3250} +\mdline{3250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3250} specifying the probability of the action\mdline{3250}'\mdline{3250}s selection at runtime. 0 is +not a valid \mdline{3251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3251} value and the server must return \mdline{3251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3251} if +the client attempts to use it. The sum of all weights across all +\mdline{3253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3253} messages for that \mdline{3253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3253} message must +not exceed the \mdline{3254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3254} specificed in the P4Info (if greater than 0), +or the server must return \mdline{3255}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3255}.%mdk%mdk + +%mdk-data-line={3257} +\item{} +%mdk-data-line={3257} +\mdline{3257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3257} is the controller-defined 32-bit port number that the action\mdline{3257}'\mdline{3257}s +liveness depends on. At runtime, the action must be excluded from selection if +the watch port is down.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3261} +\noindent\mdline{3261}Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics.%mdk + +%mdk-data-line={3266} +\mdline{3266}To preserve read-write symmetry, an implementation must answer \mdline{3266}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3266}s +with the original one shot messages. It may not return a desugared version of +the one shot message.%mdk + +%mdk-data-line={3270} +\mdline{3270}For example, consider the action selector table defined +\mdline{3271}\mdref{sec-action-profile-member-and-group}{here}\mdline{3271}. This table could be programmed +with the following one shot update:%mdk + +%mdk-data-line={3274} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3275} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{\\ +~~~~action\_profile\_action\_set~\{\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}1}\\ +~~~~~~~~watch:~{\mdcolor{purple}1}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}2}\\ +~~~~~~~~watch:~{\mdcolor{purple}2}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}3}\\ +~~~~~~~~watch:~{\mdcolor{purple}3}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3300} +\noindent\mdline{3300}Which would be equivalent to the following updates, where \mdline{3300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GROUP\_ID}}}\mdline{3300}, +\mdline{3301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_1}}}\mdline{3301}, \mdline{3301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_2}}}\mdline{3301}, and \mdline{3301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_3}}}\mdline{3301} are unused ids:%mdk + +%mdk-data-line={3303} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3304} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_1\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_2\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_3\\ +~~action~\{~~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +\}\\ +action\_profile\_group~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~group\_id:~GROUP\_ID\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_1\\ +~~~~weight:~{\mdcolor{purple}1}\\ +~~~~watch:~{\mdcolor{purple}1}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_2\\ +~~~~weight:~{\mdcolor{purple}2}\\ +~~~~watch:~{\mdcolor{purple}2}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_3\\ +~~~~weight:~{\mdcolor{purple}3}\\ +~~~~watch:~{\mdcolor{purple}3}\\ +~~\}\\ +\}\\ +table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{~action\_profile\_group\_id:~GROUP\_ID~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3345} +\noindent\mdline{3345}Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure\mdline{3346}~\mdref{sec-batching-and-ordering-of-updates}{correct ordering between the dependent +updates}\mdline{3347}. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct \mdline{3349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3349} batches are required.%mdk + +%mdk-data-line={3351} +\mdline{3351}It is possible to include several \mdline{3351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3351} messages with the same +exact \mdline{3352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3352} specification in one \mdline{3352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3352} message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the \mdline{3354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3354} field. Note that to preserve read-write symmetry, the server +must not coalesce multiple \mdline{3355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3355} messages with the same \mdline{3355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3355} +specification into one.%mdk + +%mdk-data-line={3358} +\mdline{3358}All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with \mdline{3359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3359} and +\mdline{3360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3360} messages. Programming some entries with one shots, and +other entries with \mdline{3361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3361} and \mdline{3361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3361} messages is +not allowed, and the server must return the error code \mdline{3362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3362} in +that case.%mdk + +%mdk-data-line={3365} +\mdline{3365}A P4Runtime server \mdline{3365}\emph{must}\mdline{3365} support the one shot style of programming tables with +an action selector implementation. Support for the \mdline{3366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3366} and +\mdline{3367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3367} style is \mdline{3367}\emph{optional}\mdline{3367}. If \mdline{3367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3367} and +\mdline{3368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3368} are not supported by a server, it must return an +\mdline{3369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3369} error for every \mdline{3369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3369} or \mdline{3369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3369} +message that it receives.%mdk + +%mdk-data-line={3372} +\subsubsection{\mdline{3372}9.2.4.\hspace*{0.5em}\mdline{3372}Constraints on action selector programming}\label{sec-constraints-on-action-selector-programming}%mdk%mdk + +%mdk-data-line={3374} +\noindent\mdline{3374}The PSA specification states that the following features are \mdline{3374}\emph{optional}\mdline{3374} in +action selector implementations\mdline{3375}~[\mdcite{psaactionselector}{21}]\mdline{3375}:%mdk + +%mdk-data-line={3377} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3377} +\item\mdline{3377}Support for non-empty groups where in the same group, different members are +bound to different actions.%mdk + +%mdk-data-line={3379} +\item\mdline{3379}Predictable data plane behavior when a matched table entry points to an empty +group.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={3382} +\noindent\mdline{3382}For 1., if a client tries to \mdline{3382}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3382} or \mdline{3382}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3382} a group with members bound to +different actions, the server should return \mdline{3383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3383} if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return \mdline{3389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3389} (modifying the action parameter values must be +supported, however).%mdk + +%mdk-data-line={3392} +\mdline{3392}PSA 1.1 introduces the \mdline{3392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3392} table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. \mdline{3396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3396} is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of \mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3399} at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +\mdline{3401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3401}. Even when \mdline{3401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3401} is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of \mdline{3405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3405} mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming.%mdk + +%mdk-data-line={3410} +\mdline{3410}The PSA specification includes a discussion on how to implement +\mdline{3411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3411} in software in the P4Runtime server +\mdline{3412}[\mdcite{psaemptygroupactionappendix}{24}]\mdline{3412}.%mdk + +%mdk-data-line={3414} +\subsection{\mdline{3414}9.3.\hspace*{0.5em}\mdline{3414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3414} \mdline{3414}\&\mdline{3414} \mdline{3414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-counterentry-directcounterentry}%mdk%mdk + +%mdk-data-line={3416} +\noindent\mdline{3416}PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The \mdline{3418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3418} +P4Runtime message can be used for all three types of PSA counters\mdline{3419} \mdline{3419}\textemdash{}\mdline{3419} \mdline{3419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{3419}, +\mdline{3420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{3420} and \mdline{3420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3420} \mdline{3420}\textemdash{}\mdline{3420} and consists of the following fields:%mdk + +%mdk-data-line={3422} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3422} +\item\mdline{3422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3422} is an \mdline{3422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3422}, corresponding to the number of octets.%mdk + +%mdk-data-line={3423} +\item\mdline{3423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3423} is an \mdline{3423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3423}, corresponding to the number of packets.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3425} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3426} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterData~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~byte\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}int64}}~packet\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3432} +\noindent\mdline{3432}P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of \mdline{3433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3433} and \mdline{3433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3433} fields, which +is equivalent to specifying the counter type \mdline{3434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3434}. Counters may +be defined as direct or indirect (indexed) instances.%mdk + +%mdk-data-line={3437} +\subsubsection{\mdline{3437}9.3.1.\hspace*{0.5em}\mdline{3437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-directcounterentry}%mdk%mdk + +%mdk-data-line={3439} +\noindent\mdline{3439}A direct counter is a direct resource associated with a \mdline{3439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3439} (see +\mdline{3440}\mdref{sec-direct-resources}{Direct Resources}\mdline{3440}). The \mdline{3440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3440} field of the +\mdline{3441}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3441} message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +\mdline{3444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3444} message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed.%mdk + +%mdk-data-line={3447} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3448} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectCounterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3454} +\noindent\mdline{3454}A \mdline{3454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3454} may only include an \mdline{3454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3454} message of type \mdline{3454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3454} with a +\mdline{3455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3455}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3457} +\begin{itemize}%mdk + +%mdk-data-line={3457} +\item{} +%mdk-data-line={3457} +\mdline{3457}the \mdline{3457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3457} field must match \mdline{3457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry.match}}}\mdline{3457} of the table entry +to which this direct counter entry is associated. If a matching \mdline{3458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3458} +is not found, the server returns the error code \mdline{3459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3459}.%mdk%mdk + +%mdk-data-line={3461} +\item{} +%mdk-data-line={3461} +\mdline{3461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3461} is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3465} +\noindent\mdline{3465}Specifying \mdline{3465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3465} in an \mdline{3465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3465} message of type \mdline{3465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3465} or +\mdline{3466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3466} is not allowed, and the server must return the error code +\mdline{3467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3467} in that case.%mdk + +%mdk-data-line={3469} +\mdline{3469}A client may use \mdline{3469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3469} in two ways to read the contents of a +\mdline{3470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3470}:%mdk + +%mdk-data-line={3472} +\begin{itemize}%mdk + +%mdk-data-line={3472} +\item{} +%mdk-data-line={3472} +\mdline{3472}As a direct resource associated with a table entry, request the server to +return the counter value in the \mdline{3473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3473} field of the \mdline{3473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3473} message +(see\mdline{3474}~\mdref{sec-direct-resources}{Direct resources}\mdline{3474}).%mdk%mdk + +%mdk-data-line={3476} +\item{} +%mdk-data-line={3476} +\mdline{3476}Explicitly request the counter value by including the \mdline{3476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3476} in +the \mdline{3477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3477}. The \mdline{3477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3477} field must match the \mdline{3477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3477} +whose counter is being read. If no such entry is found, the server returns the +error code \mdline{3479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3479}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3481} +\subsubsection{\mdline{3481}9.3.2.\hspace*{0.5em}\mdline{3481}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}\label{sec-counterentry}%mdk%mdk + +%mdk-data-line={3483} +\noindent\mdline{3483}An indirect or indexed counter is not associated with a specific \mdline{3483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3483} +and may be updated independently of any action. It may be read or written using +the P4Runtime \mdline{3485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3485} message whose fields are defined as follows:%mdk + +%mdk-data-line={3487} +\begin{itemize}%mdk + +%mdk-data-line={3487} +\item{} +%mdk-data-line={3487} +\mdline{3487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3487} is a \mdline{3487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3487}, the unique identifier for the counter.%mdk%mdk + +%mdk-data-line={3489} +\item{} +%mdk-data-line={3489} +\mdline{3489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3489} is a Protobuf message that encapsulates an \mdline{3489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3489}, used to index into +the counter array.%mdk%mdk + +%mdk-data-line={3492} +\item{} +%mdk-data-line={3492} +\mdline{3492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3492} is a Protobuf message of type \mdline{3492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3492}, which represents the +counter value.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3495} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3496} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~counter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3503} +\noindent\mdline{3503}The \mdline{3503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3503} can only be used in a \mdline{3503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3503} with the \mdline{3503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3503} update +type. The P4Runtime server must return an \mdline{3504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3504} error code for +update types \mdline{3505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3505} and \mdline{3505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3505}. By default all the counter entries in the +array have default value 0.%mdk + +%mdk-data-line={3508} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3508} +\item\mdline{3508}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3508}: Server returns the error code \mdline{3508}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3508}.%mdk + +%mdk-data-line={3509} +\item\mdline{3509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3509}: Modify an indirect counter instance whose unique id is \mdline{3509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3509} +and array index is specified by \mdline{3510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3510}. The counter value is set to the value +specified by the client in the \mdline{3511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3511} field. Note that the counter value is +not modified if this Protobuf field is not set. If \mdline{3512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3512} is omitted all +counter values in the array will be set to the value provided by the +client. The server must return \mdline{3514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3514} for a negative index value +and \mdline{3515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3515} if the index value exceeds the size of the counter array.%mdk + +%mdk-data-line={3516} +\item\mdline{3516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3516}: Server returns the error code \mdline{3516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3516}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3518} +\noindent\mdline{3518}A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a \mdline{3519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3519} by including a \mdline{3519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3519} +entity for each of the instances, specifying the \mdline{3520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3520} and +\mdline{3521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3521}. Wildcard reads are also supported as follows.%mdk + +%mdk-data-line={3523} +\begin{itemize}%mdk + +%mdk-data-line={3523} +\item{} +%mdk-data-line={3523} +\mdline{3523}If the \mdline{3523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3523} field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the \mdline{3524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3524}.%mdk%mdk + +%mdk-data-line={3526} +\item{} +%mdk-data-line={3526} +\mdline{3526}If the \mdline{3526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3526} field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id \mdline{3527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3527}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3529} +\subsection{\mdline{3529}9.4.\hspace*{0.5em}\mdline{3529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3529} \mdline{3529}\&\mdline{3529} \mdline{3529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-meterentry-directmeterentry}%mdk%mdk + +%mdk-data-line={3531} +\noindent\mdline{3531}Meters are an advanced mechanism for keeping statistics, involving stateful +\mdline{3532}\textquotedblleft{}marking\textquotedblright{}\mdline{3532} and usually \mdline{3532}\textquotedblleft{}throttling\textquotedblright{}\mdline{3532} of packets based on configured rates of +traffic. The PSA metering function is based on the \mdline{3533}\emph{Two Rate Three Color Marker}\mdline{3533} +(trTCM) defined in RFC 2698\mdline{3534}~[\mdcite{rfc2698}{2}]\mdline{3534}. The trTCM meters an arbitrary packet +stream using two configured rates\mdline{3535} \mdline{3535}\textemdash{}\mdline{3535} the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes\mdline{3536} \mdline{3536}\textemdash{}\mdline{3536} and +\mdline{3537}\textquotedblleft{}marks\textquotedblright{}\mdline{3537} its packets as GREEN, YELLOW or RED based on the observed rate.%mdk + +%mdk-data-line={3539} +\mdline{3539}A meter may be configured as a direct or indirect instance, similar to a +counter. The \mdline{3540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{3540} P4Runtime message represents meter configuration.%mdk + +%mdk-data-line={3542} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3543} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterConfig~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~cir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~Committed~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~cburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};~~{\mdcolor{darkgreen}//~Committed~Burst~Size}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};~~{\mdcolor{darkgreen}//~Peak~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};~~{\mdcolor{darkgreen}//~Peak~Burst~Size}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3551} +\subsubsection{\mdline{3551}9.4.1.\hspace*{0.5em}\mdline{3551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-directmeterentry}%mdk%mdk + +%mdk-data-line={3553} +\noindent\mdline{3553}A direct meter is a direct resource associated with a \mdline{3553}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3553} (see\mdline{3553}~\mdref{sec-direct-resources}{Direct +resources}\mdline{3554}). The \mdline{3554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3554} field of the \mdline{3554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3554} +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +\mdline{3558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3558} message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed.%mdk + +%mdk-data-line={3561} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3562} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectMeterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3568} +\noindent\mdline{3568}A \mdline{3568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3568} may only include an \mdline{3568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3568} message of type \mdline{3568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3568} with a +\mdline{3569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3569}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3571} +\begin{itemize}%mdk + +%mdk-data-line={3571} +\item{} +%mdk-data-line={3571} +\mdline{3571}the \mdline{3571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3571} field must match the match key of the \mdline{3571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3571} +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching \mdline{3573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3573} is not found, +the server returns the error code \mdline{3574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3574}.%mdk%mdk + +%mdk-data-line={3576} +\item{} +%mdk-data-line={3576} +\mdline{3576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3576} is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3580} +\noindent\mdline{3580}Specifying \mdline{3580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3580} in an \mdline{3580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3580} message of type \mdline{3580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3580} or +\mdline{3581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3581} is not allowed, and the server must return the error code +\mdline{3582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3582} in that case.%mdk + +%mdk-data-line={3584} +\mdline{3584}A client may use \mdline{3584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3584} in two ways to read a \mdline{3584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3584} config.%mdk + +%mdk-data-line={3586} +\begin{itemize}%mdk + +%mdk-data-line={3586} +\item{} +%mdk-data-line={3586} +\mdline{3586}As a direct resource associated with a table entry, request the server to +return the meter config in the \mdline{3587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3587} field of the \mdline{3587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3587} +message (see\mdline{3588}~\mdref{sec-direct-resources}{Direct resources}\mdline{3588}).%mdk%mdk + +%mdk-data-line={3590} +\item{} +%mdk-data-line={3590} +\mdline{3590}Explicitly request the meter configuration by including the \mdline{3590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3590} +in the \mdline{3591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3591}. The \mdline{3591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3591} field must match the +\mdline{3592}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3592} whose meter config is being read. If no such entry is found, the +server returns the error code \mdline{3593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3593}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3595} +\subsubsection{\mdline{3595}9.4.2.\hspace*{0.5em}\mdline{3595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}\label{sec-meterentry}%mdk%mdk + +%mdk-data-line={3597} +\noindent\mdline{3597}An indirect or indexed meter is not associated with a specific \mdline{3597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3597} and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime \mdline{3599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3599} message whose fields are defined as +follows:%mdk + +%mdk-data-line={3602} +\begin{itemize}%mdk + +%mdk-data-line={3602} +\item{} +%mdk-data-line={3602} +\mdline{3602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3602} is a \mdline{3602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3602}, the unique identifier for the meter.%mdk%mdk + +%mdk-data-line={3604} +\item{} +%mdk-data-line={3604} +\mdline{3604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3604} is a Protobuf message that encapsulates an \mdline{3604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3604}, used to index into +a meter array.%mdk%mdk + +%mdk-data-line={3607} +\item{} +%mdk-data-line={3607} +\mdline{3607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3607} is a Protobuf message of type \mdline{3607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{3607}, which represents the +meter configuration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3610} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3611} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~meter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3618} +\noindent\mdline{3618}The \mdline{3618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3618} can only be used in a \mdline{3618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3618} with the \mdline{3618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3618} update +type. The P4Runtime server must return an \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3619} error code for +update types \mdline{3620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3620} and \mdline{3620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3620}. By default all the meter entries in the +array have a default configuration (GREEN for all packets).%mdk + +%mdk-data-line={3623} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3623} +\item\mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3623}: Server returns the error code \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3623}.%mdk + +%mdk-data-line={3624} +\item\mdline{3624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3624}: Modify an indirect meter instance whose unique id is \mdline{3624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3624} and +array index is specified by \mdline{3625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3625}. The meter is reconfigured using the +\mdline{3626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3626} field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the \mdline{3628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3628} field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if \mdline{3630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3630} is unset). The server must return \mdline{3630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3630} for a +negative index value and \mdline{3631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3631} if the index value exceeds the size of +the meter array.%mdk + +%mdk-data-line={3633} +\item\mdline{3633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3633}: Server returns the error code \mdline{3633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3633}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3635} +\noindent\mdline{3635}A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a \mdline{3636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3636} by including a \mdline{3636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3636} entity for each +of the instances, specifying the \mdline{3637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3637} and \mdline{3637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3637}. Wildcard reads are also +supported as follows:%mdk + +%mdk-data-line={3640} +\begin{itemize}%mdk + +%mdk-data-line={3640} +\item{} +%mdk-data-line={3640} +\mdline{3640}If the \mdline{3640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3640} field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the \mdline{3641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3641}.%mdk%mdk + +%mdk-data-line={3643} +\item{} +%mdk-data-line={3643} +\mdline{3643}If the \mdline{3643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3643} field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id \mdline{3644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{3644}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3646} +\subsection{\mdline{3646}9.5.\hspace*{0.5em}\mdline{3646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}\label{sec-packetreplicationengineentry}%mdk%mdk + +%mdk-data-line={3648} +\noindent\mdline{3648}The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets.%mdk + +%mdk-data-line={3654} +\subsubsection{\mdline{3654}9.5.1.\hspace*{0.5em}\mdline{3654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}\label{sec-multicastgroupentry}%mdk%mdk + +%mdk-data-line={3656} +\noindent\mdline{3656}Multicasting is achieved in PSA programs by setting the \mdline{3656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{3656} +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the \mdline{3659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{3659} API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example.%mdk + +%mdk-data-line={3664} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3665} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~arp\_multicast({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ethernet.isValid()~\&\&\\ +~~~~~~~~hdr.ethernet.eth\_type~==~ETH\_TYPE\_ARP)~\{\\ +~~~~~~smeta.multicast\_group~=~(MulticastGroup\_t)~{\mdcolor{purple}1};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3675} +\noindent\mdline{3675}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={3678} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3679} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~multicast\_group\_entry~\{\\ +~~~~~~multicast\_group\_id:~{\mdcolor{purple}1}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}5}~instance:~{\mdcolor{purple}1}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}12}~instance:~{\mdcolor{purple}2}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}18}~instance:~{\mdcolor{purple}3}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}24}~instance:~{\mdcolor{purple}4}~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3693} +\noindent\mdline{3693}As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +\mdline{3698}\mdref{sec-translation-of-port-numbers}{PSA Metadata Translation}\mdline{3698} section.%mdk + +%mdk-data-line={3700} +\mdline{3700}The egress packets may be distinguished for further processing in the egress +using the \mdline{3701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{3701} metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 \mdline{3703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{3703} metadata is set to a value that is not +programmed in the PRE, then the packet is dropped.%mdk + +%mdk-data-line={3706} +\mdline{3706}A multicast group may be inserted, modified or deleted as per the following +semantics.%mdk + +%mdk-data-line={3709} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3709} +\item\mdline{3709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3709}: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The \mdline{3710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3710} field is a \mdline{3710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3710} and must be greater +than 0 (see explanation\mdline{3711}~\mdref{sec-valid-values-for-mg-id}{below}\mdline{3711}), or the +P4Runtime server must return an \mdline{3712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3712} error. The replica +\mdline{3713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{3713} ID is also a \mdline{3713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3713}, and its value may not exceed the maximum +allowed by the target for the \mdline{3714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{3714} type (0 is allowed), or the +server must return an \mdline{3715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3715} error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of \mdline{3717}\emph{both}\mdline{3717} \mdline{3717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{3717} and \mdline{3717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{3717}, or the server +must return \mdline{3718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3718}.%mdk + +%mdk-data-line={3719} +\item\mdline{3719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3719}: Modify the set of replicas for a given multicast group entry, +indexed by the given \mdline{3720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3720}. Same restrictions as \mdline{3720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3720} apply +here.%mdk + +%mdk-data-line={3722} +\item\mdline{3722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3722}: Delete the multicast group indexed by the given +\mdline{3723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3723}. The replicas need not be provided for this +operation. Any packets with their \mdline{3724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{3724} metadata in the data plane +set to the deleted \mdline{3725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3725} will be dropped.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3727} +\noindent\mdline{3727}When reading a multicast group, only \mdline{3727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3727} is considered. All +other fields in \mdline{3728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{3728} are ignored. To perform a \mdline{3728}\emph{wildcard}\mdline{3728} +\mdline{3729}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{3729} on all configured multicast group entries, the \mdline{3729}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3729} field +must be set to 0, its default value.%mdk + +%mdk-data-line={3732} +\paragraph{\mdline{3732}9.5.1.1.\hspace*{0.5em}\mdline{3732}Valid Values for \mdline{3732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}}\label{sec-valid-values-for-mg-id}%mdk%mdk + +%mdk-data-line={3734} +\noindent\mdline{3734}The PSA specification states that the valid \mdline{3734}\emph{data plane}\mdline{3734} values for multicast +group ids (\mdline{3735}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroup\_t}}}\mdline{3735}) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target\mdline{3737}~[\mdcite{psatranslation}{23}]\mdline{3737}. This means that, in the absence of +translation, the client must set the \mdline{3738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3738} field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special \mdline{3740}\emph{wildcard}\mdline{3740} value which is used to read all the multicast groups +configured in the target, the \mdline{3741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{3741} field must never be set to 0 +when performing a \mdline{3742}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{3742} RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value.%mdk + +%mdk-data-line={3747} +\subsubsection{\mdline{3747}9.5.2.\hspace*{0.5em}\mdline{3747}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}\label{sec-clonesessionentry}%mdk%mdk + +%mdk-data-line={3749} +\noindent\mdline{3749}PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +\mdline{3753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3753} identifier and a boolean flag \mdline{3753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone}}}\mdline{3753} in the packet +metadata. The \mdline{3754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3754} serves as a handle to the clone attributes, +namely a set \mdline{3755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}replicas}}}\mdline{3755} of \mdline{3755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(egress~port,~instance)}}}\mdline{3755} pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +\mdline{3758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{3758} API.%mdk + +%mdk-data-line={3760} +\mdline{3760}The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the \mdline{3763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_low\_ttl}}}\mdline{3763} control block is applied in the ingress +pipeline to create an ingress-to-egress clone.%mdk + +%mdk-data-line={3766} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3767} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~clone\_low\_ttl({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ipv4.isValid()~\&\&\\ +~~~~~~~~hdr.ipv4.ttl~\textless{}=~LOW\_TTL\_THRESHOLD)~\{\\ +~~~~~~smeta.clone\_session\_id~=~{\mdcolor{purple}10}w100;\\ +~~~~~~smeta.clone~=~{\bfseries{\mdcolor{navy}true}};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3779} +\noindent\mdline{3779}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={3782} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3783} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~clone\_session\_entry~\{\\ +~~~~~~session\_id:~{\mdcolor{purple}100}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}0xfffffffd}~instance:~{\mdcolor{purple}1}~\}~{\mdcolor{darkgreen}\#~to~CPU}\\ +~~~~~~class\_of\_service:~{\mdcolor{purple}2}\\ +~~~~~~packet\_length\_bytes:~{\mdcolor{purple}4096}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3796} +\noindent\mdline{3796}As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type \mdline{3800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{3800}~[\mdcite{psatranslation}{23}]\mdline{3800}). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes.%mdk + +%mdk-data-line={3805} +\mdline{3805}The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port \mdline{3806}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfffffffd}}}\mdline{3806}; see +\mdline{3807}\mdref{sec-translation-of-port-numbers}{Translation of Port Numbers}\mdline{3807}). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port.%mdk + +%mdk-data-line={3810} +\mdline{3810}If the \mdline{3810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3810} data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created.%mdk + +%mdk-data-line={3813} +\mdline{3813}A clone session may be inserted, modified or deleted as per the following +semantics:%mdk + +%mdk-data-line={3816} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3816} +\item\mdline{3816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3816}: Add a new clone session entry bound to a set of egress ports and +replica IDs. The \mdline{3817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{3817} is a \mdline{3817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3817} and must be greater than 0 (see +explanation\mdline{3818}~\mdref{sec-valid-values-for-session-id}{below}\mdline{3818}), or the P4Runtime +server must return an \mdline{3819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3819} error. The replica \mdline{3819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{3819} ID is +also a \mdline{3820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3820}, and its value may not exceed the maximum allowed by the +target for the \mdline{3821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{3821} type (0 is allowed), or the server must also +return an \mdline{3822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3822} error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (\mdline{3825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}class\_of\_service}}}\mdline{3825} field). This value must be a valid +value for the PSA \mdline{3826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ClassOfService\_t}}}\mdline{3826} type, which supports runtime translation +by default\mdline{3827}~[\mdcite{psatranslation}{23}]\mdline{3827}, or the server must return +\mdline{3828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3828}. See\mdline{3828}~\mdref{sec-translation-of-port-numbers}{PSA Metadata +Translation}\mdline{3829} for more information. The +\mdline{3830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{3830} field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +\mdline{3832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{3832} field is 0 (default), no truncation on the clone will be +performed.%mdk + +%mdk-data-line={3834} +\item\mdline{3834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3834}: Modify the attributes of a given clone session entry, indexed by the +given \mdline{3835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3835}. Same restrictions as \mdline{3835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3835} apply here.%mdk + +%mdk-data-line={3836} +\item\mdline{3836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3836}: Delete the clone session indexed by the given +\mdline{3837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3837}. Other fields need not be provided for this operation. Any +packet with their \mdline{3838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{3838} metadata in the data plane set to the +deleted \mdline{3839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{3839} will no longer be cloned.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3841} +\noindent\mdline{3841}When reading a clone session, only \mdline{3841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{3841} is considered. All other fields +in \mdline{3842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{3842} are ignored. To perform a \mdline{3842}\emph{wildcard}\mdline{3842} \mdline{3842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{3842} on all +configured clone session entries, the \mdline{3843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{3843} field must be set to 0, its +default value. The \mdline{3844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{3844} field can never be equal to 0 in a \mdline{3844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{3844} +RPC. If it does, the server must return an \mdline{3845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3845} error.%mdk + +%mdk-data-line={3847} +\paragraph{\mdline{3847}9.5.2.1.\hspace*{0.5em}\mdline{3847}Valid Values for \mdline{3847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}}\label{sec-valid-values-for-session-id}%mdk%mdk + +%mdk-data-line={3849} +\noindent\mdline{3849}The PSA specification states that the valid \mdline{3849}\emph{data plane}\mdline{3849} values for clone +session ids (\mdline{3850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{3850}) range from 0 to the maximum value supported by +the target\mdline{3851}~[\mdcite{psatranslation}{23}]\mdline{3851}. Note that unlike for\mdline{3851}~\mdref{sec-valid-values-for-mg-id}{multicast group +ids}\mdline{3852}, 0 is a valid \mdline{3852}\emph{data plane}\mdline{3852} value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special \mdline{3854}\emph{wildcard}\mdline{3854} value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a \mdline{3855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{3855} +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is \mdline{3857}\emph{not}\mdline{3857} enabled, we effectively +\mdline{3858}\textquotedblleft{}lose\textquotedblright{}\mdline{3858} one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (\mdline{3859}e.g.\mdline{3859} because the target supports a very +limited number of clone sessions), one can enable translation on +\mdline{3861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{3861} and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id.%mdk + +%mdk-data-line={3864} +\subsection{\mdline{3864}9.6.\hspace*{0.5em}\mdline{3864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}\label{sec-valuesetentry}%mdk%mdk + +%mdk-data-line={3866} +\noindent\mdline{3866}Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the \mdline{3870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{3870} state.%mdk + +%mdk-data-line={3872} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3873} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}state}}~parse\_l2~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}(MAX\_TRILL\_TYPES)~trill\_types;}\\ +~~extract(hdr.ethernet);\\ +~~{\bfseries{\mdcolor{navy}select}}~(hdr.ethernet.eth\_type)~\{\\ +~~~~ETH\_TYPE\_IPV4:~parse\_ipv4;\\ +~~~~ETH\_TYPE\_IPV6:~parse\_ipv6;\\ +~~~~trill\_types:~~~parse\_trill\_types;\\ +~~~~\_:~~~~~~~~~~~~~reject;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3885} +\noindent\mdline{3885}The corresponding entry in the P4Info for this Value Set is:%mdk + +%mdk-data-line={3887} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3888} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}trill\_types}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~\textless{}MAX\_TRILL\_TYPES\textgreater{}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3902} +\noindent\mdline{3902}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={3905} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3906} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x22f3}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x893b}~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3924} +\noindent\mdline{3924}As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the \mdline{3926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{3926} state.%mdk + +%mdk-data-line={3928} +\mdline{3928}A \mdline{3928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{3928} entity update message has the following fields:%mdk + +%mdk-data-line={3930} +\begin{itemize}%mdk + +%mdk-data-line={3930} +\item{} +%mdk-data-line={3930} +\mdline{3930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{3930} is the \mdline{3930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3930} identifier of the Value Set instance, as +defined in P4Info.%mdk%mdk + +%mdk-data-line={3933} +\item{} +%mdk-data-line={3933} +\mdline{3933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3933} is a repeated field of type \mdline{3933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{3933}. When \mdline{3933}\textquotedblleft{}selecting\textquotedblright{}\mdline{3933} +against a Value Set, every member will be considered and if at least one +\mdline{3935}\textquotedblleft{}matches\textquotedblright{}\mdline{3935}, the corresponding parser transition will be taken. Each +\mdline{3936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{3936} contains a repeated field of \mdline{3936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3936} messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a \mdline{3938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{3938} if and only if +it matches all its \mdline{3939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3939} messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. \mdline{3941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3941} messages in a \mdline{3941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{3941} follow +the\mdline{3942}~\mdref{sec-match-format}{same rules}\mdline{3942} as in a \mdline{3942}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3942}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3944} +\noindent\mdline{3944}A \mdline{3944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{3944} may only be modified. If the update type is \mdline{3944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3944} or +\mdline{3945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3945}, the server must return an \mdline{3945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3945} error. If the update type +is \mdline{3946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3946}, the server writes the members given in the repeated field to the +Value Set entry indexed by the given \mdline{3947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{3947}. The maximum number of +matches must not exceed the maximum size given by the \mdline{3948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{3948} field in P4Info of +the Value Set, otherwise the server must return a \mdline{3949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3949} error. To +empty a Value Set (\mdline{3950}i.e.\mdline{3950} restore it to its initial state), the P4Runtime client +can perform a \mdline{3951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3951} update with an empty \mdline{3951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3951} repeated field.%mdk + +%mdk-data-line={3953} +\mdline{3953}To facilitate\mdline{3953}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{3953}, the server must +return an \mdline{3954}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3954} error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary and range matches: +overlapping entries do not need to be ordered and the parse state transition +is determined by whether or not the packet matches at least one entry in the +set.%mdk + +%mdk-data-line={3960} +\mdline{3960}See Appendix\mdline{3960}~\mdref{sec-value-set-example}{A.3}\mdline{3960} for a more complex Value Set example.%mdk + +%mdk-data-line={3962} +\subsection{\mdline{3962}9.7.\hspace*{0.5em}\mdline{3962}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}\label{sec-registerentry}%mdk%mdk + +%mdk-data-line={3964} +\noindent\mdline{3964}The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The \mdline{3965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3965} P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations.%mdk + +%mdk-data-line={3969} +\mdline{3969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3969} has the following fields:%mdk + +%mdk-data-line={3971} +\begin{itemize}%mdk + +%mdk-data-line={3971} +\item{} +%mdk-data-line={3971} +\mdline{3971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{3971}, which identifies the PSA Register extern instance which is +being accessed by the client; the \mdline{3972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{3972} is specified by the P4Info +message.%mdk%mdk + +%mdk-data-line={3975} +\item{} +%mdk-data-line={3975} +\mdline{3975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3975}, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the \mdline{3977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3977} message +used for the request. When an \mdline{3978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3978} is provided , the server must validate +its value, and return \mdline{3979}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3979} for a negative index or +\mdline{3980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3980} if the index exceeds the size of the register array.%mdk%mdk + +%mdk-data-line={3982} +\item{} +%mdk-data-line={3982} +\mdline{3982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3982}: the data to be written to the array (if \mdline{3982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3982} is part of a +\mdline{3983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3983} message) or the data read from the array (if \mdline{3983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{3983} is +part of a \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3984} message). The \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3984} field is a \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{3984} message and +must match the format described by the \mdline{3985}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{3985} field of the corresponding +Register entry in the P4Info, or the server must return an \mdline{3986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3986} +error.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3989} +\subsection{\mdline{3989}9.8.\hspace*{0.5em}\mdline{3989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}\label{sec-digestentry}%mdk%mdk + +%mdk-data-line={3991} +\noindent\mdline{3991}A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly.%mdk + +%mdk-data-line={3996} +\mdline{3996}The \mdline{3996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{3996} P4Runtime entity is used to \mdline{3996}\textbf{configure}\mdline{3996} how the device must +generate digest messages. The \mdline{3997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{3997} Protobuf message is not used to +carry digest data, which is done on the \mdline{3998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{3998} bidirectional stream +using the \mdline{3999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{3999} (digest data sent by the target to the client) and +\mdline{4000}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4000} (digest data acknowledgments sent by the client to the target) +Protobuf messages.%mdk + +%mdk-data-line={4003} +\mdline{4003}In this section, we refer to the data learned by a single data plane call to +\mdline{4004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}T\textgreater{}::pack}}}\mdline{4004} as a \mdline{4004}\textquotedblleft{}digest message\textquotedblright{}\mdline{4004} and we use \mdline{4004}\textquotedblleft{}digest list\textquotedblright{}\mdline{4004} to designate +the list of digest messages bundled by the P4Runtime service in a single +\mdline{4006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4006} stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are \mdline{4008}\textquotedblleft{}duplicate\textquotedblright{}\mdline{4008} if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are \mdline{4009}\textquotedblleft{}distinct\textquotedblright{}\mdline{4009} +if they are not duplicate.%mdk + +%mdk-data-line={4012} +\mdline{4012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4012} has the following fields:%mdk + +%mdk-data-line={4014} +\begin{itemize}%mdk + +%mdk-data-line={4014} +\item{} +%mdk-data-line={4014} +\mdline{4014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4014}, which identifies the PSA Digest extern instance which emitted the +data; the \mdline{4015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4015} is determined by the P4Info message.%mdk%mdk + +%mdk-data-line={4017} +\item{} +%mdk-data-line={4017} +\mdline{4017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4017}, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +\mdline{4019}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4019}; these parameters are:%mdk + +%mdk-data-line={4021} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4021} +\item\mdline{4021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4021}: the maximum server buffering delay in nanoseconds for an +outstanding digest message.%mdk + +%mdk-data-line={4023} +\item\mdline{4023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4023}: the maximum digest list size\mdline{4023} \mdline{4023}\textemdash{}\mdline{4023} in number of digest +messages\mdline{4024} \mdline{4024}\textemdash{}\mdline{4024} sent by the server to the client as a single \mdline{4024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4024} +Protobuf message.%mdk + +%mdk-data-line={4026} +\item\mdline{4026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4026}: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4030} +\noindent\mdline{4030}Here is the significance of the different \mdline{4030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4030} types for \mdline{4030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4030}:%mdk + +%mdk-data-line={4032} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4032} +\item\mdline{4032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4032}: Enable server generation of \mdline{4032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4032} messages for given digest +instance and use provided configuration parameters.%mdk + +%mdk-data-line={4034} +\item\mdline{4034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4034}: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance.%mdk + +%mdk-data-line={4036} +\item\mdline{4036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4036}: Disable server generation of \mdline{4036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4036} messages for given digest +instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4039} +\noindent\mdline{4039}A server should buffer digest messages until either:%mdk + +%mdk-data-line={4041} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4041} +\item\mdline{4041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4041} time has passed since the first digest message was added to +the empty buffer, or%mdk + +%mdk-data-line={4043} +\item\mdline{4043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4043} \mdline{4043}\emph{distinct}\mdline{4043} digest messages have been received from the +data plane and added to the buffer%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4046} +\noindent\mdline{4046}At which point the server should, with best effort, generate a \mdline{4046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4046} +stream message with the buffer contents and send it to the master client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software.%mdk + +%mdk-data-line={4052} +\mdline{4052}To avoid sending duplicate digest messages across different \mdline{4052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4052} +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the master client indicates that it has received the +digest list and acted on it. The server must keep a \mdline{4055}\textquotedblleft{}cache\textquotedblright{}\mdline{4055} containing the set +of all digest messages that have been sent, but not acknowledged yet by the +master client, up-to \mdline{4057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4057} in the past. The server must delete all +cache entries for a given digest list when they are at least \mdline{4058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4058} +old or when a matching \mdline{4059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4059} message (\mdline{4059}i.e.\mdline{4059} with the same \mdline{4059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4059} +and \mdline{4060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}list\_id}}}\mdline{4060} fields as the \mdline{4060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4060} message) is received.%mdk + +%mdk-data-line={4062} +\mdline{4062}The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged \mdline{4067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4067} messages.%mdk + +%mdk-data-line={4069} +\mdline{4069}When \mdline{4069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4069} is set to 0 and / or \mdline{4069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4069} is set to 1, the +server should, with best effort, generate a \mdline{4070}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4070} message for every +digest message generated by the data plane which is not already in the cache. If +\mdline{4072}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4072} is set to 0, the cache must always be an empty set. If +\mdline{4073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4073} is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +\mdline{4075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4075} configuration parameter.%mdk + +%mdk-data-line={4077} +\mdline{4077}The P4Runtime server may empty the digest message cache in case of a client +mastership change.%mdk + +%mdk-data-line={4080} +\mdline{4080}Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server:%mdk + +%mdk-data-line={4083} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4084} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestStream~stream;\\ +DigestCache~cache;\\ +DigestBuffer~buffers;\\ +\\ +{\mdcolor{darkgreen}//~sends~digest~list~when~it~is~ready}\\ +send\_buffer(Id~digest\_id)~\{\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~stream.write(DigestList(buffer));\\ +~~cache.merge(buffer);~~{\mdcolor{darkgreen}//~updates~cache~with~new~digest~list}\\ +~~buffer.clear();\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~data~plane~digest~messages~from~device}\\ +handle\_dataplane\_digest(Digest~msg)~\{\\ +~~digest\_id~=~msg.digest\_id();\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~{\bfseries{\mdcolor{navy}if}}~(msg~in~cache~{\mdcolor{teal}OR}~msg~in~buffer)~{\bfseries{\mdcolor{navy}return}};\\ +~~buffer.enqueue(msg);\\ +~~{\bfseries{\mdcolor{navy}if}}~(buffer.length()~\textless{}~max\_list\_size(digest\_id))~{\bfseries{\mdcolor{navy}return}};\\ +~~send\_buffer(digest\_id);\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~ack~messages~received~on~the~stream}\\ +handle\_stream\_ack(DigestListAck~ack)~\{\\ +~~{\mdcolor{darkgreen}//~clear~all~cache~entries~matching~the~tuple~(digest\_id,~list\_id)}\\ +~~cache.erase(~(ack.digest\_id(),~ack.list\_id()~)\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~loop~to~enforce~timeouts}\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~now~=~now();\\ +~~{\mdcolor{darkgreen}//~check~for~buffers~that~need~to~be~sent}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~buffer)~in~buffers)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~buffer.first\_enq\_time()~\textgreater{}=~max\_timeout\_ns(digest\_id))\\ +~~~~~~send\_buffer(buffer\_id);\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~check~for~expired~entries~in~cache}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~list\_id,~sent\_time)~in~cache)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~sent\_time~\textgreater{}=~ack\_timeout\_ns(digest\_id))\\ +~~~~~~cache.erase(~(digest\_id,~list\_id)~);\\ +~~\}\\ +~~sleep({\mdcolor{teal}X});\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4129} +\subsection{\mdline{4129}9.9.\hspace*{0.5em}\mdline{4129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\label{sec-extern-entry}%mdk%mdk + +%mdk-data-line={4131} +\noindent\mdline{4131}This is used to support a P4 extern entity that is not part of PSA. It is +defined as:%mdk + +%mdk-data-line={4134} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4135} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ExternEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_type\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~google.protobuf.Any~entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4142} +\noindent\mdline{4142}Each \mdline{4142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4142} entity maps to an \mdline{4142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{4142} message in the +\mdline{4143}\mdref{sec-p4info-extern}{P4Info}\mdline{4143} and an \mdline{4143}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4143} message within that +message. The \mdline{4144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{4144} field must be equal to the one in +\mdline{4145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4145}. The \mdline{4145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_id}}}\mdline{4145} field must be equal to the ID included in the +\mdline{4146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{4146} of the corresponding \mdline{4146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4146} message.%mdk + +%mdk-data-line={4148} +\mdline{4148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entry}}}\mdline{4148} itself is embedded as an \mdline{4148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{4148} Protobuf message\mdline{4148}~[\mdcite{protoany}{30}]\mdline{4148} to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on\mdline{4152}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{4153} for more information.%mdk + +%mdk-data-line={4155} +\section{\mdline{4155}10.\hspace*{0.5em}\mdline{4155}Error Reporting Messages}\label{sec-error-reporting-messages}%mdk%mdk + +%mdk-data-line={4157} +\noindent\mdline{4157}P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case.%mdk + +%mdk-data-line={4161} +\mdline{4161}gRPC uses \mdline{4161}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4161}~[\mdcite{grpcstatus}{31}]\mdline{4161} to represent the status returned by an +RPC. It has 3 attributes:%mdk + +%mdk-data-line={4164} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4165} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StatusCode~code\_;\\ +{\mdcolor{navy}grpc::}string~error\_message\_;\\ +{\mdcolor{navy}grpc::}string~binary\_error\_details\_;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4170} +\noindent\mdline{4170}The \mdline{4170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4170} represents a canonical error\mdline{4170}~[\mdcite{grpcstatuscodes}{33}]\mdline{4170} and describes the +overall RPC status. The \mdline{4171}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4171} is a developer-facing error message, +which should be in English. The \mdline{4172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}binary\_error\_details\_}}}\mdline{4172} carries a serialized +\mdline{4173}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4173} message\mdline{4173}~[\mdcite{protostatus}{27}]\mdline{4173} message, which has 3 fields:%mdk + +%mdk-data-line={4175} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4176} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}int32}}~code~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~see~code.proto}\\ +{\bfseries{\mdcolor{navy}string}}~{\bfseries{\mdcolor{navy}message}}~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +{\bfseries{\mdcolor{navy}repeated}}~google.protobuf.Any~details~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4181} +\noindent\mdline{4181}The code and message fields must be the same as \mdline{4181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4181} and \mdline{4181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4181} +fields from \mdline{4182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4182} above. The \mdline{4182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{4182} field is a list that consists of +\mdline{4183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4183} messages that carry error details for individual elements inside +batch-request RPCs (\mdline{4184}e.g.\mdline{4184} \mdline{4184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4184} and \mdline{4184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4184}). \mdline{4184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4184} includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices\mdline{4188}~[\mdcite{grpcstatuscodes}{33}]\mdline{4188}.%mdk + +%mdk-data-line={4190} +\mdline{4190}Figure\mdline{4190}~\mdref{fig-error-report}{\mdcaptionlabel{7}}\mdline{4190} illustrates how these messages fit together.%mdk + +%mdk-data-line={4192} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={4193} +\noindent\mdline{4193}\includegraphics[keepaspectratio=true,width=\dimwidth{0.70}]{build/error-report}{}\mdline{4193}%mdk + +%mdk-data-line={4194} +\mdhr{}%mdk + +%mdk-data-line={4195} +\noindent\mdline{4195}\mdcaption{\textbf{Figure~\mdcaptionlabel{7}.}~\mdcaptiontext{P4Runtime Error Report Message Format}}%mdk +%mdk +\end{mdcenter}\label{fig-error-report}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={4197} +\noindent\mdline{4197}gRPC provides utility functions \mdline{4197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExtractErrorDetails()}}}\mdline{4197} and \mdline{4197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetErrorDetails()}}}\mdline{4197} +\mdline{4198}[\mdcite{grpcerrordetails}{32}]\mdline{4198} to easily convert between \mdline{4198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4198} and +\mdline{4199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4199}.%mdk + +%mdk-data-line={4201} +\mdline{4201}Please see sections on individual P4Runtime RPCs for details on how +\mdline{4202}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4202} is populated for reporting errors.%mdk + +%mdk-data-line={4204} +\mdline{4204}Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on\mdline{4207}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{4208} for more information.%mdk + +%mdk-data-line={4210} +\section{\mdline{4210}11.\hspace*{0.5em}\mdline{4210}Atomicity of Individual \mdline{4210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4210} and \mdline{4210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4210} Operations}\label{sec-atomicity-of-individual-write-and-read-operations}%mdk%mdk + +%mdk-data-line={4212} +\noindent\mdline{4212}Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane \mdline{4213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4213} +operation, and every single \mdline{4214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4214} operation on a table that inserts, deletes, +or modifies one table entry, the \mdline{4215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4215} operation should behave as if that +\mdline{4216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4216} operation has not yet occurred, or as if the \mdline{4216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4216} operation is +complete. The P4 program should never behave as if the \mdline{4217}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4217} operation is +partially complete. These guarantees also apply to extern instances: \mdline{4218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4218} and +\mdline{4219}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4219} operations on extern entities must execute atomically relative to extern +data plane methods.%mdk + +%mdk-data-line={4222} +\mdline{4222}The atomicity guarantees provided by P4Runtime for individual \mdline{4222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4222} and \mdline{4222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4222} +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification\mdline{4224}~[\mdcite{psaatomicityofcontrolplaneops}{22}]\mdline{4224}.%mdk + +%mdk-data-line={4226} +\mdline{4226}The P4\mdline{4226}\mdsub{16}\mdline{4226} language introduces an \mdline{4226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4226} annotation\mdline{4226}~[\mdcite{p4concurrency}{13}]\mdline{4226}, to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the \mdline{4228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4228} annotation for \mdline{4228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4228} +operations, as well as\mdline{4229}~\mdref{wildcard-reads}{non-wildcard \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} operations}\mdline{4229}, +relative to data plane execution. Consider the following P4 example written for +PSA:%mdk + +%mdk-data-line={4233} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4234} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024)~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\mdcolor{darkgreen}//~...}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~Value\_t~v~=~r1.read((Index\_t){\mdcolor{purple}1});\\ +~~~~~~~~v~=~v~+~{\mdcolor{purple}1};\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~v);\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4250} +\noindent\mdline{4250}If a P4Runtime server is processing messages which write to Register \mdline{4250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4250} at +index \mdline{4251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}1}}}\mdline{4251}, these writes must not happen between the data plane \mdline{4251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}read}}}\mdline{4251} and +\mdline{4252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}write}}}\mdline{4252}.%mdk + +%mdk-data-line={4254} +\mdline{4254}Now let\mdline{4254}'\mdline{4254}s consider the following example:%mdk + +%mdk-data-line={4256} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4257} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024,~(Value\_t){\mdcolor{purple}0}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~initial~value~}{\mdcolor{darkgreen}*/})~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}100});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}100});\\ +~~~~\}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}200});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}200});\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4275} +\noindent\mdline{4275}If a P4Runtime client issues a \mdline{4275}\emph{wildcard}\mdline{4275} \mdline{4275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4275} on Register \mdline{4275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4275}, there is no +guarantee that \mdline{4276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]~==~r1{}[2]}}}\mdline{4276} in the response, as the read for \mdline{4276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4276} may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for \mdline{4278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4278} may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read \mdline{4280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4280} and \mdline{4280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4280} separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +\mdline{4283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4283} message) of individual read requests. Similar to a batch +\mdline{4284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4284}, a wildcard read of a register can execute the reads of the +register array elements (\mdline{4285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4285}, \mdline{4285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4285}, \mdline{4285}\dots{}\mdline{4285}) in an arbitrary order relative +to each other.%mdk + +%mdk-data-line={4288} +\mdline{4288}If the \mdline{4288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4288} annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program.%mdk + +%mdk-data-line={4292} +\section{\mdline{4292}12.\hspace*{0.5em}\mdline{4292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4292} RPC}\label{sec-write-rpc}%mdk%mdk + +%mdk-data-line={4294} +\noindent\mdline{4294}The \mdline{4294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4294} RPC updates one or more P4 entities on the target. The request is +defined as follows:%mdk + +%mdk-data-line={4297} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4298} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~WriteRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint64}}~role\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Update~updates~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\bfseries{\mdcolor{navy}enum}}~Atomicity~\{\\ +~~~~CONTINUE\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~ROLLBACK\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~DATAPLANE\_ATOMIC~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~\}\\ +~~Atomicity~atomicity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4312} +\noindent\mdline{4312}The \mdline{4312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4312} uniquely identifies the target P4 device. The \mdline{4312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4312} and +\mdline{4313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4313} define the client role and election-id as described in the +\mdline{4314}\mdref{sec-master-slave-arbitration-and-controller-replication}{Master-Slave Arbitration and Controller +Replication}\mdline{4315} +section. The server is expected to perform the following checks (in this order) +before processing the \mdline{4317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}updates}}}\mdline{4317} list:%mdk + +%mdk-data-line={4319} +\begin{enumerate}%mdk + +%mdk-data-line={4319} +\item{} +%mdk-data-line={4319} +\mdline{4319}If \mdline{4319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4319} does not match any of the devices known to the P4Runtime +server or if \mdline{4320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4320} does not match any of the roles for the device, the +server must return a \mdline{4321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4321} error.%mdk%mdk + +%mdk-data-line={4323} +\item{} +%mdk-data-line={4323} +\mdline{4323}If the client is not the master for (\mdline{4323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4323}, \mdline{4323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4323}) according to the +\mdline{4324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4324} value, the server must return a \mdline{4324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4324} error.%mdk%mdk + +%mdk-data-line={4326} +\item{} +%mdk-data-line={4326} +\mdline{4326}If the \mdline{4326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4326} is attempted before a \mdline{4326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4326} has been set, +the server must return a \mdline{4327}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{4327} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4329} +\noindent\mdline{4329}The updates field is a list of P4 entity updates to be applied. Each update is +defined as:%mdk + +%mdk-data-line={4332} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4333} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Update~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Type~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~INSERT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~MODIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DELETE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~Type~type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Entity~entity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4345} +\noindent\mdline{4345}This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a \mdline{4346}\emph{logical}\mdline{4346} table (\mdline{4346}e.g.\mdline{4346} +\mdline{4347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4347}) or an actual table (\mdline{4347}e.g.\mdline{4347} \mdline{4347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4347}) in the P4 data +plane. Each entity in the container is uniquely identified by its \mdline{4348}\emph{key}\mdline{4348}. Please +refer to the\mdline{4349}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4349} section for details on +what parts of the entity specification make up the \mdline{4350}\emph{key}\mdline{4350} for each P4 entity.%mdk + +%mdk-data-line={4352} +\mdline{4352}An update can be one of the following types:%mdk + +%mdk-data-line={4354} +\begin{itemize}%mdk + +%mdk-data-line={4354} +\item{} +%mdk-data-line={4354} +\mdline{4354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4354}: Inserts the given P4 entity in the entity container. +The \mdline{4355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{4355} field always specifies the full state of the P4 entity. +If the entity already exists, an \mdline{4356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4356} error is returned, and +the existing entity remains unchanged. +If the entity is malformed, an \mdline{4358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4358} error is returned. +If the entity cannot be inserted because the container is already full, +a \mdline{4360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4360} error is returned.%mdk%mdk + +%mdk-data-line={4362} +\item{} +%mdk-data-line={4362} +\mdline{4362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4362}: Modifies the P4 entity to its new specified state. This uses +\mdline{4363}\emph{assign}\mdline{4363} or \mdline{4363}\emph{full-snapshot}\mdline{4363} semantics, \mdline{4363}i.e.\mdline{4363} the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an \mdline{4365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4365} error is usually returned (unless a +more specific error code applies\mdline{4366}~[\mdcite{grpcstatuscodes}{33}]\mdline{4366}). If the entity does not +exist, a \mdline{4367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4367} error is returned.%mdk%mdk + +%mdk-data-line={4369} +\item{} +%mdk-data-line={4369} +\mdline{4369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4369}: Deletes the specified P4 entity. If the entity does not exist, a +\mdline{4370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4370} error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4373} +\noindent\mdline{4373}If an update is not allowed under the given controller role, the server must +return a \mdline{4374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4374} error for this update.%mdk + +%mdk-data-line={4376} +\subsection{\mdline{4376}12.1.\hspace*{0.5em}\mdline{4376}Batching and Ordering of Updates}\label{sec-batching-and-ordering-of-updates}%mdk%mdk + +%mdk-data-line={4378} +\noindent\mdline{4378}P4Runtime supports batching of \mdline{4378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4378} operations. The list of updates in a +\mdline{4379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4379} is referred to as a \mdline{4379}\emph{batch}\mdline{4379}. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of \mdline{4381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4381} entities).%mdk + +%mdk-data-line={4383} +\mdline{4383}The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +\mdline{4385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4385}s can also be processed interleaved and/or in parallel. +However, \mdline{4386}\textbf{the processing of requests must be strictly serializable}\mdline{4386}. That +is, given a history \mdline{4387}$S$\mdline{4387} of \mdline{4387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4387}s including the responses to those +requests, there must exist an order \mdline{4388}$L$\mdline{4388} for all updates in \mdline{4388}$S$\mdline{4388}, such that:%mdk + +%mdk-data-line={4390} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4390} +\item\mdline{4390}All updates from the same write request must appear as a contiguous +subsequence in \mdline{4391}$L$\mdline{4391}, but the order within that subsequence can be arbitrary.%mdk + +%mdk-data-line={4392} +\item\mdline{4392}For two updates \mdline{4392}$u_1$\mdline{4392} and \mdline{4392}$u_2$\mdline{4392}, if the write request containing \mdline{4392}$u_1$\mdline{4392} +completed before the write request of \mdline{4393}$u_2$\mdline{4393} was sent, then \mdline{4393}$u_1$\mdline{4393} must appear +before \mdline{4394}$u_2$\mdline{4394} in \mdline{4394}$L$\mdline{4394}.%mdk + +%mdk-data-line={4395} +\item\mdline{4395}Executing all updates in \mdline{4395}$L$\mdline{4395} sequentially must yield the same response for +every update as in \mdline{4396}$S$\mdline{4396}.%mdk + +%mdk-data-line={4397} +\item\mdline{4397}The observable state of the switch after \mdline{4397}$S$\mdline{4397} (\mdline{4397}e.g.\mdline{4397}, through the \mdline{4397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4397} RPC) +is identical to the one obtained by sequentially executing \mdline{4398}$L$\mdline{4398}.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4400} +\noindent\mdline{4400}The \mdline{4400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4400} RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the \mdline{4401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4401} RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (\mdline{4404}e.g.\mdline{4404} inserting an \mdline{4404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4404} +followed by pointing a \mdline{4405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4405} to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding \mdline{4407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4407} RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate \mdline{4411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4411} calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each \mdline{4412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4412} call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one.%mdk + +%mdk-data-line={4417} +\subsection{\mdline{4417}12.2.\hspace*{0.5em}\mdline{4417}Batch Atomicity}\label{sec-batch-atomicity}%mdk%mdk + +%mdk-data-line={4419} +\noindent\mdline{4419}A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the \mdline{4420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4420} +enum. A P4Runtime server is required to support only the modes marked as +\mdline{4422}\emph{Required}\mdline{4422} below:%mdk + +%mdk-data-line={4424} +\begin{itemize}%mdk + +%mdk-data-line={4424} +\item{} +%mdk-data-line={4424} +\mdline{4424}\emph{Required}\mdline{4424}: \mdline{4424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4424}: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that \mdline{4428}\emph{see}\mdline{4428} each of +these intermediate stages.%mdk%mdk + +%mdk-data-line={4431} +\item{} +%mdk-data-line={4431} +\mdline{4431}\emph{Optional}\mdline{4431}: \mdline{4431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ROLLBACK\_ON\_ERROR}}}\mdline{4431}: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is \mdline{4435}\emph{all-or-none}\mdline{4435}, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that \mdline{4439}\emph{see}\mdline{4439} each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure.%mdk + +%mdk-data-line={4444} +\mdline{4444}If a P4Runtime server does not support this option at all, an +\mdline{4445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4445} error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (\mdline{4446}e.g.\mdline{4446} it is +more straightforward to implement batches that contain only \mdline{4447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4447} +operations, vs. those that contain \mdline{4448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4448} operations), an +\mdline{4449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4449} error is returned when the batch cannot be executed +in a data plane-atomic way.%mdk%mdk + +%mdk-data-line={4452} +\item{} +%mdk-data-line={4452} +\mdline{4452}\emph{Optional}\mdline{4452}: \mdline{4452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4452}: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +\mdline{4456}\emph{transaction}\mdline{4456}. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane\mdline{4458}'\mdline{4458}s table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table.%mdk + +%mdk-data-line={4465} +\mdline{4465}If a P4Runtime server does not support this option at all, an \mdline{4465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4465} +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an \mdline{4467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4467} error is returned when the batch +cannot be executed in a data plane-atomic way.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4470} +\noindent\mdline{4470}There is no expectation that a given client must always use the same \mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4470} +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use \mdline{4473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4473} at one time and default behavior +(\mdline{4474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4474}) at other times.%mdk + +%mdk-data-line={4476} +\subsection{\mdline{4476}12.3.\hspace*{0.5em}\mdline{4476}Error Reporting}\label{sec-error-reporting}%mdk%mdk + +%mdk-data-line={4478} +\noindent\mdline{4478}Please see section\mdline{4478}~\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{4478} for +information on error reporting messages and guidelines. P4Runtime server will +populate \mdline{4480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4480} as follows:%mdk + +%mdk-data-line={4482} +\begin{enumerate}%mdk + +%mdk-data-line={4482} +\item{} +%mdk-data-line={4482} +\mdline{4482}If all batch updates succeeded, set \mdline{4482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4482} to \mdline{4482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4482} and do not +populate any other field.%mdk%mdk + +%mdk-data-line={4485} +\item{} +%mdk-data-line={4485} +\mdline{4485}If an error is encountered before even trying to attempt individual batch +updates, set \mdline{4486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4486} that best describes that RPC-wide +error. For example, use \mdline{4487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNAVAILABLE}}}\mdline{4487} if the P4Runtime service is not yet +ready to handle requests. Set \mdline{4488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4488} to describe the issue. Do not +set \mdline{4489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_details}}}\mdline{4489} in this case.%mdk%mdk + +%mdk-data-line={4491} +\item{} +%mdk-data-line={4491} +\mdline{4491}Otherwise, if one or more updates in the batch (\mdline{4491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest.updates}}}\mdline{4491}) +failed, set \mdline{4492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4492} to \mdline{4492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{4492}. For example, one update in +the batch may fail with \mdline{4493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4493} and another with +\mdline{4494}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4494}. A \mdline{4494}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4494} message is used to capture the status of +each and every update in the batch. The number of \mdline{4495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4495} messages packed +into \mdline{4496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{4496} field should therefore always match the +number of updates in the \mdline{4497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4497}, and the order of +\mdline{4498}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4498} messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +\mdline{4500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4500} should set the code to \mdline{4500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4500} and omit other fields.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4502} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4503} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}\#~Example~of~a~grpc::Status~returned~for~a~Write~RPC~with~a~batch~of~3~updates.}\\ +{\mdcolor{darkgreen}\#~The~first~and~third~updates~encountered~an~error,~while~the~second~update}\\ +{\mdcolor{darkgreen}\#~succeeded.}\\ +code\_~=~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +error\_message\_~=~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +binary\_error\_details~\{\\ +~~code:~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}8}~~{\mdcolor{darkgreen}\#~RESOURCE\_EXHAUSTED}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Table~is~full.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}500}~~{\mdcolor{darkgreen}\#~ERR\_TABLE\_FULL}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}0}~~{\mdcolor{darkgreen}\#~OK}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}6}~~{\mdcolor{darkgreen}\#~ALREADY\_EXISTS}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Entity~already~exists.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}600}~~{\mdcolor{darkgreen}\#~ERR\_ENTITY\_ALREADY\_EXISTS}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4529} +\section{\mdline{4529}13.\hspace*{0.5em}\mdline{4529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4529} RPC}\label{sec-read-rpc}%mdk%mdk + +%mdk-data-line={4531} +\noindent\mdline{4531}The \mdline{4531}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4531} RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as:%mdk + +%mdk-data-line={4534} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4535} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4541} +\noindent\mdline{4541}The \mdline{4541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4541} uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +\mdline{4543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4543} error. The \mdline{4543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{4543} repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server.%mdk + +%mdk-data-line={4546} +\mdline{4546}Since \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4546}s do not mutate any state on the switch, they do not +require an \mdline{4547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4547}, and they do not require the presence of an open +\mdline{4548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4548} between the server and client.%mdk + +%mdk-data-line={4550} +\mdline{4550}The \mdline{4550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read~}}}\mdline{4550}response consists of a sequence of messages (a gRPC \mdline{4550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}stream}}}\mdline{4550}) with +each message defined as:%mdk + +%mdk-data-line={4553} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4554} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadResponse~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4559} +\noindent\mdline{4559}The \mdline{4559}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{4559} repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the \mdline{4563}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Finish()}}}\mdline{4563} method on the stream object +\mdline{4564}[\mdcite{grpcstreamc}{10}]\mdline{4564}).%mdk + +%mdk-data-line={4566} +\subsection{\mdline{4566}13.1.\hspace*{0.5em}\mdline{4566}Nomenclature}\label{sec-nomenclature}%mdk%mdk + +%mdk-data-line={4568} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries request}}%mdk + +%mdk-data-line={4568} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{4568}An element of the \mdline{4568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{4568} repeated field. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries batch}}%mdk + +%mdk-data-line={4570} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{4570}Refers to the \mdline{4570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{4570} repeated field.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={4573} +\noindent\mdline{4573}Each \mdline{4573}\emph{request}\mdline{4573} acts as a query filter for that entity type. If a \mdline{4573}\emph{request}\mdline{4573} fully +specifies the entity key, the \mdline{4574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4574} operation should retrieve a single P4 +entity. Please refer to the\mdline{4575}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4575} section +for details on what parts of the entity specification make up the entity \mdline{4576}\emph{key}\mdline{4576}.%mdk + +%mdk-data-line={4578} +\subsection{\mdline{4578}13.2.\hspace*{0.5em}\mdline{4578}Wildcard Reads}\label{sec-wildcard-reads}%mdk%mdk + +%mdk-data-line={4580} +\noindent\mdline{4580}P4Runtime allows wildcard read of P4 entities. A \mdline{4580}\emph{request}\mdline{4580} may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the\mdline{4582}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4582} section for details on +what parts of the entity can be wildcarded in a given \mdline{4583}\emph{request}\mdline{4583}.%mdk + +%mdk-data-line={4585} +\mdline{4585}For example, in a \mdline{4585}\emph{request}\mdline{4585} of type \mdline{4585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4585}:%mdk + +%mdk-data-line={4587} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4587} +\item\mdline{4587}A default \mdline{4587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4587} (0) implies a request to read all counter-entries for +all indirect counters.%mdk + +%mdk-data-line={4589} +\item\mdline{4589}A particular (non-default) \mdline{4589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4589} in conjunction with \mdline{4589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4589} unset +implies a request to read all counter-entries for the given indirect counter +ID.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4593} +\noindent\mdline{4593}To read the entire forwarding state for a given device, the P4Runtime client can +generate the following \mdline{4594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4594}:%mdk + +%mdk-data-line={4596} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4597} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~\textless{}ID\textgreater{}\\ +entities~\{\\ +~~extern\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~extern~instances~for~all~supported~extern~types}\\ +~~table\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~table~entries~for~all~tables}\\ +~~action\_profile\_member~\{~\}~~{\mdcolor{darkgreen}\#~read~all~members~for~all~action~profiles}\\ +~~action\_profile\_group~\{~\}~~{\mdcolor{darkgreen}\#~read~all~groups~for~all~action~profiles}\\ +~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4607} +\noindent\mdline{4607}The \mdline{4607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{4607} oneof field in the \mdline{4607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{4607} message must always be set, or the +server must return an \mdline{4608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4608} error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty \mdline{4610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{4610} message in the \mdline{4610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4610}. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the \mdline{4612}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{4612} oneof\mdline{4612}~[\mdcite{protooneofbackwardscompatibility}{19}]\mdline{4612}.%mdk + +%mdk-data-line={4614} +\subsection{\mdline{4614}13.3.\hspace*{0.5em}\mdline{4614}Batch Processing}\label{sec-batch-processing}%mdk%mdk + +%mdk-data-line={4616} +\noindent\mdline{4616}A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type \mdline{4617}\emph{request}\mdline{4617} +appears only once in the batch.%mdk + +%mdk-data-line={4620} +\mdline{4620}A P4Runtime server will process the batch as follows:%mdk + +%mdk-data-line={4622} +\begin{enumerate}%mdk + +%mdk-data-line={4622} +\item{} +%mdk-data-line={4622} +\mdline{4622}Lock state (preventing new writes) and validate each \mdline{4622}\emph{request}\mdline{4622} in the batch:%mdk + +%mdk-data-line={4624} +\begin{enumerate}%mdk + +%mdk-data-line={4624} +\item{} +%mdk-data-line={4624} +\mdline{4624}If it is a valid \mdline{4624}\emph{request}\mdline{4624}, perform the read;%mdk + +%mdk-data-line={4626} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4626} +\item\mdline{4626}If the read was successful, return the entities read in +\mdline{4627}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4627} stream.%mdk + +%mdk-data-line={4628} +\item\mdline{4628}If the read failed (exception / critical-error), prepare a \mdline{4628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4628} +with code set to \mdline{4629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INTERNAL}}}\mdline{4629}.%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={4631} +\item{} +%mdk-data-line={4631} +\mdline{4631}If the \mdline{4631}\emph{request}\mdline{4631} is invalid (invalid-argument, not-supported, etc.), +prepare a \mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4632} with relevant canonical code to capture the error.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={4634} +\item{} +%mdk-data-line={4634} +\mdline{4634}Unlock the state (allowing new writes);%mdk%mdk + +%mdk-data-line={4636} +\item{} +%mdk-data-line={4636} +\mdline{4636}Close the \mdline{4636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4636} stream and return a \mdline{4636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4636} as follows:%mdk + +%mdk-data-line={4638} +\begin{enumerate}%mdk + +%mdk-data-line={4638} +\item{} +%mdk-data-line={4638} +\mdline{4638}If no errors were encountered, set code to \mdline{4638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4638} and do not populate any +other field.%mdk%mdk + +%mdk-data-line={4641} +\item{} +%mdk-data-line={4641} +\mdline{4641}Otherwise, the overall code should be set to \mdline{4641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{4641}. See section +\mdline{4642}\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{4642} for information +on error reporting messages and guidelines. Assemble a list of \mdline{4643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4643} +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +\mdline{4647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{4647} field. This behavior also matches \mdline{4647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4647} +RPC.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4650} +\subsubsection{\mdline{4650}13.3.1.\hspace*{0.5em}\mdline{4650}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={4652} +\noindent\mdline{4652}If a client asked to read \mdline{4652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{a,b,c,d\}}}}\mdline{4652} and \mdline{4652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}b}}}\mdline{4652} and \mdline{4652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}d}}}\mdline{4652} \mdline{4652}\emph{requests}\mdline{4652} didn\mdline{4652}'\mdline{4652}t +validate, the server will return entities corresponding to \mdline{4653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{4653} and \mdline{4653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}c}}}\mdline{4653}, followed +by a status \mdline{4654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{p4.Error(OK),~p4.Error(xxx),~p4.Error(yyy),~p4.Error(OK)\}}}}\mdline{4654} in the +\mdline{4655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{4655} field.%mdk + +%mdk-data-line={4657} +\mdline{4657}The P4Runtime server is not required to perform any optimization (\mdline{4657}e.g.\mdline{4657} merge two +\mdline{4658}\emph{requests}\mdline{4658} in the \mdline{4658}\emph{batch}\mdline{4658} if one is a subset of other). As a result of this, it +is possible for the \mdline{4659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4659} to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging.%mdk + +%mdk-data-line={4662} +\mdline{4662}There is no requirement that each request in the batch will correspond to one +\mdline{4663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4663} message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit.%mdk + +%mdk-data-line={4668} +\mdline{4668}A P4Runtime server must be prepared to handle multiple concurrent \mdline{4668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4668} RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (\mdline{4673}e.g.\mdline{4673} in a single-threaded architecture), it may choose to serialize +\mdline{4674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4674} RPC processing.%mdk + +%mdk-data-line={4676} +\subsection{\mdline{4676}13.4.\hspace*{0.5em}\mdline{4676}Parallelism of Read and Write Requests}\label{sec-parallelism-of-read-and-write-requests}%mdk%mdk + +%mdk-data-line={4678} +\noindent\mdline{4678}A P4Runtime server may be implemented to serve at most one +\mdline{4679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4679} or \mdline{4679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4679} message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so.%mdk + +%mdk-data-line={4684} +\mdline{4684}For example, imagine a client that wanted to use \mdline{4684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4684} +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +\mdline{4688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4688} messages with only a few updates to an \mdline{4688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{4688} +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +\mdline{4691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4691} batch currently being processed, but it will not +complete for a significant amount of time.%mdk + +%mdk-data-line={4694} +\mdline{4694}The restrictions on which a client may rely are:%mdk + +%mdk-data-line={4696} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4696} +\item\mdline{4696}The processing of any two \mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4696} messages \mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W1}}}\mdline{4696} and \mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W2}}}\mdline{4696} must +result in the same state as if one of them was completed before the +other began.%mdk + +%mdk-data-line={4699} +\item\mdline{4699}For any \mdline{4699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4699} \mdline{4699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{4699} and any \mdline{4699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4699} \mdline{4699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{4699}, \mdline{4699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{4699} must +return results consistent with a state where \mdline{4700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{4700} has completed +processing, or \mdline{4701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{4701} has not yet begun processing.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4703} +\noindent\mdline{4703}For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a \mdline{4706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4706} message it acquired a write lock for each stateful +object affected by the \mdline{4707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4707}, and before starting the +processing of a \mdline{4708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4708} message it acquired a read lock for each +stateful object accessed by the \mdline{4709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4709}, such an implementation +meets all of the requirements above.%mdk + +%mdk-data-line={4712} +\mdline{4712}It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, \mdline{4714}e.g.\mdline{4714} if the server somehow determined that two +\mdline{4715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4715} messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly.%mdk + +%mdk-data-line={4721} +\section{\mdline{4721}14.\hspace*{0.5em}\mdline{4721}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4721} RPC}\label{sec-setforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={4723} +\noindent\mdline{4723}A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the \mdline{4724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig~RPC}}}\mdline{4724}. The request is defined as:%mdk + +%mdk-data-line={4726} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4727} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~SetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Action~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~VERIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~VERIFY\_AND\_SAVE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~VERIFY\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~~~COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~~~RECONCILE\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint64}}~role\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~Action~action~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4744} +\noindent\mdline{4744}The server is expected to perform the following checks (in this order) +before performing the required \mdline{4745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{4745}:%mdk + +%mdk-data-line={4747} +\begin{enumerate}%mdk + +%mdk-data-line={4747} +\item{} +%mdk-data-line={4747} +\mdline{4747}If \mdline{4747}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4747} does not match any of the devices known to the P4Runtime +server or if \mdline{4748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4748} does not match any of the roles for the device, the +server must return a \mdline{4749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4749} error.%mdk%mdk + +%mdk-data-line={4751} +\item{} +%mdk-data-line={4751} +\mdline{4751}If the client is not the master for (\mdline{4751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4751}, \mdline{4751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4751}) according to the +\mdline{4752}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4752} value, the server must return a \mdline{4752}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4752} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4754} +\noindent\mdline{4754}The action is the type of configuration action requested, it can be one of:%mdk + +%mdk-data-line={4756} +\begin{itemize}%mdk + +%mdk-data-line={4756} +\item{} +%mdk-data-line={4756} +\mdline{4756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY}}}\mdline{4756}: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an \mdline{4757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4757} +error if config is not provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={4760} +\item{} +%mdk-data-line={4760} +\mdline{4760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{4760}: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent \mdline{4762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4762} / \mdline{4762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4762} requests must refer to fields in the new +config. Returns an \mdline{4763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4763} error if the forwarding config is not +provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={4766} +\item{} +%mdk-data-line={4766} +\mdline{4766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_COMMIT}}}\mdline{4766}: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an \mdline{4768}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4768} error if the forwarding config is not provided of if the +provided config cannot be realized.%mdk%mdk + +%mdk-data-line={4771} +\item{} +%mdk-data-line={4771} +\mdline{4771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COMMIT}}}\mdline{4771}: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a \mdline{4774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4774} error if no saved config +is found, \mdline{4775}i.e.\mdline{4775} if no \mdline{4775}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{4775} action preceded this one. Returns an +\mdline{4776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4776} error if a config is provided with this message.%mdk%mdk + +%mdk-data-line={4778} +\item{} +%mdk-data-line={4778} +\mdline{4778}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RECONCILE\_AND\_COMMIT}}}\mdline{4778}: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an \mdline{4784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4784} error. For targets that support this option, an +\mdline{4785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4785} error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4789} +\noindent\mdline{4789}The \mdline{4789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4789} field is a message of type \mdline{4789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4789} that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(\mdline{4791}e.g.\mdline{4791} generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the\mdline{4792}~\mdref{sec-p4-fwd-pipe-config}{Forwarding-Pipeline +Configuration}\mdline{4793} section for details.%mdk + +%mdk-data-line={4795} +\mdline{4795}A P4Runtime server running on a non-programmable device may not +support \mdline{4796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4796} (\mdline{4796}e.g.\mdline{4796} the forwarding-pipeline +config is part of the device\mdline{4797}'\mdline{4797}s software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +\mdline{4799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4799} error.%mdk + +%mdk-data-line={4801} +\section{\mdline{4801}15.\hspace*{0.5em}\mdline{4801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{4801} RPC}\label{sec-getforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={4803} +\noindent\mdline{4803}The forwarding-pipeline configuration of the target can be retrieved by invoking +the \mdline{4804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig~RPC}}}\mdline{4804}. The request is defined as:%mdk + +%mdk-data-line={4806} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4807} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~ResponseType~\{\\ +~~~~ALL~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~COOKIE\_ONLY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~P{\mdcolor{purple}4}INFO\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DEVICE\_CONFIG\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~ResponseType~response\_type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4819} +\noindent\mdline{4819}The \mdline{4819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4819} uniquely identifies the target P4 device. A \mdline{4819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4819} error is +returned if the \mdline{4820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4820} is not recognized by the P4Runtime server.%mdk + +%mdk-data-line={4822} +\mdline{4822}The \mdline{4822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{4822} is used to specify which fields to populate in the response, +its value can be one of:%mdk + +%mdk-data-line={4825} +\begin{itemize}%mdk + +%mdk-data-line={4825} +\item{} +%mdk-data-line={4825} +\mdline{4825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{4825}: returns a \mdline{4825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4825} with all fields +set as stored by the target. This is the default behaviour if the +\mdline{4827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{4827} field is not set.%mdk%mdk + +%mdk-data-line={4829} +\item{} +%mdk-data-line={4829} +\mdline{4829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COOKIE\_ONLY}}}\mdline{4829}: reply by setting only the \mdline{4829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{4829} field in the +\mdline{4830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4830}, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message.%mdk%mdk + +%mdk-data-line={4834} +\item{} +%mdk-data-line={4834} +\mdline{4834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4INFO\_AND\_COOKIE}}}\mdline{4834}: reply by setting the \mdline{4834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{4834} and \mdline{4834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{4834} fields.%mdk%mdk + +%mdk-data-line={4836} +\item{} +%mdk-data-line={4836} +\mdline{4836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEVICE\_CONFIG\_AND\_COOKIE}}}\mdline{4836}: reply by setting the \mdline{4836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{4836} and +\mdline{4837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{4837} fields.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4839} +\noindent\mdline{4839}The response contains the \mdline{4839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4839} for the specified device:%mdk + +%mdk-data-line={4841} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4842} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigResponse~\{\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4847} +\noindent\mdline{4847}If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level \mdline{4848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4848} field will be unset in the response. Examples are +(i) a server that only allows configuration via \mdline{4849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4849} +but this RPC hasn\mdline{4850}'\mdline{4850}t been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn\mdline{4851}'\mdline{4851}t yet occurred.%mdk + +%mdk-data-line={4853} +\mdline{4853}Once a forwarding-pipeline config is installed on the device (either via +\mdline{4854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4854} or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +\mdline{4856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.p4\_device\_config}}}\mdline{4856} will be empty / unset in the response, even if +\mdline{4857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{4857} in the request was set to \mdline{4857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{4857}. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the \mdline{4859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4859} RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +\mdline{4861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4861}, the value of \mdline{4861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.cookie}}}\mdline{4861} will be unset.%mdk + +%mdk-data-line={4863} +\mdline{4863}If a P4Runtime server supports both \mdline{4863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4863} as well as +returning the \mdline{4864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{4864}, there should be read-write symmetry between +\mdline{4865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{4865} and \mdline{4865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{4865} RPCs.%mdk + +%mdk-data-line={4867} +\section{\mdline{4867}16.\hspace*{0.5em}\mdline{4867}P4Runtime Stream Messages}\label{sec-p4runtime-stream-messages}%mdk%mdk + +%mdk-data-line={4869} +\subsection{\mdline{4869}16.1.\hspace*{0.5em}\mdline{4869}Packet I/O}\label{sec-packet-i_o}%mdk%mdk + +%mdk-data-line={4871} +\noindent\mdline{4871}P4Runtime supports controller packet-in and packet-out by means of \mdline{4871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{4871} +and \mdline{4872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4872} stream messages, respectively.%mdk + +%mdk-data-line={4874} +\mdline{4874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{4874} messages are sent by the P4Runtime server to the client. Conversely, +\mdline{4875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4875} messages are sent by the client to the server. Any \mdline{4875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4875} +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a \mdline{4878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{4878} message with the \mdline{4878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{4878} field set to +report the error to the client. See the section on\mdline{4879}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{4880} for more information on \mdline{4880}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{4880}.%mdk + +%mdk-data-line={4882} +\mdline{4882}As introduced in the\mdline{4882}~\mdref{sec-controller-packet-meta}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\mdline{4882} +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with \mdline{4884}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{4884}. The expected metadata is described +in the P4Info using the \mdline{4885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{4885} messages.%mdk + +%mdk-data-line={4887} +\mdline{4887}Both \mdline{4887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{4887} and \mdline{4887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4887} stream messages share the same fields and are +defined as follows:%mdk + +%mdk-data-line={4890} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4891} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Packet~sent~from~the~controller~to~the~switch.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketOut~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~Packet~sent~from~the~switch~to~the~controller.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketIn~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~PacketMetadata~\{\\ +~~{\mdcolor{darkgreen}//~This~refers~to~Metadata.id~coming~from~P4Info~ControllerPacketMetadata.}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~metadata\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4910} +\begin{itemize}%mdk + +%mdk-data-line={4910} +\item{} +%mdk-data-line={4910} +\mdline{4910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}payload}}}\mdline{4910} is used to carry the full packet content, including the headers.%mdk%mdk + +%mdk-data-line={4912} +\item{} +%mdk-data-line={4912} +\mdline{4912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{4912} is a repeated field of \mdline{4912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{4912} messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +\mdline{4915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{4915}. Indeed, when a P4Runtime client (or server) +generates a \mdline{4916}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4916} (or \mdline{4916}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{4916}) message, it needs to populate the +\mdline{4917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{4917} field with as many values as in \mdline{4917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{4917} +for the packet-out (or packet-in) case. Each \mdline{4918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata.value}}}\mdline{4918} is a +binary string and must conform to the\mdline{4919}~\mdref{sec-bytestrings}{Bytestrings}\mdline{4919} +requirements based on the corresponding P4Info +\mdline{4921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{4921} specification. If the \mdline{4921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{4921} field +does not match the P4Info specification, the server must drop the \mdline{4922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4922} +message and may generate a \mdline{4923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{4923} message with the \mdline{4923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{4923} +field set to report the error to the client which issued the \mdline{4924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{4924}. See +the section on\mdline{4925}~\mdref{sec-stream-error-reporting}{Stream Error Reporting}\mdline{4925} for more +information on \mdline{4926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{4926}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4928} +\subsection{\mdline{4928}16.2.\hspace*{0.5em}\mdline{4928}Master Arbitration Update}\label{sec-master-arbitration-update}%mdk%mdk + +%mdk-data-line={4930} +\noindent\mdline{4930}P4Runtime\mdline{4930}'\mdline{4930}s master arbitration mechanism ensures that only the current master +can modify state on the switch, and that the \mdline{4931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4931} is monotonically +increasing. For example, the switch must finish all previous write operations +before changing masters, and must only accept write requests from the current +master.%mdk + +%mdk-data-line={4936} +\mdline{4936}As explained earlier in this document, the controller uses the \mdline{4936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4936} +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via \mdline{4938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4938} RPC), +it needs to start a controller session and become a \mdline{4939}\textquotedblleft{}master\textquotedblright{}\mdline{4939}. To do so, the +controller first opens a bidirectional stream channel to the server via +\mdline{4941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4941} for each device and sends a \mdline{4941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{4941} message. The +controller populates the \mdline{4942}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4942} field in this message using +its \mdline{4943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4943} and \mdline{4943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4943} and the \mdline{4943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4943} of the device, as explained +in detail in the\mdline{4944}~\mdref{sec-master-slave-arbitration-and-controller-replication}{Master-Slave Arbitration and Controller +Replication}\mdline{4945} +section. For any given \mdline{4946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role\_id)}}}\mdline{4946}, the P4Runtime server keeps track +of the highest \mdline{4947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4947} that it has ever received. If a controller\mdline{4947}'\mdline{4947}s +\mdline{4948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4948} is equal to the highest \mdline{4948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4948} that the server has ever +received, that controller is the master. All other controllers are slaves. Note +that it is possible that all controllers are slaves, and that there is no +master. There can be at most one master, because for any given +\mdline{4952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role\_id)}}}\mdline{4952}, each connected controller has a unique \mdline{4952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4952}.%mdk + +%mdk-data-line={4954} +\mdline{4954}This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest \mdline{4955}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4955} after such a restart. +However, across a\mdline{4956}~\mdref{sec-restarts}{full restart}\mdline{4956}, the \mdline{4956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4956} must be +reset. In fact, a full restart is the only way to reset the \mdline{4957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4957}.%mdk + +%mdk-data-line={4959} +\mdline{4959}The \mdline{4959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4959} message is defined as follows:%mdk + +%mdk-data-line={4961} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4962} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Role~\{\\ +~~{\mdcolor{darkgreen}//~role\_id~for~this~role.~Defined~offline~in~agreement~across~the}\\ +~~{\mdcolor{darkgreen}//~entire~control~plane.}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Describes~the~role~configuration.}\\ +~~google.protobuf.Any~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~MasterArbitrationUpdate~\{\\ +~~{\mdcolor{darkgreen}//~Identifies~the~device~(aka~target~or~node~or~switching~chip).}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~The~role~for~which~the~mastership~is~being~arbitrated.}\\ +~~Role~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~The~election\_id~(unique~per~role).}\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Switch~populates~this~with~OK~for~the~client~that~is~the~master,}\\ +~~{\mdcolor{darkgreen}//~and~with~an~error~status~for~all~other~connected~clients~(at}\\ +~~{\mdcolor{darkgreen}//~every~mastership~change).~The~controller~does~not~populate~this}\\ +~~{\mdcolor{darkgreen}//~field.}\\ +~~google.{\bfseries{\mdcolor{navy}rpc}}.Status~status~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4985} +\noindent\mdline{4985}Note that the \mdline{4985}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{4985} field in the \mdline{4985}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4985} message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a \mdline{4987}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{4987} message back to the controller, in which +it populates the \mdline{4988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4988} message using the \mdline{4988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4988}, +\mdline{4989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{4989}, and \mdline{4989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4989} it previously received from the controller. The server +also populates the \mdline{4990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{4990} field in the \mdline{4990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{4990} according to +the rules in an\mdline{4991}~\mdref{sec-mastership-updates}{earlier section}\mdline{4991}.%mdk + +%mdk-data-line={4993} +\mdline{4993}The sender need not specify an \mdline{4993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4993}. If the \mdline{4993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4993} is not +specified, the sender\mdline{4994}'\mdline{4994}s \mdline{4994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4994} is considered lower than any +\mdline{4995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4995}, and the sender will thus never become master. This way, a +controller can choose to be a standby controller, in order to avoid master +\mdline{4997}\textquotedblleft{}flapping\textquotedblright{}\mdline{4997} (if a standby controller connects to the switch shortly before the +actual master controller, therefore becoming master temporarily).%mdk + +%mdk-data-line={5001} +\subsection{\mdline{5001}16.3.\hspace*{0.5em}\mdline{5001}Digest Messages}\label{sec-digest-messages}%mdk%mdk + +%mdk-data-line={5003} +\noindent\mdline{5003}See the\mdline{5003}~\mdref{sec-digestentry}{DigestEntry}\mdline{5003} section.%mdk + +%mdk-data-line={5005} +\subsection{\mdline{5005}16.4.\hspace*{0.5em}\mdline{5005}Table Idle Timeout Notification}\label{sec-table-idle-timeout-notification}%mdk%mdk + +%mdk-data-line={5007} +\noindent\mdline{5007}When a table supports idle timeout (as per the P4Info message), the master +client can specify a TTL value for each entry in the table (see +\mdline{5009}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{5009} section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an \mdline{5011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5011} message on the +\mdline{5012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5012} bidirectional stream to the master client. The master client can +then take the action of its choice, most likely remove the idle entry.%mdk + +%mdk-data-line={5015} +\mdline{5015}The \mdline{5015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5015} Protobuf message has the following fields:%mdk + +%mdk-data-line={5017} +\begin{itemize}%mdk + +%mdk-data-line={5017} +\item{} +%mdk-data-line={5017} +\mdline{5017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}timestamp}}}\mdline{5017}: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server\mdline{5018}'\mdline{5018}s local clock.%mdk%mdk + +%mdk-data-line={5020} +\item{} +%mdk-data-line={5020} +\mdline{5020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5020}: a repeated field of entries which have expired. Each individual +entry is identified by a single \mdline{5021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5021} message. For each \mdline{5021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5021}, +the \mdline{5022}\emph{key}\mdline{5022} fields (\mdline{5022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{5022}, \mdline{5022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{5022} and \mdline{5022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{5022}) must be set, along with +the \mdline{5023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{5023} field and the \mdline{5023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{5023} field. Other fields +may be set by the server but should be ignored by the client.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5026} +\noindent\mdline{5026}Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +\mdline{5028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5028} message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an \mdline{5033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5033} +message with an empty \mdline{5034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5034} repeated field.%mdk + +%mdk-data-line={5036} +\mdline{5036}After generating an idle notification, the P4Runtime server must \mdline{5036}\textquotedblleft{}reset\textquotedblright{}\mdline{5036} the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the master client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle.%mdk + +%mdk-data-line={5043} +\mdline{5043}Here is a reasonable pseudo-code implementation for idle timeout for table +entries:%mdk + +%mdk-data-line={5046} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5047} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutStream~stream;\\ +\\ +scanning\_interval~=~{\mdcolor{purple}10}ms;\\ +\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~{\mdcolor{darkgreen}//~iterate~over~all~tables~which~support~idle~timeout}\\ +~~{\bfseries{\mdcolor{navy}for}}~(table~in~tables)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(!table.idle\_timeout\_supported)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~{\mdcolor{darkgreen}//~we~coalesce~all~idle~notifications~for~the~same~table~in~one}\\ +~~~~{\mdcolor{darkgreen}//~message}\\ +~~~~IdleTimeoutNotification~msg;\\ +~~~~{\mdcolor{darkgreen}//~read~time\_since\_last\_hit~from~device}\\ +~~~~entries~=~device.load\_table\_entries\_from\_hw(table);\\ +~~~~{\bfseries{\mdcolor{navy}for}}~(entry~in~entries)~\{\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.idle\_timeout~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~TTL}\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.time\_since\_last\_hit~\textless{}~entry.idle\_timeout)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~~~msg.table\_entry\_add(entry);\\ +~~~~~~entry.reset\_time\_since\_last\_hit();\\ +~~~~\}\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(msg.table\_entry\_size()~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~notifications}\\ +~~~~msg.set\_timestamp(now());\\ +~~~~stream.write(msg);\\ +~~\}\\ +~~sleep(scanning\_interval);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5074} +\subsection{\mdline{5074}16.5.\hspace*{0.5em}\mdline{5074}Architecture-Specific Notifications}\label{sec-architecture-specific-notifications}%mdk%mdk + +%mdk-data-line={5076} +\noindent\mdline{5076}P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on \mdline{5077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5077}, by including an \mdline{5077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5077} Protobuf field\mdline{5077}~[\mdcite{protoany}{30}]\mdline{5077} +named \mdline{5078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5078} in both \mdline{5078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5078} and \mdline{5078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5078}. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the\mdline{5080}~\mdref{sec-digestentry}{PSA \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}} +extern}\mdline{5081}. See section on\mdline{5081}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{5082} for more information.%mdk + +%mdk-data-line={5084} +\subsection{\mdline{5084}16.6.\hspace*{0.5em}\mdline{5084}Stream Error Reporting}\label{sec-stream-error-reporting}%mdk%mdk + +%mdk-data-line={5086} +\noindent\mdline{5086}The P4Runtime server can asynchronously report errors which occur when +processing \mdline{5087}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5087} messages, using the \mdline{5087}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5087} message field (of +type \mdline{5088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5088}) in \mdline{5088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5088}. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature.%mdk + +%mdk-data-line={5092} +\mdline{5092}The \mdline{5092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5092} message has the following fields:%mdk + +%mdk-data-line={5094} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5094} +\item\mdline{5094}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5094}, which must be set to the appropriate canonical error code +\mdline{5095}[\mdcite{grpcstatuscodes}{33}]\mdline{5095}.%mdk + +%mdk-data-line={5096} +\item\mdline{5096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{5096}, an optional developer-facing error message describing the error.%mdk + +%mdk-data-line={5097} +\item\mdline{5097}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5097} and \mdline{5097}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5097}, which are optional and can be used by vendors to provide +additional details on the error. \mdline{5098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5098} is a numeric error code drawn from a +vendor\mdline{5099}'\mdline{5099}s chosen error \mdline{5099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5099}.%mdk + +%mdk-data-line={5100} +\item\mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5100}, which is a Protobuf \mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5100} used to help the client identify which +\mdline{5101}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5101} triggered the error. The server is required to set the +appropriate field in the \mdline{5102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5102} so that the client can identify which type +of stream message is responsible for the error (\mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5103}, +\mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_list\_ack}}}\mdline{5104} or \mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5104}), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid \mdline{5106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5106} message from the +client, the \mdline{5107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5107} field (of type \mdline{5107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError)}}}\mdline{5107} should be set in +the \mdline{5108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5108} \mdline{5108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5108}, and the server may additionally set the \mdline{5108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5108} +field in the \mdline{5109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError}}}\mdline{5109} sub-message (by copying it from the invalid +\mdline{5110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5110} message received on the stream channel) so that the client can +know exactly what packet-out triggered the error.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5113} +\noindent\mdline{5113}The appropriate canonical error code\mdline{5113}~[\mdcite{grpcstatuscodes}{33}]\mdline{5113} should be used when +populating the \mdline{5114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5114} field. For example:%mdk + +%mdk-data-line={5116} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5116} +\item\mdline{5116}if a controller is not allowed to send a \mdline{5116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5116} message under its +current role definition, the code should be set to \mdline{5117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5117}.%mdk + +%mdk-data-line={5118} +\item\mdline{5118}if the \mdline{5118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5118} repeated field in \mdline{5118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5118} does not match the P4Info +definition, the code should be set to \mdline{5119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5119}. It may be useful +for the server to set the \mdline{5120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5120} field in this case, so that the client +can find out which set of metadata fields triggered the error.%mdk + +%mdk-data-line={5122} +\item\mdline{5122}if the \mdline{5122}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{5122} field in \mdline{5122}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{5122} does not match any \mdline{5122}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{5122} entry +in P4Info, the code should be set to \mdline{5123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5123}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5125} +\noindent\mdline{5125}The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, \mdline{5126}e.g.\mdline{5126} because of a +burst of \mdline{5127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5127} messages.%mdk + +%mdk-data-line={5129} +\mdline{5129}Note that master-arbitration errors are never reported using the \mdline{5129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5129} +message. Invalid \mdline{5130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5130} messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section\mdline{5132}~\mdref{sec-mastership-updates}{5.3}\mdline{5132}.%mdk + +%mdk-data-line={5134} +\subsubsection{\mdline{5134}16.6.1.\hspace*{0.5em}\mdline{5134}Examples of \mdline{5134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5134} Messages}\label{sec-examples-of-streamerror-messages}%mdk%mdk + +%mdk-data-line={5136} +\begin{itemize}%mdk + +%mdk-data-line={5136} +\item{} +%mdk-data-line={5136} +\mdline{5136}\textbf{Malformed packet-out metadata.}\mdline{5136} If the server receives a \mdline{5136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5136} +message with a \mdline{5137}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5137} field with id 7 which is not included in the P4Info +\mdline{5138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5138} message for \mdline{5138}\textquotedblleft{}packet\_out\textquotedblright{}\mdline{5138}, the server may send the +following \mdline{5139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5139} back to the client:%mdk + +%mdk-data-line={5140} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5141} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Unknown~metadata~field~id~7.}{\mdcolor{maroon}"}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~copied~from~the~PacketOut~message~received~from~the~client}\\ +~~~packet\_out~\{\\ +~~~~~payload:~...\\ +~~~~~metadata~\{\\ +~~~~~~~id:~{\mdcolor{purple}7}\\ +~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}I\_should\_not\_be\_here}{\mdcolor{maroon}"}\\ +~~~~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~~\}\\ +~~~~~{\mdcolor{darkgreen}\#~more~metadata}\\ +~~~\}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={5159} +\item{} +%mdk-data-line={5159} +\mdline{5159}\textbf{Packet-out which exceeds the MTU.}\mdline{5159} If the server receives a \mdline{5159}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5159} +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following \mdline{5162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5162}:%mdk + +%mdk-data-line={5163} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5164} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Packet~exceeds~the~MTU~for~port.}{\mdcolor{maroon}"}\\ +~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendor1}{\mdcolor{maroon}"}\\ +~code:~{\mdcolor{purple}123}~~{\mdcolor{darkgreen}\#~MTU\_EXCEEDED}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~we~do~not~set~the~packet\_out~field~as~it~does~not~provide~any}\\ +~~~{\mdcolor{darkgreen}\#~extra~information~to~the~client}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5176} +\section{\mdline{5176}17.\hspace*{0.5em}\mdline{5176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5176} RPC}\label{sec-capabilities-rpc}%mdk%mdk + +%mdk-data-line={5178} +\noindent\mdline{5178}The \mdline{5178}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5178} RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the \mdline{5180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesRequest}}}\mdline{5180} message is empty and the \mdline{5180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5180} +message only includes the \mdline{5181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_api\_version}}}\mdline{5181} string field. This field must +be set to the full semantic version string\mdline{5182}~[\mdcite{semver}{26}]\mdline{5182} corresponding to the +version of the P4Runtime API implemented by the server, \mdline{5183}e.g.\mdline{5183} \mdline{5183}\textquotedblleft{}1.1.0-rc.1\textquotedblright{}\mdline{5183}.%mdk + +%mdk-data-line={5185} +\mdline{5185}Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three\mdline{5186}~\mdref{sec-batch-atomicity}{atomicity +modes}\mdline{5187} for \mdline{5187}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5187} batches, two of them being +optional. In the future we may decide to leverage the \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5188} +message to enable the server to report to the client which subset of these +atomicity modes is supported.%mdk + +%mdk-data-line={5192} +\mdline{5192}The semantic version string included in \mdline{5192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5192} can be used by +the client to determine which exact feature set is implemented by the server, +since\mdline{5194}~\mdref{sec-p4runtime-versioning}{minor releases}\mdline{5194} may introduce new +functionality. However, because the \mdline{5195}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5195} RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (\mdline{5197}i.e.\mdline{5197} an \mdline{5197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5197} error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0).%mdk + +%mdk-data-line={5201} +\section{\mdline{5201}18.\hspace*{0.5em}\mdline{5201}Portability Considerations}\label{sec-portability-considerations}%mdk%mdk + +%mdk-data-line={5203} +\subsection{\mdline{5203}18.1.\hspace*{0.5em}\mdline{5203}PSA Metadata Translation}\label{sec-psa-metadata-translation}%mdk%mdk + +%mdk-data-line={5205} +\noindent\mdline{5205}The \mdline{5205}\emph{Portable Switch Architecture}\mdline{5205} (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +\mdline{5209}[\mdcite{psatranslation}{23}]\mdline{5209}. For such metadata, a translation between the controller\mdline{5209}'\mdline{5209}s +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service.%mdk + +%mdk-data-line={5215} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={5216} +\noindent\mdline{5216}\includegraphics[keepaspectratio=true,height=7cm]{build/psa-metadata-translation}{}\mdline{5216}%mdk + +%mdk-data-line={5217} +\mdhr{}%mdk + +%mdk-data-line={5218} +\noindent\mdline{5218}\mdcaption{\textbf{Figure~\mdcaptionlabel{8}.}~\mdcaptiontext{P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdcenter}\label{fig-psa-metadata-translation}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={5222} +\noindent\mdline{5222}Figure\mdline{5222}~\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}}\mdline{5222} illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller\mdline{5228}'\mdline{5228}s 32 bit port +numbers to a target\mdline{5229}'\mdline{5229}s 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch.%mdk + +%mdk-data-line={5233} +\subsubsection{\mdline{5233}18.1.1.\hspace*{0.5em}\mdline{5233}Translation of Port Numbers}\label{sec-translation-of-port-numbers}%mdk%mdk + +%mdk-data-line={5235} +\noindent\mdline{5235}In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller\mdline{5236}'\mdline{5236}s space and the PSA device\mdline{5236}'\mdline{5236}s space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +\mdline{5240}\mdref{sec-user-defined-types}{user-defined P4 types}\mdline{5240}, namely \mdline{5240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5240} and +\mdline{5241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5241}, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in \mdline{5244}\emph{psa.p4}\mdline{5244} for +the PSA device in Switch 1.%mdk + +%mdk-data-line={5247} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5248} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~PortId\_t~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{};\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortIdInHeader\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~PortIdInHeader\_t~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5254} +\noindent\mdline{5254}The first argument to the \mdline{5254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5254} annotation is a URI that +indicates to the P4Runtime server which numerical mapping\mdline{5255} \mdline{5255}\textemdash{}\mdline{5255} provided by the +out-of-band switch configuration mechanism\mdline{5256} \mdline{5256}\textemdash{}\mdline{5256} to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports).%mdk + +%mdk-data-line={5260} +\mdline{5260}An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows:%mdk + +%mdk-data-line={5266} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5267} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}enum}}~SdnPort~\{\\ +~~SDN\_PORT\_UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +\\ +~~{\mdcolor{darkgreen}//~SDN~ports~are~numbered~starting~form~1.}\\ +~~SDN\_PORT\_MIN~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\\ +~~{\mdcolor{darkgreen}//~The~maximum~value~of~an~SDN~port~(physical~or~logical).}\\ +~~SDN\_PORT\_MAX~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffeff};\\ +\\ +~~{\mdcolor{darkgreen}//~Reserved~SDN~port~numbers~(0xfffffff0~-~0xffffffff)}\\ +\\ +~~SDN\_PORT\_RECIRCULATE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffa};\\ +~~SDN\_PORT\_CPU~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffd};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5283} +\noindent\mdline{5283}The switch config will map \mdline{5283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_RECIRCULATE}}}\mdline{5283} and \mdline{5283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_CPU}}}\mdline{5283} \mdline{5283}\textemdash{}\mdline{5283} as well +as any SDN port number corresponding to a \mdline{5284}\textquotedblleft{}regular\textquotedblright{}\mdline{5284} front-panel port\mdline{5284} \mdline{5284}\textemdash{}\mdline{5284} to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation.%mdk + +%mdk-data-line={5288} +\mdline{5288}The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs.%mdk + +%mdk-data-line={5291} +\subsubsection{\mdline{5291}18.1.2.\hspace*{0.5em}\mdline{5291}Translation of Packet-IO Header Fields}\label{sec-translation-of-packet-io-header-fields}%mdk%mdk + +%mdk-data-line={5293} +\noindent\mdline{5293}Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:.%mdk + +%mdk-data-line={5296} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5297} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~PortIdInHeader\_t~egress\_port;\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~PortIdInHeader\_t~ingress\_port;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5308} +\noindent\mdline{5308}The header-level annotation \mdline{5308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5308} is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (\mdline{5312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5312}) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI\mdline{5316} \mdline{5316}\textemdash{}\mdline{5316} first argument to the \mdline{5316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5316} +annotation). Any subsequent reference to the \mdline{5317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5317} field in the +data plane will use the translated value. \mdline{5318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5318} is used in the +header definition instead of \mdline{5319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5319} to guarantee byte-aligned headers in +case this is required by the target.%mdk + +%mdk-data-line={5322} +\mdline{5322}A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target\mdline{5324}'\mdline{5324}s PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the \mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ingress\_port}}}\mdline{5326} field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller.%mdk + +%mdk-data-line={5332} +\subsubsection{\mdline{5332}18.1.3.\hspace*{0.5em}\mdline{5332}Translation of Match Fields}\label{sec-translation-of-match-fields}%mdk%mdk + +%mdk-data-line={5334} +\noindent\mdline{5334}Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table\mdline{5335}'\mdline{5335}s match key as shown in the example below:%mdk + +%mdk-data-line={5337} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5338} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~istd.ingress\_port:~exact;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~ingress~port}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5348} +\noindent\mdline{5348}Table \mdline{5348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5348} has an exact match on PSA standard metadata ingress port +(\mdline{5349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}istd.ingress\_port}}}\mdline{5349}). Since the field is of type \mdline{5349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5349}, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in \mdline{5352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5352} from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table \mdline{5357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5357} is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values.%mdk + +%mdk-data-line={5361} +\mdline{5361}Note that it may be infeasible to translate the value-mask pair for ternary +matches: \mdline{5362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5362}, \mdline{5362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5362} or \mdline{5362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5362} match kinds. The P4Runtime server may +require that for these match kinds the port match be either \mdline{5363}\emph{de facto}\mdline{5363} \mdline{5363}\textquotedblleft{}exact\textquotedblright{}\mdline{5363} +(0xffffffff mask for \mdline{5364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5364}, prefix-length of 32 for \mdline{5364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5364}, or same low and +high bounds for \mdline{5365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5365}) or \mdline{5365}\textquotedblleft{}don't care\textquotedblright{}\mdline{5365}.%mdk + +%mdk-data-line={5367} +\subsubsection{\mdline{5367}18.1.4.\hspace*{0.5em}\mdline{5367}Translation of Action Parameters}\label{sec-translation-of-action-parameters}%mdk%mdk + +%mdk-data-line={5369} +\noindent\mdline{5369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5369} type parameters can be part of a P4 action definition as shown in the +example below:%mdk + +%mdk-data-line={5372} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5373} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.h.f:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~a;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5387} +\noindent\mdline{5387}The controller may write entries in table \mdline{5387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5387} with action \mdline{5387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5387} to set the egress +port as shown in the P4 code above. The action parameter \mdline{5388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5388} is of type +\mdline{5389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5389}, which leads to a 32-bit bitwidth for \mdline{5389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5389} being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device.%mdk + +%mdk-data-line={5395} +\subsubsection{\mdline{5395}18.1.5.\hspace*{0.5em}\mdline{5395}Port Translation for PSA Extern APIs}\label{sec-port-translation-for-psa-extern-apis}%mdk%mdk + +%mdk-data-line={5397} +\noindent\mdline{5397}The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch field is +of type \mdline{5403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5403} to carry the 32-bit SDN representation of the port being +watched. The P4Runtime server will translate the given watch port number into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device.%mdk + +%mdk-data-line={5408} +\mdline{5408}The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type \mdline{5410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5410} to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane.%mdk + +%mdk-data-line={5414} +\subsubsection{\mdline{5414}18.1.6.\hspace*{0.5em}\mdline{5414}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}\label{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}%mdk%mdk + +%mdk-data-line={5416} +\noindent\mdline{5416}P4Runtime supports using a translated value (\mdline{5416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5416} or any other translated +type for which the underlying built-in type is \mdline{5417}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5417}) as an index to a +register, indirect counter, or indirect meter.%mdk + +%mdk-data-line={5420} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5421} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~counter~entry~type~}{\mdcolor{darkgreen}*/},~PortId\_t~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~index~type~}{\mdcolor{darkgreen}*/}\textgreater{}(\\ +~~{\mdcolor{purple}32}w1024,~PSA\_CounterType\_t.PACKETS)~counter;\\ +{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +~~counter.count(p);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5429} +\noindent\mdline{5429}This P4 Counter declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={5432} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5433} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counters~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x12000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}counter}{\mdcolor{maroon}"}\\ +~~\}\\ +~~spec~\{\\ +~~~~unit:~PACKETS\\ +~~\}\\ +~~index\_type\_name~\{\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5447} +\noindent\mdline{5447}The controller may read and write counter values from indexed counter \mdline{5447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter}}}\mdline{5447} +using SDN port numbers as indices, and not device-specific port numbers. The +\mdline{5449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{5449} field in the P4Info message is a signal to the P4Runtime +server that translation is required.%mdk + +%mdk-data-line={5452} +\section{\mdline{5452}19.\hspace*{0.5em}\mdline{5452}P4Runtime Versioning}\label{sec-p4runtime-versioning}%mdk%mdk + +%mdk-data-line={5454} +\noindent\mdline{5454}P4Runtime follows the Google guidelines for versioning cloud APIs +\mdline{5455}[\mdcite{apiversioning}{6}]\mdline{5455}. We use a \mdline{5455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR.MINOR.PATCH}}}\mdline{5455} style version number scheme and +we increment the:%mdk + +%mdk-data-line={5458} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5458} +\item\mdline{5458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5458} version when we make incompatible API changes,%mdk + +%mdk-data-line={5459} +\item\mdline{5459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MINOR}}}\mdline{5459} version when we add functionality in a backwards-compatible manner,%mdk + +%mdk-data-line={5460} +\item\mdline{5460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PATCH}}}\mdline{5460} version when we make backwards-compatible bug fixes.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5462} +\noindent\mdline{5462}The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is \mdline{5464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1}}}\mdline{5464} and the package +name for P4Info is \mdline{5465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1}}}\mdline{5465}. Even though \mdline{5465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5465} and \mdline{5465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5465} are two +different Protobuf packages, \mdline{5466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5466} depends on \mdline{5466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5466} and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence.%mdk + +%mdk-data-line={5470} +\mdline{5470}As recommended in\mdline{5470}~[\mdcite{apiversioning}{6}]\mdline{5470}, we may consider using pre-GA release +suffixes (such as \mdline{5471}\emph{alpha}\mdline{5471} or \mdline{5471}\emph{beta}\mdline{5471}) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1).%mdk + +%mdk-data-line={5475} +\mdline{5475}Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner.\mdline{5476}~[\mdcite{apiversioningbackwardscompatibility}{7}]\mdline{5476} describes +what constitute a backwards-compatible change. We expect \mdline{5477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5477} version bumps +to be a \mdline{5478}\textbf{rare}\mdline{5478} event.%mdk + +%mdk-data-line={5480} +\mdline{5480}Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor\mdline{5485} \mdline{5485}+ patch version numbers in future releases.%mdk + +%mdk-data-line={5487} +\mdline{5487}All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository\mdline{5488}~[\mdcite{p4runtimerepo}{14}]\mdline{5488} and the version label follows +semantic versioning rules\mdline{5489}~[\mdcite{semver}{26}]\mdline{5489}.%mdk + +%mdk-data-line={5491} +\section{\mdline{5491}20.\hspace*{0.5em}\mdline{5491}Extending P4Runtime for non-PSA Architectures}\label{sec-extending-p4runtime}%mdk%mdk + +%mdk-data-line={5493} +\noindent\mdline{5493}P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place.%mdk + +%mdk-data-line={5501} +\mdline{5501}When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names:%mdk + +%mdk-data-line={5505} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5505} +\item\mdline{5505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/config/\textless{}major~version\textgreater{}/p4info.proto}}}\mdline{5505}%mdk + +%mdk-data-line={5506} +\item\mdline{5506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/\textless{}major~version\textgreater{}/p4runtime.proto}}}\mdline{5506}%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5508} +\noindent\mdline{5508}We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they \mdline{5509}\textquotedblleft{}extend\textquotedblright{}\mdline{5509}.%mdk + +%mdk-data-line={5511} +\mdline{5511}For the remainder of this section, we will refer to these two files as +\mdline{5512}\emph{p4info-ext}\mdline{5512} and \mdline{5512}\emph{p4runtime-ext}\mdline{5512} respectively.%mdk + +%mdk-data-line={5514} +\subsection{\mdline{5514}20.1.\hspace*{0.5em}\mdline{5514}Extending P4Runtime for Architecture-Specific Externs}\label{sec-extending-p4runtime-for-architecture-specific-externs}%mdk%mdk + +%mdk-data-line={5516} +\noindent\mdline{5516}Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both \mdline{5517}\emph{p4info-ext}\mdline{5517} and +\mdline{5518}\emph{p4runtime-ext}\mdline{5518}. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example:%mdk + +%mdk-data-line={5522} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5523} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~T~must~be~a~bit\textless{}W\textgreater{}~type,~it~indicates~the~width~of~each~counter~cell}\\ +{\bfseries{\mdcolor{navy}extern}}~MyNewPacketCounter\textless{}T\textgreater{}~\{\\ +~~counter({\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~size);\\ +~~increment({\bfseries{\mdcolor{navy}in}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~index);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5530} +\subsubsection{\mdline{5530}20.1.1.\hspace*{0.5em}\mdline{5530}Extending the P4Info message}\label{sec-extending-the-p4info-message}%mdk%mdk + +%mdk-data-line={5532} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5532} +\item\mdline{5532}Id prefixes \mdline{5532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0x81}}}\mdline{5532} through \mdline{5532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfe}}}\mdline{5532} are reserved for architecture-specific +externs. It is recommended that \mdline{5533}\emph{p4info-ext}\mdline{5533} include a \mdline{5533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Ids}}}\mdline{5533} message based +on the one in p4info.proto that the P4 compiler can refer to when\mdline{5534}~\mdref{sec-id-allocation}{assigning +IDs}\mdline{5535} to each extern instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5537} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5538} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~P{\mdcolor{purple}4}Ids~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Prefix~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~MY\_NEW\_PACKET\_COUNTER~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0x81};\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5546} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5546} +\item\mdline{5546}\emph{p4info-ext}\mdline{5546} should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +\mdline{5550}\mdref{sec-p4info-extern}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ExternInstance}}}}\mdline{5550} message as the \mdline{5550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{5550} +field, which is of type \mdline{5551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5551}~[\mdcite{protoany}{30}]\mdline{5551}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5553} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5554} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\mdcolor{darkgreen}//~corresponds~to~the~T~type~parameter~in~the~P4~extern~definition}\\ +~~p4.config.v1.P{\mdcolor{purple}4}DataTypeSpec~type\_spec~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~constructor~argument}\\ +~~{\bfseries{\mdcolor{navy}int64}}~size~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5562} +\subsubsection{\mdline{5562}20.1.2.\hspace*{0.5em}\mdline{5562}Extending the P4Runtime Service}\label{sec-extending-the-p4runtime-service}%mdk%mdk + +%mdk-data-line={5564} +\noindent\mdline{5564}Just like \mdline{5564}\emph{p4info-ext}\mdline{5564}, \mdline{5564}\emph{p4runtime-ext}\mdline{5564} should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an\mdline{5569}~\mdref{sec-extern-entry}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\mdline{5569} message generated by the +P4Runtime client.%mdk + +%mdk-data-line={5572} +\mdline{5572}Here is a possible Protobuf message for our \mdline{5572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyNewPacketCounter}}}\mdline{5572} P4 extern:%mdk + +%mdk-data-line={5573} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5574} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~This~message~enables~reading~/~writing~data~to~the~counter~at~the~provided}\\ +{\mdcolor{darkgreen}//~index}\\ +{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~p4.v1.P{\mdcolor{purple}4}Data~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5582} +\noindent\mdline{5582}P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an \mdline{5583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5583} Protobuf field\mdline{5583}~[\mdcite{protoany}{30}]\mdline{5583} named \mdline{5583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5583} +in both \mdline{5584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{5584} and +\mdline{5585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{5585}. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in \mdline{5587}\emph{p4runtime-ext}\mdline{5587} and embed instances of these messages in +\mdline{5588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{5588} and \mdline{5588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{5588} as appropriate.%mdk + +%mdk-data-line={5590} +\subsection{\mdline{5590}20.2.\hspace*{0.5em}\mdline{5590}Architecture-Specific Table Extensions}\label{sec-architecture-specific-table-extensions}%mdk%mdk + +%mdk-data-line={5592} +\subsubsection{\mdline{5592}20.2.1.\hspace*{0.5em}\mdline{5592}New Match Types}\label{sec-new-match-types}%mdk%mdk + +%mdk-data-line={5594} +\noindent\mdline{5594}An architecture may introduce new table match types\mdline{5594}~[\mdcite{p4matchtypes}{12}]\mdline{5594}. P4Runtime +accounts for this by providing the following hooks:%mdk + +%mdk-data-line={5597} +\begin{itemize}%mdk + +%mdk-data-line={5597} +\item{} +%mdk-data-line={5597} +\mdline{5597}The \mdline{5597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{5597} field in \mdline{5597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{5597} (p4info.proto) is a \mdline{5597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5597} +which can be either one of the default match types (\mdline{5598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{5598}, \mdline{5598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5598}, \mdline{5598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5598} +or \mdline{5599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5599}) or an architecture-specific match type encoded as a string.%mdk%mdk + +%mdk-data-line={5601} +\item{} +%mdk-data-line={5601} +\mdline{5601}The \mdline{5601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{5601} field in \mdline{5601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{5601} (p4runtime.proto) is a +\mdline{5602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5602} which includes an \mdline{5602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5602} Protobuf message\mdline{5602}~[\mdcite{protoany}{30}]\mdline{5602} field +(\mdline{5603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5603}). \mdline{5603}\emph{p4info-ext}\mdline{5603} should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in \mdline{5606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{5606} as the +\mdline{5607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5607} field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5610} +\subsubsection{\mdline{5610}20.2.2.\hspace*{0.5em}\mdline{5610}New Table Properties}\label{sec-new-table-properties}%mdk%mdk + +%mdk-data-line={5612} +\noindent\mdline{5612}An architecture may introduce additional table properties +\mdline{5613}[\mdcite{p4tableproperties}{29}]\mdline{5613}. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +\mdline{5615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Table}}}\mdline{5615} message includes the \mdline{5615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{5615} \mdline{5615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5615} Protobuf +field\mdline{5616}~[\mdcite{protoany}{30}]\mdline{5616}. At the moment, there is not any mechanism to extend the +\mdline{5617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.TableEntry}}}\mdline{5617} message based on the value of architecture-specific table +properties, but we may include on in future versions of the API.%mdk + +%mdk-data-line={5620} +\section{\mdline{5620}21.\hspace*{0.5em}\mdline{5620}Known Limitations of Current P4Runtime Version}\label{sec-known-limitations-of-current-p4runtime-version}%mdk%mdk + +%mdk-data-line={5622} +\begin{itemize}%mdk + +%mdk-data-line={5622} +\item{} +%mdk-data-line={5622} +\mdline{5622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{5622}, action \mdline{5622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{5622}, and controller packet metadata fields only +support unsigned bitstrings, \mdline{5623}i.e.\mdline{5623} values of one of the following types (not +the more general \mdline{5624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{5624}):%mdk + +%mdk-data-line={5625} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5625} +\item\mdline{5625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5625}%mdk + +%mdk-data-line={5626} +\item\mdline{5626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{5626}. Note that as far as the \mdline{5626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Info}}}\mdline{5626} message contents and +thus controller software is concerned, such fields of type \mdline{5627}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{5627} +will be indistinguishable from those that have been declared with +type \mdline{5629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{5629}. P4Runtime server software will automatically +perform any conversion needed between the type \mdline{5630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{5630} values in +P4Runtime messages and the data plane representation.%mdk + +%mdk-data-line={5632} +\item\mdline{5632}an \mdline{5632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{5632} with underlying type \mdline{5632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5632}%mdk + +%mdk-data-line={5633} +\item\mdline{5633}a \mdline{5633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{5633} or \mdline{5633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{5633} with an underlying type that is one of the above (or +in general a \mdline{5634}\textquotedblleft{}chain\textquotedblright{}\mdline{5634} of \mdline{5634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{5634} and/or \mdline{5634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{5634} that eventually ends with +one of the types above)%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={5637} +\item{} +%mdk-data-line={5637} +\mdline{5637}Support for PSA Random \mdline{5637}\&\mdline{5637} Timestamp externs is postponed to a future minor +version update.%mdk%mdk + +%mdk-data-line={5640} +\item{} +%mdk-data-line={5640} +\mdline{5640}P4Info does not include information about which of a table\mdline{5640}'\mdline{5640}s actions execute +which direct resource(s).%mdk%mdk + +%mdk-data-line={5643} +\item{} +%mdk-data-line={5643} +\mdline{5643}The default action for indirect match tables is restricted to a \mdline{5643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\\ +NoAction}}}\mdline{5644} known at compile-time.%mdk%mdk + +%mdk-data-line={5646} +\item{} +%mdk-data-line={5646} +\mdline{5646}There is no mechanism for changing the value of the \mdline{5646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{5646} +table property at runtime.%mdk%mdk + +%mdk-data-line={5649} +\item{} +%mdk-data-line={5649} +\mdline{5649}There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor\mdline{5650} \mdline{5650}+ +patch version numbers.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5653} +\section{\mdline{5653}22.\hspace*{0.5em}\mdline{5653}Security concerns for P4Runtime}\label{sec-security-concerns-for-p4runtime}%mdk%mdk + +%mdk-data-line={5655} +\noindent\mdline{5655}Appropriate measures and security best practices need to be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client.%mdk + +%mdk-data-line={5662} +\section{\mdline{5662}A.\hspace*{0.5em}\mdline{5662}Appendix}\label{sec-appendix}%mdk%mdk + +%mdk-data-line={5664} +\subsection{\mdline{5664}A.1.\hspace*{0.5em}\mdline{5664}Revision History}\label{sec-revision-history}%mdk%mdk + +%mdk-data-line={5666} +\subsubsection{\mdline{5666}A.1.1.\hspace*{0.5em}\mdline{5666}Changes in v1.1.0}\label{sec-changes-in-v110}%mdk%mdk + +%mdk-data-line={5668} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5668} +\item\mdline{5668}Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously.%mdk + +%mdk-data-line={5674} +\item\mdline{5674}Add \mdline{5674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5674} field to stream messages sent by the server.%mdk + +%mdk-data-line={5675} +\item\mdline{5675}Add \mdline{5675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5675} RPC to query the P4Runtime API version implemented by the +server.%mdk + +%mdk-data-line={5677} +\item\mdline{5677}Support wildcard reads for multicast groups and clone sessions.%mdk + +%mdk-data-line={5678} +\item\mdline{5678}Support for modifying direct resources of const tables.%mdk + +%mdk-data-line={5679} +\item\mdline{5679}Support P4 user-defined types for Packet IO metadata fields.%mdk + +%mdk-data-line={5680} +\item\mdline{5680}Clarify consistency requirements for \mdline{5680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5680} and \mdline{5680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5680} RPCs.%mdk + +%mdk-data-line={5681} +\item\mdline{5681}Add Appendix providing implementation advice for avoiding common pitfalls: + +%mdk-data-line={5682} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5682} +\item\mdline{5682}advice on setting gRPC Metadata Maximum Size%mdk + +%mdk-data-line={5683} +\item\mdline{5683}advice on setting gRPC Server Maximum Receive Message Size%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={5684} +\item\mdline{5684}Clarify limitations on supported types for \mdline{5684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{5684}, action \mdline{5684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{5684}, and +Packet IO metadata fields.%mdk + +%mdk-data-line={5686} +\item\mdline{5686}Clarify that reading entire forwarding state with empty \mdline{5686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5686} is not +supported.%mdk + +%mdk-data-line={5688} +\item\mdline{5688}Document that \mdline{5688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5688} need only be supported when applied to +type declarations in P4.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5691} +\subsection{\mdline{5691}A.2.\hspace*{0.5em}\mdline{5691}P4 Annotations}\label{sec-p4-annotations}%mdk%mdk + +%mdk-data-line={5693} +\noindent\mdline{5693}Table\mdline{5693}~\mdref{tab-p4-annotations}{\mdcaptionlabel{7}}\mdline{5693} lists P4\mdline{5693}\mdsub{16}\mdline{5693} annotations introduced primarily for +the purpose of adding features for the P4Runtime API.%mdk + +%mdk-data-line={5696} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{5698} Annotation}}&\multicolumn{1}{|c|}{{\bfseries\mdline{5698} Description}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{5700} \mdline{5700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{5700}}&\multicolumn{1}{|l|}{\mdline{5700} See section\mdline{5700}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{5700}}\\ +\multicolumn{1}{|l}{\mdline{5701} \mdline{5701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5701}}&\multicolumn{1}{|l|}{\mdline{5701} See section\mdline{5701}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{5701}}\\ +\multicolumn{1}{|l}{\mdline{5702} \mdline{5702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{5702}}&\multicolumn{1}{|l|}{\mdline{5702} See section\mdline{5702}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{5702}}\\ +\multicolumn{1}{|l}{\mdline{5703} \mdline{5703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{5703}}&\multicolumn{1}{|l|}{\mdline{5703} See section\mdline{5703}~\mdref{sec-id-allocation}{6.3}\mdline{5703}}\\ +\multicolumn{1}{|l}{\mdline{5704} \mdline{5704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{5704}}&\multicolumn{1}{|l|}{\mdline{5704} See sections\mdline{5704}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{5704},\mdline{5704}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{5704}}\\ +\multicolumn{1}{|l}{\mdline{5705} \mdline{5705}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{5705}}&\multicolumn{1}{|l|}{\mdline{5705} See section\mdline{5705}~\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1}\mdline{5705}}\\ +\multicolumn{1}{|l}{\mdline{5706} \mdline{5706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5706}}&\multicolumn{1}{|l|}{\mdline{5706} See sections\mdline{5706}~\mdref{sec-user-defined-types}{8.5.6}\mdline{5706},\mdline{5706}~\mdref{sec-translation-of-port-numbers}{18.1.1}\mdline{5706}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={5708} +\mdhr{}%mdk + +%mdk-data-line={5709} +\noindent\mdline{5709}\mdcaption{\textbf{Table~\mdcaptionlabel{7}.}~\mdcaptiontext{P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-annotations}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={5712} +\subsection{\mdline{5712}A.3.\hspace*{0.5em}\mdline{5712}A More Complex Value Set Example}\label{sec-value-set-example}%mdk%mdk + +%mdk-data-line={5714} +\noindent\mdline{5714}This section includes a more complex Value Set example, with multiple matches of +different kinds.%mdk + +%mdk-data-line={5717} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5718} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5727} +\noindent\mdline{5727}This P4 Value Set declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={5730} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5731} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5758} +\noindent\mdline{5758}A P4Runtime client can set the membership for this Value Set with \mdline{5758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5758} +messages similar to this one:%mdk + +%mdk-data-line={5761} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5762} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xac}~\}\\ +~~~~~~\}\\ +~~~~~~{\mdcolor{darkgreen}\#~match~for~field\_id~2~is~missing~=\textgreater{}~don't~care~match}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xdc}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~~~ternary~\{~value:~{\mdcolor{purple}0x88}~mask:~{\mdcolor{purple}8}f~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5796} +\subsection{\mdline{5796}A.4.\hspace*{0.5em}\mdline{5796}Guidelines for Implementations}\label{sec-guidelines-for-implementations}%mdk%mdk + +%mdk-data-line={5798} +\noindent\mdline{5798}This section contains practical advice for implementing P4Runtime clients and +servers.%mdk + +%mdk-data-line={5801} +\subsubsection{\mdline{5801}A.4.1.\hspace*{0.5em}\mdline{5801}gRPC Metadata Maximum Size}\label{sec-grpc-metadata-maximum-size}%mdk%mdk + +%mdk-data-line={5803} +\noindent\mdline{5803}In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the \mdline{5804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{5804} gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the \mdline{5805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5805} P4Runtime RPC. The \mdline{5805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5805} RPC +returns an individual error for every item in a batch (see Section +\mdline{5807}\mdref{sec-write-rpc}{12}\mdline{5807}), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +\mdline{5809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{5809} error, without any of the individual errors.%mdk + +%mdk-data-line={5811} +\mdline{5811}To fix this problem, one can set the \mdline{5811}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{5811} option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it\mdline{5813}'\mdline{5813}s +limit, as only the receiving side\mdline{5814}'\mdline{5814}s limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every \mdline{5816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5816}, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +\mdline{5818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}8192~+~MAX\_UPDATES\_PER\_WRITE~*~100}}}\mdline{5818} bytes of metadata.%mdk + +%mdk-data-line={5820} +\mdline{5820}For example, in C++, one can create a client channel as follows:%mdk + +%mdk-data-line={5821} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5822} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}~=~{\mdcolor{purple}100};\\ +::{\mdcolor{navy}grpc::}ChannelArguments~arguments;\\ +arguments{\bfseries{\mdcolor{navy}.}}SetInt({\mdcolor{teal}GRPC\_ARG\_MAX\_METADATA\_SIZE},~{\mdcolor{purple}8192}~+~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}*{\mdcolor{purple}100});\\ +{\bfseries{\mdcolor{navy}return}}~{\mdcolor{navy}grpc::}CreateCustomChannel(address,~credentials,~arguments);}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5828} +\subsubsection{\mdline{5828}A.4.2.\hspace*{0.5em}\mdline{5828}gRPC Server Maximum Receive Message Size}\label{sec-grpc-server-maximum-receive-message-size}%mdk%mdk + +%mdk-data-line={5830} +\noindent\mdline{5830}At the time of writing, the default maximum receive message size in gRPC is 4MB +\mdline{5831}\textemdash{}\mdline{5831} while the default maximum send message size is unlimited. This can be a +problem for the \mdline{5832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5832} RPC, since for some targets the +binary \mdline{5833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5833} can exceed 4MB, in which case by default the P4Runtime +server would return an \mdline{5834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5834} error. To a lesser extent, this may +affect the \mdline{5835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5835} RPC as well, in case of extremely large batches.%mdk + +%mdk-data-line={5837} +\mdline{5837}To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of \mdline{5839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5839} for their target(s). This can be done by +setting the \mdline{5840}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_receive\_message\_length}}}\mdline{5840} when building the gRPC server.%mdk + +%mdk-data-line={5842} +\mdline{5842}For example, in C++, one can set the maximum receive message size as follows:%mdk + +%mdk-data-line={5843} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5844} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE}~=~{\mdcolor{purple}128}~*~{\mdcolor{purple}1024}~*~{\mdcolor{purple}1024};~~{\mdcolor{darkgreen}//~128MB}\\ +::{\mdcolor{navy}grpc::}ServerBuilder~server\_builder;\\ +builder{\bfseries{\mdcolor{navy}.}}AddListeningPort({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});\\ +builder{\bfseries{\mdcolor{navy}.}}RegisterService({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});~~{\mdcolor{darkgreen}//~register~P4Runtime~service}\\ +builder{\bfseries{\mdcolor{navy}.}}SetMaxReceiveMessageSize({\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE});\\ +builder{\bfseries{\mdcolor{navy}.}}BuildAndStart();}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5852} +\noindent\mdline{5852}On the client side, we recommend that P4Runtime clients do not use \mdline{5852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5852} +batches larger than the default maximum receive message size (4MB)\mdline{5853} \mdline{5853}\textemdash{}\mdline{5853} in case +the server did not deem necessary to increase the default value\mdline{5854} \mdline{5854}\textemdash{}\mdline{5854}, unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB).%mdk + +%mdk-data-line={5860;build/P4Runtime-Spec-bib.bbl.mdk:1} +%mdk-data-line={5860;build/P4Runtime-Spec-bib.bbl.mdk:2} +\mdsetrefname{References}%mdk +{\mdbibindent{0}%mdk +\begin{thebibliography}{37}%mdk +\label{sec-bibliography}%mdk + +%mdk-data-line={references.bib:68} +\bibitem{p4spec}\mdbibitemlabel{{}[1]}\textquotedblleft{}$P4_{16}$ 1.2.0 Specification.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html}}.\label{p4spec}%mdk%mdk + +%mdk-data-line={references.bib:134} +\bibitem{rfc2698}\mdbibitemlabel{{}[2]}\textquotedblleft{}A Two Rate Three Color Marker.\textquotedblright{} \href{https://tools.ietf.org/html/rfc2698}{{\ttfamily https://\hspace{0pt}tools.\hspace{0pt}ietf.\hspace{0pt}org/\hspace{0pt}html/\hspace{0pt}rfc2698}}.\label{rfc2698}%mdk%mdk + +%mdk-data-line={references.bib:32} +\bibitem{p4complextypes}\mdbibitemlabel{{}[3]}\textquotedblleft{}Complex Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-p4-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}p4-\hspace{0pt}type}}.\label{p4complextypes}%mdk%mdk + +%mdk-data-line={references.bib:37} +\bibitem{protodefaults}\mdbibitemlabel{{}[4]}\textquotedblleft{}Default Values for Protobuf 3 ($proto3$) Fields.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23default}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}default}}.\label{protodefaults}%mdk%mdk + +%mdk-data-line={references.bib:78} +\bibitem{p4enums}\mdbibitemlabel{{}[5]}\textquotedblleft{}Enums in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-enum-types}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}enum-\hspace{0pt}types}}.\label{p4enums}%mdk%mdk + +%mdk-data-line={references.bib:119} +\bibitem{apiversioning}\mdbibitemlabel{{}[6]}\textquotedblleft{}Google Cloud APIs Versioning.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning}}.\label{apiversioning}%mdk%mdk + +%mdk-data-line={references.bib:124} +\bibitem{apiversioningbackwardscompatibility}\mdbibitemlabel{{}[7]}\textquotedblleft{}Google Cloud APIs Versioning - Backwards-Compatibility.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning\%23backwards_compatibility}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning\#\hspace{0pt}backwards\_\hspace{0pt}compatibility}}.\label{apiversioningbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:149} +\bibitem{grpcauth}\mdbibitemlabel{{}[8]}\textquotedblleft{}gRPC Authentication.\textquotedblright{} \href{https://grpc.io/docs/guides/auth.html}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}guides/\hspace{0pt}auth.\hspace{0pt}html}}.\label{grpcauth}%mdk%mdk + +%mdk-data-line={references.bib:7} +\bibitem{grpc}\mdbibitemlabel{{}[9]}\textquotedblleft{}gRPC Main Site.\textquotedblright{} \href{https://grpc.io}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io}}.\label{grpc}%mdk%mdk + +%mdk-data-line={references.bib:144} +\bibitem{grpcstreamc}\mdbibitemlabel{{}[10]}\textquotedblleft{}gRPC Streaming RPCs in C++.\textquotedblright{} \href{https://grpc.io/docs/tutorials/basic/c.html\%23streaming-rpcs}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}tutorials/\hspace{0pt}basic/\hspace{0pt}c.\hspace{0pt}html\#\hspace{0pt}streaming-\hspace{0pt}rpcs}}.\label{grpcstreamc}%mdk%mdk + +%mdk-data-line={references.bib:114} +\bibitem{p4newtypes}\mdbibitemlabel{{}[11]}\textquotedblleft{}Introducing New Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-newtype}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}newtype}}.\label{p4newtypes}%mdk%mdk + +%mdk-data-line={references.bib:139} +\bibitem{p4matchtypes}\mdbibitemlabel{{}[12]}\textquotedblleft{}Match Types in P4.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-match-kind-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}match-\hspace{0pt}kind-\hspace{0pt}type}}.\label{p4matchtypes}%mdk%mdk + +%mdk-data-line={references.bib:174} +\bibitem{p4concurrency}\mdbibitemlabel{{}[13]}\textquotedblleft{}P4 Concurrency Model.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-concurrency}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}concurrency}}.\label{p4concurrency}%mdk%mdk + +%mdk-data-line={references.bib:1} +\bibitem{p4runtimerepo}\mdbibitemlabel{{}[14]}\textquotedblleft{}p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.\textquotedblright{} \href{https://github.com/p4lang/p4runtime}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4runtime}}.\label{p4runtimerepo}%mdk%mdk + +%mdk-data-line={references.bib:42} +\bibitem{pirepo}\mdbibitemlabel{{}[15]}\textquotedblleft{}p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.\textquotedblright{} \href{https://github.com/p4lang/PI}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}PI}}.\label{pirepo}%mdk%mdk + +%mdk-data-line={references.bib:109} +\bibitem{p4apiwgcharter}\mdbibitemlabel{{}[16]}\textquotedblleft{}P4.org API Working Group Charter.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4_API_WG_charter.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4\_\hspace{0pt}API\_\hspace{0pt}WG\_\hspace{0pt}charter.\hspace{0pt}html}}.\label{p4apiwgcharter}%mdk%mdk + +%mdk-data-line={references.bib:154} +\bibitem{p4actionannotations}\mdbibitemlabel{{}[17]}\textquotedblleft{}P4 Standard Annotations on Table Actions.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-table-action-anno}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}action-\hspace{0pt}anno}}.\label{p4actionannotations}%mdk%mdk + +%mdk-data-line={references.bib:73} +\bibitem{psa}\mdbibitemlabel{{}[18]}\textquotedblleft{}Portable Switch Architecture Specification (v1.1.0).\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html}}.\label{psa}%mdk%mdk + +%mdk-data-line={references.bib:189} +\bibitem{protooneofbackwardscompatibility}\mdbibitemlabel{{}[19]}\textquotedblleft{}Protobuf OneOf Backwards-Compatibility Issues.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23backwards-compatibility-issues}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}backwards-\hspace{0pt}compatibility-\hspace{0pt}issues}}.\label{protooneofbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:12} +\bibitem{proto}\mdbibitemlabel{{}[20]}\textquotedblleft{}Protocol Buffers Main Site.\textquotedblright{} \href{https://developers.google.com/protocol-buffers}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers}}.\label{proto}%mdk%mdk + +%mdk-data-line={references.bib:159} +\bibitem{psaactionselector}\mdbibitemlabel{{}[21]}\textquotedblleft{}PSA Action Selector.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-action-selector}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}action-\hspace{0pt}selector}}.\label{psaactionselector}%mdk%mdk + +%mdk-data-line={references.bib:169} +\bibitem{psaatomicityofcontrolplaneops}\mdbibitemlabel{{}[22]}\textquotedblleft{}PSA Atomicity of Control Plane Operations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-atomicity-of-control-plane-api-operations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}atomicity-\hspace{0pt}of-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}api-\hspace{0pt}operations}}.\label{psaatomicityofcontrolplaneops}%mdk%mdk + +%mdk-data-line={references.bib:179} +\bibitem{psatranslation}\mdbibitemlabel{{}[23]}\textquotedblleft{}PSA Data Plane vs Control Plane Types.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-data-plane-vs-control-plane-values}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}data-\hspace{0pt}plane-\hspace{0pt}vs-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}values}}.\label{psatranslation}%mdk%mdk + +%mdk-data-line={references.bib:164} +\bibitem{psaemptygroupactionappendix}\mdbibitemlabel{{}[24]}\textquotedblleft{}PSA Empty Group Action Appendix.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23appendix-empty-action-selector-groups}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}appendix-\hspace{0pt}empty-\hspace{0pt}action-\hspace{0pt}selector-\hspace{0pt}groups}}.\label{psaemptygroupactionappendix}%mdk%mdk + +%mdk-data-line={references.bib:58} +\bibitem{p4selectexpr}\mdbibitemlabel{{}[25]}\textquotedblleft{}Select Expressions in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-select}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}select}}.\label{p4selectexpr}%mdk%mdk + +%mdk-data-line={references.bib:129} +\bibitem{semver}\mdbibitemlabel{{}[26]}\textquotedblleft{}Semantic Versioning.\textquotedblright{} \href{https://semver.org/}{{\ttfamily https://\hspace{0pt}semver.\hspace{0pt}org/\hspace{0pt}}}.\label{semver}%mdk%mdk + +%mdk-data-line={references.bib:98} +\bibitem{protostatus}\mdbibitemlabel{{}[27]}\textquotedblleft{}Status.proto:the Protobuf Status Message.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}src/\hspace{0pt}proto/\hspace{0pt}grpc/\hspace{0pt}status/\hspace{0pt}status.\hspace{0pt}proto}}.\label{protostatus}%mdk%mdk + +%mdk-data-line={references.bib:63} +\bibitem{p4revisions110}\mdbibitemlabel{{}[28]}\textquotedblleft{}Summary of Changes Made in $P4_{16}$ Version 1.1.0.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-summary-of-changes-made-in-version-110}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}summary-\hspace{0pt}of-\hspace{0pt}changes-\hspace{0pt}made-\hspace{0pt}in-\hspace{0pt}version-\hspace{0pt}110}}.\label{p4revisions110}%mdk%mdk + +%mdk-data-line={references.bib:48} +\bibitem{p4tableproperties}\mdbibitemlabel{{}[29]}\textquotedblleft{}Table Properties in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-table-props}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}props}}.\label{p4tableproperties}%mdk%mdk + +%mdk-data-line={references.bib:83} +\bibitem{protoany}\mdbibitemlabel{{}[30]}\textquotedblleft{}The Any Protobuf Message.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23any}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}any}}.\label{protoany}%mdk%mdk + +%mdk-data-line={references.bib:88} +\bibitem{grpcstatus}\mdbibitemlabel{{}[31]}\textquotedblleft{}The gRPC $Status$ Class.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/status.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}impl/\hspace{0pt}codegen/\hspace{0pt}status.\hspace{0pt}h}}.\label{grpcstatus}%mdk%mdk + +%mdk-data-line={references.bib:104} +\bibitem{grpcerrordetails}\mdbibitemlabel{{}[32]}\textquotedblleft{}The gRPC C++ Error Details Library.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/support/error_details.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}support/\hspace{0pt}error\_\hspace{0pt}details.\hspace{0pt}h}}.\label{grpcerrordetails}%mdk%mdk + +%mdk-data-line={references.bib:93} +\bibitem{grpcstatuscodes}\mdbibitemlabel{{}[33]}\textquotedblleft{}The gRPC Canonical Status Codes.\textquotedblright{} \href{https://developers.google.com/maps-booking/reference/grpc-api/status_codes}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}maps-\hspace{0pt}booking/\hspace{0pt}reference/\hspace{0pt}grpc-\hspace{0pt}api/\hspace{0pt}status\_\hspace{0pt}codes}}.\label{grpcstatuscodes}%mdk%mdk + +%mdk-data-line={references.bib:22} +\bibitem{openconfig}\mdbibitemlabel{{}[34]}\textquotedblleft{}The OpenConfig Project.\textquotedblright{} \href{http://openconfig.net}{{\ttfamily http://\hspace{0pt}openconfig.\hspace{0pt}net}}.\label{openconfig}%mdk%mdk + +%mdk-data-line={references.bib:184} +\bibitem{protomessagedifferencer}\mdbibitemlabel{{}[35]}\textquotedblleft{}The Protobuf MessageDifferencer in the C++ API.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.util.message_differencer}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}reference/\hspace{0pt}cpp/\hspace{0pt}google.\hspace{0pt}protobuf.\hspace{0pt}util.\hspace{0pt}message\_\hspace{0pt}differencer}}.\label{protomessagedifferencer}%mdk%mdk + +%mdk-data-line={references.bib:27} +\bibitem{stratum}\mdbibitemlabel{{}[36]}\textquotedblleft{}The Stratum Project.\textquotedblright{} \href{https://stratumproject.org/}{{\ttfamily https://\hspace{0pt}stratumproject.\hspace{0pt}org/\hspace{0pt}}}.\label{stratum}%mdk%mdk + +%mdk-data-line={references.bib:53} +\bibitem{p4valuesets}\mdbibitemlabel{{}[37]}\textquotedblleft{}Value Sets in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.0.html\%23sec-value-set}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}value-\hspace{0pt}set}}.\label{p4valuesets}%mdk%mdk +\par%mdk +\end{thebibliography}}%mdk%mdk +}%mdk + + +\end{document} diff --git a/spec/v1.1.0/ellipse.sty b/spec/v1.1.0/ellipse.sty new file mode 100644 index 00000000..7c0ecb3e --- /dev/null +++ b/spec/v1.1.0/ellipse.sty @@ -0,0 +1,318 @@ +%% +%% This is file `ellipse.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ellipse.dtx (with options: `package') +%% +%% Copyright (C) 2015 +%% Daan Leijen +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". +%% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{ellipse} + [2004/11/05 v1.0 .dtx ellipse file] +\RequirePackage{pict2e} + +\providecommand*\pIIe@csedef[1]{\expandafter\edef\csname #1\endcsname} +\newcommand*\pIIe@ellip@csqrt[3]{% + \@ovxx=#1\relax + \ifdim\@ovxx<\z@\@ovxx-\@ovxx\fi + \@ovyy=#2\relax + \ifdim\@ovyy<\z@\@ovyy-\@ovyy\fi + \edef\pIIe@csname{@csqrt(\number\@ovxx,\number\@ovyy)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@ellip@csqrt@% + \pIIe@csedef{\pIIe@csname}{\the\dimen@}% + #3\dimen@ + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} +\newcommand*\pIIe@ellip@csqrt@{% + \@ovdx\@ovxx + \advance\@ovdx by \@ovyy + \dimen@0.7071067\@ovdx + \ifdim\dimen@<\@ovyy\dimen@\@ovyy\fi + \ifdim\dimen@<\@ovxx\dimen@\@ovxx\fi + \ifdim\@ovdx<128\p@ + \edef\@tempa{\strip@pt\@ovxx}% + \@ovxx\@tempa\@ovxx + \edef\@tempa{\strip@pt\@ovyy}% + \@ovyy\@tempa\@ovyy + \advance\@ovxx by \@ovyy + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \fi +} + +\newcommand*\pIIe@atan@{% + \@tempdima\dimen@ + \@tempdimb\@tempdima + \ifdim\@tempdimb<\z@\@tempdimb-\@tempdimb\fi + \dimen@0.0663\@tempdimb + \advance\dimen@ 0.2447pt\relax + \advance\@tempdimb -1pt\relax + \edef\@tempa{\strip@pt\@tempdimb}% + \dimen@\@tempa\dimen@ + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \dimen@-\dimen@ + \advance\dimen@ 0.7853\@tempdima +} + +\newcommand*\pIIe@atantwo[3]{% + \edef\pIIe@csname{@atan2(\number\dimexpr#1\relax,\number\dimexpr#2\relax)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@atantwo@{#1}{#2}{#3}% + \pIIe@csedef{\pIIe@csname}{\the\dimexpr#3\relax}% + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} + +\newcommand*\pIIe@atantwo@[3]{% + \@tempdima\dimexpr#2\relax + \@tempdimb\dimexpr#1\relax + \ifdim\@tempdima=\z@\relax + \ifdim\@tempdimb>\z@\relax\dimen@90\p@ + \else\ifdim\@tempdimb<\z@\relax\dimen@-90\p@ + \else\dimen@0\p@ + \fi\fi + \else + \@tempdimd\z@ + \ifdim\@tempdima<\z@\relax + \ifdim\@tempdimb<\z@\relax\@tempdimd-180\p@ + \else\@tempdimd180\p@ + \fi + \fi + \dimen@\dimexpr1pt * \@tempdimb/\@tempdima\relax + \@tempdimc\dimen@ + \ifdim\@tempdimc<\z@\relax\@tempdimc-\@tempdimc\fi + \ifdim\@tempdimc>\p@\relax + \dimen@\dimexpr1pt * \@tempdima/\@tempdimb\relax + \ifdim\dimen@<\z@\relax\def\@tempsign{-}\else\def\@tempsign{}\fi + \pIIe@atan@ + \dimen@-\dimen@ + \advance\dimen@ by \@tempsign1.5707pt\relax + \else + \pIIe@atan@ + \fi + \dimen@57.29578\dimen@ + \advance\dimen@ by \@tempdimd + \fi + #3\dimen@% +} + +\newcommand*\pIIe@noneto[2]{} +\newcommand*\pIIe@ellip@sincost@[2]{% + \CalculateSin{#1}% + \CalculateCos{#1}% + \@tempdima\UseSin{#1}\p@ + \@tempdimb\UseCos{#1}\p@ + \ifdim\@tempdima=\p@\relax + \pIIe@csedef{@ellipsin#2}{1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else\ifdim\@tempdima=-\p@\relax + \pIIe@csedef{@ellipsin#2}{-1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else + \@tempdimc\@ellipratio\dimexpr1pt * \@tempdima/\@tempdimb\relax + %\typeout{ i#2=\the\@tempdimc, sin(#1)=\the\@tempdima}% + \pIIe@ellip@csqrt{\p@}{\@tempdimc}\@tempdimd + \ifdim\@tempdimb<\z@\relax\@tempdimd-\@tempdimd\fi + \pIIe@csedef{@ellipsin#2}{\strip@pt\dimexpr1pt * \@tempdimc/\@tempdimd\relax}% + \pIIe@csedef{@ellipcos#2}{\strip@pt\dimexpr1pt * \p@/\@tempdimd\relax}% + \fi\fi +} + +\newcommand*\pIIe@ellip@sincost[2]{% + %\typeout{ calc sin cos: angles (#1,#2), radii: (\the\@ovro,\the\@ovri)}% + \edef\@ellipratio{\strip@pt\dimexpr1pt * \@ovro/\@ovri\relax}% + \pIIe@ellip@sincost@{#1}{one}% + \pIIe@ellip@sincost@{#2}{two}% + %\typeout{ sincos(a=#1)=(\@ellipsinone,\@ellipcosone), sincos(a=#2)=(\@ellipsintwo,\@ellipcostwo), }% +} +\newcommand*\pIIe@omega[3]{% + \@tempdima\csname @ellipcos#3\endcsname\@ovro + \advance\@tempdima by #1\relax + \@tempdimb\csname @ellipsin#3\endcsname\@ovri + \advance\@tempdimb by #2\relax +} + +\newcommand*\pIIe@omegai[1]{% + \@tempdimc\csname @ellipsin#1\endcsname\@ovro + \@tempdimc-\@tempdimc + \@tempdimd\csname @ellipcos#1\endcsname\@ovri +} + +\newcommand*\pIIe@ellip@kappa{% + \@ovyy\@ellipsinone\p@ + \@ovxx\@ellipcosone\p@ + \@tempdima\@ellipcostwo\@ovyy + \@tempdima-\@tempdima + \advance\@tempdima by \@ellipsintwo\@ovxx + \@tempdimb\@ellipcostwo\@ovxx + \advance\@tempdimb by \@ellipsintwo\@ovyy + \ifdim\@tempdima=\z@\relax + \edef\@ellipkappa{0}% + \else + \dimen@\dimexpr1pt - \@tempdimb\relax + \dimen@\dimexpr1pt * \dimen@/\@tempdima\relax + \pIIe@ellip@csqrt{2\p@}{1.73205\dimen@}{\dimen@}% + \advance\dimen@ by -\p@ + \divide\dimen@ by 3% + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \edef\@ellipkappa{\strip@pt\dimen@}% + \fi + %\typeout{ calculated kappa: \@ellipkappa}% +} + +\newcommand*\pIIe@elliparc@[5]{% + %\typeout{elliparc: #1, center: (#2, #3), radius (\the\@ovro, \the\@ovri),angle (#4, #5)}% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \pIIe@ellip@sincost{#4}{#5}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@t[5]{% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \CalculateSin{#4}\CalculateCos{#4}% + \edef\@ellipsinone{\UseSin{#4}}% + \edef\@ellipcosone{\UseCos{#4}}% + \CalculateSin{#5}\CalculateCos{#5}% + \edef\@ellipsintwo{\UseSin{#5}}% + \edef\@ellipcostwo{\UseCos{#5}}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@draw[2]{% + \pIIe@ellip@kappa% + \pIIe@omega{#1}{#2}{one}% + %\typeout{ point one: (\the\@tempdima,\the\@tempdimb)}% + \@ellip@startto\@tempdima\@tempdimb + \pIIe@omegai{one}% + \advance\@tempdima by \@ellipkappa\@tempdimc + \advance\@tempdimb by \@ellipkappa\@tempdimd + \pIIe@add@nums\@tempdima\@tempdimb + %\typeout{ control one: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@omega{#1}{#2}{two}% + \pIIe@omegai{two}% + \@tempdimc\@ellipkappa\@tempdimc + \@tempdimd\@ellipkappa\@tempdimd + \@tempdimc-\@tempdimc + \@tempdimd-\@tempdimd + \advance\@tempdimc by \@tempdima + \advance\@tempdimd by \@tempdimb + \pIIe@add@nums\@tempdimc\@tempdimd + %\typeout{ control two: (\the\@tempdimc,\the\@tempdimd)}% + \pIIe@add@CP\@tempdima\@tempdimb + %\typeout{ point two: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@addtoGraph\pIIe@curveto@op +} +\newcommand*\pIIe@elliparc[7][0]{% + \@ovro #4\relax + \@ovri #5\relax + \iffalse%dim\@ovro=\@ovri + \pIIe@arc[#1]{#2}{#3}{#4}{#6}{#7} + \else + \ifdim \@ovro<\z@ \pIIe@badcircarg\else + \ifdim \@ovri<\z@ \pIIe@badcircarg\else + \@arclen #7\p@ \advance\@arclen -#6\p@ + \ifdim \@arclen<\z@ \def\@tempsign{-}\else\def\@tempsign{}\fi + \ifdim \@tempsign\@arclen>720\p@ + \PackageWarning {ellipse}{The arc angle is reduced to -720..720}% + \@whiledim \@tempsign\@arclen>720\p@ \do {\advance\@arclen-\@tempsign360\p@}% + \@tempdima #6\p@ \advance\@tempdima \@arclen + \edef\@angleend{\strip@pt\@tempdima}% + \pIIe@@elliparc{#1}{#2}{#3}{#6}{\@angleend}% + \else + \pIIe@@elliparc{#1}{#2}{#3}{#6}{#7}% + \fi + \fi + \fi + \fi +} +\newcommand*\pIIe@@elliparc[5]{% + \begingroup + \ifdim \@tempsign\@arclen>90\p@ + \divide\@arclen 2% + \@tempdima #4\p@\advance\@tempdima by \@arclen + \edef\@anglemid{\strip@pt\@tempdima}% + \def\@tempa{\pIIe@@elliparc{#1}{#2}{#3}{#4}}% + \expandafter\@tempa\expandafter{\@anglemid}% + \def\@tempa{\pIIe@@elliparc{2}{#2}{#3}}% + \expandafter\@tempa\expandafter{\@anglemid}{#5}% + \else + \pIIe@elliparc@{#1}{#2}{#3}{#4}{#5}% + \fi + \endgroup +}% + +\newcommand*\pIIeelliparc[7][0]{% + \@killglue + \pIIe@elliparc[#1]{#2\unitlength}{#3\unitlength}{#4\unitlength}{#5\unitlength}{#6}{#7}% + \ignorespaces% +} +\ifx\undefined\elliparc\else + \PackageWarning{ellipse}{\protect\elliparc\space is redefined}% +\fi +\let\elliparc\pIIeelliparc + +\newcommand*\pIIeearc + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\newcommand*\pIIe@earc@[3][0,360]{\pIIe@earc@@(#1){#2}{#3}} +\def\pIIe@earc@@(#1,#2)#3#4{% + \if@tempswa + \pIIe@moveto\z@\z@ + \pIIe@elliparc{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@closepath\pIIe@fillGraph + \else + \pIIe@elliparc[1]{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@strokeGraph + \fi} +\ifx\undefined\earc\else + \PackageWarning{ellipse}{\protect\earc\space is redefined}% +\fi +\let\earc\pIIeearc + +\newcommand*\pIIeellipse + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\let\ellipse\pIIeellipse + +\endinput +%% +%% End of file `ellipse.sty'. diff --git a/spec/v1.1.0/embedded-plus-single-remote-controller.png b/spec/v1.1.0/embedded-plus-single-remote-controller.png new file mode 100644 index 00000000..2e0f1803 Binary files /dev/null and b/spec/v1.1.0/embedded-plus-single-remote-controller.png differ diff --git a/spec/v1.1.0/embedded-plus-single-remote-controller.svg b/spec/v1.1.0/embedded-plus-single-remote-controller.svg new file mode 100644 index 00000000..9fe2ce9c --- /dev/null +++ b/spec/v1.1.0/embedded-plus-single-remote-controller.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spec/v1.1.0/embedded-plus-two-remote-controllers.png b/spec/v1.1.0/embedded-plus-two-remote-controllers.png new file mode 100644 index 00000000..b6dc04fc Binary files /dev/null and b/spec/v1.1.0/embedded-plus-two-remote-controllers.png differ diff --git a/spec/v1.1.0/embedded-plus-two-remote-controllers.svg b/spec/v1.1.0/embedded-plus-two-remote-controllers.svg new file mode 100644 index 00000000..0f97ba38 --- /dev/null +++ b/spec/v1.1.0/embedded-plus-two-remote-controllers.svg @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + + + Entities + + + + + + + \ No newline at end of file diff --git a/spec/v1.1.0/embedded-plus-two-remote-ha-controllers.png b/spec/v1.1.0/embedded-plus-two-remote-ha-controllers.png new file mode 100644 index 00000000..f663e9bf Binary files /dev/null and b/spec/v1.1.0/embedded-plus-two-remote-ha-controllers.png differ diff --git a/spec/v1.1.0/embedded-plus-two-remote-ha-controllers.svg b/spec/v1.1.0/embedded-plus-two-remote-ha-controllers.svg new file mode 100644 index 00000000..710111fa --- /dev/null +++ b/spec/v1.1.0/embedded-plus-two-remote-ha-controllers.svg @@ -0,0 +1,510 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + Master (Active) + + + + + + Slave (Standby) + + + + + + + \ No newline at end of file diff --git a/spec/v1.1.0/error-report.png b/spec/v1.1.0/error-report.png new file mode 100644 index 00000000..766cb77f Binary files /dev/null and b/spec/v1.1.0/error-report.png differ diff --git a/spec/v1.1.0/error-report.svg b/spec/v1.1.0/error-report.svg new file mode 100644 index 00000000..a2709a72 --- /dev/null +++ b/spec/v1.1.0/error-report.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StatusCode error_code_; // canonical error codestring error_message_;string binary_error_details_; // serialized google.rpc.Status + + + + + + + + + + + + + google.rpc.Status + + + + + + int32 error_code; // canonical error codestring message;repeated Any details; // P4Error + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + + + p4.Error + + + + + + p4.Error + + + + + + + + + + + + + + + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + grpc::Status + + + + + + + \ No newline at end of file diff --git a/spec/v1.1.0/longbox.sty b/spec/v1.1.0/longbox.sty new file mode 100644 index 00000000..cab48934 --- /dev/null +++ b/spec/v1.1.0/longbox.sty @@ -0,0 +1,853 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longbox}[2015/12/01, Daan Leijen, Provides basic longbox that can break over pages] +\RequirePackage{options} + +\@ifclassloaded{beamer}{% + \newcommand\lb@savefootnotes{}% + \newcommand\lb@restorefootnotes{}% +}% +{\RequirePackage{footnote}% + \newcommand\lb@savefootnotes{\savenotes}% + \newcommand\lb@restorefootnotes{\spewnotes}% +} + + +% -------------------------------------------------------- +% Debugging +% -------------------------------------------------------- + +\newcommand*\lb@debug[1]{% + \ontoggle{lb@debug}{\typeout{longbox debug: #1}}% +} +\newcommand*\lb@typeout[1]{% + \ontoggle{lb@verbose}{\typeout{longbox: #1}}% +} +\newcommand*\lb@warncannotsplit{% + \PackageWarning{longbox}{Cannot split box; it seems you are using a non-splittable contents}% +} +\newcommand*\lb@warnbadsplit[1]{% + \PackageWarning{longbox}{Bad split (underful vbox by \the#1)}% +} + + +% -------------------------------------------------------- +% Utilities for LaTeX internals +% -------------------------------------------------------- + +% Suppress the indentation on the following paragraph +\providecommand\nofirstindent{\@afterindentfalse\@afterheading} + +% Suppress the paragraph skip on the following paragraph +\providecommand\nofirstparskip{\addvskip{-\parskip}} + +% In contrast to addvspace, addvskip is not suppressed in a minipage +\providecommand\addvskip[1]{% + \ifvmode + \ifdim\lastskip=\z@ + \vskip #1\relax + \else + \@tempskipb#1\relax\@xaddvskip + \fi + \else\@noitemerr\fi +} + + +% Skip to 0.3\baselineskip multiple taking prevdepth into account. +\newskip\lb@prevdepth +\newcommand\lb@skiptobaseline{% + \global\lb@prevdepth=-\@m\p@\relax + \ifvmode + \ifdim\lastskip=\z@\relax + \ifdim\prevdepth=-\@m\p@\else + \dimen@\prevdepth + % Calculate the modulus of the previous depth with 0.3|\baselineskip| in |\dimen@|. + \@tempcnta\prevdepth + \@tempskipa=0.3\baselineskip\relax + \@tempcntb=\@tempskipa\relax + \divide \@tempcnta by \@tempcntb + \dimen@\prevdepth + \advance\dimen@ -\@tempcnta\@tempskipa + % Skip back by that amount, and then skip by 0.3|\baselineskip|. + \vskip -\dimen@ + \vskip \@tempskipa\relax + \global\lb@prevdepth=\@tempskipa\relax + \fi + \fi + \fi +} + +% unvbox a box, and return a vbox with a given background color +% \unvcolorbox{}{} +\newcommand\unvcolorbox[2]{% + \ifoptionblank{#1}{\vbox{\unvbox#2}}{% + \lb@debug{vcolorbox: #1}% + \vbox{\offinterlineskip + \hbox to \z@{\vbox to \z@{\optioncolor{#1}\hrule\@width\wd#2\@height\ht#2\@depth\dp#2\vss}\hss}% + \unvbox#2% + }% + }% +} + +% create a vbox with a given background color +\newcommand\vcolorbox[2]{% + \eifblank{#1}{\vbox{#2}}{% + \setbox\z@=\vbox{#2}\relax + \unvcolorbox{#1}{\z@}% + }% +}% + +% -------------------------------------------------------- +% The following macros come from mdframed +% -------------------------------------------------------- + +% Determine the amount of free space left on the current page +\newlength\lb@freevspace +\newcommand*\lb@setfreevspace@page{% + \lb@debug{ determine free space}% + \bgroup\@nobreakfalse\addpenalty\z@\egroup% + \penalty\@M\relax\vskip 2\baselineskip\relax% + \penalty9999\relax\vskip -2\baselineskip\relax% + \penalty9999% + \ifdim\pagegoal=\maxdimen\relax% + \lb@freevspace=\vsize% + \else + \lb@freevspace=\dimexpr\pagegoal-\pagetotal-\parskip\relax% + \fi + \lb@debug{free space: \the\lb@freevspace, in page: \the\textheight, vsize=\the\vsize}% +} + +\newcommand*\lb@shiftdim[2]{% + %\letoption{#1}\lb@list + \expandafter\lb@setheadtail@#1,\relax + \eifblank{\lb@head}{}{\option@invoke{/longbox/@breakat-previous}{\lb@head}}% + #2\option{/longbox/@breakat-previous}% + \eifblank{\lb@tail}{}{\let#1\lb@tail}% push back tail +} +\def\lb@comma{,}% +\def\lb@setheadtail@#1,#2\relax{% + \def\lb@head{#1}% + \def\lb@tail{#2}% adds commas! +} + +\newcommand*\lb@setfreevspace{% + \eifblank{\lb@breakat}{\lb@setfreevspace@page}{% + \def\lb@eject{\par}%no eject + \lb@extrasplit=\z@\relax% + \lb@shiftdim{\lb@breakat}\lb@freevspace + \ifdim\lb@freevspace>\z@\else\lb@setfreevspace@page\fi + }% +} + + +% Suppress overfull-underfull vbox messages +\newcommand*\lb@ignorevbadness{% + \edef\lb@currentvbadness{\the\vbadness}% + \edef\lb@currentvfuzz{\the\vfuzz}% + \vbadness=\@M\relax% + \vfuzz=\maxdimen\relax% + \afterassignment\lb@restorevbadness +} +\newcommand*\lb@restorevbadness{% + \vbadness=\lb@currentvbadness\relax + \vfuzz=\lb@currentvfuzz\relax +} + + +% -------------------------------------------------------- +% The 'long vbox' (lvbox) environment collects long material +% into a long \vbox, instead of a \hbox like a lrbox in latex. +% The collected box can contain any box, minipage, lrbox, fbox etc, +% but not outer-par material like a figure. Footnotes can be +% dealt with useing lb@savefootnotes. +% +% The material is typeset in a \vbox according to a given width. +% inside the environment, the boolean 'inlvbox' is true. +% +% \begin{lvbox}{}{} +% -------------------------------------------------------- + +\newif\ifinlvbox +\newcommand\lvbox[4]{% + \setbox#1\vbox\bgroup + \begingroup + \inlvboxtrue + % reset defaults + \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\par\@@par + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + % set margin and linewidth + \leftmargin=#2\relax\rightmargin=#4\relax + \@totalleftmargin=\leftmargin% + %\leftskip=#2\relax\rightskip=#4\relax\@rightskip=#4\relax + \linewidth=#3\relax + % set primitive tex margins + \leftskip=\@totalleftmargin% + \rightskip=\rightmargin% + \@rightskip=\rightmargin% + \hsize=\dimexpr\@totalleftmargin+\linewidth+\rightmargin\relax + \columnwidth\hsize + \textwidth\hsize + \nofirstindent + %\nofirstparskip +} +\def\endlvbox{\endgroup\egroup} + + + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + + +\newsavebox\lb@headbox +\newsavebox\lb@savebox +\newsavebox\lb@mainbox + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@setbaseline[1]{% + %\typeout{ set baseline, \the\dp#1,\the\ht#1}% + \ifcase\lb@baseline% + \relax%bottom + \or%middle + \setbox#1=\vbox{\hbox{\lower \dimexpr(\dp#1 + \ht#1)/2 - \dp#1\relax\vbox{\unvbox#1}}}% + \or%top + \setbox#1=\vtop{\unvbox#1}% + \fi + %\typeout{ .new dim: \the\dp#1, \the\ht#1}% +} + + +\@ifundefined{define@key}{}% + {\define@key{longbox}{options}{\options{#1}\option{/longbox/adjust-options}}}% + +\newcommand*\lb@render@breakbox{% + %\typeout{render breakbox entry (in output routine), height=\the\bb@height}% + \bb@restorekeys{longbox}% + \lb@skiptop=\ifbb@isfirst\option{/longbox/skip-top}\else\option{/longbox/skip-break-top}\fi\relax + \lb@skipbottom=\ifbb@islast\option{/longbox/skip-bottom}\else\option{/longbox/skip-break-bottom}\fi\relax + \lb@skipbreaktop=\ifbb@isfirst 0pt\else\option{/longbox/skip-break-top}\fi + \lb@skipbreakbottom=\ifbb@islast 0pt\else\option{/longbox/skip-break-bottom}\fi + %\typeout{ render: skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom, break-top=\the\dimexpr\option{/longbox/skip-bottom}}% + \options{% + /longbox/@part-height=\bb@height + \lb@skipbreaktop + \lb@skipbreakbottom, + /longbox/@part-width=\option{/longbox/width} + \option{/longbox/skip-left} + \option{/longbox/skip-right},%\bb@width, + /longbox/@part-depth=0pt, + /longbox/@part-needtop=\ifbb@isfirst true\else false\fi, + /longbox/@part-needbottom=\ifbb@islast true\else false\fi, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-depth=\option{/longbox/@part-depth}, + }% + %\typeout{breakbox: width=\expandafter\the\option{/longbox/width}, \the\bb@width, \the\dimexpr\option{/longbox/@part-width}}% + \vbox{% + \kern -\lb@skipbreaktop% todo: move to breakbox? + \option{/longbox/render}% + \kern -\lb@skipbreakbottom + }% +} + +\newcommand*\lb@render@vbox[1]{% + \lb@debug{render vbox entry}% + \lb@restoreoptions + \lb@skiptop=\dimexpr\iftoggle{/longbox/@part-needtop}{\option{/longbox/skip-top}}{\option{/longbox/skip-break-top}}\relax + \lb@skipbottom=\dimexpr\iftoggle{/longbox/@part-needbottom}{\option{/longbox/skip-bottom}}{\option{/longbox/skip-break-bottom}}\relax + %\typeout{ skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom}% + % add top skip while maintaining the baseline. + \ifdim\lb@skiptop=\z@\relax\else + \setbox\z@=\vtop{\unvcopy#1}% + \dimen@=\ht\z@ + \setbox#1=\vbox{\offinterlineskip + \hrule width \z@ height \dimexpr\dimen@ + \lb@skiptop\relax depth -\dimen@ + \unvbox#1% + }% + \fi + % add bottom skip while maintaining the baseline. + \ifdim\lb@skipbottom=\z@\relax\else + \dimen@=\dp#1% + \setbox#1=\vbox{\offinterlineskip\unvbox#1\hrule width \z@ height -\dimen@ depth \dimexpr\dimen@ + \lb@skipbottom\relax}% + \fi + \lb@setbaseline{#1}% + \options{% + /longbox/@part-height=\dimexpr\ht#1 + \dp#1\relax, + /longbox/@part-width=\dimexpr\wd#1 + \option{/longbox/skip-left} + \option{/longbox/skip-right}\relax, + /longbox/@part-depth=\dp#1, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-depth=\option{/longbox/@part-depth} - \lb@skipbottom, + }% + %\typeout{ longbox: height=\the\dimexpr\option{/longbox/@content-box-height}, outer height=\the\dimexpr\option{/longbox/@part-height}\relax}% + % lower the box depending on vertical alignment + \ifcase\option{/longbox/vertical-align/@ord}\relax + \@tempdima\z@ + \or + %bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%middle + \@tempdima\dimexpr0.5\option{/longbox/@part-height} - \option{/longbox/@part-depth}\relax + \or%top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%text-bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%text-top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%super + \@tempdima=-0.9ex% + \or%sub + \@tempdima=0.7ex% + \else + \@tempdima\z@ + \fi + \advance\@tempdima by -\option{/longbox/raise}% + \option@invoke{/longbox/@lower}{\@tempdima}% + \noindent\hbox{\lower \@tempdima\vbox{\offinterlineskip + \hbox to \z@{% + \vbox to \z@{% + \hbox{\lower \option{/longbox/@part-height}\vbox{\offinterlineskip{\option{/longbox/render}}}}% + \vss}% + \hss + }% + \hbox{% + \ifdim\option{/longbox/skip-left}=\z@\else\hskip\option{/longbox/skip-left}\fi + \box#1% + \ifdim\option{/longbox/skip-right}=\z@\else\hskip\option{/longbox/skip-right}\fi + %$\box#1% + }% + }}% +} + +\newcommand*\lb@single@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} +\newcommand*\lb@first@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@middle@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@last@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand*\lb@env@start{% + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore +} + +\newcount\lb@usevbox +\newlength\lb@width +\newlength\lb@height +\newlength\lb@skiptop +\newlength\lb@skipright +\newlength\lb@skipbottom +\newlength\lb@skipleft +\newlength\lb@skipbreaktop +\newlength\lb@skipbreakbottom +\newlength\lb@outerwidth +\newlength\lb@extrasplit +\newcount\lb@textalign +\newcount\lb@baseline +\newtoggle{lb@baselineskip}% +\newtoggle{lb@breakable}% +\newtoggle{lb@debug}% +\newtoggle{lb@verbose}% +\def\lb@breakat{}% +\def\lb@halign{}% +\def\lb@eject{}% +\def\lb@insertafter{} +\def\lb@insertbefore{} + +\newcommand*\lb@peekoptions[1]{% + % process options inside a group and just set necessary parameters + % this way, nested boxes don't influence each other's parameters + \begingroup + \options{#1}% + \option{/longbox/adjust-options}% + \protected@edef\lb@temp{\endgroup + \lb@width=\the\dimexpr\option{/longbox/width}\relax + \lb@height=\the\dimexpr\option{/longbox/height}\relax + \lb@textalign=\the\numexpr\option{/longbox/text-align/@ord}\relax + \lb@baseline=\the\numexpr\option{/longbox/baseline/@ord}\relax + \lb@skiptop=\the\dimexpr\option{/longbox/skip-top}\relax + \lb@skipright=\the\dimexpr\option{/longbox/skip-right}\relax + \lb@skipbottom=\the\dimexpr\option{/longbox/skip-bottom}\relax + \lb@skipleft=\the\dimexpr\option{/longbox/skip-left}\relax + \lb@skipbreaktop=\the\dimexpr\option{/longbox/skip-break-top}\relax + \lb@skipbreakbottom=\the\dimexpr\option{/longbox/skip-break-bottom}\relax + \lb@usevbox=\iftoggle{/longbox/use-vbox}{1}{0}\relax + \lb@outerwidth=\the\dimexpr\option{/longbox/outer-width}\relax + \lb@extrasplit=\the\dimexpr\option{/longbox/split-minimum}\relax + \def\noexpand\lb@insertafter{\option{/longbox/insert-after}}% + \def\noexpand\lb@insertbefore{\option{/longbox/insert-before}}% + \def\noexpand\lb@breakat{\option{/longbox/breakat}}% + \def\noexpand\lb@halign{\option{/longbox/height-align}}% + \def\noexpand\lb@eject{\option{/longbox/eject}}% + \noexpand\csname toggle\iftoggle{/longbox/baseline-skip}{true}{false}\endcsname{lb@baselineskip}% + \noexpand\csname toggle\iftoggle{/longbox/breakable}{true}{false}\endcsname{lb@breakable}% + \noexpand\csname toggle\iftoggle{/longbox/debug}{true}{false}\endcsname{lb@debug}% + \noexpand\csname toggle\iftoggle{/longbox/verbose}{true}{false}\endcsname{lb@verbose}% + }% + \lb@temp +} + +\newenvironment{longbox@env}[2]{% + % save options + \lb@peekoptions{#1,#2}% + % + \ifnum\lb@usevbox=0\relax + \lb@debug{start breakbox}% + \let\bb@render\lb@render@breakbox + \bb@savekeys{longbox}{options={#1,#2,outer-width=\the\lb@outerwidth}}% + \iftoggle{lb@baselineskip}{\typeout{**insert bskip}}{\typeout{**suppress bskip}\vskip 1pt}% + \begin{breakbox}% + \ifdim\lb@skiptop=\z@\relax\else\vspace{\lb@skiptop}\fi% + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \begin{bb@margins}{\lb@skipleft}{\dimen@}% + \else + \lb@debug{start vbox}% + \def\lb@restoreoptions{\options{#1,#2}\option{/longbox/adjust-options}}% + \lb@savefootnotes + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \lb@debug{ width=\the\lb@width, linewidth=\the\linewidth, skipleft=\the\lb@skipleft, right=\the\lb@skipright, total right=\the\dimen@}% + \iftoggle{lb@baselineskip}{\lb@skiptobaseline}{\lb@prevdepth=-\@m pt}% + \lvbox{\lb@mainbox}{0pt}{\lb@width}{0pt}%{\lb@skipleft}{\lb@width}{\lb@skipright}% + \prevdepth=\lb@prevdepth + \fi + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore + \begingroup +}{% + \par\unskip + \endgroup + \lb@insertafter + %\ifdim\lb@skipbottom=\z@\relax\else\vskip\lb@skipbottom\fi% + \ifnum\lb@usevbox=0\relax + \end{bb@margins}% + \ifdim\lb@skipbottom=\z@\relax\else\hrule width \z@ height \lb@skipbottom\fi%\vspace{\lb@skipbottom}\fi% + \iftoggle{lb@baselineskip}{}{\vskip 1sp}% + \end{breakbox}% + \lb@debug{end breakbox}% + \else + \ontoggle{lb@baselineskip}{\lb@skiptobaseline}% + \endlvbox% + \lb@debug{initial lvbox: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@processbox + %\setbox\lb@mainbox=\hbox{\lower \lb@skipbottom\vbox{\offinterlineskip\unvbox\lb@mainbox}}% + \lb@restorefootnotes + \lb@debug{end vbox}% + \fi +} + +\newcommand\longbox@cmd[3]{% + \begingroup + %\options{/options/collectunknown,/longbox/scoped,#2}% set scoped options first + %\option{/longbox/scoped/@adjust-options}% + \lb@peekoptions{#1,#2}% + \leavevmode + %\setbox\lb@mainbox=\hbox{% + % \begingroup + % #3% + % \endgroup + %}% + \setbox\lb@mainbox=\hbox{% + \begingroup + \ifcase\lb@textalign\relax + %default=left + \or%left + \or\hss%center + \or\hss%right + \else%justify + \fi + \lb@insertbefore + #3% + \lb@insertafter + \ifnum\lb@textalign<3\relax\hss\fi% default,left,center + \endgroup + }% + \options{#1,#2}% + \ifdim\option{/longbox/width}=-1sp\relax + \options{/longbox/width=\wd\lb@mainbox}%set to natural width + \fi + \option{/longbox/adjust-options}% + % make it a vbox + \setbox\lb@mainbox=\vbox{\offinterlineskip% + \hbox to \option{/longbox/width}{% + \unhbox\lb@mainbox + }% + }% + \def\lb@restoreoptions{}% + \letoption{/longbox/height-align}\lb@halign + \lb@height=\option{/longbox/height}\relax + \lb@baseline=\option{/longbox/baseline/@ord}\relax + \lb@processbox + \endgroup +} + +\newcommand\lb@processbox{% + \ifdim\lb@height<0pt\relax + \lb@setbaseline{\lb@mainbox}% + \else + \lb@restrictheight + \fi + \lb@typesetbox +} + +\newcommand\lb@typesetbox{% + \ifinlvbox + \iftoggle{lb@breakable}{% + %\lb@debug{disable breakable due to nesting of long-boxes}% + \togglefalse{lb@breakable}% + }{}% + \fi + \ifhmode\lb@single@{\lb@mainbox}\else\lb@typeset\fi +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@restrictheight{% + \lb@typeout{restrict height to \the\lb@height}% + \lb@splitheight=\lb@height% + %lb@debug{before height split: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + %split failed.. do nothing + \lb@debug{could not restrict height}% + \else + % store splitted off content in the mainbox (and discard the rest) + \setbox\lb@mainbox\vbox{\unvbox\lb@headbox}% + \lb@debug{restricted height to \the\ht\lb@mainbox}% + \fi + % set baseline + \lb@setbaseline{\lb@mainbox}% + % height align + %\letoption{/longbox/height-align}\lb@halign + \eifstrequal{\lb@halign}{bottom}% + {\setbox\lb@mainbox=\vbox{\hbox{\vbox to \lb@splitheight{\vss\unvbox\lb@mainbox}}}}% + {\eifstrequal{\lb@halign}{middle}% + {\dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\hbox{% + \lower \dimexpr0.5\dimen@ + \dp\lb@mainbox\relax% + \vbox to \lb@splitheight{\vss\unvbox\lb@mainbox\vss}}}}% + {% default is top + \dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\vtop to \lb@splitheight{\box\lb@mainbox\vss}}% + }% + }% +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newlength\lb@neededvspace +\newcommand\lb@typeset[1][0pt]{% + \iftoggle{lb@breakable}{% + \lb@setfreevspace + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skiptop+\lb@skipbottom\relax}% + \lb@debug{needed: \the\lb@neededvspace, available: \the\lb@freevspace}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@single@{\lb@mainbox}% + \else + \lb@typeout{longbox needs splitting}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skiptop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \ifdim\dimexpr\lb@freevspace + #1\relax<\textheight\relax % test if we were at a fresh page.. (and prevent infinite recursion) + \lb@debug{failed to split the box, inserting a page break}% + \hrule \@height\z@ \@width\hsize + \lb@eject% + \lb@typeset[\textheight]% try again, but pass \textheight to guard against infinite recursion + \else + % on a fresh page we should not fail anymore.. just output as is.. + % lb@warncannotsplit + \lb@single@{\lb@mainbox}% + \fi + \else + % first part success + \lb@typeout{first part splitted}% + \lb@first@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest + \fi + \fi + }{%\else + \lb@debug{unbreakable box}% + \lb@single@{\lb@mainbox}% always directly output an unbreakable box + }% +} + +\newcommand\lb@typesetrest{% + \lb@setfreevspace% + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skipbottom+\lb@skipbreaktop\relax}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@typeout{output last part of box}% + \lb@last@{\lb@mainbox}% + \else + \lb@debug{split box further}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skipbreaktop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \lb@typeout{failed to split box!}% + \lb@last@{\lb@mainbox}% + \else + % middle part success + \lb@typeout{output middle part of box}% + \lb@middle@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest% continue the iteration... + \fi + \fi +} + +% -------------------------------------------------------- +% Split a long vbox over multiple pages. +% This code is based on similar code in the mdframed package +% -------------------------------------------------------- + +\newlength\lb@splitheight +\newlength\lb@insurance % tiny extra space to ensure our box will really fit +\setlength\lb@insurance{1pt} + +% expects split target height in lb@splitheight, and splits off the start of lb@mainbox to lb@headbox +\newcommand\lb@splitbox{% + \ifdim\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax>\lb@splitheight\relax + % the main box is larger than our target split height.. + \ifdim\lb@extrasplit>\lb@splitheight\relax + % not enough space to bother + \lb@typeout{not enough space on page for a split}% + \setbox\lb@headbox=\vbox{}% empty head + \else + % try a split; lower the split height a bit so we are sure to fit + \advance\lb@splitheight -\lb@insurance\relax + \lb@debug{split: \the\lb@splitheight, from \the\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax}% + \setbox\lb@savebox=\vbox{\unvcopy\lb@mainbox}% save original + \lb@trysplit{\lb@splitheight}% + \ifdim\dimexpr\ht\lb@headbox + \dp\lb@headbox>\lb@splitheight\relax + % too big, bad split. Try other splits.. iterate N times with 1 or 5pt less before giving up + \dimen@=\lb@splitheight\relax + \@tempcnta=\z@\relax + \loop + \ifdim\dimexpr\ht\lb@headbox+\dp\lb@headbox\relax>\lb@splitheight\relax + \ifnum\@tempcnta<50% + \advance\dimen@ by -\p@\relax% try a slightly smaller height.. + \else + \advance\dimen@ by -5\p@\relax% try larger increase after 50pt.. + \fi + \advance\@tempcnta by \@ne\relax + \lb@ignorevbadness + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \lb@trysplit{\dimen@}% + \ifdim\lb@extrasplit<\dimen@\relax\else\lb@splitstop\fi % don't try to split too small + \ifnum\@tempcnta<100\relax\else\lb@splitstop\fi % and not more than N attempts + \repeat% + \ifnum\@tempcnta<100\relax + \dimen@=\dimexpr\lb@splitheight - \ht\lb@headbox - \dp\lb@headbox\relax + \ifdim\dimen@>\option{/longbox/split-badness}\relax + \lb@warnbadsplit{\dimen@}% + \fi + \fi + \fi + \fi + \else + % mainbox fits in our target lb@splitheight + \setbox\lb@headbox=\vbox{\unvbox\lb@mainbox}% + \setbox\lb@mainbox=\vbox{}% + \fi +} + +\newcommand\lb@splitstop{% + \lb@typeout{cannot find a good split}% + \let\iterate\relax + \lb@warncannotsplit + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \setbox\lb@headbox=\vbox{}% empty head + \@tempcnta=\@M\relax +} + +\newcommand\lb@trysplit[1]{% try to split at given height + \lb@typeout{try to split at: \the\dimexpr #1\relax}% + \lb@ignorevbadness + \setbox\lb@headbox=\vsplit\lb@mainbox to #1\relax% + \setbox\lb@headbox=\vbox{\unvbox\lb@headbox}% + \setbox\lb@mainbox=\vbox{\unvbox\lb@mainbox}% +} + +% -------------------------------------------------------- +% The longbox environment uses options to set its options +% -------------------------------------------------------- + + +% keys and styles that can be set once globally +\options{% + /longbox/.new family, +}% + +\options{/longbox,% + % computed + @part-needtop/.new toggle, + @part-needbottom/.new toggle, + @part-height/.new length, + @part-width/.new length, + @part-depth/.new length, + @content-box-height/.new length, + @content-box-width/.new length, + @content-box-depth/.new length, + @breakat-previous/.new length, + @lower/.new length, + % + debug/.new toggle, + verbose/.new toggle, + render/.new value =\lb@render@fbox, + adjust-options/.new value = {\longbox@adjustoptions}, + eject/.new value = {\protect\vfill\protect\eject}, + use-vbox/.new toggle = true, + split-minimum/.new length = {1.5\baselineskip}, + split-badness/.new length = \baselineskip, + % + height-align/.new choice= {top,middle,bottom}, + baseline/.new choice = {bottom,middle,top}, + text-align/.new choice = {default,left,center,right,justify}, + vertical-align/.new choice = {baseline,bottom,middle,top,text-bottom,text-top,super,sub}, + raise/.new length = {0pt}, + baseline-skip/.new toggle =true, + % + height/.new length = -1sp, + width/.new length = -1sp, + outer-height/.new length= -1sp, + outer-width/.new length = -1sp, + insert-before/.new value= {}, + insert-after/.new value = {}, + breakat/.new value = {}, + breakable/.new toggle = false, + skip/.new style = {skip-top=#1,skip-right=#1,skip-bottom=#1,skip-left=#1}, + skip-top/.new length, + skip-right/.new length, + skip-bottom/.new length, + skip-left/.new length, + skip-break-bottom/.new length, + skip-break-top/.new length, +} + +\newcommand\longbox@adjustoptions{% + %\typeout{ standard longbox adjustoptions}% + \lb@debug{ current width=\the\dimexpr\option{/longbox/width}, outer=\the\dimexpr\option{/longbox/outer-width}, linewidth=\the\linewidth}% + \ontoggle{/longbox/debug}{\option@invoke{/longbox/verbose}{true}}% + % adjust height + \ifdim\option{/longbox/height}=-1sp\relax + \ifdim\option{/longbox/outer-height}=-1sp\else + \option@invoke{/longbox/height}% + {\option{/longbox/outer-height}-\option{/longbox/skip-top}-\option{/longbox/skip-bottom}}% + \fi + \fi + % set width + \ifdim\option{/longbox/width}=-1sp\relax + \ifdim\option{/longbox/outer-width}=-1sp\relax + \option@invoke{/longbox/outer-width}{\linewidth}% + \fi + \dimen@=\dimexpr\option{/longbox/outer-width}-\option{/longbox/skip-left}-\option{/longbox/skip-right}\relax + \ifdim\dimen@<\z@\relax\dimen@=\z@\fi + \option@invoke{/longbox/width}{\dimen@}% + \fi + % use a breakbox whenever we are in external vertical mode and not width or height restricted. + \iftoggle{/longbox/use-vbox}{}{% + \ifinner\toggletrue{/longbox/use-vbox}\else + \ifhmode\toggletrue{/longbox/use-vbox}\else + \ifdim\option{/longbox/height}>-1sp\toggletrue{/longbox/use-vbox}\else + \iftoggle{/longbox/breakable}{}{\toggletrue{/longbox/use-vbox}}% + \ifoptionblank{/longbox/breakat}{}{\toggletrue{/longbox/use-vbox}}% + \fi\fi\fi + }% +} + +\newenvironment{longbox}[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \begin{longbox@env}{/longbox}{#1}% +}{\end{longbox@env}} + +\newcommand\lbox[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \longbox@cmd{/longbox}{#1}% +} + +\newcommand*\lb@render@fbox{% + %\typeout{render defaultbox: bgcolor=\bb@bgcolor, needtop=\iftoggle{/longbox/@part-needtop}{true}{false}}% + \@ovdx=\dimexpr\option{/longbox/@part-width} - 2\fboxrule\relax% + \@ovdy=\dimexpr\option{/longbox/@part-height}\relax% + \iftoggle{/longbox/@part-needbottom}% + {\@tempdima=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdima=\dimexpr\fboxrule + \bb@stickout\relax + \advance\bb@height by \@tempdima + \advance\@ovdy by \@tempdima}% + \iftoggle{/longbox/@part-needtop}% + {\@tempdimb=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdimb=\dimexpr\bb@stickout\relax + \advance\bb@height by \@tempdimb + \advance\@ovdy by \@tempdimb}% + % + \hbox{\lower \@tempdima\vbox{% + \vskip -\@tempdimb + \ontoggle{/longbox/@part-needtop}{\lb@debug{toprule wd=\expandafter\the\option{/longbox/width}}\hrule width \option{/longbox/@part-width} height \fboxrule}% + \hbox{% + \vrule width \fboxrule height \@ovdy% + \ifx\bb@bgcolor\@empty + \vrule width \@ovdx height \z@\relax + \else + {\color{\bb@bgcolor}\vrule width \@ovdx height \@ovdy}% + \fi + \vrule width \fboxrule height \@ovdy% + }% + \ontoggle{/longbox/@part-needbottom}{\hrule width \option{/longbox/@part-width} height \fboxrule}% + }}% +} \ No newline at end of file diff --git a/spec/v1.1.0/longfbox.sty b/spec/v1.1.0/longfbox.sty new file mode 100644 index 00000000..0df01331 --- /dev/null +++ b/spec/v1.1.0/longfbox.sty @@ -0,0 +1,1344 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longfbox}[2015/12/01, Daan Leijen, Provides long fbox that can break over pages] + +\RequirePackage{options} +\RequirePackage{longbox} +\RequirePackage{pict2e} +\RequirePackage{ellipse} + +% -------------------------------------------------------- +% Dimension calulations +% -------------------------------------------------------- + +% dimmin/dimmax return minimum or maximum dimension +\providecommand\dim@min[2]{\ifdim#1>#2#2\else #1\fi} +\providecommand\dim@max[2]{\ifdim#1>#2#1\else #2\fi} + +\newcommand*\option@dimmin[2]{\dim@min{\option{#1}}{\option{#2}}} +\newcommand*\option@dimmax[2]{\dim@max{\option{#1}}{\option{#2}}} + + +% -------------------------------------------------------- +% Add a new 'sides' option type +% -------------------------------------------------------- + +\options{ + /handlers/new sides/.new handler = []{ + \ifblank{#2}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#1-top={##1}, #1-right={##2}, #1-bottom={##3}, #1-left={##4}}}}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#2}}}% + \optionsalso{ + #1/.new cmdx = {##1,##2,##3,##4,##5\relax}{,,,,\relax}{% + \ifblank{##2##3##4}{\option{#1/@cmd@sides}{##1}{##1}{##1}{##1}}% + {\ifblank{##3##4}{\option{#1/@cmd@sides}{##1}{##2}{##1}{##2}}% + {\ifblank{##4}{\option{#1/@cmd@sides}{##1}{##2}{##3}{##2}}% + {\option{#1/@cmd@sides}{##1}{##2}{##3}{##4}}% + }% + }% + }, + #1/.type = sides, + }% + },% +} + +\newcommand*\optionlengthlimit[3]{% len, min, max + \letoption{#1}\opt@temp + \ifdim\opt@temp<\dimexpr#2\relax + \option@invoke{#1}{#2}% + \else\ifdim\opt@temp>\dimexpr#3\relax + \option@invoke{#1}{#3}% + \fi\fi +} + +\newcommand*\optionradiuslimit[4]{% r1, r2, min, max + \letoption{#1}\opt@tempa + \letoption{#2}\opt@tempb + \ifdim\opt@tempa<\dimexpr#3\relax\option@invoke{#1}{#3}\fi + \ifdim\opt@tempb<\dimexpr#3\relax\option@invoke{#2}{#3}\fi + \ifdim\dimexpr\opt@tempa + \opt@tempb\relax=\z@\relax\else + \ifdim\dimexpr\opt@tempa+\opt@tempb\relax>\dimexpr#4\relax + \edef\opt@perc{\the\numexpr(\number\dimexpr#4\relax)/% + (\number\dimexpr(\opt@tempa+\opt@tempb)/100\relax)}% + %\typeout{scale:\the\opt@tempa,\the\opt@tempb, by \opt@perc percent to make \the\dimexpr#4\relax}% + \edef\opt@temp{\dimexpr\opt@perc\dimexpr\the\opt@tempa\relax / 100\relax}% + \option@einvoke{#1}{\opt@temp}% + \option@einvoke{#2}{\dimexpr#4 - \opt@temp\relax}% + %\typeout{ scaled to: \the\opt@temp,\the\dimexpr#4 - \opt@temp\relax}% + \fi + \fi +} + + +% \begin{macro}{\trig@atantan} +% \marg{a}\marg{b}\marg{$\alpha$}{dimen$_\mathit{reg}$}\\ +% Assigns $\atan_2(\frac{\sin(\alpha)}{b},\frac{\cos(\alpha)}{a})$ to dimension register \textit{dimen$_\mathit{reg}$}, +% where $a$ and $b$ are dimensions. +% Returns $\alpha$ when $a = b$, or when $a=0$ or $b=0$. +% \begin{macrocode} +\newcommand*\trig@atantan[4]{% + %\typeout{ atantan:(\the#1,\the#2,\the#3, #4)}% + \@tempdima\dimexpr#1\relax + \@tempdimb\dimexpr#2\relax +% \end{macrocode} +% If $a = b$, we have a circle and the result is $\alpha$. +% \begin{macrocode} + \ifdim\@tempdima=\@tempdimb + #4\dimexpr#3\relax + \else\ifdim\@tempdima=\z@ + #4\dimexpr#3\relax + \else\ifdim\@tempdimb=\z@ + #4\dimexpr#3\relax + \else + \edef\trig@temp{\strip@pt\dimexpr#3\relax}% + \CalculateSin{\trig@temp}\CalculateCos{\trig@temp}% + \@tempdimc\dimexpr1\p@ * \dimexpr\UseSin{\trig@temp}\p@\relax/\@tempdimb\relax + \@tempdimd\dimexpr1\p@ * \dimexpr\UseCos{\trig@temp}\p@\relax/\@tempdima\relax + \pIIe@atantwo{\@tempdimc}{\@tempdimd}\dimen@ + \ifdim\dimen@<\z@ + \ifdim\dimexpr#3\relax<\z@\else\advance\dimen@360\p@\fi + \fi + \@tempdima\dimexpr#3 - \dimen@\relax + \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi + \ifdim\@tempdima<360\p@\else\advance\dimen@360\p@\fi + %\typeout{atan: \the\dimexpr#3\relax versus. \the\dimen@ }% + #4\dimen@ + \fi\fi\fi +} +% \end{macrocode} +% \end{macro} + +% rough approximation of the perimeter; +% if |radius-x == radius-y| = 0 (a circle), the approximation is precise. +% otherwise, works best when |angle2-angle1| <= 45 and gets worse from there on. +\newcommand*\ellip@letarcperimeter[5]{% 'radius-x', 'radius-y', 'angle-1', 'angle-2', '\result' + \@tempdima\dimexpr#3\relax + \@tempdimb\dimexpr#4\relax + \@tempdimc\dimexpr\@tempdima - \@tempdimb\relax + \ifdim\@tempdimc<\z@\@tempdimc-\@tempdimc\fi + \ifdim#1=#2\relax% circle? + \edef\@tempa{\strip@pt\@tempdimc}% angle difference delta as factor + \dimen@\@tempa\dimexpr#1\relax% r*delta + \dimen@0.017453\dimen@% (2*pi/360) * r * delta = 2*pi*r * (delta/360) + \else% ellipse: take the distance between the points on the ellipse, works pretty good if delta <= 45, and ok'ish for delta <= 90 + \@ovro\dimexpr#1\relax + \@ovri\dimexpr#2\relax + \edef\fbox@tempa{\strip@pt\@tempdima}% + \edef\fbox@tempb{\strip@pt\@tempdimb}% + \pIIe@ellip@sincost{\fbox@tempa}{\fbox@tempb}% + \@tempdima\@ellipcosone\@ovro + \@tempdimb\@ellipsinone\@ovri + \@tempdimc\@ellipcostwo\@ovro + \@tempdimd\@ellipsintwo\@ovri + \advance\@tempdimc by -\@tempdima% + \advance\@tempdimd by -\@tempdimb% + \pIIe@ellip@csqrt{\@tempdimc}{\@tempdimd}{\dimen@}% + %\typeout{ distance: \the\dimen@, from (x,y)=(\the\@tempdimc,\the\@tempdimd), radii=(\the#1,\the#2), angles=(\the#3,\the#4)}% + \fi + \edef#5{\the\dimen@}% +} + + +% ------------------------------------------------------------------------------ +% Borders using the picture environment +% ------------------------------------------------------------------------------ + +\newcommand*\fbox@border@pict{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \begingroup + \hbox{% + \unitlength\p@ + \begin{picture}(0,0)(0,\optionunit{/fbox/@border-box-height})% bottom-left is origin + % markers + \ontoggle{/fbox/show-markers}{% + \linethickness{\option{/fbox/marker-width}}% + \optioncolor{/fbox/marker-color}% + \fbox@rect{0pt}{0pt}{\option{/fbox/@border-box-width}}{\option{/fbox/@border-box-height}}% + \fbox@rect{\option{/fbox/border-left-width}}{\option{/fbox/border-\fbox@bottom-width}}% + {\option{/fbox/@border-box-width}-\option{/fbox/border-right-width}}% + {\option{/fbox/@border-box-height}-\option{/fbox/border-\fbox@top-width}}%S + }% + %compute corner coordinates + \fbox@border@calccorners + %put down the background color + \fbox@border@colorbackground + \option{/fbox/picture-insert-before}% + %put down the sides + \fbox@border@side{3}{-2}{0}%top + \fbox@border@side{5}{-4}{3}%left + \fbox@border@side{-6}{7}{2}%bottom + \fbox@border@side{-8}{1}{1}%right + \end{picture}% + }% + \endgroup + \fi +} + +\newcommand*\fbox@border@pict@after{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \letoption{/fbox/picture-insert-after}\fbox@insertafter + \eifblank{\fbox@insertafter}{}{% + \begingroup + \hbox{% + \begin{picture}(0,0)(0,0)% bottom-left is origin + \fbox@insertafter + \end{picture}% + }% + \endgroup + }% + \fi +} + +\newcommand*\fbox@border@side[3]{% + \fbox@setoct@angles{#1}% + \edef\fbox@style{\option{/fbox/border-\fbox@side-style}}% + \optioncolor{/fbox/border-\fbox@side-color}% + \option{/fbox/picture-side-insert-before}% + \ifcsdef{fbox@border@pict@\fbox@style}% + {\csuse{fbox@border@pict@\fbox@style}{#1}{#2}{#3}}% + {\PackageWarning{longfbox}{Unknown style "\fbox@style". Using "solid" instead.}% + \fbox@border@pict@solid{#1}{#2}{#3}}% + \option{/fbox/picture-side-insert-after}% +} + +% ------------------------------------------------------------------------------ +% Define standard border styles for the picture environment +% +% a style has the form \fbox@border@pict@ + + + + + + +
+
+
+
P4Runtime Specification
+
version 1.2.0-rc.1
+
+
+
The P4.org API Working Group
+
2020-06-18
+
+

Abstract. P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.

+ + +

1. Introduction and Scope

+

This document is published by the P4.org API Working Group, which was +chartered [17] to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called P4Runtime. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +https://github.com/p4lang/p4runtime/tree/master/proto. +

1.1. P4 Language Version Applicability

+

P4Runtime is designed to be implemented in conjunction with the P416 language +version or later. P414 programs should be translated into P416 to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P416 1.0, but were introduced in P416 1.1.0 [29]. For +this version of P4Runtime, we recommend using P416 1.2.1 [1]. +

1.2. In Scope

+

This specification document defines the semantics of P4Runtime messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime: +

+
    +
  • Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA) [19] externs (e.g. Counters, Meters, Action +Profiles, ). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0. +
  • +
  • Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism. +
  • +
  • Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy. +
  • +
  • Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities. +
  • +
  • Packet I/O to enable streaming packets to & from the control plane. +
  • +
  • Batching support, with different atomicity guarantees. +
  • +
  • In-the-field device-reconfiguration with a new P4 data plane. +
+ +

The following are in the scope of this specification document: +

+
    +
  • Rationale for the P4Runtime design. +
  • +
  • Reference architecture and use-cases for deploying a P4Runtime service. +
  • +
  • Detailed description of the API semantics. +
  • +
  • Requirements for conformant implementations of the API. +
+

1.3. Not In Scope

+

The following are not in scope of P4Runtime: +

+
    +
  • Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +[35]. An open source implementation of these APIs is also in progress +as part of the Stratum project [37]. +
  • +
  • Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures. +
+ +

The following are not in scope of this specification document: +

+
    +
  • Description of the P4 programming language; it is assumed that the reader is +already familiar with P416 [1]. +
  • +
  • Descriptions of gRPC and Protobuf files in general. +
  • +
  • Controller role definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme. +
+

2. Terms and Definitions

+
+
arbitration
+
Refers to the process through which P4Runtime ensures that at any given +time, there is a single master (i.e. a client with write access) for a given +role. Also referred to as “master-slave arbitration”. +
+
client
+
The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +
+
COS
+
Class of Service. +
+
device
+
Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +
+
entity
+
An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +
+
gRPC
+
gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +[9]. +
+
HA
+
High-Availability. Refers to a redundancy architecture. +
+
Instrumentation
+
The part of the P4Runtime server which implements the calls to the device or +target native “SDK” or backend. +
+
IPC
+
Inter-Process Communication. +
+
P4 Blob
+
A more colloquial term for P4 Device Config (Blob = Binary Large Object). +
+
P4 Device Config
+
The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its “program.” +
+
P4Info
+
Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +
+
P4RT
+
Abbreviation for P4Runtime. +
+
Protobuf (Protocol Buffers)
+
The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See [21]. +
+
PSA
+
Portable Switch Architecture [19]; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +
+
RPC
+
Remote Procedure Call. +
+
RTT
+
Round-trip time. +
+
SDN
+
Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network controller. +
+
SDN port
+
A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +
+
server
+
The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +
+
stream
+
Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (StreamChannel), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and master-slave arbitration, among other +things. +
+
switch config
+
Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +
+
target
+
The hardware or software entity which “executes” the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with “device”. +
+
URI
+
Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.

3. Reference Architecture

+

Figure 1 represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. A multi-master protocol allows more than +one controller to participate, and a role-based arbitration scheme ensures only +one controller has write access to each read/write entity, or the pipeline +config itself. Any controller may perform read access to any entity or the +pipeline config. Later sections describe this in detail. For the sake of +brevity, the term controller may refer to one or more controllers. +

+

The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +[15]. It may be compiled via protoc the Protobuf compiler +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server. +

+

Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository [16]. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, e.g. via callbacks, thus reducing the burden of implementing +P4Runtime. +

+

The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard. +

+

The controller can also set the ForwardingPipelineConfig, which amounts to +installing and running the compiled P4 program output, which is included in the +p4_device_config Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +ForwardingPipelineConfig to retrieve the device config and the P4Info. +

+
+

reference-architecture +

+
+ +
Figure 1. P4Runtime Reference Architecture.

3.1. Idealized Workflow

+

In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the ForwardingPipelineConfig +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a SetForwardingPipelineConfig +RPC. Metadata in the P4Info describes both the overall program itself +(PkgInfo) as well as all entity instances derived from the P4 program +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise “handle” used in API +calls. +

+

In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible. +

+

In some use cases, it is expected that a controller will store a +collection of multiple P4 “packages”, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the ForwardingPipelineConfig from the target via the +GetForwardingPipelineRequest RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state. +

3.2. P4 as a Behavioral Description Language

+

P4 can be considered a behavioral description of a switching device which may or +may not execute “P4” natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a SetForwardingPipelineRequest to +change its pipeline “program”, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device. +

+

While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API. +

+

In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the PkgInfo +message as well as the embedded doc fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections. +

3.3. Alternative Workflows

+

Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary. +

3.3.1. P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config

+

In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +p4_device_config. The device's configuration might be derived via some other +means to implement the P4 source code's intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane. +

3.3.2. No P4 Source Available, P4Info Available

+

In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are: +

+
    +
  1. +

    The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security. +

  2. +
  3. +

    The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info. +

+ +

As discussed in Section 3.2, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, e.g. documentation. +

3.3.3. Partial P4Info and P4 Source are Available

+

In this situation, a subset of the target's pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code. +

3.3.4. P4Info Role-Based Subsets

+

In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more. +

3.4. P4Runtime State Across Restarts

+

All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade. +

4. Controller Use-cases

+

P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +section. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime's flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex. +

4.1. Single Embedded Controller

+

Figure 2 shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases. +

+

P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC. +

+
+

single-embedded-controller +

+
+ +
Figure 2. Use-Case: Single Embedded Controller

4.2. Single Remote Controller

+

Figure 3 shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections. +

+
+

single-remote-controller +

+
+ +
Figure 3. Use-Case: Single Remote Controller

4.3. Embedded + Single Remote Controller

+

Figure 4 illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller. +

+

For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables. +

+
+

embedded-plus-single-remote-controller +

+
+ +
Figure 4. Use-Case: Embedded Plus Single Remote Controller

4.4. Embedded + Two Remote Controllers

+

Figure 5 illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +e.g. routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership. +

+
+

embedded-plus-two-remote-controllers +

+
+ +
Figure 5. Use-Case: Embedded Plus Two Remote Controllers

4.5. Embedded Controller + Two High-Availability Remote Controllers

+

Figure 6 illustrates a single +embedded controller plus two remote controllers in an active-standby HA +(High-Availability) configuration. Controller #1 is the active controller and is +in charge of some entities. If it fails, Controller #2 takes over and manages +the tables formerly owned by Controller #1. The mechanics of HA architectures +are beyond the scope of this document, but the P4Runtime multi-master +arbitration scheme supports it. +

+
+

embedded-plus-two-remote-ha-controllers +

+
+ +
Figure 6. Use-Case: Embedded Plus Two Remote High-Availability Controllers

5. Master-Slave Arbitration and Controller Replication

+

The P4Runtime interface allows multiple controllers to be connected to the +P4Runtime server running on the device at the same time for the following +reasons: +

+
    +
  1. +

    Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, “roles” (or “realms”) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +master and the rest are slaves. Role definition, i.e. how P4 entities get +assigned to each role, is out-of-scope of this document. +

  2. +
  3. +

    Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby slave controllers. These can already have a connection +open, which can help them become master more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved. +

+ +

To support multiple controllers, P4Runtime uses the streaming channel (available +via StreamChannel RPC) for session management. The workflow is described as +follows: +

+
    +
  • +

    Each controller instance (e.g. a controller process) can participate in one or +more roles. For each (device_id, role_id), the controller receives an +election_id. This election_id can be the same for different roles and/or +devices, as long as the tuple (device_id, role_id, election_id) is +unique. For each (device_id, role_id) that the controller wishes to +control, it establishes a StreamChannel with the P4Runtime server +responsible for that device, and sends a MasterArbitrationUpdate message +containing that tuple of (device_id, role_id, election_id) values. The +P4Runtime server selects a master independently for each (device_id, +role_id) pair. The master is the client that has the highest election_id +that the device has ever received for the same (device_id, +role_id) values. A connection between a controller instance and a device id + which involves a persistent StreamChannel can be referred to as a +P4Runtime client. +

    +

    Note that the P4Runtime server does not assign a role_id or election_id to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the election_id values used for each +StreamChannel. The P4Runtime server only keeps track of the (device_id, +role_id, election_id) of each StreamChannel that has sent a successful +MasterArbitrationUpdate message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +WriteRequest message to identify which client is making the WriteRequest, +not only the election_id. This enables controllers to re-use the same +numeric election_id values across different (device_id, role_id) +pairs. P4Runtime does not require election_id values be reused across such +different (device_id, role_id) pairs; it allows it. +

  • +
  • +

    To start a controller session, a controller first opens a bidirectional stream +channel to the server via the StreamChannel RPC for each device. This stream +will be used for two purposes: +

    +
      +
    • +

      Session management: As soon as the controller opens the stream +channel, it sends a StreamMessageRequest message to the switch. The +controller populates the MasterArbitrationUpdate field in this message +using its role_id and election_id, as well as the device_id of the +device. Note that the status field in the MasterArbitrationUpdate is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below. +

    • +
    • +

      Streaming of notifications (e.g. digests) and packet I/O: The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the master controller can participate in packet +I/O. This feature is explained in more details in the Packet +I/O section. +

    + +

    Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state. +

  • +
  • +

    Note that the stream is opened per device. In case a switching platform has +multiple devices (e.g. multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different masters for different +devices. In this case, it is the responsibility of the P4Runtime server to +keep track of the master for each device (and role). More specifically, the +P4Runtime server will know which stream corresponds to the master controller +for each pair of (device_id, role_id) at any point of time. +

  • +
  • +

    The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered “offline” or +“dead” as soon as its stream channel to the switch is broken. When a master +channel gets broken: (i) an advisory message is sent to all other controllers +for that device_id and role_id, as described in the +following section (ii) the P4Runtime server +will be without a master, until a client sends a successful +MasterArbitrationUpdate (as per the rules in a +later section). +

  • +
  • +

    The mechanism via which the controller receives the P4Runtime server details +which includes the device_id, ip and port, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +device_id) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks. +

+ +

gRPC enables the server to identify which client originated each message in the +StreamChannel stream. For example, the C++ gRPC library [10] in +synchronous mode enables a server process to cause a function to be called when +a new client creates a StreamChannel stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +StreamChannel is closed normally (or broken, e.g. because a client process +unexpectedly terminated). Thus the server can easily associate all +StreamChannel messages received from the same client, because they are +processed within the context of the same function call. +

+

A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values device_id, role_id, and election_id in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods [8] that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server. +

5.1. Default Role

+

A controller can omit the role message in MasterArbitrationUpdate. This +implies the “default role”, which corresponds to “full pipeline access”. This +also implies that a default role has a role.id of 0 (default). If using a +default role, all RPCs from the controller (e.g. Write) must set the role_id +to 0. +

5.2. Role Config

+

The role.config field in the MasterArbitrationUpdate message sent by the +controller describes the role configuration, i.e. which operations are in the +scope of a given role. In particular, the definition of a role may include the +following: +

+
    +
  • A list of P4 entities for which the controller may issue Write updates and +receive notification messages (e.g. DigestList and +IdleTimeoutNotification). +
  • +
  • Whether the controller is able to receive PacketIn messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketIn messages should be sent to the controller. +
  • +
  • Whether the controller is able to send PacketOut messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketOut messages are allowed to be sent by the controller. +
+ +

An unset role.config implies “full pipeline access” (similar to the default +role explained above). In order to support different role definition schemes, +role.config is defined as an Any Protobuf message [31]. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion. +

+

It is the job of the P4Runtime server to remember the role.config for every +device_id and role_id pair. +

5.3. Rules for Handling MasterArbitrationUpdate Messages Received from Controllers

+
    +
  1. +

    If the MasterArbitrationUpdate message is received for the first time on +this particular channel (i.e. for a newly connected controller): +

    +
      +
    1. +

      If device_id does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +NOT_FOUND error. +

    2. +
    3. +

      If the election_id is set and is already used by another controller for +the same (device_id, role_id), the P4Runtime server shall terminate +the stream by returning an INVALID_ARGUMENT error. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the number of open streams for the given (device_id, role_id) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a RESOURCE_EXHAUSTED error. +

    8. +
    9. +

      Otherwise, the controller is added to a list of connected controllers for +the given (device_id, role_id) and the server remembers the +controllers device_id, role_id and election_id for this gRPC +channel. See below for the rules to determine if this controller becomes +a master or slave, and what notifications are sent as a consequence. +

    +
  2. +
  3. +

    Otherwise, if the MasterArbitrationUpdate message is received from an +already connected controller: +

    +
      +
    1. +

      If the device_id does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. +

    2. +
    3. +

      If the role.id does not match the current role_id assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. If the controller wishes to change its role, +it must close the current stream channel and open a new one. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the election_id is set and is already used by another controller +(excluding the controller making the request) for the same +(device_id, role_id), the P4Runtime server shall terminate the stream +by returning an INVALID_ARGUMENT error. +

    8. +
    9. +

      If the election_id matches the one assigned to this stream: +

      +
        +
      1. +

        If the controller for this channel is the master, then the server +updates the role.config to the one specified in the +MasterArbitrationUpdate. An advisory mastership message is sent to +all controllers for this device_id and role_id informing +them of the new role.config. Since the format of role.config is +out of scope for the P4Runtime specification, the server will send +the advisory message for every update, even if the master sets the +same role.config as it has before. See the +following section for the format of +the advisory message. +

      2. +
      3. +

        If the controller is a slave, this is a no-op and the role.config +is ignored. No response is sent to any controller. +

      +
    10. +
    11. +

      Otherwise, the server updates the election_id it has stored for this +controller. This change might cause a change in mastership (this +controller might become master, or the controller might have downgraded +itself to a slave, see below), as well as notifications being sent to one +or more controllers. +

    +
+ +

If the MasterArbitrationUpdate is accepted by either of the two steps above +(cases 1.5. and 2.6. above), then the server determines if there are changes in +mastership. Let election_id_past be the highest election ID the server has +ever seen for the given device_id and role_id (including the one of the +current master if there is one). +

+
    +
  1. +

    If election_id is greater than or equal to election_id_past, then the +controller becomes master. The server updates the role configuration to +role.config for the given role.id. Furthermore: +

    +
      +
    1. +

      If there was no master for this device_id and role_id before and +there are no Write requests still processing from a previous master, +then the server immediately sends an advisory notification to all +controllers for this device_id and role_id. See the +following section for the format of the +advisory message. +

    2. +
    3. +

      If there was a previous master or Write requests in flight, then the +server carries out the following steps (in this order): +

      +
        +
      1. +

        The server stops accepting Write requests from the previous master +(if there is one). At this point, the server will reject all Write +requests with PERMISSION_DENIED. +

      2. +
      3. +

        The server notifies all controllers other than the new master of the +mastership change by sending the advisory notification described in +the following section. +

      4. +
      5. +

        The server will finish processing any Write requests that have +already started. If there are errors, they are reported as usual to +the previous master. If the previous master has already disconnected, +any possible errors are dropped and not reported. +

      6. +
      7. +

        The server now accepts the current controller as the new master, thus +accepting Write requests from this controller. The server updates +the highest election ID (i.e. election_id_past) it has seen for +this device_id and role_id to election_id. +

      8. +
      9. +

        The server notifies the new master by sending the advisory message +described in the following section. +

      +
    +
  2. +
  3. +

    Otherwise, the controller becomes a slave. If the controller was previously a +master (and downgraded itself), then an advisory message is sent to all +controllers for this device_id and role_id. Otherwise, the advisory +message is only sent to the controller that sent the initial +MasterArbitrationUpdate. See the +following section for the format of the +advisory message. +

+

5.4. Mastership Notifications

+

For any given device_id and role_id, any time a new master is chosen, a +master downgrades its status to a slave, a master disconnects, or the +role.config is updated by the master, all controllers for that +(device_id, role_id) are informed of this by sending a +StreamMessageResponse. The MasterArbitrationUpdate is populated as follows: +

+
    +
  • +

    device_id and role.id as given. +

  • +
  • +

    role.config is set to the role configuration the server received most +recently in a MasterArbitrationUpdate from a master. +

  • +
  • +

    election_id is populated as follows: +

    +
      +
    • +

      If there has not been any master at all, the election_id is left unset. +

    • +
    • +

      Otherwise, election_id is set to the highest election ID that the server +has seen for this device_id and role_id (which is the election_id of +the current master if there is any). +

    +
  • +
  • +

    status is set differently based on whether the notification is sent to the +master or a slave controller: +

    +
      +
    • +

      If there is a master: +

      +
        +
      • +

        For the master, status is OK (with status.code set to +google.rpc.OK). +

      • +
      • +

        For all slave controllers, status is set to non-OK (with +status.code set to google.rpc.ALREADY_EXISTS). +

      +
    • +
    • +

      Otherwise, if there is no master currently, for all slave controllers, +status is set to non-OK (with status.code set to +google.rpc.NOT_FOUND). +

    +
+ +

Note that on mastership changes with outstanding Write request, some +notifications might be delayed, see the +previous section for details. +

6. The P4Info Message

+

The purpose of P4Info was described under +Reference Architecture. +Here we describe the various +components. +

6.1. Common Messages

+

These messages appear nested within many other messages. +

6.1.1. Documentation Message

+

Documentation is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers. +

+
+
+
message Documentation {
+  // A brief description of something, e.g. one sentence
+  string brief = 1;
+  // A more verbose description of something.
+  // Multiline is accepted. Markup format (if any) is TBD.
+  string description = 2;
+}

6.1.2. Preamble Message

+

The preamble serves as the “descriptor” for each entity and contains the unique +instance ID, name, alias, annotations and documentation. +

+
+
+
message Preamble {
+  // ids share the same number-space; e.g. table ids cannot overlap with counter
+  // ids. Even though this is irrelevant to this proto definition, the ids are
+  // allocated in such a way that it is possible based on an id to deduce the
+  // resource type (e.g. table, action, counter, ...). This means that code
+  // using these ids can detect if the wrong resource type is used
+  // somewhere. This also means that ids of different types can be mixed
+  // (e.g. direct resource list for a table) without ambiguity. Note that id 0
+  // is reserved and means "invalid id".
+  uint32 id = 1;
+  // fully qualified name of the P4 object, e.g. c1.c2.ipv4_lpm
+  string name = 2;
+  // an alias (alternative name) for the P4 object, probably shorter than its
+  // fully qualified name. The only constraint is for it to be unique with
+  // respect to other P4 objects of the same type. By default, the compiler uses
+  // the shortest suffix of the name that uniquely identifies the object. For
+  // example if the P4 program contains two tables with names s.c1.t and s.c2.t,
+  // the default aliases will respectively be c1.t and c2.t. In the future, the
+  // P4 programmer may also be able to override the default alias for any P4
+  // object (TBD).
+  string alias = 3;
+  repeated string annotations = 4;
+  // The location of `annotations[i]` is given by `annotation_locations[i]`.
+  repeated SourceLocation annotation_locations = 7;
+  // Documentation of the entity
+  Documentation doc = 5;
+  repeated StructuredAnnotation structured_annotations = 6;
+}

6.1.3. Annotating P4 Entities with Documentation

+

P4 entities may be annotated using the following annotations: +

+
+
+
@brief(string...)
+@description(string...)
+

Attaching either or both of these annotations to an entity will generate a +P4Info Documentation Message, which in turn will +appear in the Preamble Message for the entity. +

+

The P4 compiler should not emit annotation messages in the P4Info for these +specific cases; instead, it should generate the Documentation messages as +described. +

+

The following example shows documentation annotations for a table entity: +

+
+
+
@brief("Match IPv4 addresses to next-hop MAC and port")
+@description("Match IPv4 addresses to next-hop MAC and port. \
+Uses LPM match type.")
+table my_ipv4_lkup {
+  ...
+}

6.1.4. Structured Annotations

+

P4 supports both unstructured and structured annotations [13]. +Unstructured annotations of the form MyAnno1 or MyAnno2(body-content) can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +MyAnno3[] or MyAnno4[kvList|expressionList] have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this. +

+

The annotations described up to this point, e.g. @brief(), have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as repeated string annotations fields in the various messages. +Similarly, structured annotations are represented in repeated +StructuredAnnotation structured_annotations fields which are siblings to the +unstructured annotations. The structured_annotations contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations. +

+

The structured annotation messages are defined in p4types.proto. +

+
+
+
message KeyValuePair {
+  string key = 1;
+  Expression value = 2;
+}
+
+message KeyValuePairList {
+  repeated KeyValuePair kv_pairs = 1;
+}
+
+message Expression {
+  oneof value {
+    string string_value = 1;
+    int64 int64_value = 2;
+    bool bool_value = 3;
+  }
+}
+
+message ExpressionList {
+  repeated Expression expressions = 1;
+}
+
+message StructuredAnnotation {
+  string name = 1;
+  oneof body {
+    ExpressionList expression_list = 2;
+    KeyValuePairList kv_pair_list = 3;
+  }
+  // Location of the '@' symbol of this annotation in the source code.
+  SourceLocation source_location = 4;
+}
+

The StructuredAnnotation message can represent either a KeyValuePairList +or an ExpressionList. +

+

The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The p4c +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don't match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler may print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions. +

+

The following invariants hold: +

+
    +
  1. +

    For any P4 entity, there are no two StructuredAnnotations that have the +same name. +

  2. +
  3. +

    Within a KeyValuePairList, there are no two KeyValuePairs that have the +same key. +

+
6.1.4.1. Structured Annotation Examples
+

We omit the source_location field in the following examples. +

+

Empty Expression List +

+
+
+
@Empty[]
+table t {
+    ...
+}
+

The generated P4Info will contain the following. +

+
+
+
structured_annotations {
+  name: "Empty"
+}
+

Mixed Expression List +

+
+
+
#define TEXT_CONST "hello"
+#define NUM_CONST 6
+@MixedExprList[1,TEXT_CONST,true,1==2,5+NUM_CONST]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedExprList"
+  expression_list {
+    expressions {
+      int64_value: 1
+    }
+    expressions {
+      string_value: "hello"
+    }
+    expressions {
+      bool_value: true
+    }
+    expressions {
+      bool_value: false
+    }
+    expressions {
+      int64_value: 11
+    }
+  }
+}
+

kvList of Mixed Expressions +

+
+
+
@MixedKV[label="text", my_bool=true, int_val=2*3]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedKV"
+  kv_pair_list {
+    kv_pairs {
+      key: "label"
+      value {
+        string_value: "text"
+      }
+    }
+    kv_pairs {
+      key: "my_bool"
+      value {
+        bool_value: true
+      }
+    }
+    kv_pairs {
+      key: "int_val"
+      value {
+        int64_value: 6
+      }
+    }
+  }
+}

6.1.5. SourceLocation Message

+

A source location describes a location within a .p4-source file. The +SourceLocation message is defined in p4types.proto as follows: +

+
+
+
// Location of code relative to a given source file.
+message SourceLocation {
+  // Path to the source file (absolute or relative to the working directory).
+  string file = 1;
+  // Line and column numbers within the source file, 1-based.
+  int32 line = 2;
+  int32 column = 3;
+}
+

We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations. +

+

The SourceLocation message associated with an annotation holds the location of +the @ symbol introducing the annotation in the P4 source code; the message can +be found in the following place: +

+
    +
  • +

    For unstructured annotations, every message containing a field +repeated string annotations also contains a field +repeated SourceLocation annotation_locations. The i-th member of +annotation_locations is the source location of the i-th member of +annotations. +

  • +
  • +

    For structured annotations, every StructuredAnnotation message contains +a field SourceLocation source_location holding its source location. +

+

6.2. PkgInfo Message

+

The PkgInfo message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. PkgInfo can be extracted +and used to facilitate “browsing” of available P4 programs from a +library. Although all fields are technically “optional,” every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included. +

+
+
+
// Can be used to manage multiple P4 packages.
+message PkgInfo {
+  // a definitive name for this configuration, e.g. switch.p4_v1.0
+  string name = 1;
+  // configuration version, free-format string
+  string version = 2;
+  // brief and detailed descriptions
+  Documentation doc = 3;
+  // Miscellaneous metadata, free-form; a way to extend PkgInfo
+  repeated string annotations = 4;
+  // the target architecture, e.g. "psa"
+  string arch = 5;
+  // organization which produced the configuration, e.g. "p4.org"
+  string organization = 6;
+  // contact info for support,e.g. "tech-support@acme.org"
+  string contact = 7;
+  // url for more information, e.g. "http://support.p4.org/ref/p4/switch.p4_v1.0"
+  string url = 8;
+  // Miscellaneous metadata, structured; a way to extend PkgInfo
+  repeated StructuredAnnotation structured_annotations = 9;
+}

6.2.1. Annotating P4 code with PkgInfo

+

A P4 progam's PkgInfo may be declared using one or more of the following +annotations, attached to the main block only: +

+
+
+
@pkginfo(key=value)
+@pkginfo(key=value[,key=value,...])
+@brief("A brief description")
+@description("A longer\
+description")
+@custom_annotation(...)
+@another_custom_annotation(...)
+

Above we see several different types of annotations: +

+
    +
  • +

    @pkginfo - This is used to populate a specific field within the PkgInfo +message. Multiple @pkginfo annotations are allowed. For compactness, +multiple key-value pairs can appear in a single @pkginfo annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The keys must be from +among the message fields inside PkgInfo, for example, name, version, +etc. Each key-value pair assigns a value to the corresponding field inside the +single PkgInfo message for the program's P4Info. One exception is that the +Documentation field of PkgInfo must be expressed as individual +@description and @brief annotations, see next bullets. The key arch will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself. +

  • +
  • +

    @brief - This will populate the PkgInfo.doc.brief message field. +

  • +
  • +

    @description - This will populate the PkgInfo.doc.description message +field +

  • +
  • +

    @<anything else> - This will create a PkgInfo.annotation entry +

+ +

Declaring one or more of these annotations on main will +generate a single corresponding PkgInfo message in the P4Info as described in +PkgInfo Message. +

+

The following example shows @pkginfo annotations using a mixture of single and +multiple key-value pairs. It also shows @brief and @description annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the PkgInfo message. The custom annotations will +be appended to the PkgInfo.annotations list. +

+
+
+
@pkginfo(name="switch.p4",version="2")
+@pkginfo(organization="p4.org")
+@pkginfo(contact="info@p4.org")
+@pkginfo(url="www.p4.org")
+@brief("L2/L3 switch")
+@description("L2/L3 switch.\
+Built for data-center profile.")
+@my_annotation1(...) // Not well-known, this will appear in PkgInfo annotations
+@my_annotation2(...) // Not well-known, this will appear in PkgInfo annotations
+PSA_Switch(IgPipeline, PacketReplicationEngine(), EgPipeline,
+           BufferingQueueingEngine()) main;

6.3. ID Allocation for P4Info Objects

+

P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(e.g. table, action, counter, ). The most significant 8 bits of the ID +encodes the object type (as per Table 1). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (p4.config.v1.P4Ids.Prefix). These values must +be used (e.g. by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table 2 shows the ID +layout. +

+
+ + + + + + + + + + + + + + + + + + + + + +
8-bit prefix value P4 object type
0x00 Reserved (unspecified)
0x01 Action
0x02 Table
0x03 Value-set
0x04 Controller header (header type with @controller_header annotation)
0x050x0f Reserved (for future P4 built-in objects)
0x10 Reserved (start of PSA extern types)
0x11 PSA Action profiles / selectors
0x12 PSA Counter
0x13 PSA Direct counter
0x14 PSA Meter
0x15 PSA Direct meter
0x16 PSA Register
0x17 PSA Digest
0x180x7f Reserved (for future PSA extern types)
0x80 Reserved (start of vendor-specific extern types)
0x810xfe Vendor-specific extern types
0xff Reserved (max prefix value)
+
+ +
Table 1. Mapping of P4Info object type to 8-bit ID prefix value
+
+ + + + +
MSB bit 31 .. bit 24 bit 23 .. bit 0 LSB
Object type prefix Generated suffix (e.g. by the compiler)
+
+ +
Table 2. Format of P4Info object IDs
+

It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with @id (see Table +3). The compiler must honor the @id annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (i.e. if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same @id value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct. +

+
+ + + + + + + + + + +
P4 declaration(s) Compiler-allocated ID(s)
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) table tA... Error(same ID suffixes for 2 objects of the same type)
@id(0x12ab34) table tB...
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) action act1... 0x0112ab34
+
+ +
Table 3. Example of statically-assigned P4Info object IDs
+

The @id annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively). +

6.4. P4Info Objects

6.4.1. Table

+

Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this table. +

  • +
  • +

    match_fields, a repeated field of type MatchField representing the data to +be used to construct the lookup key matched in this table. Each MatchField +message is defined with the following fields: +

    +
      +
    • +

      id, the uint32 identifier of this MatchField, unique in the scope of +this table. No rules are prescribed on the way MatchField IDs should be +allocated, as long as two MatchField of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the @id annotation, or let the compiler +choose them. +

    • +
    • +

      name, the string representing the name of this MatchField. +

    • +
    • +

      annotations, a repeated field of strings, each one representing a P4 +annotation associated to this match field. +

    • +
    • +

      bitwidth, an int32 value set to the size in bits of this match field. +

    • +
    • +

      match, a oneof describing the match behavior for this field; it can be +either: +

      +
        +
      • match_type, an enum field of type MatchType, which includes all +possible PSA match kinds. +
      • +
      • other_match_type, a string field which can be used to encode any +architecture-specific match type. +
      +
    • +
    • +

      doc, a Documentation message describing this match field. +

    • +
    • +

      type_name, which indicates whether the match field has a user-defined +type; this is useful for +translation. +

    +
  • +
  • +

    action_refs, a repeated ActionRef field representing the set of possible +actions for this table. The ActionRef message is used to reference an action +specified in the same P4Info message and it includes the following fields: +

    +
      +
    • id, the uint32 identifier of the action. +
    • +
    • scope, an enum value which can take one of three values: + TABLE_AND_DEFAULT, TABLE_ONLY and DEFAULT_ONLY. The scope of the + action is determined by the use of the P4 standard annotations + @tableonly and @defaultonly [18]. TABLE_ONLY + (@tableonly annotation) means that the action can only appear within + the table, and never as the default action. DEFAULT_ONLY + (@defaultonly annotation) means that the action can only be used as the + default action. TABLE_AND_DEFAULT is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action. +
    • +
    • annotations, a repeated string field, each one representing a P4 +annotation associated to the action reference in this table. +
    +
  • +
  • +

    const_default_action_id, if this table has a constant default action, this +field will carry the uint32 identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action's +arguments. +

  • +
  • +

    implementation_id, the uint32 identifier of the “implementation” of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (e.g. a PSA ActionProfile or ActionSelector +instance). The table is then referred to as an indirect match table. +

  • +
  • +

    direct_resource_ids, repeated uint32 identifiers for all the direct +resources attached to this table, such as DirectMeter and DirectCounter +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2. +

  • +
  • +

    size, an int64 describing the desired number of table entries that the +target should support for the table. See the “Size” subsection within the +“Table Properties” section of the P416 language specification for details +[30]. +

  • +
  • +

    idle_timeout_behavior, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +Idle-Timeout section). Value can be any of the +IdleTimeoutBehavior enum: +

    +
      +
    • NO_TIMEOUT (default value), which means that idle timeout is not +supported for this table. +
    • +
    • NOTIFY_CONTROL, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +Table Idle Timeout Notifications). +
    +
  • +
  • +

    is_const_table, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime. +

  • +
  • +

    other_properties, an Any Protobuf message [31] to embed +architecture-specific table properties [30] which are not part +of the core P4 language or of the PSA architecture. +

+

6.4.2. Action

+

Action messages are used to specify all possible actions of all match-action +tables. +

+

The Action message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this action +

  • +
  • +

    params, a repeated field of Param messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each Param message contains the +following fields: +

    +
      +
    • id, the uint32 identifier of this parameter. No rules are prescribed +on the way Param IDs should be allocated, as long as two Param of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the @id +annotation, or let the compiler choose them. +
    • +
    • name, the string representing the name of this parameter. +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this parameter. +
    • +
    • bitwidth, an int32 value set to the size in bits of this parameter. +
    • +
    • doc, which describes this parameter using a Documentation message. +
    • +
    • type_name, which indicates whether the action parameter has a +user-defined type; this is useful for +translation. +
    +
+

6.4.3. ActionProfile

+

ActionProfile messages are used to specify all available instances of Action +Profile and Action Selector PSA externs. +

+

PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile member, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime. +

+

PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into groups. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime. +

+

While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same ActionProfile message to describe both. +

+

The ActionProfile message includes the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Action +Profile or Selector. +

  • +
  • +

    table_ids, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector. +

  • +
  • +

    with_selector, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern. +

  • +
  • +

    size, an int64 representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups. +

  • +
  • +

    max_group_size, an int32 representing the maximum sum of all member +weights within any given selector group, in the case of an Action Selector, or +0 for an Action Profile. PSA programs can use the @max_group_size annotation +to provide this value for Action Selectors. If the annotation is omitted, the +P4Info field will default to 0. +

+

6.4.4. Counter & DirectCounter

+

Counter and DirectCounter messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is: +

+
    +
  • +

    Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index. +

  • +
  • +

    Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table. +

+ +

Both Counter and DirectCounter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this counter +extern instance. +

  • +
  • +

    spec, a message of of type CounterSpec used to describe the compile-time +configuration of this counter. Currently, the CounterSpec message is used to +carry only the counter unit, which can be any of the CounterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES: byte counter. +
    • +
    • PACKETS: packet counter. +
    • +
    • BOTH: combination of both byte and packet counter. +
    +
+ +

For indexed counters, the Counter message contains also a size field, an +int64 representing the maximum number of independent values that can be held +by this counter array. Conversely, the DirectCounter message contains a +direct_table_id field that carries the unit32 identifier of the table to +which this direct counter is attached. +

+

For indexed counters, the Counter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.5. Meter & DirectMeter

+

Meter and DirectMeter messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is: +

+
    +
  • +

    Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +e.g. to set the rate threshold. +

  • +
  • +

    Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table. +

+ +

Both Meter and DirectMeter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this meter +extern instance. +

  • +
  • +

    spec, a message of type MeterSpec used to describe the capabilities of +this meter extern instance. Currently, the MeterSpec message is used to +carry only the meter unit, which can be any of the MeterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES, which signifies that this meter can be configured with rates +expressed in bytes/second. +
    • +
    • PACKETS, for rates expressed in packets/second. +
    +
+ +

For indexed meters, the Meter message contains also a size field, an int64 +representing the maximum number of independent cells that can be held by this +meter. Conversely, the DirectMeter message contains a direct_table_id field +that carries the uint32 identifier of the table to which this direct meter is +attached. +

+

For indexed meters, the Meter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.6. ControllerPacketMetadata

+

ControllerPacketMetadata messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server. +

+

When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet. +

+

Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +@controller_header("packet_in") and @controller_header("packet_out"), +respectively. ControllerPacketMetadata messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages). +

+

A P4Info message can contain at most two ControllerPacketMetadata messages, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message where preamble.name is set to "packet_in" +and "packet_out" for packet-in and packet-out metadata, respectively. +

  • +
  • +

    metadata, a repeated field of type Metadata, where each Metadata message +includes the following fields: +

    +
      +
    • id, a uint32 identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two Metadata of the +same ControllerPacketMetadata message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the @id annotation, or let the compiler choose them. +
    • +
    • name, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below). +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this metadata. +
    • +
    • bitwidth, an int32 representing the size in bits of this metadata. +
    • +
    • type_name, which indicates whether the metadata field has a +user-defined type; this is useful for +translation. +
    +
+ +

As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding ControllerPacketMetadata +messages. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  bit<9> egress_port; /* suggested port where the packet
+                         should be sent */
+  bit<8> queue_id;    /* suggested queue ID */
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  bit<9> ingress_port; /* data plane port ID where
+                          the original packet was received */
+  bit<1> is_clone;     /* 1 if this is a clone of the
+                          original packet */
+}
+
+
+
controller_packet_metadata {
+  preamble {
+    id: 2868916615
+    name: "packet_out"
+    annotations: "@controller_header(\"packet_out\")"
+  }
+  metadata {
+    id: 1
+    name: "egress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "queue_id"
+    bitwidth: 8
+  }
+}
+
+controller_packet_metadata {
+  preamble {
+    id: 2868941301
+    name: "packet_in"
+    annotations: "@controller_header(\"packet_in\")"
+  }
+  metadata {
+    id: 1
+    name: "ingress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "is_clone"
+    bitwidth: 1
+  }
+}
+

Note that the use of @controller_header is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages. +

6.4.7. ValueSet

+

ValueSet messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P416 +specification [39]. +

+

The ValueSet message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Value +Set. +

  • +
  • +

    match, a repeated field of MatchField messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the match_fields repeated field in the +Table message. +

  • +
  • +

    size, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +value_set constructor call. +

+ +

According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of bit<W>, +tuple, or struct [26]. The rest of this section looks at all 3 of +these cases and gives an example ValueSet message when appropriate. +

+
    +
  1. +

    If the type parameter is bit<W>, match will include exactly one +MatchField message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used): +

    +
      +
    • id: set to 1 +
    • +
    • bitwidth: set to the value of W +
    • +
    • match_type: set to EXACT +
    +
+ +
+
+
@id(1) value_set<bit<8> >(4) pvs;
+select (hdr.f8) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    bitwidth: 8
+    match_type: EXACT
+  }
+  size: 4
+}
+
    +
  1. +

    If the type parameter is a tuple, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program. +

  2. +
  3. +

    If the type parameter is a struct, this version of P4Runtime requires that +all the fields of the struct be of type bit<W> (where W can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +match field will include one MatchField message for each field in the +struct, with the following fields: +

    +
      +
    • id: must be unique with respect to the other match entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +@id annotation, or let the compiler choose them. +
    • +
    • name: set to the name of the corresponding struct field. +
    • +
    • annotations: set to the list of P4 annotations associated with the struct +field, except for the @match annotation, if present (see the match field +below). +
    • +
    • bitwidth: set to the value of W for the corresponding struct field. +
    • +
    • type_name, which indicates whether the struct field has a user-defined +type; this is useful for +translation. +
    • +
    • match: by default match_type is set to EXACT; the P4 programmer can +specify a different match type by using the @match annotation +[26]. +
    • +
    • doc: documentation associated with the struct field. +
    +
+ +
+
+
struct match_t {
+  @id(1) bit<8> f8;
+  @id(2) @match(ternary) bit<16> f16;
+  @id(3) @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

In the above example, the @id annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs. +

+

Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a user-defined +type that resolves to a bit<W>, or a struct where +one or more fields is a user-defined type that +resolves to a bit<W>. For each MatchField that corresponds to a user-defined +type, the type_name field must be set to the appropriate value (i.e. the name +of the type). +

6.4.8. Register

+

Register messages are used to specify all possible instances of Register PSA +externs. +

+

Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime. +

+

The Register message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this register +instance. +

  • +
  • +

    type_spec, which specifies the data type stored by this register, expressed +using a P4DataTypeSpec message (see section on Representation of Arbitrary +P4 Types). +

  • +
  • +

    size, an int32 value representing the total number of independent register +cells available. +

  • +
  • +

    index_type_name, which indicates whether the register index has a +user-defined type. This is useful for +translation. The underlying built-in type +must be a fixed-width unsigned bitstring (bit<W>). +

+

6.4.9. Digest

+

Digest messages are used to specify all possible instances of Packet Digest +PSA externs. +

+

A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages. +

+

The Digest message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this digest +instance. +

  • +
  • +

    type_spec, which specifies the data type of an individual digest +notification using a P4DataTypeSpec message (see section on Representation +of Arbitrary P4 Types). +

+

6.4.10. Extern

+

Extern messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one Extern message instance in P4Info. The Extern message defines +the following fields: +

+
    +
  • +

    extern_type_id, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the reserved +range [0x81, 0xfe]. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture. +

  • +
  • +

    extern_type_name, which specifies the fully-qualified P4 name of the extern +type. +

  • +
  • +

    instances, a repeated field of ExternInstance Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +ExternInstance in turn defines the following fields: +

    +
      +
    • preamble, a Preamble message with the ID, name, and alias of this digest +instance. +
    • +
    • info, an Any Protobuf message [31] which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for info should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on Extending +P4Runtime for non-PSA Architectures for more +information. +
    +
+ +

If the P4 program does not include any instance of a given extern type, the +Extern message instance for that type should be omitted from the P4Info. +

6.5. Support for Arbitrary P4 Types with P4TypeInfo

+

See section on Representation of Arbitrary P4 +Types. +

7. P4 Forwarding-Pipeline Configuration

+

The ForwardingPipelineConfig captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the “Device Configuration” and sometimes also referred to as +the “P4 Blob”. It is defined as: +

+
+
+
message ForwardingPipelineConfig {
+  config.P4Info p4info = 1;
+  bytes p4_device_config = 2;
+  message Cookie {
+    uint64 cookie = 1;
+  }
+  Cookie cookie = 3;
+}
+

The p4info field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic. +

+

The p4_device_config is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new ForwardingPipelineConfig on that target. +

+

The cookie field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a GetForwardingPipelineConfig RPC. +When writing the config via a SetForwardingPipelineConfig RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present. +

8. General Principles for Message Formatting

8.1. Set / Unset Protobuf Field

+

In Protobuf version 3 (proto3), the default value for a message field is +“unset” [4]. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +CounterEntry message, an “unset” index field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the index message field is +set, a single entry will be read. +

+

Let's look at the counter example in more details. Based on this specification +document, the C++ server code which processes CounterEntry messages may look +like this: +

+
+
+
auto *counter_entry = ...
+if (counter_entry->has_index()) {
+  auto index = counter_entry->index().index();
+  read_one_entry(counter_entry->id(), index);
+} else {
+  read_all_entries(counter_entry->id());
+}
+
    +
  1. +

    Reading a single counter entry at index 0 in the counter array with id +<id>: +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
      +entry.mutable_index();
      +// The above line sets the index field; it is equivalent to:
      +// auto *index = entry.mutable_index();
      +// index->set_index(0);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
      +index {}
    • +
    • Expected behavior: Counter entry at index 0 is read. Notice that the +index subfield is missing under the index field message of +CounterEntry in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages. +
    +
  2. +
  3. +

    Reading all counter entries by leaving the index field unset +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
    • +
    • Expected behavior: All counter entries for the provided counter +instance are read. Notice that the index message field is unset (default +value) and is therefore omitted from the textual representation of the +message. +
    +
+

8.2. Read-Write Symmetry

+

The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example: +

+
+
+
intended_value = value
+
+status = server.write(intended_value, p4_entity)
+observed_value = server.read(p4_entity)
+
+assert(intended_value == observed_value)
+

To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If Read RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol's complexities to the client implementations. +

+

In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the match fields in a TableEntry message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +MessageDifferencer class [36] included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance. +

8.3. Zero as Reserved Value

+

p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a uint32. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a WriteRequest or a SetForwardingPipelineConfigRequest. +

8.4. Bytestrings

+

P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (bit<W>) or signed (int<W>), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +bytes Protobuf type. The correct bitwidth as per the P4 program of +each integer variable exposed through P4Runtime is specified in the P4Info +message. +

+

The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals: +

+
    +
  • +

    It ensures that a properly encoded binary string's integer value conforms +to the P4Info-specified bitwidth. +

  • +
  • +

    It supports read-write symmetry. +

  • +
  • +

    It helps facilitate non-disruptive P4 program updates. +

+ +

In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type bit<W> and/or int<W>. +

+

Note that this representation does not make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range. +

+

In the P4Runtime API version 1.0, values of table key fields, action parameters, +and fields in packet-in and packet-out headers between a device and the +controller (see 6.4.6), may not be of type int<W>. +The rules for encoding signed values thus only apply to messages of type +P4Data (see 8.5.3). +

+

For a value of type bit<W>, the fewest number of bits required to represent +the integer value $V > 0$ is the smallest integer $A$ such that $V \leq 2^A -1$. +

+

For a value of type int<W>, the fewest number of bits required to represent +the integer value $V \neq 0$ in 2's complement form is the smallest integer $A$ +such that $-2^{A-1} \leq V \leq 2^{A-1} - 1$. +

+

As a special case, define that the value $V=0$ requires at least $A=1$ bit to +represent, regardless of whether it is signed or unsigned. +

+

The shortest possible binary string for an integer $V$ that needs $A$ bits to +represent it is computed as: +

+
+
+
minimum_string_size = floor((A + 7) / 8)
+

Binary strings with the byte length computed as minimum_string_size promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies. +

+

Any additional bits in the bytes sent for an unsigned integer value (type +bit<W>) must be 0. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with 0. +

+

Any additional bits in the bytes sent for a signed integer value (type int<W>) +must be copies of the sign bit, i.e. 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with copies of the +sign bit, i.e. 0 for non-negative values, or 0xff for negative values. In 2's +complement representation, this is called “sign extension”, and leaves the +numeric value represented unchanged. +

+

Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value. +

+

For a received bitstring expected to fit within a bit<W> type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring's width is W bits or less. +

+

For a received bitstring expected to fit within an int<W> type, the value it +represents is in range if, after “undoing sign extension”, the remaining bit +string's width is W bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other. +

+

If the string's byte length is zero, the server always rejects the string. +

+

When the server rejects a binary string due to any of the previous criteria, +it returns an OUT_OF_RANGE error. +

+

For all binary strings, P4Runtime uses big-endian (i.e. network) byte-order. +For signed integer values (int<W> P4 type), P4Runtime uses the same two's +complement bitwise representation as P4. Table 4 +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above. +

+
+ + + + + + + + + + + + + + + + + +
P4 type Integer value P4Runtime binary string Read-write symmetry
bit<8> 99 (0x63) \x63 yes
bit<16> 99 (0x63) \x00\x63 no
bit<16> 99 (0x63) \x63 yes
bit<16> 12388 (0x3064) \x30\x64 yes
bit<16> 12388 (0x3064) \x00\x30\x64 no
bit<12> 99 (0x63) \x00\x63 no
bit<12> 99 (0x63) \x63 yes
bit<12> 99 (0x63) \x00\x00\x63 no
int<8> 99 (0x63) \x63 yes
int<8> -99 (-0x63) \x9d yes
int<8> -99 (-0x63) \xff\x9d no
int<12> -739 (-0x2e3) \xfd\x1d yes
int<16> 0 (0x0) \x00\x00 no
int<16> 0 (0x0) \x00 yes
+
+ +
Table 4. Examples of Valid Bytestring Encoding
+

Table 5 shows some examples of invalid +P4Runtime binary strings: +

+
+ + + + + + + + + + + + +
P4 type P4Runtime binary string
bit<8> \x01\x63
bit<8> empty string
bit<16> \x01\x00\x63
bit<12> \x10\x63
bit<12> \x01\x00\x63
bit<12> \x00\x40\x63
int<8> \x00\x9d
int<12> \x8d\x1d
int<16> empty string
+
+ +
Table 5. Examples of Invalid Bytestring Encoding
+

As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from bit<8> to bit<9>, a server +running the bit<9> version of the P4 program will accept requests from +clients that remain on the bit<8> P4Runtime version. +

+

Despite the server's binary string flexibility for P4 program update support, +the client and server must both remain aware of the +read-write symmetry +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values. +

+

Representation of variable-length integer values (varbit<W> P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the dynamic-length of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an OUT_OF_RANGE error code otherwise. +

8.5. Representation of Arbitrary P4 Types

8.5.1. Problem Statement

+

The P416 language includes more complex types than just binary strings +[3]. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table 6 shows the different +P416 types and how they are allowed to be used, as per the P416 +specification. +

+
+ + + + + + + + + + + + + + + + + + + +
Container type
Element type header header_union struct or tuple
bit<W> allowed error allowed
int<W> allowed error allowed
varbit<W> allowed error allowed
int error error error
void error error error
error error error allowed
match_kind error error error
bool error error allowed
enum allowed1 error allowed
header error allowed allowed
header stack error error allowed
header_union error error allowed
struct error error allowed
tuple error error allowed
+
+ +
Table 6. P4 Type Usage
+

For example, the following P416 objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects. +

+
+
+
Digest<tuple<bit<4>, bit<8> > >() digest_complex;
+digest_complex.pack({ hdr.ipv4.version, hdr.ipv4.protocol });
+// ...
+header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

One solution would be to use only binary string (bytes type) in +p4runtime.proto and to define a custom serialization format for complex P416 +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P416 types. +

8.5.2. P4 Type Specifications in p4info.proto

+

In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type ip_t, which is a header union with 2 possible headers: +ipv4 with type ipv4_t and ipv6 with type ipv6_t. Similarly, they need to +know the field layout for both of these header types. +

+

To achieve this we introduce 2 main Protobuf messages: P4TypeInfo and +P4DataTypeSpec. +

+

P4TypeInfo is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P416 program. These +named types are struct, header, header_union, enum and +serializable_enum; for each of these we have a type specification message, +respectively P4StructTypeSpec, P4HeaderTypeSpec, P4HeaderUnionTypeSpec, +P4EnumTypeSpec and P4SerializableEnumTypeSpec. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. P4TypeInfo also includes the list of parser errors for the program, as +a P4ErrorTypeSpec message. +

+

P4DataTypeSpec is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each P4DataTypeSpec message corresponds to a compile-time type in the +original P416 program (e.g. the type parameter of an extern). This +compile-time type is represented as a Protobuf oneof, which can be: +

+
    +
  • +

    a string representing the name of the type in case of a named type (struct, +header, header_union, enum, serializable_enum or user-defined “new” +type), +

  • +
  • +

    an empty Protobuf message for bool and error, or +

  • +
  • +

    a Protobuf message for other anonymous types (bit<W>, int<W>, varbit<W>, +tuple or stack). The “binary string” types (bit<W>, int<W>, and +varbit<W>) are grouped together in the P4BitstringLikeTypeSpec message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf bytes +type). +

+ +

For all P416 compound types (tuple, struct, header, and header_union), +the order of members in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P416 declaration. The same goes for the order of members of an enum +(serializable or not) or members of error. +

8.5.3. P4Data in p4runtime.proto

+

P4Runtime uses the P4Data message to represent values of arbitrary types. The +P4Runtime client must generate correct P4Data messages based on the type +specification information included in P4Info. The P4Data message was designed +to introduce little overhead compared to using binary strings in the most common +case (P416 bit<W> type). +

+

Just like its P4Info counterpart - P4DataTypeSpec -, P4Data uses a Protobuf +oneof to represent all possible values. +

+

We define a canonical representation for P4Data messages therefore +guaranteeing read-write symmetry by introducing the following requirements: +

+
    +
  • +

    The order of members in P4StructLike and the order of bitstrings in +P4Header must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P416 type +declaration. +

  • +
  • +

    An invalid header is represented by a P4Header message where the is_valid +field is false and the bitstrings repeated field is empty. +

  • +
  • +

    An invalid header union (i.e. all headers in the union are invalid) is +represented by a P4HeaderUnion message where the valid_header_name is the +empty string (default value for the field) and the valid_header is unset. +

  • +
  • +

    The order of entries in P4HeaderStack and P4HeaderUnionStack is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the entries field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding P4HeaderStackTypeSpec or +P4HeaderUnionStackTypeSpec message. +

+

8.5.4. Example

+

Let's look at the Register example again: +

+
+
+
header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

Here's the corresponding entry in the P4Info message: +

+
+
+
registers {
+  preamble {
+    id: 369119267
+    name: "register_ip"
+    alias: "register_ip"
+  }
+  type_spec {
+    header_union {
+      name: "ip_t"
+    }
+  }
+  size: 128
+}
+type_info {
+  headers {
+    key: "ipv4_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  headers {
+    key: "ipv6_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  header_unions {
+    key: "ip_t"
+    value {
+      members {
+        name: "ipv4"
+        header {
+          name: "ipv4_t"
+        }
+      }
+      members {
+        name: "ipv6"
+        header {
+          name: "ipv6_t"
+        }
+      }
+    }
+  }
+}
+

Here's a p4.WriteRequest to set the value of register_ip[12]: +

+
+
+
update {
+  type: INSERT
+  entity {
+    register_entry {
+      register_id: 369119267
+      index {
+        index: 12
+      }
+      data {
+        header_union {
+          valid_header_name: "ipv4"
+          valid_header {
+            is_valid: true
+            bitstrings: "\x04"
+            bitstrings: # ...
+          }
+        }
+      }
+    }
+  }
+}

8.5.5. enum, serializable enum and error

+

P416 supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or “unsafe” enum) +[5]. For enum types with no underlying type as well as error +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in P4Data to represent enum and +error values. +

+

Serializable enum types have an underlying fixed-width unsigned integer +representation (bit<W>). All named enum members must be assigned an integer +value by the P4 programmer, but not all valid numeric values for the +underlying type need to have a corresponding name. P4TypeInfo includes the +mapping between entry name and entry value. When providing serializable enum +values through P4Data, one must use the assigned integer value (enum_value +bytestring field). P4Runtime does not provide a way for the client to use the +name even when the enum member has one instead of the value, as it makes +it easier for the server to respect the read-write +symmetry principle. +

8.5.6. User-defined types

+

P416 enables programmers to introduce new types [11]. While similar +to typedef, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +translation. When introducing a new type, the +declaration can be annotated with @p4runtime_translation to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for port numbers, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. The @p4runtime_translation annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (bit<W>). The type exposed to the control plane (referred to as the +controller_type) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a URI (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the controller_type of the values exposed to the control plane. The +controller_type can be either bit<W> where W is any positive integer, or +string, or a positive integer W which has the same meaning as bit<W>. +Specifying just an integer is deprecated. +

+

It is recommended that the URI includes at least the P4 architecture name and +the type name. +

+

A @p4runtime_translation annotation need not have any effect if it is used to +annotate anything in a P4 program other than a type declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect. +

+

User-defined types are specified using the P4NewTypeSpec message, which has +the following fields: +

+
    +
  • +

    representation, a Protobuf oneof specifying how values of this type are +exchanged between client and server; it can be either: +

    +
      +
    • +

      original_type, if and only if no @p4runtime_translation annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 type declaration is itself a +user-defined type, original_type is obtained by “walking” the chain of +type declarations recursively until a built-in type (e.g. bit<W>) is +found. +

    • +
    • +

      translated_type, if and only if the P4 type declaration was annotated +with @p4runtime_translation. It is of type P4NewTypeTranslation, +which itself has two fields uri and either sdn_string or +sdn_bitwidth , which map to the two input parameters to the +annotation. +

    +
  • +
  • +

    annotations, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration. +

+ +

For example, an architecture in this case PSA may introduce a new type +for port numbers: +

+
+
+
// Controller refers to ports as a string, e.g. "eth0".
+@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+// Controller refers to ports as a 32-bit integer, e.g. 0xffffffff.
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+// Same as above.
+@p4runtime_translation("p4.org/psa/v1/PortId_32_t", 32)
+type bit<9> PortId_32_t;
+

In this case, the P4Info message would include the following P4TypeInfo +messages: +

+
+
+
type_info {
+  new_types {
+    key: "PortId_String_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_String_t"
+        sdn_string: {}
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_Bit32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_Bit32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+

Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (e.g. through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over @p4runtime_translation to enable users +to overwrite annotations included as part of the P4 architecture definition. +

8.5.7. Trade-off for v1.x Releases

+

For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +bytes with P4Data in the p4.v1.FieldMatch message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +bytes to provide action parameter values and controller metadata +values. However P4Data is used whenever appropriate for PSA externs and we +encourage the use of P4Data in architecture-specific extensions. +

+

In order to support translation for action +parameters and match fields, we include a type_name field in +p4.config.v1.MatchField, p4.config.v1.Action.Param and +p4.config.v1.ControllerPacketMetadata.Metadata. In addition, the bitwidth +field for all of these message types must abide by the following rule when +type_name names a translated user-defined type: +

+
    +
  • +

    If the controller_type is a fixed-width unsigned bitstring, the bitwidth +field must be set to the bitwidth of the controller_type. This information +is redundant with the one included in the P4TypeInfo entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent. +

  • +
  • +

    Otherwise (i.e., if the controller_type is a string), the bitwidth must +be “unset”, which, in Protobuf version 3, is the same as setting the field to +0. +

+ +

For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types: +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+@name(".t")
+table t {
+  key = {
+    meta.port1: exact;  // meta.port1 has type PortId_String_t
+    meta.port2: exact;  // meta.port2 has type PortId_Bit32_t
+  }
+  actions = {
+    drop;
+  }
+}
+

This table would have the following representation in the generated P4Info +message: +

+
+
+
tables {
+  preamble {
+    id: 34728461
+    name: "t"
+    alias: "t"
+  }
+  match_fields {
+    id: 1
+    name: "meta.port1"
+    # notice that bitwidth is unset
+    match_type: EXACT
+    type_name {
+      name: "PortId_String_t"
+    }
+  }
+  match_fields {
+    id: 2
+    name: "meta.port2"
+    bitwidth: 32
+    match_type: EXACT
+    type_name {
+      name: "PortId_Bit32_t"
+    }
+  }
+  # ...
+}

9. P4 Entity Messages

+

P4Runtime covers P4 entities that are either part of the P416 language, or +defined as PSA externs. The sections below describe the messages for each +supported entity. +

9.1. TableEntry

+

The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action's +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification. +

+

P4Runtime supports inserting, modifying, deleting and reading table entries with +the TableEntry entity, which has the following fields: +

+
    +
  • +

    table_id, which identifies the table instance; the table_id is determined +by the P4Info message. +

  • +
  • +

    match, a repeated field of FieldMatch messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration. +

  • +
  • +

    action, which indicates which of the table's actions to execute in case of +match and with which argument values. +

  • +
  • +

    priority, a 32-bit integer used to order entries when the table's match key +includes an optional, ternary or range match. +

  • +
  • +

    controller_metadata, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +metadata field. +

  • +
  • +

    metadata, an arbitrary bytes value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. +

  • +
  • +

    meter_config, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    counter_data, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    is_default_action, a boolean flag which indicates whether the table entry is +the default entry for the table. See Default entry +section for more information. +

  • +
  • +

    idle_timeout_ns and time_since_last_hit, which are two fields used to +implement idle-timeout support for the table, if applicable. See +Idle-timeout section for more information. +

+ +

The priority field must be set to a non-zero value if the match key includes a +ternary match (i.e. in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an OPTIONAL, TERNARY or +RANGE match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches. +

+

The match and priority fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for MODIFY and DELETE updates. When deleting +an entry, these key fields (along with is_default_action) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a keyless +table (the table has an empty match key), the server must reject all attempts to +INSERT a match entry and return an INVALID_ARGUMENT error. +

+

The number of match entries that a table should support is indicated in P4Info +(size field of Table message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P416 specification for the +size property [30]. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +RESOURCE_EXHAUSTED when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached. +

9.1.1. Match Format

+

The bytes fields in the FieldMatch message follow the format described in +Bytestrings. +

+

For “don't care” matches, the P4Runtime client must omit the field's entire +FieldMatch entry when building the match repeated field of the TableEntry +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for “don't care” matches, which is needed +to ensure read-write symmetry. For PSA match types, +a “don't care” match for a specific match key field is defined as follows: +

+
    +
  • +

    For a TERNARY match, it is logically equivalent to a mask of zeros. +

  • +
  • +

    For a OPTIONAL match, it is logically equivalent to a wildcard match. +

  • +
  • +

    For an LPM match, it is logically equivalent to a prefix_len of zero. +

  • +
  • +

    For a RANGE match, it is logically equivalent to a range which includes all +possible values for the field. +

+ +

Note that there is no “don't care” value for EXACT matches and therefore exact +match fields can never be omitted from the TableEntry message. +

+

The following example shows a P4Runtime message that treats a TERNARY field +as a “don't care” match. The P4 program defines table t with TERNARY +and EXACT fields in its match key: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: ternary;
+    istd.ingress_port: exact;
+  }
+  actions = {
+    drop;
+  }
+}
+

In this P4Runtime request, the client omits the table's TERNARY field +from the repeated match field to indicate a “don't care” match. As shown +below, the match specifies only the EXACT field given by field_id: 2. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 33554439  # Table t's ID.
+    match {
+      # field_id 1 is not present to use the don't care ternary value.
+      field_id: 2
+      exact {
+        value: "\x20"
+      }
+    }
+    action {
+      # Action selection goes here.
+    }
+  }
+}
+

For every member of the TableEntry repeated match field, field_id must be +a valid id for the table, as per the P4Info, and one of the fields in +field_match_type must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an INVALID_ARGUMENT error code. +

+
    +
  • EXACT match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.exact().value()))
+
    +
  • LPM match + +
      +
    • The binary string encoding of the value (when present) must conform to the +Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • “Don't care” bits must be 0 in value. +
+ +
+
+
assert(BytestringValid(match.lpm().value()))
+
+pLen = match.lpm().prefix_len()
+assert(pLen > 0)
+
+trailing_zeros = countTrailingZeros(match.lpm().value())
+assert(trailing_zeros >= field_bits - pLen)
+
    +
  • TERNARY match + +
      +
    • The binary string encoding of the value (when present) and mask (when +present) must conform to the Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • Masked bits must be 0 in value. This constraint taken together +with the Bytestrings requirements means that the +value's binary string is never longer than the mask's binary string. +When the value's string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask. +
+ +
+
+
assert(BytestringValid(match.ternary().value()))
+assert(BytestringValid(match.ternary().mask()))
+assert(match.ternary().value().size() <= match.ternary().mask().size());
+
+value = parseInteger(match.ternary().value())
+mask = parseInteger(match.ternary().mask())
+
+assert(mask != 0)
+
+assert(value & mask == value)
+
    +
  • RANGE match + +
      +
    • The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the Bytestrings +requirements. +
    • +
    • Low bound must be less than or equal to the high bound. +
    • +
    • “Don't care” match must be omitted. +
+ +
+
+
assert(BytestringValid(match.range().low()))
+assert(BytestringValid(match.range().high()))
+
+low = parseInteger(match.range().low())
+high = parseInteger(match.range().high())
+
+assert(low <= high)
+
+assert(low != min_field_value || high != max_field_value)
+
    +
  • OPTIONAL match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.optional().value()))

9.1.2. Action Specification

+

The TableEntry action field must be set for every INSERT update but may be +left unset for MODIFY updates, in which case the action specification for the +table entry will not be modified (if a MODIFY update has an unset action field +and does not modify any direct resource attached to the table then the MODIFY +update is a no-op). Based on the implementation property value of the P4 table, +the oneof in the TableAction message will either be: +

+
    +
  • +

    an Action specification for direct tables (with no P4 implementation +property) +

  • +
  • +

    an action profile member id for indirect tables for which the implementation +property is an action profile with no selector. +

  • +
  • +

    an action profile member id or group id for indirect tables for which the +implementation property is an action profile with selector. +

  • +
  • +

    an ActionProfileActionSet specification for indirect tables for +which the implementation property is an action profile with +selector. This usage is described in One Shot Action Selector +Programming +

+ +

If the oneof does not match the table description in the P4Info (e.g. the +oneof is action_profile_member_id for a direct table), the server must +return an INVALID_ARGUMENT error code. +

+

The Action Protobuf message has the following fields: +

+
    +
  • +

    action_id, which identifies the action instance; the action_id is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an INVALID_ARGUMENT error +code. If the client uses a valid action_id for the table but does not +respect the action scope specified in P4Info (e.g. tries to set a TABLE_ONLY +action as the default action), the server must return a PERMISSION_DENIED +error code. +

  • +
  • +

    params: a repeated Protobuf field of action parameter values, each encoded +as a Param message. For each parameter, param_id must be valid for the +action (as per the P4Info) and value must follow the format described in +Bytestrings. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an INVALID_ARGUMENT error code +if a parameter id is missing, if an extra parameter id not found in the +P4Info was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +Bytestrings format. +

+ +

For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a NOT_FOUND error code. +

9.1.3. Default Entry

+

According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer or defaults to NoAction +(which is a no-op) otherwise and assuming it is not declared as const, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow INSERT and DELETE updates on the default entry and the +P4Runtime server must return an INVALID_ARGUMENT error code if the client +attempts one. +

+

The default entry is identified by setting the is_default_action boolean field +to true. When this flag is set to true, the repeated match field must be empty +and the priority field must be set to zero, otherwise the P4Runtime server +must return an INVALID_ARGUMENT error code. When performing a MODIFY update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its controller_metadata and metadata value as well as the +configurations for its direct resources will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a PERMISSION_DENIED +error code if the client attempts to modify it. +

+

Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to direct resources. +

+

In this P4Runtime release, we have decided to restrict the default entry for +indirect tables tables with an ActionProfile or ActionSelector +implementation property to a constant NoAction action entry, with the +hope that it would simplify the implementation of the P4Runtime service. +

9.1.4. Constant Tables

+

Constant tables are defined as tables whose match entries are immutable. They +are identified by the is_const_table flag in P4Info. +

+

The only write updates which are allowed for constant tables are MODIFY +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +PERMISSION_DENIED error. Just like any table entry MODIFY request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a PERMISSION_DENIED error. +

+

The contents of const tables can be queried by the client through a +ReadRequest. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: table_id, match, action, +is_default_action, and priority (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the priority field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P416 does not support assigning explicit priorities to static +entries. When a priority value is required (e.g. for tables including RANGE, +TERNARY or OPTIONAL matches), it is inferred based on the order in which +entries appear in the table declaration. +

9.1.5. Wildcard Reads

+

When performing a ReadRequest, the P4Runtime client can select all entries +from one or all tables on the target and use several of the TableEntry fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as priority and “unset” for message fields such as match. The following +fields may be used to select and filter results: +

+
    +
  • table_id: If default (0), entries from all tables including constant +tables will be selected and no other filter can be used. Otherwise only +the specified table will be considered. +
  • +
  • match: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned. +
  • +
  • action: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an action_id (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id. +
  • +
  • priority: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value. +
  • +
  • controller_metadata: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +controller_metadata value. +
  • +
  • metadata: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided metadata value. +
  • +
  • is_default_action: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered. +
+ +

For example, in order to read all entries from all tables from device 3, the +client can use the following ReadRequest message. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0
+    priority: 0
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following ReadRequest +message: +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+    priority: 11
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

The canonical representation of “don't care” matches, combined with the ability +to do a wildcard read on all table entries by leaving the match field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single “don't care” entry or to do a wildcard +read. If a table has no fields with match kind EXACT, it is possible via +P4Runtime to add an entry that is “don't care” for all fields (i.e. has an empty +match field) but is not the default entry (i.e. is_default_action is +false). When reading this entry from the table, there is no way to read only +that entry from the table, because it would require providing an unset match +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single LPM match: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: lpm;
+  }
+  actions = {
+    drop; fwd;
+  }
+}
+

The following WriteRequest message can be used to add 2 entries: +

+
+
+
device_id: 3
+entities {
+  table_entry { # don't care entry
+    table_id: 0x0212ab34
+    # ...
+  }
+  table entry {
+    table_id: 0x0212ab34
+    match {
+      field_id: 1
+      lpm {
+        value: 0x0a000000
+        prefix_len: 8
+      }
+    # ...
+  }
+}
+

The first entry is a “don't care” entry, while the second one matches all +10.0.0.0/8 addresses. The second entry has higher priority than the first one. +

+

The following ReadRequest message will return all entries in the table, not +just the “don't care” entry. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+  }
+}
+

This issue also exists for tables with TERNARY, RANGE, and OPTIONAL +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the “don't care” entry will be returned to the +client. If the client uses distinct priority values for all entries which is +strongly recommended to achieve deterministic behavior , +then there is no ambiguity because the wildcard read will actually return a +single entry (the “don't care” entry) as long as the priority field is set to +the correct value. +

9.1.6. Direct Resources

+

In addition to the DirectCounterEntry and DirectMeterEntry entities, +P4Runtime support reading and writing direct resources as part of the +TableEntry message. This is convenient for two reasons: +

+
    +
  • +

    A table entry and its direct resources can be read with a single entity when +doing a Read RPC call +

  • +
  • +

    The initial configuration for an entry's direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can “hit” the table entry without +executing the appropriate meter entry. +

+ +

Once the table entry has been inserted, the P4Runtime client is free to use the +DirectCounterEntry and DirectMeterEntry messages for read and write +operations on DirectCounter and DirectMeter instances. For example, it is +usually more convenient as well as more efficient to use DirectCounterEntry to +query a counter entry value rather than use TableEntry, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry. +

+

The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does not need to be “executed” in +every action bound to the table. It is an error to provide a direct resource +configuration in a TableEntry message when programming an action that does not +execute the direct resource, and the server must return an INVALID_ARGUMENT +error code. +

+

We leverage Protobuf's ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the TableEntry message. The list below describes how +the server must handle the meter_config and counter_data fields for read and +write requests, based on whether the fields are set or not. We do not cover +error cases in the list, i.e. we assume that we are dealing with a table which +is assigned a direct counter / a direct meter, and that the action being used +for the table entry “executes” the direct resource appropriately. +

+
    +
  • +

    meter_config field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets). +
      • +
      • if set: The initial configuration for the meter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The meter entry's configuration is reset to the default +(meter returns GREEN for all packets). +
      • +
      • if set: The value provided by the client is used to re-configure +the meter entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the meter entry's +configuration (meter_config is unset in the response). +
      • +
      • if set: If the meter entry's configuration is the default +configuration, meter_config is unset in the response. Otherwise, the +response includes the meter entry's configuration that was written by +the client earlier. This respects the “read-write symmetry” principle. +
    +
  • +
  • +

    counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for the counter entry is the default +(0). +
      • +
      • if set: The initial value for the counter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The counter entry's value is not changed. +
      • +
      • if set: The value provided by the client is written to the counter +entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the counter entry's value +(counter_data is unset in the response). +
      • +
      • if set: The response includes the counter entry's value read from +the target. +
    +
+ +

In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +meter_config field unset when inserting or modifying a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the TableEntry message +(i.e. the meter_config field must be set to match the existing configuration). +

9.1.7. Idle-timeout

+

P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not “hit” (i.e. not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification using the +IdleTimeoutNotification message to the master client, which can then take +action, such as remove the idle table entry. +

+

Two fields of the TableEntry Protobuf message are used to implement idle +timeout: +

+
    +
  • +

    idle_timeout_ns: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, i.e. no +IdleTimeoutNotification message will ever be generated for this entry. When +a client reads a TableEntry, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry. +

  • +
  • +

    time_since_last_hit: a Protobuf message with a single field (elapsed_ns) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The time_since_last_hit field must be unset for a +TableEntry write. When reading a table entry, time_since_last_hit must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0. +

+ +

These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an INVALID_ARGUMENT error code if at least one of these +conditions is met: +

+
    +
  • idle_timeout_ns is set to a non-zero value, or +
  • +
  • time_since_last_hit is set +
+ +

The target should do its best to approximate the idle_timeout_ns value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the TableEntry write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for time_since_last_hit. +

+

P4Runtime does not support idle timeout for default entries. When the +is_default_action flag is set in a TableEntry message, idle_timeout_ns +must be set to 0 (default) and time_since_last_hit must be unset. If the +server receives a TableEntry message which violates this, it must return an +INVALID_ARGUMENT error. +

+

For more information about idle timeout, in particular regarding +IdleTimeoutNotification, please refer to the Table idle timeout +notifications section. +

9.2. ActionProfileMember & ActionProfileGroup

+

P4Runtime defines an API for programming a PSA ActionProfile extern using +ActionProfileMember messages. A PSA ActionSelector extern can be programmed +using both ActionProfileMember and ActionProfileGroup messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table t for L3 routing, implemented with an action +selector as. +

+
+
+
ActionSelector(HashAlgorithm.crc32,
+               /*size = */ 32w1024,
+               /*output_width = */ 32w10) as;
+
+action set_nhop(PortId_t p, EthAddr smac, EthAddr dmac) {
+  istd.egress_port = p;
+  hdr.ethernet.smac = smac;
+  hdr.ethernet.dmac = dmac;
+}
+
+table t {
+  key = {
+    hdr.ipv4.dip: lpm;  // LPM on destination IP address
+  }
+  actions = {
+    set_nhop;
+  }
+  implementation = as;
+}
+

When programming table t in the example above, a P4Runtime client should +specify the TableAction in the TableEntry to be a reference to either an +action profile member or group. The reference is a non-zero uint32 identifier +that uniquely identifies a member or group programmed in the action selector +as. +

+

If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata. +

+

If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata. +

9.2.1. Action Profile Member Programming

+

Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a uint32 identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the actions +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the actions attributes of the +tables must have an identical list of P4 actions. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector. +

+

An ActionProfileMember entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info. +

  • +
  • +

    member_id is the non-zero uint32 identifier of the action profile member +entry being updated. +

  • +
  • +

    action is the specification of the P4 action instance bound to the action +profile member entry. +

+ +

An action profile member may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an ALREADY_EXISTS error +code. The action specification must be provided, or the server must return +INVALID_ARGUMENT. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return RESOURCE_EXHAUSTED. +
  • +
  • MODIFY: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return NOT_FOUND, +and the action specification must be provided, or the server must return +INVALID_ARGUMENT. +
  • +
  • DELETE: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a NOT_FOUND error code. The member +must not be part of an action profile group, or the server must return +FAILED_PRECONDITION. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return FAILED_PRECONDITION. action_profile_id and member_id are the only +fields that are considered when performing a DELETE and every other field +will be ignored. +
+ +

When reading, an ActionProfileMember message with action_profile_id and +member_id equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with action_profile_id equal to the id of +an existing ActionProfile or ActionSelector object, and a member_id equal to +0, will read all members of that specified object. +

9.2.2. Action Profile Group Programming

+

Action profile groups are entries in an ActionSelector and are referenced by a +uint32 identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type. +

+

Within a single ActionSelector object, the uint32 values used to identify its +members are in a separate ‘scope’ from the uint32 values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5. +

+

There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it. +

+

An ActionProfileGroup entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionSelector +extern instance, as defined in P4Info. +

  • +
  • +

    group_id is the non-zero uint32 identifier of the action profile group +entry being updated. +

  • +
  • +

    members is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields: +

    +
      +
    • member_id for looking up the member table in the selector. +
    • +
    • weight specifying the probability of the member's selection at +runtime. 0 is not a valid weight value and the server must return +INVALID_ARGUMENT if the client attempts to use it. +
    • +
    • watch is the controller-defined 32-bit port number that the member's +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +9.2.4 for notes on the behavior if all members in +a group are excluded for this reason. If watch is 0, then the member is +always included in the selection, regardless of the status of any port of +the device. The value must be 0 or the SDN port number of an existing +port on the device, otherwise the server must return INVALID_ARGUMENT. +
    +
  • +
  • +

    max_size is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +MODIFY update. See the subsection below for the rules on setting +max_size. +

+ +

An action profile group may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new group entry bound to a set of existing action profile +members. The group_id must be different from ids of already programmed +groups for that selector, or the server must return an ALREADY_EXISTS error +code. All members specified in the group must exist in the selector, or the +server must return NOT_FOUND. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target. +
  • +
  • MODIFY: Modify the member set specification of an existing group entry. An +entry with the group_id must exist, or the server must return +NOT_FOUND. All members specified in the group entry must exist in the +selector, or the server must return NOT_FOUND. The value of max_size must +be identical to the value used when inserting the group, otherwise an +INVALID_ARGUMENT error is returned. +
  • +
  • DELETE: Delete the group entry and deallocate the group_id. The group must +not be referenced in the table action of any table entry, or the server must +return a FAILED_PRECONDITION error code. If the group_id is invalid, the +server must return NOT_FOUND. action_profile_id and group_id are the +only fields that are considered when performing a DELETE and every other +field will be ignored. +
+ +

When setting the group membership with INSERT or MODIFY, the members +repeated field must not include duplicates, i.e. members with the same +member_id. The weight field is used instead to logically “repeat” the member +inside the group. +

+

It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation “stores” the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made. +

+

When reading, an ActionProfileGroup message with action_profile_id and +group_id equal to 0 will read all groups of all ActionSelector objects. A +message with action_profile_id equal to the id of an existing ActionSelector +object, and a group_id equal to 0, will read all groups of that one specified +object. +

9.2.2.1. Rules on Setting max_size
+

The valid values for max_size depend on the static max_group_size included +in the P4Info message: +

+
    +
  • +

    If max_group_size is greater than 0, then max_size must be greater than 0, +and less than or equal to max_group_size. We assume that the target can +support selector groups for which the sum of all member weights is up to +max_group_size, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If max_size is greater than max_group_size, the server +must return INVALID_ARGUMENT. +

  • +
  • +

    Otherwise (i.e. if max_group_size is 0), the P4Runtime client can set +max_size to any value greater than or equal to 0. +

    +
      +
    • +

      A max_size of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (INSERT or MODIFY), the target must return a +RESOURCE_EXHAUSTED error. +

    • +
    • +

      If max_size is greater than 0 and the value is not supported by the +target, the server must return a RESOURCE_EXHAUSTED error at +group-creation time. +

    +
+

9.2.3. One Shot Action Selector Programming

+

P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids. +

+

One shots are programmed by choosing the ActionProfileActionSet message as the +TableAction. The ActionProfileActionSet message consists of a set of +ActionProfileAction messages, which in turn have the following fields: +

+
    +
  • +

    action is one of the actions specified by the table that is being +programmed. +

  • +
  • +

    weight specifying the probability of the action's selection at runtime. 0 is +not a valid weight value and the server must return INVALID_ARGUMENT if +the client attempts to use it. The sum of all weights across all +ActionProfileAction messages for that ActionProfileActionSet message must +not exceed the max_group_size specificed in the P4Info (if greater than 0), +or the server must return INVALID_ARGUMENT. +

  • +
  • +

    watch is the controller-defined 32-bit port number that the action's +liveness depends on. At runtime, the action must be excluded from selection if +the watch port is down. See Section +9.2.2 for more details on the watch field, +which also apply for one shot action selector programming. +

+ +

Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics. +

+

To preserve read-write symmetry, an implementation must answer ReadRequests +with the original one shot messages. It may not return a desugared version of +the one shot message. +

+

For example, consider the action selector table defined +here. This table could be programmed +with the following one shot update: +

+
+
+
table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action {
+    action_profile_action_set {
+      action_profile_actions {
+        action { /* set nexthop 1 */ }
+        weight: 1
+        watch: 1
+      }
+      action_profile_actions {
+        action { /* set nexthop 2 */ }
+        weight: 2
+        watch: 2
+      }
+      action_profile_actions {
+        action { /* set nexthop 3 */ }
+        weight: 3
+        watch: 3
+      }
+    }
+  }
+}
+

Which would be equivalent to the following updates, where GROUP_ID, +MEMBER_ID_1, MEMBER_ID_2, and MEMBER_ID_3 are unused ids: +

+
+
+
action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_1
+  action { /* set nexthop 1 */ }
+}
+action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_2
+  action { /* set nexthop 2 */ }
+}
+action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_3
+  action {  /* set nexthop 3 */ }
+}
+action_profile_group {
+  action_profile_id: 0x11ab12cd
+  group_id: GROUP_ID
+  members {
+    member_id: MEMBER_ID_1
+    weight: 1
+    watch: 1
+  }
+  members {
+    member_id: MEMBER_ID_2
+    weight: 2
+    watch: 2
+  }
+  members {
+    member_id: MEMBER_ID_3
+    weight: 3
+    watch: 3
+  }
+}
+table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action { action_profile_group_id: GROUP_ID }
+}
+

Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure correct ordering between the dependent +updates. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct WriteRequest batches are required. +

+

It is possible to include several ActionProfileAction messages with the same +exact action specification in one ActionProfileActionSet message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the weight field. Note that to preserve read-write symmetry, the server +must not coalesce multiple ActionProfileAction messages with the same action +specification into one. +

+

All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with ActionProfileMember and +ActionProfileGroup messages. Programming some entries with one shots, and +other entries with ActionProfileMember and ActionProfileGroup messages is +not allowed, and the server must return the error code INVALID_ARGUMENT in +that case. +

+

A P4Runtime server must support the one shot style of programming tables with +an action selector implementation. Support for the ActionProfileMember and +ActionProfileGroup style is optional. If ActionProfileMember and +ActionProfileGroup are not supported by a server, it must return an +UNIMPLEMENTED error for every ActionProfileMember or ActionProfileGroup +message that it receives. +

9.2.4. Constraints on action selector programming

+

The PSA specification states that the following features are optional in +action selector implementations [22]: +

+
    +
  1. Support for non-empty groups where in the same group, different members are +bound to different actions. +
  2. +
  3. Predictable data plane behavior when a matched table entry points to an empty +group. +
+ +

For 1., if a client tries to INSERT or MODIFY a group with members bound to +different actions, the server should return UNIMPLEMENTED if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return UNIMPLEMENTED (modifying the action parameter values must be +supported, however). +

+

PSA 1.1 introduces the psa_empty_group_action table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. psa_empty_group_action is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of psa_empty_group_action at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +NoAction. Even when psa_empty_group_action is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of psa_empty_group_action mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming. +

+

The PSA specification includes a discussion on how to implement +psa_empty_group_action in software in the P4Runtime server +[25]. +

+

If a P4Runtime implementation does support psa_empty_group_action, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down. +

+

If a P4Runtime implementation does not support psa_empty_group_action, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down. +

9.3. CounterEntry & DirectCounterEntry

+

PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The CounterData +P4Runtime message can be used for all three types of PSA counters PACKETS, +BYTES and PACKETS_AND_BYTES and consists of the following fields: +

+
    +
  • byte_count is an int64, corresponding to the number of octets. +
  • +
  • packet_count is an int64, corresponding to the number of packets. +
+ +
+
+
message CounterData {
+  int64 byte_count = 1;
+  int64 packet_count = 2;
+}
+

P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of byte_count and packet_count fields, which +is equivalent to specifying the counter type PACKETS_AND_BYTES. Counters may +be defined as direct or indirect (indexed) instances. +

9.3.1. DirectCounterEntry

+

A direct counter is a direct resource associated with a TableEntry (see +Direct Resources). The counter_data field of the +TableEntry message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +DirectCounterEntry message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed. +

+
+
+
message DirectCounterEntry {
+  TableEntry table_entry = 1;
+  CounterData data = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectCounterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match TableEntry.match of the table entry +to which this direct counter entry is associated. If a matching TableEntry +is not found, the server returns the error code NOT_FOUND. +

  • +
  • +

    data is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified. +

+ +

Specifying DirectCounterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read the contents of a +DirectCounter: +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the counter value in the counter_data field of the TableEntry message +(see Direct resources). +

  • +
  • +

    Explicitly request the counter value by including the DirectCounterEntry in +the ReadRequest. The table_entry.match field must match the TableEntry +whose counter is being read. If no such entry is found, the server returns the +error code NOT_FOUND. +

+

9.3.2. CounterEntry

+

An indirect or indexed counter is not associated with a specific TableEntry +and may be updated independently of any action. It may be read or written using +the P4Runtime CounterEntry message whose fields are defined as follows: +

+
    +
  • +

    counter_id is a uint32, the unique identifier for the counter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +the counter array. +

  • +
  • +

    data is a Protobuf message of type CounterData, which represents the +counter value. +

+ +
+
+
message CounterEntry {
+  uint32 counter_id = 1;
+  Index index = 2;
+  CounterData data = 3;
+}
+

The CounterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the counter entries in the +array have default value 0. +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect counter instance whose unique id is counter_id +and array index is specified by index. The counter value is set to the value +specified by the client in the data field. Note that the counter value is +not modified if this Protobuf field is not set. If index is omitted all +counter values in the array will be set to the value provided by the +client. The server must return INVALID_ARGUMENT for a negative index value +and OUT_OF_RANGE if the index value exceeds the size of the counter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a ReadRequest by including a CounterEntry +entity for each of the instances, specifying the counter_id and +index. Wildcard reads are also supported as follows. +

+
    +
  • +

    If the counter_id field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id counter_id. +

+

9.4. MeterEntry & DirectMeterEntry

+

Meters are an advanced mechanism for keeping statistics, involving stateful +“marking” and usually “throttling” of packets based on configured rates of +traffic. The PSA metering function is based on the Two Rate Three Color Marker +(trTCM) defined in RFC 2698 [2]. The trTCM meters an arbitrary packet +stream using two configured rates the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes and +“marks” its packets as GREEN, YELLOW or RED based on the observed rate. +

+

A meter may be configured as a direct or indirect instance, similar to a +counter. The MeterConfig P4Runtime message represents meter configuration. +

+
+
+
message MeterConfig {
+  int64 cir = 1;  // Committed Information Rate
+  int64 cburst = 2;  // Committed Burst Size
+  int64 pir = 3;  // Peak Information Rate
+  int64 pburst = 4;  // Peak Burst Size
+}

9.4.1. DirectMeterEntry

+

A direct meter is a direct resource associated with a TableEntry (see Direct +resources). The meter_config field of the TableEntry +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +DirectMeterEntry message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed. +

+
+
+
message DirectMeterEntry {
+  TableEntry table_entry = 1;
+  MeterConfig config = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectMeterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match the match key of the TableEntry +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching TableEntry is not found, +the server returns the error code NOT_FOUND. +

  • +
  • +

    config is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets). +

+ +

Specifying DirectMeterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read a DirectMeter config. +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the meter config in the meter_config field of the TableEntry +message (see Direct resources). +

  • +
  • +

    Explicitly request the meter configuration by including the DirectMeterEntry +in the ReadRequest. The table_entry.match field must match the +TableEntry whose meter config is being read. If no such entry is found, the +server returns the error code NOT_FOUND. +

+

9.4.2. MeterEntry

+

An indirect or indexed meter is not associated with a specific TableEntry and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime MeterEntry message whose fields are defined as +follows: +

+
    +
  • +

    meter_id is a uint32, the unique identifier for the meter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +a meter array. +

  • +
  • +

    config is a Protobuf message of type MeterConfig, which represents the +meter configuration. +

+ +
+
+
message MeterEntry {
+  uint32 meter_id = 1;
+  Index index = 2;
+  MeterConfig config = 3;
+}
+

The MeterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the meter entries in the +array have a default configuration (GREEN for all packets). +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect meter instance whose unique id is meter_id and +array index is specified by index. The meter is reconfigured using the +config field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the index field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if config is unset). The server must return INVALID_ARGUMENT for a +negative index value and OUT_OF_RANGE if the index value exceeds the size of +the meter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a ReadRequest by including a MeterEntry entity for each +of the instances, specifying the meter_id and index. Wildcard reads are also +supported as follows: +

+
    +
  • +

    If the meter_id field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id meter_id. +

+

9.5. PacketReplicationEngineEntry

+

The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets. +

9.5.1. MulticastGroupEntry

+

Multicasting is achieved in PSA programs by setting the multicast_group +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the MulticastGroupEntry API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example. +

+
+
+
control arp_multicast(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ethernet.isValid() &&
+        hdr.ethernet.eth_type == ETH_TYPE_ARP) {
+      smeta.multicast_group = (MulticastGroup_t) 1;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    multicast_group_entry {
+      multicast_group_id: 1
+      replicas { egress_port: 5 instance: 1 }
+      replicas { egress_port: 12 instance: 2 }
+      replicas { egress_port: 18 instance: 3 }
+      replicas { egress_port: 24 instance: 4 }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +PSA Metadata Translation section. +

+

The egress packets may be distinguished for further processing in the egress +using the instance metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 multicast_group metadata is set to a value that is not +programmed in the PRE, then the packet is dropped. +

+

A multicast group may be inserted, modified or deleted as per the following +semantics. +

+
    +
  • INSERT: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The multicast_group_id field is a uint32 and must be greater +than 0 (see explanation below), or the +P4Runtime server must return an INVALID_ARGUMENT error. The replica +instance ID is also a uint32, and its value may not exceed the maximum +allowed by the target for the EgressInstance_t type (0 is allowed), or the +server must return an INVALID_ARGUMENT error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of both egress_port and instance, or the server +must return INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify the set of replicas for a given multicast group entry, +indexed by the given multicast_group_id. Same restrictions as INSERT apply +here. +
  • +
  • DELETE: Delete the multicast group indexed by the given +multicast_group_id. The replicas need not be provided for this +operation. Any packets with their multicast_group metadata in the data plane +set to the deleted multicast_group_id will be dropped. +
+ +

When reading a multicast group, only multicast_group_id is considered. All +other fields in MulticastGroupEntry are ignored. To perform a wildcard +Read on all configured multicast group entries, the multicast_group_id field +must be set to 0, its default value. +

9.5.1.1. Valid Values for multicast_group_id
+

The PSA specification states that the valid data plane values for multicast +group ids (MulticastGroup_t) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target [24]. This means that, in the absence of +translation, the client must set the multicast_group_id field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special wildcard value which is used to read all the multicast groups +configured in the target, the multicast_group_id field must never be set to 0 +when performing a Write RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value. +

9.5.2. CloneSessionEntry

+

PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +clone_session_id identifier and a boolean flag clone in the packet +metadata. The clone_session_id serves as a handle to the clone attributes, +namely a set replicas of (egress port, instance) pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +CloneSessionEntry API. +

+

The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the clone_low_ttl control block is applied in the ingress +pipeline to create an ingress-to-egress clone. +

+
+
+
control clone_low_ttl(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ipv4.isValid() &&
+        hdr.ipv4.ttl <= LOW_TTL_THRESHOLD) {
+      smeta.clone_session_id = 10w100;
+      smeta.clone = true;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    clone_session_entry {
+      session_id: 100
+      replicas { egress_port: 0xfffffffd instance: 1 } # to CPU
+      class_of_service: 2
+      packet_length_bytes: 4096
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type CloneSessionId_t [24]). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes. +

+

The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port 0xfffffffd; see +Translation of Port Numbers). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port. +

+

If the clone_session_id data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created. +

+

A clone session may be inserted, modified or deleted as per the following +semantics: +

+
    +
  • INSERT: Add a new clone session entry bound to a set of egress ports and +replica IDs. The session_id is a uint32 and must be greater than 0 (see +explanation below), or the P4Runtime +server must return an INVALID_ARGUMENT error. The replica instance ID is +also a uint32, and its value may not exceed the maximum allowed by the +target for the EgressInstance_t type (0 is allowed), or the server must also +return an INVALID_ARGUMENT error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (class_of_service field). This value must be a valid +value for the PSA ClassOfService_t type, which supports runtime translation +by default [24], or the server must return +INVALID_ARGUMENT. See PSA Metadata +Translation for more information. The +packet_length_bytes field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +packet_length_bytes field is 0 (default), no truncation on the clone will be +performed. +
  • +
  • MODIFY: Modify the attributes of a given clone session entry, indexed by the +given clone_session_id. Same restrictions as INSERT apply here. +
  • +
  • DELETE: Delete the clone session indexed by the given +clone_session_id. Other fields need not be provided for this operation. Any +packet with their clone_session_id metadata in the data plane set to the +deleted session_id will no longer be cloned. +
+ +

When reading a clone session, only session_id is considered. All other fields +in CloneSessionEntry are ignored. To perform a wildcard Read on all +configured clone session entries, the session_id field must be set to 0, its +default value. The session_id field can never be equal to 0 in a Write +RPC. If it does, the server must return an INVALID_ARGUMENT error. +

9.5.2.1. Valid Values for session_id
+

The PSA specification states that the valid data plane values for clone +session ids (CloneSessionId_t) range from 0 to the maximum value supported by +the target [24]. Note that unlike for multicast group +ids, 0 is a valid data plane value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special wildcard value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a session_id +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is not enabled, we effectively +“lose” one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (e.g. because the target supports a very +limited number of clone sessions), one can enable translation on +CloneSessionId_t and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id. +

9.6. ValueSetEntry

+

Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the parse_trill_types state. +

+
+
+
state parse_l2 {
+  @id(1) value_set<ETH_TYPE_BITWIDTH>(MAX_TRILL_TYPES) trill_types;
+  extract(hdr.ethernet);
+  select (hdr.ethernet.eth_type) {
+    ETH_TYPE_IPV4: parse_ipv4;
+    ETH_TYPE_IPV6: parse_ipv6;
+    trill_types:   parse_trill_types;
+    _:             reject;
+  }
+}
+

The corresponding entry in the P4Info for this Value Set is: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "trill_types"
+  }
+  match {
+    id: 1
+    bitwidth: <ETH_TYPE_BITWIDTH>
+    match_type: EXACT
+  }
+  size: <MAX_TRILL_TYPES>
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0x22f3 }
+      }
+      match {
+        field_id: 1
+        exact { value: 0x893b }
+      }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the parse_trill_types state. +

+

A ValueSetEntry entity update message has the following fields: +

+
    +
  • +

    value_set_id is the uint32 identifier of the Value Set instance, as +defined in P4Info. +

  • +
  • +

    members is a repeated field of type ValueSetMember. When “selecting” +against a Value Set, every member will be considered and if at least one +“matches”, the corresponding parser transition will be taken. Each +ValueSetMember contains a repeated field of FieldMatch messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a ValueSetMember if and only if +it matches all its FieldMatch messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. FieldMatch messages in a ValueSetEntry follow +the same rules as in a TableEntry. +

+ +

A ValueSetEntry may only be modified. If the update type is INSERT or +DELETE, the server must return an INVALID_ARGUMENT error. If the update type +is MODIFY, the server writes the members given in the repeated field to the +Value Set entry indexed by the given value_set_id. The maximum number of +matches must not exceed the maximum size given by the size field in P4Info of +the Value Set, otherwise the server must return a RESOURCE_EXHAUSTED error. To +empty a Value Set (i.e. restore it to its initial state), the P4Runtime client +can perform a MODIFY update with an empty members repeated field. +

+

To facilitate read-write symmetry, the server must +return an ALREADY_EXISTS error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set. +

+

See Appendix A.3 for a more complex Value Set example. +

9.7. RegisterEntry

+

The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The RegisterEntry P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations. +

+

RegisterEntry has the following fields: +

+
    +
  • +

    register_id, which identifies the PSA Register extern instance which is +being accessed by the client; the register_id is specified by the P4Info +message. +

  • +
  • +

    index, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the RegisterEntry message +used for the request. When an index is provided , the server must validate +its value, and return INVALID_ARGUMENT for a negative index or +OUT_OF_RANGE if the index exceeds the size of the register array. +

  • +
  • +

    data: the data to be written to the array (if RegisterEntry is part of a +WriteRequest message) or the data read from the array (if RegisterEntry is +part of a ReadResponse message). The data field is a P4Data message and +must match the format described by the type_spec field of the corresponding +Register entry in the P4Info, or the server must return an INVALID_ARGUMENT +error. +

+

9.8. DigestEntry

+

A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly. +

+

The DigestEntry P4Runtime entity is used to configure how the device must +generate digest messages. The DigestEntry Protobuf message is not used to +carry digest data, which is done on the StreamChannel bidirectional stream +using the DigestList (digest data sent by the target to the client) and +DigestListAck (digest data acknowledgments sent by the client to the target) +Protobuf messages. +

+

In this section, we refer to the data learned by a single data plane call to +Digest<T>::pack as a “digest message” and we use “digest list” to designate +the list of digest messages bundled by the P4Runtime service in a single +DigestList stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are “duplicate” if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are “distinct” +if they are not duplicate. +

+

DigestEntry has the following fields: +

+
    +
  • +

    digest_id, which identifies the PSA Digest extern instance which emitted the +data; the digest_id is determined by the P4Info message. +

  • +
  • +

    config, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +digest_id; these parameters are: +

    +
      +
    • max_timeout_ns: the maximum server buffering delay in nanoseconds for an +outstanding digest message. +
    • +
    • max_list_size: the maximum digest list size in number of digest +messages sent by the server to the client as a single DigestList +Protobuf message. +
    • +
    • ack_timeout_ns: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data. +
    +
+ +

Here is the significance of the different Update types for DigestEntry: +

+
    +
  • INSERT: Enable server generation of DigestList messages for given digest +instance and use provided configuration parameters. +
  • +
  • MODIFY: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance. +
  • +
  • DELETE: Disable server generation of DigestList messages for given digest +instance. +
+ +

A server should buffer digest messages until either: +

+
    +
  • max_timeout_ns time has passed since the first digest message was added to +the empty buffer, or +
  • +
  • max_list_size distinct digest messages have been received from the +data plane and added to the buffer +
+ +

At which point the server should, with best effort, generate a DigestList +stream message with the buffer contents and send it to the master client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software. +

+

To avoid sending duplicate digest messages across different DigestList +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the master client indicates that it has received the +digest list and acted on it. The server must keep a “cache” containing the set +of all digest messages that have been sent, but not acknowledged yet by the +master client, up-to ack_timeout_ns in the past. The server must delete all +cache entries for a given digest list when they are at least ack_timeout_ns +old or when a matching DigestListAck message (i.e. with the same digest_id +and list_id fields as the DigestList message) is received. +

+

The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged DigestList messages. +

+

When max_timeout_ns is set to 0 and / or max_list_size is set to 1, the +server should, with best effort, generate a DigestList message for every +digest message generated by the data plane which is not already in the cache. If +ack_timeout_ns is set to 0, the cache must always be an empty set. If +max_list_size is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +max_timeout_ns configuration parameter. +

+

The P4Runtime server may empty the digest message cache in case of a client +mastership change. +

+

Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server: +

+
+
+
DigestStream stream;
+DigestCache cache;
+DigestBuffer buffers;
+
+// sends digest list when it is ready
+send_buffer(Id digest_id) {
+  buffer = buffers[digest_id];
+  stream.write(DigestList(buffer));
+  cache.merge(buffer);  // updates cache with new digest list
+  buffer.clear();
+}
+
+// callback which handles data plane digest messages from device
+handle_dataplane_digest(Digest msg) {
+  digest_id = msg.digest_id();
+  buffer = buffers[digest_id];
+  if (msg in cache OR msg in buffer) return;
+  buffer.enqueue(msg);
+  if (buffer.length() < max_list_size(digest_id)) return;
+  send_buffer(digest_id);
+}
+
+// callback which handles ack messages received on the stream
+handle_stream_ack(DigestListAck ack) {
+  // clear all cache entries matching the tuple (digest_id, list_id)
+  cache.erase( (ack.digest_id(), ack.list_id() )
+}
+
+// loop to enforce timeouts
+while (true) {
+  now = now();
+  // check for buffers that need to be sent
+  for ((digest_id, buffer) in buffers) {
+    if (now - buffer.first_enq_time() >= max_timeout_ns(digest_id))
+      send_buffer(buffer_id);
+  }
+  // check for expired entries in cache
+  for ((digest_id, list_id, sent_time) in cache) {
+    if (now - sent_time >= ack_timeout_ns(digest_id))
+      cache.erase( (digest_id, list_id) );
+  }
+  sleep(X);
+}

9.9. ExternEntry

+

This is used to support a P4 extern entity that is not part of PSA. It is +defined as: +

+
+
+
message ExternEntry {
+  uint32 extern_type_id = 1;
+  uint32 extern_id = 2;
+  google.protobuf.Any entry = 3;
+}
+

Each ExternEntry entity maps to an Extern message in the +P4Info and an ExternInstance message within that +message. The extern_type_id field must be equal to the one in +ExternEntry. The extern_id field must be equal to the ID included in the +preamble of the corresponding ExternInstance message. +

+

entry itself is embedded as an Any Protobuf message [31] to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on Extending P4Runtime for non-PSA +Architectures for more information. +

10. Error Reporting Messages

+

P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case. +

+

gRPC uses grpc::Status [32] to represent the status returned by an +RPC. It has 3 attributes: +

+
+
+
StatusCode code_;
+grpc::string error_message_;
+grpc::string binary_error_details_;
+

The code_ represents a canonical error [34] and describes the +overall RPC status. The error_message_ is a developer-facing error message, +which should be in English. The binary_error_details_ carries a serialized +google.rpc.Status message [28] message, which has 3 fields: +

+
+
+
int32 code = 1;  // see code.proto
+string message = 2;
+repeated google.protobuf.Any details = 3;
+

The code and message fields must be the same as code_ and error_message_ +fields from grpc::Status above. The details field is a list that consists of +p4.Error messages that carry error details for individual elements inside +batch-request RPCs (e.g. Write and Read). p4.Error includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices [34]. +

+

Figure 7 illustrates how these messages fit together. +

+
+

error-report +

+
+ +
Figure 7. P4Runtime Error Report Message Format
+

gRPC provides utility functions ExtractErrorDetails() and SetErrorDetails() +[33] to easily convert between grpc::Status and +google.rpc.Status. +

+

Please see sections on individual P4Runtime RPCs for details on how +grpc::Status is populated for reporting errors. +

+

Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on Stream Error +Reporting for more information. +

11. Atomicity of Individual Write and Read Operations

+

Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane apply +operation, and every single Write operation on a table that inserts, deletes, +or modifies one table entry, the apply operation should behave as if that +Write operation has not yet occurred, or as if the Write operation is +complete. The P4 program should never behave as if the Write operation is +partially complete. These guarantees also apply to extern instances: Read and +Write operations on extern entities must execute atomically relative to extern +data plane methods. +

+

The atomicity guarantees provided by P4Runtime for individual Read and Write +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification [23]. +

+

The P416 language introduces an @atomic annotation [14], to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the @atomic annotation for Write +operations, as well as non-wildcard Read operations, +relative to data plane execution. Consider the following P4 example written for +PSA: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024) r1;
+
+  apply {
+    // ...
+    @atomic {
+        Value_t v = r1.read((Index_t)1);
+        v = v + 1;
+        r1.write((Index_t)1, v);
+    }
+  }
+}
+

If a P4Runtime server is processing messages which write to Register r1 at +index 1, these writes must not happen between the data plane read and +write. +

+

Now let's consider the following example: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024, (Value_t)0 /* initial value */) r1;
+
+  apply {
+    @atomic {
+        r1.write((Index_t)1, (Value_t)100);
+        r1.write((Index_t)2, (Value_t)100);
+    }
+    @atomic {
+        r1.write((Index_t)1, (Value_t)200);
+        r1.write((Index_t)2, (Value_t)200);
+    }
+  }
+}
+

If a P4Runtime client issues a wildcard Read on Register r1, there is no +guarantee that r1[1] == r1[2] in the response, as the read for r1[1] may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for r1[2] may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read r1[1] and r1[2] separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +ReadRequest message) of individual read requests. Similar to a batch +ReadRequest, a wildcard read of a register can execute the reads of the +register array elements (r1[1], r1[2], ) in an arbitrary order relative +to each other. +

+

If the @atomic annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program. +

12. Write RPC

+

The Write RPC updates one or more P4 entities on the target. The request is +defined as follows: +

+
+
+
message WriteRequest {
+  uint64 device_id = 1;
+  uint64 role_id = 2;
+  Uint128 election_id = 3;
+  repeated Update updates = 4;
+  enum Atomicity {
+    CONTINUE_ON_ERROR = 0;
+    ROLLBACK_ON_ERROR = 1;
+    DATAPLANE_ATOMIC = 2;
+  }
+  Atomicity atomicity = 5;
+}
+

The device_id uniquely identifies the target P4 device. The role_id and +election_id define the client role and election-id as described in the +Master-Slave Arbitration and Controller +Replication +section. The server is expected to perform the following checks (in this order) +before processing the updates list: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role_id does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the master for (device_id, role_id) according to the +election_id value, the server must return a PERMISSION_DENIED error. +

  4. +
  5. +

    If the Write is attempted before a ForwardingPipelineConfig has been set, +the server must return a FAILED_PRECONDITION error. +

+ +

The updates field is a list of P4 entity updates to be applied. Each update is +defined as: +

+
+
+
message Update {
+  enum Type {
+    UNSPECIFIED = 0;
+    INSERT = 1;
+    MODIFY = 2;
+    DELETE = 3;
+  }
+  Type type = 1;
+  Entity entity = 2;
+}
+

This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a logical table (e.g. +CounterEntry) or an actual table (e.g. TableEntry) in the P4 data +plane. Each entity in the container is uniquely identified by its key. Please +refer to the P4 Entity Messages section for details on +what parts of the entity specification make up the key for each P4 entity. +

+

An update can be one of the following types: +

+
    +
  • +

    INSERT: Inserts the given P4 entity in the entity container. +The entity field always specifies the full state of the P4 entity. +If the entity already exists, an ALREADY_EXISTS error is returned, and +the existing entity remains unchanged. +If the entity is malformed, an INVALID_ARGUMENT error is returned. +If the entity cannot be inserted because the container is already full, +a RESOURCE_EXHAUSTED error is returned. +

  • +
  • +

    MODIFY: Modifies the P4 entity to its new specified state. This uses +assign or full-snapshot semantics, i.e. the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an INVALID_ARGUMENT error is usually returned (unless a +more specific error code applies [34]). If the entity does not +exist, a NOT_FOUND error is returned. +

  • +
  • +

    DELETE: Deletes the specified P4 entity. If the entity does not exist, a +NOT_FOUND error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored. +

+ +

If an update is not allowed under the given controller role, the server must +return a PERMISSION_DENIED error for this update. +

12.1. Batching and Ordering of Updates

+

P4Runtime supports batching of Write operations. The list of updates in a +WriteRequest is referred to as a batch. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of TableEntry entities). +

+

The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +WriteRequests can also be processed interleaved and/or in parallel. +However, the processing of requests must be strictly serializable. That +is, given a history $S$ of WriteRequests including the responses to those +requests, there must exist an order $L$ for all updates in $S$, such that: +

+
    +
  1. All updates from the same write request must appear as a contiguous +subsequence in $L$, but the order within that subsequence can be arbitrary. +
  2. +
  3. For two updates $u_1$ and $u_2$, if the write request containing $u_1$ +completed before the write request of $u_2$ was sent, then $u_1$ must appear +before $u_2$ in $L$. +
  4. +
  5. Executing all updates in $L$ sequentially must yield the same response for +every update as in $S$. +
  6. +
  7. The observable state of the switch after $S$ (e.g., through the Read RPC) +is identical to the one obtained by sequentially executing $L$. +
+ +

The Write RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the Write RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (e.g. inserting an ActionProfileMember +followed by pointing a TableEntry to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding Write RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate Write calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each Write call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one. +

12.2. Batch Atomicity

+

A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the Atomicity +enum. A P4Runtime server is required to support only the modes marked as +Required below: +

+
    +
  • +

    Required: CONTINUE_ON_ERROR: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that see each of +these intermediate stages. +

  • +
  • +

    Optional: ROLLBACK_ON_ERROR: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is all-or-none, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that see each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure. +

    +

    If a P4Runtime server does not support this option at all, an +UNIMPLEMENTED error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (e.g. it is +more straightforward to implement batches that contain only INSERT +operations, vs. those that contain DELETE operations), an +UNIMPLEMENTED error is returned when the batch cannot be executed +in a data plane-atomic way. +

  • +
  • +

    Optional: DATAPLANE_ATOMIC: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +transaction. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane's table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table. +

    +

    If a P4Runtime server does not support this option at all, an UNIMPLEMENTED +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an UNIMPLEMENTED error is returned when the batch +cannot be executed in a data plane-atomic way. +

+ +

There is no expectation that a given client must always use the same Atomicity +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use DATAPLANE_ATOMIC at one time and default behavior +(CONTINUE_ON_ERROR) at other times. +

12.3. Error Reporting

+

Please see section Error Reporting Messages for +information on error reporting messages and guidelines. P4Runtime server will +populate grpc::Status as follows: +

+
    +
  1. +

    If all batch updates succeeded, set grpc::Status::code_ to OK and do not +populate any other field. +

  2. +
  3. +

    If an error is encountered before even trying to attempt individual batch +updates, set grpc::Status::code_ that best describes that RPC-wide +error. For example, use UNAVAILABLE if the P4Runtime service is not yet +ready to handle requests. Set error_message_ to describe the issue. Do not +set error_details in this case. +

  4. +
  5. +

    Otherwise, if one or more updates in the batch (WriteRequest.updates) +failed, set grpc::Status::code_ to UNKNOWN. For example, one update in +the batch may fail with RESOURCE_EXHAUSTED and another with +INVALID_ARGUMENT. A p4.Error message is used to capture the status of +each and every update in the batch. The number of p4.Error messages packed +into google.rpc.Status.details field should therefore always match the +number of updates in the WriteRequest, and the order of +p4.Error messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +p4.Error should set the code to OK and omit other fields. +

+ +
+
+
# Example of a grpc::Status returned for a Write RPC with a batch of 3 updates.
+# The first and third updates encountered an error, while the second update
+# succeeded.
+code_ = 2  # UNKNOWN
+error_message_ = "Write failure."
+binary_error_details {
+  code: 2  # UNKNOWN
+  message: "Write failure."
+  details {
+    canonical_code: 8  # RESOURCE_EXHAUSTED
+    message: "Table is full."
+    space: "targetX-psa-vendorY"
+    code: 500  # ERR_TABLE_FULL
+  }
+  details {
+    canonical_code: 0  # OK
+  }
+  details {
+    canonical_code: 6  # ALREADY_EXISTS
+    message: "Entity already exists."
+    space: "targetX-psa-vendorY"
+    code: 600  # ERR_ENTITY_ALREADY_EXISTS
+  }
+}

13. Read RPC

+

The Read RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as: +

+
+
+
message ReadRequest {
+  uint64 device_id = 1;
+  repeated Entity entities = 2;
+}
+

The device_id uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +NOT_FOUND error. The entities repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server. +

+

Since ReadRequests do not mutate any state on the switch, they do not +require an election_id, and they do not require the presence of an open +StreamChannel between the server and client. +

+

The Read response consists of a sequence of messages (a gRPC stream) with +each message defined as: +

+
+
+
message ReadResponse {
+  repeated Entity entities = 1;
+}
+

The entities repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the Finish() method on the stream object +[10]). +

13.1. Nomenclature

+
+
request
+
An element of the p4.ReadRequest.entities repeated field. +
+
batch
+
Refers to the p4.ReadRequest.entities repeated field.
+

Each request acts as a query filter for that entity type. If a request fully +specifies the entity key, the Read operation should retrieve a single P4 +entity. Please refer to the P4 Entity Messages section +for details on what parts of the entity specification make up the entity key. +

13.2. Wildcard Reads

+

P4Runtime allows wildcard read of P4 entities. A request may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the P4 Entity Messages section for details on +what parts of the entity can be wildcarded in a given request. +

+

For example, in a request of type CounterEntry: +

+
    +
  • A default counter_id (0) implies a request to read all counter-entries for +all indirect counters. +
  • +
  • A particular (non-default) counter_id in conjunction with index unset +implies a request to read all counter-entries for the given indirect counter +ID. +
+ +

To read the entire forwarding state for a given device, the P4Runtime client can +generate the following ReadRequest: +

+
+
+
device_id: <ID>
+entities {
+  extern_entry { }  # read all extern instances for all supported extern types
+  table_entry { }  # read all table entries for all tables
+  action_profile_member { }  # read all members for all action profiles
+  action_profile_group { }  # read all groups for all action profiles
+  ...
+}
+

The entity oneof field in the Entity message must always be set, or the +server must return an INVALID_ARGUMENT error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty Entity message in the ReadRequest. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the entity oneof [20]. +

13.3. Batch Processing

+

A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type request +appears only once in the batch. +

+

A P4Runtime server will process the batch as follows: +

+
    +
  1. +

    Lock state (preventing new writes) and validate each request in the batch: +

    +
      +
    1. +

      If it is a valid request, perform the read; +

      +
        +
      1. If the read was successful, return the entities read in +ReadResponse stream. +
      2. +
      3. If the read failed (exception / critical-error), prepare a p4.Error +with code set to INTERNAL. +
      +
    2. +
    3. +

      If the request is invalid (invalid-argument, not-supported, etc.), +prepare a p4.Error with relevant canonical code to capture the error. +

    +
  2. +
  3. +

    Unlock the state (allowing new writes); +

  4. +
  5. +

    Close the ReadResponse stream and return a grpc::Status as follows: +

    +
      +
    1. +

      If no errors were encountered, set code to OK and do not populate any +other field. +

    2. +
    3. +

      Otherwise, the overall code should be set to UNKNOWN. See section +Error Reporting Messages for information +on error reporting messages and guidelines. Assemble a list of p4.Error +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +google.rpc.Status.details field. This behavior also matches Write +RPC. +

    +
+

13.3.1. Example

+

If a client asked to read {a,b,c,d} and b and d requests didn't +validate, the server will return entities corresponding to a and c, followed +by a status {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} in the +details field. +

+

The P4Runtime server is not required to perform any optimization (e.g. merge two +requests in the batch if one is a subset of other). As a result of this, it +is possible for the ReadResponse to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging. +

+

There is no requirement that each request in the batch will correspond to one +ReadResponse message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit. +

+

A P4Runtime server must be prepared to handle multiple concurrent Read RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (e.g. in a single-threaded architecture), it may choose to serialize +Read RPC processing. +

13.4. Parallelism of Read and Write Requests

+

A P4Runtime server may be implemented to serve at most one +ReadRequest or WriteRequest message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so. +

+

For example, imagine a client that wanted to use WriteRequest +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +WriteRequest messages with only a few updates to an ActionSelector +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +WriteRequest batch currently being processed, but it will not +complete for a significant amount of time. +

+

The restrictions on which a client may rely are: +

+
    +
  • The processing of any two WriteRequest messages W1 and W2 must +result in the same state as if one of them was completed before the +other began. +
  • +
  • For any WriteRequest W and any ReadRequest R, R must +return results consistent with a state where W has completed +processing, or W has not yet begun processing. +
+ +

For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a WriteRequest message it acquired a write lock for each stateful +object affected by the WriteRequest, and before starting the +processing of a ReadRequest message it acquired a read lock for each +stateful object accessed by the ReadRequest, such an implementation +meets all of the requirements above. +

+

It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, e.g. if the server somehow determined that two +WriteRequest messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly. +

14. SetForwardingPipelineConfig RPC

+

A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the SetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message SetForwardingPipelineConfigRequest {
+  enum Action {
+    UNSPECIFIED = 0;
+    VERIFY = 1;
+    VERIFY_AND_SAVE = 2;
+    VERIFY_AND_COMMIT = 3;
+    COMMIT = 4;
+    RECONCILE_AND_COMMIT = 5;
+  }
+  uint64 device_id = 1;
+  uint64 role_id = 2;
+  Uint128 election_id = 3;
+  Action action = 4;
+  ForwardingPipelineConfig config = 5;
+}
+

The server is expected to perform the following checks (in this order) +before performing the required action: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role_id does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the master for (device_id, role_id) according to the +election_id value, the server must return a PERMISSION_DENIED error. +

+ +

The action is the type of configuration action requested, it can be one of: +

+
    +
  • +

    VERIFY: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an INVALID_ARGUMENT +error if config is not provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_SAVE: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent Read / Write requests must refer to fields in the new +config. Returns an INVALID_ARGUMENT error if the forwarding config is not +provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_COMMIT: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an INVALID_ARGUMENT error if the forwarding config is not provided or if the +provided config cannot be realized. +

  • +
  • +

    COMMIT: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a NOT_FOUND error if no saved config +is found, i.e. if no VERIFY_AND_SAVE action preceded this one. Returns an +INVALID_ARGUMENT error if a config is provided with this message. +

  • +
  • +

    RECONCILE_AND_COMMIT: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an UNIMPLEMENTED error. For targets that support this option, an +INVALID_ARGUMENT error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target. +

+ +

The config field is a message of type ForwardingPipelineConfig that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(e.g. generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the Forwarding-Pipeline +Configuration section for details. +

+

A P4Runtime server running on a non-programmable device may not +support SetForwardingPipelineConfig (e.g. the forwarding-pipeline +config is part of the device's software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +UNIMPLEMENTED error. +

15. GetForwardingPipelineConfig RPC

+

The forwarding-pipeline configuration of the target can be retrieved by invoking +the GetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message GetForwardingPipelineConfigRequest {
+  enum ResponseType {
+    ALL = 0;
+    COOKIE_ONLY = 1;
+    P4INFO_AND_COOKIE = 2;
+    DEVICE_CONFIG_AND_COOKIE = 3;
+  }
+  uint64 device_id = 1;
+  ResponseType response_type = 2;
+}
+

The device_id uniquely identifies the target P4 device. A NOT_FOUND error is +returned if the device_id is not recognized by the P4Runtime server. +

+

The response_type is used to specify which fields to populate in the response, +its value can be one of: +

+
    +
  • +

    ALL: returns a ForwardingPipelineConfig with all fields +set as stored by the target. This is the default behaviour if the +response_type field is not set. +

  • +
  • +

    COOKIE_ONLY: reply by setting only the cookie field in the +ForwardingPipelineConfig, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message. +

  • +
  • +

    P4INFO_AND_COOKIE: reply by setting the p4info and cookie fields. +

  • +
  • +

    DEVICE_CONFIG_AND_COOKIE: reply by setting the p4_device_config and +cookie fields. +

+ +

The response contains the ForwardingPipelineConfig for the specified device: +

+
+
+
message GetForwardingPipelineConfigResponse {
+  ForwardingPipelineConfig config = 1;
+}
+

If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level config field will be unset in the response. Examples are +(i) a server that only allows configuration via SetForwardingPipelineConfig +but this RPC hasn't been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn't yet occurred. +

+

Once a forwarding-pipeline config is installed on the device (either via +SetForwardingPipelineConfig or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +config.p4_device_config will be empty / unset in the response, even if +response_type in the request was set to ALL. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the SetForwardingPipelineConfig RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +SetForwardingPipelineConfig, the value of config.cookie will be unset. +

+

If a P4Runtime server supports both SetForwardingPipelineConfig as well as +returning the p4_device_config, there should be read-write symmetry between +SetForwardingPipelineConfig and GetForwardingPipelineConfig RPCs. +

16. P4Runtime Stream Messages

16.1. Packet I/O

+

P4Runtime supports controller packet-in and packet-out by means of PacketIn +and PacketOut stream messages, respectively. +

+

PacketIn messages are sent by the P4Runtime server to the client. Conversely, +PacketOut messages are sent by the client to the server. Any PacketOut +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a StreamMessageResponse message with the error field set to +report the error to the client. See the section on Stream Error +Reporting for more information on error. +

+

As introduced in the ControllerPacketMetadata +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with @controller_header. The expected metadata is described +in the P4Info using the ControllerPacketMetadata messages. +

+

Both PacketIn and PacketOut stream messages share the same fields and are +defined as follows: +

+
+
+
// Packet sent from the controller to the switch.
+message PacketOut {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+// Packet sent from the switch to the controller.
+message PacketIn {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+message PacketMetadata {
+  // This refers to Metadata.id coming from P4Info ControllerPacketMetadata.
+  uint32 metadata_id = 1;
+  bytes value = 2;
+}
+
    +
  • +

    payload is used to carry the full packet content, including the headers. +

  • +
  • +

    metadata is a repeated field of PacketMetadata messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +ControllerPacketMetadata. Indeed, when a P4Runtime client (or server) +generates a PacketOut (or PacketIn) message, it needs to populate the +metadata field with as many values as in ControllerPacketMetadata.metadata +for the packet-out (or packet-in) case. Each PacketMetadata.value is a +binary string and must conform to the Bytestrings +requirements based on the corresponding P4Info +ControllerPacketMetadata.metadata specification. If the metadata field +does not match the P4Info specification, the server must drop the PacketOut +message and may generate a StreamMessageResponse message with the error +field set to report the error to the client which issued the PacketOut. See +the section on Stream Error Reporting for more +information on error. +

+

16.2. Master Arbitration Update

+

P4Runtime's master arbitration mechanism ensures that only the current master +can modify state on the switch, and that the election_id is monotonically +increasing. For example, the switch must finish all previous write operations +before changing masters, and must only accept write requests from the current +master. +

+

As explained earlier in this document, the controller uses the StreamChannel +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via Write RPC), +it needs to start a controller session and become a “master”. To do so, the +controller first opens a bidirectional stream channel to the server via +StreamChannel for each device and sends a StreamMessageRequest message. The +controller populates the MasterArbitrationUpdate field in this message using +its role_id and election_id and the device_id of the device, as explained +in detail in the Master-Slave Arbitration and Controller +Replication +section. For any given (device_id, role_id), the P4Runtime server keeps track +of the highest election_id that it has ever received. If a controller's +election_id is equal to the highest election_id that the server has ever +received, that controller is the master. All other controllers are slaves. Note +that it is possible that all controllers are slaves, and that there is no +master. There can be at most one master, because for any given +(device_id, role_id), each connected controller has a unique election_id. +

+

This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest election_id after such a restart. +However, across a full restart, the election_id must be +reset. In fact, a full restart is the only way to reset the election_id. +

+

The MasterArbitrationUpdate message is defined as follows: +

+
+
+
message Role {
+  // role_id for this role. Defined offline in agreement across the
+  // entire control plane.
+  uint64 id = 1;
+  // Describes the role configuration.
+  google.protobuf.Any config = 2;
+}
+
+message MasterArbitrationUpdate {
+  // Identifies the device (aka target or node or switching chip).
+  uint64 device_id = 1;
+  // The role for which the mastership is being arbitrated.
+  Role role = 2;
+  // The election_id (unique per role).
+  Uint128 election_id = 3;
+  // Switch populates this with OK for the client that is the master,
+  // and with an error status for all other connected clients (at
+  // every mastership change). The controller does not populate this
+  // field.
+  google.rpc.Status status = 4;
+}
+

Note that the status field in the MasterArbitrationUpdate message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a StreamMessageResponse message back to the controller, in which +it populates the MasterArbitrationUpdate message using the device_id, +role, and election_id it previously received from the controller. The server +also populates the status field in the MasterArbitrationUpdate according to +the rules in an earlier section. +

+

The sender need not specify an election_id. If the election_id is not +specified, the sender's election_id is considered lower than any +election_id, and the sender will thus never become master. This way, a +controller can choose to be a standby controller, in order to avoid master +“flapping” (if a standby controller connects to the switch shortly before the +actual master controller, therefore becoming master temporarily). +

16.3. Digest Messages

+

See the DigestEntry section. +

16.4. Table Idle Timeout Notification

+

When a table supports idle timeout (as per the P4Info message), the master +client can specify a TTL value for each entry in the table (see +Idle-timeout section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an IdleTimeoutNotification message on the +StreamChannel bidirectional stream to the master client. The master client can +then take the action of its choice, most likely remove the idle entry. +

+

The IdleTimeoutNotification Protobuf message has the following fields: +

+
    +
  • +

    timestamp: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server's local clock. +

  • +
  • +

    table_entry: a repeated field of entries which have expired. Each individual +entry is identified by a single TableEntry message. For each TableEntry, +the key fields (table_id, match and priority) must be set, along with +the controller_metadata field, the metadata field, and the +idle_timeout_ns field. Other fields may be set by the server but should be +ignored by the client. +

+ +

Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +IdleTimeoutNotification message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an IdleTimeoutNotification +message with an empty table_entry repeated field. +

+

After generating an idle notification, the P4Runtime server must “reset” the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the master client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle. +

+

Here is a reasonable pseudo-code implementation for idle timeout for table +entries: +

+
+
+
IdleTimeoutStream stream;
+
+scanning_interval = 10ms;
+
+while (true) {
+  // iterate over all tables which support idle timeout
+  for (table in tables) {
+    if (!table.idle_timeout_supported) continue;
+    // we coalesce all idle notifications for the same table in one
+    // message
+    IdleTimeoutNotification msg;
+    // read time_since_last_hit from device
+    entries = device.load_table_entries_from_hw(table);
+    for (entry in entries) {
+      if (entry.idle_timeout == 0) continue;  // no TTL
+      if (entry.time_since_last_hit < entry.idle_timeout) continue;
+      msg.table_entry_add(entry);
+      entry.reset_time_since_last_hit();
+    }
+    if (msg.table_entry_size() == 0) continue;  // no notifications
+    msg.set_timestamp(now());
+    stream.write(msg);
+  }
+  sleep(scanning_interval);
+}

16.5. Architecture-Specific Notifications

+

P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on StreamChannel, by including an Any Protobuf field [31] +named other in both StreamMessageRequest and StreamMessageResponse. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the PSA Digest +extern. See section on Extending P4Runtime for non-PSA +Architectures for more information. +

16.6. Stream Error Reporting

+

The P4Runtime server can asynchronously report errors which occur when +processing StreamMessageRequest messages, using the error message field (of +type StreamError) in StreamMessageResponse. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature. +

+

The StreamError message has the following fields: +

+
    +
  • canonical_code, which must be set to the appropriate canonical error code +[34]. +
  • +
  • message, an optional developer-facing error message describing the error. +
  • +
  • space and code, which are optional and can be used by vendors to provide +additional details on the error. code is a numeric error code drawn from a +vendor's chosen error space. +
  • +
  • details, which is a Protobuf oneof used to help the client identify which +StreamMessageRequest triggered the error. The server is required to set the +appropriate field in the oneof so that the client can identify which type +of stream message is responsible for the error (packet_out, +digest_list_ack or other), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid PacketOut message from the +client, the packet_out field (of type PacketOutError) should be set in +the details oneof, and the server may additionally set the packet_out +field in the PacketOutError sub-message (by copying it from the invalid +PacketOut message received on the stream channel) so that the client can +know exactly what packet-out triggered the error. +
+ +

The appropriate canonical error code [34] should be used when +populating the canonical_code field. For example: +

+
    +
  • if a controller is not allowed to send a PacketOut message under its +current role definition, the code should be set to PERMISSION_DENIED. +
  • +
  • if the metadata repeated field in PacketOut does not match the P4Info +definition, the code should be set to INVALID_ARGUMENT. It may be useful +for the server to set the packet_out field in this case, so that the client +can find out which set of metadata fields triggered the error. +
  • +
  • if the digest_id field in DigestListAck does not match any Digest entry +in P4Info, the code should be set to INVALID_ARGUMENT. +
+ +

The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, e.g. because of a +burst of PacketIn messages. +

+

Note that master-arbitration errors are never reported using the StreamError +message. Invalid MasterArbitrationUpdate messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section 5.3. +

16.6.1. Examples of StreamError Messages

+
    +
  • +

    Malformed packet-out metadata. If the server receives a PacketOut +message with a metadata field with id 7 which is not included in the P4Info +ControllerPacketMetadata message for “packet_out”, the server may send the +following StreamMessageResponse back to the client: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Unknown metadata field id 7."
    + packet_out {
    +   # copied from the PacketOut message received from the client
    +   packet_out {
    +     payload: ...
    +     metadata {
    +       id: 7
    +       name: "I_should_not_be_here"
    +       bitwidth: 32
    +     }
    +     # more metadata
    +   }
    + }
    +}
  • +
  • +

    Packet-out which exceeds the MTU. If the server receives a PacketOut +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following StreamMessageResponse: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Packet exceeds the MTU for port."
    + space: "targetX-psa-vendor1"
    + code: 123  # MTU_EXCEEDED
    + packet_out {
    +   # we do not set the packet_out field as it does not provide any
    +   # extra information to the client
    + }
    +}
+

17. Capabilities RPC

+

The Capabilities RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the CapabilitiesRequest message is empty and the CapabilitiesResponse +message only includes the p4runtime_api_version string field. This field must +be set to the full semantic version string [27] corresponding to the +version of the P4Runtime API implemented by the server, e.g. “1.1.0-rc.1”. +

+

Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three atomicity +modes for WriteRequest batches, two of them being +optional. In the future we may decide to leverage the CapabilitiesResponse +message to enable the server to report to the client which subset of these +atomicity modes is supported. +

+

The semantic version string included in CapabilitiesResponse can be used by +the client to determine which exact feature set is implemented by the server, +since minor releases may introduce new +functionality. However, because the Capabilities RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (i.e. an UNIMPLEMENTED error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0). +

18. Portability Considerations

18.1. PSA Metadata Translation

+

The Portable Switch Architecture (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +[24]. For such metadata, a translation between the controller's +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the @p4runtime_translation annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture. +

+
+

psa-metadata-translation +

+
+ +
Figure 8. P4Runtime Metadata Translation for the Portable Switch Architecture
+

Figure 8 illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller's 32 bit port +numbers to a target's 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch. +

18.1.1. Translation of Port Numbers

+

In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller's space and the PSA device's space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +user-defined P4 types, namely PortId_t and +PortIdInHeader_t, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in psa.p4 for +the PSA device in Switch 1. +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type bit<9> PortId_t;
+@p4runtime_translation("p4.org/psa/v1/PortIdInHeader_t", 32)
+type bit<32> PortIdInHeader_t;
+

The first argument to the @p4runtime_translation annotation is a URI that +indicates to the P4Runtime server which numerical mapping provided by the +out-of-band switch configuration mechanism to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports). +

+

An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows: +

+
+
+
enum SdnPort {
+  SDN_PORT_UNSPECIFIED = 0;
+
+  // SDN ports are numbered starting from 1.
+  SDN_PORT_MIN = 1;
+
+  // The maximum value of an SDN port (physical or logical).
+  SDN_PORT_MAX = 0xfffffeff;
+
+  // Reserved SDN port numbers (0xfffffff0 - 0xffffffff)
+
+  SDN_PORT_RECIRCULATE = 0xfffffffa;
+  SDN_PORT_CPU = 0xfffffffd;
+}
+

The switch config will map SDN_PORT_RECIRCULATE and SDN_PORT_CPU as well +as any SDN port number corresponding to a “regular” front-panel port to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation. +

+

The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs. +

18.1.2. Translation of Packet-IO Header Fields

+

Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  PortIdInHeader_t egress_port;
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  PortIdInHeader_t ingress_port;
+}
+

The header-level annotation @controller_header is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (egress_port) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI first argument to the @p4runtime_translation +annotation). Any subsequent reference to the egress_port field in the +data plane will use the translated value. PortIdInHeader_t is used in the +header definition instead of PortId_t to guarantee byte-aligned headers in +case this is required by the target. +

+

A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target's PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the ingress_port field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller. +

18.1.3. Translation of Match Fields

+

Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table's match key as shown in the example below: +

+
+
+
table t {
+  key = {
+    istd.ingress_port: exact;  // PSA standard metadata ingress port
+  }
+  actions = {
+    drop;
+  }
+}
+

Table t has an exact match on PSA standard metadata ingress port +(istd.ingress_port). Since the field is of type PortId_t, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in t from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table t is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values. +

+

Note that it may be infeasible to translate the value-mask pair for ternary +matches: LPM, TERNARY or RANGE match kinds. The P4Runtime server may +require that for these match kinds the port match be either de facto “exact” +(0xffffffff mask for TERNARY, prefix-length of 32 for LPM, or same low and +high bounds for RANGE) or “don't care”. +

18.1.4. Translation of Action Parameters

+

PortId_t type parameters can be part of a P4 action definition as shown in the +example below: +

+
+
+
action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+}
+
+table t {
+  key = {
+    hdr.h.f: exact;
+  }
+  actions = {
+    a;
+  }
+}
+

The controller may write entries in table t with action a to set the egress +port as shown in the P4 code above. The action parameter p is of type +PortId_t, which leads to a 32-bit bitwidth for p being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device. +

18.1.5. Port Translation for PSA Extern APIs

+

The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch field is +of type uint32 to carry the 32-bit SDN representation of the port being +watched. The P4Runtime server will translate the given watch port number into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device. +

+

The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type uint32 to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane. +

18.1.6. Using Port as an Index to a Register, Indirect Counter or Indirect Meter

+

P4Runtime supports using a translated value (PortId_t or any other translated +type for which the underlying built-in type is bit<W>) as an index to a +register, indirect counter, or indirect meter. +

+
+
+
Counter<bit<32> /* counter entry type */, PortId_t /* index type */>(
+  32w1024, PSA_CounterType_t.PACKETS) counter;
+action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+  counter.count(p);
+}
+

This P4 Counter declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
counters {
+  preamble {
+    id: 0x12000001
+    name: "counter"
+  }
+  spec {
+    unit: PACKETS
+  }
+  index_type_name {
+    name: "PortId_t"
+  }
+}
+

The controller may read and write counter values from indexed counter counter +using SDN port numbers as indices, and not device-specific port numbers. The +index_type_name field in the P4Info message is a signal to the P4Runtime +server that translation is required. +

19. P4Runtime Versioning

+

P4Runtime follows the Google guidelines for versioning cloud APIs +[6]. We use a MAJOR.MINOR.PATCH style version number scheme and +we increment the: +

+
    +
  • MAJOR version when we make incompatible API changes, +
  • +
  • MINOR version when we add functionality in a backwards-compatible manner, +
  • +
  • PATCH version when we make backwards-compatible bug fixes. +
+ +

The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is p4.v1 and the package +name for P4Info is p4.config.v1. Even though p4 and p4.config are two +different Protobuf packages, p4 depends on p4.config and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence. +

+

As recommended in [6], we may consider using pre-GA release +suffixes (such as alpha or beta) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1). +

+

Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner. [7] describes +what constitute a backwards-compatible change. We expect MAJOR version bumps +to be a rare event. +

+

Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor + patch version numbers in future releases. +

+

All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository [15] and the version label follows +semantic versioning rules [27]. +

20. Extending P4Runtime for non-PSA Architectures

+

P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place. +

+

When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names: +

+
    +
  • p4/[organization]/arch/config/<major version>/p4info.proto +
  • +
  • p4/[organization]/arch/<major version>/p4runtime.proto +
+ +

We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they “extend”. +

+

For the remainder of this section, we will refer to these two files as +p4info-ext and p4runtime-ext respectively. +

20.1. Extending P4Runtime for Architecture-Specific Externs

+

Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both p4info-ext and +p4runtime-ext. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example: +

+
+
+
// T must be a bit<W> type, it indicates the width of each counter cell
+extern MyNewPacketCounter<T> {
+  counter(bit<32> size);
+  increment(in bit<32> index);
+}

20.1.1. Extending the P4Info message

+
    +
  • Id prefixes 0x81 through 0xfe are reserved for architecture-specific +externs. It is recommended that p4info-ext include a P4Ids message based +on the one in p4info.proto that the P4 compiler can refer to when assigning +IDs to each extern instance. +
+ +
+
+
message P4Ids {
+  enum Prefix {
+    UNSPECIFIED = 0;
+    MY_NEW_PACKET_COUNTER = 0x81;
+  }
+}
+
    +
  • p4info-ext should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +p4.config.v1.ExternInstance message as the info +field, which is of type Any [31]. +
+ +
+
+
message MyNewPacketCounter {
+  // corresponds to the T type parameter in the P4 extern definition
+  p4.config.v1.P4DataTypeSpec type_spec = 1;
+  // constructor argument
+  int64 size = 2;
+}

20.1.2. Extending the P4Runtime Service

+

Just like p4info-ext, p4runtime-ext should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an ExternEntry message generated by the +P4Runtime client. +

+

Here is a possible Protobuf message for our MyNewPacketCounter P4 extern: +

+
+
+
// This message enables reading / writing data to the counter at the provided
+// index
+message MyNewPacketCounter {
+  int64 index = 1;
+  p4.v1.P4Data data = 2;
+}
+

P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an Any Protobuf field [31] named other +in both p4.v1.StreamMessageRequest and +p4.v1.StreamMessageResponse. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in p4runtime-ext and embed instances of these messages in +p4.v1.StreamMessageRequest and p4.v1.StreamMessageResponse as appropriate. +

20.2. Architecture-Specific Table Extensions

20.2.1. New Match Types

+

An architecture may introduce new table match types [12]. P4Runtime +accounts for this by providing the following hooks: +

+
    +
  • +

    The match field in p4.config.v1.MatchField (p4info.proto) is a oneof +which can be either one of the default match types (EXACT, LPM, TERNARY, +RANGE, or OPTIONAL) or an architecture-specific match type encoded as a +string. +

  • +
  • +

    The field_match_type field in p4.v1.FieldMatch (p4runtime.proto) is a +oneof which includes an Any Protobuf message [31] field +(other). p4info-ext should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in p4.v1.FieldMatch as the +other field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info. +

+

20.2.2. New Table Properties

+

An architecture may introduce additional table properties +[30]. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +p4.config.v1.Table message includes the other_properties Any Protobuf +field [31]. At the moment, there is not any mechanism to extend the +p4.v1.TableEntry message based on the value of architecture-specific table +properties, but we may include on in future versions of the API. +

21. Known Limitations of Current P4Runtime Version

+
    +
  • +

    FieldMatch, action Param, and controller packet metadata fields only +support unsigned bitstrings, i.e. values of one of the following types (not +the more general P4Data): +

    +
      +
    • bit<W> +
    • +
    • bool. Note that as far as the P4Info message contents and +thus controller software is concerned, such fields of type bool +will be indistinguishable from those that have been declared with +type bit<1>. P4Runtime server software will automatically +perform any conversion needed between the type bit<1> values in +P4Runtime messages and the data plane representation. +
    • +
    • an enum with underlying type bit<W> +
    • +
    • a type or typedef with an underlying type that is one of the above (or +in general a “chain” of type and/or typedef that eventually ends with +one of the types above) +
    +
  • +
  • +

    Support for PSA Random & Timestamp externs is postponed to a future minor +version update. +

  • +
  • +

    P4Info does not include information about which of a table's actions execute +which direct resource(s). +

  • +
  • +

    The default action for indirect match tables is restricted to a const +NoAction known at compile-time. +

  • +
  • +

    There is no mechanism for changing the value of the psa_empty_group_action +table property at runtime. +

  • +
  • +

    There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor + +patch version numbers. +

+

22. Security concerns for P4Runtime

+

Appropriate measures and security best practices need to be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. +

A. Appendix

A.1. Revision History

A.1.1. Changes in v1.2.0

+
    +
  • Add new OPTIONAL match kind. At the moment, OPTIONAL is only supported by +the v1model architecture [38], and not by PSA. It will eventually be +included in the core P4 language. +
  • +
  • Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists. +
  • +
  • Add a new metadata field of type bytes to TableEntry. This is more +flexible than the now deprecated controller_metadata field. +
  • +
  • Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +@id annotation. +
  • +
  • Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature. +
  • +
  • Support using string as the controller type in the @p4runtime_translation +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type. +
  • +
  • Add optional P4 source locations to both structured and unstructured +annotations. +
+

A.1.2. Changes in v1.1.0

+
    +
  • Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously. +
  • +
  • Add error field to stream messages sent by the server. +
  • +
  • Add Capabilities RPC to query the P4Runtime API version implemented by the +server. +
  • +
  • Support wildcard reads for multicast groups and clone sessions. +
  • +
  • Support for modifying direct resources of const tables. +
  • +
  • Support P4 user-defined types for Packet IO metadata fields. +
  • +
  • Clarify consistency requirements for Write and Read RPCs. +
  • +
  • Add Appendix providing implementation advice for avoiding common pitfalls: + +
      +
    • advice on setting gRPC Metadata Maximum Size +
    • +
    • advice on setting gRPC Server Maximum Receive Message Size +
  • +
  • Clarify limitations on supported types for FieldMatch, action Param, and +Packet IO metadata fields. +
  • +
  • Clarify that reading entire forwarding state with empty entity is not +supported. +
  • +
  • Document that @p4runtime_translation need only be supported when applied to +type declarations in P4. +
+

A.2. P4 Annotations

+

Table 7 lists P416 annotations introduced primarily for +the purpose of adding features for the P4Runtime API. +

+
+ + + + + + + + + + +
Annotation Description
@brief See section 6.1.3
@controller_header See section 6.4.6
@description See section 6.1.3
@id See section 6.3
@max_group_size See sections 6.4.3, 9.2.2
@pkginfo See section 6.2.1
@p4runtime_translation See sections 8.5.6, 18.1.1
+
+ +
Table 7. P4 annotations introduced by P4Runtime

A.3. A More Complex Value Set Example

+

This section includes a more complex Value Set example, with multiple matches of +different kinds. +

+
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+

This P4 Value Set declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

A P4Runtime client can set the membership for this Value Set with WriteRequest +messages similar to this one: +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xac }
+      }
+      # match for field_id 2 is missing => don't care match
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xdc }
+      }
+      match {
+        field_id: 2
+        ternary { value: 0x88 mask: 8f }
+      }
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+  }
+}

A.4. Guidelines for Implementations

+

This section contains practical advice for implementing P4Runtime clients and +servers. +

A.4.1. gRPC Metadata Maximum Size

+

In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the grpc.max_metadata_size gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the Write P4Runtime RPC. The Write RPC +returns an individual error for every item in a batch (see Section +12), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +RESOURCE_EXHAUSTED error, without any of the individual errors. +

+

To fix this problem, one can set the grpc.max_metadata_size option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it's +limit, as only the receiving side's limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every p4.Error, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +8192 + MAX_UPDATES_PER_WRITE * 100 bytes of metadata. +

+

For example, in C++, one can create a client channel as follows: +

+
+
+
const int MAX_UPDATES_PER_WRITE = 100;
+::grpc::ChannelArguments arguments;
+arguments.SetInt(GRPC_ARG_MAX_METADATA_SIZE, 8192 + MAX_UPDATES_PER_WRITE*100);
+return grpc::CreateCustomChannel(address, credentials, arguments);

A.4.2. gRPC Server Maximum Receive Message Size

+

At the time of writing, the default maximum receive message size in gRPC is 4MB + while the default maximum send message size is unlimited. This can be a +problem for the SetForwardingPipelineConfig RPC, since for some targets the +binary p4_device_config can exceed 4MB, in which case by default the P4Runtime +server would return an INVALID_ARGUMENT error. To a lesser extent, this may +affect the Write RPC as well, in case of extremely large batches. +

+

To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of p4_device_config for their target(s). This can be done by +setting the grpc.max_receive_message_length when building the gRPC server. +

+

For example, in C++, one can set the maximum receive message size as follows: +

+
+
+
const int MAX_RECEIVE_MESSAGE_SIZE = 128 * 1024 * 1024;  // 128MB
+::grpc::ServerBuilder server_builder;
+builder.AddListeningPort(/*...*/);
+builder.RegisterService(/*...*/);  // register P4Runtime service
+builder.SetMaxReceiveMessageSize(MAX_RECEIVE_MESSAGE_SIZE);
+builder.BuildAndStart();
+

On the client side, we recommend that P4Runtime clients do not use Write +batches larger than the default maximum receive message size (4MB) in case +the server did not deem necessary to increase the default value , unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB). +

+

References

+
+ +
[2]“A Two Rate Three Color Marker.” https://​tools.​ietf.​org/​html/​rfc2698.
+ + + + +
[7]“Google Cloud APIs Versioning - Backwards-Compatibility.” https://​cloud.​google.​com/​apis/​design/​versioning#​backwards_​compatibility.
+ +
[9]“gRPC Main Site.” https://​grpc.​io.
+ + + + + +
[15]“p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” https://​github.​com/​p4lang/​p4runtime.
+
[16]“p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.” https://​github.​com/​p4lang/​PI.
+ + +
[19]“Portable Switch Architecture Specification (v1.1.0).” https://​p4.​org/​p4-​spec/​docs/​PSA-​v1.​1.​0.​html.
+ + + + + + + +
[27]“Semantic Versioning.” https://​semver.​org/​.
+ + + + + + + +
[35]“The OpenConfig Project.” http://​openconfig.​net.
+ +
[37]“The Stratum Project.” https://​stratumproject.​org/​.
+ +
+
+
+ +
+

1.an enum type used as a field in a header must specify a +underlying type and representation for enum elements. +

+ + + diff --git a/spec/v1.2.0-rc.1/P4Runtime-Spec.log b/spec/v1.2.0-rc.1/P4Runtime-Spec.log new file mode 100644 index 00000000..74cc65e6 --- /dev/null +++ b/spec/v1.2.0-rc.1/P4Runtime-Spec.log @@ -0,0 +1,14554 @@ +This is XeTeX, Version 3.14159265-2.6-0.99992 (TeX Live 2015/Debian) (preloaded format=xelatex 2018.8.17) 18 JUN 2020 03:18 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**build/P4Runtime-Spec.tex +(./build/P4Runtime-Spec.tex +LaTeX2e <2016/02/01> +Babel <3.9q> and hyphenation patterns for 81 language(s) loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2014/09/29 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo +File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@section=\count80 +\c@subsection=\count81 +\c@subsubsection=\count82 +\c@paragraph=\count83 +\c@subparagraph=\count84 +\c@figure=\count85 +\c@table=\count86 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) (build/madoko2.sty (/usr/share/texlive/texmf-dist/tex/latex/colortbl/colortbl.sty +Package: colortbl 2012/02/13 v1.0a Color table columns (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty +Package: array 2014/10/28 v2.4c Tabular extension package (FMi) +\col@sep=\dimen103 +\extrarowheight=\dimen104 +\NC@list=\toks14 +\extratabsurround=\skip43 +\backup@length=\skip44 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty +Package: color 2016/01/03 v1.1b Standard LaTeX Color (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package color Info: Driver file: xetex.def on input line 143. +(/usr/share/texlive/texmf-dist/tex/xelatex/xetex-def/xetex.def +File: xetex.def 2015/09/11 v4.06 LaTeX color/graphics driver for XeTeX (TeX Live/RRM/JK) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +))) +\everycr=\toks15 +\minrowclearance=\skip45 +) (/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: xetex.def on input line 225. +LaTeX Info: Redefining \color on input line 702. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) (build/options.sty +Package: options 2015/03/01, Daan Leijen, Provides convenient path-value (or key-value) options +(/usr/share/texlive/texmf-dist/tex/latex/etoolbox/etoolbox.sty +Package: etoolbox 2015/08/02 v2.2a e-TeX tools for LaTeX (JAW) +\etb@tempcnta=\count87 +) +\opt@nesting=\count88 +\opt@idx=\count89 +\opt@choiceord=\count90 +) (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty +Package: iftex 2013/04/04 v0.2 Provides if(tex) conditional for PDFTeX, XeTeX, and LuaTeX +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2014/10/28 v1.0g Enhanced LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks16 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2016/01/03 v1.0q Standard LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2016/01/03 v1.10 sin cos tan (DPC) +) (/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg +File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live +) +Package graphics Info: Driver file: xetex.def on input line 95. +) +\Gin@req@height=\dimen105 +\Gin@req@width=\dimen106 +) (build/longfbox.sty +Package: longfbox 2015/12/01, Daan Leijen, Provides long fbox that can break over pages +(build/longbox.sty +Package: longbox 2015/12/01, Daan Leijen, Provides basic longbox that can break over pages +(/usr/share/texlive/texmf-dist/tex/latex/mdwtools/footnote.sty +Package: footnote 1997/01/28 1.13 Save footnotes around boxes +\fn@notes=\box26 +\fn@width=\dimen107 +) +\lb@prevdepth=\skip46 +\lb@freevspace=\skip47 +\lb@headbox=\box27 +\lb@savebox=\box28 +\lb@mainbox=\box29 +\lb@usevbox=\count91 +\lb@width=\skip48 +\lb@height=\skip49 +\lb@skiptop=\skip50 +\lb@skipright=\skip51 +\lb@skipbottom=\skip52 +\lb@skipleft=\skip53 +\lb@skipbreaktop=\skip54 +\lb@skipbreakbottom=\skip55 +\lb@outerwidth=\skip56 +\lb@extrasplit=\skip57 +\lb@textalign=\count92 +\lb@baseline=\count93 +\lb@neededvspace=\skip58 +\lb@splitheight=\skip59 +\lb@insurance=\skip60 +\/longbox/@part-height=\skip61 +\/longbox/@part-width=\skip62 +\/longbox/@part-depth=\skip63 +\/longbox/@content-box-height=\skip64 +\/longbox/@content-box-width=\skip65 +\/longbox/@content-box-depth=\skip66 +\/longbox/@breakat-previous=\skip67 +\/longbox/@lower=\skip68 +\/longbox/split-minimum=\skip69 +\/longbox/split-badness=\skip70 +\/longbox/raise=\skip71 +\/longbox/height=\skip72 +\/longbox/width=\skip73 +\/longbox/outer-height=\skip74 +\/longbox/outer-width=\skip75 +\/longbox/skip-top=\skip76 +\/longbox/skip-right=\skip77 +\/longbox/skip-bottom=\skip78 +\/longbox/skip-left=\skip79 +\/longbox/skip-break-bottom=\skip80 +\/longbox/skip-break-top=\skip81 +) (/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.sty +Package: pict2e 2016/02/05 v0.3b Improved picture commands (HjG,RN,JT) +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.cfg +File: pict2e.cfg 2016/02/05 v0.1u pict2e configuration for teTeX/TeXLive +) +Package pict2e Info: Driver file: xetex.def on input line 119. +Package pict2e Info: Driver file for pict2e: p2e-xetex.def on input line 121. +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/p2e-xetex.def +File: p2e-xetex.def 2016/02/05 v0.1u Driver-dependant file (RN,HjG,JT) +) +\pIIe@GRAPH=\toks17 +\@arclen=\dimen108 +\@arcrad=\dimen109 +\@tempdimd=\dimen110 +) (build/ellipse.sty +Package: ellipse 2004/11/05 v1.0 .dtx ellipse file +) +\fbox@oct=\count94 +\fbox@quad=\count95 +\fbox@diaq=\count96 +\fbox@sign=\count97 +\fbox@anglestart=\skip82 +\fbox@angleend=\skip83 +\fbox@dash=\skip84 +\fbox@dashskip=\skip85 +\fbox@anglecur=\skip86 +\fbox@dashangle=\skip87 +\fbox@dashskipangle=\skip88 +\fbox@delta=\skip89 +\fbox@from=\skip90 +\fbox@to=\skip91 +\/fbox/padding-top=\skip92 +\/fbox/padding-right=\skip93 +\/fbox/padding-bottom=\skip94 +\/fbox/padding-left=\skip95 +\/fbox/padding-break-top=\skip96 +\/fbox/padding-break-bottom=\skip97 +\/fbox/margin-top=\skip98 +\/fbox/margin-right=\skip99 +\/fbox/margin-bottom=\skip100 +\/fbox/margin-left=\skip101 +\/fbox/margin-break-top=\skip102 +\/fbox/margin-break-bottom=\skip103 +\/fbox/border-top-width=\skip104 +\/fbox/border-right-width=\skip105 +\/fbox/border-bottom-width=\skip106 +\/fbox/border-left-width=\skip107 +\/fbox/border-break-top-width=\skip108 +\/fbox/border-break-bottom-width=\skip109 +\/fbox/@lower=\skip110 +\/fbox/@padding-box-height=\skip111 +\/fbox/@padding-box-depth=\skip112 +\/fbox/@padding-box-width=\skip113 +\/fbox/@border-box-width=\skip114 +\/fbox/@border-box-height=\skip115 +\/fbox/@border-box-depth=\skip116 +\/fbox/@border-top-left-radius-x=\skip117 +\/fbox/@border-top-right-radius-x=\skip118 +\/fbox/@border-bottom-left-radius-x=\skip119 +\/fbox/@border-bottom-right-radius-x=\skip120 +\/fbox/@border-top-left-radius-y=\skip121 +\/fbox/@border-top-right-radius-y=\skip122 +\/fbox/@border-bottom-left-radius-y=\skip123 +\/fbox/@border-bottom-right-radius-y=\skip124 +\/fbox/@border-top-left-ix=\skip125 +\/fbox/@border-top-left-iy=\skip126 +\/fbox/@border-top-right-ix=\skip127 +\/fbox/@border-top-right-iy=\skip128 +\/fbox/@border-bottom-left-ix=\skip129 +\/fbox/@border-bottom-left-iy=\skip130 +\/fbox/@border-bottom-right-ix=\skip131 +\/fbox/@border-bottom-right-iy=\skip132 +\/fbox/@border-top-left-phi=\skip133 +\/fbox/@border-top-right-phi=\skip134 +\/fbox/@border-bottom-left-phi=\skip135 +\/fbox/@border-bottom-right-phi=\skip136 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2016/03/03 v2.15a AMS math features +\@mathmargin=\skip137 +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2000/06/29 v2.01 AMS text +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen111 +)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen112 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 1999/12/14 v2.01 operator names +) +\inf@bad=\count98 +LaTeX Info: Redefining \frac on input line 199. +\uproot@=\count99 +\leftroot@=\count100 +LaTeX Info: Redefining \overline on input line 297. +\classnum@=\count101 +\DOTSCASE@=\count102 +LaTeX Info: Redefining \ldots on input line 394. +LaTeX Info: Redefining \dots on input line 397. +LaTeX Info: Redefining \cdots on input line 518. +\Mathstrutbox@=\box30 +\strutbox@=\box31 +\big@size=\dimen113 +LaTeX Font Info: Redeclaring font encoding OML on input line 630. +LaTeX Font Info: Redeclaring font encoding OMS on input line 631. +\macc@depth=\count103 +\c@MaxMatrixCols=\count104 +\dotsspace@=\muskip10 +\c@parentequation=\count105 +\dspbrk@lvl=\count106 +\tag@help=\toks19 +\row@=\count107 +\column@=\count108 +\maxfields@=\count109 +\andhelp@=\toks20 +\eqnshift@=\dimen114 +\alignsep@=\dimen115 +\tagshift@=\dimen116 +\tagwidth@=\dimen117 +\totwidth@=\dimen118 +\lineht@=\dimen119 +\@envbody=\toks21 +\multlinegap=\skip138 +\multlinetaggap=\skip139 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2735. +LaTeX Info: Redefining \] on input line 2736. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +) (/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/stmaryrd.sty +Package: stmaryrd 1994/03/03 St Mary's Road symbol package +\symstmry=\mathgroup6 +LaTeX Font Info: Overwriting symbol font `stmry' in version `bold' +(Font) U/stmry/m/n --> U/stmry/b/n on input line 89. +) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty +Package: textcomp 2005/09/27 v1.99g Standard LaTeX package +Package textcomp Info: Sub-encoding information: +(textcomp) 5 = only ISO-Adobe without \textcurrency +(textcomp) 4 = 5 + \texteuro +(textcomp) 3 = 4 + \textohm +(textcomp) 2 = 3 + \textestimated + \textcurrency +(textcomp) 1 = TS1 - \textcircled - \t +(textcomp) 0 = TS1 (full) +(textcomp) Font families with sub-encoding setting implement +(textcomp) only a restricted character set as indicated. +(textcomp) Family '?' is the default used for unknown fonts. +(textcomp) See the documentation for details. +Package textcomp Info: Setting ? sub-encoding to TS1/1 on input line 79. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +) +LaTeX Info: Redefining \oldstylenums on input line 334. +Package textcomp Info: Setting cmr sub-encoding to TS1/0 on input line 349. +Package textcomp Info: Setting cmss sub-encoding to TS1/0 on input line 350. +Package textcomp Info: Setting cmtt sub-encoding to TS1/0 on input line 351. +Package textcomp Info: Setting cmvtt sub-encoding to TS1/0 on input line 352. +Package textcomp Info: Setting cmbr sub-encoding to TS1/0 on input line 353. +Package textcomp Info: Setting cmtl sub-encoding to TS1/0 on input line 354. +Package textcomp Info: Setting ccr sub-encoding to TS1/0 on input line 355. +Package textcomp Info: Setting ptm sub-encoding to TS1/4 on input line 356. +Package textcomp Info: Setting pcr sub-encoding to TS1/4 on input line 357. +Package textcomp Info: Setting phv sub-encoding to TS1/4 on input line 358. +Package textcomp Info: Setting ppl sub-encoding to TS1/3 on input line 359. +Package textcomp Info: Setting pag sub-encoding to TS1/4 on input line 360. +Package textcomp Info: Setting pbk sub-encoding to TS1/4 on input line 361. +Package textcomp Info: Setting pnc sub-encoding to TS1/4 on input line 362. +Package textcomp Info: Setting pzc sub-encoding to TS1/4 on input line 363. +Package textcomp Info: Setting bch sub-encoding to TS1/4 on input line 364. +Package textcomp Info: Setting put sub-encoding to TS1/5 on input line 365. +Package textcomp Info: Setting uag sub-encoding to TS1/5 on input line 366. +Package textcomp Info: Setting ugq sub-encoding to TS1/5 on input line 367. +Package textcomp Info: Setting ul8 sub-encoding to TS1/4 on input line 368. +Package textcomp Info: Setting ul9 sub-encoding to TS1/4 on input line 369. +Package textcomp Info: Setting augie sub-encoding to TS1/5 on input line 370. +Package textcomp Info: Setting dayrom sub-encoding to TS1/3 on input line 371. +Package textcomp Info: Setting dayroms sub-encoding to TS1/3 on input line 372. +Package textcomp Info: Setting pxr sub-encoding to TS1/0 on input line 373. +Package textcomp Info: Setting pxss sub-encoding to TS1/0 on input line 374. +Package textcomp Info: Setting pxtt sub-encoding to TS1/0 on input line 375. +Package textcomp Info: Setting txr sub-encoding to TS1/0 on input line 376. +Package textcomp Info: Setting txss sub-encoding to TS1/0 on input line 377. +Package textcomp Info: Setting txtt sub-encoding to TS1/0 on input line 378. +Package textcomp Info: Setting lmr sub-encoding to TS1/0 on input line 379. +Package textcomp Info: Setting lmdh sub-encoding to TS1/0 on input line 380. +Package textcomp Info: Setting lmss sub-encoding to TS1/0 on input line 381. +Package textcomp Info: Setting lmssq sub-encoding to TS1/0 on input line 382. +Package textcomp Info: Setting lmvtt sub-encoding to TS1/0 on input line 383. +Package textcomp Info: Setting lmtt sub-encoding to TS1/0 on input line 384. +Package textcomp Info: Setting qhv sub-encoding to TS1/0 on input line 385. +Package textcomp Info: Setting qag sub-encoding to TS1/0 on input line 386. +Package textcomp Info: Setting qbk sub-encoding to TS1/0 on input line 387. +Package textcomp Info: Setting qcr sub-encoding to TS1/0 on input line 388. +Package textcomp Info: Setting qcs sub-encoding to TS1/0 on input line 389. +Package textcomp Info: Setting qpl sub-encoding to TS1/0 on input line 390. +Package textcomp Info: Setting qtm sub-encoding to TS1/0 on input line 391. +Package textcomp Info: Setting qzc sub-encoding to TS1/0 on input line 392. +Package textcomp Info: Setting qhvc sub-encoding to TS1/0 on input line 393. +Package textcomp Info: Setting futs sub-encoding to TS1/4 on input line 394. +Package textcomp Info: Setting futx sub-encoding to TS1/4 on input line 395. +Package textcomp Info: Setting futj sub-encoding to TS1/4 on input line 396. +Package textcomp Info: Setting hlh sub-encoding to TS1/3 on input line 397. +Package textcomp Info: Setting hls sub-encoding to TS1/3 on input line 398. +Package textcomp Info: Setting hlst sub-encoding to TS1/3 on input line 399. +Package textcomp Info: Setting hlct sub-encoding to TS1/5 on input line 400. +Package textcomp Info: Setting hlx sub-encoding to TS1/5 on input line 401. +Package textcomp Info: Setting hlce sub-encoding to TS1/5 on input line 402. +Package textcomp Info: Setting hlcn sub-encoding to TS1/5 on input line 403. +Package textcomp Info: Setting hlcw sub-encoding to TS1/5 on input line 404. +Package textcomp Info: Setting hlcf sub-encoding to TS1/5 on input line 405. +Package textcomp Info: Setting pplx sub-encoding to TS1/3 on input line 406. +Package textcomp Info: Setting pplj sub-encoding to TS1/3 on input line 407. +Package textcomp Info: Setting ptmx sub-encoding to TS1/4 on input line 408. +Package textcomp Info: Setting ptmj sub-encoding to TS1/4 on input line 409. +) (/usr/share/texlive/texmf-dist/tex/latex/psnfss/pifont.sty +Package: pifont 2005/04/12 PSNFSS-v9.2a Pi font support (SPQR) +LaTeX Font Info: Try loading font information for U+pzd on input line 63. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upzd.fd +File: upzd.fd 2001/06/04 font definitions for U/pzd. +) +LaTeX Font Info: Try loading font information for U+psy on input line 64. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upsy.fd +File: upsy.fd 2001/06/04 font definitions for U/psy. +)) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2012/11/06 v6.83m Hypertext links for LaTeX +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO) +Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO) +Package hobsub Info: Skipping package `infwarerr' (already loaded). +Package hobsub Info: Skipping package `ltxcmds' (already loaded). +Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO) +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is not detected. +Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) +Package etexcmds Info: Could not find \expanded. +(etexcmds) That can mean that you are not using pdfTeX 1.50 or +(etexcmds) that some package has redefined \expanded. +(etexcmds) In the latter case, load this package earlier. +Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) +Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO) +Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: pdfTeX >= 1.30 not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode not found. +Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO) +Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO) +Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO) +Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO) +Package: xcolor-patch 2011/01/30 xcolor patch +Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO) +Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO) +Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO) +Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2011/03/04 v1.3 Hooks for auxiliary files (HO) +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) +) +\@linkdim=\dimen120 +\Hy@linkcounter=\count110 +\Hy@pagecounter=\count111 +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count112 +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Hyper figures OFF on input line 4443. +Package hyperref Info: Link nesting OFF on input line 4448. +Package hyperref Info: Hyper index ON on input line 4451. +Package hyperref Info: Plain pages OFF on input line 4458. +Package hyperref Info: Backreferencing OFF on input line 4463. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4688. +\c@Hy@tempcnt=\count113 +(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip11 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 5041. +\XeTeXLinkMargin=\dimen121 +\Fld@menulength=\count114 +\Field@Width=\dimen122 +\Fld@charsize=\dimen123 +Package hyperref Info: Hyper figures OFF on input line 6295. +Package hyperref Info: Link nesting OFF on input line 6300. +Package hyperref Info: Hyper index ON on input line 6303. +Package hyperref Info: backreferencing OFF on input line 6310. +Package hyperref Info: Link coloring OFF on input line 6315. +Package hyperref Info: Link coloring with OCG OFF on input line 6320. +Package hyperref Info: PDF/A mode OFF on input line 6325. +LaTeX Info: Redefining \ref on input line 6365. +LaTeX Info: Redefining \pageref on input line 6369. +\Hy@abspage=\count115 +\c@Item=\count116 +\c@Hfootnote=\count117 +) + +Package hyperref Message: Driver (autodetected): hxetex. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hxetex.def +File: hxetex.def 2012/11/06 v6.83m Hyperref driver for XeTeX +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def +File: puenc.def 2012/11/06 v6.83m Hyperref: PDF Unicode definition (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/stringenc.sty +Package: stringenc 2011/12/02 v1.10 Convert strings between diff. encodings (HO) +) +\pdfm@box=\box32 +\c@Hy@AnnotLevel=\count118 +\HyField@AnnotCount=\count119 +\Fld@listcount=\count120 +\c@bookmark@seq@number=\count121 +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO) +Package rerunfilecheck Info: Feature \pdfmdfivesum is not available +(rerunfilecheck) (e.g. pdfTeX or LuaTeX with package `pdftexcmds'). +(rerunfilecheck) Therefore file contents cannot be checked efficiently +(rerunfilecheck) and the loading of the package is aborted. +) +\Hy@SectionHShift=\skip140 +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bookmark.sty +Package: bookmark 2011/12/02 v1.24 PDF bookmarks (HO) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bkm-dvipdfm.def +File: bkm-dvipdfm.def 2011/12/02 v1.24 bookmark driver for dvipdfm (HO) +\BKM@id=\count122 +)) (/usr/share/texlive/texmf-dist/tex/latex/booktabs/booktabs.sty +Package: booktabs 2005/04/14 v1.61803 publication quality tables +\heavyrulewidth=\dimen124 +\lightrulewidth=\dimen125 +\cmidrulewidth=\dimen126 +\belowrulesep=\dimen127 +\belowbottomsep=\dimen128 +\aboverulesep=\dimen129 +\abovetopsep=\dimen130 +\cmidrulesep=\dimen131 +\cmidrulekern=\dimen132 +\defaultaddspace=\dimen133 +\@cmidla=\count123 +\@cmidlb=\count124 +\@aboverulesep=\dimen134 +\@belowrulesep=\dimen135 +\@thisruleclass=\count125 +\@lastruleclass=\count126 +\@thisrulewidth=\dimen136 +) (/usr/share/texlive/texmf-dist/tex/latex/tools/longtable.sty +Package: longtable 2014/10/28 v4.11 Multi-page Table package (DPC) +\LTleft=\skip141 +\LTright=\skip142 +\LTpre=\skip143 +\LTpost=\skip144 +\LTchunksize=\count127 +\LTcapwidth=\dimen137 +\LT@head=\box33 +\LT@firsthead=\box34 +\LT@foot=\box35 +\LT@lastfoot=\box36 +\LT@cols=\count128 +\LT@rows=\count129 +\c@LT@tables=\count130 +\c@LT@chunks=\count131 +\LT@p@ftn=\toks23 +) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Package: anyfontsize 2007/11/22 anyfontsize.sty by pts +) (/usr/share/texlive/texmf-dist/tex/latex/enumitem/enumitem.sty +Package: enumitem 2011/09/28 v3.5.2 Customized lists +\labelindent=\skip145 +\enit@outerparindent=\dimen138 +\enit@toks=\toks24 +\enit@inbox=\box37 +\enitdp@description=\count132 +) (/usr/share/texlive/texmf-dist/tex/latex/wrapfig/wrapfig.sty +\wrapoverhang=\dimen139 +\WF@size=\dimen140 +\c@WF@wrappedlines=\count133 +\WF@box=\box38 +\WF@everypar=\toks25 +Package: wrapfig 2003/01/31 v 3.6 +) (/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.sty (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty +Package: expl3 2016/01/19 v6377 L3 programming layer (loader) +(/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3-code.tex +Package: expl3 2016/01/19 v6377 L3 programming layer (code) +L3 Module: l3bootstrap 2016/01/01 v6339 L3 Bootstrap code +L3 Module: l3names 2015/12/21 v6328 L3 Namespace for primitives +L3 Module: l3basics 2015/11/22 v6315 L3 Basic definitions +L3 Module: l3expan 2015/09/10 v5983 L3 Argument expansion +L3 Module: l3tl 2015/09/29 v6121 L3 Token lists +L3 Module: l3str 2016/01/03 v6357 L3 Strings +L3 Module: l3seq 2015/08/05 v5777 L3 Sequences and stacks +L3 Module: l3int 2016/01/05 v6366 L3 Integers +\c_max_int=\count134 +\l_tmpa_int=\count135 +\l_tmpb_int=\count136 +\g_tmpa_int=\count137 +\g_tmpb_int=\count138 +L3 Module: l3quark 2015/08/17 v5855 L3 Quarks +L3 Module: l3prg 2015/11/01 v6216 L3 Control structures +\g__prg_map_int=\count139 +L3 Module: l3clist 2015/09/02 v5901 L3 Comma separated lists +L3 Module: l3token 2015/11/11 v6249 L3 Experimental token manipulation +L3 Module: l3prop 2016/01/05 v6366 L3 Property lists +L3 Module: l3msg 2015/09/28 v6113 L3 Messages +L3 Module: l3file 2015/12/03 v6317 L3 File and I/O operations +\l_iow_line_count_int=\count140 +\l__iow_target_count_int=\count141 +\l__iow_current_line_int=\count142 +\l__iow_current_word_int=\count143 +\l__iow_current_indentation_int=\count144 +L3 Module: l3skip 2016/01/05 v6366 L3 Dimensions and skips +\c_zero_dim=\dimen141 +\c_max_dim=\dimen142 +\l_tmpa_dim=\dimen143 +\l_tmpb_dim=\dimen144 +\g_tmpa_dim=\dimen145 +\g_tmpb_dim=\dimen146 +\c_zero_skip=\skip146 +\c_max_skip=\skip147 +\l_tmpa_skip=\skip148 +\l_tmpb_skip=\skip149 +\g_tmpa_skip=\skip150 +\g_tmpb_skip=\skip151 +\c_zero_muskip=\muskip12 +\c_max_muskip=\muskip13 +\l_tmpa_muskip=\muskip14 +\l_tmpb_muskip=\muskip15 +\g_tmpa_muskip=\muskip16 +\g_tmpb_muskip=\muskip17 +L3 Module: l3keys 2015/11/17 v6284 L3 Key-value interfaces +\g__keyval_level_int=\count145 +\l_keys_choice_int=\count146 +L3 Module: l3fp 2015/08/25 v5890 L3 Floating points +\c__fp_leading_shift_int=\count147 +\c__fp_middle_shift_int=\count148 +\c__fp_trailing_shift_int=\count149 +\c__fp_big_leading_shift_int=\count150 +\c__fp_big_middle_shift_int=\count151 +\c__fp_big_trailing_shift_int=\count152 +\c__fp_Bigg_leading_shift_int=\count153 +\c__fp_Bigg_middle_shift_int=\count154 +\c__fp_Bigg_trailing_shift_int=\count155 +L3 Module: l3box 2015/08/09 v5822 L3 Experimental boxes +\c_empty_box=\box39 +\l_tmpa_box=\box40 +\l_tmpb_box=\box41 +\g_tmpa_box=\box42 +\g_tmpb_box=\box43 +L3 Module: l3coffins 2015/08/06 v5789 L3 Coffin code layer +\l__coffin_internal_box=\box44 +\l__coffin_internal_dim=\dimen147 +\l__coffin_offset_x_dim=\dimen148 +\l__coffin_offset_y_dim=\dimen149 +\l__coffin_x_dim=\dimen150 +\l__coffin_y_dim=\dimen151 +\l__coffin_x_prime_dim=\dimen152 +\l__coffin_y_prime_dim=\dimen153 +\c_empty_coffin=\box45 +\l__coffin_aligned_coffin=\box46 +\l__coffin_aligned_internal_coffin=\box47 +\l_tmpa_coffin=\box48 +\l_tmpb_coffin=\box49 +\l__coffin_display_coffin=\box50 +\l__coffin_display_coord_coffin=\box51 +\l__coffin_display_pole_coffin=\box52 +\l__coffin_display_offset_dim=\dimen154 +\l__coffin_display_x_dim=\dimen155 +\l__coffin_display_y_dim=\dimen156 +L3 Module: l3color 2014/08/23 v5354 L3 Experimental color support +L3 Module: l3sys 2015/09/25 v6087 L3 Experimental system/runtime functions +L3 Module: l3candidates 2016/01/14 v6376 L3 Experimental additions to l3kernel +\l__box_top_dim=\dimen157 +\l__box_bottom_dim=\dimen158 +\l__box_left_dim=\dimen159 +\l__box_right_dim=\dimen160 +\l__box_top_new_dim=\dimen161 +\l__box_bottom_new_dim=\dimen162 +\l__box_left_new_dim=\dimen163 +\l__box_right_new_dim=\dimen164 +\l__box_internal_box=\box53 +\l__coffin_bounding_shift_dim=\dimen165 +\l__coffin_left_corner_dim=\dimen166 +\l__coffin_right_corner_dim=\dimen167 +\l__coffin_bottom_corner_dim=\dimen168 +\l__coffin_top_corner_dim=\dimen169 +\l__coffin_scaled_total_height_dim=\dimen170 +\l__coffin_scaled_width_dim=\dimen171 +L3 Module: l3luatex 2015/11/11 v6250 L3 Experimental LuaTeX-specific functions +) (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def +File: l3xdvidpfmx.def 2015/11/11 v6250 L3 Experimental driver: xdvipdfmx +)) (/usr/share/texlive/texmf-dist/tex/latex/l3packages/xparse/xparse.sty +Package: xparse 2016/01/19 v6377 L3 Experimental document command parser +\l__xparse_current_arg_int=\count156 +\l__xparse_m_args_int=\count157 +\l__xparse_mandatory_args_int=\count158 +\l__xparse_processor_int=\count159 +\l__xparse_v_nesting_int=\count160 +) +Package: fontspec 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec-xetex.sty +Package: fontspec-xetex 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +\l_fontspec_script_int=\count161 +\l_fontspec_language_int=\count162 +\l_fontspec_strnum_int=\count163 +\l__fontspec_tmpa_dim=\dimen172 +\l__fontspec_tmpb_dim=\dimen173 +\l__fontspec_tmpc_dim=\dimen174 +\g__file_internal_ior=\read1 +(/usr/share/texlive/texmf-dist/tex/latex/base/fontenc.sty +Package: fontenc 2005/09/27 v1.99g Standard LaTeX package +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1enc.def +File: eu1enc.def 2010/05/27 v0.1h Experimental Unicode font encodings +) +LaTeX Font Info: Try loading font information for EU1+lmr on input line 105. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmr.fd +File: eu1lmr.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) (/usr/share/texlive/texmf-dist/tex/xelatex/xunicode/xunicode.sty +File: xunicode.sty 2011/09/09 v0.981 provides access to latin accents and many other characters in Unicode lower plane +(/usr/share/texmf/tex/latex/tipa/t3enc.def +File: t3enc.def 2001/12/31 T3 encoding +LaTeX Font Info: Try loading font information for EU1+lmss on input line 357. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmss.fd +File: eu1lmss.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) +\tipaTiiicode=\count164 +\tipasavetokens=\toks26 +\tipachecktokens=\toks27 +) +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \__fontspec_post_arg:w with sig. 'mmO{}' on line 353. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \fontspec with sig. 'om' on line 355. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmainfont with sig. 'om' on line 365. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setsansfont with sig. 'om' on line 375. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmonofont with sig. 'om' on line 385. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathrm with sig. 'om' on line 399. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setboldmathrm with sig. 'om' on line 407. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathsf with sig. 'om' on line 415. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathtt with sig. 'om' on line 423. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfamily with sig. 'mom' on line 437. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontface with sig. 'mom' on line 453. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \defaultfontfeatures with sig. 't+om' on line 467. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \addfontfeatures with sig. 'm' on line 529. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfeature with sig. 'mm' on line 540. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newAATfeature with sig. 'mmmm' on line 548. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newopentypefeature with sig. 'mmm' on line 556. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeature with sig. 'mm' on line 577. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeatureoption with sig. 'mmm' on line 586. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontscript with sig. 'mm' on line 590. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontlanguage with sig. 'mm' on line 594. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \DeclareFontsExtensions with sig. 'm' on line 599. +................................................. +\l__fontspec_tmp_int=\count165 +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.cfg) +LaTeX Info: Redefining \itshape on input line 2705. +LaTeX Info: Redefining \slshape on input line 2710. +LaTeX Info: Redefining \scshape on input line 2715. +LaTeX Info: Redefining \upshape on input line 2720. +\l__fontspec_em_int=\count166 +\l__fontspec_emdef_int=\count167 +LaTeX Info: Redefining \em on input line 2736. +LaTeX Info: Redefining \emph on input line 2742. +LaTeX Info: Redefining \- on input line 2746. +................................................. +. LaTeX info: "xparse/redefine-command" +. +. Redefining command \oldstylenums with sig. 'm' on line 2841. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \liningnums with sig. 'm' on line 2845. +................................................. +)) +Package hyperref Info: Option `colorlinks' set `true' on input line 87. +\px=\skip152 +\c@md@targetcount=\count168 +\mdcompactskip=\skip153 +\mdcompacttopsep=\skip154 +\dim@rem=\skip155 +\dim@ch=\skip156 +\md@height=\skip157 +\dim@marginbottom=\skip158 +\dim@paddingbottom=\skip159 +\md@interaction=\count169 +\mddefinitionsskip=\skip160 +\md@captionlen=\skip161 +\mdtoclevel=\count170 +\c@mdtoclevelbold=\count171 +\c@mdtocleveldots=\count172 +\mdtocskip=\skip162 +\mdpreskip=\skip163 +\presp=\skip164 +LaTeX Font Info: Try loading font information for EU1+lmtt on input line 801. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmtt.fd +File: eu1lmtt.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +\md@postskip=\skip165 +\ppresp=\skip166 +\md@thmcaption=\box54 +\md@defaultcolwidth=\skip167 +\mdtabularskip=\skip168 +\mdbibindentunit=\skip169 +\c@md@authorcount=\count173 +\c@mdx@authorcount=\count174 +\c@@mdTargetCount=\count175 +\@snippetBox=\box55 +\@snippetWidth=\skip170 +\@snippetHeight=\skip171 +\@snippetDepth=\skip172 +\c@snippets=\count176 +) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty +Package: geometry 2010/09/12 v5.6 Page Geometry +\Gm@cnth=\count177 +\Gm@cntv=\count178 +\c@Gm@tempcnt=\count179 +\Gm@bindingoffset=\dimen175 +\Gm@wd@mp=\dimen176 +\Gm@odd@mp=\dimen177 +\Gm@even@mp=\dimen178 +\Gm@layoutwidth=\dimen179 +\Gm@layoutheight=\dimen180 +\Gm@layouthoffset=\dimen181 +\Gm@layoutvoffset=\dimen182 +\Gm@dimlist=\toks28 +) (/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +\fancy@headwidth=\skip173 +\f@ncyO@elh=\skip174 +\f@ncyO@erh=\skip175 +\f@ncyO@olh=\skip176 +\f@ncyO@orh=\skip177 +\f@ncyO@elf=\skip178 +\f@ncyO@erf=\skip179 +\f@ncyO@olf=\skip180 +\f@ncyO@orf=\skip181 +) (build/P4Runtime-Spec.aux + +LaTeX Warning: Label `sec-example' multiply defined. + +) +\openout1 = `P4Runtime-Spec.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for TS1+cmr on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1cmr.fd +File: ts1cmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions +) +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for EU1/lmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T3/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for T3+cmr on input line 14. +(/usr/share/texmf/tex/latex/tipa/t3cmr.fd +File: t3cmr.fd 2001/12/31 TIPA font definitions +) +LaTeX Font Info: ... okay on input line 14. +\AtBeginShipoutBox=\box56 +Package hyperref Info: Link coloring ON on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2012/10/27 v2.43 Cross-referencing by name of section +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO) +) +\c@section@level=\count180 +) +LaTeX Info: Redefining \ref on input line 14. +LaTeX Info: Redefining \pageref on input line 14. +LaTeX Info: Redefining \nameref on input line 14. +................................................. +. fontspec info: "setup-math" +. +. Adjusting the maths setup (use [no-math] to avoid this). +................................................. +\symlegacymaths=\mathgroup7 +LaTeX Font Info: Overwriting symbol font `legacymaths' in version `bold' +(Font) OT1/cmr/m/n --> OT1/cmr/bx/n on input line 14. +LaTeX Font Info: Redeclaring math accent \acute on input line 14. +LaTeX Font Info: Redeclaring math accent \grave on input line 14. +LaTeX Font Info: Redeclaring math accent \ddot on input line 14. +LaTeX Font Info: Redeclaring math accent \tilde on input line 14. +LaTeX Font Info: Redeclaring math accent \bar on input line 14. +LaTeX Font Info: Redeclaring math accent \breve on input line 14. +LaTeX Font Info: Redeclaring math accent \check on input line 14. +LaTeX Font Info: Redeclaring math accent \hat on input line 14. +LaTeX Font Info: Redeclaring math accent \dot on input line 14. +LaTeX Font Info: Redeclaring math accent \mathring on input line 14. +LaTeX Font Info: Redeclaring math symbol \Gamma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Delta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Theta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Lambda on input line 14. +LaTeX Font Info: Redeclaring math symbol \Xi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Pi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Sigma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Upsilon on input line 14. +LaTeX Font Info: Redeclaring math symbol \Phi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Psi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Omega on input line 14. +LaTeX Font Info: Redeclaring math symbol \mathdollar on input line 14. +LaTeX Font Info: Redeclaring symbol font `operators' on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `normal' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/cmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `bold' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/cmr/bx/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) EU1/lmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/cmr/m/it --> EU1/lmr/m/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/cmr/bx/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/cmss/m/n --> EU1/lmss/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/cmtt/m/n --> EU1/lmtt/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) EU1/lmr/m/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' +(Font) OT1/cmr/bx/it --> EU1/lmr/bx/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/cmss/bx/n --> EU1/lmss/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/cmtt/m/n --> EU1/lmtt/bx/n on input line 14. +*geometry* driver: auto-detecting +*geometry* detected driver: xetex +*geometry* verbose mode - [ preamble ] result: +* driver: xetex +* paper: +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: +* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt) +* v-part:(T,H,B)=(72.26999pt, 632.3625pt, 90.3375pt) +* \paperwidth=614.295pt +* \paperheight=794.96999pt +* \textwidth=469.75502pt +* \textheight=632.3625pt +* \oddsidemargin=0.0pt +* \evensidemargin=0.0pt +* \topmargin=-37.0pt +* \headheight=30.0pt +* \headsep=25.0pt +* \topskip=11.0pt +* \footskip=30.0pt +* \marginparwidth=59.0pt +* \marginparsep=10.0pt +* \columnsep=10.0pt +* \skip\footins=10.0pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +resolve font stack: UtopiaStd-Regular + +\g__fontspec_family_UtopiaStd-Regular_int=\count181 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'UtopiaStd-Regular(0)' created for font 'UtopiaStd-Regular' with +. options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;" +. - 'small caps' (m/sc) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;+smcp;" +................................................. + +resolved font stack 'UtopiaStd-Regular' to: UtopiaStd-Regular +LaTeX Font Info: Try loading font information for U+msa on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Try loading font information for U+msb on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Try loading font information for U+stmry on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/Ustmry.fd) + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/bx/n' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 35. + +resolve font stack: LuxiMono + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +\g__fontspec_family_LuxiMono_int=\count182 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'LuxiMono(0)' created for font 'LuxiMono' with options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: <->"LuxiMono/OT:" +. - 'small caps' (m/sc) with NFSS spec.: +................................................. + +resolved font stack 'LuxiMono' to: LuxiMono +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/se-ascii-print.def +File: se-ascii-print.def 2011/12/02 v1.10 stringenc: Printable ASCII characters +) [1 + +] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[2] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <10.95> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 299. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Font Warning: Font shape `EU1/LuxiMono(0)/bx/n' undefined +(Font) using `EU1/LuxiMono(0)/m/n' instead on input line 299. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[3] + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/m/it' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 509. + +[4] [5] [6] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[7] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/reference-architecture.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[8] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[9] +File: build/single-embedded-controller.png Graphic file (type QTm) + [10] +File: build/single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-controllers.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-ha-controllers.png Graphic file (type QTm) + [11] [12] [13] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[14] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[15] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <12> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 1493. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1493. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[16] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[17] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (53.84203pt too wide) in paragraph at lines 1790--1793 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For all slave controllers, \EU1/LuxiMono(0)/bx/n/8.2125 status \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set to non-OK (with \EU1/LuxiMono(0)/bx/n/8.2125 status.code \EU1/UtopiaStd-Regular(0)/m/it/10.95 set to \EU1/LuxiMono(0)/bx/n/8.2125 google.rpc.ALREADY_EXISTS\EU1/UtopiaStd-Regular(0)/m/it/10.95 ). + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[18] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1827. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1851. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[19] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1895. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[20] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[21] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[22] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2178. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[23] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2233. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[24] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[25] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[26] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (12.45624pt too wide) in paragraph at lines 2464--2477 + [] + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2500. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[27] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[28] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2691. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2751. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[29] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2824. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[30] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2905. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.59204pt too wide) in paragraph at lines 2959--2961 +[]\EU1/LuxiMono(0)/bx/n/8.2125 BYTES\EU1/UtopiaStd-Regular(0)/m/it/10.95 , which signifies that this meter can be configured with rates expressed in bytes/second. + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2984. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[31] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (18.74199pt too wide) in paragraph at lines 3001--3008 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 carrying P4 standard annotations \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_in") \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_out")\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[32] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3143. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[33] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[34] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[35] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3371. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3418. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[36] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3456. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[37] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[38] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[39] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[40] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[41] [42] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1629) in paragraph at lines 4060--4062 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For example, the following P4$[]$ objects involve complex types that need to be exposed in + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[43] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1454) in paragraph at lines 4108--4117 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 ification for all the named types in the P4$[]$ program. These named types are \EU1/LuxiMono(0)/bx/n/8.2125 struct\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 header\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + + +Underfull \hbox (badness 1831) in paragraph at lines 4108--4117 +\EU1/LuxiMono(0)/bx/n/8.2125 header_union\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 enum \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 serializable_enum\EU1/UtopiaStd-Regular(0)/m/it/10.95 ; for each of these we have a type specification mes- + [] + + +Underfull \hbox (badness 1845) in paragraph at lines 4108--4117 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 sage, respectively \EU1/LuxiMono(0)/bx/n/8.2125 P4StructTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnionTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4EnumTypeSpec \EU1/UtopiaStd-Regular(0)/m/it/10.95 and + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (33.06564pt too wide) in paragraph at lines 4143--4150 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 “binary string” types (\EU1/LuxiMono(0)/bx/n/8.2125 bit\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 int\EU1/UtopiaStd-Regular(0)/m/it/10.95 , and \EU1/LuxiMono(0)/bx/n/8.2125 varbit\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) are grouped together in the \EU1/LuxiMono(0)/bx/n/8.2125 P4BitstringLikeTypeSpec + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4160. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[44] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.46094pt too wide) in paragraph at lines 4197--4200 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 An invalid header union (i.e. all headers in the union are invalid) is represented by a \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnion + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[45] [46] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4334. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[47] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (24.68944pt too wide) in paragraph at lines 4422--4428 +[]\EU1/LuxiMono(0)/bx/n/8.2125 translated_type\EU1/UtopiaStd-Regular(0)/m/it/10.95 , if and only if the P4 \EU1/LuxiMono(0)/bx/n/8.2125 type \EU1/UtopiaStd-Regular(0)/m/it/10.95 declaration was annotated with \EU1/LuxiMono(0)/bx/n/8.2125 @p4runtime_translation\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[48] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[49] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (32.59732pt too wide) in paragraph at lines 4530--4536 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 in \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.MatchField\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.Action.Param \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.ControllerPacketMetadata.Metadata\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[50] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4637. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[51] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[52] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[53] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[54] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.53593pt too wide) in paragraph at lines 5093--5096 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 If the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 does not match the table description in the P4Info (e.g. the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 is \EU1/LuxiMono(0)/bx/n/8.2125 action_profile_member_id + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[55] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[56] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[57] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[58] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[59] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[60] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5666. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[61] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[62] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[63] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (9.29865pt too wide) in paragraph at lines 5949--5951 + []\EU1/lmr/bx/n/10.95 9.2.2.1.| Rules on Setting \EU1/LuxiMono(0)/bx/n/8.2125 max_size[] \EU1/UtopiaStd-Regular(0)/m/it/10.95 The valid values for \EU1/LuxiMono(0)/bx/n/8.2125 max_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 depend on the static \EU1/LuxiMono(0)/bx/n/8.2125 max_group_size + [] + +[64] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[65] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[66] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[67] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6237. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6277. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1331) in paragraph at lines 6280--6287 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 A direct counter is a direct resource associated with a \EU1/LuxiMono(0)/bx/n/8.2125 TableEntry \EU1/UtopiaStd-Regular(0)/m/it/10.95 (see [][]Direct Resources[][]). The + [] + +[68] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6354. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[69] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6447. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6478. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[70] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6555. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 6596. + + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 6596. + +[71] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6651. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6661. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[72] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[73] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6785. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[74] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.93839pt too wide) in paragraph at lines 6896--6898 +[]\EU1/LuxiMono(0)/bx/n/8.2125 MODIFY\EU1/UtopiaStd-Regular(0)/m/it/10.95 : Modify the attributes of a given clone session entry, indexed by the given \EU1/LuxiMono(0)/bx/n/8.2125 clone_session_id\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[75] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6934. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[76] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7070. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[77] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7114. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[78] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[79] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7312. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[80] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/error-report.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[81] +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <14.4> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 7436. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7436. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: Hyper reference `wildcard-reads' on page 82 undefined on input line 7458. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[82] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7538. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[83] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[84] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[85] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (34.34796pt too wide) in paragraph at lines 7822--7827 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If an error is encountered before even trying to attempt individual batch updates, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.66206pt too wide) in paragraph at lines 7831--7842 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 Otherwise, if one or more updates in the batch (\EU1/LuxiMono(0)/bx/n/8.2125 WriteRequest.updates\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) failed, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[86] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7878. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[87] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[88] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.4752pt too wide) in paragraph at lines 8107--8111 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 responding to \EU1/LuxiMono(0)/bx/n/8.2125 a \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 c\EU1/UtopiaStd-Regular(0)/m/it/10.95 , followed by a status \EU1/LuxiMono(0)/bx/n/8.2125 {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[89] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8193. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[90] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8316. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[91] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 8414--8417 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If a P4Runtime server supports both \EU1/LuxiMono(0)/bx/n/8.2125 SetForwardingPipelineConfig \EU1/UtopiaStd-Regular(0)/m/it/10.95 as well as returning the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[92] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[93] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[94] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[95] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[96] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8777. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[97] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8845. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/psa-metadata-translation.png Graphic file (type QTm) + [98] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[99] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[100] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[101] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[102] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[103] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 9355--9362 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 p4info-ext should include a Protobuf message definition for every extern type that can + [] + +[104] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 4036) in paragraph at lines 9410--9417 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 P4Runtime also supports streaming arbitrary Protobuf messages between the server and the + [] + + +Underfull \hbox (badness 1629) in paragraph at lines 9410--9417 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 client, by including an \EU1/LuxiMono(0)/bx/n/8.2125 Any \EU1/UtopiaStd-Regular(0)/m/it/10.95 Protobuf field [[][]31[][]] named \EU1/LuxiMono(0)/bx/n/8.2125 other \EU1/UtopiaStd-Regular(0)/m/it/10.95 in both \EU1/LuxiMono(0)/bx/n/8.2125 p4.v1.StreamMessageRequest + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[105] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[106] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1997) in paragraph at lines 9656--9658 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 Table [][]7[][] lists P4$[]$ annotations introduced primarily for the purpose of adding features for the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[107] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[108] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[109] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.61781pt too wide) in paragraph at lines 9803--9810 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 In gRPC, the status of a RPC request is sent as metadata, whose size is limited by the \EU1/LuxiMono(0)/bx/n/8.2125 grpc.max_metadata_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[110] +Underfull \hbox (badness 10000) in paragraph at lines 9894--9895 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Complex Types in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- p4- + [] + + +Underfull \hbox (badness 4001) in paragraph at lines 9906--9907 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Google Cloud APIs Versioning - Backwards-Compatibility.” [][]\EU1/lmtt/m/n/10.95 https:// cloud. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9915--9916 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “gRPC Streaming RPCs in C++.” [][]\EU1/lmtt/m/n/10.95 https:// grpc. io/ docs/ tutorials/ basic/ c. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9927--9928 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “P4 Concurrency Model.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9930--9931 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9945--9946 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Protobuf OneOf Backwards-Compatibility Issues.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + +[111] +Underfull \hbox (badness 10000) in paragraph at lines 9951--9952 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Action Selector.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# sec- action- + [] + + +Underfull \hbox (badness 2409) in paragraph at lines 9960--9961 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Empty Group Action Appendix.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9963--9964 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Select Expressions in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 1668) in paragraph at lines 9978--9979 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Any Protobuf Message.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ protocol- buffers/ docs/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9984--9985 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC C++ Error Details Library.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ grpc/ grpc/ blob/ master/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9987--9988 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC Canonical Status Codes.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ maps- booking/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9993--9994 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Protobuf MessageDifferencer in the C++ API.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9999--10000 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “v1model Architecture Definition.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ p4lang/ p4c/ blob/ master/ + [] + +[112] +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 10008. +[113] +Package atveryend Info: Empty hook `AfterLastShipout' on input line 10008. +(build/P4Runtime-Spec.aux) +Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 10008. +Package atveryend Info: Empty hook `AtEndAfterFileList' on input line 10008. + +LaTeX Font Warning: Some font shapes were not available, defaults substituted. + + +LaTeX Warning: There were undefined references. + + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 27547 strings out of 493638 + 517856 string characters out of 6146796 + 566451 words of memory out of 5000000 + 30649 multiletter control sequences out of 15000+600000 + 14633 words of font info for 98 fonts, out of 8000000 for 9000 + 1328 hyphenation exceptions out of 8191 + 48i,19n,81p,10429b,902s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on build/P4Runtime-Spec.pdf (113 pages). diff --git a/spec/v1.2.0-rc.1/P4Runtime-Spec.pdf b/spec/v1.2.0-rc.1/P4Runtime-Spec.pdf new file mode 100644 index 00000000..d3b70b60 Binary files /dev/null and b/spec/v1.2.0-rc.1/P4Runtime-Spec.pdf differ diff --git a/spec/v1.2.0-rc.1/P4Runtime-Spec.tex b/spec/v1.2.0-rc.1/P4Runtime-Spec.tex new file mode 100644 index 00000000..27addb99 --- /dev/null +++ b/spec/v1.2.0-rc.1/P4Runtime-Spec.tex @@ -0,0 +1,10008 @@ +\documentclass[11pt]{article} +% generated by Madoko, version 1.1.4 +%mdk-data-line={1} + + +\usepackage[heading-base={2},section-num={False},bib-label={hide},fontspec={True}]{madoko2} +\usepackage[top=1in, bottom=1.25in, left=1in, right=1in]{geometry} +\usepackage{fancyhdr} +%mdk-data-line={11} + + \setlength{\headheight}{30pt} + \setlength{\emergencystretch}{2em} + +\begin{document} + + + +{\mdfontfamily{UtopiaStd-Regular} +%mdk-data-line={203} +\mdxtitleblockstart{} +%mdk-data-line={203} +\mdxtitle{{\sffamily{\bfseries\mdline{203}P4Runtime Specification}}}%mdk + +%mdk-data-line={206} +\mdxtitlenote{{\sffamily{\bfseries\mdline{206}version 1.2.0-rc.1}}}%mdk +\mdxauthorstart{} +%mdk-data-line={211} +\mdxauthorname{\mdline{211}The P4.org API Working Group}%mdk +\mdxauthorend +%mdk-data-line={220} +\mdxtitlefooter{{\sffamily{\bfseries\mdline{220}2020-06-18}}}%mdk +\mdtitleauthorrunning{}{}\mdxtitleblockend%mdk + +%mdk-data-line={205} +\begin{abstract}%mdk + +%mdk-data-line={206} +\noindent\mdline{206}P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.%mdk +%mdk +\end{abstract}%mdk +\mdline{214} +\begin{mdtoc}%mdk + +\section*{Contents}\label{sec-contents}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-introduction-and-scope}{\mdref{sec-introduction-and-scope}{1.\hspace*{0.5em}Introduction and Scope}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-language-version-applicability}{\mdref{sec-p4-language-version-applicability}{1.1.\hspace*{0.5em}P4 Language Version Applicability}}%mdk + +\mdtocitemx{sec-in-scope}{\mdref{sec-in-scope}{1.2.\hspace*{0.5em}In Scope}}%mdk + +\mdtocitemx{sec-not-in-scope}{\mdref{sec-not-in-scope}{1.3.\hspace*{0.5em}Not In Scope}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-terms-and-definitions}{\mdref{sec-terms-and-definitions}{2.\hspace*{0.5em}Terms and Definitions}}%mdk + +\mdtocitemx{sec-reference-architecture}{\mdref{sec-reference-architecture}{3.\hspace*{0.5em}Reference Architecture}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-idealized-workflow}{\mdref{sec-idealized-workflow}{3.1.\hspace*{0.5em}Idealized Workflow}}%mdk + +\mdtocitemx{sec-p4-as-behavioral-description-language}{\mdref{sec-p4-as-behavioral-description-language}{3.2.\hspace*{0.5em}P4 as a Behavioral Description Language}}%mdk + +\mdtocitemx{sec-alternative-workflows}{\mdref{sec-alternative-workflows}{3.3.\hspace*{0.5em}Alternative Workflows}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{\mdref{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{3.3.1.\hspace*{0.5em}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}}%mdk + +\mdtocitemx{sec-no-p4-source-available-p4info-available}{\mdref{sec-no-p4-source-available-p4info-available}{3.3.2.\hspace*{0.5em}No P4 Source Available, P4Info Available}}%mdk + +\mdtocitemx{sec-partial-p4info-and-p4-source-are-available}{\mdref{sec-partial-p4info-and-p4-source-are-available}{3.3.3.\hspace*{0.5em}Partial P4Info and P4 Source are Available}}%mdk + +\mdtocitemx{sec-p4info-role-based-subsets}{\mdref{sec-p4info-role-based-subsets}{3.3.4.\hspace*{0.5em}P4Info Role-Based Subsets}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-restarts}{\mdref{sec-restarts}{3.4.\hspace*{0.5em}P4Runtime State Across Restarts}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-controller-use-cases}{\mdref{sec-controller-use-cases}{4.\hspace*{0.5em}Controller Use-cases}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-single-embedded-controller}{\mdref{sec-single-embedded-controller}{4.1.\hspace*{0.5em}Single Embedded Controller}}%mdk + +\mdtocitemx{sec-single-remote-controller}{\mdref{sec-single-remote-controller}{4.2.\hspace*{0.5em}Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-single-remote-controller}{\mdref{sec-embedded-single-remote-controller}{4.3.\hspace*{0.5em}Embedded + Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-two-remote-controllers}{\mdref{sec-embedded-two-remote-controllers}{4.4.\hspace*{0.5em}Embedded + Two Remote Controllers}}%mdk + +\mdtocitemx{sec-embedded-controller-two-high-availability-remote-controllers}{\mdref{sec-embedded-controller-two-high-availability-remote-controllers}{4.5.\hspace*{0.5em}Embedded Controller + Two High-Availability Remote Controllers}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-master-slave-arbitration-and-controller-replication}{\mdref{sec-master-slave-arbitration-and-controller-replication}{5.\hspace*{0.5em}Master-Slave Arbitration and Controller Replication}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-default-role}{\mdref{sec-default-role}{5.1.\hspace*{0.5em}Default Role}}%mdk + +\mdtocitemx{sec-arbitration-role-config}{\mdref{sec-arbitration-role-config}{5.2.\hspace*{0.5em}Role Config}}%mdk + +\mdtocitemx{sec-mastership-updates}{\mdref{sec-mastership-updates}{5.3.\hspace*{0.5em}Rules for Handling \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}} Messages Received from Controllers}}%mdk + +\mdtocitemx{sec-mastership-notification}{\mdref{sec-mastership-notification}{5.4.\hspace*{0.5em}Mastership Notifications}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-the-p4info-message}{\mdref{sec-the-p4info-message}{6.\hspace*{0.5em}The P4Info Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-common-messages}{\mdref{sec-common-messages}{6.1.\hspace*{0.5em}Common Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-documentation-message}{\mdref{sec-documentation-message}{6.1.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}} Message}}%mdk + +\mdtocitemx{sec-preamble-message}{\mdref{sec-preamble-message}{6.1.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}} Message}}%mdk + +\mdtocitemx{sec-annotating-p4-entities-with-documentation}{\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3.\hspace*{0.5em}Annotating P4 Entities with \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}}%mdk + +\mdtocitemx{sec-structured-annotations}{\mdref{sec-structured-annotations}{6.1.4.\hspace*{0.5em}Structured Annotations}}%mdk + +\mdtocitemx{sec-sourcelocation-message}{\mdref{sec-sourcelocation-message}{6.1.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}} Message}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-pkginfo-message}{\mdref{sec-pkginfo-message}{6.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}} Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-annotating-p4-code-with-pkginfo}{\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1.\hspace*{0.5em}Annotating P4 code with PkgInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-id-allocation}{\mdref{sec-id-allocation}{6.3.\hspace*{0.5em}ID Allocation for P4Info Objects}}%mdk + +\mdtocitemx{sec-p4info-objects}{\mdref{sec-p4info-objects}{6.4.\hspace*{0.5em}P4Info Objects}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table}{\mdref{sec-table}{6.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}}%mdk + +\mdtocitemx{sec-action}{\mdref{sec-action}{6.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}}%mdk + +\mdtocitemx{sec-p4info-action-profile}{\mdref{sec-p4info-action-profile}{6.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}}%mdk + +\mdtocitemx{sec-counter-directcounter}{\mdref{sec-counter-directcounter}{6.4.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}}%mdk + +\mdtocitemx{sec-meter-directmeter}{\mdref{sec-meter-directmeter}{6.4.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}}%mdk + +\mdtocitemx{sec-controller-packet-meta}{\mdref{sec-controller-packet-meta}{6.4.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}}%mdk + +\mdtocitemx{sec-valueset}{\mdref{sec-valueset}{6.4.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}}%mdk + +\mdtocitemx{sec-register}{\mdref{sec-register}{6.4.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}}%mdk + +\mdtocitemx{sec-digest}{\mdref{sec-digest}{6.4.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}}%mdk + +\mdtocitemx{sec-p4info-extern}{\mdref{sec-p4info-extern}{6.4.10.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{\mdref{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{6.5.\hspace*{0.5em}Support for Arbitrary P4 Types with P4TypeInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-fwd-pipe-config}{\mdref{sec-p4-fwd-pipe-config}{7.\hspace*{0.5em}P4 Forwarding-Pipeline Configuration}}%mdk + +\mdtocitemx{sec-general-principles-for-message-formatting}{\mdref{sec-general-principles-for-message-formatting}{8.\hspace*{0.5em}General Principles for Message Formatting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-set-unset-protobuf-field}{\mdref{sec-set-unset-protobuf-field}{8.1.\hspace*{0.5em}Set / Unset Protobuf Field}}%mdk + +\mdtocitemx{sec-read-write-symmetry}{\mdref{sec-read-write-symmetry}{8.2.\hspace*{0.5em}Read-Write Symmetry}}%mdk + +\mdtocitemx{sec-zero-as-reserved-value}{\mdref{sec-zero-as-reserved-value}{8.3.\hspace*{0.5em}Zero as Reserved Value}}%mdk + +\mdtocitemx{sec-bytestrings}{\mdref{sec-bytestrings}{8.4.\hspace*{0.5em}Bytestrings}}%mdk + +\mdtocitemx{sec-representation-of-arbitrary-p4-types}{\mdref{sec-representation-of-arbitrary-p4-types}{8.5.\hspace*{0.5em}Representation of Arbitrary P4 Types}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-problem-statement}{\mdref{sec-problem-statement}{8.5.1.\hspace*{0.5em}Problem Statement}}%mdk + +\mdtocitemx{sec-p4-type-specifications-in-p4infoproto}{\mdref{sec-p4-type-specifications-in-p4infoproto}{8.5.2.\hspace*{0.5em}P4 Type Specifications in p4info.proto}}%mdk + +\mdtocitemx{sec-p4data-in-p4runtime-proto}{\mdref{sec-p4data-in-p4runtime-proto}{8.5.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}} in p4runtime.proto}}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{8.5.4.\hspace*{0.5em}Example}}%mdk + +\mdtocitemx{sec-enum-serializable-enum-and-error}{\mdref{sec-enum-serializable-enum-and-error}{8.5.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}, serializable \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}}%mdk + +\mdtocitemx{sec-user-defined-types}{\mdref{sec-user-defined-types}{8.5.6.\hspace*{0.5em}User-defined types}}%mdk + +\mdtocitemx{sec-trade-off-for-v1x-releases}{\mdref{sec-trade-off-for-v1x-releases}{8.5.7.\hspace*{0.5em}Trade-off for v1.x Releases}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-entity-msgs}{\mdref{sec-p4-entity-msgs}{9.\hspace*{0.5em}P4 Entity Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table-entry}{\mdref{sec-table-entry}{9.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-match-format}{\mdref{sec-match-format}{9.1.1.\hspace*{0.5em}Match Format}}%mdk + +\mdtocitemx{sec-action-specification}{\mdref{sec-action-specification}{9.1.2.\hspace*{0.5em}Action Specification}}%mdk + +\mdtocitemx{sec-default-entry}{\mdref{sec-default-entry}{9.1.3.\hspace*{0.5em}Default Entry}}%mdk + +\mdtocitemx{sec-constant-tables}{\mdref{sec-constant-tables}{9.1.4.\hspace*{0.5em}Constant Tables}}%mdk + +\mdtocitemx{sec-table-wildcard-reads}{\mdref{sec-table-wildcard-reads}{9.1.5.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-direct-resources}{\mdref{sec-direct-resources}{9.1.6.\hspace*{0.5em}Direct Resources}}%mdk + +\mdtocitemx{sec-idle-timeout}{\mdref{sec-idle-timeout}{9.1.7.\hspace*{0.5em}Idle-timeout}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-and-group}{\mdref{sec-action-profile-member-and-group}{9.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-programming}{\mdref{sec-action-profile-member-programming}{9.2.1.\hspace*{0.5em}Action Profile Member Programming}}%mdk + +\mdtocitemx{sec-action-profile-group-programming}{\mdref{sec-action-profile-group-programming}{9.2.2.\hspace*{0.5em}Action Profile Group Programming}}%mdk + +\mdtocitemx{sec-oneshot}{\mdref{sec-oneshot}{9.2.3.\hspace*{0.5em}One Shot Action Selector Programming}}%mdk + +\mdtocitemx{action-selector-constraints}{\mdref{action-selector-constraints}{9.2.4.\hspace*{0.5em}Constraints on action selector programming}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-counterentry-directcounterentry}{\mdref{sec-counterentry-directcounterentry}{9.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directcounterentry}{\mdref{sec-directcounterentry}{9.3.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\mdtocitemx{sec-counterentry}{\mdref{sec-counterentry}{9.3.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-meterentry-directmeterentry}{\mdref{sec-meterentry-directmeterentry}{9.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directmeterentry}{\mdref{sec-directmeterentry}{9.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\mdtocitemx{sec-meterentry}{\mdref{sec-meterentry}{9.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-packetreplicationengineentry}{\mdref{sec-packetreplicationengineentry}{9.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-multicastgroupentry}{\mdref{sec-multicastgroupentry}{9.5.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}}%mdk + +\mdtocitemx{sec-clonesessionentry}{\mdref{sec-clonesessionentry}{9.5.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-valuesetentry}{\mdref{sec-valuesetentry}{9.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}}%mdk + +\mdtocitemx{sec-registerentry}{\mdref{sec-registerentry}{9.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}}%mdk + +\mdtocitemx{sec-digestentry}{\mdref{sec-digestentry}{9.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}}%mdk + +\mdtocitemx{sec-extern-entry}{\mdref{sec-extern-entry}{9.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-error-reporting-messages}{\mdref{sec-error-reporting-messages}{10.\hspace*{0.5em}Error Reporting Messages}}%mdk + +\mdtocitemx{sec-atomicity-of-individual-write-and-read-operations}{\mdref{sec-atomicity-of-individual-write-and-read-operations}{11.\hspace*{0.5em}Atomicity of Individual \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} Operations}}%mdk + +\mdtocitemx{sec-write-rpc}{\mdref{sec-write-rpc}{12.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-batching-and-ordering-of-updates}{\mdref{sec-batching-and-ordering-of-updates}{12.1.\hspace*{0.5em}Batching and Ordering of Updates}}%mdk + +\mdtocitemx{sec-batch-atomicity}{\mdref{sec-batch-atomicity}{12.2.\hspace*{0.5em}Batch Atomicity}}%mdk + +\mdtocitemx{sec-error-reporting}{\mdref{sec-error-reporting}{12.3.\hspace*{0.5em}Error Reporting}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-read-rpc}{\mdref{sec-read-rpc}{13.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-nomenclature}{\mdref{sec-nomenclature}{13.1.\hspace*{0.5em}Nomenclature}}%mdk + +\mdtocitemx{sec-wildcard-reads}{\mdref{sec-wildcard-reads}{13.2.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-batch-processing}{\mdref{sec-batch-processing}{13.3.\hspace*{0.5em}Batch Processing}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{13.3.1.\hspace*{0.5em}Example}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-parallelism-of-read-and-write-requests}{\mdref{sec-parallelism-of-read-and-write-requests}{13.4.\hspace*{0.5em}Parallelism of Read and Write Requests}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-setforwardingpipelineconfig-rpc}{\mdref{sec-setforwardingpipelineconfig-rpc}{14.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-getforwardingpipelineconfig-rpc}{\mdref{sec-getforwardingpipelineconfig-rpc}{15.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-p4runtime-stream-messages}{\mdref{sec-p4runtime-stream-messages}{16.\hspace*{0.5em}P4Runtime Stream Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-packet-i_o}{\mdref{sec-packet-i_o}{16.1.\hspace*{0.5em}Packet I/O}}%mdk + +\mdtocitemx{sec-master-arbitration-update}{\mdref{sec-master-arbitration-update}{16.2.\hspace*{0.5em}Master Arbitration Update}}%mdk + +\mdtocitemx{sec-digest-messages}{\mdref{sec-digest-messages}{16.3.\hspace*{0.5em}Digest Messages}}%mdk + +\mdtocitemx{sec-table-idle-timeout-notification}{\mdref{sec-table-idle-timeout-notification}{16.4.\hspace*{0.5em}Table Idle Timeout Notification}}%mdk + +\mdtocitemx{sec-architecture-specific-notifications}{\mdref{sec-architecture-specific-notifications}{16.5.\hspace*{0.5em}Architecture-Specific Notifications}}%mdk + +\mdtocitemx{sec-stream-error-reporting}{\mdref{sec-stream-error-reporting}{16.6.\hspace*{0.5em}Stream Error Reporting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-examples-of-streamerror-messages}{\mdref{sec-examples-of-streamerror-messages}{16.6.1.\hspace*{0.5em}Examples of \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}} Messages}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-capabilities-rpc}{\mdref{sec-capabilities-rpc}{17.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}} RPC}}%mdk + +\mdtocitemx{sec-portability-considerations}{\mdref{sec-portability-considerations}{18.\hspace*{0.5em}Portability Considerations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-psa-metadata-translation}{\mdref{sec-psa-metadata-translation}{18.1.\hspace*{0.5em}PSA Metadata Translation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-translation-of-port-numbers}{\mdref{sec-translation-of-port-numbers}{18.1.1.\hspace*{0.5em}Translation of Port Numbers}}%mdk + +\mdtocitemx{sec-translation-of-packet-io-header-fields}{\mdref{sec-translation-of-packet-io-header-fields}{18.1.2.\hspace*{0.5em}Translation of Packet-IO Header Fields}}%mdk + +\mdtocitemx{sec-translation-of-match-fields}{\mdref{sec-translation-of-match-fields}{18.1.3.\hspace*{0.5em}Translation of Match Fields}}%mdk + +\mdtocitemx{sec-translation-of-action-parameters}{\mdref{sec-translation-of-action-parameters}{18.1.4.\hspace*{0.5em}Translation of Action Parameters}}%mdk + +\mdtocitemx{sec-port-translation-for-psa-extern-apis}{\mdref{sec-port-translation-for-psa-extern-apis}{18.1.5.\hspace*{0.5em}Port Translation for PSA Extern APIs}}%mdk + +\mdtocitemx{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{\mdref{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{18.1.6.\hspace*{0.5em}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-versioning}{\mdref{sec-p4runtime-versioning}{19.\hspace*{0.5em}P4Runtime Versioning}}%mdk + +\mdtocitemx{sec-extending-p4runtime}{\mdref{sec-extending-p4runtime}{20.\hspace*{0.5em}Extending P4Runtime for non-PSA Architectures}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-p4runtime-for-architecture-specific-externs}{\mdref{sec-extending-p4runtime-for-architecture-specific-externs}{20.1.\hspace*{0.5em}Extending P4Runtime for Architecture-Specific Externs}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-the-p4info-message}{\mdref{sec-extending-the-p4info-message}{20.1.1.\hspace*{0.5em}Extending the P4Info message}}%mdk + +\mdtocitemx{sec-extending-the-p4runtime-service}{\mdref{sec-extending-the-p4runtime-service}{20.1.2.\hspace*{0.5em}Extending the P4Runtime Service}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-architecture-specific-table-extensions}{\mdref{sec-architecture-specific-table-extensions}{20.2.\hspace*{0.5em}Architecture-Specific Table Extensions}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-new-match-types}{\mdref{sec-new-match-types}{20.2.1.\hspace*{0.5em}New Match Types}}%mdk + +\mdtocitemx{sec-new-table-properties}{\mdref{sec-new-table-properties}{20.2.2.\hspace*{0.5em}New Table Properties}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-known-limitations-of-current-p4runtime-version}{\mdref{sec-known-limitations-of-current-p4runtime-version}{21.\hspace*{0.5em}Known Limitations of Current P4Runtime Version}}%mdk + +\mdtocitemx{sec-security-concerns-for-p4runtime}{\mdref{sec-security-concerns-for-p4runtime}{22.\hspace*{0.5em}Security concerns for P4Runtime}}%mdk + +\mdtocitemx{sec-appendix}{\mdref{sec-appendix}{A.\hspace*{0.5em}Appendix}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-revision-history}{\mdref{sec-revision-history}{A.1.\hspace*{0.5em}Revision History}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-changes-in-v120}{\mdref{sec-changes-in-v120}{A.1.1.\hspace*{0.5em}Changes in v1.2.0}}%mdk + +\mdtocitemx{sec-changes-in-v110}{\mdref{sec-changes-in-v110}{A.1.2.\hspace*{0.5em}Changes in v1.1.0}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-annotations}{\mdref{sec-p4-annotations}{A.2.\hspace*{0.5em}P4 Annotations}}%mdk + +\mdtocitemx{sec-value-set-example}{\mdref{sec-value-set-example}{A.3.\hspace*{0.5em}A More Complex Value Set Example}}%mdk + +\mdtocitemx{sec-guidelines-for-implementations}{\mdref{sec-guidelines-for-implementations}{A.4.\hspace*{0.5em}Guidelines for Implementations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-grpc-metadata-maximum-size}{\mdref{sec-grpc-metadata-maximum-size}{A.4.1.\hspace*{0.5em}gRPC Metadata Maximum Size}}%mdk + +\mdtocitemx{sec-grpc-server-maximum-receive-message-size}{\mdref{sec-grpc-server-maximum-receive-message-size}{A.4.2.\hspace*{0.5em}gRPC Server Maximum Receive Message Size}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-bibliography}{\mdref{sec-bibliography}{References}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{215} +\begin{mdtoc}%mdk + +\section*{Figures}\label{sec-figures}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{fig-reference-architecture}{\mdref{fig-reference-architecture}{\mdcaptionlabel{1}. P4Runtime Reference Architecture.}}%mdk + +\mdtocitemx{fig-single-embedded-controller}{\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}. Use-Case: Single Embedded Controller}}%mdk + +\mdtocitemx{fig-single-remote-controller}{\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}. Use-Case: Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-single-remote-controller}{\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}. Use-Case: Embedded Plus Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-controllers}{\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}. Use-Case: Embedded Plus Two Remote Controllers}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-ha-controllers}{\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}. Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk + +\mdtocitemx{fig-error-report}{\mdref{fig-error-report}{\mdcaptionlabel{7}. P4Runtime Error Report Message Format}}%mdk + +\mdtocitemx{fig-psa-metadata-translation}{\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}. P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{216} +\begin{mdtoc}%mdk + +\section*{Tables}\label{sec-tables}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{tab-mapping-p4-obj-ids}{\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}. Mapping of P4Info object type to 8-bit ID prefix value}}%mdk + +\mdtocitemx{tab-format-p4-obj-ids}{\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}. Format of P4Info object IDs}}%mdk + +\mdtocitemx{tab-exmpl-p4-obj-ids}{\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}. Example of statically-assigned P4Info object IDs}}%mdk + +\mdtocitemx{tab-valid-bytestring-encoding}{\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}. Examples of Valid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-invalid-bytestring-encoding}{\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}. Examples of Invalid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-p4-type-usage}{\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}. P4 Type Usage}}%mdk + +\mdtocitemx{tab-p4-annotations}{\mdref{tab-p4-annotations}{\mdcaptionlabel{7}. P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk + +%mdk-data-line={218} +\section{\mdline{218}1.\hspace*{0.5em}\mdline{218}Introduction and Scope}\label{sec-introduction-and-scope}%mdk%mdk + +%mdk-data-line={220} +\noindent\mdline{220}This document is published by the \mdline{220}\emph{P4.org API Working Group}\mdline{220}, which was +chartered\mdline{221}~[\mdcite{p4apiwgcharter}{17}]\mdline{221} to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called \mdline{223}\emph{P4Runtime}\mdline{223}. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +\mdline{226}\href{https://github.com/p4lang/p4runtime/tree/master/proto}{https://github.com/p4lang/p4runtime/tree/master/proto}\mdline{226}.%mdk + +%mdk-data-line={228} +\subsection{\mdline{228}1.1.\hspace*{0.5em}\mdline{228}P4 Language Version Applicability}\label{sec-p4-language-version-applicability}%mdk%mdk + +%mdk-data-line={230} +\noindent\mdline{230}P4Runtime is designed to be implemented in conjunction with the P4\mdline{230}\mdsub{16}\mdline{230} language +version or later. P4\mdline{231}\mdsub{14}\mdline{231} programs should be translated into P4\mdline{231}\mdsub{16}\mdline{231} to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P4\mdline{233}\mdsub{16}\mdline{233} 1.0, but were introduced in P4\mdline{233}\mdsub{16}\mdline{233} 1.1.0\mdline{233}~[\mdcite{p4revisions110}{29}]\mdline{233}. For +this version of P4Runtime, we recommend using P4\mdline{234}\mdsub{16}\mdline{234} 1.2.1\mdline{234}~[\mdcite{p4spec}{1}]\mdline{234}.%mdk + +%mdk-data-line={236} +\subsection{\mdline{236}1.2.\hspace*{0.5em}\mdline{236}In Scope}\label{sec-in-scope}%mdk%mdk + +%mdk-data-line={238} +\noindent\mdline{238}This specification document defines the \mdline{238}\emph{semantics}\mdline{238} of \mdline{238}\emph{P4Runtime}\mdline{238} messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime:%mdk + +%mdk-data-line={242} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={242} +\item\mdline{242}Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA)\mdline{243}~[\mdcite{psa}{19}]\mdline{243} externs (\mdline{243}e.g.\mdline{243} Counters, Meters, Action +Profiles, \mdline{244}\dots{}\mdline{244}). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0.%mdk + +%mdk-data-line={246} +\item\mdline{246}Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism.%mdk + +%mdk-data-line={248} +\item\mdline{248}Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy.%mdk + +%mdk-data-line={251} +\item\mdline{251}Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities.%mdk + +%mdk-data-line={253} +\item\mdline{253}Packet I/O to enable streaming packets to \mdline{253}\&\mdline{253} from the control plane.%mdk + +%mdk-data-line={254} +\item\mdline{254}Batching support, with different atomicity guarantees.%mdk + +%mdk-data-line={255} +\item\mdline{255}In-the-field device-reconfiguration with a new P4 data plane.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={257} +\noindent\mdline{257}The following are in the scope of this specification document:%mdk + +%mdk-data-line={259} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={259} +\item\mdline{259}Rationale for the P4Runtime design.%mdk + +%mdk-data-line={260} +\item\mdline{260}Reference architecture and use-cases for deploying a P4Runtime service.%mdk + +%mdk-data-line={261} +\item\mdline{261}Detailed description of the API semantics.%mdk + +%mdk-data-line={262} +\item\mdline{262}Requirements for conformant implementations of the API.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={264} +\subsection{\mdline{264}1.3.\hspace*{0.5em}\mdline{264}Not In Scope}\label{sec-not-in-scope}%mdk%mdk + +%mdk-data-line={266} +\noindent\mdline{266}The following are not in scope of P4Runtime:%mdk + +%mdk-data-line={268} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={268} +\item\mdline{268}Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +\mdline{273}[\mdcite{openconfig}{35}]\mdline{273}. An open source implementation of these APIs is also in progress +as part of the Stratum project\mdline{274}~[\mdcite{stratum}{37}]\mdline{274}.%mdk + +%mdk-data-line={275} +\item\mdline{275}Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={280} +\noindent\mdline{280}The following are not in scope of this specification document:%mdk + +%mdk-data-line={282} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={282} +\item\mdline{282}Description of the P4 programming language; it is assumed that the reader is +already familiar with P4\mdline{283}\mdsub{16}\mdline{283}~[\mdcite{p4spec}{1}]\mdline{283}.%mdk + +%mdk-data-line={284} +\item\mdline{284}Descriptions of gRPC and Protobuf files in general.%mdk + +%mdk-data-line={285} +\item\mdline{285}Controller\mdline{285}~\mdref{sec-arbitration-role-config}{role}\mdline{285} definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={289} +\section{\mdline{289}2.\hspace*{0.5em}\mdline{289}Terms and Definitions}\label{sec-terms-and-definitions}%mdk%mdk + +%mdk-data-line={291} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries arbitration}}%mdk + +%mdk-data-line={291} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{291}Refers to the process through which P4Runtime ensures that at any given +time, there is a single master (\mdline{292}i.e.\mdline{292} a client with write access) for a given +role. Also referred to as \mdline{293}\textquotedblleft{}master-slave arbitration\textquotedblright{}\mdline{293}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries client}}%mdk + +%mdk-data-line={295} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{295}The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries COS}}%mdk + +%mdk-data-line={299} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{299}Class of Service. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries device}}%mdk + +%mdk-data-line={301} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{301}Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries entity}}%mdk + +%mdk-data-line={305} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{305}An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries gRPC}}%mdk + +%mdk-data-line={308} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{308}gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +\mdline{309}[\mdcite{grpc}{9}]\mdline{309}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries HA}}%mdk + +%mdk-data-line={311} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{311}High-Availability. Refers to a redundancy architecture. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Instrumentation}}%mdk + +%mdk-data-line={313} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{313}The part of the P4Runtime server which implements the calls to the device or +target native \mdline{314}\textquotedblleft{}SDK\textquotedblright{}\mdline{314} or backend. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries IPC}}%mdk + +%mdk-data-line={316} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{316}Inter-Process Communication. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Blob}}%mdk + +%mdk-data-line={318} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{318}A more colloquial term for P4 Device Config (Blob = Binary Large Object). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Device Config}}%mdk + +%mdk-data-line={320} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{320}The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its \mdline{322}\textquotedblleft{}program.\textquotedblright{}\mdline{322} +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4Info}}%mdk + +%mdk-data-line={324} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{324}Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4RT}}%mdk + +%mdk-data-line={328} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{328}Abbreviation for P4Runtime. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Protobuf (Protocol Buffers)}}%mdk + +%mdk-data-line={330} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{330}The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See\mdline{331}~[\mdcite{proto}{21}]\mdline{331}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries PSA}}%mdk + +%mdk-data-line={333} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{333}Portable Switch Architecture\mdline{333}~[\mdcite{psa}{19}]\mdline{333}; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RPC}}%mdk + +%mdk-data-line={337} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{337}Remote Procedure Call. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RTT}}%mdk + +%mdk-data-line={339} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{339}Round-trip time. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN}}%mdk + +%mdk-data-line={341} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{341}Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network \mdline{346}\emph{controller}\mdline{346}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN port}}%mdk + +%mdk-data-line={348} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{348}A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries server}}%mdk + +%mdk-data-line={352} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{352}The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries stream}}%mdk + +%mdk-data-line={356} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{356}Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (\mdline{357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{357}), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and master-slave arbitration, among other +things. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries switch config}}%mdk + +%mdk-data-line={362} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{362}Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries target}}%mdk + +%mdk-data-line={367} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{367}The hardware or software entity which \mdline{367}\textquotedblleft{}executes\textquotedblright{}\mdline{367} the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with \mdline{368}\textquotedblleft{}device\textquotedblright{}\mdline{368}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries URI}}%mdk + +%mdk-data-line={370} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{370}Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={374} +\section{\mdline{374}3.\hspace*{0.5em}\mdline{374}Reference Architecture}\label{sec-reference-architecture}%mdk%mdk + +%mdk-data-line={376} +\noindent\mdline{376}Figure\mdline{376}~\mdref{fig-reference-architecture}{\mdcaptionlabel{1}}\mdline{376} represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. A multi-master protocol allows more than +one controller to participate, and a role-based arbitration scheme ensures only +one controller has write access to each read/write entity, or the pipeline +config itself. Any controller may perform read access to any entity or the +pipeline config. Later sections describe this in detail. For the sake of +brevity, the term controller may refer to one or more controllers.%mdk + +%mdk-data-line={385} +\mdline{385}The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +\mdline{388}[\mdcite{p4runtimerepo}{15}]\mdline{388}. It may be compiled via protoc\mdline{388} \mdline{388}\textemdash{}\mdline{388} the Protobuf compiler\mdline{388} \mdline{388}\textemdash{}\mdline{388} +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server.%mdk + +%mdk-data-line={393} +\mdline{393}Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository\mdline{394}~[\mdcite{pirepo}{16}]\mdline{394}. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, \mdline{396}e.g.\mdline{396} via callbacks, thus reducing the burden of implementing +P4Runtime.%mdk + +%mdk-data-line={399} +\mdline{399}The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard.%mdk + +%mdk-data-line={403} +\mdline{403}The controller can also set the \mdline{403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{403}, which amounts to +installing and running the compiled P4 program output, which is included in the +\mdline{405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{405} Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +\mdline{407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{407} to retrieve the device config and the P4Info.%mdk + +%mdk-data-line={410} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={411} +\noindent\mdline{411}\includegraphics[keepaspectratio=true,height=7cm]{build/reference-architecture}{}\mdline{411}%mdk + +%mdk-data-line={412} +\mdhr{}%mdk + +%mdk-data-line={413} +\noindent\mdline{413}\mdcaption{\textbf{Figure~\mdcaptionlabel{1}.}~\mdcaptiontext{P4Runtime Reference Architecture.}}%mdk +%mdk +\end{mdcenter}\label{fig-reference-architecture}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={417} +\subsection{\mdline{417}3.1.\hspace*{0.5em}\mdline{417}Idealized Workflow}\label{sec-idealized-workflow}%mdk%mdk + +%mdk-data-line={419} +\noindent\mdline{419}In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the \mdline{420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{420} +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a \mdline{422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{422} +RPC. Metadata in the P4Info describes both the overall program itself +(\mdline{424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{424}) as well as all entity instances derived from the P4 program\mdline{424} \mdline{424}\textemdash{}\mdline{424} +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise \mdline{426}\textquotedblleft{}handle\textquotedblright{}\mdline{426} used in API +calls.%mdk + +%mdk-data-line={429} +\mdline{429}In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible.%mdk + +%mdk-data-line={435} +\mdline{435}In some use cases, it is expected that a controller will store a +collection of multiple P4 \mdline{436}\textquotedblleft{}packages\textquotedblright{}\mdline{436}, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the \mdline{438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{438} from the target via the +\mdline{439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineRequest}}}\mdline{439} RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state.%mdk + +%mdk-data-line={443} +\subsection{\mdline{443}3.2.\hspace*{0.5em}\mdline{443}P4 as a Behavioral Description Language}\label{sec-p4-as-behavioral-description-language}%mdk%mdk + +%mdk-data-line={445} +\noindent\mdline{445}P4 can be considered a behavioral description of a switching device which may or +may not execute \mdline{446}\textquotedblleft{}P4\textquotedblright{}\mdline{446} natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a \mdline{448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineRequest}}}\mdline{448} to +change its pipeline \mdline{449}\textquotedblleft{}program\textquotedblright{}\mdline{449}, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device.%mdk + +%mdk-data-line={455} +\mdline{455}While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API.%mdk + +%mdk-data-line={464} +\mdline{464}In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the \mdline{465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{465} +message as well as the embedded \mdline{466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{466} fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections.%mdk + +%mdk-data-line={470} +\subsection{\mdline{470}3.3.\hspace*{0.5em}\mdline{470}Alternative Workflows}\label{sec-alternative-workflows}%mdk%mdk + +%mdk-data-line={472} +\noindent\mdline{472}Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary.%mdk + +%mdk-data-line={476} +\subsubsection{\mdline{476}3.3.1.\hspace*{0.5em}\mdline{476}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}\label{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}%mdk%mdk + +%mdk-data-line={478} +\noindent\mdline{478}In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +\mdline{480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{480}. The device\mdline{480}'\mdline{480}s configuration might be derived via some other +means to implement the P4 source code\mdline{481}'\mdline{481}s intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane.%mdk + +%mdk-data-line={485} +\subsubsection{\mdline{485}3.3.2.\hspace*{0.5em}\mdline{485}No P4 Source Available, P4Info Available}\label{sec-no-p4-source-available-p4info-available}%mdk%mdk + +%mdk-data-line={487} +\noindent\mdline{487}In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are:%mdk + +%mdk-data-line={490} +\begin{enumerate}%mdk + +%mdk-data-line={490} +\item{} +%mdk-data-line={490} +\mdline{490}The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security.%mdk%mdk + +%mdk-data-line={493} +\item{} +%mdk-data-line={493} +\mdline{493}The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={496} +\noindent\mdline{496}As discussed in Section\mdline{496}~\mdref{sec-p4-as-behavioral-description-language}{3.2}\mdline{496}, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, \mdline{499}e.g.\mdline{499} documentation.%mdk + +%mdk-data-line={501} +\subsubsection{\mdline{501}3.3.3.\hspace*{0.5em}\mdline{501}Partial P4Info and P4 Source are Available}\label{sec-partial-p4info-and-p4-source-are-available}%mdk%mdk + +%mdk-data-line={503} +\noindent\mdline{503}In this situation, a subset of the target\mdline{503}'\mdline{503}s pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code.%mdk + +%mdk-data-line={510} +\subsubsection{\mdline{510}3.3.4.\hspace*{0.5em}\mdline{510}P4Info Role-Based Subsets}\label{sec-p4info-role-based-subsets}%mdk%mdk + +%mdk-data-line={512} +\noindent\mdline{512}In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more.%mdk + +%mdk-data-line={516} +\subsection{\mdline{516}3.4.\hspace*{0.5em}\mdline{516}P4Runtime State Across Restarts}\label{sec-restarts}%mdk%mdk + +%mdk-data-line={518} +\noindent\mdline{518}All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade.%mdk + +%mdk-data-line={524} +\section{\mdline{524}4.\hspace*{0.5em}\mdline{524}Controller Use-cases}\label{sec-controller-use-cases}%mdk%mdk + +%mdk-data-line={526} +\noindent\mdline{526}P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +\mdline{528}\mdref{sec-master-slave-arbitration-and-controller-replication}{section}\mdline{528}. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime\mdline{530}'\mdline{530}s flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex.%mdk + +%mdk-data-line={533} +\subsection{\mdline{533}4.1.\hspace*{0.5em}\mdline{533}Single Embedded Controller}\label{sec-single-embedded-controller}%mdk%mdk + +%mdk-data-line={535} +\noindent\mdline{535}Figure\mdline{535}~\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}}\mdline{535} shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases.%mdk + +%mdk-data-line={540} +\mdline{540}P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC.%mdk + +%mdk-data-line={545} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={546} +\noindent\mdline{546}\includegraphics[keepaspectratio=true,height=6cm]{build/single-embedded-controller}{}\mdline{546}%mdk + +%mdk-data-line={547} +\mdhr{}%mdk + +%mdk-data-line={548} +\noindent\mdline{548}\mdcaption{\textbf{Figure~\mdcaptionlabel{2}.}~\mdcaptiontext{Use-Case: Single Embedded Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-embedded-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={552} +\subsection{\mdline{552}4.2.\hspace*{0.5em}\mdline{552}Single Remote Controller}\label{sec-single-remote-controller}%mdk%mdk + +%mdk-data-line={554} +\noindent\mdline{554}Figure\mdline{554}~\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}}\mdline{554} shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections.%mdk + +%mdk-data-line={559} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={560} +\noindent\mdline{560}\includegraphics[keepaspectratio=true,height=7cm]{build/single-remote-controller}{}\mdline{560}%mdk + +%mdk-data-line={561} +\mdhr{}%mdk + +%mdk-data-line={562} +\noindent\mdline{562}\mdcaption{\textbf{Figure~\mdcaptionlabel{3}.}~\mdcaptiontext{Use-Case: Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={566} +\subsection{\mdline{566}4.3.\hspace*{0.5em}\mdline{566}Embedded\mdline{566} \mdline{566}+ Single Remote Controller}\label{sec-embedded-single-remote-controller}%mdk%mdk + +%mdk-data-line={568} +\noindent\mdline{568}Figure\mdline{568}~\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}}\mdline{568} illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller.%mdk + +%mdk-data-line={575} +\mdline{575}For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables.%mdk + +%mdk-data-line={579} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={580} +\noindent\mdline{580}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-single-remote-controller}{}\mdline{580}%mdk + +%mdk-data-line={581} +\mdhr{}%mdk + +%mdk-data-line={582} +\noindent\mdline{582}\mdcaption{\textbf{Figure~\mdcaptionlabel{4}.}~\mdcaptiontext{Use-Case: Embedded Plus Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={587} +\subsection{\mdline{587}4.4.\hspace*{0.5em}\mdline{587}Embedded\mdline{587} \mdline{587}+ Two Remote Controllers}\label{sec-embedded-two-remote-controllers}%mdk%mdk + +%mdk-data-line={589} +\noindent\mdline{589}Figure\mdline{589}~\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}}\mdline{589} illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +\mdline{592}e.g.\mdline{592} routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership.%mdk + +%mdk-data-line={595} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={596} +\noindent\mdline{596}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-controllers}{}\mdline{596}%mdk + +%mdk-data-line={597} +\mdhr{}%mdk + +%mdk-data-line={598} +\noindent\mdline{598}\mdcaption{\textbf{Figure~\mdcaptionlabel{5}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={603} +\subsection{\mdline{603}4.5.\hspace*{0.5em}\mdline{603}Embedded Controller\mdline{603} \mdline{603}+ Two High-Availability Remote Controllers}\label{sec-embedded-controller-two-high-availability-remote-controllers}%mdk%mdk + +%mdk-data-line={605} +\noindent\mdline{605}Figure\mdline{605}~\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}}\mdline{605} illustrates a single +embedded controller plus two remote controllers in an active-standby HA +(High-Availability) configuration. Controller \mdline{607}\#\mdline{607}1 is the active controller and is +in charge of some entities. If it fails, Controller \mdline{608}\#\mdline{608}2 takes over and manages +the tables formerly owned by Controller \mdline{609}\#\mdline{609}1. The mechanics of HA architectures +are beyond the scope of this document, but the P4Runtime multi-master +arbitration scheme supports it.%mdk + +%mdk-data-line={613} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={614} +\noindent\mdline{614}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-ha-controllers}{}\mdline{614}%mdk + +%mdk-data-line={615} +\mdhr{}%mdk + +%mdk-data-line={616} +\noindent\mdline{616}\mdcaption{\textbf{Figure~\mdcaptionlabel{6}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-ha-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={621} +\section{\mdline{621}5.\hspace*{0.5em}\mdline{621}Master-Slave Arbitration and Controller Replication}\label{sec-master-slave-arbitration-and-controller-replication}%mdk%mdk + +%mdk-data-line={624} +\noindent\mdline{624}The P4Runtime interface allows multiple controllers to be connected to the +P4Runtime server running on the device at the same time for the following +reasons:%mdk + +%mdk-data-line={628} +\begin{enumerate}%mdk + +%mdk-data-line={628} +\item{} +%mdk-data-line={628} +\mdline{628}Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, \mdline{629}\textquotedblleft{}roles\textquotedblright{}\mdline{629} (or \mdline{629}\textquotedblleft{}realms\textquotedblright{}\mdline{629}) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +master and the rest are slaves. Role definition, \mdline{632}i.e.\mdline{632} how P4 entities get +assigned to each role, is \mdline{633}\textbf{out-of-scope}\mdline{633} of this document.%mdk%mdk + +%mdk-data-line={635} +\item{} +%mdk-data-line={635} +\mdline{635}Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby slave controllers. These can already have a connection +open, which can help them become master more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={641} +\noindent\mdline{641}To support multiple controllers, P4Runtime uses the streaming channel (available +via \mdline{642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{642} RPC) for session management. The workflow is described as +follows:%mdk + +%mdk-data-line={645} +\begin{itemize}%mdk + +%mdk-data-line={645} +\item{} +%mdk-data-line={645} +\mdline{645}Each controller instance (\mdline{645}e.g.\mdline{645} a controller process) can participate in one or +more roles. For each (\mdline{646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{646}, \mdline{646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{646}), the controller receives an +\mdline{647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{647}. This \mdline{647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{647} can be the same for different roles and/or +devices, as long as the tuple (\mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{648}, \mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{648}, \mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{648}) is +unique. For each (\mdline{649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{649}, \mdline{649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{649}) that the controller wishes to +control, it establishes a \mdline{650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{650} with the P4Runtime server +responsible for that device, and sends a \mdline{651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{651} message +containing that tuple of (\mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{652}, \mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{652}, \mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{652}) values. The +P4Runtime server selects a master independently for each (\mdline{653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{653}, +\mdline{654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{654}) pair. The master is the client that has the highest \mdline{654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{654} +that the device has ever received for the same (\mdline{655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{655}, +\mdline{656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{656}) values. A connection between a controller instance and a device id +\mdline{657}\textemdash{}\mdline{657} which involves a persistent \mdline{657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{657} \mdline{657}\textemdash{}\mdline{657} can be referred to as a +P4Runtime client.%mdk + +%mdk-data-line={660} +\mdline{660}Note that the P4Runtime server does not assign a \mdline{660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{660} or \mdline{660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{660} to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the \mdline{662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{662} values used for each +\mdline{663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{663}. The P4Runtime server only keeps track of the (\mdline{663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{663}, +\mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{664}, \mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{664}) of each \mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{664} that has sent a successful +\mdline{665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{665} message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +\mdline{667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{667} message to identify which client is making the \mdline{667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{667}, +not only the \mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{668}. This enables controllers to re-use the same +numeric \mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{669} values across different (\mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{669}, \mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{669}) +pairs. P4Runtime does not require \mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{670} values be reused across such +different (\mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{671}, \mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{671}) pairs; it allows it.%mdk%mdk + +%mdk-data-line={673} +\item{} +%mdk-data-line={673} +\mdline{673}To start a controller session, a controller first opens a bidirectional stream +channel to the server via the \mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{674} RPC for each device. This stream +will be used for two purposes:%mdk + +%mdk-data-line={677} +\begin{itemize}%mdk + +%mdk-data-line={677} +\item{} +%mdk-data-line={677} +\mdline{677}\textbf{Session management:}\mdline{677} As soon as the controller opens the stream +channel, it sends a \mdline{678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{678} message to the switch. The +controller populates the \mdline{679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{679} field in this message +using its \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{680} and \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{680}, as well as the \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{680} of the +device. Note that the \mdline{681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{681} field in the \mdline{681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{681} is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below.%mdk%mdk + +%mdk-data-line={685} +\item{} +%mdk-data-line={685} +\mdline{685}\textbf{Streaming of notifications (e.g. digests) and packet I/O:}\mdline{685} The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the master controller can participate in packet +I/O. This feature is explained in more details in the\mdline{689}~\mdref{sec-packet-i_o}{Packet +I/O}\mdline{690} section.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={692} +\mdline{692}Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state.%mdk%mdk + +%mdk-data-line={695} +\item{} +%mdk-data-line={695} +\mdline{695}Note that the stream is opened per device. In case a switching platform has +multiple devices (\mdline{696}e.g.\mdline{696} multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different masters for different +devices. In this case, it is the responsibility of the P4Runtime server to +keep track of the master for each device (and role). More specifically, the +P4Runtime server will know which stream corresponds to the master controller +for each pair of (\mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{701}, \mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{701}) at any point of time.%mdk%mdk + +%mdk-data-line={703} +\item{} +%mdk-data-line={703} +\mdline{703}The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered \mdline{704}\textquotedblleft{}offline\textquotedblright{}\mdline{704} or +\mdline{705}\textquotedblleft{}dead\textquotedblright{}\mdline{705} as soon as its stream channel to the switch is broken. When a master +channel gets broken: (i) an advisory message is sent to all other controllers +for that \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{707} and \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{707}, as described in the +\mdline{708}\mdref{sec-mastership-notification}{following section}\mdline{708} (ii) the P4Runtime server +will be without a master, until a client sends a successful +\mdline{710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{710} (as per the rules in a +\mdline{711}\mdref{sec-mastership-updates}{later section}\mdline{711}).%mdk%mdk + +%mdk-data-line={713} +\item{} +%mdk-data-line={713} +\mdline{713}The mechanism via which the controller receives the P4Runtime server details +which includes the \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{714}, \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip}}}\mdline{714} and \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{714}, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +\mdline{718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{718}) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={723} +\noindent\mdline{723}gRPC enables the server to identify which client originated each message in the +\mdline{724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{724} stream. For example, the C++ gRPC library\mdline{724}~[\mdcite{grpcstreamc}{10}]\mdline{724} in +synchronous mode enables a server process to cause a function to be called when +a new client creates a \mdline{726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{726} stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +\mdline{728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{728} is closed normally (or broken, \mdline{728}e.g.\mdline{728} because a client process +unexpectedly terminated). Thus the server can easily associate all +\mdline{730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{730} messages received from the same client, because they are +processed within the context of the same function call.%mdk + +%mdk-data-line={733} +\mdline{733}A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{738}, \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{738}, and \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{738} in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods\mdline{740}~[\mdcite{grpcauth}{8}]\mdline{740} that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server.%mdk + +%mdk-data-line={744} +\subsection{\mdline{744}5.1.\hspace*{0.5em}\mdline{744}Default Role}\label{sec-default-role}%mdk%mdk + +%mdk-data-line={746} +\noindent\mdline{746}A controller can omit the role message in \mdline{746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{746}. This +implies the \mdline{747}\textquotedblleft{}default role\textquotedblright{}\mdline{747}, which corresponds to \mdline{747}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{747}. This +also implies that a default role has a \mdline{748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{748} of 0 (default). If using a +default role, all RPCs from the controller (\mdline{749}e.g.\mdline{749} \mdline{749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{749}) must set the \mdline{749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{749} +to 0.%mdk + +%mdk-data-line={752} +\subsection{\mdline{752}5.2.\hspace*{0.5em}\mdline{752}Role Config}\label{sec-arbitration-role-config}%mdk%mdk + +%mdk-data-line={754} +\noindent\mdline{754}The \mdline{754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{754} field in the \mdline{754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{754} message sent by the +controller describes the role configuration, \mdline{755}i.e.\mdline{755} which operations are in the +scope of a given role. In particular, the definition of a role may include the +following:%mdk + +%mdk-data-line={759} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={759} +\item\mdline{759}A list of P4 entities for which the controller may issue \mdline{759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{759} updates and +receive notification messages (\mdline{760}e.g.\mdline{760} \mdline{760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{760} and +\mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{761}).%mdk + +%mdk-data-line={762} +\item\mdline{762}Whether the controller is able to receive \mdline{762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{762} messages, along with a +filtering mechanism based on the values of the \mdline{763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{763} fields to +select which \mdline{764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{764} messages should be sent to the controller.%mdk + +%mdk-data-line={765} +\item\mdline{765}Whether the controller is able to send \mdline{765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{765} messages, along with a +filtering mechanism based on the values of the \mdline{766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{766} fields to +select which \mdline{767}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{767} messages are allowed to be sent by the controller.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={769} +\noindent\mdline{769}An unset \mdline{769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{769} implies \mdline{769}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{769} (similar to the default +role explained above). In order to support different role definition schemes, +\mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{771} is defined as an \mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{771} Protobuf message\mdline{771}~[\mdcite{protoany}{31}]\mdline{771}. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion.%mdk + +%mdk-data-line={776} +\mdline{776}It is the job of the P4Runtime server to remember the \mdline{776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{776} for every +\mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{777} and \mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{777} pair.%mdk + +%mdk-data-line={779} +\subsection{\mdline{779}5.3.\hspace*{0.5em}\mdline{779}Rules for Handling \mdline{779}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{779} Messages Received from Controllers}\label{sec-mastership-updates}%mdk%mdk + +%mdk-data-line={781} +\begin{enumerate}%mdk + +%mdk-data-line={781} +\item{} +%mdk-data-line={781} +\mdline{781}If the \mdline{781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{781} message is received for the first time on +this particular channel (\mdline{782}i.e.\mdline{782} for a newly connected controller):%mdk + +%mdk-data-line={784} +\begin{enumerate}%mdk + +%mdk-data-line={784} +\item{} +%mdk-data-line={784} +\mdline{784}If \mdline{784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{784} does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +\mdline{786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{786} error.%mdk%mdk + +%mdk-data-line={788} +\item{} +%mdk-data-line={788} +\mdline{788}If the \mdline{788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{788} is set and is already used by another controller for +the same (\mdline{789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{789}, \mdline{789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{789}), the P4Runtime server shall terminate +the stream by returning an \mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{790} error.%mdk%mdk + +%mdk-data-line={792} +\item{} +%mdk-data-line={792} +\mdline{792}If \mdline{792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{792} does not match the \mdline{792}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{792} scheme previously +agreed upon, the server must return an \mdline{793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{793} error.%mdk%mdk + +%mdk-data-line={795} +\item{} +%mdk-data-line={795} +\mdline{795}If the number of open streams for the given (\mdline{795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{795}, \mdline{795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{795}) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a \mdline{797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{797} error.%mdk%mdk + +%mdk-data-line={799} +\item{} +%mdk-data-line={799} +\mdline{799}Otherwise, the controller is added to a list of connected controllers for +the given (\mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{800}, \mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{800}) and the server remembers the +controllers \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{801}, \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{801} and \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{801} for this gRPC +channel. See below for the rules to determine if this controller becomes +a master or slave, and what notifications are sent as a consequence.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={805} +\item{} +%mdk-data-line={805} +\mdline{805}Otherwise, if the \mdline{805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{805} message is received from an +already connected controller:%mdk + +%mdk-data-line={808} +\begin{enumerate}%mdk + +%mdk-data-line={808} +\item{} +%mdk-data-line={808} +\mdline{808}If the \mdline{808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{808} does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{810} error.%mdk%mdk + +%mdk-data-line={812} +\item{} +%mdk-data-line={812} +\mdline{812}If the \mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{812} does not match the current \mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{812} assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{814} error. If the controller wishes to change its role, +it must close the current stream channel and open a new one.%mdk%mdk + +%mdk-data-line={817} +\item{} +%mdk-data-line={817} +\mdline{817}If \mdline{817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{817} does not match the \mdline{817}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{817} scheme previously +agreed upon, the server must return an \mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{818} error.%mdk%mdk + +%mdk-data-line={820} +\item{} +%mdk-data-line={820} +\mdline{820}If the \mdline{820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{820} is set and is already used by another controller +(excluding the controller making the request) for the same +(\mdline{822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{822}, \mdline{822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{822}), the P4Runtime server shall terminate the stream +by returning an \mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{823} error.%mdk%mdk + +%mdk-data-line={825} +\item{} +%mdk-data-line={825} +\mdline{825}If the \mdline{825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{825} matches the one assigned to this stream:%mdk + +%mdk-data-line={827} +\begin{enumerate}%mdk + +%mdk-data-line={827} +\item{} +%mdk-data-line={827} +\mdline{827}If the controller for this channel is the master, then the server +updates the \mdline{828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{828} to the one specified in the +\mdline{829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{829}. An advisory mastership message is sent to +all controllers for this \mdline{830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{830} and \mdline{830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{830} informing +them of the new \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{831}. Since the format of \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{831} is +out of scope for the P4Runtime specification, the server will send +the advisory message for every update, even if the master sets the +same \mdline{834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{834} as it has before. See the +\mdline{835}\mdref{sec-mastership-notification}{following section}\mdline{835} for the format of +the advisory message.%mdk%mdk + +%mdk-data-line={838} +\item{} +%mdk-data-line={838} +\mdline{838}If the controller is a slave, this is a no-op and the \mdline{838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{838} +is ignored. No response is sent to any controller.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={841} +\item{} +%mdk-data-line={841} +\mdline{841}Otherwise, the server updates the \mdline{841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{841} it has stored for this +controller. This change might cause a change in mastership (this +controller might become master, or the controller might have downgraded +itself to a slave, see below), as well as notifications being sent to one +or more controllers.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={847} +\noindent\mdline{847}If the \mdline{847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{847} is accepted by either of the two steps above +(cases 1.5. and 2.6. above), then the server determines if there are changes in +mastership. Let \mdline{849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{849} be the highest election ID the server has +ever seen for the given \mdline{850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{850} and \mdline{850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{850} (including the one of the +current master if there is one).%mdk + +%mdk-data-line={853} +\begin{enumerate}%mdk + +%mdk-data-line={853} +\item{} +%mdk-data-line={853} +\mdline{853}If \mdline{853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{853} is greater than or equal to \mdline{853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{853}, then the +controller becomes master. The server updates the role configuration to +\mdline{855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{855} for the given \mdline{855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{855}. Furthermore:%mdk + +%mdk-data-line={857} +\begin{enumerate}%mdk + +%mdk-data-line={857} +\item{} +%mdk-data-line={857} +\mdline{857}If there was no master for this \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{857} and \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{857} before and +there are no \mdline{858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{858} requests still processing from a previous master, +then the server immediately sends an advisory notification to all +controllers for this \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{860} and \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{860}. See the +\mdline{861}\mdref{sec-mastership-notification}{following section}\mdline{861} for the format of the +advisory message.%mdk%mdk + +%mdk-data-line={864} +\item{} +%mdk-data-line={864} +\mdline{864}If there was a previous master or \mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{864} requests in flight, then the +server carries out the following steps (in this order):%mdk + +%mdk-data-line={867} +\begin{enumerate}%mdk + +%mdk-data-line={867} +\item{} +%mdk-data-line={867} +\mdline{867}The server stops accepting \mdline{867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{867} requests from the previous master +(if there is one). At this point, the server will reject all \mdline{868}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{868} +requests with \mdline{869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{869}.%mdk%mdk + +%mdk-data-line={871} +\item{} +%mdk-data-line={871} +\mdline{871}The server notifies all controllers other than the new master of the +mastership change by sending the advisory notification described in +the\mdline{873}~\mdref{sec-mastership-notification}{following section}\mdline{873}.%mdk%mdk + +%mdk-data-line={875} +\item{} +%mdk-data-line={875} +\mdline{875}The server will finish processing any \mdline{875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{875} requests that have +already started. If there are errors, they are reported as usual to +the previous master. If the previous master has already disconnected, +any possible errors are dropped and not reported.%mdk%mdk + +%mdk-data-line={880} +\item{} +%mdk-data-line={880} +\mdline{880}The server now accepts the current controller as the new master, thus +accepting \mdline{881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{881} requests from this controller. The server updates +the highest election ID (\mdline{882}i.e.\mdline{882} \mdline{882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{882}) it has seen for +this \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{883} and \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{883} to \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{883}.%mdk%mdk + +%mdk-data-line={885} +\item{} +%mdk-data-line={885} +\mdline{885}The server notifies the new master by sending the advisory message +described in the\mdline{886}~\mdref{sec-mastership-notification}{following section}\mdline{886}.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={888} +\item{} +%mdk-data-line={888} +\mdline{888}Otherwise, the controller becomes a slave. If the controller was previously a +master (and downgraded itself), then an advisory message is sent to all +controllers for this \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{890} and \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{890}. Otherwise, the advisory +message is only sent to the controller that sent the initial +\mdline{892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{892}. See the +\mdline{893}\mdref{sec-mastership-notification}{following section}\mdline{893} for the format of the +advisory message.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={896} +\subsection{\mdline{896}5.4.\hspace*{0.5em}\mdline{896}Mastership Notifications}\label{sec-mastership-notification}%mdk%mdk + +%mdk-data-line={898} +\noindent\mdline{898}For any given \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{898} and \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{898}, any time a new master is chosen, a +master downgrades its status to a slave, a master disconnects, or the +\mdline{900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{900} is updated by the master, all controllers for that +(\mdline{901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{901}, \mdline{901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{901}) are informed of this by sending a +\mdline{902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{902}. The \mdline{902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{902} is populated as follows:%mdk + +%mdk-data-line={904} +\begin{itemize}%mdk + +%mdk-data-line={904} +\item{} +%mdk-data-line={904} +\mdline{904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{904} and \mdline{904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{904} as given.%mdk%mdk + +%mdk-data-line={906} +\item{} +%mdk-data-line={906} +\mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{906} is set to the role configuration the server received most +recently in a \mdline{907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{907} from a master.%mdk%mdk + +%mdk-data-line={909} +\item{} +%mdk-data-line={909} +\mdline{909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{909} is populated as follows:%mdk + +%mdk-data-line={911} +\begin{itemize}%mdk + +%mdk-data-line={911} +\item{} +%mdk-data-line={911} +\mdline{911}If there has not been any master at all, the election\mdline{911}\_\mdline{911}id is left unset.%mdk%mdk + +%mdk-data-line={913} +\item{} +%mdk-data-line={913} +\mdline{913}Otherwise, \mdline{913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{913} is set to the highest election ID that the server +has seen for this \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{914} and \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{914} (which is the \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{914} of +the current master if there is any).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={917} +\item{} +%mdk-data-line={917} +\mdline{917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{917} is set differently based on whether the notification is sent to the +master or a slave controller:%mdk + +%mdk-data-line={920} +\begin{itemize}%mdk + +%mdk-data-line={920} +\item{} +%mdk-data-line={920} +\mdline{920}If there is a master:%mdk + +%mdk-data-line={922} +\begin{itemize}%mdk + +%mdk-data-line={922} +\item{} +%mdk-data-line={922} +\mdline{922}For the master, \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{922} is OK (with \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{922} set to +\mdline{923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.OK}}}\mdline{923}).%mdk%mdk + +%mdk-data-line={925} +\item{} +%mdk-data-line={925} +\mdline{925}For all slave controllers, \mdline{925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{925} is set to non-OK (with +\mdline{926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{926} set to \mdline{926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.ALREADY\_EXISTS}}}\mdline{926}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={928} +\item{} +%mdk-data-line={928} +\mdline{928}Otherwise, if there is no master currently, for all slave controllers, +\mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{929} is set to non-OK (with \mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{929} set to +\mdline{930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.NOT\_FOUND}}}\mdline{930}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={932} +\noindent\mdline{932}Note that on mastership changes with outstanding \mdline{932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{932} request, some +notifications might be delayed, see the +\mdline{934}\mdref{sec-mastership-updates}{previous section}\mdline{934} for details.%mdk + +%mdk-data-line={936} +\section{\mdline{936}6.\hspace*{0.5em}\mdline{936}The P4Info Message}\label{sec-the-p4info-message}%mdk%mdk + +%mdk-data-line={938} +\noindent\mdline{938}The purpose of P4Info was described under +\mdline{939}\mdref{sec-reference-architecture}{Reference Architecture}\mdline{939}. +Here we describe the various +components.%mdk + +%mdk-data-line={943} +\subsection{\mdline{943}6.1.\hspace*{0.5em}\mdline{943}Common Messages}\label{sec-common-messages}%mdk%mdk + +%mdk-data-line={945} +\noindent\mdline{945}These messages appear nested within many other messages.%mdk + +%mdk-data-line={947} +\subsubsection{\mdline{947}6.1.1.\hspace*{0.5em}\mdline{947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{947} Message}\label{sec-documentation-message}%mdk%mdk + +%mdk-data-line={949} +\noindent\mdline{949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{949} is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers.%mdk + +%mdk-data-line={953} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={954} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Documentation~\{\\ +~~{\mdcolor{darkgreen}//~A~brief~description~of~something,~e.g.~one~sentence}\\ +~~{\bfseries{\mdcolor{navy}string}}~brief~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~A~more~verbose~description~of~something.}\\ +~~{\mdcolor{darkgreen}//~Multiline~is~accepted.~Markup~format~(if~any)~is~TBD.}\\ +~~{\bfseries{\mdcolor{navy}string}}~description~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={963} +\subsubsection{\mdline{963}6.1.2.\hspace*{0.5em}\mdline{963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{963} Message}\label{sec-preamble-message}%mdk%mdk + +%mdk-data-line={965} +\noindent\mdline{965}The preamble serves as the \mdline{965}\textquotedblleft{}descriptor\textquotedblright{}\mdline{965} for each entity and contains the unique +instance ID, name, alias, annotations and documentation.%mdk + +%mdk-data-line={968} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={969} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Preamble~\{\\ +~~{\mdcolor{darkgreen}//~ids~share~the~same~number-space;~e.g.~table~ids~cannot~overlap~with~counter}\\ +~~{\mdcolor{darkgreen}//~ids.~Even~though~this~is~irrelevant~to~this~proto~definition,~the~ids~are}\\ +~~{\mdcolor{darkgreen}//~allocated~in~such~a~way~that~it~is~possible~based~on~an~id~to~deduce~the}\\ +~~{\mdcolor{darkgreen}//~resource~type~(e.g.~table,~action,~counter,~...).~This~means~that~code}\\ +~~{\mdcolor{darkgreen}//~using~these~ids~can~detect~if~the~wrong~resource~type~is~used}\\ +~~{\mdcolor{darkgreen}//~somewhere.~This~also~means~that~ids~of~different~types~can~be~mixed}\\ +~~{\mdcolor{darkgreen}//~(e.g.~direct~resource~list~for~a~table)~without~ambiguity.~Note~that~id~0}\\ +~~{\mdcolor{darkgreen}//~is~reserved~and~means~"invalid~id".}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name~of~the~P4~object,~e.g.~c1.c2.ipv4\_lpm}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~an~alias~(alternative~name)~for~the~P4~object,~probably~shorter~than~its}\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name.~The~only~constraint~is~for~it~to~be~unique~with}\\ +~~{\mdcolor{darkgreen}//~respect~to~other~P4~objects~of~the~same~type.~By~default,~the~compiler~uses}\\ +~~{\mdcolor{darkgreen}//~the~shortest~suffix~of~the~name~that~uniquely~identifies~the~object.~For}\\ +~~{\mdcolor{darkgreen}//~example~if~the~P4~program~contains~two~tables~with~names~s.c1.t~and~s.c2.t,}\\ +~~{\mdcolor{darkgreen}//~the~default~aliases~will~respectively~be~c1.t~and~c2.t.~In~the~future,~the}\\ +~~{\mdcolor{darkgreen}//~P4~programmer~may~also~be~able~to~override~the~default~alias~for~any~P4}\\ +~~{\mdcolor{darkgreen}//~object~(TBD).}\\ +~~{\bfseries{\mdcolor{navy}string}}~alias~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~The~location~of~`annotations{}[i]`~is~given~by~`annotation\_locations{}[i]`.}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~SourceLocation~annotation\_locations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~Documentation~of~the~entity}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={999} +\subsubsection{\mdline{999}6.1.3.\hspace*{0.5em}\mdline{999}Annotating P4 Entities with \mdline{999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}\label{sec-annotating-p4-entities-with-documentation}%mdk%mdk + +%mdk-data-line={1001} +\noindent\mdline{1001}P4 entities may be annotated using the following annotations:%mdk + +%mdk-data-line={1003} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1004} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}(string...)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}(string...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1008} +\noindent\mdline{1008}Attaching either or both of these annotations to an entity will generate a +P4Info\mdline{1009}~\mdref{sec-documentation-message}{Documentation Message}\mdline{1009}, which in turn will +appear in the\mdline{1010}~\mdref{sec-preamble-message}{Preamble Message}\mdline{1010} for the entity.%mdk + +%mdk-data-line={1012} +\mdline{1012}The P4 compiler should not emit \mdline{1012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation}}}\mdline{1012} messages in the P4Info for these +specific cases; instead, it should generate the \mdline{1013}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1013} messages as +described.%mdk + +%mdk-data-line={1016} +\mdline{1016}The following example shows documentation annotations for a \mdline{1016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table}}}\mdline{1016} entity:%mdk + +%mdk-data-line={1018} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1019} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port.~\textbackslash{}}\\ +Uses~LPM~match~{\bfseries{\mdcolor{navy}type}}.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}table~my\_ipv4\_lkup~\{}\\ +{\mdcolor{maroon}~~...}\\ +{\mdcolor{maroon}\}}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1027} +\subsubsection{\mdline{1027}6.1.4.\hspace*{0.5em}\mdline{1027}Structured Annotations}\label{sec-structured-annotations}%mdk%mdk + +%mdk-data-line={1029} +\noindent\mdline{1029}P4 supports both unstructured and structured annotations\mdline{1029}~[\mdcite{p4annotations}{13}]\mdline{1029}. +Unstructured annotations of the form \mdline{1030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno1}}}\mdline{1030} or \mdline{1030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno2(body-content)}}}\mdline{1030} can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +\mdline{1033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno3{}[]}}}\mdline{1033} or \mdline{1033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno4{}[kvList\textbar{}expressionList]}}}\mdline{1033} have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this.%mdk + +%mdk-data-line={1038} +\mdline{1038}The annotations described up to this point, \mdline{1038}e.g.\mdline{1038} \mdline{1038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief()}}}\mdline{1038}, have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as \mdline{1040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1040} fields in the various \mdline{1040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{1040}s. +Similarly, structured annotations are represented in \mdline{1041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated\\ +StructuredAnnotation~structured\_annotations}}}\mdline{1042} fields which are siblings to the +unstructured \mdline{1043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1043}. The \mdline{1043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations}}}\mdline{1043} contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations.%mdk + +%mdk-data-line={1048} +\mdline{1048}The structured annotation messages are defined in p4types.proto.%mdk + +%mdk-data-line={1050} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1051} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~KeyValuePair~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~key~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Expression~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~KeyValuePairList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~KeyValuePair~kv\_pairs~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Expression~\{\\ +~~{\bfseries{\mdcolor{navy}oneof}}~value~\{\\ +~~~~{\bfseries{\mdcolor{navy}string}}~string\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~{\bfseries{\mdcolor{navy}int64}}~int64\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~{\bfseries{\mdcolor{navy}bool}}~bool\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~ExpressionList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Expression~expressions~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~StructuredAnnotation~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}oneof}}~body~\{\\ +~~~~ExpressionList~expression\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~KeyValuePairList~kv\_pair\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~Location~of~the~'@'~symbol~of~this~annotation~in~the~source~code.}\\ +~~SourceLocation~source\_location~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1083} +\noindent\mdline{1083}The \mdline{1083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1083} message can represent either a \mdline{1083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1083} +or an \mdline{1084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExpressionList}}}\mdline{1084}.%mdk + +%mdk-data-line={1086} +\mdline{1086}The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The \mdline{1087}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{1087} +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don\mdline{1089}'\mdline{1089}t match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler \mdline{1091}\emph{may}\mdline{1091} print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions.%mdk + +%mdk-data-line={1095} +\mdline{1095}The following invariants hold:%mdk + +%mdk-data-line={1097} +\begin{enumerate}%mdk + +%mdk-data-line={1097} +\item{} +%mdk-data-line={1097} +\mdline{1097}For any P4 entity, there are no two \mdline{1097}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1097}s that have the +same name.%mdk%mdk + +%mdk-data-line={1100} +\item{} +%mdk-data-line={1100} +\mdline{1100}Within a \mdline{1100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1100}, there are no two \mdline{1100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePair}}}\mdline{1100}s that have the +same \mdline{1101}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key.}}}\mdline{1101}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1103} +\paragraph{\mdline{1103}6.1.4.1.\hspace*{0.5em}\mdline{1103}Structured Annotation Examples}\label{sec-structured-annotation-examples}%mdk%mdk + +%mdk-data-line={1105} +\noindent\mdline{1105}We omit the \mdline{1105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}source\_location}}}\mdline{1105} field in the following examples.%mdk + +%mdk-data-line={1107} +\mdline{1107}\textbf{Empty Expression List}\mdline{1107}%mdk + +%mdk-data-line={1109} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1110} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}Empty}{\mdcolor{maroon}{}[]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1116} +\noindent\mdline{1116}The generated P4Info will contain the following.%mdk + +%mdk-data-line={1118} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1119} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}Empty}{\mdcolor{maroon}"}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1124} +\noindent\mdline{1124}\textbf{Mixed Expression List}\mdline{1124}%mdk + +%mdk-data-line={1126} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1127} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~TEXT\_CONST~"hello"}\\ +{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~NUM\_CONST~6}\\ +{\mdcolor{gray}@}{\mdcolor{gray}MixedExprList}{\mdcolor{maroon}{}[1,TEXT\_CONST,true,1==2,5+NUM\_CONST]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1135} +\noindent\mdline{1135}The generated P4Info will contain:%mdk + +%mdk-data-line={1137} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1138} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedExprList}{\mdcolor{maroon}"}\\ +~~expression\_list~\{\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}1}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}hello}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~true\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~false\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}11}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1160} +\noindent\mdline{1160}\textbf{kvList of Mixed Expressions}\mdline{1160}%mdk + +%mdk-data-line={1162} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1163} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}MixedKV}{\mdcolor{maroon}{}[label="text",~my\_bool=true,~int\_val=2*3]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1169} +\noindent\mdline{1169}The generated P4Info will contain:%mdk + +%mdk-data-line={1171} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1172} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedKV}{\mdcolor{maroon}"}\\ +~~kv\_pair\_list~\{\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}label}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}text}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}my\_bool}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~bool\_value:~true\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}int\_val}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~int64\_value:~{\mdcolor{purple}6}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1197} +\subsubsection{\mdline{1197}6.1.5.\hspace*{0.5em}\mdline{1197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1197} Message}\label{sec-sourcelocation-message}%mdk%mdk + +%mdk-data-line={1199} +\noindent\mdline{1199}A source location describes a location within a \mdline{1199}\emph{.p4}\mdline{1199}-source file. The +\mdline{1200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1200} message is defined in p4types.proto as follows:%mdk + +%mdk-data-line={1202} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1203} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Location~of~code~relative~to~a~given~source~file.}\\ +{\bfseries{\mdcolor{navy}message}}~SourceLocation~\{\\ +~~{\mdcolor{darkgreen}//~Path~to~the~source~file~(absolute~or~relative~to~the~working~directory).}\\ +~~{\bfseries{\mdcolor{navy}string}}~file~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Line~and~column~numbers~within~the~source~file,~1-based.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~line~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}int32}}~column~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1213} +\noindent\mdline{1213}We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations.%mdk + +%mdk-data-line={1218} +\mdline{1218}The \mdline{1218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1218} message associated with an annotation holds the location of +the \mdline{1219}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@}}}\mdline{1219} symbol introducing the annotation in the P4 source code; the message can +be found in the following place:%mdk + +%mdk-data-line={1222} +\begin{itemize}%mdk + +%mdk-data-line={1222} +\item{} +%mdk-data-line={1222} +\mdline{1222}For \mdline{1222}\textbf{unstructured annotations}\mdline{1222}, every message containing a field +\mdline{1223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1223} also contains a field +\mdline{1224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~SourceLocation~annotation\_locations}}}\mdline{1224}. The i-th member of +\mdline{1225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation\_locations}}}\mdline{1225} is the source location of the i-th member of +\mdline{1226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1226}.%mdk%mdk + +%mdk-data-line={1228} +\item{} +%mdk-data-line={1228} +\mdline{1228}For \mdline{1228}\textbf{structured annotations}\mdline{1228}, every \mdline{1228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1228} message contains +a field \mdline{1229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation~source\_location}}}\mdline{1229} holding its source location.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1232} +\subsection{\mdline{1232}6.2.\hspace*{0.5em}\mdline{1232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1232} Message}\label{sec-pkginfo-message}%mdk%mdk + +%mdk-data-line={1234} +\noindent\mdline{1234}The \mdline{1234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1234} message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. \mdline{1235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1235} can be extracted +and used to facilitate \mdline{1236}\textquotedblleft{}browsing\textquotedblright{}\mdline{1236} of available P4 programs from a +library. Although all fields are technically \mdline{1237}\textquotedblleft{}optional,\textquotedblright{}\mdline{1237} every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included.%mdk + +%mdk-data-line={1241} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1242} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Can~be~used~to~manage~multiple~P4~packages.}\\ +{\bfseries{\mdcolor{navy}message}}~PkgInfo~\{\\ +~~{\mdcolor{darkgreen}//~a~definitive~name~for~this~configuration,~e.g.~switch.p4\_v1.0}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~configuration~version,~free-format~string}\\ +~~{\bfseries{\mdcolor{navy}string}}~version~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~brief~and~detailed~descriptions}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~free-form;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~the~target~architecture,~e.g.~"psa"}\\ +~~{\bfseries{\mdcolor{navy}string}}~arch~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\mdcolor{darkgreen}//~organization~which~produced~the~configuration,~e.g.~"p4.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~organization~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~{\mdcolor{darkgreen}//~contact~info~for~support,e.g.~"tech-support@acme.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~contact~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~url~for~more~information,~e.g.~"http://support.p4.org/ref/p4/switch.p4\_v1.0"}\\ +~~{\bfseries{\mdcolor{navy}string}}~url~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}8};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~structured;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}9};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1265} +\subsubsection{\mdline{1265}6.2.1.\hspace*{0.5em}\mdline{1265}Annotating P4 code with PkgInfo}\label{sec-annotating-p4-code-with-pkginfo}%mdk%mdk + +%mdk-data-line={1267} +\noindent\mdline{1267}A P4 progam\mdline{1267}'\mdline{1267}s \mdline{1267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1267} may be declared using one or more of the following +annotations, attached to the \mdline{1268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1268} block only:%mdk + +%mdk-data-line={1270} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1271} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value{}[,key=value,...])}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("A~brief~description")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("A~longer\textbackslash{}}\\ +description{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@custom\_annotation(...)}\\ +{\mdcolor{maroon}@another\_custom\_annotation(...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1280} +\noindent\mdline{1280}Above we see several different types of annotations:%mdk + +%mdk-data-line={1282} +\begin{itemize}%mdk + +%mdk-data-line={1282} +\item{} +%mdk-data-line={1282} +\mdline{1282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1282} \mdline{1282}- This is used to populate a specific field within the \mdline{1282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1282} +message. Multiple \mdline{1283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1283} annotations are allowed. For compactness, +multiple key-value pairs can appear in a single \mdline{1284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1284} annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The \mdline{1286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{1286}s must be from +among the message fields inside \mdline{1287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1287}, for example, \mdline{1287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1287}, \mdline{1287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}version}}}\mdline{1287}, +etc. Each key-value pair assigns a value to the corresponding field inside the +single \mdline{1289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1289} message for the program\mdline{1289}'\mdline{1289}s P4Info. One exception is that the +\mdline{1290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1290} field of \mdline{1290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1290} must be expressed as individual +\mdline{1291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1291} and \mdline{1291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1291} annotations, see next bullets. The key \mdline{1291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}arch}}}\mdline{1291} will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself.%mdk%mdk + +%mdk-data-line={1295} +\item{} +%mdk-data-line={1295} +\mdline{1295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1295} \mdline{1295}- This will populate the \mdline{1295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.brief}}}\mdline{1295} message field.%mdk%mdk + +%mdk-data-line={1297} +\item{} +%mdk-data-line={1297} +\mdline{1297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1297} \mdline{1297}- This will populate the \mdline{1297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.description}}}\mdline{1297} message +field%mdk%mdk + +%mdk-data-line={1300} +\item{} +%mdk-data-line={1300} +\mdline{1300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@\textless{}anything~else\textgreater{}}}}\mdline{1300} \mdline{1300}- This will create a \mdline{1300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotation}}}\mdline{1300} entry%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1302} +\noindent\mdline{1302}Declaring one or more of these annotations on \mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1302} will +generate a single corresponding \mdline{1303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1303} message in the P4Info as described in +\mdline{1304}\mdref{sec-pkginfo-message}{PkgInfo Message}\mdline{1304}.%mdk + +%mdk-data-line={1306} +\mdline{1306}The following example shows \mdline{1306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1306} annotations using a mixture of single and +multiple key-value pairs. It also shows \mdline{1307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1307} and \mdline{1307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1307} annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the \mdline{1309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1309} message. The custom annotations will +be appended to the \mdline{1310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotations}}}\mdline{1310} list.%mdk + +%mdk-data-line={1312} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1313} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(name="switch.p4",version="2")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(organization="p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(contact="info@p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(url="www.p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("L2/L3~switch")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("L2/L3~switch.\textbackslash{}}\\ +Built~for~data-center~profile.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@my\_annotation1(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}@my\_annotation2(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}PSA\_Switch(IgPipeline,~PacketReplicationEngine(),~EgPipeline,}\\ +{\mdcolor{maroon}~~~~~~~~~~~BufferingQueueingEngine())~main;}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1326} +\subsection{\mdline{1326}6.3.\hspace*{0.5em}\mdline{1326}ID Allocation for P4Info Objects}\label{sec-id-allocation}%mdk%mdk + +%mdk-data-line={1328} +\noindent\mdline{1328}P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(\mdline{1332}e.g.\mdline{1332} table, action, counter, \mdline{1332}\dots{}\mdline{1332}). The most significant 8 bits of the ID +encodes the object type (as per Table\mdline{1333}~\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}}\mdline{1333}). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (\mdline{1335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.P4Ids.Prefix}}}\mdline{1335}). These values must +be used (\mdline{1336}e.g.\mdline{1336} by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table\mdline{1338}~\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}}\mdline{1338} shows the ID +layout.%mdk + +%mdk-data-line={1341} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1343} 8-bit prefix value}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1343} P4 object type}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{1345} 0x00}&\multicolumn{1}{|l|}{\mdline{1345} Reserved (unspecified)}\\ +\multicolumn{1}{|l}{\mdline{1346} 0x01}&\multicolumn{1}{|l|}{\mdline{1346} Action}\\ +\multicolumn{1}{|l}{\mdline{1347} 0x02}&\multicolumn{1}{|l|}{\mdline{1347} Table}\\ +\multicolumn{1}{|l}{\mdline{1348} 0x03}&\multicolumn{1}{|l|}{\mdline{1348} Value-set}\\ +\multicolumn{1}{|l}{\mdline{1349} 0x04}&\multicolumn{1}{|l|}{\mdline{1349} Controller header (header type with \mdline{1349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1349} annotation)}\\ +\multicolumn{1}{|l}{\mdline{1350} 0x05\mdline{1350}\dots{}\mdline{1350}0x0f}&\multicolumn{1}{|l|}{\mdline{1350} Reserved (for future P4 built-in objects)}\\ +\multicolumn{1}{|l}{\mdline{1351} 0x10}&\multicolumn{1}{|l|}{\mdline{1351} Reserved (start of PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1352} 0x11}&\multicolumn{1}{|l|}{\mdline{1352} PSA Action profiles / selectors}\\ +\multicolumn{1}{|l}{\mdline{1353} 0x12}&\multicolumn{1}{|l|}{\mdline{1353} PSA Counter}\\ +\multicolumn{1}{|l}{\mdline{1354} 0x13}&\multicolumn{1}{|l|}{\mdline{1354} PSA Direct counter}\\ +\multicolumn{1}{|l}{\mdline{1355} 0x14}&\multicolumn{1}{|l|}{\mdline{1355} PSA Meter}\\ +\multicolumn{1}{|l}{\mdline{1356} 0x15}&\multicolumn{1}{|l|}{\mdline{1356} PSA Direct meter}\\ +\multicolumn{1}{|l}{\mdline{1357} 0x16}&\multicolumn{1}{|l|}{\mdline{1357} PSA Register}\\ +\multicolumn{1}{|l}{\mdline{1358} 0x17}&\multicolumn{1}{|l|}{\mdline{1358} PSA Digest}\\ +\multicolumn{1}{|l}{\mdline{1359} 0x18\mdline{1359}\dots{}\mdline{1359}0x7f}&\multicolumn{1}{|l|}{\mdline{1359} Reserved (for future PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1360} 0x80}&\multicolumn{1}{|l|}{\mdline{1360} Reserved (start of vendor-specific extern types)}\\ +\multicolumn{1}{|l}{\mdline{1361} 0x81\mdline{1361}\dots{}\mdline{1361}0xfe}&\multicolumn{1}{|l|}{\mdline{1361} Vendor-specific extern types}\\ +\multicolumn{1}{|l}{\mdline{1362} 0xff}&\multicolumn{1}{|l|}{\mdline{1362} Reserved (max prefix value)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1364} +\mdhr{}%mdk + +%mdk-data-line={1365} +\noindent\mdline{1365}\mdcaption{\textbf{Table~\mdcaptionlabel{1}.}~\mdcaptiontext{Mapping of P4Info object type to 8-bit ID prefix value}}%mdk +%mdk +\end{mdcenter}\label{tab-mapping-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1368} +\begin{table}[h!]%mdk +\begin{mdblock}{text-align=center,breakable=true}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{cc}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1370} MSB bit 31 \mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}.. bit 24}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1370} bit 23 \mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}.. bit 0 LSB}}\\ + +\midrule +\multicolumn{1}{|c}{\mdline{1372} Object type prefix}&\multicolumn{1}{|c|}{\mdline{1372} Generated suffix (\mdline{1372}e.g.\mdline{1372} by the compiler)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1374} +\mdhr{}%mdk + +%mdk-data-line={1375} +\noindent\mdline{1375}\mdcaption{\textbf{Table~\mdcaptionlabel{2}.}~\mdcaptiontext{Format of P4Info object IDs}}%mdk%mdk +\end{mdblock}\label{tab-format-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1379} +\mdline{1379}It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with \mdline{1380}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1380} (see Table +\mdline{1381}\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}}\mdline{1381}). The compiler must honor the \mdline{1381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1381} annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (\mdline{1383}i.e.\mdline{1383} if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same \mdline{1385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1385} value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct.%mdk + +%mdk-data-line={1394} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth-7cm)/1}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{\mdinline{width=7cm}{{\bfseries\mdline{1396} P4 declaration(s)}}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1396} Compiler-allocated ID(s)}}\\ + +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1398} \mdline{1398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1398}}}&\multicolumn{1}{|l|}{\mdline{1398} 0x0212ab34}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1400} \mdline{1400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1400}}}&\multicolumn{1}{|l|}{\mdline{1400} \mdline{1400}\textbf{Error}\mdline{1400}(same ID suffixes for 2 objects of the same type)}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1401} \mdline{1401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tB...}}}\mdline{1401}}}&\multicolumn{1}{|l|}{\mdline{1401}}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1403} \mdline{1403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1403}}}&\multicolumn{1}{|l|}{\mdline{1403} 0x0212ab34}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1404} \mdline{1404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~action~act1...}}}\mdline{1404}}}&\multicolumn{1}{|l|}{\mdline{1404} 0x0112ab34}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1406} +\mdhr{}%mdk + +%mdk-data-line={1407} +\noindent\mdline{1407}\mdcaption{\textbf{Table~\mdcaptionlabel{3}.}~\mdcaptiontext{Example of statically-assigned P4Info object IDs}}%mdk +%mdk +\end{mdcenter}\label{tab-exmpl-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1410} +\mdline{1410}The \mdline{1410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1410} annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively).%mdk + +%mdk-data-line={1416} +\subsection{\mdline{1416}6.4.\hspace*{0.5em}\mdline{1416}P4Info Objects}\label{sec-p4info-objects}%mdk%mdk + +%mdk-data-line={1418} +\subsubsection{\mdline{1418}6.4.1.\hspace*{0.5em}\mdline{1418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}\label{sec-table}%mdk%mdk + +%mdk-data-line={1420} +\noindent\mdline{1420}Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields:%mdk + +%mdk-data-line={1423} +\begin{itemize}%mdk + +%mdk-data-line={1423} +\item{} +%mdk-data-line={1423} +\mdline{1423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1423}, a \mdline{1423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1423} message with the ID, name, and alias of this table.%mdk%mdk + +%mdk-data-line={1425} +\item{} +%mdk-data-line={1425} +\mdline{1425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1425}, a repeated field of type \mdline{1425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1425} representing the data to +be used to construct the lookup key matched in this table. Each \mdline{1426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1426} +message is defined with the following fields:%mdk + +%mdk-data-line={1429} +\begin{itemize}%mdk + +%mdk-data-line={1429} +\item{} +%mdk-data-line={1429} +\mdline{1429}id, the \mdline{1429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1429} identifier of this \mdline{1429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1429}, unique in the scope of +this table. No rules are prescribed on the way \mdline{1430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1430} IDs should be +allocated, as long as two \mdline{1431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1431} of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the \mdline{1435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1435} annotation, or let the compiler +choose them.%mdk%mdk + +%mdk-data-line={1438} +\item{} +%mdk-data-line={1438} +\mdline{1438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1438}, the string representing the name of this \mdline{1438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1438}.%mdk%mdk + +%mdk-data-line={1440} +\item{} +%mdk-data-line={1440} +\mdline{1440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1440}, a repeated field of strings, each one representing a P4 +annotation associated to this match field.%mdk%mdk + +%mdk-data-line={1443} +\item{} +%mdk-data-line={1443} +\mdline{1443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1443}, an \mdline{1443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1443} value set to the size in bits of this match field.%mdk%mdk + +%mdk-data-line={1445} +\item{} +%mdk-data-line={1445} +\mdline{1445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1445}, a \mdline{1445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{1445} describing the match behavior for this field; it can be +either:%mdk + +%mdk-data-line={1447} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1447} +\item\mdline{1447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1447}, an enum field of type \mdline{1447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchType}}}\mdline{1447}, which includes all +possible PSA match kinds.%mdk + +%mdk-data-line={1449} +\item\mdline{1449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_match\_type}}}\mdline{1449}, a string field which can be used to encode any +architecture-specific match type.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1452} +\item{} +%mdk-data-line={1452} +\mdline{1452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1452}, a \mdline{1452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1452} message describing this match field.%mdk%mdk + +%mdk-data-line={1454} +\item{} +%mdk-data-line={1454} +\mdline{1454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1454}, which indicates whether the match field has a\mdline{1454}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1455}; this is useful for +\mdline{1456}\mdref{sec-psa-metadata-translation}{translation}\mdline{1456}.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1458} +\item{} +%mdk-data-line={1458} +\mdline{1458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_refs}}}\mdline{1458}, a repeated \mdline{1458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1458} field representing the set of possible +actions for this table. The \mdline{1459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1459} message is used to reference an action +specified in the same P4Info message and it includes the following fields:%mdk + +%mdk-data-line={1461} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1461} +\item\mdline{1461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1461}, the \mdline{1461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1461} identifier of the action.%mdk + +%mdk-data-line={1462} +\item\mdline{1462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1462}, an enum value which can take one of three values: + \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1463}, \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1463} and \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1463}. The \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1463} of the + action is determined by the use of the P4 standard annotations + \mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1465} and \mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1465}~[\mdcite{p4actionannotations}{18}]\mdline{1465}. \mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1465} + (\mdline{1466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1466} annotation) means that the action can only appear within + the table, and never as the default action. \mdline{1467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1467} + (\mdline{1468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1468} annotation) means that the action can only be used as the + default action. \mdline{1469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1469} is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action.%mdk + +%mdk-data-line={1472} +\item\mdline{1472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1472}, a repeated string field, each one representing a P4 +annotation associated to the action \mdline{1473}\emph{reference}\mdline{1473} in this table.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1475} +\item{} +%mdk-data-line={1475} +\mdline{1475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\_default\_action\_id}}}\mdline{1475}, if this table has a constant default action, this +field will carry the \mdline{1476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1476} identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action\mdline{1479}'\mdline{1479}s +arguments.%mdk%mdk + +%mdk-data-line={1482} +\item{} +%mdk-data-line={1482} +\mdline{1482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation\_id}}}\mdline{1482}, the \mdline{1482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1482} identifier of the \mdline{1482}\textquotedblleft{}implementation\textquotedblright{}\mdline{1482} of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (\mdline{1485}e.g.\mdline{1485} a PSA \mdline{1485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1485} or \mdline{1485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{1485} +instance). The table is then referred to as an indirect match table.%mdk%mdk + +%mdk-data-line={1488} +\item{} +%mdk-data-line={1488} +\mdline{1488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_resource\_ids}}}\mdline{1488}, repeated \mdline{1488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1488} identifiers for all the direct +resources attached to this table, such as \mdline{1489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1489} and \mdline{1489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1489} +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2.%mdk%mdk + +%mdk-data-line={1495} +\item{} +%mdk-data-line={1495} +\mdline{1495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1495}, an \mdline{1495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1495} describing the desired number of table entries that the +target should support for the table. See the \mdline{1496}\textquotedblleft{}Size\textquotedblright{}\mdline{1496} subsection within the +\mdline{1497}\textquotedblleft{}Table Properties\textquotedblright{}\mdline{1497} section of the P4\mdline{1497}\mdsub{16}\mdline{1497} language specification for details +\mdline{1498}[\mdcite{p4tableproperties}{30}]\mdline{1498}.%mdk%mdk + +%mdk-data-line={1500} +\item{} +%mdk-data-line={1500} +\mdline{1500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_behavior}}}\mdline{1500}, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +\mdline{1502}\mdref{sec-idle-timeout}{Idle-Timeout}\mdline{1502} section). Value can be any of the +\mdline{1503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutBehavior}}}\mdline{1503} enum:%mdk + +%mdk-data-line={1504} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1504} +\item\mdline{1504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NO\_TIMEOUT}}}\mdline{1504} (default value), which means that idle timeout is not +supported for this table.%mdk + +%mdk-data-line={1506} +\item\mdline{1506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOTIFY\_CONTROL}}}\mdline{1506}, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +\mdline{1508}\mdref{sec-table-idle-timeout-notification}{Table Idle Timeout Notifications}\mdline{1508}).%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1510} +\item{} +%mdk-data-line={1510} +\mdline{1510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{1510}, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime.%mdk%mdk + +%mdk-data-line={1513} +\item{} +%mdk-data-line={1513} +\mdline{1513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{1513}, an \mdline{1513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1513} Protobuf message\mdline{1513}~[\mdcite{protoany}{31}]\mdline{1513} to embed +architecture-specific table properties\mdline{1514}~[\mdcite{p4tableproperties}{30}]\mdline{1514} which are not part +of the core P4 language or of the PSA architecture.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1517} +\subsubsection{\mdline{1517}6.4.2.\hspace*{0.5em}\mdline{1517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}\label{sec-action}%mdk%mdk + +%mdk-data-line={1519} +\noindent\mdline{1519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1519} messages are used to specify all possible actions of all match-action +tables.%mdk + +%mdk-data-line={1522} +\mdline{1522}The \mdline{1522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1522} message defines the following fields:%mdk + +%mdk-data-line={1524} +\begin{itemize}%mdk + +%mdk-data-line={1524} +\item{} +%mdk-data-line={1524} +\mdline{1524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1524}, a \mdline{1524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1524} message with the ID, name, and alias of this action%mdk%mdk + +%mdk-data-line={1526} +\item{} +%mdk-data-line={1526} +\mdline{1526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{1526}, a repeated field of \mdline{1526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1526} messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each \mdline{1528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1528} message contains the +following fields:%mdk + +%mdk-data-line={1530} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1530} +\item\mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1530}, the \mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1530} identifier of this parameter. No rules are prescribed +on the way \mdline{1531}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1531} IDs should be allocated, as long as two \mdline{1531}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1531} of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the \mdline{1535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1535} +annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1537} +\item\mdline{1537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1537}, the string representing the name of this parameter.%mdk + +%mdk-data-line={1538} +\item\mdline{1538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1538}, a repeated field of strings, each one representing a P4 +annotation associated to this parameter.%mdk + +%mdk-data-line={1540} +\item\mdline{1540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1540}, an \mdline{1540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1540} value set to the size in bits of this parameter.%mdk + +%mdk-data-line={1541} +\item\mdline{1541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1541}, which describes this parameter using a \mdline{1541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1541} message.%mdk + +%mdk-data-line={1542} +\item\mdline{1542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1542}, which indicates whether the action parameter has a +\mdline{1543}\mdref{sec-user-defined-types}{user-defined type}\mdline{1543}; this is useful for +\mdline{1544}\mdref{sec-psa-metadata-translation}{translation}\mdline{1544}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1546} +\subsubsection{\mdline{1546}6.4.3.\hspace*{0.5em}\mdline{1546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}\label{sec-p4info-action-profile}%mdk%mdk + +%mdk-data-line={1548} +\noindent\mdline{1548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1548} messages are used to specify all available instances of Action +Profile and Action Selector PSA externs.%mdk + +%mdk-data-line={1551} +\mdline{1551}PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile \mdline{1555}\emph{member}\mdline{1555}, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime.%mdk + +%mdk-data-line={1559} +\mdline{1559}PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into \mdline{1560}\emph{groups}\mdline{1560}. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime.%mdk + +%mdk-data-line={1569} +\mdline{1569}While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same \mdline{1570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1570} message to describe both.%mdk + +%mdk-data-line={1572} +\mdline{1572}The \mdline{1572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1572} message includes the following fields:%mdk + +%mdk-data-line={1574} +\begin{itemize}%mdk + +%mdk-data-line={1574} +\item{} +%mdk-data-line={1574} +\mdline{1574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1574}, a \mdline{1574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1574} message with the ID, name, and alias of this Action +Profile or Selector.%mdk%mdk + +%mdk-data-line={1577} +\item{} +%mdk-data-line={1577} +\mdline{1577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_ids}}}\mdline{1577}, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector.%mdk%mdk + +%mdk-data-line={1580} +\item{} +%mdk-data-line={1580} +\mdline{1580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}with\_selector}}}\mdline{1580}, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern.%mdk%mdk + +%mdk-data-line={1583} +\item{} +%mdk-data-line={1583} +\mdline{1583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1583}, an \mdline{1583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1583} representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups.%mdk%mdk + +%mdk-data-line={1587} +\item{} +%mdk-data-line={1587} +\mdline{1587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1587}, an \mdline{1587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1587} representing the maximum sum of all member +weights within any given selector group, in the case of an Action Selector, or +0 for an Action Profile. PSA programs can use the \mdline{1589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{1589} annotation +to provide this value for Action Selectors. If the annotation is omitted, the +P4Info field will default to 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1593} +\subsubsection{\mdline{1593}6.4.4.\hspace*{0.5em}\mdline{1593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1593} \mdline{1593}\&\mdline{1593} \mdline{1593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}\label{sec-counter-directcounter}%mdk%mdk + +%mdk-data-line={1595} +\noindent\mdline{1595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1595} and \mdline{1595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1595} messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is:%mdk + +%mdk-data-line={1601} +\begin{itemize}%mdk + +%mdk-data-line={1601} +\item{} +%mdk-data-line={1601} +\mdline{1601}Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index.%mdk%mdk + +%mdk-data-line={1605} +\item{} +%mdk-data-line={1605} +\mdline{1605}Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1608} +\noindent\mdline{1608}Both \mdline{1608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1608} and \mdline{1608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1608} messages share the following fields:%mdk + +%mdk-data-line={1610} +\begin{itemize}%mdk + +%mdk-data-line={1610} +\item{} +%mdk-data-line={1610} +\mdline{1610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1610}, a \mdline{1610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1610} message with the ID, name, and alias of this counter +extern instance.%mdk%mdk + +%mdk-data-line={1613} +\item{} +%mdk-data-line={1613} +\mdline{1613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1613}, a message of of type \mdline{1613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1613} used to describe the compile-time +configuration of this counter. Currently, the \mdline{1614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1614} message is used to +carry only the counter unit, which can be any of the \mdline{1615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec.Unit}}}\mdline{1615} enum +values:%mdk + +%mdk-data-line={1617} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1617} +\item\mdline{1617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1617}: reserved value.%mdk + +%mdk-data-line={1618} +\item\mdline{1618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1618}: byte counter.%mdk + +%mdk-data-line={1619} +\item\mdline{1619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1619}: packet counter.%mdk + +%mdk-data-line={1620} +\item\mdline{1620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BOTH}}}\mdline{1620}: combination of both byte and packet counter.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1622} +\noindent\mdline{1622}For indexed counters, the \mdline{1622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1622} message contains also a \mdline{1622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1622} field, an +\mdline{1623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1623} representing the maximum number of independent values that can be held +by this counter array. Conversely, the \mdline{1624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1624} message contains a +\mdline{1625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1625} field that carries the \mdline{1625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}unit32}}}\mdline{1625} identifier of the table to +which this direct counter is attached.%mdk + +%mdk-data-line={1628} +\mdline{1628}For indexed counters, the \mdline{1628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1628} message contains also an \mdline{1628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1628} +field, which indicates whether the index has a\mdline{1629}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1630}. This is useful for +\mdline{1631}\mdref{sec-psa-metadata-translation}{translation}\mdline{1631}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1632}).%mdk + +%mdk-data-line={1634} +\subsubsection{\mdline{1634}6.4.5.\hspace*{0.5em}\mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1634} \mdline{1634}\&\mdline{1634} \mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}\label{sec-meter-directmeter}%mdk%mdk + +%mdk-data-line={1636} +\noindent\mdline{1636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1636} and \mdline{1636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1636} messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is:%mdk + +%mdk-data-line={1642} +\begin{itemize}%mdk + +%mdk-data-line={1642} +\item{} +%mdk-data-line={1642} +\mdline{1642}Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +\mdline{1644}e.g.\mdline{1644} to set the rate threshold.%mdk%mdk + +%mdk-data-line={1646} +\item{} +%mdk-data-line={1646} +\mdline{1646}Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1649} +\noindent\mdline{1649}Both \mdline{1649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1649} and \mdline{1649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1649} messages share the following fields:%mdk + +%mdk-data-line={1651} +\begin{itemize}%mdk + +%mdk-data-line={1651} +\item{} +%mdk-data-line={1651} +\mdline{1651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1651}, a \mdline{1651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1651} message with the ID, name, and alias of this meter +extern instance.%mdk%mdk + +%mdk-data-line={1654} +\item{} +%mdk-data-line={1654} +\mdline{1654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1654}, a message of type \mdline{1654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1654} used to describe the capabilities of +this meter extern instance. Currently, the \mdline{1655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1655} message is used to +carry only the meter unit, which can be any of the \mdline{1656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Unit}}}\mdline{1656} enum +values:%mdk + +%mdk-data-line={1658} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1658} +\item\mdline{1658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1658}: reserved value.%mdk + +%mdk-data-line={1659} +\item\mdline{1659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1659}, which signifies that this meter can be configured with rates +expressed in bytes/second.%mdk + +%mdk-data-line={1661} +\item\mdline{1661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1661}, for rates expressed in packets/second.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1663} +\noindent\mdline{1663}For indexed meters, the \mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1663} message contains also a \mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1663} field, an \mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1663} +representing the maximum number of independent cells that can be held by this +meter. Conversely, the \mdline{1665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1665} message contains a \mdline{1665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1665} field +that carries the \mdline{1666}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1666} identifier of the table to which this direct meter is +attached.%mdk + +%mdk-data-line={1669} +\mdline{1669}For indexed meters, the \mdline{1669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1669} message contains also an \mdline{1669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1669} +field, which indicates whether the index has a\mdline{1670}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1671}. This is useful for +\mdline{1672}\mdref{sec-psa-metadata-translation}{translation}\mdline{1672}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1673}).%mdk + +%mdk-data-line={1675} +\subsubsection{\mdline{1675}6.4.6.\hspace*{0.5em}\mdline{1675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\label{sec-controller-packet-meta}%mdk%mdk + +%mdk-data-line={1677} +\noindent\mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1677} messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server.%mdk + +%mdk-data-line={1683} +\mdline{1683}When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet.%mdk + +%mdk-data-line={1689} +\mdline{1689}Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +\mdline{1691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_in")}}}\mdline{1691} and \mdline{1691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_out")}}}\mdline{1691}, +respectively. \mdline{1692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1692} messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages).%mdk + +%mdk-data-line={1697} +\mdline{1697}A P4Info message can contain at most two \mdline{1697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata~messages}}}\mdline{1697}, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields:%mdk + +%mdk-data-line={1701} +\begin{itemize}%mdk + +%mdk-data-line={1701} +\item{} +%mdk-data-line={1701} +\mdline{1701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1701}, a \mdline{1701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1701} message where \mdline{1701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble.name}}}\mdline{1701} is set to \mdline{1701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_in"}}}\mdline{1701} +and \mdline{1702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_out"}}}\mdline{1702} for packet-in and packet-out metadata, respectively.%mdk%mdk + +%mdk-data-line={1704} +\item{} +%mdk-data-line={1704} +\mdline{1704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{1704}, a repeated field of type \mdline{1704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1704}, where each \mdline{1704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1704} message +includes the following fields:%mdk + +%mdk-data-line={1706} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1706} +\item\mdline{1706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1706}, a \mdline{1706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1706} identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two \mdline{1707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1707} of the +same \mdline{1708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1708} message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the \mdline{1712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1712} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1713} +\item\mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1713}, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below).%mdk + +%mdk-data-line={1717} +\item\mdline{1717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1717}, a repeated field of strings, each one representing a P4 +annotation associated to this metadata.%mdk + +%mdk-data-line={1719} +\item\mdline{1719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1719}, an \mdline{1719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1719} representing the size in bits of this metadata.%mdk + +%mdk-data-line={1720} +\item\mdline{1720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1720}, which indicates whether the metadata field has a +\mdline{1721}\mdref{sec-user-defined-types}{user-defined type}\mdline{1721}; this is useful for +\mdline{1722}\mdref{sec-psa-metadata-translation}{translation}\mdline{1722}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1724} +\noindent\mdline{1724}As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding \mdline{1725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1725} +messages.%mdk + +%mdk-data-line={1728} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1729} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~egress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~port~where~the~packet}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~should~be~sent~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~queue\_id;~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~queue~ID~}{\mdcolor{darkgreen}*/}\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~ingress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~data~plane~port~ID~where}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~the~original~packet~was~received~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}1}\textgreater{}~is\_clone;~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~1~if~this~is~a~clone~of~the}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~original~packet~}{\mdcolor{darkgreen}*/}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1744} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1745} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868916615}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_out}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_out}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}egress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}queue\_id}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~\}\\ +\}\\ +\\ +controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868941301}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_in}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_in}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ingress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}is\_clone}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}1}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1782} +\noindent\mdline{1782}Note that the use of \mdline{1782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1782} is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages.%mdk + +%mdk-data-line={1788} +\subsubsection{\mdline{1788}6.4.7.\hspace*{0.5em}\mdline{1788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}\label{sec-valueset}%mdk%mdk + +%mdk-data-line={1790} +\noindent\mdline{1790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1790} messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P4\mdline{1793}\mdsub{16}\mdline{1793} +specification\mdline{1794}~[\mdcite{p4valuesets}{39}]\mdline{1794}.%mdk + +%mdk-data-line={1796} +\mdline{1796}The \mdline{1796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1796} message defines the following fields:%mdk + +%mdk-data-line={1798} +\begin{itemize}%mdk + +%mdk-data-line={1798} +\item{} +%mdk-data-line={1798} +\mdline{1798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1798}, a \mdline{1798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1798} message with the ID, name, and alias of this Value +Set.%mdk%mdk + +%mdk-data-line={1801} +\item{} +%mdk-data-line={1801} +\mdline{1801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1801}, a repeated field of \mdline{1801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1801} messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the \mdline{1804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1804} repeated field in the +\mdline{1805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{1805} message.%mdk%mdk + +%mdk-data-line={1807} +\item{} +%mdk-data-line={1807} +\mdline{1807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1807}, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +\mdline{1809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set}}}\mdline{1809} constructor call.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1811} +\noindent\mdline{1811}According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of \mdline{1814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1814}, +\mdline{1815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1815}, or \mdline{1815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1815}~[\mdcite{p4selectexpr}{26}]\mdline{1815}. The rest of this section looks at all 3 of +these cases and gives an example \mdline{1816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1816} message when appropriate.%mdk + +%mdk-data-line={1818} +\begin{enumerate}%mdk + +%mdk-data-line={1818} +\item{} +%mdk-data-line={1818} +\mdline{1818}If the type parameter is \mdline{1818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1818}, \mdline{1818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1818} will include exactly one +\mdline{1819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1819} message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used):%mdk + +%mdk-data-line={1822} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1822} +\item\mdline{1822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1822}: set to 1%mdk + +%mdk-data-line={1823} +\item\mdline{1823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1823}: set to the value of \mdline{1823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1823}%mdk + +%mdk-data-line={1824} +\item\mdline{1824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1824}: set to \mdline{1824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1824}%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1826} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1827} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}bit\textless{}8\textgreater{}~\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(hdr.f8)~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1830} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1831} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1845} +\begin{enumerate}[,start=2]%mdk + +%mdk-data-line={1845} +\item{} +%mdk-data-line={1845} +\mdline{1845}If the type parameter is a \mdline{1845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1845}, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program.%mdk%mdk + +%mdk-data-line={1850} +\item{} +%mdk-data-line={1850} +\mdline{1850}If the type parameter is a \mdline{1850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1850}, this version of P4Runtime requires that +all the fields of the struct be of type \mdline{1851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1851} (where \mdline{1851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1851} can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +\mdline{1854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1854} field will include one \mdline{1854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1854} message for each field in the +struct, with the following fields:%mdk + +%mdk-data-line={1857} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1857} +\item\mdline{1857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1857}: must be unique with respect to the other \mdline{1857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1857} entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +\mdline{1861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1861} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1862} +\item\mdline{1862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1862}: set to the name of the corresponding struct field.%mdk + +%mdk-data-line={1863} +\item\mdline{1863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1863}: set to the list of P4 annotations associated with the struct +field, except for the \mdline{1864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1864} annotation, if present (see the \mdline{1864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1864} field +below).%mdk + +%mdk-data-line={1866} +\item\mdline{1866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1866}: set to the value of \mdline{1866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1866} for the corresponding struct field.%mdk + +%mdk-data-line={1867} +\item\mdline{1867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1867}, which indicates whether the struct field has a\mdline{1867}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1868}; this is useful for +\mdline{1869}\mdref{sec-psa-metadata-translation}{translation}\mdline{1869}.%mdk + +%mdk-data-line={1870} +\item\mdline{1870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1870}: by default \mdline{1870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1870} is set to \mdline{1870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1870}; the P4 programmer can +specify a different match type by using the \mdline{1871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1871} annotation +\mdline{1872}[\mdcite{p4selectexpr}{26}]\mdline{1872}.%mdk + +%mdk-data-line={1873} +\item\mdline{1873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1873}: documentation associated with the struct field.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1875} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1876} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~bit\textless{}8\textgreater{}~f8;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(2)~@match(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(3)~@match(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1884} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1885} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1912} +\noindent\mdline{1912}In the above example, the \mdline{1912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1912} annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs.%mdk + +%mdk-data-line={1915} +\mdline{1915}Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a\mdline{1916}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1917} that resolves to a \mdline{1917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1917}, or a \mdline{1917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1917} where +one or more fields is a\mdline{1918}~\mdref{sec-user-defined-types}{user-defined type}\mdline{1918} that +resolves to a \mdline{1919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1919}. For each \mdline{1919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1919} that corresponds to a user-defined +type, the \mdline{1920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1920} field must be set to the appropriate value (\mdline{1920}i.e.\mdline{1920} the name +of the type).%mdk + +%mdk-data-line={1923} +\subsubsection{\mdline{1923}6.4.8.\hspace*{0.5em}\mdline{1923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}\label{sec-register}%mdk%mdk + +%mdk-data-line={1925} +\noindent\mdline{1925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1925} messages are used to specify all possible instances of Register PSA +externs.%mdk + +%mdk-data-line={1928} +\mdline{1928}Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime.%mdk + +%mdk-data-line={1932} +\mdline{1932}The \mdline{1932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1932} message defines the following fields:%mdk + +%mdk-data-line={1934} +\begin{itemize}%mdk + +%mdk-data-line={1934} +\item{} +%mdk-data-line={1934} +\mdline{1934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1934}, a \mdline{1934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1934} message with the ID, name, and alias of this register +instance.%mdk%mdk + +%mdk-data-line={1937} +\item{} +%mdk-data-line={1937} +\mdline{1937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1937}, which specifies the data type stored by this register, expressed +using a \mdline{1938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1938} message (see section on\mdline{1938}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary +P4 Types}\mdline{1939}).%mdk%mdk + +%mdk-data-line={1941} +\item{} +%mdk-data-line={1941} +\mdline{1941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1941}, an \mdline{1941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1941} value representing the total number of independent register +cells available.%mdk%mdk + +%mdk-data-line={1944} +\item{} +%mdk-data-line={1944} +\mdline{1944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1944}, which indicates whether the register index has a +\mdline{1945}\mdref{sec-user-defined-types}{user-defined type}\mdline{1945}. This is useful for +\mdline{1946}\mdref{sec-psa-metadata-translation}{translation}\mdline{1946}. The underlying built-in type +must be a fixed-width unsigned bitstring (\mdline{1947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1947}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1949} +\subsubsection{\mdline{1949}6.4.9.\hspace*{0.5em}\mdline{1949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}\label{sec-digest}%mdk%mdk + +%mdk-data-line={1951} +\noindent\mdline{1951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1951} messages are used to specify all possible instances of Packet Digest +PSA externs.%mdk + +%mdk-data-line={1954} +\mdline{1954}A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages.%mdk + +%mdk-data-line={1963} +\mdline{1963}The \mdline{1963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1963} message defines the following fields:%mdk + +%mdk-data-line={1965} +\begin{itemize}%mdk + +%mdk-data-line={1965} +\item{} +%mdk-data-line={1965} +\mdline{1965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1965}, a \mdline{1965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1965} message with the ID, name, and alias of this digest +instance.%mdk%mdk + +%mdk-data-line={1968} +\item{} +%mdk-data-line={1968} +\mdline{1968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1968}, which specifies the data type of an individual digest +notification using a \mdline{1969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1969} message (see section on\mdline{1969}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation +of Arbitrary P4 Types}\mdline{1970}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1972} +\subsubsection{\mdline{1972}6.4.10.\hspace*{0.5em}\mdline{1972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}\label{sec-p4info-extern}%mdk%mdk + +%mdk-data-line={1974} +\noindent\mdline{1974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1974} messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one \mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1977} message instance in P4Info. The \mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1977} message defines +the following fields:%mdk + +%mdk-data-line={1980} +\begin{itemize}%mdk + +%mdk-data-line={1980} +\item{} +%mdk-data-line={1980} +\mdline{1980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{1980}, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the\mdline{1981}~\mdref{sec-id-allocation}{reserved +range}\mdline{1982} \mdline{1982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{}[0x81,~0xfe]}}}\mdline{1982}. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture.%mdk%mdk + +%mdk-data-line={1987} +\item{} +%mdk-data-line={1987} +\mdline{1987}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_name}}}\mdline{1987}, which specifies the fully-qualified P4 name of the extern +type.%mdk%mdk + +%mdk-data-line={1990} +\item{} +%mdk-data-line={1990} +\mdline{1990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instances}}}\mdline{1990}, a repeated field of \mdline{1990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{1990} Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +\mdline{1992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{1992} in turn defines the following fields:%mdk + +%mdk-data-line={1994} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1994} +\item\mdline{1994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1994}, a \mdline{1994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1994} message with the ID, name, and alias of this digest +instance.%mdk + +%mdk-data-line={1996} +\item\mdline{1996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{1996}, an \mdline{1996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1996} Protobuf message\mdline{1996}~[\mdcite{protoany}{31}]\mdline{1996} which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for \mdline{1998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{1998} should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on\mdline{2000}~\mdref{sec-extending-p4runtime}{Extending +P4Runtime for non-PSA Architectures}\mdline{2001} for more +information.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2004} +\noindent\mdline{2004}If the P4 program does not include any instance of a given extern type, the +\mdline{2005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2005} message instance for that type should be omitted from the P4Info.%mdk + +%mdk-data-line={2007} +\subsection{\mdline{2007}6.5.\hspace*{0.5em}\mdline{2007}Support for Arbitrary P4 Types with P4TypeInfo}\label{sec-support-for-arbitrary-p4-types-with-p4typeinfo}%mdk%mdk + +%mdk-data-line={2009} +\noindent\mdline{2009}See section on\mdline{2009}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary P4 +Types}\mdline{2010}.%mdk + +%mdk-data-line={2012} +\section{\mdline{2012}7.\hspace*{0.5em}\mdline{2012}P4 Forwarding-Pipeline Configuration}\label{sec-p4-fwd-pipe-config}%mdk%mdk + +%mdk-data-line={2014} +\noindent\mdline{2014}The \mdline{2014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2014} captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the \mdline{2016}\textquotedblleft{}Device Configuration\textquotedblright{}\mdline{2016} and sometimes also referred to as +the \mdline{2017}\textquotedblleft{}P4 Blob\textquotedblright{}\mdline{2017}. It is defined as:%mdk + +%mdk-data-line={2019} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2020} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ForwardingPipelineConfig~\{\\ +~~config.P{\mdcolor{purple}4}Info~p4info~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~p4\_device\_config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}message}}~Cookie~\{\\ +~~~~{\bfseries{\mdcolor{navy}uint64}}~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~\}\\ +~~Cookie~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2030} +\noindent\mdline{2030}The \mdline{2030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{2030} field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic.%mdk + +%mdk-data-line={2033} +\mdline{2033}The \mdline{2033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{2033} is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new \mdline{2035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2035} on that target.%mdk + +%mdk-data-line={2037} +\mdline{2037}The \mdline{2037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{2037} field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a \mdline{2042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{2042} RPC. +When writing the config via a \mdline{2043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{2043} RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present.%mdk + +%mdk-data-line={2047} +\section{\mdline{2047}8.\hspace*{0.5em}\mdline{2047}General Principles for Message Formatting}\label{sec-general-principles-for-message-formatting}%mdk%mdk + +%mdk-data-line={2049} +\subsection{\mdline{2049}8.1.\hspace*{0.5em}\mdline{2049}Set / Unset Protobuf Field}\label{sec-set-unset-protobuf-field}%mdk%mdk + +%mdk-data-line={2051} +\noindent\mdline{2051}In Protobuf version 3 (\mdline{2051}\emph{proto3}\mdline{2051}), the default value for a message field is +\mdline{2052}\textquotedblleft{}unset\textquotedblright{}\mdline{2052}~[\mdcite{protodefaults}{4}]\mdline{2052}. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +\mdline{2057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2057} message, an \mdline{2057}\textquotedblleft{}unset\textquotedblright{}\mdline{2057} \mdline{2057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2057} field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the \mdline{2059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2059} message field is +set, a single entry will be read.%mdk + +%mdk-data-line={2062} +\mdline{2062}Let\mdline{2062}'\mdline{2062}s look at the counter example in more details. Based on this specification +document, the C++ server code which processes \mdline{2063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2063} messages may look +like this:%mdk + +%mdk-data-line={2065} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2066} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}auto}}~*counter\_entry~=~...\\ +{\bfseries{\mdcolor{navy}if}}~(counter\_entry-\textgreater{}has\_index())~\{\\ +~~{\bfseries{\mdcolor{navy}auto}}~index~=~counter\_entry-\textgreater{}index().index();\\ +~~read\_one\_entry(counter\_entry-\textgreater{}id(),~index);\\ +\}~{\bfseries{\mdcolor{navy}else}}~\{\\ +~~read\_all\_entries(counter\_entry-\textgreater{}id());\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2075} +\begin{enumerate}%mdk + +%mdk-data-line={2075} +\item{} +%mdk-data-line={2075} +\mdline{2075}Reading a single counter entry at index 0 in the counter array with id +\mdline{2076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textless{}id\textgreater{}}}}\mdline{2076}:%mdk + +%mdk-data-line={2077} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2077} +\item\mdline{2077}Here is the C++ client code: + +%mdk-data-line={2078} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2079} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});\\ +entry.mutable\_index();\\ +{\mdcolor{darkgreen}//~The~above~line~sets~the~index~field;~it~is~equivalent~to:}\\ +{\mdcolor{darkgreen}//~auto~*index~=~entry.mutable\_index();}\\ +{\mdcolor{darkgreen}//~index-\textgreater{}set\_index(0);}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2086} +\item\mdline{2086}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2087} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2088} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}\\ +index~\{\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2091} +\item\mdline{2091}\textbf{Expected behavior}\mdline{2091}: Counter entry at index 0 is read. Notice that the +\mdline{2092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2092} subfield is missing under the \mdline{2092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2092} field message of +\mdline{2093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2093} in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2098} +\item{} +%mdk-data-line={2098} +\mdline{2098}Reading all counter entries by leaving the \mdline{2098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2098} field unset%mdk + +%mdk-data-line={2099} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2099} +\item\mdline{2099}Here is the C++ client code: + +%mdk-data-line={2100} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2101} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2104} +\item\mdline{2104}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2105} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2106} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2108} +\item\mdline{2108}\textbf{Expected behavior}\mdline{2108}: All counter entries for the provided counter +instance are read. Notice that the \mdline{2109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2109} message field is unset (default +value) and is therefore omitted from the textual representation of the +message.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={2113} +\subsection{\mdline{2113}8.2.\hspace*{0.5em}\mdline{2113}Read-Write Symmetry}\label{sec-read-write-symmetry}%mdk%mdk + +%mdk-data-line={2115} +\noindent\mdline{2115}The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example:%mdk + +%mdk-data-line={2121} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2122} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}intended\_value~=~value\\ +\\ +status~=~server.write(intended\_value,~p4\_entity)\\ +observed\_value~=~server.read(p4\_entity)\\ +\\ +assert(intended\_value~==~observed\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2130} +\noindent\mdline{2130}To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If \mdline{2134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{2134} RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol\mdline{2137}'\mdline{2137}s complexities to the client implementations.%mdk + +%mdk-data-line={2139} +\mdline{2139}In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the \mdline{2142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2142} fields in a \mdline{2142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2142} message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +\mdline{2145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MessageDifferencer}}}\mdline{2145} class\mdline{2145}~[\mdcite{protomessagedifferencer}{36}]\mdline{2145} included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance.%mdk + +%mdk-data-line={2150} +\subsection{\mdline{2150}8.3.\hspace*{0.5em}\mdline{2150}Zero as Reserved Value}\label{sec-zero-as-reserved-value}%mdk%mdk + +%mdk-data-line={2152} +\noindent\mdline{2152}p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a \mdline{2153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{2153}. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a \mdline{2156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{2156} or a \mdline{2156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfigRequest}}}\mdline{2156}.%mdk + +%mdk-data-line={2158} +\subsection{\mdline{2158}8.4.\hspace*{0.5em}\mdline{2158}Bytestrings}\label{sec-bytestrings}%mdk%mdk + +%mdk-data-line={2160} +\noindent\mdline{2160}P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (\mdline{2162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2162}) or signed (\mdline{2162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2162}), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +\mdline{2165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2165} Protobuf type. The correct bitwidth\mdline{2165} \mdline{2165}\textemdash{}\mdline{2165} as per the P4 program\mdline{2165} \mdline{2165}\textemdash{}\mdline{2165} of +each integer variable exposed through P4Runtime is specified in the P4Info +message.%mdk + +%mdk-data-line={2169} +\mdline{2169}The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals:%mdk + +%mdk-data-line={2172} +\begin{itemize}%mdk + +%mdk-data-line={2172} +\item{} +%mdk-data-line={2172} +\mdline{2172}It ensures that a properly encoded binary string\mdline{2172}'\mdline{2172}s integer value conforms +to the P4Info-specified bitwidth.%mdk%mdk + +%mdk-data-line={2175} +\item{} +%mdk-data-line={2175} +\mdline{2175}It supports\mdline{2175}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2175}.%mdk%mdk + +%mdk-data-line={2177} +\item{} +%mdk-data-line={2177} +\mdline{2177}It helps facilitate non-disruptive P4 program updates.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2179} +\noindent\mdline{2179}In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type \mdline{2184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2184} and/or \mdline{2184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2184}.%mdk + +%mdk-data-line={2186} +\mdline{2186}Note that this representation does \mdline{2186}\emph{not}\mdline{2186} make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range.%mdk + +%mdk-data-line={2195} +\mdline{2195}In the P4Runtime API version 1.0, values of table key fields, action parameters, +and fields in packet-in and packet-out headers between a device and the +controller (see\mdline{2197}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{2197}), may not be of type \mdline{2197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2197}. +The rules for encoding signed values thus only apply to messages of type +\mdline{2199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2199} (see\mdline{2199}~\mdref{sec-p4data-in-p4runtime-proto}{8.5.3}\mdline{2199}).%mdk + +%mdk-data-line={2201} +\mdline{2201}For a value of type \mdline{2201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2201}, the fewest number of bits required to represent +the integer value \mdline{2202}$V > 0$\mdline{2202} is the smallest integer \mdline{2202}$A$\mdline{2202} such that \mdline{2202}$V \leq 2^A -1$\mdline{2203}.%mdk + +%mdk-data-line={2205} +\mdline{2205}For a value of type \mdline{2205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2205}, the fewest number of bits required to represent +the integer value \mdline{2206}$V \neq 0$\mdline{2206} in 2\mdline{2206}'\mdline{2206}s complement form is the smallest integer \mdline{2206}$A$\mdline{2206} +such that \mdline{2207}$-2^{A-1} \leq V \leq 2^{A-1} - 1$\mdline{2207}.%mdk + +%mdk-data-line={2209} +\mdline{2209}As a special case, define that the value \mdline{2209}$V=0$\mdline{2209} requires at least \mdline{2209}$A=1$\mdline{2209} bit to +represent, regardless of whether it is signed or unsigned.%mdk + +%mdk-data-line={2212} +\mdline{2212}The shortest possible binary string for an integer \mdline{2212}$V$\mdline{2212} that needs \mdline{2212}$A$\mdline{2212} bits to +represent it is computed as:%mdk + +%mdk-data-line={2214} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2215} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size~=~floor(({\mdcolor{teal}A}~+~{\mdcolor{purple}7})~/~{\mdcolor{purple}8})}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2218} +\noindent\mdline{2218}Binary strings with the byte length computed as \mdline{2218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2218} promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies.%mdk + +%mdk-data-line={2222} +\mdline{2222}Any additional bits in the bytes sent for an unsigned integer value (type +\mdline{2223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2223}) must be 0. If additional bytes are transmitted above the +\mdline{2224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2224} minimum required, they must be filled with 0.%mdk + +%mdk-data-line={2226} +\mdline{2226}Any additional bits in the bytes sent for a signed integer value (type \mdline{2226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2226}) +must be copies of the sign bit, \mdline{2227}i.e.\mdline{2227} 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +\mdline{2229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2229} minimum required, they must be filled with copies of the +sign bit, \mdline{2230}i.e.\mdline{2230} 0 for non-negative values, or 0xff for negative values. In 2\mdline{2230}'\mdline{2230}s +complement representation, this is called \mdline{2231}\textquotedblleft{}sign extension\textquotedblright{}\mdline{2231}, and leaves the +numeric value represented unchanged.%mdk + +%mdk-data-line={2234} +\mdline{2234}Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value.%mdk + +%mdk-data-line={2240} +\mdline{2240}For a received bitstring expected to fit within a \mdline{2240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2240} type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring\mdline{2242}'\mdline{2242}s width is \mdline{2242}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2242} bits or less.%mdk + +%mdk-data-line={2244} +\mdline{2244}For a received bitstring expected to fit within an \mdline{2244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2244} type, the value it +represents is in range if, after \mdline{2245}\textquotedblleft{}undoing sign extension\textquotedblright{}\mdline{2245}, the remaining bit +string\mdline{2246}'\mdline{2246}s width is \mdline{2246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2246} bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other.%mdk + +%mdk-data-line={2252} +\mdline{2252}If the string\mdline{2252}'\mdline{2252}s byte length is zero, the server always rejects the string.%mdk + +%mdk-data-line={2254} +\mdline{2254}When the server rejects a binary string due to any of the previous criteria, +it returns an \mdline{2255}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2255} error.%mdk + +%mdk-data-line={2257} +\mdline{2257}For all binary strings, P4Runtime uses big-endian (\mdline{2257}i.e.\mdline{2257} network) byte-order. +For signed integer values (\mdline{2258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2258} P4 type), P4Runtime uses the same two\mdline{2258}'\mdline{2258}s +complement bitwise representation as P4. Table\mdline{2259}~\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}}\mdline{2259} +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above.%mdk + +%mdk-data-line={2263} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2265} P4 type}}&\multicolumn{1}{|c}{{\bfseries\mdline{2265} Integer value}}&\multicolumn{1}{|c}{{\bfseries\mdline{2265} P4Runtime binary string}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2265} Read-write symmetry}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2267} \mdline{2267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2267}}&\multicolumn{1}{|l}{\mdline{2267} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2267} \mdline{2267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2267}}&\multicolumn{1}{|l|}{\mdline{2267} yes}\\ +\multicolumn{1}{|l}{\mdline{2268} \mdline{2268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2268}}&\multicolumn{1}{|l}{\mdline{2268} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2268} \mdline{2268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2268}}&\multicolumn{1}{|l|}{\mdline{2268} no}\\ +\multicolumn{1}{|l}{\mdline{2269} \mdline{2269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2269}}&\multicolumn{1}{|l}{\mdline{2269} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2269} \mdline{2269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2269}}&\multicolumn{1}{|l|}{\mdline{2269} yes}\\ +\multicolumn{1}{|l}{\mdline{2270} \mdline{2270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2270}}&\multicolumn{1}{|l}{\mdline{2270} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2270} \mdline{2270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x30\textbackslash{}x64}}}\mdline{2270}}&\multicolumn{1}{|l|}{\mdline{2270} yes}\\ +\multicolumn{1}{|l}{\mdline{2271} \mdline{2271}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2271}}&\multicolumn{1}{|l}{\mdline{2271} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2271} \mdline{2271}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x30\textbackslash{}x64}}}\mdline{2271}}&\multicolumn{1}{|l|}{\mdline{2271} no}\\ +\multicolumn{1}{|l}{\mdline{2272} \mdline{2272}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2272}}&\multicolumn{1}{|l}{\mdline{2272} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2272} \mdline{2272}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2272}}&\multicolumn{1}{|l|}{\mdline{2272} no}\\ +\multicolumn{1}{|l}{\mdline{2273} \mdline{2273}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2273}}&\multicolumn{1}{|l}{\mdline{2273} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2273} \mdline{2273}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2273}}&\multicolumn{1}{|l|}{\mdline{2273} yes}\\ +\multicolumn{1}{|l}{\mdline{2274} \mdline{2274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2274}}&\multicolumn{1}{|l}{\mdline{2274} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2274} \mdline{2274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00\textbackslash{}x63}}}\mdline{2274}}&\multicolumn{1}{|l|}{\mdline{2274} no}\\ +\multicolumn{1}{|l}{\mdline{2275} \mdline{2275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2275}}&\multicolumn{1}{|l}{\mdline{2275} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2275} \mdline{2275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2275}}&\multicolumn{1}{|l|}{\mdline{2275} yes}\\ +\multicolumn{1}{|l}{\mdline{2276} \mdline{2276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2276}}&\multicolumn{1}{|l}{\mdline{2276} \mdline{2276}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2276} \mdline{2276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x9d}}}\mdline{2276}}&\multicolumn{1}{|l|}{\mdline{2276} yes}\\ +\multicolumn{1}{|l}{\mdline{2277} \mdline{2277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2277}}&\multicolumn{1}{|l}{\mdline{2277} \mdline{2277}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2277} \mdline{2277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xff\textbackslash{}x9d}}}\mdline{2277}}&\multicolumn{1}{|l|}{\mdline{2277} no}\\ +\multicolumn{1}{|l}{\mdline{2278} \mdline{2278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2278}}&\multicolumn{1}{|l}{\mdline{2278} \mdline{2278}-739 (-0x2e3)}&\multicolumn{1}{|l}{\mdline{2278} \mdline{2278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xfd\textbackslash{}x1d}}}\mdline{2278}}&\multicolumn{1}{|l|}{\mdline{2278} yes}\\ +\multicolumn{1}{|l}{\mdline{2279} \mdline{2279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2279}}&\multicolumn{1}{|l}{\mdline{2279} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2279} \mdline{2279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00}}}\mdline{2279}}&\multicolumn{1}{|l|}{\mdline{2279} no}\\ +\multicolumn{1}{|l}{\mdline{2280} \mdline{2280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2280}}&\multicolumn{1}{|l}{\mdline{2280} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2280} \mdline{2280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00}}}\mdline{2280}}&\multicolumn{1}{|l|}{\mdline{2280} yes}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2282} +\mdhr{}%mdk + +%mdk-data-line={2283} +\noindent\mdline{2283}\mdcaption{\textbf{Table~\mdcaptionlabel{4}.}~\mdcaptiontext{Examples of Valid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-valid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2285} +\mdline{2285}Table\mdline{2285}~\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}}\mdline{2285} shows some examples of invalid +P4Runtime binary strings:%mdk + +%mdk-data-line={2288} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2290} P4 type}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2290} P4Runtime binary string}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2292} \mdline{2292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2292}}&\multicolumn{1}{|l|}{\mdline{2292} \mdline{2292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x63}}}\mdline{2292}}\\ +\multicolumn{1}{|l}{\mdline{2293} \mdline{2293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2293}}&\multicolumn{1}{|l|}{\mdline{2293} \mdline{2293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2293}}\\ +\multicolumn{1}{|l}{\mdline{2294} \mdline{2294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2294}}&\multicolumn{1}{|l|}{\mdline{2294} \mdline{2294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2294}}\\ +\multicolumn{1}{|l}{\mdline{2295} \mdline{2295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2295}}&\multicolumn{1}{|l|}{\mdline{2295} \mdline{2295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x10\textbackslash{}x63}}}\mdline{2295}}\\ +\multicolumn{1}{|l}{\mdline{2296} \mdline{2296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2296}}&\multicolumn{1}{|l|}{\mdline{2296} \mdline{2296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2296}}\\ +\multicolumn{1}{|l}{\mdline{2297} \mdline{2297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2297}}&\multicolumn{1}{|l|}{\mdline{2297} \mdline{2297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x40\textbackslash{}x63}}}\mdline{2297}}\\ +\multicolumn{1}{|l}{\mdline{2298} \mdline{2298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2298}}&\multicolumn{1}{|l|}{\mdline{2298} \mdline{2298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x9d}}}\mdline{2298}}\\ +\multicolumn{1}{|l}{\mdline{2299} \mdline{2299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2299}}&\multicolumn{1}{|l|}{\mdline{2299} \mdline{2299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x8d\textbackslash{}x1d}}}\mdline{2299}}\\ +\multicolumn{1}{|l}{\mdline{2300} \mdline{2300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2300}}&\multicolumn{1}{|l|}{\mdline{2300} \mdline{2300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2300}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2302} +\mdhr{}%mdk + +%mdk-data-line={2303} +\noindent\mdline{2303}\mdcaption{\textbf{Table~\mdcaptionlabel{5}.}~\mdcaptiontext{Examples of Invalid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-invalid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2305} +\mdline{2305}As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from \mdline{2310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2310} to \mdline{2310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2310}, a server +running the \mdline{2311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2311} version of the P4 program will accept requests from +clients that remain on the \mdline{2312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2312} P4Runtime version.%mdk + +%mdk-data-line={2314} +\mdline{2314}Despite the server\mdline{2314}'\mdline{2314}s binary string flexibility for P4 program update support, +the client and server must both remain aware of the +\mdline{2316}\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2316} +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values.%mdk + +%mdk-data-line={2321} +\mdline{2321}Representation of variable-length integer values (\mdline{2321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2321} P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the \mdline{2323}\emph{dynamic-length}\mdline{2323} of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an \mdline{2326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2326} error code otherwise.%mdk + +%mdk-data-line={2328} +\subsection{\mdline{2328}8.5.\hspace*{0.5em}\mdline{2328}Representation of Arbitrary P4 Types}\label{sec-representation-of-arbitrary-p4-types}%mdk%mdk + +%mdk-data-line={2330} +\subsubsection{\mdline{2330}8.5.1.\hspace*{0.5em}\mdline{2330}Problem Statement}\label{sec-problem-statement}%mdk%mdk + +%mdk-data-line={2332} +\noindent\mdline{2332}The P4\mdline{2332}\mdsub{16}\mdline{2332} language includes more complex types than just binary strings +\mdline{2333}[\mdcite{p4complextypes}{3}]\mdline{2333}. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table\mdline{2336}~\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}}\mdline{2336} shows the different +P4\mdline{2337}\mdsub{16}\mdline{2337} types and how they are allowed to be used, as per the P4\mdline{2337}\mdsub{16}\mdline{2337} +specification.%mdk + +%mdk-data-line={2340} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|l}{{\bfseries\mdline{2342}}}&\multicolumn{3}{|c|}{{\bfseries\mdline{2342} Container type}}\\ +\cmidrule{2-2}\cmidrule{3-3}\cmidrule{4-4} +\multicolumn{1}{|l}{{\bfseries\mdline{2344} Element type}}&\multicolumn{1}{|l}{{\bfseries\mdline{2344} header}}&\multicolumn{1}{|l}{{\bfseries\mdline{2344} header\mdline{2344}\_\mdline{2344}union}}&\multicolumn{1}{|l|}{{\bfseries\mdline{2344} struct or tuple}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2346} \mdline{2346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2346}}&\multicolumn{1}{|l}{\mdline{2346} allowed}&\multicolumn{1}{|l}{\mdline{2346} error}&\multicolumn{1}{|l|}{\mdline{2346} allowed}\\ +\multicolumn{1}{|l}{\mdline{2347} \mdline{2347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2347}}&\multicolumn{1}{|l}{\mdline{2347} allowed}&\multicolumn{1}{|l}{\mdline{2347} error}&\multicolumn{1}{|l|}{\mdline{2347} allowed}\\ +\multicolumn{1}{|l}{\mdline{2348} \mdline{2348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2348}}&\multicolumn{1}{|l}{\mdline{2348} allowed}&\multicolumn{1}{|l}{\mdline{2348} error}&\multicolumn{1}{|l|}{\mdline{2348} allowed}\\ +\multicolumn{1}{|l}{\mdline{2349} \mdline{2349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int}}}\mdline{2349}}&\multicolumn{1}{|l}{\mdline{2349} error}&\multicolumn{1}{|l}{\mdline{2349} error}&\multicolumn{1}{|l|}{\mdline{2349} error}\\ +\multicolumn{1}{|l}{\mdline{2350} \mdline{2350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}void}}}\mdline{2350}}&\multicolumn{1}{|l}{\mdline{2350} error}&\multicolumn{1}{|l}{\mdline{2350} error}&\multicolumn{1}{|l|}{\mdline{2350} error}\\ +\multicolumn{1}{|l}{\mdline{2351} \mdline{2351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2351}}&\multicolumn{1}{|l}{\mdline{2351} error}&\multicolumn{1}{|l}{\mdline{2351} error}&\multicolumn{1}{|l|}{\mdline{2351} allowed}\\ +\multicolumn{1}{|l}{\mdline{2352} \mdline{2352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_kind}}}\mdline{2352}}&\multicolumn{1}{|l}{\mdline{2352} error}&\multicolumn{1}{|l}{\mdline{2352} error}&\multicolumn{1}{|l|}{\mdline{2352} error}\\ +\multicolumn{1}{|l}{\mdline{2353} \mdline{2353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2353}}&\multicolumn{1}{|l}{\mdline{2353} error}&\multicolumn{1}{|l}{\mdline{2353} error}&\multicolumn{1}{|l|}{\mdline{2353} allowed}\\ +\multicolumn{1}{|l}{\mdline{2354} \mdline{2354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2354}}&\multicolumn{1}{|l}{\mdline{2354} allowed\mdline{2354}\mdfootnote{1}{%mdk-data-line={2364} +%mdk-data-line={2364} +\noindent\mdline{2364}an \mdline{2364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2364} type used as a field in a \mdline{2364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2364} must specify a +underlying type and representation for \mdline{2365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2365} elements.%mdk +\label{fn-enum_header}%mdk%mdk +}\mdline{2354}}&\multicolumn{1}{|l}{\mdline{2354} error}&\multicolumn{1}{|l|}{\mdline{2354} allowed}\\ +\multicolumn{1}{|l}{\mdline{2355} \mdline{2355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2355}}&\multicolumn{1}{|l}{\mdline{2355} error}&\multicolumn{1}{|l}{\mdline{2355} allowed}&\multicolumn{1}{|l|}{\mdline{2355} allowed}\\ +\multicolumn{1}{|l}{\mdline{2356} header stack}&\multicolumn{1}{|l}{\mdline{2356} error}&\multicolumn{1}{|l}{\mdline{2356} error}&\multicolumn{1}{|l|}{\mdline{2356} allowed}\\ +\multicolumn{1}{|l}{\mdline{2357} \mdline{2357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2357}}&\multicolumn{1}{|l}{\mdline{2357} error}&\multicolumn{1}{|l}{\mdline{2357} error}&\multicolumn{1}{|l|}{\mdline{2357} allowed}\\ +\multicolumn{1}{|l}{\mdline{2358} \mdline{2358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2358}}&\multicolumn{1}{|l}{\mdline{2358} error}&\multicolumn{1}{|l}{\mdline{2358} error}&\multicolumn{1}{|l|}{\mdline{2358} allowed}\\ +\multicolumn{1}{|l}{\mdline{2359} \mdline{2359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2359}}&\multicolumn{1}{|l}{\mdline{2359} error}&\multicolumn{1}{|l}{\mdline{2359} error}&\multicolumn{1}{|l|}{\mdline{2359} allowed}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2361} +\mdhr{}%mdk + +%mdk-data-line={2362} +\noindent\mdline{2362}\mdcaption{\textbf{Table~\mdcaptionlabel{6}.}~\mdcaptiontext{P4 Type Usage}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-type-usage}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2367} +\mdline{2367}For example, the following P4\mdline{2367}\mdsub{16}\mdline{2367} objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects.%mdk + +%mdk-data-line={2370} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2371} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}{\bfseries{\mdcolor{navy}tuple}}\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}4}\textgreater{},~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~\textgreater{}~\textgreater{}()~digest\_complex;\\ +digest\_complex.pack(\{~hdr.ipv4.version,~hdr.ipv4.protocol~\});\\ +{\mdcolor{darkgreen}//~...}\\ +{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2381} +\noindent\mdline{2381}One solution would be to use only binary string (\mdline{2381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2381} type) in +p4runtime.proto and to define a custom serialization format for complex P4\mdline{2382}\mdsub{16}\mdline{2382} +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P4\mdline{2389}\mdsub{16}\mdline{2389} types.%mdk + +%mdk-data-line={2391} +\subsubsection{\mdline{2391}8.5.2.\hspace*{0.5em}\mdline{2391}P4 Type Specifications in p4info.proto}\label{sec-p4-type-specifications-in-p4infoproto}%mdk%mdk + +%mdk-data-line={2393} +\noindent\mdline{2393}In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type \mdline{2397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip\_t}}}\mdline{2397}, which is a header union with 2 possible headers: +\mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4}}}\mdline{2398} with type \mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4\_t}}}\mdline{2398} and \mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6}}}\mdline{2398} with type \mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6\_t}}}\mdline{2398}. Similarly, they need to +know the field layout for both of these header types.%mdk + +%mdk-data-line={2401} +\mdline{2401}To achieve this we introduce 2 main Protobuf messages: \mdline{2401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2401} and +\mdline{2402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2402}.%mdk + +%mdk-data-line={2404} +\mdline{2404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2404} is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P4\mdline{2405}\mdsub{16}\mdline{2405} program. These +named types are \mdline{2406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2406}, \mdline{2406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2406}, \mdline{2406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2406}, \mdline{2406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2406} and +\mdline{2407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2407}; for each of these we have a type specification message, +respectively \mdline{2408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructTypeSpec}}}\mdline{2408}, \mdline{2408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderTypeSpec}}}\mdline{2408}, \mdline{2408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionTypeSpec}}}\mdline{2408}, +\mdline{2409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4EnumTypeSpec}}}\mdline{2409} and \mdline{2409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4SerializableEnumTypeSpec}}}\mdline{2409}. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. \mdline{2411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2411} also includes the list of parser errors for the program, as +a \mdline{2412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4ErrorTypeSpec}}}\mdline{2412} message.%mdk + +%mdk-data-line={2414} +\mdline{2414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2414} is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each \mdline{2416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2416} message corresponds to a compile-time type in the +original P4\mdline{2417}\mdsub{16}\mdline{2417} program (\mdline{2417}e.g.\mdline{2417} the type parameter of an extern). This +compile-time type is represented as a Protobuf \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2418}, which can be:%mdk + +%mdk-data-line={2420} +\begin{itemize}%mdk + +%mdk-data-line={2420} +\item{} +%mdk-data-line={2420} +\mdline{2420}a string representing the name of the type in case of a named type (\mdline{2420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2420}, +\mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2421}, \mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2421}, \mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2421}, \mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2421} or user-defined \mdline{2421}\textquotedblleft{}new\textquotedblright{}\mdline{2421} +\mdline{2422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2422}),%mdk%mdk + +%mdk-data-line={2424} +\item{} +%mdk-data-line={2424} +\mdline{2424}an empty Protobuf message for \mdline{2424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2424} and \mdline{2424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2424}, or%mdk%mdk + +%mdk-data-line={2426} +\item{} +%mdk-data-line={2426} +\mdline{2426}a Protobuf message for other anonymous types (\mdline{2426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2426}, \mdline{2426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2426}, \mdline{2426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2426}, +\mdline{2427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2427} or stack). The \mdline{2427}\textquotedblleft{}binary string\textquotedblright{}\mdline{2427} types (\mdline{2427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2427}, \mdline{2427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2427}, and +\mdline{2428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2428}) are grouped together in the \mdline{2428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4BitstringLikeTypeSpec}}}\mdline{2428} message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf \mdline{2430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2430} +type).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2433} +\noindent\mdline{2433}For all P4\mdline{2433}\mdsub{16}\mdline{2433} compound types (\mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2433}, and \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2433}), +the order of \mdline{2434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2434} in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P4\mdline{2436}\mdsub{16}\mdline{2436} declaration. The same goes for the order of members of an \mdline{2436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2436} +(serializable or not) or members of \mdline{2437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2437}.%mdk + +%mdk-data-line={2439} +\subsubsection{\mdline{2439}8.5.3.\hspace*{0.5em}\mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2439} in p4runtime.proto}\label{sec-p4data-in-p4runtime-proto}%mdk%mdk + +%mdk-data-line={2441} +\noindent\mdline{2441}P4Runtime uses the \mdline{2441}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2441} message to represent values of arbitrary types. The +P4Runtime client must generate correct \mdline{2442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2442} messages based on the type +specification information included in P4Info. The \mdline{2443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2443} message was designed +to introduce little overhead compared to using binary strings in the most common +case (P4\mdline{2445}\mdsub{16}\mdline{2445} \mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2445} type).%mdk + +%mdk-data-line={2447} +\mdline{2447}Just like its P4Info counterpart\mdline{2447} \mdline{2447}- \mdline{2447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2447} \mdline{2447}-, \mdline{2447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2447} uses a Protobuf +\mdline{2448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2448} to represent all possible values.%mdk + +%mdk-data-line={2450} +\mdline{2450}We define a canonical representation for \mdline{2450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2450} messages\mdline{2450} \mdline{2450}\textemdash{}\mdline{2450} therefore +guaranteeing read-write symmetry\mdline{2451} \mdline{2451}\textemdash{}\mdline{2451} by introducing the following requirements:%mdk + +%mdk-data-line={2453} +\begin{itemize}%mdk + +%mdk-data-line={2453} +\item{} +%mdk-data-line={2453} +\mdline{2453}The order of \mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2453} in \mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructLike}}}\mdline{2453} and the order of \mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2453} in +\mdline{2454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2454} must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P4\mdline{2455}\mdsub{16}\mdline{2455} type +declaration.%mdk%mdk + +%mdk-data-line={2458} +\item{} +%mdk-data-line={2458} +\mdline{2458}An invalid header is represented by a \mdline{2458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2458} message where the \mdline{2458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_valid}}}\mdline{2458} +field is false and the \mdline{2459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2459} repeated field is empty.%mdk%mdk + +%mdk-data-line={2461} +\item{} +%mdk-data-line={2461} +\mdline{2461}An invalid header union (\mdline{2461}i.e.\mdline{2461} all headers in the union are invalid) is +represented by a \mdline{2462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnion}}}\mdline{2462} message where the \mdline{2462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header\_name}}}\mdline{2462} is the +empty string (default value for the field) and the \mdline{2463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header}}}\mdline{2463} is unset.%mdk%mdk + +%mdk-data-line={2465} +\item{} +%mdk-data-line={2465} +\mdline{2465}The order of \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2465} in \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStack}}}\mdline{2465} and \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStack}}}\mdline{2465} is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the \mdline{2467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2467} field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding \mdline{2469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStackTypeSpec}}}\mdline{2469} or +\mdline{2470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStackTypeSpec}}}\mdline{2470} message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2472} +\subsubsection{\mdline{2472}8.5.4.\hspace*{0.5em}\mdline{2472}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={2474} +\noindent\mdline{2474}Let\mdline{2474}'\mdline{2474}s look at the Register example again:%mdk + +%mdk-data-line={2476} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2477} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2484} +\noindent\mdline{2484}Here\mdline{2484}'\mdline{2484}s the corresponding entry in the P4Info message:%mdk + +%mdk-data-line={2486} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2487} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}registers~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}369119267}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~\}\\ +~~type\_spec~\{\\ +~~~~header\_union~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~size:~{\mdcolor{purple}128}\\ +\}\\ +type\_info~\{\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~header\_unions~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2543} +\noindent\mdline{2543}Here\mdline{2543}'\mdline{2543}s a \mdline{2543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.WriteRequest}}}\mdline{2543} to set the value of \mdline{2543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_ip{}[12]}}}\mdline{2543}:%mdk + +%mdk-data-line={2545} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2546} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}update~\{\\ +~~type:~INSERT\\ +~~entity~\{\\ +~~~~register\_entry~\{\\ +~~~~~~register\_id:~{\mdcolor{purple}369119267}\\ +~~~~~~index~\{\\ +~~~~~~~~index:~{\mdcolor{purple}12}\\ +~~~~~~\}\\ +~~~~~~data~\{\\ +~~~~~~~~header\_union~\{\\ +~~~~~~~~~~valid\_header\_name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~~~valid\_header~\{\\ +~~~~~~~~~~~~is\_valid:~true\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x04}{\mdcolor{maroon}"}\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{darkgreen}\#~...}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2569} +\subsubsection{\mdline{2569}8.5.5.\hspace*{0.5em}\mdline{2569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2569}, serializable \mdline{2569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2569} and \mdline{2569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}\label{sec-enum-serializable-enum-and-error}%mdk%mdk + +%mdk-data-line={2571} +\noindent\mdline{2571}P4\mdline{2571}\mdsub{16}\mdline{2571} supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or \mdline{2572}\textquotedblleft{}unsafe\textquotedblright{}\mdline{2572} enum) +\mdline{2573}[\mdcite{p4enums}{5}]\mdline{2573}. For \mdline{2573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2573} types with no underlying type\mdline{2573} \mdline{2573}\textemdash{}\mdline{2573} as well as \mdline{2573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2573} \mdline{2573}\textemdash{}\mdline{2573} +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in \mdline{2576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2576} to represent \mdline{2576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2576} and +\mdline{2577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2577} values.%mdk + +%mdk-data-line={2579} +\mdline{2579}Serializable \mdline{2579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2579} types have an underlying fixed-width unsigned integer +representation (\mdline{2580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2580}). All named enum members must be assigned an integer +value by the P4 programmer, but \mdline{2581}\emph{not all}\mdline{2581} valid numeric values for the +underlying type need to have a corresponding name. \mdline{2582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2582} includes the +mapping between entry name and entry value. When providing serializable enum +values through \mdline{2584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2584}, one must use the assigned integer value (\mdline{2584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum\_value}}}\mdline{2584} +bytestring field). P4Runtime does not provide a way for the client to use the +name\mdline{2586} \mdline{2586}\textemdash{}\mdline{2586} even when the enum member has one\mdline{2586} \mdline{2586}\textemdash{}\mdline{2586} instead of the value, as it makes +it easier for the server to respect the\mdline{2587}~\mdref{sec-read-write-symmetry}{read-write +symmetry}\mdline{2588} principle.%mdk + +%mdk-data-line={2590} +\subsubsection{\mdline{2590}8.5.6.\hspace*{0.5em}\mdline{2590}User-defined types}\label{sec-user-defined-types}%mdk%mdk + +%mdk-data-line={2592} +\noindent\mdline{2592}P4\mdline{2592}\mdsub{16}\mdline{2592} enables programmers to introduce new types\mdline{2592}~[\mdcite{p4newtypes}{11}]\mdline{2592}. While similar +to \mdline{2593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{2593}, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +\mdline{2596}\mdref{sec-psa-metadata-translation}{translation}\mdline{2596}. When introducing a new type, the +declaration can be annotated with \mdline{2597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2597} to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for\mdline{2599}~\mdref{sec-translation-of-port-numbers}{port numbers}\mdline{2599}, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. \mdline{2602}\textbf{The \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}} annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}})}\mdline{2604}. The type exposed to the control plane (referred to as the +\mdline{2605}\emph{controller\_type}\mdline{2605}) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a \mdline{2607}\emph{URI}\mdline{2607} (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the \mdline{2609}\emph{controller\_type}\mdline{2609} of the values exposed to the control plane. The +\mdline{2610}\emph{controller\_type}\mdline{2610} can be either \mdline{2610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2610} where \mdline{2610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2610} is any positive integer, or +\mdline{2611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{2611}, or a positive integer \mdline{2611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2611} which has the same meaning as \mdline{2611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2611}. +Specifying just an integer is deprecated.%mdk + +%mdk-data-line={2614} +\mdline{2614}It is recommended that the URI includes at least the P4 architecture name and +the type name.%mdk + +%mdk-data-line={2617} +\mdline{2617}A \mdline{2617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2617} annotation need not have any effect if it is used to +annotate anything in a P4 program other than a \mdline{2618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2618} declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect.%mdk + +%mdk-data-line={2622} +\mdline{2622}User-defined types are specified using the \mdline{2622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{2622} message, which has +the following fields:%mdk + +%mdk-data-line={2625} +\begin{itemize}%mdk + +%mdk-data-line={2625} +\item{} +%mdk-data-line={2625} +\mdline{2625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}representation}}}\mdline{2625}, a Protobuf \mdline{2625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2625} specifying how values of this type are +exchanged between client and server; it can be either:%mdk + +%mdk-data-line={2628} +\begin{itemize}%mdk + +%mdk-data-line={2628} +\item{} +%mdk-data-line={2628} +\mdline{2628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2628}, if and only if no \mdline{2628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2628} annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 \mdline{2630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2630} declaration is itself a +user-defined type, \mdline{2631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2631} is obtained by \mdline{2631}\textquotedblleft{}walking\textquotedblright{}\mdline{2631} the chain of +\mdline{2632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2632} declarations recursively until a built-in type (\mdline{2632}e.g.\mdline{2632} \mdline{2632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2632}) is +found.%mdk%mdk + +%mdk-data-line={2635} +\item{} +%mdk-data-line={2635} +\mdline{2635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}translated\_type}}}\mdline{2635}, if and only if the P4 \mdline{2635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2635} declaration was annotated +with \mdline{2636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2636}. It is of type \mdline{2636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeTranslation}}}\mdline{2636}, +which itself has two fields\mdline{2637} \mdline{2637}\textemdash{}\mdline{2637} \mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uri}}}\mdline{2637} and either \mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_string}}}\mdline{2637} or +\mdline{2638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_bitwidth}}}\mdline{2638} \mdline{2638}\textemdash{}\mdline{2638}, which map to the two input parameters to the +annotation.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2641} +\item{} +%mdk-data-line={2641} +\mdline{2641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{2641}, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2644} +\noindent\mdline{2644}For example, an architecture\mdline{2644} \mdline{2644}\textemdash{}\mdline{2644} in this case PSA\mdline{2644} \mdline{2644}\textemdash{}\mdline{2644} may introduce a new type +for port numbers:%mdk + +%mdk-data-line={2646} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2647} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~string,~e.g.~"eth0".}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~32-bit~integer,~e.g.~0xffffffff.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{darkgreen}//~Same~as~above.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_32\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_32\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2660} +\noindent\mdline{2660}In this case, the P4Info message would include the following \mdline{2660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2660} +messages:%mdk + +%mdk-data-line={2663} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2664} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_string:~\{\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2701} +\noindent\mdline{2701}Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (\mdline{2702}e.g.\mdline{2702} through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over \mdline{2704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2704} to enable users +to overwrite annotations included as part of the P4 architecture definition.%mdk + +%mdk-data-line={2707} +\subsubsection{\mdline{2707}8.5.7.\hspace*{0.5em}\mdline{2707}Trade-off for v1.x Releases}\label{sec-trade-off-for-v1x-releases}%mdk%mdk + +%mdk-data-line={2709} +\noindent\mdline{2709}For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +\mdline{2710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2710} with \mdline{2710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2710} in the \mdline{2710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{2710} message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +\mdline{2713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2713} to provide action parameter values and controller metadata +values. However \mdline{2714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2714} is used whenever appropriate for PSA externs and we +encourage the use of \mdline{2715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2715} in architecture-specific extensions.%mdk + +%mdk-data-line={2717} +\mdline{2717}In order to support\mdline{2717}~\mdref{sec-psa-metadata-translation}{translation}\mdline{2717} for action +parameters and match fields, we include a \mdline{2718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2718} field in +\mdline{2719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{2719}, \mdline{2719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Action.Param}}}\mdline{2719} and +\mdline{2720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ControllerPacketMetadata.Metadata}}}\mdline{2720}. In addition, the \mdline{2720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2720} +field for all of these message types must abide by the following rule when +\mdline{2722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2722} names a translated user-defined type:%mdk + +%mdk-data-line={2724} +\begin{itemize}%mdk + +%mdk-data-line={2724} +\item{} +%mdk-data-line={2724} +\mdline{2724}If the \mdline{2724}\emph{controller\_type}\mdline{2724} is a fixed-width unsigned bitstring, the \mdline{2724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2724} +field must be set to the bitwidth of the \mdline{2725}\emph{controller\_type}\mdline{2725}. This information +is redundant with the one included in the \mdline{2726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2726} entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent.%mdk%mdk + +%mdk-data-line={2732} +\item{} +%mdk-data-line={2732} +\mdline{2732}Otherwise (\mdline{2732}i.e.\mdline{2732}, if the \mdline{2732}\emph{controller\_type}\mdline{2732} is a string), the \mdline{2732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2732} must +be \mdline{2733}\textquotedblleft{}unset\textquotedblright{}\mdline{2733}, which, in Protobuf version 3, is the same as setting the field to +0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2736} +\noindent\mdline{2736}For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types:%mdk + +%mdk-data-line={2738} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2739} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{navy}@}{\mdcolor{navy}name}{\mdcolor{maroon}(".t")}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~meta.port1:~exact;~~{\mdcolor{darkgreen}//~meta.port1~has~type~PortId\_String\_t}\\ +~~~~meta.port2:~exact;~~{\mdcolor{darkgreen}//~meta.port2~has~type~PortId\_Bit32\_t}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2757} +\noindent\mdline{2757}This table would have the following representation in the generated P4Info +message:%mdk + +%mdk-data-line={2759} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2760} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tables~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}34728461}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port1}{\mdcolor{maroon}"}\\ +~~~~{\mdcolor{darkgreen}\#~notice~that~bitwidth~is~unset}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port2}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~{\mdcolor{darkgreen}\#~...}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2788} +\section{\mdline{2788}9.\hspace*{0.5em}\mdline{2788}P4 Entity Messages}\label{sec-p4-entity-msgs}%mdk%mdk + +%mdk-data-line={2790} +\noindent\mdline{2790}P4Runtime covers P4 entities that are either part of the P4\mdline{2790}\mdsub{16}\mdline{2790} language, or +defined as PSA externs. The sections below describe the messages for each +supported entity.%mdk + +%mdk-data-line={2794} +\subsection{\mdline{2794}9.1.\hspace*{0.5em}\mdline{2794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}\label{sec-table-entry}%mdk%mdk + +%mdk-data-line={2796} +\noindent\mdline{2796}The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action\mdline{2798}'\mdline{2798}s +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification.%mdk + +%mdk-data-line={2804} +\mdline{2804}P4Runtime supports inserting, modifying, deleting and reading table entries with +the \mdline{2805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2805} entity, which has the following fields:%mdk + +%mdk-data-line={2807} +\begin{itemize}%mdk + +%mdk-data-line={2807} +\item{} +%mdk-data-line={2807} +\mdline{2807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2807}, which identifies the table instance; the \mdline{2807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2807} is determined +by the P4Info message.%mdk%mdk + +%mdk-data-line={2810} +\item{} +%mdk-data-line={2810} +\mdline{2810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2810}, a repeated field of \mdline{2810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2810} messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration.%mdk%mdk + +%mdk-data-line={2814} +\item{} +%mdk-data-line={2814} +\mdline{2814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2814}, which indicates which of the table\mdline{2814}'\mdline{2814}s actions to execute in case of +match and with which argument values.%mdk%mdk + +%mdk-data-line={2817} +\item{} +%mdk-data-line={2817} +\mdline{2817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2817}, a 32-bit integer used to order entries when the table\mdline{2817}'\mdline{2817}s match key +includes an optional, ternary or range match.%mdk%mdk + +%mdk-data-line={2820} +\item{} +%mdk-data-line={2820} +\mdline{2820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2820}, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +\mdline{2824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{2824} field.%mdk%mdk + +%mdk-data-line={2826} +\item{} +%mdk-data-line={2826} +\mdline{2826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{2826}, an arbitrary \mdline{2826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2826} value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry.%mdk%mdk + +%mdk-data-line={2831} +\item{} +%mdk-data-line={2831} +\mdline{2831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2831}, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See\mdline{2832}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2833} section for more information.%mdk%mdk + +%mdk-data-line={2835} +\item{} +%mdk-data-line={2835} +\mdline{2835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2835}, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See\mdline{2836}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2837} section for more information.%mdk%mdk + +%mdk-data-line={2839} +\item{} +%mdk-data-line={2839} +\mdline{2839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2839}, a boolean flag which indicates whether the table entry is +the default entry for the table. See\mdline{2840}~\mdref{sec-default-entry}{Default entry}\mdline{2840} +section for more information.%mdk%mdk + +%mdk-data-line={2843} +\item{} +%mdk-data-line={2843} +\mdline{2843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2843} and \mdline{2843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2843}, which are two fields used to +implement idle-timeout support for the table, if applicable. See +\mdline{2845}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{2845} section for more information.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2847} +\noindent\mdline{2847}The \mdline{2847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2847} field must be set to a non-zero value if the match key includes a +ternary match (\mdline{2848}i.e.\mdline{2848} in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an \mdline{2849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{2849}, \mdline{2849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2849} or +\mdline{2850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2850} match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches.%mdk + +%mdk-data-line={2859} +\mdline{2859}The \mdline{2859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2859} and \mdline{2859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2859} fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for \mdline{2861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2861} and \mdline{2861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{2861} updates. When deleting +an entry, these key fields (along with \mdline{2862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2862}) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a \mdline{2864}\emph{keyless}\mdline{2864} +table (the table has an empty match key), the server must reject all attempts to +\mdline{2866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2866} a match entry and return an \mdline{2866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2866} error.%mdk + +%mdk-data-line={2868} +\mdline{2868}The number of match entries that a table \mdline{2868}\emph{should}\mdline{2868} support is indicated in P4Info +(\mdline{2869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2869} field of \mdline{2869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{2869} message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P4\mdline{2870}\mdsub{16}\mdline{2870} specification for the +\mdline{2871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2871} property\mdline{2871}~[\mdcite{p4tableproperties}{30}]\mdline{2871}. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +\mdline{2875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{2875} when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached.%mdk + +%mdk-data-line={2880} +\subsubsection{\mdline{2880}9.1.1.\hspace*{0.5em}\mdline{2880}Match Format}\label{sec-match-format}%mdk%mdk + +%mdk-data-line={2882} +\noindent\mdline{2882}The bytes fields in the \mdline{2882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2882} message follow the format described in +\mdline{2883}\mdref{sec-bytestrings}{Bytestrings}\mdline{2883}.%mdk + +%mdk-data-line={2885} +\mdline{2885}For \mdline{2885}\textquotedblleft{}don't care\textquotedblright{}\mdline{2885} matches, the P4Runtime client must omit the field\mdline{2885}'\mdline{2885}s entire +\mdline{2886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2886} entry when building the \mdline{2886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2886} repeated field of the \mdline{2886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2886} +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for \mdline{2888}\textquotedblleft{}don't care\textquotedblright{}\mdline{2888} matches, which is needed +to ensure\mdline{2889}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2889}. For PSA match types, +a \mdline{2890}\textquotedblleft{}don't care\textquotedblright{}\mdline{2890} match for a specific match key field is defined as follows:%mdk + +%mdk-data-line={2892} +\begin{itemize}%mdk + +%mdk-data-line={2892} +\item{} +%mdk-data-line={2892} +\mdline{2892}For a \mdline{2892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2892} match, it is logically equivalent to a mask of zeros.%mdk%mdk + +%mdk-data-line={2894} +\item{} +%mdk-data-line={2894} +\mdline{2894}For a \mdline{2894}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{2894} match, it is logically equivalent to a wildcard match.%mdk%mdk + +%mdk-data-line={2896} +\item{} +%mdk-data-line={2896} +\mdline{2896}For an \mdline{2896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2896} match, it is logically equivalent to a prefix\mdline{2896}\_\mdline{2896}len of zero.%mdk%mdk + +%mdk-data-line={2898} +\item{} +%mdk-data-line={2898} +\mdline{2898}For a \mdline{2898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2898} match, it is logically equivalent to a range which includes all +possible values for the field.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2901} +\noindent\mdline{2901}Note that there is no \mdline{2901}\textquotedblleft{}don't care\textquotedblright{}\mdline{2901} value for \mdline{2901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2901} matches and therefore exact +match fields can never be omitted from the \mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2902} message.%mdk + +%mdk-data-line={2904} +\mdline{2904}The following example shows a P4Runtime message that treats a \mdline{2904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2904} field +as a \mdline{2905}\textquotedblleft{}don't care\textquotedblright{}\mdline{2905} match. The P4 program defines table \mdline{2905}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{2905} with \mdline{2905}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2905} +and \mdline{2906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2906} fields in its match key:%mdk + +%mdk-data-line={2908} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2909} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~ternary;\\ +~~~~istd.ingress\_port:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2920} +\noindent\mdline{2920}In this P4Runtime request, the client omits the table\mdline{2920}'\mdline{2920}s \mdline{2920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2920} field +from the repeated \mdline{2921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2921} field to indicate a \mdline{2921}\textquotedblleft{}don't care\textquotedblright{}\mdline{2921} match. As shown +below, the \mdline{2922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2922} specifies only the \mdline{2922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2922} field given by \mdline{2922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id:~2}}}\mdline{2922}.%mdk + +%mdk-data-line={2924} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2925} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}33554439}~~{\mdcolor{darkgreen}\#~Table~t's~ID.}\\ +~~~~match~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~field\_id~1~is~not~present~to~use~the~don't~care~ternary~value.}\\ +~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~exact~\{\\ +~~~~~~~~value:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x20}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~action~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~Action~selection~goes~here.}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2943} +\noindent\mdline{2943}For every member of the \mdline{2943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2943} repeated \mdline{2943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2943} field, \mdline{2943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id}}}\mdline{2943} must be +a valid id for the table, as per the P4Info, and one of the fields in +\mdline{2945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{2945} must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an \mdline{2947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2947} error code.%mdk + +%mdk-data-line={2949} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2949} +\item\mdline{2949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2949} match + +%mdk-data-line={2950} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2950} +\item\mdline{2950}The binary string encoding of the value must conform to the +\mdline{2951}\mdref{sec-bytestrings}{Bytestrings}\mdline{2951} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2953} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2954} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.exact().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2957} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2957} +\item\mdline{2957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2957} match + +%mdk-data-line={2958} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2958} +\item\mdline{2958}The binary string encoding of the value (when present) must conform to the +\mdline{2959}\mdref{sec-bytestrings}{Bytestrings}\mdline{2959} requirements.%mdk + +%mdk-data-line={2960} +\item\mdline{2960}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2960} match must be omitted.%mdk + +%mdk-data-line={2961} +\item\mdline{2961}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2961} bits must be 0 in value.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2963} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2964} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.lpm().value()))\\ +\\ +pLen~=~match.lpm().prefix\_len()\\ +assert(pLen~\textgreater{}~0)\\ +\\ +trailing\_zeros~=~countTrailingZeros(match.lpm().value())\\ +assert(trailing\_zeros~\textgreater{}=~field\_bits~-~pLen)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2973} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2973} +\item\mdline{2973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2973} match + +%mdk-data-line={2974} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2974} +\item\mdline{2974}The binary string encoding of the value (when present) and mask (when +present) must conform to the\mdline{2975}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2975} requirements.%mdk + +%mdk-data-line={2976} +\item\mdline{2976}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2976} match must be omitted.%mdk + +%mdk-data-line={2977} +\item\mdline{2977}Masked bits must be 0 in value. This constraint taken together +with the\mdline{2978}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2978} requirements means that the +value\mdline{2979}'\mdline{2979}s binary string is never longer than the mask\mdline{2979}'\mdline{2979}s binary string. +When the value\mdline{2980}'\mdline{2980}s string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2984} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2985} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.ternary().value()))\\ +assert(BytestringValid(match.ternary().mask()))\\ +assert(match.ternary().value().size()~\textless{}=~match.ternary().mask().size());\\ +\\ +value~=~parseInteger(match.ternary().value())\\ +mask~=~parseInteger(match.ternary().mask())\\ +\\ +assert(mask~!=~0)\\ +\\ +assert(value~\&~mask~==~value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2997} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2997} +\item\mdline{2997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2997} match + +%mdk-data-line={2998} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2998} +\item\mdline{2998}The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the\mdline{2999}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2999} +requirements.%mdk + +%mdk-data-line={3001} +\item\mdline{3001}Low bound must be less than or equal to the high bound.%mdk + +%mdk-data-line={3002} +\item\mdline{3002}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3002} match must be omitted.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3004} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3005} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.range().low()))\\ +assert(BytestringValid(match.range().high()))\\ +\\ +low~=~parseInteger(match.range().low())\\ +high~=~parseInteger(match.range().high())\\ +\\ +assert(low~\textless{}=~high)\\ +\\ +assert(low~!=~min\_field\_value~\textbar{}\textbar{}~high~!=~max\_field\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3016} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3016} +\item\mdline{3016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3016} match + +%mdk-data-line={3017} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3017} +\item\mdline{3017}The binary string encoding of the value must conform to the +\mdline{3018}\mdref{sec-bytestrings}{Bytestrings}\mdline{3018} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3020} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3021} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.optional().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3024} +\subsubsection{\mdline{3024}9.1.2.\hspace*{0.5em}\mdline{3024}Action Specification}\label{sec-action-specification}%mdk%mdk + +%mdk-data-line={3026} +\noindent\mdline{3026}The \mdline{3026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3026} \mdline{3026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3026} field must be set for every \mdline{3026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3026} update but may be +left unset for \mdline{3027}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3027} updates, in which case the action specification for the +table entry will not be modified (if a \mdline{3028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3028} update has an unset action field +and does not modify any direct resource attached to the table then the \mdline{3029}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3029} +update is a no-op). Based on the implementation property value of the P4 table, +the \mdline{3031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3031} in the \mdline{3031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3031} message will either be:%mdk + +%mdk-data-line={3033} +\begin{itemize}%mdk + +%mdk-data-line={3033} +\item{} +%mdk-data-line={3033} +\mdline{3033}an \mdline{3033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3033} specification for direct tables (with no P4 \mdline{3033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3033} +property)%mdk%mdk + +%mdk-data-line={3036} +\item{} +%mdk-data-line={3036} +\mdline{3036}an action profile member id for indirect tables for which the \mdline{3036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3036} +property is an action profile with no selector.%mdk%mdk + +%mdk-data-line={3039} +\item{} +%mdk-data-line={3039} +\mdline{3039}an action profile member id or group id for indirect tables for which the +\mdline{3040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3040} property is an action profile with selector.%mdk%mdk + +%mdk-data-line={3042} +\item{} +%mdk-data-line={3042} +\mdline{3042}an \mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3042} specification for indirect tables for +which the \mdline{3043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3043} property is an action profile with +selector. This usage is described in\mdline{3044}~\mdref{sec-oneshot}{One Shot Action Selector +Programming}\mdline{3045}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3047} +\noindent\mdline{3047}If the \mdline{3047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3047} does not match the table description in the P4Info (\mdline{3047}e.g.\mdline{3047} the +\mdline{3048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3048} is \mdline{3048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member\_id}}}\mdline{3048} for a direct table), the server must +return an \mdline{3049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3049} error code.%mdk + +%mdk-data-line={3051} +\mdline{3051}The \mdline{3051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3051} Protobuf message has the following fields:%mdk + +%mdk-data-line={3053} +\begin{itemize}%mdk + +%mdk-data-line={3053} +\item{} +%mdk-data-line={3053} +\mdline{3053}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3053}, which identifies the action instance; the \mdline{3053}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3053} is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an \mdline{3055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3055} error +code. If the client uses a valid \mdline{3056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3056} for the table but does not +respect the action scope specified in P4Info (\mdline{3057}e.g.\mdline{3057} tries to set a \mdline{3057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{3057} +action as the default action), the server must return a \mdline{3058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3058} +error code.%mdk%mdk + +%mdk-data-line={3061} +\item{} +%mdk-data-line={3061} +\mdline{3061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{3061}: a repeated Protobuf field of action parameter values, each encoded +as a \mdline{3062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{3062} message. For each parameter, \mdline{3062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}param\_id}}}\mdline{3062} must be valid for the +action (as per the P4Info) and value must follow the format described in +\mdline{3064}\mdref{sec-bytestrings}{Bytestrings}\mdline{3064}. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an \mdline{3066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3066} error code +if a parameter id is missing, if an extra parameter\mdline{3067} \mdline{3067}\textemdash{}\mdline{3067} id not found in the +P4Info\mdline{3068} \mdline{3068}\textemdash{}\mdline{3068} was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +\mdline{3070}\mdref{sec-bytestrings}{Bytestrings}\mdline{3070} format.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3072} +\noindent\mdline{3072}For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a \mdline{3074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3074} error code.%mdk + +%mdk-data-line={3076} +\subsubsection{\mdline{3076}9.1.3.\hspace*{0.5em}\mdline{3076}Default Entry}\label{sec-default-entry}%mdk%mdk + +%mdk-data-line={3078} +\noindent\mdline{3078}According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer\mdline{3079} \mdline{3079}\textemdash{}\mdline{3079} or defaults to \mdline{3079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3079} +(which is a no-op) otherwise\mdline{3080} \mdline{3080}\textemdash{}\mdline{3080} and assuming it is not declared as \mdline{3080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3080}, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3082} and \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3082} updates on the default entry and the +P4Runtime server must return an \mdline{3083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3083} error code if the client +attempts one.%mdk + +%mdk-data-line={3086} +\mdline{3086}The default entry is identified by setting the \mdline{3086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3086} boolean field +to true. When this flag is set to true, the repeated \mdline{3087}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3087} field must be empty +and the \mdline{3088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3088} field must be set to zero, otherwise the P4Runtime server +must return an \mdline{3089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3089} error code. When performing a \mdline{3089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3089} update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its \mdline{3093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3093} and \mdline{3093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3093} value as well as the +configurations for its\mdline{3094}~\mdref{sec-direct-resources}{direct resources}\mdline{3094} will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a \mdline{3096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3096} +error code if the client attempts to modify it.%mdk + +%mdk-data-line={3099} +\mdline{3099}Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to\mdline{3100}~\mdref{sec-direct-resources}{direct resources}\mdline{3100}.%mdk + +%mdk-data-line={3102} +\mdline{3102}In this P4Runtime release, we have decided to restrict the default entry for +indirect tables\mdline{3103} \mdline{3103}\textemdash{}\mdline{3103} tables with an ActionProfile or ActionSelector +\mdline{3104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3104} property\mdline{3104} \mdline{3104}\textemdash{}\mdline{3104} to a constant \mdline{3104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3104} action entry, with the +hope that it would simplify the implementation of the P4Runtime service.%mdk + +%mdk-data-line={3107} +\subsubsection{\mdline{3107}9.1.4.\hspace*{0.5em}\mdline{3107}Constant Tables}\label{sec-constant-tables}%mdk%mdk + +%mdk-data-line={3109} +\noindent\mdline{3109}Constant tables are defined as tables whose match entries are immutable. They +are identified by the \mdline{3110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3110} flag in P4Info.%mdk + +%mdk-data-line={3112} +\mdline{3112}The only write updates which are allowed for constant tables are \mdline{3112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3112} +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +\mdline{3116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3116} error. Just like any table entry \mdline{3116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3116} request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a \mdline{3120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3120} error.%mdk + +%mdk-data-line={3122} +\mdline{3122}The contents of const tables can be queried by the client through a +\mdline{3123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3123}. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: \mdline{3124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3124}, \mdline{3124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3124}, \mdline{3124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3124}, +\mdline{3125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3125}, and \mdline{3125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3125} (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the \mdline{3128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3128} field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P4\mdline{3130}\mdsub{16}\mdline{3130} does not support assigning explicit priorities to static +entries. When a priority value is required (\mdline{3131}e.g.\mdline{3131} for tables including \mdline{3131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3131}, +\mdline{3132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3132} or \mdline{3132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3132} matches), it is inferred based on the order in which +entries appear in the table declaration.%mdk + +%mdk-data-line={3135} +\subsubsection{\mdline{3135}9.1.5.\hspace*{0.5em}\mdline{3135}Wildcard Reads}\label{sec-table-wildcard-reads}%mdk%mdk + +%mdk-data-line={3137} +\noindent\mdline{3137}When performing a \mdline{3137}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3137}, the P4Runtime client can select all entries +from one or all tables on the target and use several of the \mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3138} fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as \mdline{3142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3142} and \mdline{3142}\textquotedblleft{}unset\textquotedblright{}\mdline{3142} for message fields such as \mdline{3142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3142}. The following +fields may be used to select and filter results:%mdk + +%mdk-data-line={3145} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3145} +\item\mdline{3145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3145}: If default (0), entries from all tables\mdline{3145} \mdline{3145}\textemdash{}\mdline{3145} including constant +tables\mdline{3146} \mdline{3146}\textemdash{}\mdline{3146} will be selected and no other filter can be used. Otherwise only +the specified table will be considered.%mdk + +%mdk-data-line={3148} +\item\mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3148}: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned.%mdk + +%mdk-data-line={3152} +\item\mdline{3152}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3152}: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an \mdline{3153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3153} (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id.%mdk + +%mdk-data-line={3159} +\item\mdline{3159}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3159}: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value.%mdk + +%mdk-data-line={3162} +\item\mdline{3162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3162}: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +\mdline{3164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3164} value.%mdk + +%mdk-data-line={3165} +\item\mdline{3165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3165}: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided \mdline{3167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3167} value.%mdk + +%mdk-data-line={3168} +\item\mdline{3168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3168}: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3172} +\noindent\mdline{3172}For example, in order to read all entries from all tables from device 3, the +client can use the following \mdline{3173}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3173} message.%mdk + +%mdk-data-line={3175} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3176} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0}\\ +~~~~priority:~{\mdcolor{purple}0}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3187} +\noindent\mdline{3187}In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following \mdline{3188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3188} +message:%mdk + +%mdk-data-line={3191} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3192} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~priority:~{\mdcolor{purple}11}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3203} +\noindent\mdline{3203}The canonical representation of \mdline{3203}\textquotedblleft{}don't care\textquotedblright{}\mdline{3203} matches, combined with the ability +to do a wildcard read on all table entries by leaving the \mdline{3204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3204} field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single \mdline{3206}\textquotedblleft{}don't care\textquotedblright{}\mdline{3206} entry or to do a wildcard +read. If a table has no fields with match kind \mdline{3207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3207}, it is possible via +P4Runtime to add an entry that is \mdline{3208}\textquotedblleft{}don't care\textquotedblright{}\mdline{3208} for all fields (\mdline{3208}i.e.\mdline{3208} has an empty +\mdline{3209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3209} field) but is not the default entry (\mdline{3209}i.e.\mdline{3209} \mdline{3209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3209} is +false). When reading this entry from the table, there is no way to read \mdline{3210}\emph{only}\mdline{3210} +that entry from the table, because it would require providing an unset \mdline{3211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3211} +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single \mdline{3214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{3214} match:%mdk + +%mdk-data-line={3216} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3217} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;~fwd;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3227} +\noindent\mdline{3227}The following \mdline{3227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3227} message can be used to add 2 entries:%mdk + +%mdk-data-line={3228} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3229} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{~{\mdcolor{darkgreen}\#~don't~care~entry}\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +~~table~entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~match~\{\\ +~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~lpm~\{\\ +~~~~~~~~value:~{\mdcolor{purple}0x0a000000}\\ +~~~~~~~~prefix\_len:~{\mdcolor{purple}8}\\ +~~~~~~\}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3248} +\noindent\mdline{3248}The first entry is a \mdline{3248}\textquotedblleft{}don't care\textquotedblright{}\mdline{3248} entry, while the second one matches all +\mdline{3249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}10.0.0.0/8}}}\mdline{3249} addresses. The second entry has higher priority than the first one.%mdk + +%mdk-data-line={3251} +\mdline{3251}The following \mdline{3251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3251} message will return \mdline{3251}\emph{all}\mdline{3251} entries in the table, not +just the \mdline{3252}\textquotedblleft{}don't care\textquotedblright{}\mdline{3252} entry.%mdk + +%mdk-data-line={3253} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3254} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3262} +\noindent\mdline{3262}This issue also exists for tables with \mdline{3262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3262}, \mdline{3262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3262}, and \mdline{3262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3262} +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the \mdline{3265}\textquotedblleft{}don't care\textquotedblright{}\mdline{3265} entry will be returned to the +client. If the client uses distinct priority values for all entries\mdline{3266} \mdline{3266}\textemdash{}\mdline{3266} which is +strongly recommended to achieve\mdline{3267}~\mdref{sec-table-entry}{deterministic behavior}\mdline{3267} \mdline{3267}\textemdash{}\mdline{3267}, +then there is no ambiguity because the wildcard read will actually return a +single entry (the \mdline{3269}\textquotedblleft{}don't care\textquotedblright{}\mdline{3269} entry) as long as the \mdline{3269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3269} field is set to +the correct value.%mdk + +%mdk-data-line={3272} +\subsubsection{\mdline{3272}9.1.6.\hspace*{0.5em}\mdline{3272}Direct Resources}\label{sec-direct-resources}%mdk%mdk + +%mdk-data-line={3274} +\noindent\mdline{3274}In addition to the \mdline{3274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3274} and \mdline{3274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3274} entities, +P4Runtime support reading and writing direct resources as part of the +\mdline{3276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3276} message. This is convenient for two reasons:%mdk + +%mdk-data-line={3278} +\begin{itemize}%mdk + +%mdk-data-line={3278} +\item{} +%mdk-data-line={3278} +\mdline{3278}A table entry and its direct resources can be read with a single entity when +doing a \mdline{3279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{3279} RPC call%mdk%mdk + +%mdk-data-line={3281} +\item{} +%mdk-data-line={3281} +\mdline{3281}The initial configuration for an entry\mdline{3281}'\mdline{3281}s direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can \mdline{3286}\textquotedblleft{}hit\textquotedblright{}\mdline{3286} the table entry without +executing the appropriate meter entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3289} +\noindent\mdline{3289}Once the table entry has been inserted, the P4Runtime client is free to use the +\mdline{3290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3290} and \mdline{3290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3290} messages for read and write +operations on \mdline{3291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3291} and \mdline{3291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3291} instances. For example, it is +usually more convenient as well as more efficient to use \mdline{3292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3292} to +query a counter entry value rather than use \mdline{3293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3293}, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry.%mdk + +%mdk-data-line={3297} +\mdline{3297}The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does \mdline{3298}\emph{not}\mdline{3298} need to be \mdline{3298}\textquotedblleft{}executed\textquotedblright{}\mdline{3298} in +every action bound to the table. It is an error to provide a direct resource +configuration in a \mdline{3300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3300} message when programming an action that does not +execute the direct resource, and the server must return an \mdline{3301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3301} +error code.%mdk + +%mdk-data-line={3304} +\mdline{3304}We leverage Protobuf\mdline{3304}'\mdline{3304}s ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the \mdline{3306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3306} message. The list below describes how +the server must handle the \mdline{3307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3307} and \mdline{3307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3307} fields for read and +write requests, based on whether the fields are set or not. We do not cover +error cases in the list, \mdline{3309}i.e.\mdline{3309} we assume that we are dealing with a table which +is assigned a direct counter / a direct meter, and that the action being used +for the table entry \mdline{3311}\textquotedblleft{}executes\textquotedblright{}\mdline{3311} the direct resource appropriately.%mdk + +%mdk-data-line={3313} +\begin{itemize}%mdk + +%mdk-data-line={3313} +\item{} +%mdk-data-line={3313} +\mdline{3313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3313} field%mdk + +%mdk-data-line={3314} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3314} +\item\mdline{3314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3314} + +%mdk-data-line={3315} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3315} +\item\mdline{3315}if \mdline{3315}\textbf{unset}\mdline{3315}: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets).%mdk + +%mdk-data-line={3317} +\item\mdline{3317}if \mdline{3317}\textbf{set}\mdline{3317}: The initial configuration for the meter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3319} +\item\mdline{3319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3319} + +%mdk-data-line={3320} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3320} +\item\mdline{3320}if \mdline{3320}\textbf{unset}\mdline{3320}: The meter entry\mdline{3320}'\mdline{3320}s configuration is reset to the default +(meter returns GREEN for all packets).%mdk + +%mdk-data-line={3322} +\item\mdline{3322}if \mdline{3322}\textbf{set}\mdline{3322}: The value provided by the client is used to re-configure +the meter entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3324} +\item\mdline{3324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3324} + +%mdk-data-line={3325} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3325} +\item\mdline{3325}if \mdline{3325}\textbf{unset}\mdline{3325}: The response does not include the meter entry\mdline{3325}'\mdline{3325}s +configuration (\mdline{3326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3326} is unset in the response).%mdk + +%mdk-data-line={3327} +\item\mdline{3327}if \mdline{3327}\textbf{set}\mdline{3327}: If the meter entry\mdline{3327}'\mdline{3327}s configuration is the default +configuration, \mdline{3328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3328} is unset in the response. Otherwise, the +response includes the meter entry\mdline{3329}'\mdline{3329}s configuration that was written by +the client earlier. This respects the \mdline{3330}\textquotedblleft{}read-write symmetry\textquotedblright{}\mdline{3330} principle.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3332} +\item{} +%mdk-data-line={3332} +\mdline{3332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3332} field%mdk + +%mdk-data-line={3333} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3333} +\item\mdline{3333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3333} + +%mdk-data-line={3334} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3334} +\item\mdline{3334}if \mdline{3334}\textbf{unset}\mdline{3334}: The initial value for the counter entry is the default +(0).%mdk + +%mdk-data-line={3336} +\item\mdline{3336}if \mdline{3336}\textbf{set}\mdline{3336}: The initial value for the counter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3338} +\item\mdline{3338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3338} + +%mdk-data-line={3339} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3339} +\item\mdline{3339}if \mdline{3339}\textbf{unset}\mdline{3339}: The counter entry\mdline{3339}'\mdline{3339}s value is not changed.%mdk + +%mdk-data-line={3340} +\item\mdline{3340}if \mdline{3340}\textbf{set}\mdline{3340}: The value provided by the client is written to the counter +entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3342} +\item\mdline{3342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3342} + +%mdk-data-line={3343} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3343} +\item\mdline{3343}if \mdline{3343}\textbf{unset}\mdline{3343}: The response does not include the counter entry\mdline{3343}'\mdline{3343}s value +(\mdline{3344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3344} is unset in the response).%mdk + +%mdk-data-line={3345} +\item\mdline{3345}if \mdline{3345}\textbf{set}\mdline{3345}: The response includes the counter entry\mdline{3345}'\mdline{3345}s value read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3348} +\noindent\mdline{3348}In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +\mdline{3350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3350} field unset when inserting \mdline{3350}\textbf{or modifying}\mdline{3350} a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the \mdline{3352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3352} message +(\mdline{3353}i.e.\mdline{3353} the \mdline{3353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3353} field must be set to match the existing configuration).%mdk + +%mdk-data-line={3355} +\subsubsection{\mdline{3355}9.1.7.\hspace*{0.5em}\mdline{3355}Idle-timeout}\label{sec-idle-timeout}%mdk%mdk + +%mdk-data-line={3357} +\noindent\mdline{3357}P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not \mdline{3359}\textquotedblleft{}hit\textquotedblright{}\mdline{3359} (\mdline{3359}i.e.\mdline{3359} not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification\mdline{3361} \mdline{3361}\textemdash{}\mdline{3361} using the +\mdline{3362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3362} message\mdline{3362} \mdline{3362}\textemdash{}\mdline{3362} to the master client, which can then take +action, such as remove the idle table entry.%mdk + +%mdk-data-line={3365} +\mdline{3365}Two fields of the \mdline{3365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3365} Protobuf message are used to implement idle +timeout:%mdk + +%mdk-data-line={3368} +\begin{itemize}%mdk + +%mdk-data-line={3368} +\item{} +%mdk-data-line={3368} +\mdline{3368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3368}: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, \mdline{3369}i.e.\mdline{3369} no +\mdline{3370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3370} message will ever be generated for this entry. When +a client reads a \mdline{3371}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3371}, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry.%mdk%mdk + +%mdk-data-line={3375} +\item{} +%mdk-data-line={3375} +\mdline{3375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3375}: a Protobuf message with a single field (\mdline{3375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{3375}) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The \mdline{3377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3377} field must be unset for a +\mdline{3378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3378} write. When reading a table entry, \mdline{3378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3378} must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3383} +\noindent\mdline{3383}These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an \mdline{3385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3385} error code if at least one of these +conditions is met:%mdk + +%mdk-data-line={3388} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3388} +\item\mdline{3388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3388} is set to a non-zero value, or%mdk + +%mdk-data-line={3389} +\item\mdline{3389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3389} is set%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3391} +\noindent\mdline{3391}The target should do its best to approximate the \mdline{3391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3391} value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the \mdline{3394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3394} write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for \mdline{3396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3396}.%mdk + +%mdk-data-line={3398} +\mdline{3398}P4Runtime does not support idle timeout for default entries. When the +\mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3399} flag is set in a \mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3399} message, \mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3399} +must be set to 0 (default) and \mdline{3400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3400} must be unset. If the +server receives a \mdline{3401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3401} message which violates this, it must return an +\mdline{3402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3402} error.%mdk + +%mdk-data-line={3404} +\mdline{3404}For more information about idle timeout, in particular regarding +\mdline{3405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3405}, please refer to the\mdline{3405}~\mdref{sec-table-idle-timeout-notification}{Table idle timeout +notifications}\mdline{3406} section.%mdk + +%mdk-data-line={3408} +\subsection{\mdline{3408}9.2.\hspace*{0.5em}\mdline{3408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3408} \mdline{3408}\&\mdline{3408} \mdline{3408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}\label{sec-action-profile-member-and-group}%mdk%mdk + +%mdk-data-line={3410} +\noindent\mdline{3410}P4Runtime defines an API for programming a PSA ActionProfile extern using +\mdline{3411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3411} messages. A PSA ActionSelector extern can be programmed +using both \mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3412} and \mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3412} messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table \mdline{3416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3416} for L3 routing, implemented with an action +selector \mdline{3417}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3417}.%mdk + +%mdk-data-line={3419} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3420} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector(HashAlgorithm.crc32,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}size~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w1024,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}output\_width~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w10)~as;\\ +\\ +{\bfseries{\mdcolor{navy}action}}~set\_nhop(PortId\_t~p,~EthAddr~smac,~EthAddr~dmac)~\{\\ +~~istd.egress\_port~=~p;\\ +~~hdr.ethernet.smac~=~smac;\\ +~~hdr.ethernet.dmac~=~dmac;\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;~~{\mdcolor{darkgreen}//~LPM~on~destination~IP~address}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~set\_nhop;\\ +~~\}\\ +~~implementation~=~as;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3441} +\noindent\mdline{3441}When programming table \mdline{3441}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3441} in the example above, a P4Runtime client should +specify the \mdline{3442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3442} in the \mdline{3442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3442} to be a reference to either an +action profile member or group. The reference is a non-zero \mdline{3443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3443} identifier +that uniquely identifies a member or group programmed in the action selector +\mdline{3445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3445}.%mdk + +%mdk-data-line={3447} +\mdline{3447}If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata.%mdk + +%mdk-data-line={3452} +\mdline{3452}If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata.%mdk + +%mdk-data-line={3463} +\subsubsection{\mdline{3463}9.2.1.\hspace*{0.5em}\mdline{3463}Action Profile Member Programming}\label{sec-action-profile-member-programming}%mdk%mdk + +%mdk-data-line={3465} +\noindent\mdline{3465}Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a \mdline{3466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3466} identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the \mdline{3468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3468} +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the \mdline{3470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3470} attributes of the +tables \mdline{3471}\emph{must have an identical list of P4 actions}\mdline{3471}. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector.%mdk + +%mdk-data-line={3475} +\mdline{3475}An \mdline{3475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3475} entity update message has the following fields:%mdk + +%mdk-data-line={3477} +\begin{itemize}%mdk + +%mdk-data-line={3477} +\item{} +%mdk-data-line={3477} +\mdline{3477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3477} is the \mdline{3477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3477} identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3480} +\item{} +%mdk-data-line={3480} +\mdline{3480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3480} is the non-zero \mdline{3480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3480} identifier of the action profile member +entry being updated.%mdk%mdk + +%mdk-data-line={3483} +\item{} +%mdk-data-line={3483} +\mdline{3483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3483} is the specification of the P4 action instance bound to the action +profile member entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3486} +\noindent\mdline{3486}An action profile member may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3489} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3489} +\item\mdline{3489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3489}: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an \mdline{3491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3491} error +code. The action specification must be provided, or the server must return +\mdline{3493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3493}. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return \mdline{3495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3495}.%mdk + +%mdk-data-line={3496} +\item\mdline{3496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3496}: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return \mdline{3497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3497}, +and the action specification must be provided, or the server must return +\mdline{3499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3499}.%mdk + +%mdk-data-line={3500} +\item\mdline{3500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3500}: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a \mdline{3501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3501} error code. The member +must not be part of an action profile group, or the server must return +\mdline{3503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3503}. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return \mdline{3506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3506}. \mdline{3506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3506} and \mdline{3506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3506} are the only +fields that are considered when performing a \mdline{3507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3507} and every other field +will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3510} +\noindent\mdline{3510}When reading, an \mdline{3510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3510} message with \mdline{3510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3510} and +\mdline{3511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3511} equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with \mdline{3512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3512} equal to the id of +an existing ActionProfile or ActionSelector object, and a \mdline{3513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3513} equal to +0, will read all members of that specified object.%mdk + +%mdk-data-line={3516} +\subsubsection{\mdline{3516}9.2.2.\hspace*{0.5em}\mdline{3516}Action Profile Group Programming}\label{sec-action-profile-group-programming}%mdk%mdk + +%mdk-data-line={3518} +\noindent\mdline{3518}Action profile groups are entries in an ActionSelector and are referenced by a +\mdline{3519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3519} identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type.%mdk + +%mdk-data-line={3523} +\mdline{3523}Within a single ActionSelector object, the \mdline{3523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3523} values used to identify its +members are in a separate \mdline{3524}\textquoteleft{}scope\textquoteright{}\mdline{3524} from the \mdline{3524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3524} values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5.%mdk + +%mdk-data-line={3528} +\mdline{3528}There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it.%mdk + +%mdk-data-line={3534} +\mdline{3534}An \mdline{3534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3534} entity update message has the following fields:%mdk + +%mdk-data-line={3536} +\begin{itemize}%mdk + +%mdk-data-line={3536} +\item{} +%mdk-data-line={3536} +\mdline{3536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3536} is the \mdline{3536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3536} identifier of the PSA ActionSelector +extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3539} +\item{} +%mdk-data-line={3539} +\mdline{3539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3539} is the non-zero \mdline{3539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3539} identifier of the action profile group +entry being updated.%mdk%mdk + +%mdk-data-line={3542} +\item{} +%mdk-data-line={3542} +\mdline{3542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3542} is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields:%mdk + +%mdk-data-line={3545} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3545} +\item\mdline{3545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3545} for looking up the member table in the selector.%mdk + +%mdk-data-line={3546} +\item\mdline{3546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3546} specifying the probability of the member\mdline{3546}'\mdline{3546}s selection at +runtime. 0 is not a valid \mdline{3547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3547} value and the server must return +\mdline{3548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3548} if the client attempts to use it.%mdk + +%mdk-data-line={3549} +\item\mdline{3549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3549} is the controller-defined 32-bit port number that the member\mdline{3549}'\mdline{3549}s +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +\mdline{3552}\mdref{action-selector-constraints}{9.2.4}\mdline{3552} for notes on the behavior if all members in +a group are excluded for this reason. If \mdline{3553}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3553} is 0, then the member is +always included in the selection, regardless of the status of any port of +the device. The value must be 0 or the SDN port number of an existing +port on the device, otherwise the server must return \mdline{3556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3556}.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3558} +\item{} +%mdk-data-line={3558} +\mdline{3558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3558} is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +\mdline{3560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3560} update. See the subsection below for the\mdline{3560}~\mdref{sec-max-size-rules}{rules on setting +\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\mdline{3561}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3563} +\noindent\mdline{3563}An action profile group may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3566} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3566} +\item\mdline{3566}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3566}: Add a new group entry bound to a set of existing action profile +members. \mdline{3567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}The~group\_id}}}\mdline{3567} must be different from ids of already programmed +groups for that selector, or the server must return an \mdline{3568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3568} error +code. All members specified in the group must exist in the selector, or the +server must return \mdline{3570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3570}. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target.%mdk + +%mdk-data-line={3572} +\item\mdline{3572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3572}: Modify the member set specification of an existing group entry. An +entry with the \mdline{3573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3573} must exist, or the server must return +\mdline{3574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3574}. All members specified in the group entry must exist in the +selector, or the server must return \mdline{3575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3575}. The value of \mdline{3575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3575} must +be identical to the value used when inserting the group, otherwise an +\mdline{3577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3577} error is returned.%mdk + +%mdk-data-line={3578} +\item\mdline{3578}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3578}: Delete the group entry and deallocate the \mdline{3578}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3578}. The group must +not be referenced in the table action of any table entry, or the server must +return a \mdline{3580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3580} error code. If the \mdline{3580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3580} is invalid, the +server must return \mdline{3581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3581}. \mdline{3581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3581} and \mdline{3581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3581} are the +only fields that are considered when performing a \mdline{3582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3582} and every other +field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3585} +\noindent\mdline{3585}When setting the group membership with \mdline{3585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3585} or \mdline{3585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3585}, the \mdline{3585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3585} +repeated field must not include duplicates, \mdline{3586}i.e.\mdline{3586} members with the same +\mdline{3587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3587}. The \mdline{3587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3587} field is used instead to logically \mdline{3587}\textquotedblleft{}repeat\textquotedblright{}\mdline{3587} the member +inside the group.%mdk + +%mdk-data-line={3590} +\mdline{3590}It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation \mdline{3591}\textquotedblleft{}stores\textquotedblright{}\mdline{3591} the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made.%mdk + +%mdk-data-line={3595} +\mdline{3595}When reading, an \mdline{3595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3595} message with \mdline{3595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3595} and +\mdline{3596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3596} equal to 0 will read all groups of all ActionSelector objects. A +message with \mdline{3597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3597} equal to the id of an existing ActionSelector +object, and a \mdline{3598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3598} equal to 0, will read all groups of that one specified +object.%mdk + +%mdk-data-line={3601} +\paragraph{\mdline{3601}9.2.2.1.\hspace*{0.5em}\mdline{3601}Rules on Setting \mdline{3601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\label{sec-max-size-rules}%mdk%mdk + +%mdk-data-line={3603} +\noindent\mdline{3603}The valid values for \mdline{3603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3603} depend on the static \mdline{3603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3603} included +in the P4Info message:%mdk + +%mdk-data-line={3606} +\begin{itemize}%mdk + +%mdk-data-line={3606} +\item{} +%mdk-data-line={3606} +\mdline{3606}If \mdline{3606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3606} is greater than 0, then \mdline{3606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3606} must be greater than 0, +and less than or equal to \mdline{3607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3607}. We assume that the target can +support selector groups for which the sum of all member weights is up to +\mdline{3609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3609}, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If \mdline{3610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3610} is greater than \mdline{3610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3610}, the server +must return \mdline{3611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3611}.%mdk%mdk + +%mdk-data-line={3613} +\item{} +%mdk-data-line={3613} +\mdline{3613}Otherwise (\mdline{3613}i.e.\mdline{3613} if \mdline{3613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3613} is 0), the P4Runtime client can set +\mdline{3614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3614} to any value greater than or equal to 0.%mdk + +%mdk-data-line={3616} +\begin{itemize}%mdk + +%mdk-data-line={3616} +\item{} +%mdk-data-line={3616} +\mdline{3616}A \mdline{3616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3616} of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (\mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3619} or \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3619}), the target must return a +\mdline{3620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3620} error.%mdk%mdk + +%mdk-data-line={3622} +\item{} +%mdk-data-line={3622} +\mdline{3622}If \mdline{3622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3622} is greater than 0 and the value is not supported by the +target, the server must return a \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3623} error at +group-creation time.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3626} +\subsubsection{\mdline{3626}9.2.3.\hspace*{0.5em}\mdline{3626}One Shot Action Selector Programming}\label{sec-oneshot}%mdk%mdk + +%mdk-data-line={3628} +\noindent\mdline{3628}P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids.%mdk + +%mdk-data-line={3634} +\mdline{3634}One shots are programmed by choosing the \mdline{3634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3634} message as the +\mdline{3635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3635}. The \mdline{3635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3635} message consists of a set of +\mdline{3636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3636} messages, which in turn have the following fields:%mdk + +%mdk-data-line={3638} +\begin{itemize}%mdk + +%mdk-data-line={3638} +\item{} +%mdk-data-line={3638} +\mdline{3638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3638} is one of the actions specified by the table that is being +programmed.%mdk%mdk + +%mdk-data-line={3641} +\item{} +%mdk-data-line={3641} +\mdline{3641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3641} specifying the probability of the action\mdline{3641}'\mdline{3641}s selection at runtime. 0 is +not a valid \mdline{3642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3642} value and the server must return \mdline{3642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3642} if +the client attempts to use it. The sum of all weights across all +\mdline{3644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3644} messages for that \mdline{3644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3644} message must +not exceed the \mdline{3645}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3645} specificed in the P4Info (if greater than 0), +or the server must return \mdline{3646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3646}.%mdk%mdk + +%mdk-data-line={3648} +\item{} +%mdk-data-line={3648} +\mdline{3648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3648} is the controller-defined 32-bit port number that the action\mdline{3648}'\mdline{3648}s +liveness depends on. At runtime, the action must be excluded from selection if +the watch port is down. See Section +\mdline{3651}\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{3651} for more details on the \mdline{3651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3651} field, +which also apply for one shot action selector programming.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3655} +\noindent\mdline{3655}Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics.%mdk + +%mdk-data-line={3660} +\mdline{3660}To preserve read-write symmetry, an implementation must answer \mdline{3660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3660}s +with the original one shot messages. It may not return a desugared version of +the one shot message.%mdk + +%mdk-data-line={3664} +\mdline{3664}For example, consider the action selector table defined +\mdline{3665}\mdref{sec-action-profile-member-and-group}{here}\mdline{3665}. This table could be programmed +with the following one shot update:%mdk + +%mdk-data-line={3668} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3669} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{\\ +~~~~action\_profile\_action\_set~\{\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}1}\\ +~~~~~~~~watch:~{\mdcolor{purple}1}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}2}\\ +~~~~~~~~watch:~{\mdcolor{purple}2}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}3}\\ +~~~~~~~~watch:~{\mdcolor{purple}3}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3694} +\noindent\mdline{3694}Which would be equivalent to the following updates, where \mdline{3694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GROUP\_ID}}}\mdline{3694}, +\mdline{3695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_1}}}\mdline{3695}, \mdline{3695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_2}}}\mdline{3695}, and \mdline{3695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_3}}}\mdline{3695} are unused ids:%mdk + +%mdk-data-line={3697} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3698} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_1\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_2\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_3\\ +~~action~\{~~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +\}\\ +action\_profile\_group~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~group\_id:~GROUP\_ID\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_1\\ +~~~~weight:~{\mdcolor{purple}1}\\ +~~~~watch:~{\mdcolor{purple}1}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_2\\ +~~~~weight:~{\mdcolor{purple}2}\\ +~~~~watch:~{\mdcolor{purple}2}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_3\\ +~~~~weight:~{\mdcolor{purple}3}\\ +~~~~watch:~{\mdcolor{purple}3}\\ +~~\}\\ +\}\\ +table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{~action\_profile\_group\_id:~GROUP\_ID~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3739} +\noindent\mdline{3739}Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure\mdline{3740}~\mdref{sec-batching-and-ordering-of-updates}{correct ordering between the dependent +updates}\mdline{3741}. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct \mdline{3743}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3743} batches are required.%mdk + +%mdk-data-line={3745} +\mdline{3745}It is possible to include several \mdline{3745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3745} messages with the same +exact \mdline{3746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3746} specification in one \mdline{3746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3746} message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the \mdline{3748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3748} field. Note that to preserve read-write symmetry, the server +must not coalesce multiple \mdline{3749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3749} messages with the same \mdline{3749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3749} +specification into one.%mdk + +%mdk-data-line={3752} +\mdline{3752}All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with \mdline{3753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3753} and +\mdline{3754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3754} messages. Programming some entries with one shots, and +other entries with \mdline{3755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3755} and \mdline{3755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3755} messages is +not allowed, and the server must return the error code \mdline{3756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3756} in +that case.%mdk + +%mdk-data-line={3759} +\mdline{3759}A P4Runtime server \mdline{3759}\emph{must}\mdline{3759} support the one shot style of programming tables with +an action selector implementation. Support for the \mdline{3760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3760} and +\mdline{3761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3761} style is \mdline{3761}\emph{optional}\mdline{3761}. If \mdline{3761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3761} and +\mdline{3762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3762} are not supported by a server, it must return an +\mdline{3763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3763} error for every \mdline{3763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3763} or \mdline{3763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3763} +message that it receives.%mdk + +%mdk-data-line={3766} +\subsubsection{\mdline{3766}9.2.4.\hspace*{0.5em}\mdline{3766}Constraints on action selector programming}\label{action-selector-constraints}%mdk%mdk + +%mdk-data-line={3768} +\noindent\mdline{3768}The PSA specification states that the following features are \mdline{3768}\emph{optional}\mdline{3768} in +action selector implementations\mdline{3769}~[\mdcite{psaactionselector}{22}]\mdline{3769}:%mdk + +%mdk-data-line={3771} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3771} +\item\mdline{3771}Support for non-empty groups where in the same group, different members are +bound to different actions.%mdk + +%mdk-data-line={3773} +\item\mdline{3773}Predictable data plane behavior when a matched table entry points to an empty +group.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={3776} +\noindent\mdline{3776}For 1., if a client tries to \mdline{3776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3776} or \mdline{3776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3776} a group with members bound to +different actions, the server should return \mdline{3777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3777} if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return \mdline{3783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3783} (modifying the action parameter values must be +supported, however).%mdk + +%mdk-data-line={3786} +\mdline{3786}PSA 1.1 introduces the \mdline{3786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3786} table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. \mdline{3790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3790} is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of \mdline{3793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3793} at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +\mdline{3795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3795}. Even when \mdline{3795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3795} is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of \mdline{3799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3799} mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming.%mdk + +%mdk-data-line={3804} +\mdline{3804}The PSA specification includes a discussion on how to implement +\mdline{3805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3805} in software in the P4Runtime server +\mdline{3806}[\mdcite{psaemptygroupactionappendix}{25}]\mdline{3806}.%mdk + +%mdk-data-line={3808} +\mdline{3808}If a P4Runtime implementation does support \mdline{3808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3808}, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down.%mdk + +%mdk-data-line={3812} +\mdline{3812}If a P4Runtime implementation does not support \mdline{3812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3812}, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down.%mdk + +%mdk-data-line={3818} +\subsection{\mdline{3818}9.3.\hspace*{0.5em}\mdline{3818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3818} \mdline{3818}\&\mdline{3818} \mdline{3818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-counterentry-directcounterentry}%mdk%mdk + +%mdk-data-line={3820} +\noindent\mdline{3820}PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The \mdline{3822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3822} +P4Runtime message can be used for all three types of PSA counters\mdline{3823} \mdline{3823}\textemdash{}\mdline{3823} \mdline{3823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{3823}, +\mdline{3824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{3824} and \mdline{3824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3824} \mdline{3824}\textemdash{}\mdline{3824} and consists of the following fields:%mdk + +%mdk-data-line={3826} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3826} +\item\mdline{3826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3826} is an \mdline{3826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3826}, corresponding to the number of octets.%mdk + +%mdk-data-line={3827} +\item\mdline{3827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3827} is an \mdline{3827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3827}, corresponding to the number of packets.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3829} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3830} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterData~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~byte\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}int64}}~packet\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3836} +\noindent\mdline{3836}P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of \mdline{3837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3837} and \mdline{3837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3837} fields, which +is equivalent to specifying the counter type \mdline{3838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3838}. Counters may +be defined as direct or indirect (indexed) instances.%mdk + +%mdk-data-line={3841} +\subsubsection{\mdline{3841}9.3.1.\hspace*{0.5em}\mdline{3841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-directcounterentry}%mdk%mdk + +%mdk-data-line={3843} +\noindent\mdline{3843}A direct counter is a direct resource associated with a \mdline{3843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3843} (see +\mdline{3844}\mdref{sec-direct-resources}{Direct Resources}\mdline{3844}). The \mdline{3844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3844} field of the +\mdline{3845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3845} message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +\mdline{3848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3848} message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed.%mdk + +%mdk-data-line={3851} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3852} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectCounterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3858} +\noindent\mdline{3858}A \mdline{3858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3858} may only include an \mdline{3858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3858} message of type \mdline{3858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3858} with a +\mdline{3859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3859}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3861} +\begin{itemize}%mdk + +%mdk-data-line={3861} +\item{} +%mdk-data-line={3861} +\mdline{3861}the \mdline{3861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3861} field must match \mdline{3861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry.match}}}\mdline{3861} of the table entry +to which this direct counter entry is associated. If a matching \mdline{3862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3862} +is not found, the server returns the error code \mdline{3863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3863}.%mdk%mdk + +%mdk-data-line={3865} +\item{} +%mdk-data-line={3865} +\mdline{3865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3865} is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3869} +\noindent\mdline{3869}Specifying \mdline{3869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3869} in an \mdline{3869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3869} message of type \mdline{3869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3869} or +\mdline{3870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3870} is not allowed, and the server must return the error code +\mdline{3871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3871} in that case.%mdk + +%mdk-data-line={3873} +\mdline{3873}A client may use \mdline{3873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3873} in two ways to read the contents of a +\mdline{3874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3874}:%mdk + +%mdk-data-line={3876} +\begin{itemize}%mdk + +%mdk-data-line={3876} +\item{} +%mdk-data-line={3876} +\mdline{3876}As a direct resource associated with a table entry, request the server to +return the counter value in the \mdline{3877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3877} field of the \mdline{3877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3877} message +(see\mdline{3878}~\mdref{sec-direct-resources}{Direct resources}\mdline{3878}).%mdk%mdk + +%mdk-data-line={3880} +\item{} +%mdk-data-line={3880} +\mdline{3880}Explicitly request the counter value by including the \mdline{3880}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3880} in +the \mdline{3881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3881}. The \mdline{3881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3881} field must match the \mdline{3881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3881} +whose counter is being read. If no such entry is found, the server returns the +error code \mdline{3883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3883}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3885} +\subsubsection{\mdline{3885}9.3.2.\hspace*{0.5em}\mdline{3885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}\label{sec-counterentry}%mdk%mdk + +%mdk-data-line={3887} +\noindent\mdline{3887}An indirect or indexed counter is not associated with a specific \mdline{3887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3887} +and may be updated independently of any action. It may be read or written using +the P4Runtime \mdline{3889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3889} message whose fields are defined as follows:%mdk + +%mdk-data-line={3891} +\begin{itemize}%mdk + +%mdk-data-line={3891} +\item{} +%mdk-data-line={3891} +\mdline{3891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3891} is a \mdline{3891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3891}, the unique identifier for the counter.%mdk%mdk + +%mdk-data-line={3893} +\item{} +%mdk-data-line={3893} +\mdline{3893}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3893} is a Protobuf message that encapsulates an \mdline{3893}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3893}, used to index into +the counter array.%mdk%mdk + +%mdk-data-line={3896} +\item{} +%mdk-data-line={3896} +\mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3896} is a Protobuf message of type \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3896}, which represents the +counter value.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3899} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3900} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~counter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3907} +\noindent\mdline{3907}The \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3907} can only be used in a \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3907} with the \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3907} update +type. The P4Runtime server must return an \mdline{3908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3908} error code for +update types \mdline{3909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3909} and \mdline{3909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3909}. By default all the counter entries in the +array have default value 0.%mdk + +%mdk-data-line={3912} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3912} +\item\mdline{3912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3912}: Server returns the error code \mdline{3912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3912}.%mdk + +%mdk-data-line={3913} +\item\mdline{3913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3913}: Modify an indirect counter instance whose unique id is \mdline{3913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3913} +and array index is specified by \mdline{3914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3914}. The counter value is set to the value +specified by the client in the \mdline{3915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3915} field. Note that the counter value is +not modified if this Protobuf field is not set. If \mdline{3916}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3916} is omitted all +counter values in the array will be set to the value provided by the +client. The server must return \mdline{3918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3918} for a negative index value +and \mdline{3919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3919} if the index value exceeds the size of the counter array.%mdk + +%mdk-data-line={3920} +\item\mdline{3920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3920}: Server returns the error code \mdline{3920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3920}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3922} +\noindent\mdline{3922}A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a \mdline{3923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3923} by including a \mdline{3923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3923} +entity for each of the instances, specifying the \mdline{3924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3924} and +\mdline{3925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3925}. Wildcard reads are also supported as follows.%mdk + +%mdk-data-line={3927} +\begin{itemize}%mdk + +%mdk-data-line={3927} +\item{} +%mdk-data-line={3927} +\mdline{3927}If the \mdline{3927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3927} field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the \mdline{3928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3928}.%mdk%mdk + +%mdk-data-line={3930} +\item{} +%mdk-data-line={3930} +\mdline{3930}If the \mdline{3930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3930} field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id \mdline{3931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3931}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3933} +\subsection{\mdline{3933}9.4.\hspace*{0.5em}\mdline{3933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3933} \mdline{3933}\&\mdline{3933} \mdline{3933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-meterentry-directmeterentry}%mdk%mdk + +%mdk-data-line={3935} +\noindent\mdline{3935}Meters are an advanced mechanism for keeping statistics, involving stateful +\mdline{3936}\textquotedblleft{}marking\textquotedblright{}\mdline{3936} and usually \mdline{3936}\textquotedblleft{}throttling\textquotedblright{}\mdline{3936} of packets based on configured rates of +traffic. The PSA metering function is based on the \mdline{3937}\emph{Two Rate Three Color Marker}\mdline{3937} +(trTCM) defined in RFC 2698\mdline{3938}~[\mdcite{rfc2698}{2}]\mdline{3938}. The trTCM meters an arbitrary packet +stream using two configured rates\mdline{3939} \mdline{3939}\textemdash{}\mdline{3939} the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes\mdline{3940} \mdline{3940}\textemdash{}\mdline{3940} and +\mdline{3941}\textquotedblleft{}marks\textquotedblright{}\mdline{3941} its packets as GREEN, YELLOW or RED based on the observed rate.%mdk + +%mdk-data-line={3943} +\mdline{3943}A meter may be configured as a direct or indirect instance, similar to a +counter. The \mdline{3944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{3944} P4Runtime message represents meter configuration.%mdk + +%mdk-data-line={3946} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3947} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterConfig~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~cir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~Committed~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~cburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};~~{\mdcolor{darkgreen}//~Committed~Burst~Size}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};~~{\mdcolor{darkgreen}//~Peak~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};~~{\mdcolor{darkgreen}//~Peak~Burst~Size}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3955} +\subsubsection{\mdline{3955}9.4.1.\hspace*{0.5em}\mdline{3955}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-directmeterentry}%mdk%mdk + +%mdk-data-line={3957} +\noindent\mdline{3957}A direct meter is a direct resource associated with a \mdline{3957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3957} (see\mdline{3957}~\mdref{sec-direct-resources}{Direct +resources}\mdline{3958}). The \mdline{3958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3958} field of the \mdline{3958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3958} +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +\mdline{3962}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3962} message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed.%mdk + +%mdk-data-line={3965} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3966} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectMeterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3972} +\noindent\mdline{3972}A \mdline{3972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3972} may only include an \mdline{3972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3972} message of type \mdline{3972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3972} with a +\mdline{3973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3973}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3975} +\begin{itemize}%mdk + +%mdk-data-line={3975} +\item{} +%mdk-data-line={3975} +\mdline{3975}the \mdline{3975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3975} field must match the match key of the \mdline{3975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3975} +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching \mdline{3977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3977} is not found, +the server returns the error code \mdline{3978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3978}.%mdk%mdk + +%mdk-data-line={3980} +\item{} +%mdk-data-line={3980} +\mdline{3980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3980} is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3984} +\noindent\mdline{3984}Specifying \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3984} in an \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3984} message of type \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3984} or +\mdline{3985}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3985} is not allowed, and the server must return the error code +\mdline{3986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3986} in that case.%mdk + +%mdk-data-line={3988} +\mdline{3988}A client may use \mdline{3988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3988} in two ways to read a \mdline{3988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3988} config.%mdk + +%mdk-data-line={3990} +\begin{itemize}%mdk + +%mdk-data-line={3990} +\item{} +%mdk-data-line={3990} +\mdline{3990}As a direct resource associated with a table entry, request the server to +return the meter config in the \mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3991} field of the \mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3991} +message (see\mdline{3992}~\mdref{sec-direct-resources}{Direct resources}\mdline{3992}).%mdk%mdk + +%mdk-data-line={3994} +\item{} +%mdk-data-line={3994} +\mdline{3994}Explicitly request the meter configuration by including the \mdline{3994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3994} +in the \mdline{3995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3995}. The \mdline{3995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3995} field must match the +\mdline{3996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3996} whose meter config is being read. If no such entry is found, the +server returns the error code \mdline{3997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3997}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3999} +\subsubsection{\mdline{3999}9.4.2.\hspace*{0.5em}\mdline{3999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}\label{sec-meterentry}%mdk%mdk + +%mdk-data-line={4001} +\noindent\mdline{4001}An indirect or indexed meter is not associated with a specific \mdline{4001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4001} and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime \mdline{4003}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4003} message whose fields are defined as +follows:%mdk + +%mdk-data-line={4006} +\begin{itemize}%mdk + +%mdk-data-line={4006} +\item{} +%mdk-data-line={4006} +\mdline{4006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4006} is a \mdline{4006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4006}, the unique identifier for the meter.%mdk%mdk + +%mdk-data-line={4008} +\item{} +%mdk-data-line={4008} +\mdline{4008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4008} is a Protobuf message that encapsulates an \mdline{4008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4008}, used to index into +a meter array.%mdk%mdk + +%mdk-data-line={4011} +\item{} +%mdk-data-line={4011} +\mdline{4011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4011} is a Protobuf message of type \mdline{4011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{4011}, which represents the +meter configuration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4014} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4015} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~meter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4022} +\noindent\mdline{4022}The \mdline{4022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4022} can only be used in a \mdline{4022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4022} with the \mdline{4022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4022} update +type. The P4Runtime server must return an \mdline{4023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4023} error code for +update types \mdline{4024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4024} and \mdline{4024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4024}. By default all the meter entries in the +array have a default configuration (GREEN for all packets).%mdk + +%mdk-data-line={4027} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4027} +\item\mdline{4027}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4027}: Server returns the error code \mdline{4027}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4027}.%mdk + +%mdk-data-line={4028} +\item\mdline{4028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4028}: Modify an indirect meter instance whose unique id is \mdline{4028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4028} and +array index is specified by \mdline{4029}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4029}. The meter is reconfigured using the +\mdline{4030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4030} field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the \mdline{4032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4032} field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if \mdline{4034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4034} is unset). The server must return \mdline{4034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4034} for a +negative index value and \mdline{4035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4035} if the index value exceeds the size of +the meter array.%mdk + +%mdk-data-line={4037} +\item\mdline{4037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4037}: Server returns the error code \mdline{4037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4037}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4039} +\noindent\mdline{4039}A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a \mdline{4040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4040} by including a \mdline{4040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4040} entity for each +of the instances, specifying the \mdline{4041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4041} and \mdline{4041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4041}. Wildcard reads are also +supported as follows:%mdk + +%mdk-data-line={4044} +\begin{itemize}%mdk + +%mdk-data-line={4044} +\item{} +%mdk-data-line={4044} +\mdline{4044}If the \mdline{4044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4044} field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the \mdline{4045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4045}.%mdk%mdk + +%mdk-data-line={4047} +\item{} +%mdk-data-line={4047} +\mdline{4047}If the \mdline{4047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4047} field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id \mdline{4048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4048}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4050} +\subsection{\mdline{4050}9.5.\hspace*{0.5em}\mdline{4050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}\label{sec-packetreplicationengineentry}%mdk%mdk + +%mdk-data-line={4052} +\noindent\mdline{4052}The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets.%mdk + +%mdk-data-line={4058} +\subsubsection{\mdline{4058}9.5.1.\hspace*{0.5em}\mdline{4058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}\label{sec-multicastgroupentry}%mdk%mdk + +%mdk-data-line={4060} +\noindent\mdline{4060}Multicasting is achieved in PSA programs by setting the \mdline{4060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4060} +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the \mdline{4063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4063} API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example.%mdk + +%mdk-data-line={4068} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4069} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~arp\_multicast({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ethernet.isValid()~\&\&\\ +~~~~~~~~hdr.ethernet.eth\_type~==~ETH\_TYPE\_ARP)~\{\\ +~~~~~~smeta.multicast\_group~=~(MulticastGroup\_t)~{\mdcolor{purple}1};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4079} +\noindent\mdline{4079}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4082} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4083} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~multicast\_group\_entry~\{\\ +~~~~~~multicast\_group\_id:~{\mdcolor{purple}1}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}5}~instance:~{\mdcolor{purple}1}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}12}~instance:~{\mdcolor{purple}2}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}18}~instance:~{\mdcolor{purple}3}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}24}~instance:~{\mdcolor{purple}4}~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4097} +\noindent\mdline{4097}As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +\mdline{4102}\mdref{sec-translation-of-port-numbers}{PSA Metadata Translation}\mdline{4102} section.%mdk + +%mdk-data-line={4104} +\mdline{4104}The egress packets may be distinguished for further processing in the egress +using the \mdline{4105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4105} metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 \mdline{4107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4107} metadata is set to a value that is not +programmed in the PRE, then the packet is dropped.%mdk + +%mdk-data-line={4110} +\mdline{4110}A multicast group may be inserted, modified or deleted as per the following +semantics.%mdk + +%mdk-data-line={4113} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4113} +\item\mdline{4113}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4113}: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The \mdline{4114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4114} field is a \mdline{4114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4114} and must be greater +than 0 (see explanation\mdline{4115}~\mdref{sec-valid-values-for-mg-id}{below}\mdline{4115}), or the +P4Runtime server must return an \mdline{4116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4116} error. The replica +\mdline{4117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4117} ID is also a \mdline{4117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4117}, and its value may not exceed the maximum +allowed by the target for the \mdline{4118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4118} type (0 is allowed), or the +server must return an \mdline{4119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4119} error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of \mdline{4121}\emph{both}\mdline{4121} \mdline{4121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{4121} and \mdline{4121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4121}, or the server +must return \mdline{4122}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4122}.%mdk + +%mdk-data-line={4123} +\item\mdline{4123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4123}: Modify the set of replicas for a given multicast group entry, +indexed by the given \mdline{4124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4124}. Same restrictions as \mdline{4124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4124} apply +here.%mdk + +%mdk-data-line={4126} +\item\mdline{4126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4126}: Delete the multicast group indexed by the given +\mdline{4127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4127}. The replicas need not be provided for this +operation. Any packets with their \mdline{4128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4128} metadata in the data plane +set to the deleted \mdline{4129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4129} will be dropped.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4131} +\noindent\mdline{4131}When reading a multicast group, only \mdline{4131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4131} is considered. All +other fields in \mdline{4132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4132} are ignored. To perform a \mdline{4132}\emph{wildcard}\mdline{4132} +\mdline{4133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4133} on all configured multicast group entries, the \mdline{4133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4133} field +must be set to 0, its default value.%mdk + +%mdk-data-line={4136} +\paragraph{\mdline{4136}9.5.1.1.\hspace*{0.5em}\mdline{4136}Valid Values for \mdline{4136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}}\label{sec-valid-values-for-mg-id}%mdk%mdk + +%mdk-data-line={4138} +\noindent\mdline{4138}The PSA specification states that the valid \mdline{4138}\emph{data plane}\mdline{4138} values for multicast +group ids (\mdline{4139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroup\_t}}}\mdline{4139}) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target\mdline{4141}~[\mdcite{psatranslation}{24}]\mdline{4141}. This means that, in the absence of +translation, the client must set the \mdline{4142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4142} field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special \mdline{4144}\emph{wildcard}\mdline{4144} value which is used to read all the multicast groups +configured in the target, the \mdline{4145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4145} field must never be set to 0 +when performing a \mdline{4146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4146} RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value.%mdk + +%mdk-data-line={4151} +\subsubsection{\mdline{4151}9.5.2.\hspace*{0.5em}\mdline{4151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}\label{sec-clonesessionentry}%mdk%mdk + +%mdk-data-line={4153} +\noindent\mdline{4153}PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +\mdline{4157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4157} identifier and a boolean flag \mdline{4157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone}}}\mdline{4157} in the packet +metadata. The \mdline{4158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4158} serves as a handle to the clone attributes, +namely a set \mdline{4159}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}replicas}}}\mdline{4159} of \mdline{4159}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(egress~port,~instance)}}}\mdline{4159} pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +\mdline{4162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4162} API.%mdk + +%mdk-data-line={4164} +\mdline{4164}The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the \mdline{4167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_low\_ttl}}}\mdline{4167} control block is applied in the ingress +pipeline to create an ingress-to-egress clone.%mdk + +%mdk-data-line={4170} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4171} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~clone\_low\_ttl({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ipv4.isValid()~\&\&\\ +~~~~~~~~hdr.ipv4.ttl~\textless{}=~LOW\_TTL\_THRESHOLD)~\{\\ +~~~~~~smeta.clone\_session\_id~=~{\mdcolor{purple}10}w100;\\ +~~~~~~smeta.clone~=~{\bfseries{\mdcolor{navy}true}};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4183} +\noindent\mdline{4183}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4186} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4187} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~clone\_session\_entry~\{\\ +~~~~~~session\_id:~{\mdcolor{purple}100}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}0xfffffffd}~instance:~{\mdcolor{purple}1}~\}~{\mdcolor{darkgreen}\#~to~CPU}\\ +~~~~~~class\_of\_service:~{\mdcolor{purple}2}\\ +~~~~~~packet\_length\_bytes:~{\mdcolor{purple}4096}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4200} +\noindent\mdline{4200}As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type \mdline{4204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4204}~[\mdcite{psatranslation}{24}]\mdline{4204}). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes.%mdk + +%mdk-data-line={4209} +\mdline{4209}The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port \mdline{4210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfffffffd}}}\mdline{4210}; see +\mdline{4211}\mdref{sec-translation-of-port-numbers}{Translation of Port Numbers}\mdline{4211}). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port.%mdk + +%mdk-data-line={4214} +\mdline{4214}If the \mdline{4214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4214} data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created.%mdk + +%mdk-data-line={4217} +\mdline{4217}A clone session may be inserted, modified or deleted as per the following +semantics:%mdk + +%mdk-data-line={4220} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4220} +\item\mdline{4220}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4220}: Add a new clone session entry bound to a set of egress ports and +replica IDs. The \mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4221} is a \mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4221} and must be greater than 0 (see +explanation\mdline{4222}~\mdref{sec-valid-values-for-session-id}{below}\mdline{4222}), or the P4Runtime +server must return an \mdline{4223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4223} error. The replica \mdline{4223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4223} ID is +also a \mdline{4224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4224}, and its value may not exceed the maximum allowed by the +target for the \mdline{4225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4225} type (0 is allowed), or the server must also +return an \mdline{4226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4226} error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (\mdline{4229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}class\_of\_service}}}\mdline{4229} field). This value must be a valid +value for the PSA \mdline{4230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ClassOfService\_t}}}\mdline{4230} type, which supports runtime translation +by default\mdline{4231}~[\mdcite{psatranslation}{24}]\mdline{4231}, or the server must return +\mdline{4232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4232}. See\mdline{4232}~\mdref{sec-translation-of-port-numbers}{PSA Metadata +Translation}\mdline{4233} for more information. The +\mdline{4234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4234} field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +\mdline{4236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4236} field is 0 (default), no truncation on the clone will be +performed.%mdk + +%mdk-data-line={4238} +\item\mdline{4238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4238}: Modify the attributes of a given clone session entry, indexed by the +given \mdline{4239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4239}. Same restrictions as \mdline{4239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4239} apply here.%mdk + +%mdk-data-line={4240} +\item\mdline{4240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4240}: Delete the clone session indexed by the given +\mdline{4241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4241}. Other fields need not be provided for this operation. Any +packet with their \mdline{4242}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4242} metadata in the data plane set to the +deleted \mdline{4243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4243} will no longer be cloned.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4245} +\noindent\mdline{4245}When reading a clone session, only \mdline{4245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4245} is considered. All other fields +in \mdline{4246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4246} are ignored. To perform a \mdline{4246}\emph{wildcard}\mdline{4246} \mdline{4246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4246} on all +configured clone session entries, the \mdline{4247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4247} field must be set to 0, its +default value. The \mdline{4248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4248} field can never be equal to 0 in a \mdline{4248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4248} +RPC. If it does, the server must return an \mdline{4249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4249} error.%mdk + +%mdk-data-line={4251} +\paragraph{\mdline{4251}9.5.2.1.\hspace*{0.5em}\mdline{4251}Valid Values for \mdline{4251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}}\label{sec-valid-values-for-session-id}%mdk%mdk + +%mdk-data-line={4253} +\noindent\mdline{4253}The PSA specification states that the valid \mdline{4253}\emph{data plane}\mdline{4253} values for clone +session ids (\mdline{4254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4254}) range from 0 to the maximum value supported by +the target\mdline{4255}~[\mdcite{psatranslation}{24}]\mdline{4255}. Note that unlike for\mdline{4255}~\mdref{sec-valid-values-for-mg-id}{multicast group +ids}\mdline{4256}, 0 is a valid \mdline{4256}\emph{data plane}\mdline{4256} value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special \mdline{4258}\emph{wildcard}\mdline{4258} value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a \mdline{4259}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4259} +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is \mdline{4261}\emph{not}\mdline{4261} enabled, we effectively +\mdline{4262}\textquotedblleft{}lose\textquotedblright{}\mdline{4262} one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (\mdline{4263}e.g.\mdline{4263} because the target supports a very +limited number of clone sessions), one can enable translation on +\mdline{4265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4265} and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id.%mdk + +%mdk-data-line={4268} +\subsection{\mdline{4268}9.6.\hspace*{0.5em}\mdline{4268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}\label{sec-valuesetentry}%mdk%mdk + +%mdk-data-line={4270} +\noindent\mdline{4270}Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the \mdline{4274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4274} state.%mdk + +%mdk-data-line={4276} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4277} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}state}}~parse\_l2~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}(MAX\_TRILL\_TYPES)~trill\_types;}\\ +~~extract(hdr.ethernet);\\ +~~{\bfseries{\mdcolor{navy}select}}~(hdr.ethernet.eth\_type)~\{\\ +~~~~ETH\_TYPE\_IPV4:~parse\_ipv4;\\ +~~~~ETH\_TYPE\_IPV6:~parse\_ipv6;\\ +~~~~trill\_types:~~~parse\_trill\_types;\\ +~~~~\_:~~~~~~~~~~~~~reject;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4289} +\noindent\mdline{4289}The corresponding entry in the P4Info for this Value Set is:%mdk + +%mdk-data-line={4291} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4292} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}trill\_types}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~\textless{}MAX\_TRILL\_TYPES\textgreater{}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4306} +\noindent\mdline{4306}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4309} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4310} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x22f3}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x893b}~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4328} +\noindent\mdline{4328}As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the \mdline{4330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4330} state.%mdk + +%mdk-data-line={4332} +\mdline{4332}A \mdline{4332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4332} entity update message has the following fields:%mdk + +%mdk-data-line={4334} +\begin{itemize}%mdk + +%mdk-data-line={4334} +\item{} +%mdk-data-line={4334} +\mdline{4334}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4334} is the \mdline{4334}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4334} identifier of the Value Set instance, as +defined in P4Info.%mdk%mdk + +%mdk-data-line={4337} +\item{} +%mdk-data-line={4337} +\mdline{4337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4337} is a repeated field of type \mdline{4337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4337}. When \mdline{4337}\textquotedblleft{}selecting\textquotedblright{}\mdline{4337} +against a Value Set, every member will be considered and if at least one +\mdline{4339}\textquotedblleft{}matches\textquotedblright{}\mdline{4339}, the corresponding parser transition will be taken. Each +\mdline{4340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4340} contains a repeated field of \mdline{4340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4340} messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a \mdline{4342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4342} if and only if +it matches all its \mdline{4343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4343} messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. \mdline{4345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4345} messages in a \mdline{4345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4345} follow +the\mdline{4346}~\mdref{sec-match-format}{same rules}\mdline{4346} as in a \mdline{4346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4346}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4348} +\noindent\mdline{4348}A \mdline{4348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4348} may only be modified. If the update type is \mdline{4348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4348} or +\mdline{4349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4349}, the server must return an \mdline{4349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4349} error. If the update type +is \mdline{4350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4350}, the server writes the members given in the repeated field to the +Value Set entry indexed by the given \mdline{4351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4351}. The maximum number of +matches must not exceed the maximum size given by the \mdline{4352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{4352} field in P4Info of +the Value Set, otherwise the server must return a \mdline{4353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4353} error. To +empty a Value Set (\mdline{4354}i.e.\mdline{4354} restore it to its initial state), the P4Runtime client +can perform a \mdline{4355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4355} update with an empty \mdline{4355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4355} repeated field.%mdk + +%mdk-data-line={4357} +\mdline{4357}To facilitate\mdline{4357}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{4357}, the server must +return an \mdline{4358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4358} error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set.%mdk + +%mdk-data-line={4364} +\mdline{4364}See Appendix\mdline{4364}~\mdref{sec-value-set-example}{A.3}\mdline{4364} for a more complex Value Set example.%mdk + +%mdk-data-line={4366} +\subsection{\mdline{4366}9.7.\hspace*{0.5em}\mdline{4366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}\label{sec-registerentry}%mdk%mdk + +%mdk-data-line={4368} +\noindent\mdline{4368}The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The \mdline{4369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4369} P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations.%mdk + +%mdk-data-line={4373} +\mdline{4373}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4373} has the following fields:%mdk + +%mdk-data-line={4375} +\begin{itemize}%mdk + +%mdk-data-line={4375} +\item{} +%mdk-data-line={4375} +\mdline{4375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4375}, which identifies the PSA Register extern instance which is +being accessed by the client; the \mdline{4376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4376} is specified by the P4Info +message.%mdk%mdk + +%mdk-data-line={4379} +\item{} +%mdk-data-line={4379} +\mdline{4379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4379}, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the \mdline{4381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4381} message +used for the request. When an \mdline{4382}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4382} is provided , the server must validate +its value, and return \mdline{4383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4383} for a negative index or +\mdline{4384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4384} if the index exceeds the size of the register array.%mdk%mdk + +%mdk-data-line={4386} +\item{} +%mdk-data-line={4386} +\mdline{4386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4386}: the data to be written to the array (if \mdline{4386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4386} is part of a +\mdline{4387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4387} message) or the data read from the array (if \mdline{4387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4387} is +part of a \mdline{4388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4388} message). The \mdline{4388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4388} field is a \mdline{4388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{4388} message and +must match the format described by the \mdline{4389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{4389} field of the corresponding +Register entry in the P4Info, or the server must return an \mdline{4390}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4390} +error.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4393} +\subsection{\mdline{4393}9.8.\hspace*{0.5em}\mdline{4393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}\label{sec-digestentry}%mdk%mdk + +%mdk-data-line={4395} +\noindent\mdline{4395}A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly.%mdk + +%mdk-data-line={4400} +\mdline{4400}The \mdline{4400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4400} P4Runtime entity is used to \mdline{4400}\textbf{configure}\mdline{4400} how the device must +generate digest messages. The \mdline{4401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4401} Protobuf message is not used to +carry digest data, which is done on the \mdline{4402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4402} bidirectional stream +using the \mdline{4403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4403} (digest data sent by the target to the client) and +\mdline{4404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4404} (digest data acknowledgments sent by the client to the target) +Protobuf messages.%mdk + +%mdk-data-line={4407} +\mdline{4407}In this section, we refer to the data learned by a single data plane call to +\mdline{4408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}T\textgreater{}::pack}}}\mdline{4408} as a \mdline{4408}\textquotedblleft{}digest message\textquotedblright{}\mdline{4408} and we use \mdline{4408}\textquotedblleft{}digest list\textquotedblright{}\mdline{4408} to designate +the list of digest messages bundled by the P4Runtime service in a single +\mdline{4410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4410} stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are \mdline{4412}\textquotedblleft{}duplicate\textquotedblright{}\mdline{4412} if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are \mdline{4413}\textquotedblleft{}distinct\textquotedblright{}\mdline{4413} +if they are not duplicate.%mdk + +%mdk-data-line={4416} +\mdline{4416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4416} has the following fields:%mdk + +%mdk-data-line={4418} +\begin{itemize}%mdk + +%mdk-data-line={4418} +\item{} +%mdk-data-line={4418} +\mdline{4418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4418}, which identifies the PSA Digest extern instance which emitted the +data; the \mdline{4419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4419} is determined by the P4Info message.%mdk%mdk + +%mdk-data-line={4421} +\item{} +%mdk-data-line={4421} +\mdline{4421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4421}, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +\mdline{4423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4423}; these parameters are:%mdk + +%mdk-data-line={4425} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4425} +\item\mdline{4425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4425}: the maximum server buffering delay in nanoseconds for an +outstanding digest message.%mdk + +%mdk-data-line={4427} +\item\mdline{4427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4427}: the maximum digest list size\mdline{4427} \mdline{4427}\textemdash{}\mdline{4427} in number of digest +messages\mdline{4428} \mdline{4428}\textemdash{}\mdline{4428} sent by the server to the client as a single \mdline{4428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4428} +Protobuf message.%mdk + +%mdk-data-line={4430} +\item\mdline{4430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4430}: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4434} +\noindent\mdline{4434}Here is the significance of the different \mdline{4434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4434} types for \mdline{4434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4434}:%mdk + +%mdk-data-line={4436} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4436} +\item\mdline{4436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4436}: Enable server generation of \mdline{4436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4436} messages for given digest +instance and use provided configuration parameters.%mdk + +%mdk-data-line={4438} +\item\mdline{4438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4438}: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance.%mdk + +%mdk-data-line={4440} +\item\mdline{4440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4440}: Disable server generation of \mdline{4440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4440} messages for given digest +instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4443} +\noindent\mdline{4443}A server should buffer digest messages until either:%mdk + +%mdk-data-line={4445} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4445} +\item\mdline{4445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4445} time has passed since the first digest message was added to +the empty buffer, or%mdk + +%mdk-data-line={4447} +\item\mdline{4447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4447} \mdline{4447}\emph{distinct}\mdline{4447} digest messages have been received from the +data plane and added to the buffer%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4450} +\noindent\mdline{4450}At which point the server should, with best effort, generate a \mdline{4450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4450} +stream message with the buffer contents and send it to the master client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software.%mdk + +%mdk-data-line={4456} +\mdline{4456}To avoid sending duplicate digest messages across different \mdline{4456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4456} +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the master client indicates that it has received the +digest list and acted on it. The server must keep a \mdline{4459}\textquotedblleft{}cache\textquotedblright{}\mdline{4459} containing the set +of all digest messages that have been sent, but not acknowledged yet by the +master client, up-to \mdline{4461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4461} in the past. The server must delete all +cache entries for a given digest list when they are at least \mdline{4462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4462} +old or when a matching \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4463} message (\mdline{4463}i.e.\mdline{4463} with the same \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4463} +and \mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}list\_id}}}\mdline{4464} fields as the \mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4464} message) is received.%mdk + +%mdk-data-line={4466} +\mdline{4466}The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged \mdline{4471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4471} messages.%mdk + +%mdk-data-line={4473} +\mdline{4473}When \mdline{4473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4473} is set to 0 and / or \mdline{4473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4473} is set to 1, the +server should, with best effort, generate a \mdline{4474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4474} message for every +digest message generated by the data plane which is not already in the cache. If +\mdline{4476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4476} is set to 0, the cache must always be an empty set. If +\mdline{4477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4477} is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +\mdline{4479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4479} configuration parameter.%mdk + +%mdk-data-line={4481} +\mdline{4481}The P4Runtime server may empty the digest message cache in case of a client +mastership change.%mdk + +%mdk-data-line={4484} +\mdline{4484}Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server:%mdk + +%mdk-data-line={4487} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4488} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestStream~stream;\\ +DigestCache~cache;\\ +DigestBuffer~buffers;\\ +\\ +{\mdcolor{darkgreen}//~sends~digest~list~when~it~is~ready}\\ +send\_buffer(Id~digest\_id)~\{\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~stream.write(DigestList(buffer));\\ +~~cache.merge(buffer);~~{\mdcolor{darkgreen}//~updates~cache~with~new~digest~list}\\ +~~buffer.clear();\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~data~plane~digest~messages~from~device}\\ +handle\_dataplane\_digest(Digest~msg)~\{\\ +~~digest\_id~=~msg.digest\_id();\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~{\bfseries{\mdcolor{navy}if}}~(msg~in~cache~{\mdcolor{teal}OR}~msg~in~buffer)~{\bfseries{\mdcolor{navy}return}};\\ +~~buffer.enqueue(msg);\\ +~~{\bfseries{\mdcolor{navy}if}}~(buffer.length()~\textless{}~max\_list\_size(digest\_id))~{\bfseries{\mdcolor{navy}return}};\\ +~~send\_buffer(digest\_id);\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~ack~messages~received~on~the~stream}\\ +handle\_stream\_ack(DigestListAck~ack)~\{\\ +~~{\mdcolor{darkgreen}//~clear~all~cache~entries~matching~the~tuple~(digest\_id,~list\_id)}\\ +~~cache.erase(~(ack.digest\_id(),~ack.list\_id()~)\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~loop~to~enforce~timeouts}\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~now~=~now();\\ +~~{\mdcolor{darkgreen}//~check~for~buffers~that~need~to~be~sent}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~buffer)~in~buffers)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~buffer.first\_enq\_time()~\textgreater{}=~max\_timeout\_ns(digest\_id))\\ +~~~~~~send\_buffer(buffer\_id);\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~check~for~expired~entries~in~cache}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~list\_id,~sent\_time)~in~cache)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~sent\_time~\textgreater{}=~ack\_timeout\_ns(digest\_id))\\ +~~~~~~cache.erase(~(digest\_id,~list\_id)~);\\ +~~\}\\ +~~sleep({\mdcolor{teal}X});\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4533} +\subsection{\mdline{4533}9.9.\hspace*{0.5em}\mdline{4533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\label{sec-extern-entry}%mdk%mdk + +%mdk-data-line={4535} +\noindent\mdline{4535}This is used to support a P4 extern entity that is not part of PSA. It is +defined as:%mdk + +%mdk-data-line={4538} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4539} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ExternEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_type\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~google.protobuf.Any~entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4546} +\noindent\mdline{4546}Each \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4546} entity maps to an \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{4546} message in the +\mdline{4547}\mdref{sec-p4info-extern}{P4Info}\mdline{4547} and an \mdline{4547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4547} message within that +message. The \mdline{4548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{4548} field must be equal to the one in +\mdline{4549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4549}. The \mdline{4549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_id}}}\mdline{4549} field must be equal to the ID included in the +\mdline{4550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{4550} of the corresponding \mdline{4550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4550} message.%mdk + +%mdk-data-line={4552} +\mdline{4552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entry}}}\mdline{4552} itself is embedded as an \mdline{4552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{4552} Protobuf message\mdline{4552}~[\mdcite{protoany}{31}]\mdline{4552} to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on\mdline{4556}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{4557} for more information.%mdk + +%mdk-data-line={4559} +\section{\mdline{4559}10.\hspace*{0.5em}\mdline{4559}Error Reporting Messages}\label{sec-error-reporting-messages}%mdk%mdk + +%mdk-data-line={4561} +\noindent\mdline{4561}P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case.%mdk + +%mdk-data-line={4565} +\mdline{4565}gRPC uses \mdline{4565}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4565}~[\mdcite{grpcstatus}{32}]\mdline{4565} to represent the status returned by an +RPC. It has 3 attributes:%mdk + +%mdk-data-line={4568} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4569} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StatusCode~code\_;\\ +{\mdcolor{navy}grpc::}string~error\_message\_;\\ +{\mdcolor{navy}grpc::}string~binary\_error\_details\_;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4574} +\noindent\mdline{4574}The \mdline{4574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4574} represents a canonical error\mdline{4574}~[\mdcite{grpcstatuscodes}{34}]\mdline{4574} and describes the +overall RPC status. The \mdline{4575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4575} is a developer-facing error message, +which should be in English. The \mdline{4576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}binary\_error\_details\_}}}\mdline{4576} carries a serialized +\mdline{4577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4577} message\mdline{4577}~[\mdcite{protostatus}{28}]\mdline{4577} message, which has 3 fields:%mdk + +%mdk-data-line={4579} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4580} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}int32}}~code~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~see~code.proto}\\ +{\bfseries{\mdcolor{navy}string}}~{\bfseries{\mdcolor{navy}message}}~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +{\bfseries{\mdcolor{navy}repeated}}~google.protobuf.Any~details~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4585} +\noindent\mdline{4585}The code and message fields must be the same as \mdline{4585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4585} and \mdline{4585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4585} +fields from \mdline{4586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4586} above. The \mdline{4586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{4586} field is a list that consists of +\mdline{4587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4587} messages that carry error details for individual elements inside +batch-request RPCs (\mdline{4588}e.g.\mdline{4588} \mdline{4588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4588} and \mdline{4588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4588}). \mdline{4588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4588} includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices\mdline{4592}~[\mdcite{grpcstatuscodes}{34}]\mdline{4592}.%mdk + +%mdk-data-line={4594} +\mdline{4594}Figure\mdline{4594}~\mdref{fig-error-report}{\mdcaptionlabel{7}}\mdline{4594} illustrates how these messages fit together.%mdk + +%mdk-data-line={4596} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={4597} +\noindent\mdline{4597}\includegraphics[keepaspectratio=true,width=\dimwidth{0.70}]{build/error-report}{}\mdline{4597}%mdk + +%mdk-data-line={4598} +\mdhr{}%mdk + +%mdk-data-line={4599} +\noindent\mdline{4599}\mdcaption{\textbf{Figure~\mdcaptionlabel{7}.}~\mdcaptiontext{P4Runtime Error Report Message Format}}%mdk +%mdk +\end{mdcenter}\label{fig-error-report}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={4601} +\noindent\mdline{4601}gRPC provides utility functions \mdline{4601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExtractErrorDetails()}}}\mdline{4601} and \mdline{4601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetErrorDetails()}}}\mdline{4601} +\mdline{4602}[\mdcite{grpcerrordetails}{33}]\mdline{4602} to easily convert between \mdline{4602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4602} and +\mdline{4603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4603}.%mdk + +%mdk-data-line={4605} +\mdline{4605}Please see sections on individual P4Runtime RPCs for details on how +\mdline{4606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4606} is populated for reporting errors.%mdk + +%mdk-data-line={4608} +\mdline{4608}Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on\mdline{4611}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{4612} for more information.%mdk + +%mdk-data-line={4614} +\section{\mdline{4614}11.\hspace*{0.5em}\mdline{4614}Atomicity of Individual \mdline{4614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4614} and \mdline{4614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4614} Operations}\label{sec-atomicity-of-individual-write-and-read-operations}%mdk%mdk + +%mdk-data-line={4616} +\noindent\mdline{4616}Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane \mdline{4617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4617} +operation, and every single \mdline{4618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4618} operation on a table that inserts, deletes, +or modifies one table entry, the \mdline{4619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4619} operation should behave as if that +\mdline{4620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4620} operation has not yet occurred, or as if the \mdline{4620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4620} operation is +complete. The P4 program should never behave as if the \mdline{4621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4621} operation is +partially complete. These guarantees also apply to extern instances: \mdline{4622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4622} and +\mdline{4623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4623} operations on extern entities must execute atomically relative to extern +data plane methods.%mdk + +%mdk-data-line={4626} +\mdline{4626}The atomicity guarantees provided by P4Runtime for individual \mdline{4626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4626} and \mdline{4626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4626} +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification\mdline{4628}~[\mdcite{psaatomicityofcontrolplaneops}{23}]\mdline{4628}.%mdk + +%mdk-data-line={4630} +\mdline{4630}The P4\mdline{4630}\mdsub{16}\mdline{4630} language introduces an \mdline{4630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4630} annotation\mdline{4630}~[\mdcite{p4concurrency}{14}]\mdline{4630}, to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the \mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4632} annotation for \mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4632} +operations, as well as\mdline{4633}~\mdref{wildcard-reads}{non-wildcard \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} operations}\mdline{4633}, +relative to data plane execution. Consider the following P4 example written for +PSA:%mdk + +%mdk-data-line={4637} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4638} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024)~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\mdcolor{darkgreen}//~...}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~Value\_t~v~=~r1.read((Index\_t){\mdcolor{purple}1});\\ +~~~~~~~~v~=~v~+~{\mdcolor{purple}1};\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~v);\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4654} +\noindent\mdline{4654}If a P4Runtime server is processing messages which write to Register \mdline{4654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4654} at +index \mdline{4655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}1}}}\mdline{4655}, these writes must not happen between the data plane \mdline{4655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}read}}}\mdline{4655} and +\mdline{4656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}write}}}\mdline{4656}.%mdk + +%mdk-data-line={4658} +\mdline{4658}Now let\mdline{4658}'\mdline{4658}s consider the following example:%mdk + +%mdk-data-line={4660} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4661} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024,~(Value\_t){\mdcolor{purple}0}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~initial~value~}{\mdcolor{darkgreen}*/})~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}100});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}100});\\ +~~~~\}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}200});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}200});\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4679} +\noindent\mdline{4679}If a P4Runtime client issues a \mdline{4679}\emph{wildcard}\mdline{4679} \mdline{4679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4679} on Register \mdline{4679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4679}, there is no +guarantee that \mdline{4680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]~==~r1{}[2]}}}\mdline{4680} in the response, as the read for \mdline{4680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4680} may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for \mdline{4682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4682} may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read \mdline{4684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4684} and \mdline{4684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4684} separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +\mdline{4687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4687} message) of individual read requests. Similar to a batch +\mdline{4688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4688}, a wildcard read of a register can execute the reads of the +register array elements (\mdline{4689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4689}, \mdline{4689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4689}, \mdline{4689}\dots{}\mdline{4689}) in an arbitrary order relative +to each other.%mdk + +%mdk-data-line={4692} +\mdline{4692}If the \mdline{4692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4692} annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program.%mdk + +%mdk-data-line={4696} +\section{\mdline{4696}12.\hspace*{0.5em}\mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4696} RPC}\label{sec-write-rpc}%mdk%mdk + +%mdk-data-line={4698} +\noindent\mdline{4698}The \mdline{4698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4698} RPC updates one or more P4 entities on the target. The request is +defined as follows:%mdk + +%mdk-data-line={4701} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4702} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~WriteRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint64}}~role\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Update~updates~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\bfseries{\mdcolor{navy}enum}}~Atomicity~\{\\ +~~~~CONTINUE\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~ROLLBACK\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~DATAPLANE\_ATOMIC~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~\}\\ +~~Atomicity~atomicity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4716} +\noindent\mdline{4716}The \mdline{4716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4716} uniquely identifies the target P4 device. The \mdline{4716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4716} and +\mdline{4717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4717} define the client role and election-id as described in the +\mdline{4718}\mdref{sec-master-slave-arbitration-and-controller-replication}{Master-Slave Arbitration and Controller +Replication}\mdline{4719} +section. The server is expected to perform the following checks (in this order) +before processing the \mdline{4721}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}updates}}}\mdline{4721} list:%mdk + +%mdk-data-line={4723} +\begin{enumerate}%mdk + +%mdk-data-line={4723} +\item{} +%mdk-data-line={4723} +\mdline{4723}If \mdline{4723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4723} does not match any of the devices known to the P4Runtime +server or if \mdline{4724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4724} does not match any of the roles for the device, the +server must return a \mdline{4725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4725} error.%mdk%mdk + +%mdk-data-line={4727} +\item{} +%mdk-data-line={4727} +\mdline{4727}If the client is not the master for (\mdline{4727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4727}, \mdline{4727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4727}) according to the +\mdline{4728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4728} value, the server must return a \mdline{4728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4728} error.%mdk%mdk + +%mdk-data-line={4730} +\item{} +%mdk-data-line={4730} +\mdline{4730}If the \mdline{4730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4730} is attempted before a \mdline{4730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4730} has been set, +the server must return a \mdline{4731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{4731} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4733} +\noindent\mdline{4733}The updates field is a list of P4 entity updates to be applied. Each update is +defined as:%mdk + +%mdk-data-line={4736} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4737} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Update~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Type~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~INSERT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~MODIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DELETE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~Type~type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Entity~entity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4749} +\noindent\mdline{4749}This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a \mdline{4750}\emph{logical}\mdline{4750} table (\mdline{4750}e.g.\mdline{4750} +\mdline{4751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4751}) or an actual table (\mdline{4751}e.g.\mdline{4751} \mdline{4751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4751}) in the P4 data +plane. Each entity in the container is uniquely identified by its \mdline{4752}\emph{key}\mdline{4752}. Please +refer to the\mdline{4753}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4753} section for details on +what parts of the entity specification make up the \mdline{4754}\emph{key}\mdline{4754} for each P4 entity.%mdk + +%mdk-data-line={4756} +\mdline{4756}An update can be one of the following types:%mdk + +%mdk-data-line={4758} +\begin{itemize}%mdk + +%mdk-data-line={4758} +\item{} +%mdk-data-line={4758} +\mdline{4758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4758}: Inserts the given P4 entity in the entity container. +The \mdline{4759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{4759} field always specifies the full state of the P4 entity. +If the entity already exists, an \mdline{4760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4760} error is returned, and +the existing entity remains unchanged. +If the entity is malformed, an \mdline{4762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4762} error is returned. +If the entity cannot be inserted because the container is already full, +a \mdline{4764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4764} error is returned.%mdk%mdk + +%mdk-data-line={4766} +\item{} +%mdk-data-line={4766} +\mdline{4766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4766}: Modifies the P4 entity to its new specified state. This uses +\mdline{4767}\emph{assign}\mdline{4767} or \mdline{4767}\emph{full-snapshot}\mdline{4767} semantics, \mdline{4767}i.e.\mdline{4767} the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an \mdline{4769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4769} error is usually returned (unless a +more specific error code applies\mdline{4770}~[\mdcite{grpcstatuscodes}{34}]\mdline{4770}). If the entity does not +exist, a \mdline{4771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4771} error is returned.%mdk%mdk + +%mdk-data-line={4773} +\item{} +%mdk-data-line={4773} +\mdline{4773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4773}: Deletes the specified P4 entity. If the entity does not exist, a +\mdline{4774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4774} error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4777} +\noindent\mdline{4777}If an update is not allowed under the given controller role, the server must +return a \mdline{4778}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4778} error for this update.%mdk + +%mdk-data-line={4780} +\subsection{\mdline{4780}12.1.\hspace*{0.5em}\mdline{4780}Batching and Ordering of Updates}\label{sec-batching-and-ordering-of-updates}%mdk%mdk + +%mdk-data-line={4782} +\noindent\mdline{4782}P4Runtime supports batching of \mdline{4782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4782} operations. The list of updates in a +\mdline{4783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4783} is referred to as a \mdline{4783}\emph{batch}\mdline{4783}. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of \mdline{4785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4785} entities).%mdk + +%mdk-data-line={4787} +\mdline{4787}The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +\mdline{4789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4789}s can also be processed interleaved and/or in parallel. +However, \mdline{4790}\textbf{the processing of requests must be strictly serializable}\mdline{4790}. That +is, given a history \mdline{4791}$S$\mdline{4791} of \mdline{4791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4791}s including the responses to those +requests, there must exist an order \mdline{4792}$L$\mdline{4792} for all updates in \mdline{4792}$S$\mdline{4792}, such that:%mdk + +%mdk-data-line={4794} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4794} +\item\mdline{4794}All updates from the same write request must appear as a contiguous +subsequence in \mdline{4795}$L$\mdline{4795}, but the order within that subsequence can be arbitrary.%mdk + +%mdk-data-line={4796} +\item\mdline{4796}For two updates \mdline{4796}$u_1$\mdline{4796} and \mdline{4796}$u_2$\mdline{4796}, if the write request containing \mdline{4796}$u_1$\mdline{4796} +completed before the write request of \mdline{4797}$u_2$\mdline{4797} was sent, then \mdline{4797}$u_1$\mdline{4797} must appear +before \mdline{4798}$u_2$\mdline{4798} in \mdline{4798}$L$\mdline{4798}.%mdk + +%mdk-data-line={4799} +\item\mdline{4799}Executing all updates in \mdline{4799}$L$\mdline{4799} sequentially must yield the same response for +every update as in \mdline{4800}$S$\mdline{4800}.%mdk + +%mdk-data-line={4801} +\item\mdline{4801}The observable state of the switch after \mdline{4801}$S$\mdline{4801} (\mdline{4801}e.g.\mdline{4801}, through the \mdline{4801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4801} RPC) +is identical to the one obtained by sequentially executing \mdline{4802}$L$\mdline{4802}.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4804} +\noindent\mdline{4804}The \mdline{4804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4804} RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the \mdline{4805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4805} RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (\mdline{4808}e.g.\mdline{4808} inserting an \mdline{4808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4808} +followed by pointing a \mdline{4809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4809} to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding \mdline{4811}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4811} RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate \mdline{4815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4815} calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each \mdline{4816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4816} call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one.%mdk + +%mdk-data-line={4821} +\subsection{\mdline{4821}12.2.\hspace*{0.5em}\mdline{4821}Batch Atomicity}\label{sec-batch-atomicity}%mdk%mdk + +%mdk-data-line={4823} +\noindent\mdline{4823}A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the \mdline{4824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4824} +enum. A P4Runtime server is required to support only the modes marked as +\mdline{4826}\emph{Required}\mdline{4826} below:%mdk + +%mdk-data-line={4828} +\begin{itemize}%mdk + +%mdk-data-line={4828} +\item{} +%mdk-data-line={4828} +\mdline{4828}\emph{Required}\mdline{4828}: \mdline{4828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4828}: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that \mdline{4832}\emph{see}\mdline{4832} each of +these intermediate stages.%mdk%mdk + +%mdk-data-line={4835} +\item{} +%mdk-data-line={4835} +\mdline{4835}\emph{Optional}\mdline{4835}: \mdline{4835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ROLLBACK\_ON\_ERROR}}}\mdline{4835}: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is \mdline{4839}\emph{all-or-none}\mdline{4839}, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that \mdline{4843}\emph{see}\mdline{4843} each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure.%mdk + +%mdk-data-line={4848} +\mdline{4848}If a P4Runtime server does not support this option at all, an +\mdline{4849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4849} error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (\mdline{4850}e.g.\mdline{4850} it is +more straightforward to implement batches that contain only \mdline{4851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4851} +operations, vs. those that contain \mdline{4852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4852} operations), an +\mdline{4853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4853} error is returned when the batch cannot be executed +in a data plane-atomic way.%mdk%mdk + +%mdk-data-line={4856} +\item{} +%mdk-data-line={4856} +\mdline{4856}\emph{Optional}\mdline{4856}: \mdline{4856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4856}: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +\mdline{4860}\emph{transaction}\mdline{4860}. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane\mdline{4862}'\mdline{4862}s table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table.%mdk + +%mdk-data-line={4869} +\mdline{4869}If a P4Runtime server does not support this option at all, an \mdline{4869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4869} +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an \mdline{4871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4871} error is returned when the batch +cannot be executed in a data plane-atomic way.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4874} +\noindent\mdline{4874}There is no expectation that a given client must always use the same \mdline{4874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4874} +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use \mdline{4877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4877} at one time and default behavior +(\mdline{4878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4878}) at other times.%mdk + +%mdk-data-line={4880} +\subsection{\mdline{4880}12.3.\hspace*{0.5em}\mdline{4880}Error Reporting}\label{sec-error-reporting}%mdk%mdk + +%mdk-data-line={4882} +\noindent\mdline{4882}Please see section\mdline{4882}~\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{4882} for +information on error reporting messages and guidelines. P4Runtime server will +populate \mdline{4884}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4884} as follows:%mdk + +%mdk-data-line={4886} +\begin{enumerate}%mdk + +%mdk-data-line={4886} +\item{} +%mdk-data-line={4886} +\mdline{4886}If all batch updates succeeded, set \mdline{4886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4886} to \mdline{4886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4886} and do not +populate any other field.%mdk%mdk + +%mdk-data-line={4889} +\item{} +%mdk-data-line={4889} +\mdline{4889}If an error is encountered before even trying to attempt individual batch +updates, set \mdline{4890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4890} that best describes that RPC-wide +error. For example, use \mdline{4891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNAVAILABLE}}}\mdline{4891} if the P4Runtime service is not yet +ready to handle requests. Set \mdline{4892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4892} to describe the issue. Do not +set \mdline{4893}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_details}}}\mdline{4893} in this case.%mdk%mdk + +%mdk-data-line={4895} +\item{} +%mdk-data-line={4895} +\mdline{4895}Otherwise, if one or more updates in the batch (\mdline{4895}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest.updates}}}\mdline{4895}) +failed, set \mdline{4896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4896} to \mdline{4896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{4896}. For example, one update in +the batch may fail with \mdline{4897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4897} and another with +\mdline{4898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4898}. A \mdline{4898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4898} message is used to capture the status of +each and every update in the batch. The number of \mdline{4899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4899} messages packed +into \mdline{4900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{4900} field should therefore always match the +number of updates in the \mdline{4901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4901}, and the order of +\mdline{4902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4902} messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +\mdline{4904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4904} should set the code to \mdline{4904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4904} and omit other fields.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4906} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4907} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}\#~Example~of~a~grpc::Status~returned~for~a~Write~RPC~with~a~batch~of~3~updates.}\\ +{\mdcolor{darkgreen}\#~The~first~and~third~updates~encountered~an~error,~while~the~second~update}\\ +{\mdcolor{darkgreen}\#~succeeded.}\\ +code\_~=~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +error\_message\_~=~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +binary\_error\_details~\{\\ +~~code:~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}8}~~{\mdcolor{darkgreen}\#~RESOURCE\_EXHAUSTED}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Table~is~full.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}500}~~{\mdcolor{darkgreen}\#~ERR\_TABLE\_FULL}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}0}~~{\mdcolor{darkgreen}\#~OK}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}6}~~{\mdcolor{darkgreen}\#~ALREADY\_EXISTS}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Entity~already~exists.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}600}~~{\mdcolor{darkgreen}\#~ERR\_ENTITY\_ALREADY\_EXISTS}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4933} +\section{\mdline{4933}13.\hspace*{0.5em}\mdline{4933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4933} RPC}\label{sec-read-rpc}%mdk%mdk + +%mdk-data-line={4935} +\noindent\mdline{4935}The \mdline{4935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4935} RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as:%mdk + +%mdk-data-line={4938} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4939} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4945} +\noindent\mdline{4945}The \mdline{4945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4945} uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +\mdline{4947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4947} error. The \mdline{4947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{4947} repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server.%mdk + +%mdk-data-line={4950} +\mdline{4950}Since \mdline{4950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4950}s do not mutate any state on the switch, they do not +require an \mdline{4951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4951}, and they do not require the presence of an open +\mdline{4952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4952} between the server and client.%mdk + +%mdk-data-line={4954} +\mdline{4954}The \mdline{4954}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read~}}}\mdline{4954}response consists of a sequence of messages (a gRPC \mdline{4954}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}stream}}}\mdline{4954}) with +each message defined as:%mdk + +%mdk-data-line={4957} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4958} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadResponse~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4963} +\noindent\mdline{4963}The \mdline{4963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{4963} repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the \mdline{4967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Finish()}}}\mdline{4967} method on the stream object +\mdline{4968}[\mdcite{grpcstreamc}{10}]\mdline{4968}).%mdk + +%mdk-data-line={4970} +\subsection{\mdline{4970}13.1.\hspace*{0.5em}\mdline{4970}Nomenclature}\label{sec-nomenclature}%mdk%mdk + +%mdk-data-line={4972} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries request}}%mdk + +%mdk-data-line={4972} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{4972}An element of the \mdline{4972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{4972} repeated field. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries batch}}%mdk + +%mdk-data-line={4974} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{4974}Refers to the \mdline{4974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{4974} repeated field.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={4977} +\noindent\mdline{4977}Each \mdline{4977}\emph{request}\mdline{4977} acts as a query filter for that entity type. If a \mdline{4977}\emph{request}\mdline{4977} fully +specifies the entity key, the \mdline{4978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4978} operation should retrieve a single P4 +entity. Please refer to the\mdline{4979}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4979} section +for details on what parts of the entity specification make up the entity \mdline{4980}\emph{key}\mdline{4980}.%mdk + +%mdk-data-line={4982} +\subsection{\mdline{4982}13.2.\hspace*{0.5em}\mdline{4982}Wildcard Reads}\label{sec-wildcard-reads}%mdk%mdk + +%mdk-data-line={4984} +\noindent\mdline{4984}P4Runtime allows wildcard read of P4 entities. A \mdline{4984}\emph{request}\mdline{4984} may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the\mdline{4986}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4986} section for details on +what parts of the entity can be wildcarded in a given \mdline{4987}\emph{request}\mdline{4987}.%mdk + +%mdk-data-line={4989} +\mdline{4989}For example, in a \mdline{4989}\emph{request}\mdline{4989} of type \mdline{4989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4989}:%mdk + +%mdk-data-line={4991} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4991} +\item\mdline{4991}A default \mdline{4991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4991} (0) implies a request to read all counter-entries for +all indirect counters.%mdk + +%mdk-data-line={4993} +\item\mdline{4993}A particular (non-default) \mdline{4993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4993} in conjunction with \mdline{4993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4993} unset +implies a request to read all counter-entries for the given indirect counter +ID.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4997} +\noindent\mdline{4997}To read the entire forwarding state for a given device, the P4Runtime client can +generate the following \mdline{4998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4998}:%mdk + +%mdk-data-line={5000} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5001} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~\textless{}ID\textgreater{}\\ +entities~\{\\ +~~extern\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~extern~instances~for~all~supported~extern~types}\\ +~~table\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~table~entries~for~all~tables}\\ +~~action\_profile\_member~\{~\}~~{\mdcolor{darkgreen}\#~read~all~members~for~all~action~profiles}\\ +~~action\_profile\_group~\{~\}~~{\mdcolor{darkgreen}\#~read~all~groups~for~all~action~profiles}\\ +~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5011} +\noindent\mdline{5011}The \mdline{5011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5011} oneof field in the \mdline{5011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5011} message must always be set, or the +server must return an \mdline{5012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5012} error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty \mdline{5014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5014} message in the \mdline{5014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5014}. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the \mdline{5016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5016} oneof\mdline{5016}~[\mdcite{protooneofbackwardscompatibility}{20}]\mdline{5016}.%mdk + +%mdk-data-line={5018} +\subsection{\mdline{5018}13.3.\hspace*{0.5em}\mdline{5018}Batch Processing}\label{sec-batch-processing}%mdk%mdk + +%mdk-data-line={5020} +\noindent\mdline{5020}A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type \mdline{5021}\emph{request}\mdline{5021} +appears only once in the batch.%mdk + +%mdk-data-line={5024} +\mdline{5024}A P4Runtime server will process the batch as follows:%mdk + +%mdk-data-line={5026} +\begin{enumerate}%mdk + +%mdk-data-line={5026} +\item{} +%mdk-data-line={5026} +\mdline{5026}Lock state (preventing new writes) and validate each \mdline{5026}\emph{request}\mdline{5026} in the batch:%mdk + +%mdk-data-line={5028} +\begin{enumerate}%mdk + +%mdk-data-line={5028} +\item{} +%mdk-data-line={5028} +\mdline{5028}If it is a valid \mdline{5028}\emph{request}\mdline{5028}, perform the read;%mdk + +%mdk-data-line={5030} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5030} +\item\mdline{5030}If the read was successful, return the entities read in +\mdline{5031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5031} stream.%mdk + +%mdk-data-line={5032} +\item\mdline{5032}If the read failed (exception / critical-error), prepare a \mdline{5032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5032} +with code set to \mdline{5033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INTERNAL}}}\mdline{5033}.%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5035} +\item{} +%mdk-data-line={5035} +\mdline{5035}If the \mdline{5035}\emph{request}\mdline{5035} is invalid (invalid-argument, not-supported, etc.), +prepare a \mdline{5036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5036} with relevant canonical code to capture the error.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5038} +\item{} +%mdk-data-line={5038} +\mdline{5038}Unlock the state (allowing new writes);%mdk%mdk + +%mdk-data-line={5040} +\item{} +%mdk-data-line={5040} +\mdline{5040}Close the \mdline{5040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5040} stream and return a \mdline{5040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5040} as follows:%mdk + +%mdk-data-line={5042} +\begin{enumerate}%mdk + +%mdk-data-line={5042} +\item{} +%mdk-data-line={5042} +\mdline{5042}If no errors were encountered, set code to \mdline{5042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{5042} and do not populate any +other field.%mdk%mdk + +%mdk-data-line={5045} +\item{} +%mdk-data-line={5045} +\mdline{5045}Otherwise, the overall code should be set to \mdline{5045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{5045}. See section +\mdline{5046}\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{5046} for information +on error reporting messages and guidelines. Assemble a list of \mdline{5047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5047} +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +\mdline{5051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{5051} field. This behavior also matches \mdline{5051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5051} +RPC.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5054} +\subsubsection{\mdline{5054}13.3.1.\hspace*{0.5em}\mdline{5054}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={5056} +\noindent\mdline{5056}If a client asked to read \mdline{5056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{a,b,c,d\}}}}\mdline{5056} and \mdline{5056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}b}}}\mdline{5056} and \mdline{5056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}d}}}\mdline{5056} \mdline{5056}\emph{requests}\mdline{5056} didn\mdline{5056}'\mdline{5056}t +validate, the server will return entities corresponding to \mdline{5057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5057} and \mdline{5057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}c}}}\mdline{5057}, followed +by a status \mdline{5058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{p4.Error(OK),~p4.Error(xxx),~p4.Error(yyy),~p4.Error(OK)\}}}}\mdline{5058} in the +\mdline{5059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5059} field.%mdk + +%mdk-data-line={5061} +\mdline{5061}The P4Runtime server is not required to perform any optimization (\mdline{5061}e.g.\mdline{5061} merge two +\mdline{5062}\emph{requests}\mdline{5062} in the \mdline{5062}\emph{batch}\mdline{5062} if one is a subset of other). As a result of this, it +is possible for the \mdline{5063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5063} to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging.%mdk + +%mdk-data-line={5066} +\mdline{5066}There is no requirement that each request in the batch will correspond to one +\mdline{5067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5067} message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit.%mdk + +%mdk-data-line={5072} +\mdline{5072}A P4Runtime server must be prepared to handle multiple concurrent \mdline{5072}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5072} RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (\mdline{5077}e.g.\mdline{5077} in a single-threaded architecture), it may choose to serialize +\mdline{5078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5078} RPC processing.%mdk + +%mdk-data-line={5080} +\subsection{\mdline{5080}13.4.\hspace*{0.5em}\mdline{5080}Parallelism of Read and Write Requests}\label{sec-parallelism-of-read-and-write-requests}%mdk%mdk + +%mdk-data-line={5082} +\noindent\mdline{5082}A P4Runtime server may be implemented to serve at most one +\mdline{5083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5083} or \mdline{5083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5083} message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so.%mdk + +%mdk-data-line={5088} +\mdline{5088}For example, imagine a client that wanted to use \mdline{5088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5088} +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +\mdline{5092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5092} messages with only a few updates to an \mdline{5092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{5092} +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +\mdline{5095}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5095} batch currently being processed, but it will not +complete for a significant amount of time.%mdk + +%mdk-data-line={5098} +\mdline{5098}The restrictions on which a client may rely are:%mdk + +%mdk-data-line={5100} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5100} +\item\mdline{5100}The processing of any two \mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5100} messages \mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W1}}}\mdline{5100} and \mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W2}}}\mdline{5100} must +result in the same state as if one of them was completed before the +other began.%mdk + +%mdk-data-line={5103} +\item\mdline{5103}For any \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5103} \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5103} and any \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5103} \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5103}, \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5103} must +return results consistent with a state where \mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5104} has completed +processing, or \mdline{5105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5105} has not yet begun processing.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5107} +\noindent\mdline{5107}For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a \mdline{5110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5110} message it acquired a write lock for each stateful +object affected by the \mdline{5111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5111}, and before starting the +processing of a \mdline{5112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5112} message it acquired a read lock for each +stateful object accessed by the \mdline{5113}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5113}, such an implementation +meets all of the requirements above.%mdk + +%mdk-data-line={5116} +\mdline{5116}It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, \mdline{5118}e.g.\mdline{5118} if the server somehow determined that two +\mdline{5119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5119} messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly.%mdk + +%mdk-data-line={5125} +\section{\mdline{5125}14.\hspace*{0.5em}\mdline{5125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5125} RPC}\label{sec-setforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5127} +\noindent\mdline{5127}A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the \mdline{5128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig~RPC}}}\mdline{5128}. The request is defined as:%mdk + +%mdk-data-line={5130} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5131} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~SetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Action~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~VERIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~VERIFY\_AND\_SAVE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~VERIFY\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~~~COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~~~RECONCILE\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint64}}~role\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~Action~action~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5148} +\noindent\mdline{5148}The server is expected to perform the following checks (in this order) +before performing the required \mdline{5149}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{5149}:%mdk + +%mdk-data-line={5151} +\begin{enumerate}%mdk + +%mdk-data-line={5151} +\item{} +%mdk-data-line={5151} +\mdline{5151}If \mdline{5151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5151} does not match any of the devices known to the P4Runtime +server or if \mdline{5152}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{5152} does not match any of the roles for the device, the +server must return a \mdline{5153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5153} error.%mdk%mdk + +%mdk-data-line={5155} +\item{} +%mdk-data-line={5155} +\mdline{5155}If the client is not the master for (\mdline{5155}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5155}, \mdline{5155}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{5155}) according to the +\mdline{5156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5156} value, the server must return a \mdline{5156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5156} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5158} +\noindent\mdline{5158}The action is the type of configuration action requested, it can be one of:%mdk + +%mdk-data-line={5160} +\begin{itemize}%mdk + +%mdk-data-line={5160} +\item{} +%mdk-data-line={5160} +\mdline{5160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY}}}\mdline{5160}: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an \mdline{5161}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5161} +error if config is not provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5164} +\item{} +%mdk-data-line={5164} +\mdline{5164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5164}: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent \mdline{5166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5166} / \mdline{5166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5166} requests must refer to fields in the new +config. Returns an \mdline{5167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5167} error if the forwarding config is not +provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5170} +\item{} +%mdk-data-line={5170} +\mdline{5170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_COMMIT}}}\mdline{5170}: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an \mdline{5172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5172} error if the forwarding config is not provided or if the +provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5175} +\item{} +%mdk-data-line={5175} +\mdline{5175}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COMMIT}}}\mdline{5175}: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a \mdline{5178}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5178} error if no saved config +is found, \mdline{5179}i.e.\mdline{5179} if no \mdline{5179}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5179} action preceded this one. Returns an +\mdline{5180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5180} error if a config is provided with this message.%mdk%mdk + +%mdk-data-line={5182} +\item{} +%mdk-data-line={5182} +\mdline{5182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RECONCILE\_AND\_COMMIT}}}\mdline{5182}: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5188} error. For targets that support this option, an +\mdline{5189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5189} error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5193} +\noindent\mdline{5193}The \mdline{5193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5193} field is a message of type \mdline{5193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5193} that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(\mdline{5195}e.g.\mdline{5195} generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the\mdline{5196}~\mdref{sec-p4-fwd-pipe-config}{Forwarding-Pipeline +Configuration}\mdline{5197} section for details.%mdk + +%mdk-data-line={5199} +\mdline{5199}A P4Runtime server running on a non-programmable device may not +support \mdline{5200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5200} (\mdline{5200}e.g.\mdline{5200} the forwarding-pipeline +config is part of the device\mdline{5201}'\mdline{5201}s software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +\mdline{5203}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5203} error.%mdk + +%mdk-data-line={5205} +\section{\mdline{5205}15.\hspace*{0.5em}\mdline{5205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5205} RPC}\label{sec-getforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5207} +\noindent\mdline{5207}The forwarding-pipeline configuration of the target can be retrieved by invoking +the \mdline{5208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig~RPC}}}\mdline{5208}. The request is defined as:%mdk + +%mdk-data-line={5210} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5211} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~ResponseType~\{\\ +~~~~ALL~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~COOKIE\_ONLY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~P{\mdcolor{purple}4}INFO\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DEVICE\_CONFIG\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~ResponseType~response\_type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5223} +\noindent\mdline{5223}The \mdline{5223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5223} uniquely identifies the target P4 device. A \mdline{5223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5223} error is +returned if the \mdline{5224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5224} is not recognized by the P4Runtime server.%mdk + +%mdk-data-line={5226} +\mdline{5226}The \mdline{5226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5226} is used to specify which fields to populate in the response, +its value can be one of:%mdk + +%mdk-data-line={5229} +\begin{itemize}%mdk + +%mdk-data-line={5229} +\item{} +%mdk-data-line={5229} +\mdline{5229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5229}: returns a \mdline{5229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5229} with all fields +set as stored by the target. This is the default behaviour if the +\mdline{5231}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5231} field is not set.%mdk%mdk + +%mdk-data-line={5233} +\item{} +%mdk-data-line={5233} +\mdline{5233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COOKIE\_ONLY}}}\mdline{5233}: reply by setting only the \mdline{5233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5233} field in the +\mdline{5234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5234}, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message.%mdk%mdk + +%mdk-data-line={5238} +\item{} +%mdk-data-line={5238} +\mdline{5238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4INFO\_AND\_COOKIE}}}\mdline{5238}: reply by setting the \mdline{5238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{5238} and \mdline{5238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5238} fields.%mdk%mdk + +%mdk-data-line={5240} +\item{} +%mdk-data-line={5240} +\mdline{5240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEVICE\_CONFIG\_AND\_COOKIE}}}\mdline{5240}: reply by setting the \mdline{5240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5240} and +\mdline{5241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5241} fields.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5243} +\noindent\mdline{5243}The response contains the \mdline{5243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5243} for the specified device:%mdk + +%mdk-data-line={5245} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5246} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigResponse~\{\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5251} +\noindent\mdline{5251}If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level \mdline{5252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5252} field will be unset in the response. Examples are +(i) a server that only allows configuration via \mdline{5253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5253} +but this RPC hasn\mdline{5254}'\mdline{5254}t been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn\mdline{5255}'\mdline{5255}t yet occurred.%mdk + +%mdk-data-line={5257} +\mdline{5257}Once a forwarding-pipeline config is installed on the device (either via +\mdline{5258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5258} or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +\mdline{5260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.p4\_device\_config}}}\mdline{5260} will be empty / unset in the response, even if +\mdline{5261}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5261} in the request was set to \mdline{5261}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5261}. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the \mdline{5263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5263} RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +\mdline{5265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5265}, the value of \mdline{5265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.cookie}}}\mdline{5265} will be unset.%mdk + +%mdk-data-line={5267} +\mdline{5267}If a P4Runtime server supports both \mdline{5267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5267} as well as +returning the \mdline{5268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5268}, there should be read-write symmetry between +\mdline{5269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5269} and \mdline{5269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5269} RPCs.%mdk + +%mdk-data-line={5271} +\section{\mdline{5271}16.\hspace*{0.5em}\mdline{5271}P4Runtime Stream Messages}\label{sec-p4runtime-stream-messages}%mdk%mdk + +%mdk-data-line={5273} +\subsection{\mdline{5273}16.1.\hspace*{0.5em}\mdline{5273}Packet I/O}\label{sec-packet-i_o}%mdk%mdk + +%mdk-data-line={5275} +\noindent\mdline{5275}P4Runtime supports controller packet-in and packet-out by means of \mdline{5275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5275} +and \mdline{5276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5276} stream messages, respectively.%mdk + +%mdk-data-line={5278} +\mdline{5278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5278} messages are sent by the P4Runtime server to the client. Conversely, +\mdline{5279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5279} messages are sent by the client to the server. Any \mdline{5279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5279} +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a \mdline{5282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5282} message with the \mdline{5282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5282} field set to +report the error to the client. See the section on\mdline{5283}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{5284} for more information on \mdline{5284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5284}.%mdk + +%mdk-data-line={5286} +\mdline{5286}As introduced in the\mdline{5286}~\mdref{sec-controller-packet-meta}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\mdline{5286} +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with \mdline{5288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5288}. The expected metadata is described +in the P4Info using the \mdline{5289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5289} messages.%mdk + +%mdk-data-line={5291} +\mdline{5291}Both \mdline{5291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5291} and \mdline{5291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5291} stream messages share the same fields and are +defined as follows:%mdk + +%mdk-data-line={5294} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5295} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Packet~sent~from~the~controller~to~the~switch.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketOut~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~Packet~sent~from~the~switch~to~the~controller.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketIn~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~PacketMetadata~\{\\ +~~{\mdcolor{darkgreen}//~This~refers~to~Metadata.id~coming~from~P4Info~ControllerPacketMetadata.}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~metadata\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5314} +\begin{itemize}%mdk + +%mdk-data-line={5314} +\item{} +%mdk-data-line={5314} +\mdline{5314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}payload}}}\mdline{5314} is used to carry the full packet content, including the headers.%mdk%mdk + +%mdk-data-line={5316} +\item{} +%mdk-data-line={5316} +\mdline{5316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5316} is a repeated field of \mdline{5316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{5316} messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +\mdline{5319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5319}. Indeed, when a P4Runtime client (or server) +generates a \mdline{5320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5320} (or \mdline{5320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5320}) message, it needs to populate the +\mdline{5321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5321} field with as many values as in \mdline{5321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{5321} +for the packet-out (or packet-in) case. Each \mdline{5322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata.value}}}\mdline{5322} is a +binary string and must conform to the\mdline{5323}~\mdref{sec-bytestrings}{Bytestrings}\mdline{5323} +requirements based on the corresponding P4Info +\mdline{5325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{5325} specification. If the \mdline{5325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5325} field +does not match the P4Info specification, the server must drop the \mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5326} +message and may generate a \mdline{5327}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5327} message with the \mdline{5327}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5327} +field set to report the error to the client which issued the \mdline{5328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5328}. See +the section on\mdline{5329}~\mdref{sec-stream-error-reporting}{Stream Error Reporting}\mdline{5329} for more +information on \mdline{5330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5330}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5332} +\subsection{\mdline{5332}16.2.\hspace*{0.5em}\mdline{5332}Master Arbitration Update}\label{sec-master-arbitration-update}%mdk%mdk + +%mdk-data-line={5334} +\noindent\mdline{5334}P4Runtime\mdline{5334}'\mdline{5334}s master arbitration mechanism ensures that only the current master +can modify state on the switch, and that the \mdline{5335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5335} is monotonically +increasing. For example, the switch must finish all previous write operations +before changing masters, and must only accept write requests from the current +master.%mdk + +%mdk-data-line={5340} +\mdline{5340}As explained earlier in this document, the controller uses the \mdline{5340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5340} +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via \mdline{5342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5342} RPC), +it needs to start a controller session and become a \mdline{5343}\textquotedblleft{}master\textquotedblright{}\mdline{5343}. To do so, the +controller first opens a bidirectional stream channel to the server via +\mdline{5345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5345} for each device and sends a \mdline{5345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5345} message. The +controller populates the \mdline{5346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5346} field in this message using +its \mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{5347} and \mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5347} and the \mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5347} of the device, as explained +in detail in the\mdline{5348}~\mdref{sec-master-slave-arbitration-and-controller-replication}{Master-Slave Arbitration and Controller +Replication}\mdline{5349} +section. For any given \mdline{5350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role\_id)}}}\mdline{5350}, the P4Runtime server keeps track +of the highest \mdline{5351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5351} that it has ever received. If a controller\mdline{5351}'\mdline{5351}s +\mdline{5352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5352} is equal to the highest \mdline{5352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5352} that the server has ever +received, that controller is the master. All other controllers are slaves. Note +that it is possible that all controllers are slaves, and that there is no +master. There can be at most one master, because for any given +\mdline{5356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role\_id)}}}\mdline{5356}, each connected controller has a unique \mdline{5356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5356}.%mdk + +%mdk-data-line={5358} +\mdline{5358}This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest \mdline{5359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5359} after such a restart. +However, across a\mdline{5360}~\mdref{sec-restarts}{full restart}\mdline{5360}, the \mdline{5360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5360} must be +reset. In fact, a full restart is the only way to reset the \mdline{5361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5361}.%mdk + +%mdk-data-line={5363} +\mdline{5363}The \mdline{5363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5363} message is defined as follows:%mdk + +%mdk-data-line={5365} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5366} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Role~\{\\ +~~{\mdcolor{darkgreen}//~role\_id~for~this~role.~Defined~offline~in~agreement~across~the}\\ +~~{\mdcolor{darkgreen}//~entire~control~plane.}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Describes~the~role~configuration.}\\ +~~google.protobuf.Any~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~MasterArbitrationUpdate~\{\\ +~~{\mdcolor{darkgreen}//~Identifies~the~device~(aka~target~or~node~or~switching~chip).}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~The~role~for~which~the~mastership~is~being~arbitrated.}\\ +~~Role~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~The~election\_id~(unique~per~role).}\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Switch~populates~this~with~OK~for~the~client~that~is~the~master,}\\ +~~{\mdcolor{darkgreen}//~and~with~an~error~status~for~all~other~connected~clients~(at}\\ +~~{\mdcolor{darkgreen}//~every~mastership~change).~The~controller~does~not~populate~this}\\ +~~{\mdcolor{darkgreen}//~field.}\\ +~~google.{\bfseries{\mdcolor{navy}rpc}}.Status~status~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5389} +\noindent\mdline{5389}Note that the \mdline{5389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5389} field in the \mdline{5389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5389} message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a \mdline{5391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5391} message back to the controller, in which +it populates the \mdline{5392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5392} message using the \mdline{5392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5392}, +\mdline{5393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5393}, and \mdline{5393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5393} it previously received from the controller. The server +also populates the \mdline{5394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5394} field in the \mdline{5394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5394} according to +the rules in an\mdline{5395}~\mdref{sec-mastership-updates}{earlier section}\mdline{5395}.%mdk + +%mdk-data-line={5397} +\mdline{5397}The sender need not specify an \mdline{5397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5397}. If the \mdline{5397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5397} is not +specified, the sender\mdline{5398}'\mdline{5398}s \mdline{5398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5398} is considered lower than any +\mdline{5399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5399}, and the sender will thus never become master. This way, a +controller can choose to be a standby controller, in order to avoid master +\mdline{5401}\textquotedblleft{}flapping\textquotedblright{}\mdline{5401} (if a standby controller connects to the switch shortly before the +actual master controller, therefore becoming master temporarily).%mdk + +%mdk-data-line={5405} +\subsection{\mdline{5405}16.3.\hspace*{0.5em}\mdline{5405}Digest Messages}\label{sec-digest-messages}%mdk%mdk + +%mdk-data-line={5407} +\noindent\mdline{5407}See the\mdline{5407}~\mdref{sec-digestentry}{DigestEntry}\mdline{5407} section.%mdk + +%mdk-data-line={5409} +\subsection{\mdline{5409}16.4.\hspace*{0.5em}\mdline{5409}Table Idle Timeout Notification}\label{sec-table-idle-timeout-notification}%mdk%mdk + +%mdk-data-line={5411} +\noindent\mdline{5411}When a table supports idle timeout (as per the P4Info message), the master +client can specify a TTL value for each entry in the table (see +\mdline{5413}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{5413} section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an \mdline{5415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5415} message on the +\mdline{5416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5416} bidirectional stream to the master client. The master client can +then take the action of its choice, most likely remove the idle entry.%mdk + +%mdk-data-line={5419} +\mdline{5419}The \mdline{5419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5419} Protobuf message has the following fields:%mdk + +%mdk-data-line={5421} +\begin{itemize}%mdk + +%mdk-data-line={5421} +\item{} +%mdk-data-line={5421} +\mdline{5421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}timestamp}}}\mdline{5421}: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server\mdline{5422}'\mdline{5422}s local clock.%mdk%mdk + +%mdk-data-line={5424} +\item{} +%mdk-data-line={5424} +\mdline{5424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5424}: a repeated field of entries which have expired. Each individual +entry is identified by a single \mdline{5425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5425} message. For each \mdline{5425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5425}, +the \mdline{5426}\emph{key}\mdline{5426} fields (\mdline{5426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{5426}, \mdline{5426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{5426} and \mdline{5426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{5426}) must be set, along with +the \mdline{5427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{5427} field, the \mdline{5427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5427} field, and the +\mdline{5428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{5428} field. Other fields may be set by the server but should be +ignored by the client.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5431} +\noindent\mdline{5431}Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +\mdline{5433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5433} message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an \mdline{5438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5438} +message with an empty \mdline{5439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5439} repeated field.%mdk + +%mdk-data-line={5441} +\mdline{5441}After generating an idle notification, the P4Runtime server must \mdline{5441}\textquotedblleft{}reset\textquotedblright{}\mdline{5441} the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the master client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle.%mdk + +%mdk-data-line={5448} +\mdline{5448}Here is a reasonable pseudo-code implementation for idle timeout for table +entries:%mdk + +%mdk-data-line={5451} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5452} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutStream~stream;\\ +\\ +scanning\_interval~=~{\mdcolor{purple}10}ms;\\ +\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~{\mdcolor{darkgreen}//~iterate~over~all~tables~which~support~idle~timeout}\\ +~~{\bfseries{\mdcolor{navy}for}}~(table~in~tables)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(!table.idle\_timeout\_supported)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~{\mdcolor{darkgreen}//~we~coalesce~all~idle~notifications~for~the~same~table~in~one}\\ +~~~~{\mdcolor{darkgreen}//~message}\\ +~~~~IdleTimeoutNotification~msg;\\ +~~~~{\mdcolor{darkgreen}//~read~time\_since\_last\_hit~from~device}\\ +~~~~entries~=~device.load\_table\_entries\_from\_hw(table);\\ +~~~~{\bfseries{\mdcolor{navy}for}}~(entry~in~entries)~\{\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.idle\_timeout~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~TTL}\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.time\_since\_last\_hit~\textless{}~entry.idle\_timeout)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~~~msg.table\_entry\_add(entry);\\ +~~~~~~entry.reset\_time\_since\_last\_hit();\\ +~~~~\}\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(msg.table\_entry\_size()~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~notifications}\\ +~~~~msg.set\_timestamp(now());\\ +~~~~stream.write(msg);\\ +~~\}\\ +~~sleep(scanning\_interval);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5479} +\subsection{\mdline{5479}16.5.\hspace*{0.5em}\mdline{5479}Architecture-Specific Notifications}\label{sec-architecture-specific-notifications}%mdk%mdk + +%mdk-data-line={5481} +\noindent\mdline{5481}P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on \mdline{5482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5482}, by including an \mdline{5482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5482} Protobuf field\mdline{5482}~[\mdcite{protoany}{31}]\mdline{5482} +named \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5483} in both \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5483} and \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5483}. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the\mdline{5485}~\mdref{sec-digestentry}{PSA \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}} +extern}\mdline{5486}. See section on\mdline{5486}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{5487} for more information.%mdk + +%mdk-data-line={5489} +\subsection{\mdline{5489}16.6.\hspace*{0.5em}\mdline{5489}Stream Error Reporting}\label{sec-stream-error-reporting}%mdk%mdk + +%mdk-data-line={5491} +\noindent\mdline{5491}The P4Runtime server can asynchronously report errors which occur when +processing \mdline{5492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5492} messages, using the \mdline{5492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5492} message field (of +type \mdline{5493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5493}) in \mdline{5493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5493}. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature.%mdk + +%mdk-data-line={5497} +\mdline{5497}The \mdline{5497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5497} message has the following fields:%mdk + +%mdk-data-line={5499} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5499} +\item\mdline{5499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5499}, which must be set to the appropriate canonical error code +\mdline{5500}[\mdcite{grpcstatuscodes}{34}]\mdline{5500}.%mdk + +%mdk-data-line={5501} +\item\mdline{5501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{5501}, an optional developer-facing error message describing the error.%mdk + +%mdk-data-line={5502} +\item\mdline{5502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5502} and \mdline{5502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5502}, which are optional and can be used by vendors to provide +additional details on the error. \mdline{5503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5503} is a numeric error code drawn from a +vendor\mdline{5504}'\mdline{5504}s chosen error \mdline{5504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5504}.%mdk + +%mdk-data-line={5505} +\item\mdline{5505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5505}, which is a Protobuf \mdline{5505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5505} used to help the client identify which +\mdline{5506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5506} triggered the error. The server is required to set the +appropriate field in the \mdline{5507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5507} so that the client can identify which type +of stream message is responsible for the error (\mdline{5508}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5508}, +\mdline{5509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_list\_ack}}}\mdline{5509} or \mdline{5509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5509}), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid \mdline{5511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5511} message from the +client, the \mdline{5512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5512} field (of type \mdline{5512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError)}}}\mdline{5512} should be set in +the \mdline{5513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5513} \mdline{5513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5513}, and the server may additionally set the \mdline{5513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5513} +field in the \mdline{5514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError}}}\mdline{5514} sub-message (by copying it from the invalid +\mdline{5515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5515} message received on the stream channel) so that the client can +know exactly what packet-out triggered the error.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5518} +\noindent\mdline{5518}The appropriate canonical error code\mdline{5518}~[\mdcite{grpcstatuscodes}{34}]\mdline{5518} should be used when +populating the \mdline{5519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5519} field. For example:%mdk + +%mdk-data-line={5521} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5521} +\item\mdline{5521}if a controller is not allowed to send a \mdline{5521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5521} message under its +current role definition, the code should be set to \mdline{5522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5522}.%mdk + +%mdk-data-line={5523} +\item\mdline{5523}if the \mdline{5523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5523} repeated field in \mdline{5523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5523} does not match the P4Info +definition, the code should be set to \mdline{5524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5524}. It may be useful +for the server to set the \mdline{5525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5525} field in this case, so that the client +can find out which set of metadata fields triggered the error.%mdk + +%mdk-data-line={5527} +\item\mdline{5527}if the \mdline{5527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{5527} field in \mdline{5527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{5527} does not match any \mdline{5527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{5527} entry +in P4Info, the code should be set to \mdline{5528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5528}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5530} +\noindent\mdline{5530}The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, \mdline{5531}e.g.\mdline{5531} because of a +burst of \mdline{5532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5532} messages.%mdk + +%mdk-data-line={5534} +\mdline{5534}Note that master-arbitration errors are never reported using the \mdline{5534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5534} +message. Invalid \mdline{5535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5535} messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section\mdline{5537}~\mdref{sec-mastership-updates}{5.3}\mdline{5537}.%mdk + +%mdk-data-line={5539} +\subsubsection{\mdline{5539}16.6.1.\hspace*{0.5em}\mdline{5539}Examples of \mdline{5539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5539} Messages}\label{sec-examples-of-streamerror-messages}%mdk%mdk + +%mdk-data-line={5541} +\begin{itemize}%mdk + +%mdk-data-line={5541} +\item{} +%mdk-data-line={5541} +\mdline{5541}\textbf{Malformed packet-out metadata.}\mdline{5541} If the server receives a \mdline{5541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5541} +message with a \mdline{5542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5542} field with id 7 which is not included in the P4Info +\mdline{5543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5543} message for \mdline{5543}\textquotedblleft{}packet\_out\textquotedblright{}\mdline{5543}, the server may send the +following \mdline{5544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5544} back to the client:%mdk + +%mdk-data-line={5545} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5546} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Unknown~metadata~field~id~7.}{\mdcolor{maroon}"}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~copied~from~the~PacketOut~message~received~from~the~client}\\ +~~~packet\_out~\{\\ +~~~~~payload:~...\\ +~~~~~metadata~\{\\ +~~~~~~~id:~{\mdcolor{purple}7}\\ +~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}I\_should\_not\_be\_here}{\mdcolor{maroon}"}\\ +~~~~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~~\}\\ +~~~~~{\mdcolor{darkgreen}\#~more~metadata}\\ +~~~\}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={5564} +\item{} +%mdk-data-line={5564} +\mdline{5564}\textbf{Packet-out which exceeds the MTU.}\mdline{5564} If the server receives a \mdline{5564}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5564} +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following \mdline{5567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5567}:%mdk + +%mdk-data-line={5568} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5569} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Packet~exceeds~the~MTU~for~port.}{\mdcolor{maroon}"}\\ +~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendor1}{\mdcolor{maroon}"}\\ +~code:~{\mdcolor{purple}123}~~{\mdcolor{darkgreen}\#~MTU\_EXCEEDED}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~we~do~not~set~the~packet\_out~field~as~it~does~not~provide~any}\\ +~~~{\mdcolor{darkgreen}\#~extra~information~to~the~client}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5581} +\section{\mdline{5581}17.\hspace*{0.5em}\mdline{5581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5581} RPC}\label{sec-capabilities-rpc}%mdk%mdk + +%mdk-data-line={5583} +\noindent\mdline{5583}The \mdline{5583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5583} RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the \mdline{5585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesRequest}}}\mdline{5585} message is empty and the \mdline{5585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5585} +message only includes the \mdline{5586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_api\_version}}}\mdline{5586} string field. This field must +be set to the full semantic version string\mdline{5587}~[\mdcite{semver}{27}]\mdline{5587} corresponding to the +version of the P4Runtime API implemented by the server, \mdline{5588}e.g.\mdline{5588} \mdline{5588}\textquotedblleft{}1.1.0-rc.1\textquotedblright{}\mdline{5588}.%mdk + +%mdk-data-line={5590} +\mdline{5590}Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three\mdline{5591}~\mdref{sec-batch-atomicity}{atomicity +modes}\mdline{5592} for \mdline{5592}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5592} batches, two of them being +optional. In the future we may decide to leverage the \mdline{5593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5593} +message to enable the server to report to the client which subset of these +atomicity modes is supported.%mdk + +%mdk-data-line={5597} +\mdline{5597}The semantic version string included in \mdline{5597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5597} can be used by +the client to determine which exact feature set is implemented by the server, +since\mdline{5599}~\mdref{sec-p4runtime-versioning}{minor releases}\mdline{5599} may introduce new +functionality. However, because the \mdline{5600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5600} RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (\mdline{5602}i.e.\mdline{5602} an \mdline{5602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5602} error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0).%mdk + +%mdk-data-line={5606} +\section{\mdline{5606}18.\hspace*{0.5em}\mdline{5606}Portability Considerations}\label{sec-portability-considerations}%mdk%mdk + +%mdk-data-line={5608} +\subsection{\mdline{5608}18.1.\hspace*{0.5em}\mdline{5608}PSA Metadata Translation}\label{sec-psa-metadata-translation}%mdk%mdk + +%mdk-data-line={5610} +\noindent\mdline{5610}The \mdline{5610}\emph{Portable Switch Architecture}\mdline{5610} (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +\mdline{5614}[\mdcite{psatranslation}{24}]\mdline{5614}. For such metadata, a translation between the controller\mdline{5614}'\mdline{5614}s +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the \mdline{5618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5618} annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture.%mdk + +%mdk-data-line={5622} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={5623} +\noindent\mdline{5623}\includegraphics[keepaspectratio=true,height=7cm]{build/psa-metadata-translation}{}\mdline{5623}%mdk + +%mdk-data-line={5624} +\mdhr{}%mdk + +%mdk-data-line={5625} +\noindent\mdline{5625}\mdcaption{\textbf{Figure~\mdcaptionlabel{8}.}~\mdcaptiontext{P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdcenter}\label{fig-psa-metadata-translation}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={5629} +\noindent\mdline{5629}Figure\mdline{5629}~\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}}\mdline{5629} illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller\mdline{5635}'\mdline{5635}s 32 bit port +numbers to a target\mdline{5636}'\mdline{5636}s 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch.%mdk + +%mdk-data-line={5640} +\subsubsection{\mdline{5640}18.1.1.\hspace*{0.5em}\mdline{5640}Translation of Port Numbers}\label{sec-translation-of-port-numbers}%mdk%mdk + +%mdk-data-line={5642} +\noindent\mdline{5642}In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller\mdline{5643}'\mdline{5643}s space and the PSA device\mdline{5643}'\mdline{5643}s space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +\mdline{5647}\mdref{sec-user-defined-types}{user-defined P4 types}\mdline{5647}, namely \mdline{5647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5647} and +\mdline{5648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5648}, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in \mdline{5651}\emph{psa.p4}\mdline{5651} for +the PSA device in Switch 1.%mdk + +%mdk-data-line={5654} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5655} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_t;\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortIdInHeader\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~PortIdInHeader\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5661} +\noindent\mdline{5661}The first argument to the \mdline{5661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5661} annotation is a URI that +indicates to the P4Runtime server which numerical mapping\mdline{5662} \mdline{5662}\textemdash{}\mdline{5662} provided by the +out-of-band switch configuration mechanism\mdline{5663} \mdline{5663}\textemdash{}\mdline{5663} to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports).%mdk + +%mdk-data-line={5667} +\mdline{5667}An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows:%mdk + +%mdk-data-line={5673} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5674} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}enum}}~SdnPort~\{\\ +~~SDN\_PORT\_UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +\\ +~~{\mdcolor{darkgreen}//~SDN~ports~are~numbered~starting~from~1.}\\ +~~SDN\_PORT\_MIN~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\\ +~~{\mdcolor{darkgreen}//~The~maximum~value~of~an~SDN~port~(physical~or~logical).}\\ +~~SDN\_PORT\_MAX~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffeff};\\ +\\ +~~{\mdcolor{darkgreen}//~Reserved~SDN~port~numbers~(0xfffffff0~-~0xffffffff)}\\ +\\ +~~SDN\_PORT\_RECIRCULATE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffa};\\ +~~SDN\_PORT\_CPU~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffd};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5690} +\noindent\mdline{5690}The switch config will map \mdline{5690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_RECIRCULATE}}}\mdline{5690} and \mdline{5690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_CPU}}}\mdline{5690} \mdline{5690}\textemdash{}\mdline{5690} as well +as any SDN port number corresponding to a \mdline{5691}\textquotedblleft{}regular\textquotedblright{}\mdline{5691} front-panel port\mdline{5691} \mdline{5691}\textemdash{}\mdline{5691} to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation.%mdk + +%mdk-data-line={5695} +\mdline{5695}The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs.%mdk + +%mdk-data-line={5698} +\subsubsection{\mdline{5698}18.1.2.\hspace*{0.5em}\mdline{5698}Translation of Packet-IO Header Fields}\label{sec-translation-of-packet-io-header-fields}%mdk%mdk + +%mdk-data-line={5700} +\noindent\mdline{5700}Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:.%mdk + +%mdk-data-line={5703} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5704} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~PortIdInHeader\_t~egress\_port;\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~PortIdInHeader\_t~ingress\_port;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5715} +\noindent\mdline{5715}The header-level annotation \mdline{5715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5715} is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (\mdline{5719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5719}) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI\mdline{5723} \mdline{5723}\textemdash{}\mdline{5723} first argument to the \mdline{5723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5723} +annotation). Any subsequent reference to the \mdline{5724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5724} field in the +data plane will use the translated value. \mdline{5725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5725} is used in the +header definition instead of \mdline{5726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5726} to guarantee byte-aligned headers in +case this is required by the target.%mdk + +%mdk-data-line={5729} +\mdline{5729}A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target\mdline{5731}'\mdline{5731}s PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the \mdline{5733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ingress\_port}}}\mdline{5733} field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller.%mdk + +%mdk-data-line={5739} +\subsubsection{\mdline{5739}18.1.3.\hspace*{0.5em}\mdline{5739}Translation of Match Fields}\label{sec-translation-of-match-fields}%mdk%mdk + +%mdk-data-line={5741} +\noindent\mdline{5741}Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table\mdline{5742}'\mdline{5742}s match key as shown in the example below:%mdk + +%mdk-data-line={5744} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5745} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~istd.ingress\_port:~exact;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~ingress~port}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5755} +\noindent\mdline{5755}Table \mdline{5755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5755} has an exact match on PSA standard metadata ingress port +(\mdline{5756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}istd.ingress\_port}}}\mdline{5756}). Since the field is of type \mdline{5756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5756}, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in \mdline{5759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5759} from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table \mdline{5764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5764} is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values.%mdk + +%mdk-data-line={5768} +\mdline{5768}Note that it may be infeasible to translate the value-mask pair for ternary +matches: \mdline{5769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5769}, \mdline{5769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5769} or \mdline{5769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5769} match kinds. The P4Runtime server may +require that for these match kinds the port match be either \mdline{5770}\emph{de facto}\mdline{5770} \mdline{5770}\textquotedblleft{}exact\textquotedblright{}\mdline{5770} +(0xffffffff mask for \mdline{5771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5771}, prefix-length of 32 for \mdline{5771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5771}, or same low and +high bounds for \mdline{5772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5772}) or \mdline{5772}\textquotedblleft{}don't care\textquotedblright{}\mdline{5772}.%mdk + +%mdk-data-line={5774} +\subsubsection{\mdline{5774}18.1.4.\hspace*{0.5em}\mdline{5774}Translation of Action Parameters}\label{sec-translation-of-action-parameters}%mdk%mdk + +%mdk-data-line={5776} +\noindent\mdline{5776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5776} type parameters can be part of a P4 action definition as shown in the +example below:%mdk + +%mdk-data-line={5779} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5780} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.h.f:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~a;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5794} +\noindent\mdline{5794}The controller may write entries in table \mdline{5794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5794} with action \mdline{5794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5794} to set the egress +port as shown in the P4 code above. The action parameter \mdline{5795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5795} is of type +\mdline{5796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5796}, which leads to a 32-bit bitwidth for \mdline{5796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5796} being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device.%mdk + +%mdk-data-line={5802} +\subsubsection{\mdline{5802}18.1.5.\hspace*{0.5em}\mdline{5802}Port Translation for PSA Extern APIs}\label{sec-port-translation-for-psa-extern-apis}%mdk%mdk + +%mdk-data-line={5804} +\noindent\mdline{5804}The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch field is +of type \mdline{5810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5810} to carry the 32-bit SDN representation of the port being +watched. The P4Runtime server will translate the given watch port number into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device.%mdk + +%mdk-data-line={5815} +\mdline{5815}The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type \mdline{5817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5817} to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane.%mdk + +%mdk-data-line={5821} +\subsubsection{\mdline{5821}18.1.6.\hspace*{0.5em}\mdline{5821}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}\label{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}%mdk%mdk + +%mdk-data-line={5823} +\noindent\mdline{5823}P4Runtime supports using a translated value (\mdline{5823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5823} or any other translated +type for which the underlying built-in type is \mdline{5824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5824}) as an index to a +register, indirect counter, or indirect meter.%mdk + +%mdk-data-line={5827} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5828} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~counter~entry~type~}{\mdcolor{darkgreen}*/},~PortId\_t~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~index~type~}{\mdcolor{darkgreen}*/}\textgreater{}(\\ +~~{\mdcolor{purple}32}w1024,~PSA\_CounterType\_t.PACKETS)~counter;\\ +{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +~~counter.count(p);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5836} +\noindent\mdline{5836}This P4 Counter declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={5839} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5840} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counters~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x12000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}counter}{\mdcolor{maroon}"}\\ +~~\}\\ +~~spec~\{\\ +~~~~unit:~PACKETS\\ +~~\}\\ +~~index\_type\_name~\{\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5854} +\noindent\mdline{5854}The controller may read and write counter values from indexed counter \mdline{5854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter}}}\mdline{5854} +using SDN port numbers as indices, and not device-specific port numbers. The +\mdline{5856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{5856} field in the P4Info message is a signal to the P4Runtime +server that translation is required.%mdk + +%mdk-data-line={5859} +\section{\mdline{5859}19.\hspace*{0.5em}\mdline{5859}P4Runtime Versioning}\label{sec-p4runtime-versioning}%mdk%mdk + +%mdk-data-line={5861} +\noindent\mdline{5861}P4Runtime follows the Google guidelines for versioning cloud APIs +\mdline{5862}[\mdcite{apiversioning}{6}]\mdline{5862}. We use a \mdline{5862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR.MINOR.PATCH}}}\mdline{5862} style version number scheme and +we increment the:%mdk + +%mdk-data-line={5865} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5865} +\item\mdline{5865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5865} version when we make incompatible API changes,%mdk + +%mdk-data-line={5866} +\item\mdline{5866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MINOR}}}\mdline{5866} version when we add functionality in a backwards-compatible manner,%mdk + +%mdk-data-line={5867} +\item\mdline{5867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PATCH}}}\mdline{5867} version when we make backwards-compatible bug fixes.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5869} +\noindent\mdline{5869}The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is \mdline{5871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1}}}\mdline{5871} and the package +name for P4Info is \mdline{5872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1}}}\mdline{5872}. Even though \mdline{5872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5872} and \mdline{5872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5872} are two +different Protobuf packages, \mdline{5873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5873} depends on \mdline{5873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5873} and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence.%mdk + +%mdk-data-line={5877} +\mdline{5877}As recommended in\mdline{5877}~[\mdcite{apiversioning}{6}]\mdline{5877}, we may consider using pre-GA release +suffixes (such as \mdline{5878}\emph{alpha}\mdline{5878} or \mdline{5878}\emph{beta}\mdline{5878}) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1).%mdk + +%mdk-data-line={5882} +\mdline{5882}Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner.\mdline{5883}~[\mdcite{apiversioningbackwardscompatibility}{7}]\mdline{5883} describes +what constitute a backwards-compatible change. We expect \mdline{5884}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5884} version bumps +to be a \mdline{5885}\textbf{rare}\mdline{5885} event.%mdk + +%mdk-data-line={5887} +\mdline{5887}Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor\mdline{5892} \mdline{5892}+ patch version numbers in future releases.%mdk + +%mdk-data-line={5894} +\mdline{5894}All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository\mdline{5895}~[\mdcite{p4runtimerepo}{15}]\mdline{5895} and the version label follows +semantic versioning rules\mdline{5896}~[\mdcite{semver}{27}]\mdline{5896}.%mdk + +%mdk-data-line={5898} +\section{\mdline{5898}20.\hspace*{0.5em}\mdline{5898}Extending P4Runtime for non-PSA Architectures}\label{sec-extending-p4runtime}%mdk%mdk + +%mdk-data-line={5900} +\noindent\mdline{5900}P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place.%mdk + +%mdk-data-line={5908} +\mdline{5908}When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names:%mdk + +%mdk-data-line={5912} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5912} +\item\mdline{5912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/config/\textless{}major~version\textgreater{}/p4info.proto}}}\mdline{5912}%mdk + +%mdk-data-line={5913} +\item\mdline{5913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/\textless{}major~version\textgreater{}/p4runtime.proto}}}\mdline{5913}%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5915} +\noindent\mdline{5915}We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they \mdline{5916}\textquotedblleft{}extend\textquotedblright{}\mdline{5916}.%mdk + +%mdk-data-line={5918} +\mdline{5918}For the remainder of this section, we will refer to these two files as +\mdline{5919}\emph{p4info-ext}\mdline{5919} and \mdline{5919}\emph{p4runtime-ext}\mdline{5919} respectively.%mdk + +%mdk-data-line={5921} +\subsection{\mdline{5921}20.1.\hspace*{0.5em}\mdline{5921}Extending P4Runtime for Architecture-Specific Externs}\label{sec-extending-p4runtime-for-architecture-specific-externs}%mdk%mdk + +%mdk-data-line={5923} +\noindent\mdline{5923}Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both \mdline{5924}\emph{p4info-ext}\mdline{5924} and +\mdline{5925}\emph{p4runtime-ext}\mdline{5925}. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example:%mdk + +%mdk-data-line={5929} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5930} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~T~must~be~a~bit\textless{}W\textgreater{}~type,~it~indicates~the~width~of~each~counter~cell}\\ +{\bfseries{\mdcolor{navy}extern}}~MyNewPacketCounter\textless{}T\textgreater{}~\{\\ +~~counter({\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~size);\\ +~~increment({\bfseries{\mdcolor{navy}in}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~index);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5937} +\subsubsection{\mdline{5937}20.1.1.\hspace*{0.5em}\mdline{5937}Extending the P4Info message}\label{sec-extending-the-p4info-message}%mdk%mdk + +%mdk-data-line={5939} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5939} +\item\mdline{5939}Id prefixes \mdline{5939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0x81}}}\mdline{5939} through \mdline{5939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfe}}}\mdline{5939} are reserved for architecture-specific +externs. It is recommended that \mdline{5940}\emph{p4info-ext}\mdline{5940} include a \mdline{5940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Ids}}}\mdline{5940} message based +on the one in p4info.proto that the P4 compiler can refer to when\mdline{5941}~\mdref{sec-id-allocation}{assigning +IDs}\mdline{5942} to each extern instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5944} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5945} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~P{\mdcolor{purple}4}Ids~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Prefix~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~MY\_NEW\_PACKET\_COUNTER~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0x81};\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5953} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5953} +\item\mdline{5953}\emph{p4info-ext}\mdline{5953} should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +\mdline{5957}\mdref{sec-p4info-extern}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ExternInstance}}}}\mdline{5957} message as the \mdline{5957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{5957} +field, which is of type \mdline{5958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5958}~[\mdcite{protoany}{31}]\mdline{5958}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5960} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5961} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\mdcolor{darkgreen}//~corresponds~to~the~T~type~parameter~in~the~P4~extern~definition}\\ +~~p4.config.v1.P{\mdcolor{purple}4}DataTypeSpec~type\_spec~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~constructor~argument}\\ +~~{\bfseries{\mdcolor{navy}int64}}~size~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5969} +\subsubsection{\mdline{5969}20.1.2.\hspace*{0.5em}\mdline{5969}Extending the P4Runtime Service}\label{sec-extending-the-p4runtime-service}%mdk%mdk + +%mdk-data-line={5971} +\noindent\mdline{5971}Just like \mdline{5971}\emph{p4info-ext}\mdline{5971}, \mdline{5971}\emph{p4runtime-ext}\mdline{5971} should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an\mdline{5976}~\mdref{sec-extern-entry}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\mdline{5976} message generated by the +P4Runtime client.%mdk + +%mdk-data-line={5979} +\mdline{5979}Here is a possible Protobuf message for our \mdline{5979}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyNewPacketCounter}}}\mdline{5979} P4 extern:%mdk + +%mdk-data-line={5980} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5981} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~This~message~enables~reading~/~writing~data~to~the~counter~at~the~provided}\\ +{\mdcolor{darkgreen}//~index}\\ +{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~p4.v1.P{\mdcolor{purple}4}Data~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5989} +\noindent\mdline{5989}P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an \mdline{5990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5990} Protobuf field\mdline{5990}~[\mdcite{protoany}{31}]\mdline{5990} named \mdline{5990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5990} +in both \mdline{5991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{5991} and +\mdline{5992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{5992}. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in \mdline{5994}\emph{p4runtime-ext}\mdline{5994} and embed instances of these messages in +\mdline{5995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{5995} and \mdline{5995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{5995} as appropriate.%mdk + +%mdk-data-line={5997} +\subsection{\mdline{5997}20.2.\hspace*{0.5em}\mdline{5997}Architecture-Specific Table Extensions}\label{sec-architecture-specific-table-extensions}%mdk%mdk + +%mdk-data-line={5999} +\subsubsection{\mdline{5999}20.2.1.\hspace*{0.5em}\mdline{5999}New Match Types}\label{sec-new-match-types}%mdk%mdk + +%mdk-data-line={6001} +\noindent\mdline{6001}An architecture may introduce new table match types\mdline{6001}~[\mdcite{p4matchtypes}{12}]\mdline{6001}. P4Runtime +accounts for this by providing the following hooks:%mdk + +%mdk-data-line={6004} +\begin{itemize}%mdk + +%mdk-data-line={6004} +\item{} +%mdk-data-line={6004} +\mdline{6004}The \mdline{6004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{6004} field in \mdline{6004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{6004} (p4info.proto) is a \mdline{6004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6004} +which can be either one of the default match types (\mdline{6005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{6005}, \mdline{6005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{6005}, \mdline{6005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{6005}, +\mdline{6006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{6006}, or \mdline{6006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6006}) or an architecture-specific match type encoded as a +string.%mdk%mdk + +%mdk-data-line={6009} +\item{} +%mdk-data-line={6009} +\mdline{6009}The \mdline{6009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{6009} field in \mdline{6009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6009} (p4runtime.proto) is a +\mdline{6010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6010} which includes an \mdline{6010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6010} Protobuf message\mdline{6010}~[\mdcite{protoany}{31}]\mdline{6010} field +(\mdline{6011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6011}). \mdline{6011}\emph{p4info-ext}\mdline{6011} should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in \mdline{6014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6014} as the +\mdline{6015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6015} field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6018} +\subsubsection{\mdline{6018}20.2.2.\hspace*{0.5em}\mdline{6018}New Table Properties}\label{sec-new-table-properties}%mdk%mdk + +%mdk-data-line={6020} +\noindent\mdline{6020}An architecture may introduce additional table properties +\mdline{6021}[\mdcite{p4tableproperties}{30}]\mdline{6021}. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +\mdline{6023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Table}}}\mdline{6023} message includes the \mdline{6023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{6023} \mdline{6023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6023} Protobuf +field\mdline{6024}~[\mdcite{protoany}{31}]\mdline{6024}. At the moment, there is not any mechanism to extend the +\mdline{6025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.TableEntry}}}\mdline{6025} message based on the value of architecture-specific table +properties, but we may include on in future versions of the API.%mdk + +%mdk-data-line={6028} +\section{\mdline{6028}21.\hspace*{0.5em}\mdline{6028}Known Limitations of Current P4Runtime Version}\label{sec-known-limitations-of-current-p4runtime-version}%mdk%mdk + +%mdk-data-line={6030} +\begin{itemize}%mdk + +%mdk-data-line={6030} +\item{} +%mdk-data-line={6030} +\mdline{6030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6030}, action \mdline{6030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6030}, and controller packet metadata fields only +support unsigned bitstrings, \mdline{6031}i.e.\mdline{6031} values of one of the following types (not +the more general \mdline{6032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{6032}):%mdk + +%mdk-data-line={6033} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6033} +\item\mdline{6033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6033}%mdk + +%mdk-data-line={6034} +\item\mdline{6034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6034}. Note that as far as the \mdline{6034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Info}}}\mdline{6034} message contents and +thus controller software is concerned, such fields of type \mdline{6035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6035} +will be indistinguishable from those that have been declared with +type \mdline{6037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6037}. P4Runtime server software will automatically +perform any conversion needed between the type \mdline{6038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6038} values in +P4Runtime messages and the data plane representation.%mdk + +%mdk-data-line={6040} +\item\mdline{6040}an \mdline{6040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{6040} with underlying type \mdline{6040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6040}%mdk + +%mdk-data-line={6041} +\item\mdline{6041}a \mdline{6041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6041} or \mdline{6041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6041} with an underlying type that is one of the above (or +in general a \mdline{6042}\textquotedblleft{}chain\textquotedblright{}\mdline{6042} of \mdline{6042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6042} and/or \mdline{6042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6042} that eventually ends with +one of the types above)%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6045} +\item{} +%mdk-data-line={6045} +\mdline{6045}Support for PSA Random \mdline{6045}\&\mdline{6045} Timestamp externs is postponed to a future minor +version update.%mdk%mdk + +%mdk-data-line={6048} +\item{} +%mdk-data-line={6048} +\mdline{6048}P4Info does not include information about which of a table\mdline{6048}'\mdline{6048}s actions execute +which direct resource(s).%mdk%mdk + +%mdk-data-line={6051} +\item{} +%mdk-data-line={6051} +\mdline{6051}The default action for indirect match tables is restricted to a \mdline{6051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\\ +NoAction}}}\mdline{6052} known at compile-time.%mdk%mdk + +%mdk-data-line={6054} +\item{} +%mdk-data-line={6054} +\mdline{6054}There is no mechanism for changing the value of the \mdline{6054}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{6054} +table property at runtime.%mdk%mdk + +%mdk-data-line={6057} +\item{} +%mdk-data-line={6057} +\mdline{6057}There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor\mdline{6058} \mdline{6058}+ +patch version numbers.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6061} +\section{\mdline{6061}22.\hspace*{0.5em}\mdline{6061}Security concerns for P4Runtime}\label{sec-security-concerns-for-p4runtime}%mdk%mdk + +%mdk-data-line={6063} +\noindent\mdline{6063}Appropriate measures and security best practices need to be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client.%mdk + +%mdk-data-line={6070} +\section{\mdline{6070}A.\hspace*{0.5em}\mdline{6070}Appendix}\label{sec-appendix}%mdk%mdk + +%mdk-data-line={6072} +\subsection{\mdline{6072}A.1.\hspace*{0.5em}\mdline{6072}Revision History}\label{sec-revision-history}%mdk%mdk + +%mdk-data-line={6074} +\subsubsection{\mdline{6074}A.1.1.\hspace*{0.5em}\mdline{6074}Changes in v1.2.0}\label{sec-changes-in-v120}%mdk%mdk + +%mdk-data-line={6076} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6076} +\item\mdline{6076}Add new \mdline{6076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6076} match kind. At the moment, \mdline{6076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6076} is only supported by +the v1model architecture\mdline{6077}~[\mdcite{v1model}{38}]\mdline{6077}, and not by PSA. It will eventually be +included in the core P4 language.%mdk + +%mdk-data-line={6079} +\item\mdline{6079}Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists.%mdk + +%mdk-data-line={6081} +\item\mdline{6081}Add a new \mdline{6081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6081} field of type \mdline{6081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{6081} to \mdline{6081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{6081}. This is more +flexible than the now deprecated \mdline{6082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{6082} field.%mdk + +%mdk-data-line={6083} +\item\mdline{6083}Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +\mdline{6085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6085} annotation.%mdk + +%mdk-data-line={6086} +\item\mdline{6086}Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature.%mdk + +%mdk-data-line={6088} +\item\mdline{6088}Support using \mdline{6088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{6088} as the controller type in the \mdline{6088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6088} +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type.%mdk + +%mdk-data-line={6091} +\item\mdline{6091}Add optional P4 source locations to both structured and unstructured +annotations.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6094} +\subsubsection{\mdline{6094}A.1.2.\hspace*{0.5em}\mdline{6094}Changes in v1.1.0}\label{sec-changes-in-v110}%mdk%mdk + +%mdk-data-line={6096} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6096} +\item\mdline{6096}Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously.%mdk + +%mdk-data-line={6102} +\item\mdline{6102}Add \mdline{6102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{6102} field to stream messages sent by the server.%mdk + +%mdk-data-line={6103} +\item\mdline{6103}Add \mdline{6103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6103} RPC to query the P4Runtime API version implemented by the +server.%mdk + +%mdk-data-line={6105} +\item\mdline{6105}Support wildcard reads for multicast groups and clone sessions.%mdk + +%mdk-data-line={6106} +\item\mdline{6106}Support for modifying direct resources of const tables.%mdk + +%mdk-data-line={6107} +\item\mdline{6107}Support P4 user-defined types for Packet IO metadata fields.%mdk + +%mdk-data-line={6108} +\item\mdline{6108}Clarify consistency requirements for \mdline{6108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6108} and \mdline{6108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{6108} RPCs.%mdk + +%mdk-data-line={6109} +\item\mdline{6109}Add Appendix providing implementation advice for avoiding common pitfalls: + +%mdk-data-line={6110} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6110} +\item\mdline{6110}advice on setting gRPC Metadata Maximum Size%mdk + +%mdk-data-line={6111} +\item\mdline{6111}advice on setting gRPC Server Maximum Receive Message Size%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6112} +\item\mdline{6112}Clarify limitations on supported types for \mdline{6112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6112}, action \mdline{6112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6112}, and +Packet IO metadata fields.%mdk + +%mdk-data-line={6114} +\item\mdline{6114}Clarify that reading entire forwarding state with empty \mdline{6114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{6114} is not +supported.%mdk + +%mdk-data-line={6116} +\item\mdline{6116}Document that \mdline{6116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6116} need only be supported when applied to +type declarations in P4.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6119} +\subsection{\mdline{6119}A.2.\hspace*{0.5em}\mdline{6119}P4 Annotations}\label{sec-p4-annotations}%mdk%mdk + +%mdk-data-line={6121} +\noindent\mdline{6121}Table\mdline{6121}~\mdref{tab-p4-annotations}{\mdcaptionlabel{7}}\mdline{6121} lists P4\mdline{6121}\mdsub{16}\mdline{6121} annotations introduced primarily for +the purpose of adding features for the P4Runtime API.%mdk + +%mdk-data-line={6124} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{6126} Annotation}}&\multicolumn{1}{|c|}{{\bfseries\mdline{6126} Description}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{6128} \mdline{6128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{6128}}&\multicolumn{1}{|l|}{\mdline{6128} See section\mdline{6128}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6128}}\\ +\multicolumn{1}{|l}{\mdline{6129} \mdline{6129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{6129}}&\multicolumn{1}{|l|}{\mdline{6129} See section\mdline{6129}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{6129}}\\ +\multicolumn{1}{|l}{\mdline{6130} \mdline{6130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{6130}}&\multicolumn{1}{|l|}{\mdline{6130} See section\mdline{6130}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6130}}\\ +\multicolumn{1}{|l}{\mdline{6131} \mdline{6131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6131}}&\multicolumn{1}{|l|}{\mdline{6131} See section\mdline{6131}~\mdref{sec-id-allocation}{6.3}\mdline{6131}}\\ +\multicolumn{1}{|l}{\mdline{6132} \mdline{6132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{6132}}&\multicolumn{1}{|l|}{\mdline{6132} See sections\mdline{6132}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{6132},\mdline{6132}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{6132}}\\ +\multicolumn{1}{|l}{\mdline{6133} \mdline{6133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{6133}}&\multicolumn{1}{|l|}{\mdline{6133} See section\mdline{6133}~\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1}\mdline{6133}}\\ +\multicolumn{1}{|l}{\mdline{6134} \mdline{6134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6134}}&\multicolumn{1}{|l|}{\mdline{6134} See sections\mdline{6134}~\mdref{sec-user-defined-types}{8.5.6}\mdline{6134},\mdline{6134}~\mdref{sec-translation-of-port-numbers}{18.1.1}\mdline{6134}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={6136} +\mdhr{}%mdk + +%mdk-data-line={6137} +\noindent\mdline{6137}\mdcaption{\textbf{Table~\mdcaptionlabel{7}.}~\mdcaptiontext{P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-annotations}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={6140} +\subsection{\mdline{6140}A.3.\hspace*{0.5em}\mdline{6140}A More Complex Value Set Example}\label{sec-value-set-example}%mdk%mdk + +%mdk-data-line={6142} +\noindent\mdline{6142}This section includes a more complex Value Set example, with multiple matches of +different kinds.%mdk + +%mdk-data-line={6145} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6146} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6155} +\noindent\mdline{6155}This P4 Value Set declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={6158} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6159} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6186} +\noindent\mdline{6186}A P4Runtime client can set the membership for this Value Set with \mdline{6186}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6186} +messages similar to this one:%mdk + +%mdk-data-line={6189} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6190} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xac}~\}\\ +~~~~~~\}\\ +~~~~~~{\mdcolor{darkgreen}\#~match~for~field\_id~2~is~missing~=\textgreater{}~don't~care~match}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xdc}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~~~ternary~\{~value:~{\mdcolor{purple}0x88}~mask:~{\mdcolor{purple}8}f~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6224} +\subsection{\mdline{6224}A.4.\hspace*{0.5em}\mdline{6224}Guidelines for Implementations}\label{sec-guidelines-for-implementations}%mdk%mdk + +%mdk-data-line={6226} +\noindent\mdline{6226}This section contains practical advice for implementing P4Runtime clients and +servers.%mdk + +%mdk-data-line={6229} +\subsubsection{\mdline{6229}A.4.1.\hspace*{0.5em}\mdline{6229}gRPC Metadata Maximum Size}\label{sec-grpc-metadata-maximum-size}%mdk%mdk + +%mdk-data-line={6231} +\noindent\mdline{6231}In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the \mdline{6232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6232} gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the \mdline{6233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6233} P4Runtime RPC. The \mdline{6233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6233} RPC +returns an individual error for every item in a batch (see Section +\mdline{6235}\mdref{sec-write-rpc}{12}\mdline{6235}), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +\mdline{6237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{6237} error, without any of the individual errors.%mdk + +%mdk-data-line={6239} +\mdline{6239}To fix this problem, one can set the \mdline{6239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6239} option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it\mdline{6241}'\mdline{6241}s +limit, as only the receiving side\mdline{6242}'\mdline{6242}s limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every \mdline{6244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{6244}, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +\mdline{6246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}8192~+~MAX\_UPDATES\_PER\_WRITE~*~100}}}\mdline{6246} bytes of metadata.%mdk + +%mdk-data-line={6248} +\mdline{6248}For example, in C++, one can create a client channel as follows:%mdk + +%mdk-data-line={6249} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6250} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}~=~{\mdcolor{purple}100};\\ +::{\mdcolor{navy}grpc::}ChannelArguments~arguments;\\ +arguments{\bfseries{\mdcolor{navy}.}}SetInt({\mdcolor{teal}GRPC\_ARG\_MAX\_METADATA\_SIZE},~{\mdcolor{purple}8192}~+~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}*{\mdcolor{purple}100});\\ +{\bfseries{\mdcolor{navy}return}}~{\mdcolor{navy}grpc::}CreateCustomChannel(address,~credentials,~arguments);}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6256} +\subsubsection{\mdline{6256}A.4.2.\hspace*{0.5em}\mdline{6256}gRPC Server Maximum Receive Message Size}\label{sec-grpc-server-maximum-receive-message-size}%mdk%mdk + +%mdk-data-line={6258} +\noindent\mdline{6258}At the time of writing, the default maximum receive message size in gRPC is 4MB +\mdline{6259}\textemdash{}\mdline{6259} while the default maximum send message size is unlimited. This can be a +problem for the \mdline{6260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{6260} RPC, since for some targets the +binary \mdline{6261}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6261} can exceed 4MB, in which case by default the P4Runtime +server would return an \mdline{6262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6262} error. To a lesser extent, this may +affect the \mdline{6263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6263} RPC as well, in case of extremely large batches.%mdk + +%mdk-data-line={6265} +\mdline{6265}To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of \mdline{6267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6267} for their target(s). This can be done by +setting the \mdline{6268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_receive\_message\_length}}}\mdline{6268} when building the gRPC server.%mdk + +%mdk-data-line={6270} +\mdline{6270}For example, in C++, one can set the maximum receive message size as follows:%mdk + +%mdk-data-line={6271} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6272} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE}~=~{\mdcolor{purple}128}~*~{\mdcolor{purple}1024}~*~{\mdcolor{purple}1024};~~{\mdcolor{darkgreen}//~128MB}\\ +::{\mdcolor{navy}grpc::}ServerBuilder~server\_builder;\\ +builder{\bfseries{\mdcolor{navy}.}}AddListeningPort({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});\\ +builder{\bfseries{\mdcolor{navy}.}}RegisterService({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});~~{\mdcolor{darkgreen}//~register~P4Runtime~service}\\ +builder{\bfseries{\mdcolor{navy}.}}SetMaxReceiveMessageSize({\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE});\\ +builder{\bfseries{\mdcolor{navy}.}}BuildAndStart();}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6280} +\noindent\mdline{6280}On the client side, we recommend that P4Runtime clients do not use \mdline{6280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6280} +batches larger than the default maximum receive message size (4MB)\mdline{6281} \mdline{6281}\textemdash{}\mdline{6281} in case +the server did not deem necessary to increase the default value\mdline{6282} \mdline{6282}\textemdash{}\mdline{6282}, unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB).%mdk + +%mdk-data-line={6288;build/P4Runtime-Spec-bib.bbl.mdk:1} +%mdk-data-line={6288;build/P4Runtime-Spec-bib.bbl.mdk:2} +\mdsetrefname{References}%mdk +{\mdbibindent{0}%mdk +\begin{thebibliography}{39}%mdk +\label{sec-bibliography}%mdk + +%mdk-data-line={references.bib:68} +\bibitem{p4spec}\mdbibitemlabel{{}[1]}\textquotedblleft{}$P4_{16}$ 1.2.1 Specification.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html}}.\label{p4spec}%mdk%mdk + +%mdk-data-line={references.bib:134} +\bibitem{rfc2698}\mdbibitemlabel{{}[2]}\textquotedblleft{}A Two Rate Three Color Marker.\textquotedblright{} \href{https://tools.ietf.org/html/rfc2698}{{\ttfamily https://\hspace{0pt}tools.\hspace{0pt}ietf.\hspace{0pt}org/\hspace{0pt}html/\hspace{0pt}rfc2698}}.\label{rfc2698}%mdk%mdk + +%mdk-data-line={references.bib:32} +\bibitem{p4complextypes}\mdbibitemlabel{{}[3]}\textquotedblleft{}Complex Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-p4-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}p4-\hspace{0pt}type}}.\label{p4complextypes}%mdk%mdk + +%mdk-data-line={references.bib:37} +\bibitem{protodefaults}\mdbibitemlabel{{}[4]}\textquotedblleft{}Default Values for Protobuf 3 ($proto3$) Fields.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23default}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}default}}.\label{protodefaults}%mdk%mdk + +%mdk-data-line={references.bib:78} +\bibitem{p4enums}\mdbibitemlabel{{}[5]}\textquotedblleft{}Enums in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-enum-types}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}enum-\hspace{0pt}types}}.\label{p4enums}%mdk%mdk + +%mdk-data-line={references.bib:119} +\bibitem{apiversioning}\mdbibitemlabel{{}[6]}\textquotedblleft{}Google Cloud APIs Versioning.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning}}.\label{apiversioning}%mdk%mdk + +%mdk-data-line={references.bib:124} +\bibitem{apiversioningbackwardscompatibility}\mdbibitemlabel{{}[7]}\textquotedblleft{}Google Cloud APIs Versioning - Backwards-Compatibility.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning\%23backwards_compatibility}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning\#\hspace{0pt}backwards\_\hspace{0pt}compatibility}}.\label{apiversioningbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:149} +\bibitem{grpcauth}\mdbibitemlabel{{}[8]}\textquotedblleft{}gRPC Authentication.\textquotedblright{} \href{https://grpc.io/docs/guides/auth.html}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}guides/\hspace{0pt}auth.\hspace{0pt}html}}.\label{grpcauth}%mdk%mdk + +%mdk-data-line={references.bib:7} +\bibitem{grpc}\mdbibitemlabel{{}[9]}\textquotedblleft{}gRPC Main Site.\textquotedblright{} \href{https://grpc.io}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io}}.\label{grpc}%mdk%mdk + +%mdk-data-line={references.bib:144} +\bibitem{grpcstreamc}\mdbibitemlabel{{}[10]}\textquotedblleft{}gRPC Streaming RPCs in C++.\textquotedblright{} \href{https://grpc.io/docs/tutorials/basic/c.html\%23streaming-rpcs}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}tutorials/\hspace{0pt}basic/\hspace{0pt}c.\hspace{0pt}html\#\hspace{0pt}streaming-\hspace{0pt}rpcs}}.\label{grpcstreamc}%mdk%mdk + +%mdk-data-line={references.bib:114} +\bibitem{p4newtypes}\mdbibitemlabel{{}[11]}\textquotedblleft{}Introducing New Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-newtype}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}newtype}}.\label{p4newtypes}%mdk%mdk + +%mdk-data-line={references.bib:139} +\bibitem{p4matchtypes}\mdbibitemlabel{{}[12]}\textquotedblleft{}Match Types in P4.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-match-kind-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}match-\hspace{0pt}kind-\hspace{0pt}type}}.\label{p4matchtypes}%mdk%mdk + +%mdk-data-line={references.bib:194} +\bibitem{p4annotations}\mdbibitemlabel{{}[13]}\textquotedblleft{}P4 Annotations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-annotations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}annotations}}.\label{p4annotations}%mdk%mdk + +%mdk-data-line={references.bib:174} +\bibitem{p4concurrency}\mdbibitemlabel{{}[14]}\textquotedblleft{}P4 Concurrency Model.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-concurrency}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}concurrency}}.\label{p4concurrency}%mdk%mdk + +%mdk-data-line={references.bib:1} +\bibitem{p4runtimerepo}\mdbibitemlabel{{}[15]}\textquotedblleft{}p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.\textquotedblright{} \href{https://github.com/p4lang/p4runtime}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4runtime}}.\label{p4runtimerepo}%mdk%mdk + +%mdk-data-line={references.bib:42} +\bibitem{pirepo}\mdbibitemlabel{{}[16]}\textquotedblleft{}p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.\textquotedblright{} \href{https://github.com/p4lang/PI}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}PI}}.\label{pirepo}%mdk%mdk + +%mdk-data-line={references.bib:109} +\bibitem{p4apiwgcharter}\mdbibitemlabel{{}[17]}\textquotedblleft{}P4.org API Working Group Charter.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4_API_WG_charter.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4\_\hspace{0pt}API\_\hspace{0pt}WG\_\hspace{0pt}charter.\hspace{0pt}html}}.\label{p4apiwgcharter}%mdk%mdk + +%mdk-data-line={references.bib:154} +\bibitem{p4actionannotations}\mdbibitemlabel{{}[18]}\textquotedblleft{}P4 Standard Annotations on Table Actions.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-action-anno}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}action-\hspace{0pt}anno}}.\label{p4actionannotations}%mdk%mdk + +%mdk-data-line={references.bib:73} +\bibitem{psa}\mdbibitemlabel{{}[19]}\textquotedblleft{}Portable Switch Architecture Specification (v1.1.0).\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html}}.\label{psa}%mdk%mdk + +%mdk-data-line={references.bib:189} +\bibitem{protooneofbackwardscompatibility}\mdbibitemlabel{{}[20]}\textquotedblleft{}Protobuf OneOf Backwards-Compatibility Issues.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23backwards-compatibility-issues}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}backwards-\hspace{0pt}compatibility-\hspace{0pt}issues}}.\label{protooneofbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:12} +\bibitem{proto}\mdbibitemlabel{{}[21]}\textquotedblleft{}Protocol Buffers Main Site.\textquotedblright{} \href{https://developers.google.com/protocol-buffers}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers}}.\label{proto}%mdk%mdk + +%mdk-data-line={references.bib:159} +\bibitem{psaactionselector}\mdbibitemlabel{{}[22]}\textquotedblleft{}PSA Action Selector.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-action-selector}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}action-\hspace{0pt}selector}}.\label{psaactionselector}%mdk%mdk + +%mdk-data-line={references.bib:169} +\bibitem{psaatomicityofcontrolplaneops}\mdbibitemlabel{{}[23]}\textquotedblleft{}PSA Atomicity of Control Plane Operations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-atomicity-of-control-plane-api-operations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}atomicity-\hspace{0pt}of-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}api-\hspace{0pt}operations}}.\label{psaatomicityofcontrolplaneops}%mdk%mdk + +%mdk-data-line={references.bib:179} +\bibitem{psatranslation}\mdbibitemlabel{{}[24]}\textquotedblleft{}PSA Data Plane vs Control Plane Types.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-data-plane-vs-control-plane-values}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}data-\hspace{0pt}plane-\hspace{0pt}vs-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}values}}.\label{psatranslation}%mdk%mdk + +%mdk-data-line={references.bib:164} +\bibitem{psaemptygroupactionappendix}\mdbibitemlabel{{}[25]}\textquotedblleft{}PSA Empty Group Action Appendix.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23appendix-empty-action-selector-groups}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}appendix-\hspace{0pt}empty-\hspace{0pt}action-\hspace{0pt}selector-\hspace{0pt}groups}}.\label{psaemptygroupactionappendix}%mdk%mdk + +%mdk-data-line={references.bib:58} +\bibitem{p4selectexpr}\mdbibitemlabel{{}[26]}\textquotedblleft{}Select Expressions in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-select}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}select}}.\label{p4selectexpr}%mdk%mdk + +%mdk-data-line={references.bib:129} +\bibitem{semver}\mdbibitemlabel{{}[27]}\textquotedblleft{}Semantic Versioning.\textquotedblright{} \href{https://semver.org/}{{\ttfamily https://\hspace{0pt}semver.\hspace{0pt}org/\hspace{0pt}}}.\label{semver}%mdk%mdk + +%mdk-data-line={references.bib:98} +\bibitem{protostatus}\mdbibitemlabel{{}[28]}\textquotedblleft{}Status.proto:the Protobuf Status Message.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}src/\hspace{0pt}proto/\hspace{0pt}grpc/\hspace{0pt}status/\hspace{0pt}status.\hspace{0pt}proto}}.\label{protostatus}%mdk%mdk + +%mdk-data-line={references.bib:63} +\bibitem{p4revisions110}\mdbibitemlabel{{}[29]}\textquotedblleft{}Summary of Changes Made in $P4_{16}$ Version 1.1.0.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-summary-of-changes-made-in-version-110}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}summary-\hspace{0pt}of-\hspace{0pt}changes-\hspace{0pt}made-\hspace{0pt}in-\hspace{0pt}version-\hspace{0pt}110}}.\label{p4revisions110}%mdk%mdk + +%mdk-data-line={references.bib:48} +\bibitem{p4tableproperties}\mdbibitemlabel{{}[30]}\textquotedblleft{}Table Properties in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-props}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}props}}.\label{p4tableproperties}%mdk%mdk + +%mdk-data-line={references.bib:83} +\bibitem{protoany}\mdbibitemlabel{{}[31]}\textquotedblleft{}The Any Protobuf Message.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23any}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}any}}.\label{protoany}%mdk%mdk + +%mdk-data-line={references.bib:88} +\bibitem{grpcstatus}\mdbibitemlabel{{}[32]}\textquotedblleft{}The gRPC $Status$ Class.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/status.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}impl/\hspace{0pt}codegen/\hspace{0pt}status.\hspace{0pt}h}}.\label{grpcstatus}%mdk%mdk + +%mdk-data-line={references.bib:104} +\bibitem{grpcerrordetails}\mdbibitemlabel{{}[33]}\textquotedblleft{}The gRPC C++ Error Details Library.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/support/error_details.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}support/\hspace{0pt}error\_\hspace{0pt}details.\hspace{0pt}h}}.\label{grpcerrordetails}%mdk%mdk + +%mdk-data-line={references.bib:93} +\bibitem{grpcstatuscodes}\mdbibitemlabel{{}[34]}\textquotedblleft{}The gRPC Canonical Status Codes.\textquotedblright{} \href{https://developers.google.com/maps-booking/reference/grpc-api/status_codes}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}maps-\hspace{0pt}booking/\hspace{0pt}reference/\hspace{0pt}grpc-\hspace{0pt}api/\hspace{0pt}status\_\hspace{0pt}codes}}.\label{grpcstatuscodes}%mdk%mdk + +%mdk-data-line={references.bib:22} +\bibitem{openconfig}\mdbibitemlabel{{}[35]}\textquotedblleft{}The OpenConfig Project.\textquotedblright{} \href{http://openconfig.net}{{\ttfamily http://\hspace{0pt}openconfig.\hspace{0pt}net}}.\label{openconfig}%mdk%mdk + +%mdk-data-line={references.bib:184} +\bibitem{protomessagedifferencer}\mdbibitemlabel{{}[36]}\textquotedblleft{}The Protobuf MessageDifferencer in the C++ API.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.util.message_differencer}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}reference/\hspace{0pt}cpp/\hspace{0pt}google.\hspace{0pt}protobuf.\hspace{0pt}util.\hspace{0pt}message\_\hspace{0pt}differencer}}.\label{protomessagedifferencer}%mdk%mdk + +%mdk-data-line={references.bib:27} +\bibitem{stratum}\mdbibitemlabel{{}[37]}\textquotedblleft{}The Stratum Project.\textquotedblright{} \href{https://stratumproject.org/}{{\ttfamily https://\hspace{0pt}stratumproject.\hspace{0pt}org/\hspace{0pt}}}.\label{stratum}%mdk%mdk + +%mdk-data-line={references.bib:199} +\bibitem{v1model}\mdbibitemlabel{{}[38]}\textquotedblleft{}v1model Architecture Definition.\textquotedblright{} \href{https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4c/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}p4include/\hspace{0pt}v1model.\hspace{0pt}p4}}.\label{v1model}%mdk%mdk + +%mdk-data-line={references.bib:53} +\bibitem{p4valuesets}\mdbibitemlabel{{}[39]}\textquotedblleft{}Value Sets in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-value-set}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}value-\hspace{0pt}set}}.\label{p4valuesets}%mdk%mdk +\par%mdk +\end{thebibliography}}%mdk%mdk +}%mdk + + +\end{document} diff --git a/spec/v1.2.0-rc.1/ellipse.sty b/spec/v1.2.0-rc.1/ellipse.sty new file mode 100644 index 00000000..7c0ecb3e --- /dev/null +++ b/spec/v1.2.0-rc.1/ellipse.sty @@ -0,0 +1,318 @@ +%% +%% This is file `ellipse.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ellipse.dtx (with options: `package') +%% +%% Copyright (C) 2015 +%% Daan Leijen +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". +%% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{ellipse} + [2004/11/05 v1.0 .dtx ellipse file] +\RequirePackage{pict2e} + +\providecommand*\pIIe@csedef[1]{\expandafter\edef\csname #1\endcsname} +\newcommand*\pIIe@ellip@csqrt[3]{% + \@ovxx=#1\relax + \ifdim\@ovxx<\z@\@ovxx-\@ovxx\fi + \@ovyy=#2\relax + \ifdim\@ovyy<\z@\@ovyy-\@ovyy\fi + \edef\pIIe@csname{@csqrt(\number\@ovxx,\number\@ovyy)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@ellip@csqrt@% + \pIIe@csedef{\pIIe@csname}{\the\dimen@}% + #3\dimen@ + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} +\newcommand*\pIIe@ellip@csqrt@{% + \@ovdx\@ovxx + \advance\@ovdx by \@ovyy + \dimen@0.7071067\@ovdx + \ifdim\dimen@<\@ovyy\dimen@\@ovyy\fi + \ifdim\dimen@<\@ovxx\dimen@\@ovxx\fi + \ifdim\@ovdx<128\p@ + \edef\@tempa{\strip@pt\@ovxx}% + \@ovxx\@tempa\@ovxx + \edef\@tempa{\strip@pt\@ovyy}% + \@ovyy\@tempa\@ovyy + \advance\@ovxx by \@ovyy + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \fi +} + +\newcommand*\pIIe@atan@{% + \@tempdima\dimen@ + \@tempdimb\@tempdima + \ifdim\@tempdimb<\z@\@tempdimb-\@tempdimb\fi + \dimen@0.0663\@tempdimb + \advance\dimen@ 0.2447pt\relax + \advance\@tempdimb -1pt\relax + \edef\@tempa{\strip@pt\@tempdimb}% + \dimen@\@tempa\dimen@ + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \dimen@-\dimen@ + \advance\dimen@ 0.7853\@tempdima +} + +\newcommand*\pIIe@atantwo[3]{% + \edef\pIIe@csname{@atan2(\number\dimexpr#1\relax,\number\dimexpr#2\relax)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@atantwo@{#1}{#2}{#3}% + \pIIe@csedef{\pIIe@csname}{\the\dimexpr#3\relax}% + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} + +\newcommand*\pIIe@atantwo@[3]{% + \@tempdima\dimexpr#2\relax + \@tempdimb\dimexpr#1\relax + \ifdim\@tempdima=\z@\relax + \ifdim\@tempdimb>\z@\relax\dimen@90\p@ + \else\ifdim\@tempdimb<\z@\relax\dimen@-90\p@ + \else\dimen@0\p@ + \fi\fi + \else + \@tempdimd\z@ + \ifdim\@tempdima<\z@\relax + \ifdim\@tempdimb<\z@\relax\@tempdimd-180\p@ + \else\@tempdimd180\p@ + \fi + \fi + \dimen@\dimexpr1pt * \@tempdimb/\@tempdima\relax + \@tempdimc\dimen@ + \ifdim\@tempdimc<\z@\relax\@tempdimc-\@tempdimc\fi + \ifdim\@tempdimc>\p@\relax + \dimen@\dimexpr1pt * \@tempdima/\@tempdimb\relax + \ifdim\dimen@<\z@\relax\def\@tempsign{-}\else\def\@tempsign{}\fi + \pIIe@atan@ + \dimen@-\dimen@ + \advance\dimen@ by \@tempsign1.5707pt\relax + \else + \pIIe@atan@ + \fi + \dimen@57.29578\dimen@ + \advance\dimen@ by \@tempdimd + \fi + #3\dimen@% +} + +\newcommand*\pIIe@noneto[2]{} +\newcommand*\pIIe@ellip@sincost@[2]{% + \CalculateSin{#1}% + \CalculateCos{#1}% + \@tempdima\UseSin{#1}\p@ + \@tempdimb\UseCos{#1}\p@ + \ifdim\@tempdima=\p@\relax + \pIIe@csedef{@ellipsin#2}{1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else\ifdim\@tempdima=-\p@\relax + \pIIe@csedef{@ellipsin#2}{-1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else + \@tempdimc\@ellipratio\dimexpr1pt * \@tempdima/\@tempdimb\relax + %\typeout{ i#2=\the\@tempdimc, sin(#1)=\the\@tempdima}% + \pIIe@ellip@csqrt{\p@}{\@tempdimc}\@tempdimd + \ifdim\@tempdimb<\z@\relax\@tempdimd-\@tempdimd\fi + \pIIe@csedef{@ellipsin#2}{\strip@pt\dimexpr1pt * \@tempdimc/\@tempdimd\relax}% + \pIIe@csedef{@ellipcos#2}{\strip@pt\dimexpr1pt * \p@/\@tempdimd\relax}% + \fi\fi +} + +\newcommand*\pIIe@ellip@sincost[2]{% + %\typeout{ calc sin cos: angles (#1,#2), radii: (\the\@ovro,\the\@ovri)}% + \edef\@ellipratio{\strip@pt\dimexpr1pt * \@ovro/\@ovri\relax}% + \pIIe@ellip@sincost@{#1}{one}% + \pIIe@ellip@sincost@{#2}{two}% + %\typeout{ sincos(a=#1)=(\@ellipsinone,\@ellipcosone), sincos(a=#2)=(\@ellipsintwo,\@ellipcostwo), }% +} +\newcommand*\pIIe@omega[3]{% + \@tempdima\csname @ellipcos#3\endcsname\@ovro + \advance\@tempdima by #1\relax + \@tempdimb\csname @ellipsin#3\endcsname\@ovri + \advance\@tempdimb by #2\relax +} + +\newcommand*\pIIe@omegai[1]{% + \@tempdimc\csname @ellipsin#1\endcsname\@ovro + \@tempdimc-\@tempdimc + \@tempdimd\csname @ellipcos#1\endcsname\@ovri +} + +\newcommand*\pIIe@ellip@kappa{% + \@ovyy\@ellipsinone\p@ + \@ovxx\@ellipcosone\p@ + \@tempdima\@ellipcostwo\@ovyy + \@tempdima-\@tempdima + \advance\@tempdima by \@ellipsintwo\@ovxx + \@tempdimb\@ellipcostwo\@ovxx + \advance\@tempdimb by \@ellipsintwo\@ovyy + \ifdim\@tempdima=\z@\relax + \edef\@ellipkappa{0}% + \else + \dimen@\dimexpr1pt - \@tempdimb\relax + \dimen@\dimexpr1pt * \dimen@/\@tempdima\relax + \pIIe@ellip@csqrt{2\p@}{1.73205\dimen@}{\dimen@}% + \advance\dimen@ by -\p@ + \divide\dimen@ by 3% + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \edef\@ellipkappa{\strip@pt\dimen@}% + \fi + %\typeout{ calculated kappa: \@ellipkappa}% +} + +\newcommand*\pIIe@elliparc@[5]{% + %\typeout{elliparc: #1, center: (#2, #3), radius (\the\@ovro, \the\@ovri),angle (#4, #5)}% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \pIIe@ellip@sincost{#4}{#5}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@t[5]{% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \CalculateSin{#4}\CalculateCos{#4}% + \edef\@ellipsinone{\UseSin{#4}}% + \edef\@ellipcosone{\UseCos{#4}}% + \CalculateSin{#5}\CalculateCos{#5}% + \edef\@ellipsintwo{\UseSin{#5}}% + \edef\@ellipcostwo{\UseCos{#5}}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@draw[2]{% + \pIIe@ellip@kappa% + \pIIe@omega{#1}{#2}{one}% + %\typeout{ point one: (\the\@tempdima,\the\@tempdimb)}% + \@ellip@startto\@tempdima\@tempdimb + \pIIe@omegai{one}% + \advance\@tempdima by \@ellipkappa\@tempdimc + \advance\@tempdimb by \@ellipkappa\@tempdimd + \pIIe@add@nums\@tempdima\@tempdimb + %\typeout{ control one: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@omega{#1}{#2}{two}% + \pIIe@omegai{two}% + \@tempdimc\@ellipkappa\@tempdimc + \@tempdimd\@ellipkappa\@tempdimd + \@tempdimc-\@tempdimc + \@tempdimd-\@tempdimd + \advance\@tempdimc by \@tempdima + \advance\@tempdimd by \@tempdimb + \pIIe@add@nums\@tempdimc\@tempdimd + %\typeout{ control two: (\the\@tempdimc,\the\@tempdimd)}% + \pIIe@add@CP\@tempdima\@tempdimb + %\typeout{ point two: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@addtoGraph\pIIe@curveto@op +} +\newcommand*\pIIe@elliparc[7][0]{% + \@ovro #4\relax + \@ovri #5\relax + \iffalse%dim\@ovro=\@ovri + \pIIe@arc[#1]{#2}{#3}{#4}{#6}{#7} + \else + \ifdim \@ovro<\z@ \pIIe@badcircarg\else + \ifdim \@ovri<\z@ \pIIe@badcircarg\else + \@arclen #7\p@ \advance\@arclen -#6\p@ + \ifdim \@arclen<\z@ \def\@tempsign{-}\else\def\@tempsign{}\fi + \ifdim \@tempsign\@arclen>720\p@ + \PackageWarning {ellipse}{The arc angle is reduced to -720..720}% + \@whiledim \@tempsign\@arclen>720\p@ \do {\advance\@arclen-\@tempsign360\p@}% + \@tempdima #6\p@ \advance\@tempdima \@arclen + \edef\@angleend{\strip@pt\@tempdima}% + \pIIe@@elliparc{#1}{#2}{#3}{#6}{\@angleend}% + \else + \pIIe@@elliparc{#1}{#2}{#3}{#6}{#7}% + \fi + \fi + \fi + \fi +} +\newcommand*\pIIe@@elliparc[5]{% + \begingroup + \ifdim \@tempsign\@arclen>90\p@ + \divide\@arclen 2% + \@tempdima #4\p@\advance\@tempdima by \@arclen + \edef\@anglemid{\strip@pt\@tempdima}% + \def\@tempa{\pIIe@@elliparc{#1}{#2}{#3}{#4}}% + \expandafter\@tempa\expandafter{\@anglemid}% + \def\@tempa{\pIIe@@elliparc{2}{#2}{#3}}% + \expandafter\@tempa\expandafter{\@anglemid}{#5}% + \else + \pIIe@elliparc@{#1}{#2}{#3}{#4}{#5}% + \fi + \endgroup +}% + +\newcommand*\pIIeelliparc[7][0]{% + \@killglue + \pIIe@elliparc[#1]{#2\unitlength}{#3\unitlength}{#4\unitlength}{#5\unitlength}{#6}{#7}% + \ignorespaces% +} +\ifx\undefined\elliparc\else + \PackageWarning{ellipse}{\protect\elliparc\space is redefined}% +\fi +\let\elliparc\pIIeelliparc + +\newcommand*\pIIeearc + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\newcommand*\pIIe@earc@[3][0,360]{\pIIe@earc@@(#1){#2}{#3}} +\def\pIIe@earc@@(#1,#2)#3#4{% + \if@tempswa + \pIIe@moveto\z@\z@ + \pIIe@elliparc{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@closepath\pIIe@fillGraph + \else + \pIIe@elliparc[1]{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@strokeGraph + \fi} +\ifx\undefined\earc\else + \PackageWarning{ellipse}{\protect\earc\space is redefined}% +\fi +\let\earc\pIIeearc + +\newcommand*\pIIeellipse + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\let\ellipse\pIIeellipse + +\endinput +%% +%% End of file `ellipse.sty'. diff --git a/spec/v1.2.0-rc.1/embedded-plus-single-remote-controller.png b/spec/v1.2.0-rc.1/embedded-plus-single-remote-controller.png new file mode 100644 index 00000000..2e0f1803 Binary files /dev/null and b/spec/v1.2.0-rc.1/embedded-plus-single-remote-controller.png differ diff --git a/spec/v1.2.0-rc.1/embedded-plus-single-remote-controller.svg b/spec/v1.2.0-rc.1/embedded-plus-single-remote-controller.svg new file mode 100644 index 00000000..9fe2ce9c --- /dev/null +++ b/spec/v1.2.0-rc.1/embedded-plus-single-remote-controller.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spec/v1.2.0-rc.1/embedded-plus-two-remote-controllers.png b/spec/v1.2.0-rc.1/embedded-plus-two-remote-controllers.png new file mode 100644 index 00000000..b6dc04fc Binary files /dev/null and b/spec/v1.2.0-rc.1/embedded-plus-two-remote-controllers.png differ diff --git a/spec/v1.2.0-rc.1/embedded-plus-two-remote-controllers.svg b/spec/v1.2.0-rc.1/embedded-plus-two-remote-controllers.svg new file mode 100644 index 00000000..0f97ba38 --- /dev/null +++ b/spec/v1.2.0-rc.1/embedded-plus-two-remote-controllers.svg @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + + + Entities + + + + + + + \ No newline at end of file diff --git a/spec/v1.2.0-rc.1/embedded-plus-two-remote-ha-controllers.png b/spec/v1.2.0-rc.1/embedded-plus-two-remote-ha-controllers.png new file mode 100644 index 00000000..f663e9bf Binary files /dev/null and b/spec/v1.2.0-rc.1/embedded-plus-two-remote-ha-controllers.png differ diff --git a/spec/v1.2.0-rc.1/embedded-plus-two-remote-ha-controllers.svg b/spec/v1.2.0-rc.1/embedded-plus-two-remote-ha-controllers.svg new file mode 100644 index 00000000..710111fa --- /dev/null +++ b/spec/v1.2.0-rc.1/embedded-plus-two-remote-ha-controllers.svg @@ -0,0 +1,510 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + Master (Active) + + + + + + Slave (Standby) + + + + + + + \ No newline at end of file diff --git a/spec/v1.2.0-rc.1/error-report.png b/spec/v1.2.0-rc.1/error-report.png new file mode 100644 index 00000000..766cb77f Binary files /dev/null and b/spec/v1.2.0-rc.1/error-report.png differ diff --git a/spec/v1.2.0-rc.1/error-report.svg b/spec/v1.2.0-rc.1/error-report.svg new file mode 100644 index 00000000..a2709a72 --- /dev/null +++ b/spec/v1.2.0-rc.1/error-report.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StatusCode error_code_; // canonical error codestring error_message_;string binary_error_details_; // serialized google.rpc.Status + + + + + + + + + + + + + google.rpc.Status + + + + + + int32 error_code; // canonical error codestring message;repeated Any details; // P4Error + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + + + p4.Error + + + + + + p4.Error + + + + + + + + + + + + + + + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + grpc::Status + + + + + + + \ No newline at end of file diff --git a/spec/v1.2.0-rc.1/longbox.sty b/spec/v1.2.0-rc.1/longbox.sty new file mode 100644 index 00000000..cab48934 --- /dev/null +++ b/spec/v1.2.0-rc.1/longbox.sty @@ -0,0 +1,853 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longbox}[2015/12/01, Daan Leijen, Provides basic longbox that can break over pages] +\RequirePackage{options} + +\@ifclassloaded{beamer}{% + \newcommand\lb@savefootnotes{}% + \newcommand\lb@restorefootnotes{}% +}% +{\RequirePackage{footnote}% + \newcommand\lb@savefootnotes{\savenotes}% + \newcommand\lb@restorefootnotes{\spewnotes}% +} + + +% -------------------------------------------------------- +% Debugging +% -------------------------------------------------------- + +\newcommand*\lb@debug[1]{% + \ontoggle{lb@debug}{\typeout{longbox debug: #1}}% +} +\newcommand*\lb@typeout[1]{% + \ontoggle{lb@verbose}{\typeout{longbox: #1}}% +} +\newcommand*\lb@warncannotsplit{% + \PackageWarning{longbox}{Cannot split box; it seems you are using a non-splittable contents}% +} +\newcommand*\lb@warnbadsplit[1]{% + \PackageWarning{longbox}{Bad split (underful vbox by \the#1)}% +} + + +% -------------------------------------------------------- +% Utilities for LaTeX internals +% -------------------------------------------------------- + +% Suppress the indentation on the following paragraph +\providecommand\nofirstindent{\@afterindentfalse\@afterheading} + +% Suppress the paragraph skip on the following paragraph +\providecommand\nofirstparskip{\addvskip{-\parskip}} + +% In contrast to addvspace, addvskip is not suppressed in a minipage +\providecommand\addvskip[1]{% + \ifvmode + \ifdim\lastskip=\z@ + \vskip #1\relax + \else + \@tempskipb#1\relax\@xaddvskip + \fi + \else\@noitemerr\fi +} + + +% Skip to 0.3\baselineskip multiple taking prevdepth into account. +\newskip\lb@prevdepth +\newcommand\lb@skiptobaseline{% + \global\lb@prevdepth=-\@m\p@\relax + \ifvmode + \ifdim\lastskip=\z@\relax + \ifdim\prevdepth=-\@m\p@\else + \dimen@\prevdepth + % Calculate the modulus of the previous depth with 0.3|\baselineskip| in |\dimen@|. + \@tempcnta\prevdepth + \@tempskipa=0.3\baselineskip\relax + \@tempcntb=\@tempskipa\relax + \divide \@tempcnta by \@tempcntb + \dimen@\prevdepth + \advance\dimen@ -\@tempcnta\@tempskipa + % Skip back by that amount, and then skip by 0.3|\baselineskip|. + \vskip -\dimen@ + \vskip \@tempskipa\relax + \global\lb@prevdepth=\@tempskipa\relax + \fi + \fi + \fi +} + +% unvbox a box, and return a vbox with a given background color +% \unvcolorbox{}{} +\newcommand\unvcolorbox[2]{% + \ifoptionblank{#1}{\vbox{\unvbox#2}}{% + \lb@debug{vcolorbox: #1}% + \vbox{\offinterlineskip + \hbox to \z@{\vbox to \z@{\optioncolor{#1}\hrule\@width\wd#2\@height\ht#2\@depth\dp#2\vss}\hss}% + \unvbox#2% + }% + }% +} + +% create a vbox with a given background color +\newcommand\vcolorbox[2]{% + \eifblank{#1}{\vbox{#2}}{% + \setbox\z@=\vbox{#2}\relax + \unvcolorbox{#1}{\z@}% + }% +}% + +% -------------------------------------------------------- +% The following macros come from mdframed +% -------------------------------------------------------- + +% Determine the amount of free space left on the current page +\newlength\lb@freevspace +\newcommand*\lb@setfreevspace@page{% + \lb@debug{ determine free space}% + \bgroup\@nobreakfalse\addpenalty\z@\egroup% + \penalty\@M\relax\vskip 2\baselineskip\relax% + \penalty9999\relax\vskip -2\baselineskip\relax% + \penalty9999% + \ifdim\pagegoal=\maxdimen\relax% + \lb@freevspace=\vsize% + \else + \lb@freevspace=\dimexpr\pagegoal-\pagetotal-\parskip\relax% + \fi + \lb@debug{free space: \the\lb@freevspace, in page: \the\textheight, vsize=\the\vsize}% +} + +\newcommand*\lb@shiftdim[2]{% + %\letoption{#1}\lb@list + \expandafter\lb@setheadtail@#1,\relax + \eifblank{\lb@head}{}{\option@invoke{/longbox/@breakat-previous}{\lb@head}}% + #2\option{/longbox/@breakat-previous}% + \eifblank{\lb@tail}{}{\let#1\lb@tail}% push back tail +} +\def\lb@comma{,}% +\def\lb@setheadtail@#1,#2\relax{% + \def\lb@head{#1}% + \def\lb@tail{#2}% adds commas! +} + +\newcommand*\lb@setfreevspace{% + \eifblank{\lb@breakat}{\lb@setfreevspace@page}{% + \def\lb@eject{\par}%no eject + \lb@extrasplit=\z@\relax% + \lb@shiftdim{\lb@breakat}\lb@freevspace + \ifdim\lb@freevspace>\z@\else\lb@setfreevspace@page\fi + }% +} + + +% Suppress overfull-underfull vbox messages +\newcommand*\lb@ignorevbadness{% + \edef\lb@currentvbadness{\the\vbadness}% + \edef\lb@currentvfuzz{\the\vfuzz}% + \vbadness=\@M\relax% + \vfuzz=\maxdimen\relax% + \afterassignment\lb@restorevbadness +} +\newcommand*\lb@restorevbadness{% + \vbadness=\lb@currentvbadness\relax + \vfuzz=\lb@currentvfuzz\relax +} + + +% -------------------------------------------------------- +% The 'long vbox' (lvbox) environment collects long material +% into a long \vbox, instead of a \hbox like a lrbox in latex. +% The collected box can contain any box, minipage, lrbox, fbox etc, +% but not outer-par material like a figure. Footnotes can be +% dealt with useing lb@savefootnotes. +% +% The material is typeset in a \vbox according to a given width. +% inside the environment, the boolean 'inlvbox' is true. +% +% \begin{lvbox}{}{} +% -------------------------------------------------------- + +\newif\ifinlvbox +\newcommand\lvbox[4]{% + \setbox#1\vbox\bgroup + \begingroup + \inlvboxtrue + % reset defaults + \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\par\@@par + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + % set margin and linewidth + \leftmargin=#2\relax\rightmargin=#4\relax + \@totalleftmargin=\leftmargin% + %\leftskip=#2\relax\rightskip=#4\relax\@rightskip=#4\relax + \linewidth=#3\relax + % set primitive tex margins + \leftskip=\@totalleftmargin% + \rightskip=\rightmargin% + \@rightskip=\rightmargin% + \hsize=\dimexpr\@totalleftmargin+\linewidth+\rightmargin\relax + \columnwidth\hsize + \textwidth\hsize + \nofirstindent + %\nofirstparskip +} +\def\endlvbox{\endgroup\egroup} + + + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + + +\newsavebox\lb@headbox +\newsavebox\lb@savebox +\newsavebox\lb@mainbox + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@setbaseline[1]{% + %\typeout{ set baseline, \the\dp#1,\the\ht#1}% + \ifcase\lb@baseline% + \relax%bottom + \or%middle + \setbox#1=\vbox{\hbox{\lower \dimexpr(\dp#1 + \ht#1)/2 - \dp#1\relax\vbox{\unvbox#1}}}% + \or%top + \setbox#1=\vtop{\unvbox#1}% + \fi + %\typeout{ .new dim: \the\dp#1, \the\ht#1}% +} + + +\@ifundefined{define@key}{}% + {\define@key{longbox}{options}{\options{#1}\option{/longbox/adjust-options}}}% + +\newcommand*\lb@render@breakbox{% + %\typeout{render breakbox entry (in output routine), height=\the\bb@height}% + \bb@restorekeys{longbox}% + \lb@skiptop=\ifbb@isfirst\option{/longbox/skip-top}\else\option{/longbox/skip-break-top}\fi\relax + \lb@skipbottom=\ifbb@islast\option{/longbox/skip-bottom}\else\option{/longbox/skip-break-bottom}\fi\relax + \lb@skipbreaktop=\ifbb@isfirst 0pt\else\option{/longbox/skip-break-top}\fi + \lb@skipbreakbottom=\ifbb@islast 0pt\else\option{/longbox/skip-break-bottom}\fi + %\typeout{ render: skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom, break-top=\the\dimexpr\option{/longbox/skip-bottom}}% + \options{% + /longbox/@part-height=\bb@height + \lb@skipbreaktop + \lb@skipbreakbottom, + /longbox/@part-width=\option{/longbox/width} + \option{/longbox/skip-left} + \option{/longbox/skip-right},%\bb@width, + /longbox/@part-depth=0pt, + /longbox/@part-needtop=\ifbb@isfirst true\else false\fi, + /longbox/@part-needbottom=\ifbb@islast true\else false\fi, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-depth=\option{/longbox/@part-depth}, + }% + %\typeout{breakbox: width=\expandafter\the\option{/longbox/width}, \the\bb@width, \the\dimexpr\option{/longbox/@part-width}}% + \vbox{% + \kern -\lb@skipbreaktop% todo: move to breakbox? + \option{/longbox/render}% + \kern -\lb@skipbreakbottom + }% +} + +\newcommand*\lb@render@vbox[1]{% + \lb@debug{render vbox entry}% + \lb@restoreoptions + \lb@skiptop=\dimexpr\iftoggle{/longbox/@part-needtop}{\option{/longbox/skip-top}}{\option{/longbox/skip-break-top}}\relax + \lb@skipbottom=\dimexpr\iftoggle{/longbox/@part-needbottom}{\option{/longbox/skip-bottom}}{\option{/longbox/skip-break-bottom}}\relax + %\typeout{ skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom}% + % add top skip while maintaining the baseline. + \ifdim\lb@skiptop=\z@\relax\else + \setbox\z@=\vtop{\unvcopy#1}% + \dimen@=\ht\z@ + \setbox#1=\vbox{\offinterlineskip + \hrule width \z@ height \dimexpr\dimen@ + \lb@skiptop\relax depth -\dimen@ + \unvbox#1% + }% + \fi + % add bottom skip while maintaining the baseline. + \ifdim\lb@skipbottom=\z@\relax\else + \dimen@=\dp#1% + \setbox#1=\vbox{\offinterlineskip\unvbox#1\hrule width \z@ height -\dimen@ depth \dimexpr\dimen@ + \lb@skipbottom\relax}% + \fi + \lb@setbaseline{#1}% + \options{% + /longbox/@part-height=\dimexpr\ht#1 + \dp#1\relax, + /longbox/@part-width=\dimexpr\wd#1 + \option{/longbox/skip-left} + \option{/longbox/skip-right}\relax, + /longbox/@part-depth=\dp#1, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-depth=\option{/longbox/@part-depth} - \lb@skipbottom, + }% + %\typeout{ longbox: height=\the\dimexpr\option{/longbox/@content-box-height}, outer height=\the\dimexpr\option{/longbox/@part-height}\relax}% + % lower the box depending on vertical alignment + \ifcase\option{/longbox/vertical-align/@ord}\relax + \@tempdima\z@ + \or + %bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%middle + \@tempdima\dimexpr0.5\option{/longbox/@part-height} - \option{/longbox/@part-depth}\relax + \or%top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%text-bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%text-top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%super + \@tempdima=-0.9ex% + \or%sub + \@tempdima=0.7ex% + \else + \@tempdima\z@ + \fi + \advance\@tempdima by -\option{/longbox/raise}% + \option@invoke{/longbox/@lower}{\@tempdima}% + \noindent\hbox{\lower \@tempdima\vbox{\offinterlineskip + \hbox to \z@{% + \vbox to \z@{% + \hbox{\lower \option{/longbox/@part-height}\vbox{\offinterlineskip{\option{/longbox/render}}}}% + \vss}% + \hss + }% + \hbox{% + \ifdim\option{/longbox/skip-left}=\z@\else\hskip\option{/longbox/skip-left}\fi + \box#1% + \ifdim\option{/longbox/skip-right}=\z@\else\hskip\option{/longbox/skip-right}\fi + %$\box#1% + }% + }}% +} + +\newcommand*\lb@single@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} +\newcommand*\lb@first@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@middle@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@last@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand*\lb@env@start{% + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore +} + +\newcount\lb@usevbox +\newlength\lb@width +\newlength\lb@height +\newlength\lb@skiptop +\newlength\lb@skipright +\newlength\lb@skipbottom +\newlength\lb@skipleft +\newlength\lb@skipbreaktop +\newlength\lb@skipbreakbottom +\newlength\lb@outerwidth +\newlength\lb@extrasplit +\newcount\lb@textalign +\newcount\lb@baseline +\newtoggle{lb@baselineskip}% +\newtoggle{lb@breakable}% +\newtoggle{lb@debug}% +\newtoggle{lb@verbose}% +\def\lb@breakat{}% +\def\lb@halign{}% +\def\lb@eject{}% +\def\lb@insertafter{} +\def\lb@insertbefore{} + +\newcommand*\lb@peekoptions[1]{% + % process options inside a group and just set necessary parameters + % this way, nested boxes don't influence each other's parameters + \begingroup + \options{#1}% + \option{/longbox/adjust-options}% + \protected@edef\lb@temp{\endgroup + \lb@width=\the\dimexpr\option{/longbox/width}\relax + \lb@height=\the\dimexpr\option{/longbox/height}\relax + \lb@textalign=\the\numexpr\option{/longbox/text-align/@ord}\relax + \lb@baseline=\the\numexpr\option{/longbox/baseline/@ord}\relax + \lb@skiptop=\the\dimexpr\option{/longbox/skip-top}\relax + \lb@skipright=\the\dimexpr\option{/longbox/skip-right}\relax + \lb@skipbottom=\the\dimexpr\option{/longbox/skip-bottom}\relax + \lb@skipleft=\the\dimexpr\option{/longbox/skip-left}\relax + \lb@skipbreaktop=\the\dimexpr\option{/longbox/skip-break-top}\relax + \lb@skipbreakbottom=\the\dimexpr\option{/longbox/skip-break-bottom}\relax + \lb@usevbox=\iftoggle{/longbox/use-vbox}{1}{0}\relax + \lb@outerwidth=\the\dimexpr\option{/longbox/outer-width}\relax + \lb@extrasplit=\the\dimexpr\option{/longbox/split-minimum}\relax + \def\noexpand\lb@insertafter{\option{/longbox/insert-after}}% + \def\noexpand\lb@insertbefore{\option{/longbox/insert-before}}% + \def\noexpand\lb@breakat{\option{/longbox/breakat}}% + \def\noexpand\lb@halign{\option{/longbox/height-align}}% + \def\noexpand\lb@eject{\option{/longbox/eject}}% + \noexpand\csname toggle\iftoggle{/longbox/baseline-skip}{true}{false}\endcsname{lb@baselineskip}% + \noexpand\csname toggle\iftoggle{/longbox/breakable}{true}{false}\endcsname{lb@breakable}% + \noexpand\csname toggle\iftoggle{/longbox/debug}{true}{false}\endcsname{lb@debug}% + \noexpand\csname toggle\iftoggle{/longbox/verbose}{true}{false}\endcsname{lb@verbose}% + }% + \lb@temp +} + +\newenvironment{longbox@env}[2]{% + % save options + \lb@peekoptions{#1,#2}% + % + \ifnum\lb@usevbox=0\relax + \lb@debug{start breakbox}% + \let\bb@render\lb@render@breakbox + \bb@savekeys{longbox}{options={#1,#2,outer-width=\the\lb@outerwidth}}% + \iftoggle{lb@baselineskip}{\typeout{**insert bskip}}{\typeout{**suppress bskip}\vskip 1pt}% + \begin{breakbox}% + \ifdim\lb@skiptop=\z@\relax\else\vspace{\lb@skiptop}\fi% + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \begin{bb@margins}{\lb@skipleft}{\dimen@}% + \else + \lb@debug{start vbox}% + \def\lb@restoreoptions{\options{#1,#2}\option{/longbox/adjust-options}}% + \lb@savefootnotes + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \lb@debug{ width=\the\lb@width, linewidth=\the\linewidth, skipleft=\the\lb@skipleft, right=\the\lb@skipright, total right=\the\dimen@}% + \iftoggle{lb@baselineskip}{\lb@skiptobaseline}{\lb@prevdepth=-\@m pt}% + \lvbox{\lb@mainbox}{0pt}{\lb@width}{0pt}%{\lb@skipleft}{\lb@width}{\lb@skipright}% + \prevdepth=\lb@prevdepth + \fi + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore + \begingroup +}{% + \par\unskip + \endgroup + \lb@insertafter + %\ifdim\lb@skipbottom=\z@\relax\else\vskip\lb@skipbottom\fi% + \ifnum\lb@usevbox=0\relax + \end{bb@margins}% + \ifdim\lb@skipbottom=\z@\relax\else\hrule width \z@ height \lb@skipbottom\fi%\vspace{\lb@skipbottom}\fi% + \iftoggle{lb@baselineskip}{}{\vskip 1sp}% + \end{breakbox}% + \lb@debug{end breakbox}% + \else + \ontoggle{lb@baselineskip}{\lb@skiptobaseline}% + \endlvbox% + \lb@debug{initial lvbox: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@processbox + %\setbox\lb@mainbox=\hbox{\lower \lb@skipbottom\vbox{\offinterlineskip\unvbox\lb@mainbox}}% + \lb@restorefootnotes + \lb@debug{end vbox}% + \fi +} + +\newcommand\longbox@cmd[3]{% + \begingroup + %\options{/options/collectunknown,/longbox/scoped,#2}% set scoped options first + %\option{/longbox/scoped/@adjust-options}% + \lb@peekoptions{#1,#2}% + \leavevmode + %\setbox\lb@mainbox=\hbox{% + % \begingroup + % #3% + % \endgroup + %}% + \setbox\lb@mainbox=\hbox{% + \begingroup + \ifcase\lb@textalign\relax + %default=left + \or%left + \or\hss%center + \or\hss%right + \else%justify + \fi + \lb@insertbefore + #3% + \lb@insertafter + \ifnum\lb@textalign<3\relax\hss\fi% default,left,center + \endgroup + }% + \options{#1,#2}% + \ifdim\option{/longbox/width}=-1sp\relax + \options{/longbox/width=\wd\lb@mainbox}%set to natural width + \fi + \option{/longbox/adjust-options}% + % make it a vbox + \setbox\lb@mainbox=\vbox{\offinterlineskip% + \hbox to \option{/longbox/width}{% + \unhbox\lb@mainbox + }% + }% + \def\lb@restoreoptions{}% + \letoption{/longbox/height-align}\lb@halign + \lb@height=\option{/longbox/height}\relax + \lb@baseline=\option{/longbox/baseline/@ord}\relax + \lb@processbox + \endgroup +} + +\newcommand\lb@processbox{% + \ifdim\lb@height<0pt\relax + \lb@setbaseline{\lb@mainbox}% + \else + \lb@restrictheight + \fi + \lb@typesetbox +} + +\newcommand\lb@typesetbox{% + \ifinlvbox + \iftoggle{lb@breakable}{% + %\lb@debug{disable breakable due to nesting of long-boxes}% + \togglefalse{lb@breakable}% + }{}% + \fi + \ifhmode\lb@single@{\lb@mainbox}\else\lb@typeset\fi +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@restrictheight{% + \lb@typeout{restrict height to \the\lb@height}% + \lb@splitheight=\lb@height% + %lb@debug{before height split: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + %split failed.. do nothing + \lb@debug{could not restrict height}% + \else + % store splitted off content in the mainbox (and discard the rest) + \setbox\lb@mainbox\vbox{\unvbox\lb@headbox}% + \lb@debug{restricted height to \the\ht\lb@mainbox}% + \fi + % set baseline + \lb@setbaseline{\lb@mainbox}% + % height align + %\letoption{/longbox/height-align}\lb@halign + \eifstrequal{\lb@halign}{bottom}% + {\setbox\lb@mainbox=\vbox{\hbox{\vbox to \lb@splitheight{\vss\unvbox\lb@mainbox}}}}% + {\eifstrequal{\lb@halign}{middle}% + {\dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\hbox{% + \lower \dimexpr0.5\dimen@ + \dp\lb@mainbox\relax% + \vbox to \lb@splitheight{\vss\unvbox\lb@mainbox\vss}}}}% + {% default is top + \dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\vtop to \lb@splitheight{\box\lb@mainbox\vss}}% + }% + }% +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newlength\lb@neededvspace +\newcommand\lb@typeset[1][0pt]{% + \iftoggle{lb@breakable}{% + \lb@setfreevspace + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skiptop+\lb@skipbottom\relax}% + \lb@debug{needed: \the\lb@neededvspace, available: \the\lb@freevspace}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@single@{\lb@mainbox}% + \else + \lb@typeout{longbox needs splitting}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skiptop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \ifdim\dimexpr\lb@freevspace + #1\relax<\textheight\relax % test if we were at a fresh page.. (and prevent infinite recursion) + \lb@debug{failed to split the box, inserting a page break}% + \hrule \@height\z@ \@width\hsize + \lb@eject% + \lb@typeset[\textheight]% try again, but pass \textheight to guard against infinite recursion + \else + % on a fresh page we should not fail anymore.. just output as is.. + % lb@warncannotsplit + \lb@single@{\lb@mainbox}% + \fi + \else + % first part success + \lb@typeout{first part splitted}% + \lb@first@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest + \fi + \fi + }{%\else + \lb@debug{unbreakable box}% + \lb@single@{\lb@mainbox}% always directly output an unbreakable box + }% +} + +\newcommand\lb@typesetrest{% + \lb@setfreevspace% + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skipbottom+\lb@skipbreaktop\relax}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@typeout{output last part of box}% + \lb@last@{\lb@mainbox}% + \else + \lb@debug{split box further}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skipbreaktop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \lb@typeout{failed to split box!}% + \lb@last@{\lb@mainbox}% + \else + % middle part success + \lb@typeout{output middle part of box}% + \lb@middle@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest% continue the iteration... + \fi + \fi +} + +% -------------------------------------------------------- +% Split a long vbox over multiple pages. +% This code is based on similar code in the mdframed package +% -------------------------------------------------------- + +\newlength\lb@splitheight +\newlength\lb@insurance % tiny extra space to ensure our box will really fit +\setlength\lb@insurance{1pt} + +% expects split target height in lb@splitheight, and splits off the start of lb@mainbox to lb@headbox +\newcommand\lb@splitbox{% + \ifdim\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax>\lb@splitheight\relax + % the main box is larger than our target split height.. + \ifdim\lb@extrasplit>\lb@splitheight\relax + % not enough space to bother + \lb@typeout{not enough space on page for a split}% + \setbox\lb@headbox=\vbox{}% empty head + \else + % try a split; lower the split height a bit so we are sure to fit + \advance\lb@splitheight -\lb@insurance\relax + \lb@debug{split: \the\lb@splitheight, from \the\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax}% + \setbox\lb@savebox=\vbox{\unvcopy\lb@mainbox}% save original + \lb@trysplit{\lb@splitheight}% + \ifdim\dimexpr\ht\lb@headbox + \dp\lb@headbox>\lb@splitheight\relax + % too big, bad split. Try other splits.. iterate N times with 1 or 5pt less before giving up + \dimen@=\lb@splitheight\relax + \@tempcnta=\z@\relax + \loop + \ifdim\dimexpr\ht\lb@headbox+\dp\lb@headbox\relax>\lb@splitheight\relax + \ifnum\@tempcnta<50% + \advance\dimen@ by -\p@\relax% try a slightly smaller height.. + \else + \advance\dimen@ by -5\p@\relax% try larger increase after 50pt.. + \fi + \advance\@tempcnta by \@ne\relax + \lb@ignorevbadness + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \lb@trysplit{\dimen@}% + \ifdim\lb@extrasplit<\dimen@\relax\else\lb@splitstop\fi % don't try to split too small + \ifnum\@tempcnta<100\relax\else\lb@splitstop\fi % and not more than N attempts + \repeat% + \ifnum\@tempcnta<100\relax + \dimen@=\dimexpr\lb@splitheight - \ht\lb@headbox - \dp\lb@headbox\relax + \ifdim\dimen@>\option{/longbox/split-badness}\relax + \lb@warnbadsplit{\dimen@}% + \fi + \fi + \fi + \fi + \else + % mainbox fits in our target lb@splitheight + \setbox\lb@headbox=\vbox{\unvbox\lb@mainbox}% + \setbox\lb@mainbox=\vbox{}% + \fi +} + +\newcommand\lb@splitstop{% + \lb@typeout{cannot find a good split}% + \let\iterate\relax + \lb@warncannotsplit + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \setbox\lb@headbox=\vbox{}% empty head + \@tempcnta=\@M\relax +} + +\newcommand\lb@trysplit[1]{% try to split at given height + \lb@typeout{try to split at: \the\dimexpr #1\relax}% + \lb@ignorevbadness + \setbox\lb@headbox=\vsplit\lb@mainbox to #1\relax% + \setbox\lb@headbox=\vbox{\unvbox\lb@headbox}% + \setbox\lb@mainbox=\vbox{\unvbox\lb@mainbox}% +} + +% -------------------------------------------------------- +% The longbox environment uses options to set its options +% -------------------------------------------------------- + + +% keys and styles that can be set once globally +\options{% + /longbox/.new family, +}% + +\options{/longbox,% + % computed + @part-needtop/.new toggle, + @part-needbottom/.new toggle, + @part-height/.new length, + @part-width/.new length, + @part-depth/.new length, + @content-box-height/.new length, + @content-box-width/.new length, + @content-box-depth/.new length, + @breakat-previous/.new length, + @lower/.new length, + % + debug/.new toggle, + verbose/.new toggle, + render/.new value =\lb@render@fbox, + adjust-options/.new value = {\longbox@adjustoptions}, + eject/.new value = {\protect\vfill\protect\eject}, + use-vbox/.new toggle = true, + split-minimum/.new length = {1.5\baselineskip}, + split-badness/.new length = \baselineskip, + % + height-align/.new choice= {top,middle,bottom}, + baseline/.new choice = {bottom,middle,top}, + text-align/.new choice = {default,left,center,right,justify}, + vertical-align/.new choice = {baseline,bottom,middle,top,text-bottom,text-top,super,sub}, + raise/.new length = {0pt}, + baseline-skip/.new toggle =true, + % + height/.new length = -1sp, + width/.new length = -1sp, + outer-height/.new length= -1sp, + outer-width/.new length = -1sp, + insert-before/.new value= {}, + insert-after/.new value = {}, + breakat/.new value = {}, + breakable/.new toggle = false, + skip/.new style = {skip-top=#1,skip-right=#1,skip-bottom=#1,skip-left=#1}, + skip-top/.new length, + skip-right/.new length, + skip-bottom/.new length, + skip-left/.new length, + skip-break-bottom/.new length, + skip-break-top/.new length, +} + +\newcommand\longbox@adjustoptions{% + %\typeout{ standard longbox adjustoptions}% + \lb@debug{ current width=\the\dimexpr\option{/longbox/width}, outer=\the\dimexpr\option{/longbox/outer-width}, linewidth=\the\linewidth}% + \ontoggle{/longbox/debug}{\option@invoke{/longbox/verbose}{true}}% + % adjust height + \ifdim\option{/longbox/height}=-1sp\relax + \ifdim\option{/longbox/outer-height}=-1sp\else + \option@invoke{/longbox/height}% + {\option{/longbox/outer-height}-\option{/longbox/skip-top}-\option{/longbox/skip-bottom}}% + \fi + \fi + % set width + \ifdim\option{/longbox/width}=-1sp\relax + \ifdim\option{/longbox/outer-width}=-1sp\relax + \option@invoke{/longbox/outer-width}{\linewidth}% + \fi + \dimen@=\dimexpr\option{/longbox/outer-width}-\option{/longbox/skip-left}-\option{/longbox/skip-right}\relax + \ifdim\dimen@<\z@\relax\dimen@=\z@\fi + \option@invoke{/longbox/width}{\dimen@}% + \fi + % use a breakbox whenever we are in external vertical mode and not width or height restricted. + \iftoggle{/longbox/use-vbox}{}{% + \ifinner\toggletrue{/longbox/use-vbox}\else + \ifhmode\toggletrue{/longbox/use-vbox}\else + \ifdim\option{/longbox/height}>-1sp\toggletrue{/longbox/use-vbox}\else + \iftoggle{/longbox/breakable}{}{\toggletrue{/longbox/use-vbox}}% + \ifoptionblank{/longbox/breakat}{}{\toggletrue{/longbox/use-vbox}}% + \fi\fi\fi + }% +} + +\newenvironment{longbox}[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \begin{longbox@env}{/longbox}{#1}% +}{\end{longbox@env}} + +\newcommand\lbox[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \longbox@cmd{/longbox}{#1}% +} + +\newcommand*\lb@render@fbox{% + %\typeout{render defaultbox: bgcolor=\bb@bgcolor, needtop=\iftoggle{/longbox/@part-needtop}{true}{false}}% + \@ovdx=\dimexpr\option{/longbox/@part-width} - 2\fboxrule\relax% + \@ovdy=\dimexpr\option{/longbox/@part-height}\relax% + \iftoggle{/longbox/@part-needbottom}% + {\@tempdima=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdima=\dimexpr\fboxrule + \bb@stickout\relax + \advance\bb@height by \@tempdima + \advance\@ovdy by \@tempdima}% + \iftoggle{/longbox/@part-needtop}% + {\@tempdimb=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdimb=\dimexpr\bb@stickout\relax + \advance\bb@height by \@tempdimb + \advance\@ovdy by \@tempdimb}% + % + \hbox{\lower \@tempdima\vbox{% + \vskip -\@tempdimb + \ontoggle{/longbox/@part-needtop}{\lb@debug{toprule wd=\expandafter\the\option{/longbox/width}}\hrule width \option{/longbox/@part-width} height \fboxrule}% + \hbox{% + \vrule width \fboxrule height \@ovdy% + \ifx\bb@bgcolor\@empty + \vrule width \@ovdx height \z@\relax + \else + {\color{\bb@bgcolor}\vrule width \@ovdx height \@ovdy}% + \fi + \vrule width \fboxrule height \@ovdy% + }% + \ontoggle{/longbox/@part-needbottom}{\hrule width \option{/longbox/@part-width} height \fboxrule}% + }}% +} \ No newline at end of file diff --git a/spec/v1.2.0-rc.1/longfbox.sty b/spec/v1.2.0-rc.1/longfbox.sty new file mode 100644 index 00000000..0df01331 --- /dev/null +++ b/spec/v1.2.0-rc.1/longfbox.sty @@ -0,0 +1,1344 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longfbox}[2015/12/01, Daan Leijen, Provides long fbox that can break over pages] + +\RequirePackage{options} +\RequirePackage{longbox} +\RequirePackage{pict2e} +\RequirePackage{ellipse} + +% -------------------------------------------------------- +% Dimension calulations +% -------------------------------------------------------- + +% dimmin/dimmax return minimum or maximum dimension +\providecommand\dim@min[2]{\ifdim#1>#2#2\else #1\fi} +\providecommand\dim@max[2]{\ifdim#1>#2#1\else #2\fi} + +\newcommand*\option@dimmin[2]{\dim@min{\option{#1}}{\option{#2}}} +\newcommand*\option@dimmax[2]{\dim@max{\option{#1}}{\option{#2}}} + + +% -------------------------------------------------------- +% Add a new 'sides' option type +% -------------------------------------------------------- + +\options{ + /handlers/new sides/.new handler = []{ + \ifblank{#2}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#1-top={##1}, #1-right={##2}, #1-bottom={##3}, #1-left={##4}}}}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#2}}}% + \optionsalso{ + #1/.new cmdx = {##1,##2,##3,##4,##5\relax}{,,,,\relax}{% + \ifblank{##2##3##4}{\option{#1/@cmd@sides}{##1}{##1}{##1}{##1}}% + {\ifblank{##3##4}{\option{#1/@cmd@sides}{##1}{##2}{##1}{##2}}% + {\ifblank{##4}{\option{#1/@cmd@sides}{##1}{##2}{##3}{##2}}% + {\option{#1/@cmd@sides}{##1}{##2}{##3}{##4}}% + }% + }% + }, + #1/.type = sides, + }% + },% +} + +\newcommand*\optionlengthlimit[3]{% len, min, max + \letoption{#1}\opt@temp + \ifdim\opt@temp<\dimexpr#2\relax + \option@invoke{#1}{#2}% + \else\ifdim\opt@temp>\dimexpr#3\relax + \option@invoke{#1}{#3}% + \fi\fi +} + +\newcommand*\optionradiuslimit[4]{% r1, r2, min, max + \letoption{#1}\opt@tempa + \letoption{#2}\opt@tempb + \ifdim\opt@tempa<\dimexpr#3\relax\option@invoke{#1}{#3}\fi + \ifdim\opt@tempb<\dimexpr#3\relax\option@invoke{#2}{#3}\fi + \ifdim\dimexpr\opt@tempa + \opt@tempb\relax=\z@\relax\else + \ifdim\dimexpr\opt@tempa+\opt@tempb\relax>\dimexpr#4\relax + \edef\opt@perc{\the\numexpr(\number\dimexpr#4\relax)/% + (\number\dimexpr(\opt@tempa+\opt@tempb)/100\relax)}% + %\typeout{scale:\the\opt@tempa,\the\opt@tempb, by \opt@perc percent to make \the\dimexpr#4\relax}% + \edef\opt@temp{\dimexpr\opt@perc\dimexpr\the\opt@tempa\relax / 100\relax}% + \option@einvoke{#1}{\opt@temp}% + \option@einvoke{#2}{\dimexpr#4 - \opt@temp\relax}% + %\typeout{ scaled to: \the\opt@temp,\the\dimexpr#4 - \opt@temp\relax}% + \fi + \fi +} + + +% \begin{macro}{\trig@atantan} +% \marg{a}\marg{b}\marg{$\alpha$}{dimen$_\mathit{reg}$}\\ +% Assigns $\atan_2(\frac{\sin(\alpha)}{b},\frac{\cos(\alpha)}{a})$ to dimension register \textit{dimen$_\mathit{reg}$}, +% where $a$ and $b$ are dimensions. +% Returns $\alpha$ when $a = b$, or when $a=0$ or $b=0$. +% \begin{macrocode} +\newcommand*\trig@atantan[4]{% + %\typeout{ atantan:(\the#1,\the#2,\the#3, #4)}% + \@tempdima\dimexpr#1\relax + \@tempdimb\dimexpr#2\relax +% \end{macrocode} +% If $a = b$, we have a circle and the result is $\alpha$. +% \begin{macrocode} + \ifdim\@tempdima=\@tempdimb + #4\dimexpr#3\relax + \else\ifdim\@tempdima=\z@ + #4\dimexpr#3\relax + \else\ifdim\@tempdimb=\z@ + #4\dimexpr#3\relax + \else + \edef\trig@temp{\strip@pt\dimexpr#3\relax}% + \CalculateSin{\trig@temp}\CalculateCos{\trig@temp}% + \@tempdimc\dimexpr1\p@ * \dimexpr\UseSin{\trig@temp}\p@\relax/\@tempdimb\relax + \@tempdimd\dimexpr1\p@ * \dimexpr\UseCos{\trig@temp}\p@\relax/\@tempdima\relax + \pIIe@atantwo{\@tempdimc}{\@tempdimd}\dimen@ + \ifdim\dimen@<\z@ + \ifdim\dimexpr#3\relax<\z@\else\advance\dimen@360\p@\fi + \fi + \@tempdima\dimexpr#3 - \dimen@\relax + \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi + \ifdim\@tempdima<360\p@\else\advance\dimen@360\p@\fi + %\typeout{atan: \the\dimexpr#3\relax versus. \the\dimen@ }% + #4\dimen@ + \fi\fi\fi +} +% \end{macrocode} +% \end{macro} + +% rough approximation of the perimeter; +% if |radius-x == radius-y| = 0 (a circle), the approximation is precise. +% otherwise, works best when |angle2-angle1| <= 45 and gets worse from there on. +\newcommand*\ellip@letarcperimeter[5]{% 'radius-x', 'radius-y', 'angle-1', 'angle-2', '\result' + \@tempdima\dimexpr#3\relax + \@tempdimb\dimexpr#4\relax + \@tempdimc\dimexpr\@tempdima - \@tempdimb\relax + \ifdim\@tempdimc<\z@\@tempdimc-\@tempdimc\fi + \ifdim#1=#2\relax% circle? + \edef\@tempa{\strip@pt\@tempdimc}% angle difference delta as factor + \dimen@\@tempa\dimexpr#1\relax% r*delta + \dimen@0.017453\dimen@% (2*pi/360) * r * delta = 2*pi*r * (delta/360) + \else% ellipse: take the distance between the points on the ellipse, works pretty good if delta <= 45, and ok'ish for delta <= 90 + \@ovro\dimexpr#1\relax + \@ovri\dimexpr#2\relax + \edef\fbox@tempa{\strip@pt\@tempdima}% + \edef\fbox@tempb{\strip@pt\@tempdimb}% + \pIIe@ellip@sincost{\fbox@tempa}{\fbox@tempb}% + \@tempdima\@ellipcosone\@ovro + \@tempdimb\@ellipsinone\@ovri + \@tempdimc\@ellipcostwo\@ovro + \@tempdimd\@ellipsintwo\@ovri + \advance\@tempdimc by -\@tempdima% + \advance\@tempdimd by -\@tempdimb% + \pIIe@ellip@csqrt{\@tempdimc}{\@tempdimd}{\dimen@}% + %\typeout{ distance: \the\dimen@, from (x,y)=(\the\@tempdimc,\the\@tempdimd), radii=(\the#1,\the#2), angles=(\the#3,\the#4)}% + \fi + \edef#5{\the\dimen@}% +} + + +% ------------------------------------------------------------------------------ +% Borders using the picture environment +% ------------------------------------------------------------------------------ + +\newcommand*\fbox@border@pict{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \begingroup + \hbox{% + \unitlength\p@ + \begin{picture}(0,0)(0,\optionunit{/fbox/@border-box-height})% bottom-left is origin + % markers + \ontoggle{/fbox/show-markers}{% + \linethickness{\option{/fbox/marker-width}}% + \optioncolor{/fbox/marker-color}% + \fbox@rect{0pt}{0pt}{\option{/fbox/@border-box-width}}{\option{/fbox/@border-box-height}}% + \fbox@rect{\option{/fbox/border-left-width}}{\option{/fbox/border-\fbox@bottom-width}}% + {\option{/fbox/@border-box-width}-\option{/fbox/border-right-width}}% + {\option{/fbox/@border-box-height}-\option{/fbox/border-\fbox@top-width}}%S + }% + %compute corner coordinates + \fbox@border@calccorners + %put down the background color + \fbox@border@colorbackground + \option{/fbox/picture-insert-before}% + %put down the sides + \fbox@border@side{3}{-2}{0}%top + \fbox@border@side{5}{-4}{3}%left + \fbox@border@side{-6}{7}{2}%bottom + \fbox@border@side{-8}{1}{1}%right + \end{picture}% + }% + \endgroup + \fi +} + +\newcommand*\fbox@border@pict@after{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \letoption{/fbox/picture-insert-after}\fbox@insertafter + \eifblank{\fbox@insertafter}{}{% + \begingroup + \hbox{% + \begin{picture}(0,0)(0,0)% bottom-left is origin + \fbox@insertafter + \end{picture}% + }% + \endgroup + }% + \fi +} + +\newcommand*\fbox@border@side[3]{% + \fbox@setoct@angles{#1}% + \edef\fbox@style{\option{/fbox/border-\fbox@side-style}}% + \optioncolor{/fbox/border-\fbox@side-color}% + \option{/fbox/picture-side-insert-before}% + \ifcsdef{fbox@border@pict@\fbox@style}% + {\csuse{fbox@border@pict@\fbox@style}{#1}{#2}{#3}}% + {\PackageWarning{longfbox}{Unknown style "\fbox@style". Using "solid" instead.}% + \fbox@border@pict@solid{#1}{#2}{#3}}% + \option{/fbox/picture-side-insert-after}% +} + +% ------------------------------------------------------------------------------ +% Define standard border styles for the picture environment +% +% a style has the form \fbox@border@pict@ + + + + + + +
+
+
+
P4Runtime Specification
+
version 1.2.0-rc.1
+
+
+
The P4.org API Working Group
+
2020-06-23
+
+

Abstract. P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.

+ + +

1. Introduction and Scope

+

This document is published by the P4.org API Working Group, which was +chartered [17] to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called P4Runtime. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +https://github.com/p4lang/p4runtime/tree/master/proto. +

1.1. P4 Language Version Applicability

+

P4Runtime is designed to be implemented in conjunction with the P416 language +version or later. P414 programs should be translated into P416 to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P416 1.0, but were introduced in P416 1.1.0 [29]. For +this version of P4Runtime, we recommend using P416 1.2.1 [1]. +

1.2. In Scope

+

This specification document defines the semantics of P4Runtime messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime: +

+
    +
  • Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA) [19] externs (e.g. Counters, Meters, Action +Profiles, ). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0. +
  • +
  • Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism. +
  • +
  • Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy. +
  • +
  • Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities. +
  • +
  • Packet I/O to enable streaming packets to & from the control plane. +
  • +
  • Batching support, with different atomicity guarantees. +
  • +
  • In-the-field device-reconfiguration with a new P4 data plane. +
+ +

The following are in the scope of this specification document: +

+
    +
  • Rationale for the P4Runtime design. +
  • +
  • Reference architecture and use-cases for deploying a P4Runtime service. +
  • +
  • Detailed description of the API semantics. +
  • +
  • Requirements for conformant implementations of the API. +
+

1.3. Not In Scope

+

The following are not in scope of P4Runtime: +

+
    +
  • Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +[35]. An open source implementation of these APIs is also in progress +as part of the Stratum project [37]. +
  • +
  • Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures. +
+ +

The following are not in scope of this specification document: +

+
    +
  • Description of the P4 programming language; it is assumed that the reader is +already familiar with P416 [1]. +
  • +
  • Descriptions of gRPC and Protobuf files in general. +
  • +
  • Controller role definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme. +
+

2. Terms and Definitions

+
+
arbitration
+
Refers to the process through which P4Runtime ensures that at any given +time, there is a single master (i.e. a client with write access) for a given +role. Also referred to as “master-slave arbitration”. +
+
client
+
The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +
+
COS
+
Class of Service. +
+
device
+
Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +
+
entity
+
An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +
+
gRPC
+
gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +[9]. +
+
HA
+
High-Availability. Refers to a redundancy architecture. +
+
Instrumentation
+
The part of the P4Runtime server which implements the calls to the device or +target native “SDK” or backend. +
+
IPC
+
Inter-Process Communication. +
+
P4 Blob
+
A more colloquial term for P4 Device Config (Blob = Binary Large Object). +
+
P4 Device Config
+
The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its “program.” +
+
P4Info
+
Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +
+
P4RT
+
Abbreviation for P4Runtime. +
+
Protobuf (Protocol Buffers)
+
The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See [21]. +
+
PSA
+
Portable Switch Architecture [19]; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +
+
RPC
+
Remote Procedure Call. +
+
RTT
+
Round-trip time. +
+
SDN
+
Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network controller. +
+
SDN port
+
A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +
+
server
+
The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +
+
stream
+
Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (StreamChannel), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and master-slave arbitration, among other +things. +
+
switch config
+
Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +
+
target
+
The hardware or software entity which “executes” the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with “device”. +
+
URI
+
Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.

3. Reference Architecture

+

Figure 1 represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. A multi-master protocol allows more than +one controller to participate, and a role-based arbitration scheme ensures only +one controller has write access to each read/write entity, or the pipeline +config itself. Any controller may perform read access to any entity or the +pipeline config. Later sections describe this in detail. For the sake of +brevity, the term controller may refer to one or more controllers. +

+

The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +[15]. It may be compiled via protoc the Protobuf compiler +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server. +

+

Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository [16]. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, e.g. via callbacks, thus reducing the burden of implementing +P4Runtime. +

+

The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard. +

+

The controller can also set the ForwardingPipelineConfig, which amounts to +installing and running the compiled P4 program output, which is included in the +p4_device_config Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +ForwardingPipelineConfig to retrieve the device config and the P4Info. +

+
+

reference-architecture +

+
+ +
Figure 1. P4Runtime Reference Architecture.

3.1. Idealized Workflow

+

In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the ForwardingPipelineConfig +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a SetForwardingPipelineConfig +RPC. Metadata in the P4Info describes both the overall program itself +(PkgInfo) as well as all entity instances derived from the P4 program +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise “handle” used in API +calls. +

+

In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible. +

+

In some use cases, it is expected that a controller will store a +collection of multiple P4 “packages”, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the ForwardingPipelineConfig from the target via the +GetForwardingPipelineRequest RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state. +

3.2. P4 as a Behavioral Description Language

+

P4 can be considered a behavioral description of a switching device which may or +may not execute “P4” natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a SetForwardingPipelineRequest to +change its pipeline “program”, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device. +

+

While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API. +

+

In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the PkgInfo +message as well as the embedded doc fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections. +

3.3. Alternative Workflows

+

Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary. +

3.3.1. P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config

+

In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +p4_device_config. The device's configuration might be derived via some other +means to implement the P4 source code's intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane. +

3.3.2. No P4 Source Available, P4Info Available

+

In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are: +

+
    +
  1. +

    The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security. +

  2. +
  3. +

    The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info. +

+ +

As discussed in Section 3.2, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, e.g. documentation. +

3.3.3. Partial P4Info and P4 Source are Available

+

In this situation, a subset of the target's pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code. +

3.3.4. P4Info Role-Based Subsets

+

In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more. +

3.4. P4Runtime State Across Restarts

+

All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade. +

4. Controller Use-cases

+

P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +section. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime's flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex. +

4.1. Single Embedded Controller

+

Figure 2 shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases. +

+

P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC. +

+
+

single-embedded-controller +

+
+ +
Figure 2. Use-Case: Single Embedded Controller

4.2. Single Remote Controller

+

Figure 3 shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections. +

+
+

single-remote-controller +

+
+ +
Figure 3. Use-Case: Single Remote Controller

4.3. Embedded + Single Remote Controller

+

Figure 4 illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller. +

+

For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables. +

+
+

embedded-plus-single-remote-controller +

+
+ +
Figure 4. Use-Case: Embedded Plus Single Remote Controller

4.4. Embedded + Two Remote Controllers

+

Figure 5 illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +e.g. routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership. +

+
+

embedded-plus-two-remote-controllers +

+
+ +
Figure 5. Use-Case: Embedded Plus Two Remote Controllers

4.5. Embedded Controller + Two High-Availability Remote Controllers

+

Figure 6 illustrates a single +embedded controller plus two remote controllers in an active-standby HA +(High-Availability) configuration. Controller #1 is the active controller and is +in charge of some entities. If it fails, Controller #2 takes over and manages +the tables formerly owned by Controller #1. The mechanics of HA architectures +are beyond the scope of this document, but the P4Runtime multi-master +arbitration scheme supports it. +

+
+

embedded-plus-two-remote-ha-controllers +

+
+ +
Figure 6. Use-Case: Embedded Plus Two Remote High-Availability Controllers

5. Master-Slave Arbitration and Controller Replication

+

The P4Runtime interface allows multiple controllers to be connected to the +P4Runtime server running on the device at the same time for the following +reasons: +

+
    +
  1. +

    Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, “roles” (or “realms”) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +master and the rest are slaves. Role definition, i.e. how P4 entities get +assigned to each role, is out-of-scope of this document. +

  2. +
  3. +

    Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby slave controllers. These can already have a connection +open, which can help them become master more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved. +

+ +

To support multiple controllers, P4Runtime uses the streaming channel (available +via StreamChannel RPC) for session management. The workflow is described as +follows: +

+
    +
  • +

    Each controller instance (e.g. a controller process) can participate in one or +more roles. For each (device_id, role_id), the controller receives an +election_id. This election_id can be the same for different roles and/or +devices, as long as the tuple (device_id, role_id, election_id) is +unique. For each (device_id, role_id) that the controller wishes to +control, it establishes a StreamChannel with the P4Runtime server +responsible for that device, and sends a MasterArbitrationUpdate message +containing that tuple of (device_id, role_id, election_id) values. The +P4Runtime server selects a master independently for each (device_id, +role_id) pair. The master is the client that has the highest election_id +that the device has ever received for the same (device_id, +role_id) values. A connection between a controller instance and a device id + which involves a persistent StreamChannel can be referred to as a +P4Runtime client. +

    +

    Note that the P4Runtime server does not assign a role_id or election_id to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the election_id values used for each +StreamChannel. The P4Runtime server only keeps track of the (device_id, +role_id, election_id) of each StreamChannel that has sent a successful +MasterArbitrationUpdate message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +WriteRequest message to identify which client is making the WriteRequest, +not only the election_id. This enables controllers to re-use the same +numeric election_id values across different (device_id, role_id) +pairs. P4Runtime does not require election_id values be reused across such +different (device_id, role_id) pairs; it allows it. +

  • +
  • +

    To start a controller session, a controller first opens a bidirectional stream +channel to the server via the StreamChannel RPC for each device. This stream +will be used for two purposes: +

    +
      +
    • +

      Session management: As soon as the controller opens the stream +channel, it sends a StreamMessageRequest message to the switch. The +controller populates the MasterArbitrationUpdate field in this message +using its role_id and election_id, as well as the device_id of the +device. Note that the status field in the MasterArbitrationUpdate is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below. +

    • +
    • +

      Streaming of notifications (e.g. digests) and packet I/O: The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the master controller can participate in packet +I/O. This feature is explained in more details in the Packet +I/O section. +

    + +

    Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state. +

  • +
  • +

    Note that the stream is opened per device. In case a switching platform has +multiple devices (e.g. multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different masters for different +devices. In this case, it is the responsibility of the P4Runtime server to +keep track of the master for each device (and role). More specifically, the +P4Runtime server will know which stream corresponds to the master controller +for each pair of (device_id, role_id) at any point of time. +

  • +
  • +

    The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered “offline” or +“dead” as soon as its stream channel to the switch is broken. When a master +channel gets broken: (i) an advisory message is sent to all other controllers +for that device_id and role_id, as described in the +following section (ii) the P4Runtime server +will be without a master, until a client sends a successful +MasterArbitrationUpdate (as per the rules in a +later section). +

  • +
  • +

    The mechanism via which the controller receives the P4Runtime server details +which includes the device_id, ip and port, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +device_id) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks. +

+ +

gRPC enables the server to identify which client originated each message in the +StreamChannel stream. For example, the C++ gRPC library [10] in +synchronous mode enables a server process to cause a function to be called when +a new client creates a StreamChannel stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +StreamChannel is closed normally (or broken, e.g. because a client process +unexpectedly terminated). Thus the server can easily associate all +StreamChannel messages received from the same client, because they are +processed within the context of the same function call. +

+

A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values device_id, role_id, and election_id in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods [8] that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server. +

5.1. Default Role

+

A controller can omit the role message in MasterArbitrationUpdate. This +implies the “default role”, which corresponds to “full pipeline access”. This +also implies that a default role has a role.id of 0 (default). If using a +default role, all RPCs from the controller (e.g. Write) must set the role_id +to 0. +

5.2. Role Config

+

The role.config field in the MasterArbitrationUpdate message sent by the +controller describes the role configuration, i.e. which operations are in the +scope of a given role. In particular, the definition of a role may include the +following: +

+
    +
  • A list of P4 entities for which the controller may issue Write updates and +receive notification messages (e.g. DigestList and +IdleTimeoutNotification). +
  • +
  • Whether the controller is able to receive PacketIn messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketIn messages should be sent to the controller. +
  • +
  • Whether the controller is able to send PacketOut messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketOut messages are allowed to be sent by the controller. +
+ +

An unset role.config implies “full pipeline access” (similar to the default +role explained above). In order to support different role definition schemes, +role.config is defined as an Any Protobuf message [31]. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion. +

+

It is the job of the P4Runtime server to remember the role.config for every +device_id and role_id pair. +

5.3. Rules for Handling MasterArbitrationUpdate Messages Received from Controllers

+
    +
  1. +

    If the MasterArbitrationUpdate message is received for the first time on +this particular channel (i.e. for a newly connected controller): +

    +
      +
    1. +

      If device_id does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +NOT_FOUND error. +

    2. +
    3. +

      If the election_id is set and is already used by another controller for +the same (device_id, role_id), the P4Runtime server shall terminate +the stream by returning an INVALID_ARGUMENT error. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the number of open streams for the given (device_id, role_id) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a RESOURCE_EXHAUSTED error. +

    8. +
    9. +

      Otherwise, the controller is added to a list of connected controllers for +the given (device_id, role_id) and the server remembers the +controllers device_id, role_id and election_id for this gRPC +channel. See below for the rules to determine if this controller becomes +a master or slave, and what notifications are sent as a consequence. +

    +
  2. +
  3. +

    Otherwise, if the MasterArbitrationUpdate message is received from an +already connected controller: +

    +
      +
    1. +

      If the device_id does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. +

    2. +
    3. +

      If the role.id does not match the current role_id assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. If the controller wishes to change its role, +it must close the current stream channel and open a new one. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the election_id is set and is already used by another controller +(excluding the controller making the request) for the same +(device_id, role_id), the P4Runtime server shall terminate the stream +by returning an INVALID_ARGUMENT error. +

    8. +
    9. +

      If the election_id matches the one assigned to this stream: +

      +
        +
      1. +

        If the controller for this channel is the master, then the server +updates the role.config to the one specified in the +MasterArbitrationUpdate. An advisory mastership message is sent to +all controllers for this device_id and role_id informing +them of the new role.config. Since the format of role.config is +out of scope for the P4Runtime specification, the server will send +the advisory message for every update, even if the master sets the +same role.config as it has before. See the +following section for the format of +the advisory message. +

      2. +
      3. +

        If the controller is a slave, this is a no-op and the role.config +is ignored. No response is sent to any controller. +

      +
    10. +
    11. +

      Otherwise, the server updates the election_id it has stored for this +controller. This change might cause a change in mastership (this +controller might become master, or the controller might have downgraded +itself to a slave, see below), as well as notifications being sent to one +or more controllers. +

    +
+ +

If the MasterArbitrationUpdate is accepted by either of the two steps above +(cases 1.5. and 2.6. above), then the server determines if there are changes in +mastership. Let election_id_past be the highest election ID the server has +ever seen for the given device_id and role_id (including the one of the +current master if there is one). +

+
    +
  1. +

    If election_id is greater than or equal to election_id_past, then the +controller becomes master. The server updates the role configuration to +role.config for the given role.id. Furthermore: +

    +
      +
    1. +

      If there was no master for this device_id and role_id before and +there are no Write requests still processing from a previous master, +then the server immediately sends an advisory notification to all +controllers for this device_id and role_id. See the +following section for the format of the +advisory message. +

    2. +
    3. +

      If there was a previous master or Write requests in flight, then the +server carries out the following steps (in this order): +

      +
        +
      1. +

        The server stops accepting Write requests from the previous master +(if there is one). At this point, the server will reject all Write +requests with PERMISSION_DENIED. +

      2. +
      3. +

        The server notifies all controllers other than the new master of the +mastership change by sending the advisory notification described in +the following section. +

      4. +
      5. +

        The server will finish processing any Write requests that have +already started. If there are errors, they are reported as usual to +the previous master. If the previous master has already disconnected, +any possible errors are dropped and not reported. +

      6. +
      7. +

        The server now accepts the current controller as the new master, thus +accepting Write requests from this controller. The server updates +the highest election ID (i.e. election_id_past) it has seen for +this device_id and role_id to election_id. +

      8. +
      9. +

        The server notifies the new master by sending the advisory message +described in the following section. +

      +
    +
  2. +
  3. +

    Otherwise, the controller becomes a slave. If the controller was previously a +master (and downgraded itself), then an advisory message is sent to all +controllers for this device_id and role_id. Otherwise, the advisory +message is only sent to the controller that sent the initial +MasterArbitrationUpdate. See the +following section for the format of the +advisory message. +

+

5.4. Mastership Notifications

+

For any given device_id and role_id, any time a new master is chosen, a +master downgrades its status to a slave, a master disconnects, or the +role.config is updated by the master, all controllers for that +(device_id, role_id) are informed of this by sending a +StreamMessageResponse. The MasterArbitrationUpdate is populated as follows: +

+
    +
  • +

    device_id and role.id as given. +

  • +
  • +

    role.config is set to the role configuration the server received most +recently in a MasterArbitrationUpdate from a master. +

  • +
  • +

    election_id is populated as follows: +

    +
      +
    • +

      If there has not been any master at all, the election_id is left unset. +

    • +
    • +

      Otherwise, election_id is set to the highest election ID that the server +has seen for this device_id and role_id (which is the election_id of +the current master if there is any). +

    +
  • +
  • +

    status is set differently based on whether the notification is sent to the +master or a slave controller: +

    +
      +
    • +

      If there is a master: +

      +
        +
      • +

        For the master, status is OK (with status.code set to +google.rpc.OK). +

      • +
      • +

        For all slave controllers, status is set to non-OK (with +status.code set to google.rpc.ALREADY_EXISTS). +

      +
    • +
    • +

      Otherwise, if there is no master currently, for all slave controllers, +status is set to non-OK (with status.code set to +google.rpc.NOT_FOUND). +

    +
+ +

Note that on mastership changes with outstanding Write request, some +notifications might be delayed, see the +previous section for details. +

6. The P4Info Message

+

The purpose of P4Info was described under +Reference Architecture. +Here we describe the various +components. +

6.1. Common Messages

+

These messages appear nested within many other messages. +

6.1.1. Documentation Message

+

Documentation is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers. +

+
+
+
message Documentation {
+  // A brief description of something, e.g. one sentence
+  string brief = 1;
+  // A more verbose description of something.
+  // Multiline is accepted. Markup format (if any) is TBD.
+  string description = 2;
+}

6.1.2. Preamble Message

+

The preamble serves as the “descriptor” for each entity and contains the unique +instance ID, name, alias, annotations and documentation. +

+
+
+
message Preamble {
+  // ids share the same number-space; e.g. table ids cannot overlap with counter
+  // ids. Even though this is irrelevant to this proto definition, the ids are
+  // allocated in such a way that it is possible based on an id to deduce the
+  // resource type (e.g. table, action, counter, ...). This means that code
+  // using these ids can detect if the wrong resource type is used
+  // somewhere. This also means that ids of different types can be mixed
+  // (e.g. direct resource list for a table) without ambiguity. Note that id 0
+  // is reserved and means "invalid id".
+  uint32 id = 1;
+  // fully qualified name of the P4 object, e.g. c1.c2.ipv4_lpm
+  string name = 2;
+  // an alias (alternative name) for the P4 object, probably shorter than its
+  // fully qualified name. The only constraint is for it to be unique with
+  // respect to other P4 objects of the same type. By default, the compiler uses
+  // the shortest suffix of the name that uniquely identifies the object. For
+  // example if the P4 program contains two tables with names s.c1.t and s.c2.t,
+  // the default aliases will respectively be c1.t and c2.t. In the future, the
+  // P4 programmer may also be able to override the default alias for any P4
+  // object (TBD).
+  string alias = 3;
+  repeated string annotations = 4;
+  // The location of `annotations[i]` is given by `annotation_locations[i]`.
+  repeated SourceLocation annotation_locations = 7;
+  // Documentation of the entity
+  Documentation doc = 5;
+  repeated StructuredAnnotation structured_annotations = 6;
+}

6.1.3. Annotating P4 Entities with Documentation

+

P4 entities may be annotated using the following annotations: +

+
+
+
@brief(string...)
+@description(string...)
+

Attaching either or both of these annotations to an entity will generate a +P4Info Documentation Message, which in turn will +appear in the Preamble Message for the entity. +

+

The P4 compiler should not emit annotation messages in the P4Info for these +specific cases; instead, it should generate the Documentation messages as +described. +

+

The following example shows documentation annotations for a table entity: +

+
+
+
@brief("Match IPv4 addresses to next-hop MAC and port")
+@description("Match IPv4 addresses to next-hop MAC and port. \
+Uses LPM match type.")
+table my_ipv4_lkup {
+  ...
+}

6.1.4. Structured Annotations

+

P4 supports both unstructured and structured annotations [13]. +Unstructured annotations of the form MyAnno1 or MyAnno2(body-content) can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +MyAnno3[] or MyAnno4[kvList|expressionList] have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this. +

+

The annotations described up to this point, e.g. @brief(), have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as repeated string annotations fields in the various messages. +Similarly, structured annotations are represented in repeated +StructuredAnnotation structured_annotations fields which are siblings to the +unstructured annotations. The structured_annotations contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations. +

+

The structured annotation messages are defined in p4types.proto. +

+
+
+
message KeyValuePair {
+  string key = 1;
+  Expression value = 2;
+}
+
+message KeyValuePairList {
+  repeated KeyValuePair kv_pairs = 1;
+}
+
+message Expression {
+  oneof value {
+    string string_value = 1;
+    int64 int64_value = 2;
+    bool bool_value = 3;
+  }
+}
+
+message ExpressionList {
+  repeated Expression expressions = 1;
+}
+
+message StructuredAnnotation {
+  string name = 1;
+  oneof body {
+    ExpressionList expression_list = 2;
+    KeyValuePairList kv_pair_list = 3;
+  }
+  // Location of the '@' symbol of this annotation in the source code.
+  SourceLocation source_location = 4;
+}
+

The StructuredAnnotation message can represent either a KeyValuePairList +or an ExpressionList. +

+

The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The p4c +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don't match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler may print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions. +

+

The following invariants hold: +

+
    +
  1. +

    For any P4 entity, there are no two StructuredAnnotations that have the +same name. +

  2. +
  3. +

    Within a KeyValuePairList, there are no two KeyValuePairs that have the +same key. +

+
6.1.4.1. Structured Annotation Examples
+

We omit the source_location field in the following examples. +

+

Empty Expression List +

+
+
+
@Empty[]
+table t {
+    ...
+}
+

The generated P4Info will contain the following. +

+
+
+
structured_annotations {
+  name: "Empty"
+}
+

Mixed Expression List +

+
+
+
#define TEXT_CONST "hello"
+#define NUM_CONST 6
+@MixedExprList[1,TEXT_CONST,true,1==2,5+NUM_CONST]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedExprList"
+  expression_list {
+    expressions {
+      int64_value: 1
+    }
+    expressions {
+      string_value: "hello"
+    }
+    expressions {
+      bool_value: true
+    }
+    expressions {
+      bool_value: false
+    }
+    expressions {
+      int64_value: 11
+    }
+  }
+}
+

kvList of Mixed Expressions +

+
+
+
@MixedKV[label="text", my_bool=true, int_val=2*3]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedKV"
+  kv_pair_list {
+    kv_pairs {
+      key: "label"
+      value {
+        string_value: "text"
+      }
+    }
+    kv_pairs {
+      key: "my_bool"
+      value {
+        bool_value: true
+      }
+    }
+    kv_pairs {
+      key: "int_val"
+      value {
+        int64_value: 6
+      }
+    }
+  }
+}

6.1.5. SourceLocation Message

+

A source location describes a location within a .p4-source file. The +SourceLocation message is defined in p4types.proto as follows: +

+
+
+
// Location of code relative to a given source file.
+message SourceLocation {
+  // Path to the source file (absolute or relative to the working directory).
+  string file = 1;
+  // Line and column numbers within the source file, 1-based.
+  int32 line = 2;
+  int32 column = 3;
+}
+

We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations. +

+

The SourceLocation message associated with an annotation holds the location of +the @ symbol introducing the annotation in the P4 source code; the message can +be found in the following place: +

+
    +
  • +

    For unstructured annotations, every message containing a field +repeated string annotations also contains a field +repeated SourceLocation annotation_locations. The i-th member of +annotation_locations is the source location of the i-th member of +annotations. +

  • +
  • +

    For structured annotations, every StructuredAnnotation message contains +a field SourceLocation source_location holding its source location. +

+

6.2. PkgInfo Message

+

The PkgInfo message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. PkgInfo can be extracted +and used to facilitate “browsing” of available P4 programs from a +library. Although all fields are technically “optional,” every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included. +

+
+
+
// Can be used to manage multiple P4 packages.
+message PkgInfo {
+  // a definitive name for this configuration, e.g. switch.p4_v1.0
+  string name = 1;
+  // configuration version, free-format string
+  string version = 2;
+  // brief and detailed descriptions
+  Documentation doc = 3;
+  // Miscellaneous metadata, free-form; a way to extend PkgInfo
+  repeated string annotations = 4;
+  // the target architecture, e.g. "psa"
+  string arch = 5;
+  // organization which produced the configuration, e.g. "p4.org"
+  string organization = 6;
+  // contact info for support,e.g. "tech-support@acme.org"
+  string contact = 7;
+  // url for more information, e.g. "http://support.p4.org/ref/p4/switch.p4_v1.0"
+  string url = 8;
+  // Miscellaneous metadata, structured; a way to extend PkgInfo
+  repeated StructuredAnnotation structured_annotations = 9;
+}

6.2.1. Annotating P4 code with PkgInfo

+

A P4 progam's PkgInfo may be declared using one or more of the following +annotations, attached to the main block only: +

+
+
+
@pkginfo(key=value)
+@pkginfo(key=value[,key=value,...])
+@brief("A brief description")
+@description("A longer\
+description")
+@custom_annotation(...)
+@another_custom_annotation(...)
+

Above we see several different types of annotations: +

+
    +
  • +

    @pkginfo - This is used to populate a specific field within the PkgInfo +message. Multiple @pkginfo annotations are allowed. For compactness, +multiple key-value pairs can appear in a single @pkginfo annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The keys must be from +among the message fields inside PkgInfo, for example, name, version, +etc. Each key-value pair assigns a value to the corresponding field inside the +single PkgInfo message for the program's P4Info. One exception is that the +Documentation field of PkgInfo must be expressed as individual +@description and @brief annotations, see next bullets. The key arch will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself. +

  • +
  • +

    @brief - This will populate the PkgInfo.doc.brief message field. +

  • +
  • +

    @description - This will populate the PkgInfo.doc.description message +field +

  • +
  • +

    @<anything else> - This will create a PkgInfo.annotation entry +

+ +

Declaring one or more of these annotations on main will +generate a single corresponding PkgInfo message in the P4Info as described in +PkgInfo Message. +

+

The following example shows @pkginfo annotations using a mixture of single and +multiple key-value pairs. It also shows @brief and @description annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the PkgInfo message. The custom annotations will +be appended to the PkgInfo.annotations list. +

+
+
+
@pkginfo(name="switch.p4",version="2")
+@pkginfo(organization="p4.org")
+@pkginfo(contact="info@p4.org")
+@pkginfo(url="www.p4.org")
+@brief("L2/L3 switch")
+@description("L2/L3 switch.\
+Built for data-center profile.")
+@my_annotation1(...) // Not well-known, this will appear in PkgInfo annotations
+@my_annotation2(...) // Not well-known, this will appear in PkgInfo annotations
+PSA_Switch(IgPipeline, PacketReplicationEngine(), EgPipeline,
+           BufferingQueueingEngine()) main;

6.3. ID Allocation for P4Info Objects

+

P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(e.g. table, action, counter, ). The most significant 8 bits of the ID +encodes the object type (as per Table 1). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (p4.config.v1.P4Ids.Prefix). These values must +be used (e.g. by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table 2 shows the ID +layout. +

+
+ + + + + + + + + + + + + + + + + + + + + +
8-bit prefix value P4 object type
0x00 Reserved (unspecified)
0x01 Action
0x02 Table
0x03 Value-set
0x04 Controller header (header type with @controller_header annotation)
0x050x0f Reserved (for future P4 built-in objects)
0x10 Reserved (start of PSA extern types)
0x11 PSA Action profiles / selectors
0x12 PSA Counter
0x13 PSA Direct counter
0x14 PSA Meter
0x15 PSA Direct meter
0x16 PSA Register
0x17 PSA Digest
0x180x7f Reserved (for future PSA extern types)
0x80 Reserved (start of vendor-specific extern types)
0x810xfe Vendor-specific extern types
0xff Reserved (max prefix value)
+
+ +
Table 1. Mapping of P4Info object type to 8-bit ID prefix value
+
+ + + + +
MSB bit 31 .. bit 24 bit 23 .. bit 0 LSB
Object type prefix Generated suffix (e.g. by the compiler)
+
+ +
Table 2. Format of P4Info object IDs
+

It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with @id (see Table +3). The compiler must honor the @id annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (i.e. if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same @id value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct. +

+
+ + + + + + + + + + +
P4 declaration(s) Compiler-allocated ID(s)
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) table tA... Error(same ID suffixes for 2 objects of the same type)
@id(0x12ab34) table tB...
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) action act1... 0x0112ab34
+
+ +
Table 3. Example of statically-assigned P4Info object IDs
+

The @id annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively). +

6.4. P4Info Objects

6.4.1. Table

+

Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this table. +

  • +
  • +

    match_fields, a repeated field of type MatchField representing the data to +be used to construct the lookup key matched in this table. Each MatchField +message is defined with the following fields: +

    +
      +
    • +

      id, the uint32 identifier of this MatchField, unique in the scope of +this table. No rules are prescribed on the way MatchField IDs should be +allocated, as long as two MatchField of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the @id annotation, or let the compiler +choose them. +

    • +
    • +

      name, the string representing the name of this MatchField. +

    • +
    • +

      annotations, a repeated field of strings, each one representing a P4 +annotation associated to this match field. +

    • +
    • +

      bitwidth, an int32 value set to the size in bits of this match field. +

    • +
    • +

      match, a oneof describing the match behavior for this field; it can be +either: +

      +
        +
      • match_type, an enum field of type MatchType, which includes all +possible PSA match kinds. +
      • +
      • other_match_type, a string field which can be used to encode any +architecture-specific match type. +
      +
    • +
    • +

      doc, a Documentation message describing this match field. +

    • +
    • +

      type_name, which indicates whether the match field has a user-defined +type; this is useful for +translation. +

    +
  • +
  • +

    action_refs, a repeated ActionRef field representing the set of possible +actions for this table. The ActionRef message is used to reference an action +specified in the same P4Info message and it includes the following fields: +

    +
      +
    • id, the uint32 identifier of the action. +
    • +
    • scope, an enum value which can take one of three values: + TABLE_AND_DEFAULT, TABLE_ONLY and DEFAULT_ONLY. The scope of the + action is determined by the use of the P4 standard annotations + @tableonly and @defaultonly [18]. TABLE_ONLY + (@tableonly annotation) means that the action can only appear within + the table, and never as the default action. DEFAULT_ONLY + (@defaultonly annotation) means that the action can only be used as the + default action. TABLE_AND_DEFAULT is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action. +
    • +
    • annotations, a repeated string field, each one representing a P4 +annotation associated to the action reference in this table. +
    +
  • +
  • +

    const_default_action_id, if this table has a constant default action, this +field will carry the uint32 identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action's +arguments. +

  • +
  • +

    implementation_id, the uint32 identifier of the “implementation” of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (e.g. a PSA ActionProfile or ActionSelector +instance). The table is then referred to as an indirect match table. +

  • +
  • +

    direct_resource_ids, repeated uint32 identifiers for all the direct +resources attached to this table, such as DirectMeter and DirectCounter +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2. +

  • +
  • +

    size, an int64 describing the desired number of table entries that the +target should support for the table. See the “Size” subsection within the +“Table Properties” section of the P416 language specification for details +[30]. +

  • +
  • +

    idle_timeout_behavior, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +Idle-Timeout section). Value can be any of the +IdleTimeoutBehavior enum: +

    +
      +
    • NO_TIMEOUT (default value), which means that idle timeout is not +supported for this table. +
    • +
    • NOTIFY_CONTROL, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +Table Idle Timeout Notifications). +
    +
  • +
  • +

    is_const_table, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime. +

  • +
  • +

    other_properties, an Any Protobuf message [31] to embed +architecture-specific table properties [30] which are not part +of the core P4 language or of the PSA architecture. +

+

6.4.2. Action

+

Action messages are used to specify all possible actions of all match-action +tables. +

+

The Action message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this action +

  • +
  • +

    params, a repeated field of Param messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each Param message contains the +following fields: +

    +
      +
    • id, the uint32 identifier of this parameter. No rules are prescribed +on the way Param IDs should be allocated, as long as two Param of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the @id +annotation, or let the compiler choose them. +
    • +
    • name, the string representing the name of this parameter. +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this parameter. +
    • +
    • bitwidth, an int32 value set to the size in bits of this parameter. +
    • +
    • doc, which describes this parameter using a Documentation message. +
    • +
    • type_name, which indicates whether the action parameter has a +user-defined type; this is useful for +translation. +
    +
+

6.4.3. ActionProfile

+

ActionProfile messages are used to specify all available instances of Action +Profile and Action Selector PSA externs. +

+

PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile member, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime. +

+

PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into groups. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime. +

+

While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same ActionProfile message to describe both. +

+

The ActionProfile message includes the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Action +Profile or Selector. +

  • +
  • +

    table_ids, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector. +

  • +
  • +

    with_selector, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern. +

  • +
  • +

    size, an int64 representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups. +

  • +
  • +

    max_group_size, an int32 representing the maximum sum of all member +weights within any given selector group, in the case of an Action Selector, or +0 for an Action Profile. PSA programs can use the @max_group_size annotation +to provide this value for Action Selectors. If the annotation is omitted, the +P4Info field will default to 0. +

+

6.4.4. Counter & DirectCounter

+

Counter and DirectCounter messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is: +

+
    +
  • +

    Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index. +

  • +
  • +

    Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table. +

+ +

Both Counter and DirectCounter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this counter +extern instance. +

  • +
  • +

    spec, a message of of type CounterSpec used to describe the compile-time +configuration of this counter. Currently, the CounterSpec message is used to +carry only the counter unit, which can be any of the CounterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES: byte counter. +
    • +
    • PACKETS: packet counter. +
    • +
    • BOTH: combination of both byte and packet counter. +
    +
+ +

For indexed counters, the Counter message contains also a size field, an +int64 representing the maximum number of independent values that can be held +by this counter array. Conversely, the DirectCounter message contains a +direct_table_id field that carries the unit32 identifier of the table to +which this direct counter is attached. +

+

For indexed counters, the Counter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.5. Meter & DirectMeter

+

Meter and DirectMeter messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is: +

+
    +
  • +

    Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +e.g. to set the rate threshold. +

  • +
  • +

    Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table. +

+ +

Both Meter and DirectMeter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this meter +extern instance. +

  • +
  • +

    spec, a message of type MeterSpec used to describe the capabilities of +this meter extern instance. Currently, the MeterSpec message is used to +carry only the meter unit, which can be any of the MeterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES, which signifies that this meter can be configured with rates +expressed in bytes/second. +
    • +
    • PACKETS, for rates expressed in packets/second. +
    +
+ +

For indexed meters, the Meter message contains also a size field, an int64 +representing the maximum number of independent cells that can be held by this +meter. Conversely, the DirectMeter message contains a direct_table_id field +that carries the uint32 identifier of the table to which this direct meter is +attached. +

+

For indexed meters, the Meter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.6. ControllerPacketMetadata

+

ControllerPacketMetadata messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server. +

+

When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet. +

+

Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +@controller_header("packet_in") and @controller_header("packet_out"), +respectively. ControllerPacketMetadata messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages). +

+

A P4Info message can contain at most two ControllerPacketMetadata messages, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message where preamble.name is set to "packet_in" +and "packet_out" for packet-in and packet-out metadata, respectively. +

  • +
  • +

    metadata, a repeated field of type Metadata, where each Metadata message +includes the following fields: +

    +
      +
    • id, a uint32 identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two Metadata of the +same ControllerPacketMetadata message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the @id annotation, or let the compiler choose them. +
    • +
    • name, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below). +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this metadata. +
    • +
    • bitwidth, an int32 representing the size in bits of this metadata. +
    • +
    • type_name, which indicates whether the metadata field has a +user-defined type; this is useful for +translation. +
    +
+ +

As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding ControllerPacketMetadata +messages. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  bit<9> egress_port; /* suggested port where the packet
+                         should be sent */
+  bit<8> queue_id;    /* suggested queue ID */
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  bit<9> ingress_port; /* data plane port ID where
+                          the original packet was received */
+  bit<1> is_clone;     /* 1 if this is a clone of the
+                          original packet */
+}
+
+
+
controller_packet_metadata {
+  preamble {
+    id: 2868916615
+    name: "packet_out"
+    annotations: "@controller_header(\"packet_out\")"
+  }
+  metadata {
+    id: 1
+    name: "egress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "queue_id"
+    bitwidth: 8
+  }
+}
+
+controller_packet_metadata {
+  preamble {
+    id: 2868941301
+    name: "packet_in"
+    annotations: "@controller_header(\"packet_in\")"
+  }
+  metadata {
+    id: 1
+    name: "ingress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "is_clone"
+    bitwidth: 1
+  }
+}
+

Note that the use of @controller_header is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages. +

6.4.7. ValueSet

+

ValueSet messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P416 +specification [39]. +

+

The ValueSet message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Value +Set. +

  • +
  • +

    match, a repeated field of MatchField messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the match_fields repeated field in the +Table message. +

  • +
  • +

    size, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +value_set constructor call. +

+ +

According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of bit<W>, +tuple, or struct [26]. The rest of this section looks at all 3 of +these cases and gives an example ValueSet message when appropriate. +

+
    +
  1. +

    If the type parameter is bit<W>, match will include exactly one +MatchField message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used): +

    +
      +
    • id: set to 1 +
    • +
    • bitwidth: set to the value of W +
    • +
    • match_type: set to EXACT +
    +
+ +
+
+
@id(1) value_set<bit<8> >(4) pvs;
+select (hdr.f8) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    bitwidth: 8
+    match_type: EXACT
+  }
+  size: 4
+}
+
    +
  1. +

    If the type parameter is a tuple, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program. +

  2. +
  3. +

    If the type parameter is a struct, this version of P4Runtime requires that +all the fields of the struct be of type bit<W> (where W can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +match field will include one MatchField message for each field in the +struct, with the following fields: +

    +
      +
    • id: must be unique with respect to the other match entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +@id annotation, or let the compiler choose them. +
    • +
    • name: set to the name of the corresponding struct field. +
    • +
    • annotations: set to the list of P4 annotations associated with the struct +field, except for the @match annotation, if present (see the match field +below). +
    • +
    • bitwidth: set to the value of W for the corresponding struct field. +
    • +
    • type_name, which indicates whether the struct field has a user-defined +type; this is useful for +translation. +
    • +
    • match: by default match_type is set to EXACT; the P4 programmer can +specify a different match type by using the @match annotation +[26]. +
    • +
    • doc: documentation associated with the struct field. +
    +
+ +
+
+
struct match_t {
+  @id(1) bit<8> f8;
+  @id(2) @match(ternary) bit<16> f16;
+  @id(3) @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

In the above example, the @id annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs. +

+

Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a user-defined +type that resolves to a bit<W>, or a struct where +one or more fields is a user-defined type that +resolves to a bit<W>. For each MatchField that corresponds to a user-defined +type, the type_name field must be set to the appropriate value (i.e. the name +of the type). +

6.4.8. Register

+

Register messages are used to specify all possible instances of Register PSA +externs. +

+

Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime. +

+

The Register message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this register +instance. +

  • +
  • +

    type_spec, which specifies the data type stored by this register, expressed +using a P4DataTypeSpec message (see section on Representation of Arbitrary +P4 Types). +

  • +
  • +

    size, an int32 value representing the total number of independent register +cells available. +

  • +
  • +

    index_type_name, which indicates whether the register index has a +user-defined type. This is useful for +translation. The underlying built-in type +must be a fixed-width unsigned bitstring (bit<W>). +

+

6.4.9. Digest

+

Digest messages are used to specify all possible instances of Packet Digest +PSA externs. +

+

A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages. +

+

The Digest message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this digest +instance. +

  • +
  • +

    type_spec, which specifies the data type of an individual digest +notification using a P4DataTypeSpec message (see section on Representation +of Arbitrary P4 Types). +

+

6.4.10. Extern

+

Extern messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one Extern message instance in P4Info. The Extern message defines +the following fields: +

+
    +
  • +

    extern_type_id, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the reserved +range [0x81, 0xfe]. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture. +

  • +
  • +

    extern_type_name, which specifies the fully-qualified P4 name of the extern +type. +

  • +
  • +

    instances, a repeated field of ExternInstance Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +ExternInstance in turn defines the following fields: +

    +
      +
    • preamble, a Preamble message with the ID, name, and alias of this digest +instance. +
    • +
    • info, an Any Protobuf message [31] which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for info should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on Extending +P4Runtime for non-PSA Architectures for more +information. +
    +
+ +

If the P4 program does not include any instance of a given extern type, the +Extern message instance for that type should be omitted from the P4Info. +

6.5. Support for Arbitrary P4 Types with P4TypeInfo

+

See section on Representation of Arbitrary P4 +Types. +

7. P4 Forwarding-Pipeline Configuration

+

The ForwardingPipelineConfig captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the “Device Configuration” and sometimes also referred to as +the “P4 Blob”. It is defined as: +

+
+
+
message ForwardingPipelineConfig {
+  config.P4Info p4info = 1;
+  bytes p4_device_config = 2;
+  message Cookie {
+    uint64 cookie = 1;
+  }
+  Cookie cookie = 3;
+}
+

The p4info field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic. +

+

The p4_device_config is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new ForwardingPipelineConfig on that target. +

+

The cookie field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a GetForwardingPipelineConfig RPC. +When writing the config via a SetForwardingPipelineConfig RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present. +

8. General Principles for Message Formatting

8.1. Set / Unset Protobuf Field

+

In Protobuf version 3 (proto3), the default value for a message field is +“unset” [4]. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +CounterEntry message, an “unset” index field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the index message field is +set, a single entry will be read. +

+

Let's look at the counter example in more details. Based on this specification +document, the C++ server code which processes CounterEntry messages may look +like this: +

+
+
+
auto *counter_entry = ...
+if (counter_entry->has_index()) {
+  auto index = counter_entry->index().index();
+  read_one_entry(counter_entry->id(), index);
+} else {
+  read_all_entries(counter_entry->id());
+}
+
    +
  1. +

    Reading a single counter entry at index 0 in the counter array with id +<id>: +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
      +entry.mutable_index();
      +// The above line sets the index field; it is equivalent to:
      +// auto *index = entry.mutable_index();
      +// index->set_index(0);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
      +index {}
    • +
    • Expected behavior: Counter entry at index 0 is read. Notice that the +index subfield is missing under the index field message of +CounterEntry in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages. +
    +
  2. +
  3. +

    Reading all counter entries by leaving the index field unset +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
    • +
    • Expected behavior: All counter entries for the provided counter +instance are read. Notice that the index message field is unset (default +value) and is therefore omitted from the textual representation of the +message. +
    +
+

8.2. Read-Write Symmetry

+

The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example: +

+
+
+
intended_value = value
+
+status = server.write(intended_value, p4_entity)
+observed_value = server.read(p4_entity)
+
+assert(intended_value == observed_value)
+

To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If Read RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol's complexities to the client implementations. +

+

In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the match fields in a TableEntry message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +MessageDifferencer class [36] included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance. +

8.3. Zero as Reserved Value

+

p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a uint32. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a WriteRequest or a SetForwardingPipelineConfigRequest. +

8.4. Bytestrings

+

P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (bit<W>) or signed (int<W>), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +bytes Protobuf type. The correct bitwidth as per the P4 program of +each integer variable exposed through P4Runtime is specified in the P4Info +message. +

+

The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals: +

+
    +
  • +

    It ensures that a properly encoded binary string's integer value conforms +to the P4Info-specified bitwidth. +

  • +
  • +

    It supports read-write symmetry. +

  • +
  • +

    It helps facilitate non-disruptive P4 program updates. +

+ +

In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type bit<W> and/or int<W>. +

+

Note that this representation does not make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range. +

+

In the P4Runtime API version 1.0, values of table key fields, action parameters, +and fields in packet-in and packet-out headers between a device and the +controller (see 6.4.6), may not be of type int<W>. +The rules for encoding signed values thus only apply to messages of type +P4Data (see 8.5.3). +

+

For a value of type bit<W>, the fewest number of bits required to represent +the integer value $V > 0$ is the smallest integer $A$ such that $V \leq 2^A -1$. +

+

For a value of type int<W>, the fewest number of bits required to represent +the integer value $V \neq 0$ in 2's complement form is the smallest integer $A$ +such that $-2^{A-1} \leq V \leq 2^{A-1} - 1$. +

+

As a special case, define that the value $V=0$ requires at least $A=1$ bit to +represent, regardless of whether it is signed or unsigned. +

+

The shortest possible binary string for an integer $V$ that needs $A$ bits to +represent it is computed as: +

+
+
+
minimum_string_size = floor((A + 7) / 8)
+

Binary strings with the byte length computed as minimum_string_size promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies. +

+

Any additional bits in the bytes sent for an unsigned integer value (type +bit<W>) must be 0. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with 0. +

+

Any additional bits in the bytes sent for a signed integer value (type int<W>) +must be copies of the sign bit, i.e. 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with copies of the +sign bit, i.e. 0 for non-negative values, or 0xff for negative values. In 2's +complement representation, this is called “sign extension”, and leaves the +numeric value represented unchanged. +

+

Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value. +

+

For a received bitstring expected to fit within a bit<W> type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring's width is W bits or less. +

+

For a received bitstring expected to fit within an int<W> type, the value it +represents is in range if, after “undoing sign extension”, the remaining bit +string's width is W bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other. +

+

If the string's byte length is zero, the server always rejects the string. +

+

When the server rejects a binary string due to any of the previous criteria, +it returns an OUT_OF_RANGE error. +

+

For all binary strings, P4Runtime uses big-endian (i.e. network) byte-order. +For signed integer values (int<W> P4 type), P4Runtime uses the same two's +complement bitwise representation as P4. Table 4 +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above. +

+
+ + + + + + + + + + + + + + + + + +
P4 type Integer value P4Runtime binary string Read-write symmetry
bit<8> 99 (0x63) \x63 yes
bit<16> 99 (0x63) \x00\x63 no
bit<16> 99 (0x63) \x63 yes
bit<16> 12388 (0x3064) \x30\x64 yes
bit<16> 12388 (0x3064) \x00\x30\x64 no
bit<12> 99 (0x63) \x00\x63 no
bit<12> 99 (0x63) \x63 yes
bit<12> 99 (0x63) \x00\x00\x63 no
int<8> 99 (0x63) \x63 yes
int<8> -99 (-0x63) \x9d yes
int<8> -99 (-0x63) \xff\x9d no
int<12> -739 (-0x2e3) \xfd\x1d yes
int<16> 0 (0x0) \x00\x00 no
int<16> 0 (0x0) \x00 yes
+
+ +
Table 4. Examples of Valid Bytestring Encoding
+

Table 5 shows some examples of invalid +P4Runtime binary strings: +

+
+ + + + + + + + + + + + +
P4 type P4Runtime binary string
bit<8> \x01\x63
bit<8> empty string
bit<16> \x01\x00\x63
bit<12> \x10\x63
bit<12> \x01\x00\x63
bit<12> \x00\x40\x63
int<8> \x00\x9d
int<12> \x8d\x1d
int<16> empty string
+
+ +
Table 5. Examples of Invalid Bytestring Encoding
+

As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from bit<8> to bit<9>, a server +running the bit<9> version of the P4 program will accept requests from +clients that remain on the bit<8> P4Runtime version. +

+

Despite the server's binary string flexibility for P4 program update support, +the client and server must both remain aware of the +read-write symmetry +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values. +

+

Representation of variable-length integer values (varbit<W> P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the dynamic-length of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an OUT_OF_RANGE error code otherwise. +

8.5. Representation of Arbitrary P4 Types

8.5.1. Problem Statement

+

The P416 language includes more complex types than just binary strings +[3]. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table 6 shows the different +P416 types and how they are allowed to be used, as per the P416 +specification. +

+
+ + + + + + + + + + + + + + + + + + + +
Container type
Element type header header_union struct or tuple
bit<W> allowed error allowed
int<W> allowed error allowed
varbit<W> allowed error allowed
int error error error
void error error error
error error error allowed
match_kind error error error
bool error error allowed
enum allowed1 error allowed
header error allowed allowed
header stack error error allowed
header_union error error allowed
struct error error allowed
tuple error error allowed
+
+ +
Table 6. P4 Type Usage
+

For example, the following P416 objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects. +

+
+
+
Digest<tuple<bit<4>, bit<8> > >() digest_complex;
+digest_complex.pack({ hdr.ipv4.version, hdr.ipv4.protocol });
+// ...
+header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

One solution would be to use only binary string (bytes type) in +p4runtime.proto and to define a custom serialization format for complex P416 +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P416 types. +

8.5.2. P4 Type Specifications in p4info.proto

+

In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type ip_t, which is a header union with 2 possible headers: +ipv4 with type ipv4_t and ipv6 with type ipv6_t. Similarly, they need to +know the field layout for both of these header types. +

+

To achieve this we introduce 2 main Protobuf messages: P4TypeInfo and +P4DataTypeSpec. +

+

P4TypeInfo is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P416 program. These +named types are struct, header, header_union, enum and +serializable_enum; for each of these we have a type specification message, +respectively P4StructTypeSpec, P4HeaderTypeSpec, P4HeaderUnionTypeSpec, +P4EnumTypeSpec and P4SerializableEnumTypeSpec. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. P4TypeInfo also includes the list of parser errors for the program, as +a P4ErrorTypeSpec message. +

+

P4DataTypeSpec is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each P4DataTypeSpec message corresponds to a compile-time type in the +original P416 program (e.g. the type parameter of an extern). This +compile-time type is represented as a Protobuf oneof, which can be: +

+
    +
  • +

    a string representing the name of the type in case of a named type (struct, +header, header_union, enum, serializable_enum or user-defined “new” +type), +

  • +
  • +

    an empty Protobuf message for bool and error, or +

  • +
  • +

    a Protobuf message for other anonymous types (bit<W>, int<W>, varbit<W>, +tuple or stack). The “binary string” types (bit<W>, int<W>, and +varbit<W>) are grouped together in the P4BitstringLikeTypeSpec message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf bytes +type). +

+ +

For all P416 compound types (tuple, struct, header, and header_union), +the order of members in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P416 declaration. The same goes for the order of members of an enum +(serializable or not) or members of error. +

8.5.3. P4Data in p4runtime.proto

+

P4Runtime uses the P4Data message to represent values of arbitrary types. The +P4Runtime client must generate correct P4Data messages based on the type +specification information included in P4Info. The P4Data message was designed +to introduce little overhead compared to using binary strings in the most common +case (P416 bit<W> type). +

+

Just like its P4Info counterpart - P4DataTypeSpec -, P4Data uses a Protobuf +oneof to represent all possible values. +

+

We define a canonical representation for P4Data messages therefore +guaranteeing read-write symmetry by introducing the following requirements: +

+
    +
  • +

    The order of members in P4StructLike and the order of bitstrings in +P4Header must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P416 type +declaration. +

  • +
  • +

    An invalid header is represented by a P4Header message where the is_valid +field is false and the bitstrings repeated field is empty. +

  • +
  • +

    An invalid header union (i.e. all headers in the union are invalid) is +represented by a P4HeaderUnion message where the valid_header_name is the +empty string (default value for the field) and the valid_header is unset. +

  • +
  • +

    The order of entries in P4HeaderStack and P4HeaderUnionStack is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the entries field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding P4HeaderStackTypeSpec or +P4HeaderUnionStackTypeSpec message. +

+

8.5.4. Example

+

Let's look at the Register example again: +

+
+
+
header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

Here's the corresponding entry in the P4Info message: +

+
+
+
registers {
+  preamble {
+    id: 369119267
+    name: "register_ip"
+    alias: "register_ip"
+  }
+  type_spec {
+    header_union {
+      name: "ip_t"
+    }
+  }
+  size: 128
+}
+type_info {
+  headers {
+    key: "ipv4_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  headers {
+    key: "ipv6_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  header_unions {
+    key: "ip_t"
+    value {
+      members {
+        name: "ipv4"
+        header {
+          name: "ipv4_t"
+        }
+      }
+      members {
+        name: "ipv6"
+        header {
+          name: "ipv6_t"
+        }
+      }
+    }
+  }
+}
+

Here's a p4.WriteRequest to set the value of register_ip[12]: +

+
+
+
update {
+  type: INSERT
+  entity {
+    register_entry {
+      register_id: 369119267
+      index {
+        index: 12
+      }
+      data {
+        header_union {
+          valid_header_name: "ipv4"
+          valid_header {
+            is_valid: true
+            bitstrings: "\x04"
+            bitstrings: # ...
+          }
+        }
+      }
+    }
+  }
+}

8.5.5. enum, serializable enum and error

+

P416 supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or “unsafe” enum) +[5]. For enum types with no underlying type as well as error +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in P4Data to represent enum and +error values. +

+

Serializable enum types have an underlying fixed-width unsigned integer +representation (bit<W>). All named enum members must be assigned an integer +value by the P4 programmer, but not all valid numeric values for the +underlying type need to have a corresponding name. P4TypeInfo includes the +mapping between entry name and entry value. When providing serializable enum +values through P4Data, one must use the assigned integer value (enum_value +bytestring field). P4Runtime does not provide a way for the client to use the +name even when the enum member has one instead of the value, as it makes +it easier for the server to respect the read-write +symmetry principle. +

8.5.6. User-defined types

+

P416 enables programmers to introduce new types [11]. While similar +to typedef, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +translation. When introducing a new type, the +declaration can be annotated with @p4runtime_translation to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for port numbers, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. The @p4runtime_translation annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (bit<W>). The type exposed to the control plane (referred to as the +controller_type) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a URI (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the controller_type of the values exposed to the control plane. The +controller_type can be either bit<W> where W is any positive integer, or +string, or a positive integer W which has the same meaning as bit<W>. +Specifying just an integer is deprecated. +

+

It is recommended that the URI includes at least the P4 architecture name and +the type name. +

+

A @p4runtime_translation annotation need not have any effect if it is used to +annotate anything in a P4 program other than a type declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect. +

+

User-defined types are specified using the P4NewTypeSpec message, which has +the following fields: +

+
    +
  • +

    representation, a Protobuf oneof specifying how values of this type are +exchanged between client and server; it can be either: +

    +
      +
    • +

      original_type, if and only if no @p4runtime_translation annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 type declaration is itself a +user-defined type, original_type is obtained by “walking” the chain of +type declarations recursively until a built-in type (e.g. bit<W>) is +found. +

    • +
    • +

      translated_type, if and only if the P4 type declaration was annotated +with @p4runtime_translation. It is of type P4NewTypeTranslation, +which itself has two fields uri and either sdn_string or +sdn_bitwidth , which map to the two input parameters to the +annotation. +

    +
  • +
  • +

    annotations, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration. +

+ +

For example, an architecture in this case PSA may introduce a new type +for port numbers: +

+
+
+
// Controller refers to ports as a string, e.g. "eth0".
+@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+// Controller refers to ports as a 32-bit integer, e.g. 0xffffffff.
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+// Same as above.
+@p4runtime_translation("p4.org/psa/v1/PortId_32_t", 32)
+type bit<9> PortId_32_t;
+

In this case, the P4Info message would include the following P4TypeInfo +messages: +

+
+
+
type_info {
+  new_types {
+    key: "PortId_String_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_String_t"
+        sdn_string: {}
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_Bit32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_Bit32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+

Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (e.g. through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over @p4runtime_translation to enable users +to overwrite annotations included as part of the P4 architecture definition. +

8.5.7. Trade-off for v1.x Releases

+

For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +bytes with P4Data in the p4.v1.FieldMatch message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +bytes to provide action parameter values and controller metadata +values. However P4Data is used whenever appropriate for PSA externs and we +encourage the use of P4Data in architecture-specific extensions. +

+

In order to support translation for action +parameters and match fields, we include a type_name field in +p4.config.v1.MatchField, p4.config.v1.Action.Param and +p4.config.v1.ControllerPacketMetadata.Metadata. In addition, the bitwidth +field for all of these message types must abide by the following rule when +type_name names a translated user-defined type: +

+
    +
  • +

    If the controller_type is a fixed-width unsigned bitstring, the bitwidth +field must be set to the bitwidth of the controller_type. This information +is redundant with the one included in the P4TypeInfo entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent. +

  • +
  • +

    Otherwise (i.e., if the controller_type is a string), the bitwidth must +be “unset”, which, in Protobuf version 3, is the same as setting the field to +0. +

+ +

For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types: +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+@name(".t")
+table t {
+  key = {
+    meta.port1: exact;  // meta.port1 has type PortId_String_t
+    meta.port2: exact;  // meta.port2 has type PortId_Bit32_t
+  }
+  actions = {
+    drop;
+  }
+}
+

This table would have the following representation in the generated P4Info +message: +

+
+
+
tables {
+  preamble {
+    id: 34728461
+    name: "t"
+    alias: "t"
+  }
+  match_fields {
+    id: 1
+    name: "meta.port1"
+    # notice that bitwidth is unset
+    match_type: EXACT
+    type_name {
+      name: "PortId_String_t"
+    }
+  }
+  match_fields {
+    id: 2
+    name: "meta.port2"
+    bitwidth: 32
+    match_type: EXACT
+    type_name {
+      name: "PortId_Bit32_t"
+    }
+  }
+  # ...
+}

9. P4 Entity Messages

+

P4Runtime covers P4 entities that are either part of the P416 language, or +defined as PSA externs. The sections below describe the messages for each +supported entity. +

9.1. TableEntry

+

The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action's +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification. +

+

P4Runtime supports inserting, modifying, deleting and reading table entries with +the TableEntry entity, which has the following fields: +

+
    +
  • +

    table_id, which identifies the table instance; the table_id is determined +by the P4Info message. +

  • +
  • +

    match, a repeated field of FieldMatch messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration. +

  • +
  • +

    action, which indicates which of the table's actions to execute in case of +match and with which argument values. +

  • +
  • +

    priority, a 32-bit integer used to order entries when the table's match key +includes an optional, ternary or range match. +

  • +
  • +

    controller_metadata, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +metadata field. +

  • +
  • +

    metadata, an arbitrary bytes value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. +

  • +
  • +

    meter_config, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    counter_data, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    is_default_action, a boolean flag which indicates whether the table entry is +the default entry for the table. See Default entry +section for more information. +

  • +
  • +

    idle_timeout_ns and time_since_last_hit, which are two fields used to +implement idle-timeout support for the table, if applicable. See +Idle-timeout section for more information. +

+ +

The priority field must be set to a non-zero value if the match key includes a +ternary match (i.e. in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an OPTIONAL, TERNARY or +RANGE match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches. +

+

The match and priority fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for MODIFY and DELETE updates. When deleting +an entry, these key fields (along with is_default_action) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a keyless +table (the table has an empty match key), the server must reject all attempts to +INSERT a match entry and return an INVALID_ARGUMENT error. +

+

The number of match entries that a table should support is indicated in P4Info +(size field of Table message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P416 specification for the +size property [30]. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +RESOURCE_EXHAUSTED when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached. +

9.1.1. Match Format

+

The bytes fields in the FieldMatch message follow the format described in +Bytestrings. +

+

For “don't care” matches, the P4Runtime client must omit the field's entire +FieldMatch entry when building the match repeated field of the TableEntry +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for “don't care” matches, which is needed +to ensure read-write symmetry. For PSA match types, +a “don't care” match for a specific match key field is defined as follows: +

+
    +
  • +

    For a TERNARY match, it is logically equivalent to a mask of zeros. +

  • +
  • +

    For a OPTIONAL match, it is logically equivalent to a wildcard match. +

  • +
  • +

    For an LPM match, it is logically equivalent to a prefix_len of zero. +

  • +
  • +

    For a RANGE match, it is logically equivalent to a range which includes all +possible values for the field. +

+ +

Note that there is no “don't care” value for EXACT matches and therefore exact +match fields can never be omitted from the TableEntry message. +

+

The following example shows a P4Runtime message that treats a TERNARY field +as a “don't care” match. The P4 program defines table t with TERNARY +and EXACT fields in its match key: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: ternary;
+    istd.ingress_port: exact;
+  }
+  actions = {
+    drop;
+  }
+}
+

In this P4Runtime request, the client omits the table's TERNARY field +from the repeated match field to indicate a “don't care” match. As shown +below, the match specifies only the EXACT field given by field_id: 2. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 33554439  # Table t's ID.
+    match {
+      # field_id 1 is not present to use the don't care ternary value.
+      field_id: 2
+      exact {
+        value: "\x20"
+      }
+    }
+    action {
+      # Action selection goes here.
+    }
+  }
+}
+

For every member of the TableEntry repeated match field, field_id must be +a valid id for the table, as per the P4Info, and one of the fields in +field_match_type must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an INVALID_ARGUMENT error code. +

+
    +
  • EXACT match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.exact().value()))
+
    +
  • LPM match + +
      +
    • The binary string encoding of the value (when present) must conform to the +Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • “Don't care” bits must be 0 in value. +
+ +
+
+
assert(BytestringValid(match.lpm().value()))
+
+pLen = match.lpm().prefix_len()
+assert(pLen > 0)
+
+trailing_zeros = countTrailingZeros(match.lpm().value())
+assert(trailing_zeros >= field_bits - pLen)
+
    +
  • TERNARY match + +
      +
    • The binary string encoding of the value (when present) and mask (when +present) must conform to the Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • Masked bits must be 0 in value. This constraint taken together +with the Bytestrings requirements means that the +value's binary string is never longer than the mask's binary string. +When the value's string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask. +
+ +
+
+
assert(BytestringValid(match.ternary().value()))
+assert(BytestringValid(match.ternary().mask()))
+assert(match.ternary().value().size() <= match.ternary().mask().size());
+
+value = parseInteger(match.ternary().value())
+mask = parseInteger(match.ternary().mask())
+
+assert(mask != 0)
+
+assert(value & mask == value)
+
    +
  • RANGE match + +
      +
    • The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the Bytestrings +requirements. +
    • +
    • Low bound must be less than or equal to the high bound. +
    • +
    • “Don't care” match must be omitted. +
+ +
+
+
assert(BytestringValid(match.range().low()))
+assert(BytestringValid(match.range().high()))
+
+low = parseInteger(match.range().low())
+high = parseInteger(match.range().high())
+
+assert(low <= high)
+
+assert(low != min_field_value || high != max_field_value)
+
    +
  • OPTIONAL match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.optional().value()))

9.1.2. Action Specification

+

The TableEntry action field must be set for every INSERT update but may be +left unset for MODIFY updates, in which case the action specification for the +table entry will not be modified (if a MODIFY update has an unset action field +and does not modify any direct resource attached to the table then the MODIFY +update is a no-op). Based on the implementation property value of the P4 table, +the oneof in the TableAction message will either be: +

+
    +
  • +

    an Action specification for direct tables (with no P4 implementation +property) +

  • +
  • +

    an action profile member id for indirect tables for which the implementation +property is an action profile with no selector. +

  • +
  • +

    an action profile member id or group id for indirect tables for which the +implementation property is an action profile with selector. +

  • +
  • +

    an ActionProfileActionSet specification for indirect tables for +which the implementation property is an action profile with +selector. This usage is described in One Shot Action Selector +Programming +

+ +

If the oneof does not match the table description in the P4Info (e.g. the +oneof is action_profile_member_id for a direct table), the server must +return an INVALID_ARGUMENT error code. +

+

The Action Protobuf message has the following fields: +

+
    +
  • +

    action_id, which identifies the action instance; the action_id is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an INVALID_ARGUMENT error +code. If the client uses a valid action_id for the table but does not +respect the action scope specified in P4Info (e.g. tries to set a TABLE_ONLY +action as the default action), the server must return a PERMISSION_DENIED +error code. +

  • +
  • +

    params: a repeated Protobuf field of action parameter values, each encoded +as a Param message. For each parameter, param_id must be valid for the +action (as per the P4Info) and value must follow the format described in +Bytestrings. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an INVALID_ARGUMENT error code +if a parameter id is missing, if an extra parameter id not found in the +P4Info was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +Bytestrings format. +

+ +

For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a NOT_FOUND error code. +

9.1.3. Default Entry

+

According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer or defaults to NoAction +(which is a no-op) otherwise and assuming it is not declared as const, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow INSERT and DELETE updates on the default entry and the +P4Runtime server must return an INVALID_ARGUMENT error code if the client +attempts one. +

+

The default entry is identified by setting the is_default_action boolean field +to true. When this flag is set to true, the repeated match field must be empty +and the priority field must be set to zero, otherwise the P4Runtime server +must return an INVALID_ARGUMENT error code. When performing a MODIFY update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its controller_metadata and metadata value as well as the +configurations for its direct resources will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a PERMISSION_DENIED +error code if the client attempts to modify it. +

+

Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to direct resources. +

+

In this P4Runtime release, we have decided to restrict the default entry for +indirect tables tables with an ActionProfile or ActionSelector +implementation property to a constant NoAction action entry, with the +hope that it would simplify the implementation of the P4Runtime service. +

9.1.4. Constant Tables

+

Constant tables are defined as tables whose match entries are immutable. They +are identified by the is_const_table flag in P4Info. +

+

The only write updates which are allowed for constant tables are MODIFY +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +PERMISSION_DENIED error. Just like any table entry MODIFY request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a PERMISSION_DENIED error. +

+

The contents of const tables can be queried by the client through a +ReadRequest. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: table_id, match, action, +is_default_action, and priority (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the priority field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P416 does not support assigning explicit priorities to static +entries. When a priority value is required (e.g. for tables including RANGE, +TERNARY or OPTIONAL matches), it is inferred based on the order in which +entries appear in the table declaration. +

9.1.5. Wildcard Reads

+

When performing a ReadRequest, the P4Runtime client can select all entries +from one or all tables on the target and use several of the TableEntry fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as priority and “unset” for message fields such as match. The following +fields may be used to select and filter results: +

+
    +
  • table_id: If default (0), entries from all tables including constant +tables will be selected and no other filter can be used. Otherwise only +the specified table will be considered. +
  • +
  • match: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned. +
  • +
  • action: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an action_id (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id. +
  • +
  • priority: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value. +
  • +
  • controller_metadata: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +controller_metadata value. +
  • +
  • metadata: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided metadata value. +
  • +
  • is_default_action: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered. +
+ +

For example, in order to read all entries from all tables from device 3, the +client can use the following ReadRequest message. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0
+    priority: 0
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following ReadRequest +message: +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+    priority: 11
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

The canonical representation of “don't care” matches, combined with the ability +to do a wildcard read on all table entries by leaving the match field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single “don't care” entry or to do a wildcard +read. If a table has no fields with match kind EXACT, it is possible via +P4Runtime to add an entry that is “don't care” for all fields (i.e. has an empty +match field) but is not the default entry (i.e. is_default_action is +false). When reading this entry from the table, there is no way to read only +that entry from the table, because it would require providing an unset match +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single LPM match: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: lpm;
+  }
+  actions = {
+    drop; fwd;
+  }
+}
+

The following WriteRequest message can be used to add 2 entries: +

+
+
+
device_id: 3
+entities {
+  table_entry { # don't care entry
+    table_id: 0x0212ab34
+    # ...
+  }
+  table entry {
+    table_id: 0x0212ab34
+    match {
+      field_id: 1
+      lpm {
+        value: 0x0a000000
+        prefix_len: 8
+      }
+    # ...
+  }
+}
+

The first entry is a “don't care” entry, while the second one matches all +10.0.0.0/8 addresses. The second entry has higher priority than the first one. +

+

The following ReadRequest message will return all entries in the table, not +just the “don't care” entry. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+  }
+}
+

This issue also exists for tables with TERNARY, RANGE, and OPTIONAL +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the “don't care” entry will be returned to the +client. If the client uses distinct priority values for all entries which is +strongly recommended to achieve deterministic behavior , +then there is no ambiguity because the wildcard read will actually return a +single entry (the “don't care” entry) as long as the priority field is set to +the correct value. +

9.1.6. Direct Resources

+

In addition to the DirectCounterEntry and DirectMeterEntry entities, +P4Runtime support reading and writing direct resources as part of the +TableEntry message. This is convenient for two reasons: +

+
    +
  • +

    A table entry and its direct resources can be read with a single entity when +doing a Read RPC call +

  • +
  • +

    The initial configuration for an entry's direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can “hit” the table entry without +executing the appropriate meter entry. +

+ +

Once the table entry has been inserted, the P4Runtime client is free to use the +DirectCounterEntry and DirectMeterEntry messages for read and write +operations on DirectCounter and DirectMeter instances. For example, it is +usually more convenient as well as more efficient to use DirectCounterEntry to +query a counter entry value rather than use TableEntry, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry. +

+

The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does not need to be “executed” in +every action bound to the table. It is an error to provide a direct resource +configuration in a TableEntry message when programming an action that does not +execute the direct resource, and the server must return an INVALID_ARGUMENT +error code. +

+

We leverage Protobuf's ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the TableEntry message. The list below describes how +the server must handle the meter_config and counter_data fields for read and +write requests, based on whether the fields are set or not. We do not cover +error cases in the list, i.e. we assume that we are dealing with a table which +is assigned a direct counter / a direct meter, and that the action being used +for the table entry “executes” the direct resource appropriately. +

+
    +
  • +

    meter_config field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets). +
      • +
      • if set: The initial configuration for the meter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The meter entry's configuration is reset to the default +(meter returns GREEN for all packets). +
      • +
      • if set: The value provided by the client is used to re-configure +the meter entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the meter entry's +configuration (meter_config is unset in the response). +
      • +
      • if set: If the meter entry's configuration is the default +configuration, meter_config is unset in the response. Otherwise, the +response includes the meter entry's configuration that was written by +the client earlier. This respects the “read-write symmetry” principle. +
    +
  • +
  • +

    counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for the counter entry is the default +(0). +
      • +
      • if set: The initial value for the counter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The counter entry's value is not changed. +
      • +
      • if set: The value provided by the client is written to the counter +entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the counter entry's value +(counter_data is unset in the response). +
      • +
      • if set: The response includes the counter entry's value read from +the target. +
    +
+ +

In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +meter_config field unset when inserting or modifying a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the TableEntry message +(i.e. the meter_config field must be set to match the existing configuration). +

9.1.7. Idle-timeout

+

P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not “hit” (i.e. not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification using the +IdleTimeoutNotification message to the master client, which can then take +action, such as remove the idle table entry. +

+

Two fields of the TableEntry Protobuf message are used to implement idle +timeout: +

+
    +
  • +

    idle_timeout_ns: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, i.e. no +IdleTimeoutNotification message will ever be generated for this entry. When +a client reads a TableEntry, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry. +

  • +
  • +

    time_since_last_hit: a Protobuf message with a single field (elapsed_ns) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The time_since_last_hit field must be unset for a +TableEntry write. When reading a table entry, time_since_last_hit must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0. +

+ +

These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an INVALID_ARGUMENT error code if at least one of these +conditions is met: +

+
    +
  • idle_timeout_ns is set to a non-zero value, or +
  • +
  • time_since_last_hit is set +
+ +

The target should do its best to approximate the idle_timeout_ns value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the TableEntry write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for time_since_last_hit. +

+

P4Runtime does not support idle timeout for default entries. When the +is_default_action flag is set in a TableEntry message, idle_timeout_ns +must be set to 0 (default) and time_since_last_hit must be unset. If the +server receives a TableEntry message which violates this, it must return an +INVALID_ARGUMENT error. +

+

For more information about idle timeout, in particular regarding +IdleTimeoutNotification, please refer to the Table idle timeout +notifications section. +

9.2. ActionProfileMember & ActionProfileGroup

+

P4Runtime defines an API for programming a PSA ActionProfile extern using +ActionProfileMember messages. A PSA ActionSelector extern can be programmed +using both ActionProfileMember and ActionProfileGroup messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table t for L3 routing, implemented with an action +selector as. +

+
+
+
ActionSelector(HashAlgorithm.crc32,
+               /*size = */ 32w1024,
+               /*output_width = */ 32w10) as;
+
+action set_nhop(PortId_t p, EthAddr smac, EthAddr dmac) {
+  istd.egress_port = p;
+  hdr.ethernet.smac = smac;
+  hdr.ethernet.dmac = dmac;
+}
+
+table t {
+  key = {
+    hdr.ipv4.dip: lpm;  // LPM on destination IP address
+  }
+  actions = {
+    set_nhop;
+  }
+  implementation = as;
+}
+

When programming table t in the example above, a P4Runtime client should +specify the TableAction in the TableEntry to be a reference to either an +action profile member or group. The reference is a non-zero uint32 identifier +that uniquely identifies a member or group programmed in the action selector +as. +

+

If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata. +

+

If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata. +

9.2.1. Action Profile Member Programming

+

Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a uint32 identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the actions +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the actions attributes of the +tables must have an identical list of P4 actions. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector. +

+

An ActionProfileMember entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info. +

  • +
  • +

    member_id is the non-zero uint32 identifier of the action profile member +entry being updated. +

  • +
  • +

    action is the specification of the P4 action instance bound to the action +profile member entry. +

+ +

An action profile member may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an ALREADY_EXISTS error +code. The action specification must be provided, or the server must return +INVALID_ARGUMENT. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return RESOURCE_EXHAUSTED. +
  • +
  • MODIFY: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return NOT_FOUND, +and the action specification must be provided, or the server must return +INVALID_ARGUMENT. +
  • +
  • DELETE: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a NOT_FOUND error code. The member +must not be part of an action profile group, or the server must return +FAILED_PRECONDITION. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return FAILED_PRECONDITION. action_profile_id and member_id are the only +fields that are considered when performing a DELETE and every other field +will be ignored. +
+ +

When reading, an ActionProfileMember message with action_profile_id and +member_id equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with action_profile_id equal to the id of +an existing ActionProfile or ActionSelector object, and a member_id equal to +0, will read all members of that specified object. +

9.2.2. Action Profile Group Programming

+

Action profile groups are entries in an ActionSelector and are referenced by a +uint32 identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type. +

+

Within a single ActionSelector object, the uint32 values used to identify its +members are in a separate ‘scope’ from the uint32 values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5. +

+

There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it. +

+

An ActionProfileGroup entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionSelector +extern instance, as defined in P4Info. +

  • +
  • +

    group_id is the non-zero uint32 identifier of the action profile group +entry being updated. +

  • +
  • +

    members is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields: +

    +
      +
    • member_id for looking up the member table in the selector. +
    • +
    • weight specifying the probability of the member's selection at +runtime. 0 is not a valid weight value and the server must return +INVALID_ARGUMENT if the client attempts to use it. +
    • +
    • watch is the controller-defined 32-bit port number that the member's +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +9.2.4 for notes on the behavior if all members in +a group are excluded for this reason. If watch is 0, then the member is +always included in the selection, regardless of the status of any port of +the device. The value must be 0 or the SDN port number of an existing +port on the device, otherwise the server must return INVALID_ARGUMENT. +
    +
  • +
  • +

    max_size is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +MODIFY update. See the subsection below for the rules on setting +max_size. +

+ +

An action profile group may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new group entry bound to a set of existing action profile +members. The group_id must be different from ids of already programmed +groups for that selector, or the server must return an ALREADY_EXISTS error +code. All members specified in the group must exist in the selector, or the +server must return NOT_FOUND. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target. +
  • +
  • MODIFY: Modify the member set specification of an existing group entry. An +entry with the group_id must exist, or the server must return +NOT_FOUND. All members specified in the group entry must exist in the +selector, or the server must return NOT_FOUND. The value of max_size must +be identical to the value used when inserting the group, otherwise an +INVALID_ARGUMENT error is returned. +
  • +
  • DELETE: Delete the group entry and deallocate the group_id. The group must +not be referenced in the table action of any table entry, or the server must +return a FAILED_PRECONDITION error code. If the group_id is invalid, the +server must return NOT_FOUND. action_profile_id and group_id are the +only fields that are considered when performing a DELETE and every other +field will be ignored. +
+ +

When setting the group membership with INSERT or MODIFY, the members +repeated field must not include duplicates, i.e. members with the same +member_id. The weight field is used instead to logically “repeat” the member +inside the group. +

+

It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation “stores” the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made. +

+

When reading, an ActionProfileGroup message with action_profile_id and +group_id equal to 0 will read all groups of all ActionSelector objects. A +message with action_profile_id equal to the id of an existing ActionSelector +object, and a group_id equal to 0, will read all groups of that one specified +object. +

9.2.2.1. Rules on Setting max_size
+

The valid values for max_size depend on the static max_group_size included +in the P4Info message: +

+
    +
  • +

    If max_group_size is greater than 0, then max_size must be greater than 0, +and less than or equal to max_group_size. We assume that the target can +support selector groups for which the sum of all member weights is up to +max_group_size, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If max_size is greater than max_group_size, the server +must return INVALID_ARGUMENT. +

  • +
  • +

    Otherwise (i.e. if max_group_size is 0), the P4Runtime client can set +max_size to any value greater than or equal to 0. +

    +
      +
    • +

      A max_size of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (INSERT or MODIFY), the target must return a +RESOURCE_EXHAUSTED error. +

    • +
    • +

      If max_size is greater than 0 and the value is not supported by the +target, the server must return a RESOURCE_EXHAUSTED error at +group-creation time. +

    +
+

9.2.3. One Shot Action Selector Programming

+

P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids. +

+

One shots are programmed by choosing the ActionProfileActionSet message as the +TableAction. The ActionProfileActionSet message consists of a set of +ActionProfileAction messages, which in turn have the following fields: +

+
    +
  • +

    action is one of the actions specified by the table that is being +programmed. +

  • +
  • +

    weight specifying the probability of the action's selection at runtime. 0 is +not a valid weight value and the server must return INVALID_ARGUMENT if +the client attempts to use it. The sum of all weights across all +ActionProfileAction messages for that ActionProfileActionSet message must +not exceed the max_group_size specificed in the P4Info (if greater than 0), +or the server must return INVALID_ARGUMENT. +

  • +
  • +

    watch is the controller-defined 32-bit port number that the action's +liveness depends on. At runtime, the action must be excluded from selection if +the watch port is down. See Section +9.2.2 for more details on the watch field, +which also apply for one shot action selector programming. +

+ +

Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics. +

+

To preserve read-write symmetry, an implementation must answer ReadRequests +with the original one shot messages. It may not return a desugared version of +the one shot message. +

+

For example, consider the action selector table defined +here. This table could be programmed +with the following one shot update: +

+
+
+
table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action {
+    action_profile_action_set {
+      action_profile_actions {
+        action { /* set nexthop 1 */ }
+        weight: 1
+        watch: 1
+      }
+      action_profile_actions {
+        action { /* set nexthop 2 */ }
+        weight: 2
+        watch: 2
+      }
+      action_profile_actions {
+        action { /* set nexthop 3 */ }
+        weight: 3
+        watch: 3
+      }
+    }
+  }
+}
+

Which would be equivalent to the following updates, where GROUP_ID, +MEMBER_ID_1, MEMBER_ID_2, and MEMBER_ID_3 are unused ids: +

+
+
+
action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_1
+  action { /* set nexthop 1 */ }
+}
+action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_2
+  action { /* set nexthop 2 */ }
+}
+action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_3
+  action {  /* set nexthop 3 */ }
+}
+action_profile_group {
+  action_profile_id: 0x11ab12cd
+  group_id: GROUP_ID
+  members {
+    member_id: MEMBER_ID_1
+    weight: 1
+    watch: 1
+  }
+  members {
+    member_id: MEMBER_ID_2
+    weight: 2
+    watch: 2
+  }
+  members {
+    member_id: MEMBER_ID_3
+    weight: 3
+    watch: 3
+  }
+}
+table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action { action_profile_group_id: GROUP_ID }
+}
+

Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure correct ordering between the dependent +updates. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct WriteRequest batches are required. +

+

It is possible to include several ActionProfileAction messages with the same +exact action specification in one ActionProfileActionSet message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the weight field. Note that to preserve read-write symmetry, the server +must not coalesce multiple ActionProfileAction messages with the same action +specification into one. +

+

All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with ActionProfileMember and +ActionProfileGroup messages. Programming some entries with one shots, and +other entries with ActionProfileMember and ActionProfileGroup messages is +not allowed, and the server must return the error code INVALID_ARGUMENT in +that case. +

+

A P4Runtime server must support the one shot style of programming tables with +an action selector implementation. Support for the ActionProfileMember and +ActionProfileGroup style is optional. If ActionProfileMember and +ActionProfileGroup are not supported by a server, it must return an +UNIMPLEMENTED error for every ActionProfileMember or ActionProfileGroup +message that it receives. +

9.2.4. Constraints on action selector programming

+

The PSA specification states that the following features are optional in +action selector implementations [22]: +

+
    +
  1. Support for non-empty groups where in the same group, different members are +bound to different actions. +
  2. +
  3. Predictable data plane behavior when a matched table entry points to an empty +group. +
+ +

For 1., if a client tries to INSERT or MODIFY a group with members bound to +different actions, the server should return UNIMPLEMENTED if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return UNIMPLEMENTED (modifying the action parameter values must be +supported, however). +

+

PSA 1.1 introduces the psa_empty_group_action table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. psa_empty_group_action is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of psa_empty_group_action at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +NoAction. Even when psa_empty_group_action is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of psa_empty_group_action mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming. +

+

The PSA specification includes a discussion on how to implement +psa_empty_group_action in software in the P4Runtime server +[25]. +

+

If a P4Runtime implementation does support psa_empty_group_action, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down. +

+

If a P4Runtime implementation does not support psa_empty_group_action, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down. +

9.3. CounterEntry & DirectCounterEntry

+

PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The CounterData +P4Runtime message can be used for all three types of PSA counters PACKETS, +BYTES and PACKETS_AND_BYTES and consists of the following fields: +

+
    +
  • byte_count is an int64, corresponding to the number of octets. +
  • +
  • packet_count is an int64, corresponding to the number of packets. +
+ +
+
+
message CounterData {
+  int64 byte_count = 1;
+  int64 packet_count = 2;
+}
+

P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of byte_count and packet_count fields, which +is equivalent to specifying the counter type PACKETS_AND_BYTES. Counters may +be defined as direct or indirect (indexed) instances. +

9.3.1. DirectCounterEntry

+

A direct counter is a direct resource associated with a TableEntry (see +Direct Resources). The counter_data field of the +TableEntry message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +DirectCounterEntry message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed. +

+
+
+
message DirectCounterEntry {
+  TableEntry table_entry = 1;
+  CounterData data = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectCounterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match TableEntry.match of the table entry +to which this direct counter entry is associated. If a matching TableEntry +is not found, the server returns the error code NOT_FOUND. +

  • +
  • +

    data is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified. +

+ +

Specifying DirectCounterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read the contents of a +DirectCounter: +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the counter value in the counter_data field of the TableEntry message +(see Direct resources). +

  • +
  • +

    Explicitly request the counter value by including the DirectCounterEntry in +the ReadRequest. The table_entry.match field must match the TableEntry +whose counter is being read. If no such entry is found, the server returns the +error code NOT_FOUND. +

+

9.3.2. CounterEntry

+

An indirect or indexed counter is not associated with a specific TableEntry +and may be updated independently of any action. It may be read or written using +the P4Runtime CounterEntry message whose fields are defined as follows: +

+
    +
  • +

    counter_id is a uint32, the unique identifier for the counter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +the counter array. +

  • +
  • +

    data is a Protobuf message of type CounterData, which represents the +counter value. +

+ +
+
+
message CounterEntry {
+  uint32 counter_id = 1;
+  Index index = 2;
+  CounterData data = 3;
+}
+

The CounterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the counter entries in the +array have default value 0. +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect counter instance whose unique id is counter_id +and array index is specified by index. The counter value is set to the value +specified by the client in the data field. Note that the counter value is +not modified if this Protobuf field is not set. If index is omitted all +counter values in the array will be set to the value provided by the +client. The server must return INVALID_ARGUMENT for a negative index value +and OUT_OF_RANGE if the index value exceeds the size of the counter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a ReadRequest by including a CounterEntry +entity for each of the instances, specifying the counter_id and +index. Wildcard reads are also supported as follows. +

+
    +
  • +

    If the counter_id field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id counter_id. +

+

9.4. MeterEntry & DirectMeterEntry

+

Meters are an advanced mechanism for keeping statistics, involving stateful +“marking” and usually “throttling” of packets based on configured rates of +traffic. The PSA metering function is based on the Two Rate Three Color Marker +(trTCM) defined in RFC 2698 [2]. The trTCM meters an arbitrary packet +stream using two configured rates the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes and +“marks” its packets as GREEN, YELLOW or RED based on the observed rate. +

+

A meter may be configured as a direct or indirect instance, similar to a +counter. The MeterConfig P4Runtime message represents meter configuration. +

+
+
+
message MeterConfig {
+  int64 cir = 1;  // Committed Information Rate
+  int64 cburst = 2;  // Committed Burst Size
+  int64 pir = 3;  // Peak Information Rate
+  int64 pburst = 4;  // Peak Burst Size
+}

9.4.1. DirectMeterEntry

+

A direct meter is a direct resource associated with a TableEntry (see Direct +resources). The meter_config field of the TableEntry +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +DirectMeterEntry message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed. +

+
+
+
message DirectMeterEntry {
+  TableEntry table_entry = 1;
+  MeterConfig config = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectMeterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match the match key of the TableEntry +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching TableEntry is not found, +the server returns the error code NOT_FOUND. +

  • +
  • +

    config is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets). +

+ +

Specifying DirectMeterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read a DirectMeter config. +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the meter config in the meter_config field of the TableEntry +message (see Direct resources). +

  • +
  • +

    Explicitly request the meter configuration by including the DirectMeterEntry +in the ReadRequest. The table_entry.match field must match the +TableEntry whose meter config is being read. If no such entry is found, the +server returns the error code NOT_FOUND. +

+

9.4.2. MeterEntry

+

An indirect or indexed meter is not associated with a specific TableEntry and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime MeterEntry message whose fields are defined as +follows: +

+
    +
  • +

    meter_id is a uint32, the unique identifier for the meter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +a meter array. +

  • +
  • +

    config is a Protobuf message of type MeterConfig, which represents the +meter configuration. +

+ +
+
+
message MeterEntry {
+  uint32 meter_id = 1;
+  Index index = 2;
+  MeterConfig config = 3;
+}
+

The MeterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the meter entries in the +array have a default configuration (GREEN for all packets). +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect meter instance whose unique id is meter_id and +array index is specified by index. The meter is reconfigured using the +config field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the index field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if config is unset). The server must return INVALID_ARGUMENT for a +negative index value and OUT_OF_RANGE if the index value exceeds the size of +the meter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a ReadRequest by including a MeterEntry entity for each +of the instances, specifying the meter_id and index. Wildcard reads are also +supported as follows: +

+
    +
  • +

    If the meter_id field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id meter_id. +

+

9.5. PacketReplicationEngineEntry

+

The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets. +

9.5.1. MulticastGroupEntry

+

Multicasting is achieved in PSA programs by setting the multicast_group +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the MulticastGroupEntry API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example. +

+
+
+
control arp_multicast(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ethernet.isValid() &&
+        hdr.ethernet.eth_type == ETH_TYPE_ARP) {
+      smeta.multicast_group = (MulticastGroup_t) 1;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    multicast_group_entry {
+      multicast_group_id: 1
+      replicas { egress_port: 5 instance: 1 }
+      replicas { egress_port: 12 instance: 2 }
+      replicas { egress_port: 18 instance: 3 }
+      replicas { egress_port: 24 instance: 4 }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +PSA Metadata Translation section. +

+

The egress packets may be distinguished for further processing in the egress +using the instance metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 multicast_group metadata is set to a value that is not +programmed in the PRE, then the packet is dropped. +

+

A multicast group may be inserted, modified or deleted as per the following +semantics. +

+
    +
  • INSERT: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The multicast_group_id field is a uint32 and must be greater +than 0 (see explanation below), or the +P4Runtime server must return an INVALID_ARGUMENT error. The replica +instance ID is also a uint32, and its value may not exceed the maximum +allowed by the target for the EgressInstance_t type (0 is allowed), or the +server must return an INVALID_ARGUMENT error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of both egress_port and instance, or the server +must return INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify the set of replicas for a given multicast group entry, +indexed by the given multicast_group_id. Same restrictions as INSERT apply +here. +
  • +
  • DELETE: Delete the multicast group indexed by the given +multicast_group_id. The replicas need not be provided for this +operation. Any packets with their multicast_group metadata in the data plane +set to the deleted multicast_group_id will be dropped. +
+ +

When reading a multicast group, only multicast_group_id is considered. All +other fields in MulticastGroupEntry are ignored. To perform a wildcard +Read on all configured multicast group entries, the multicast_group_id field +must be set to 0, its default value. +

9.5.1.1. Valid Values for multicast_group_id
+

The PSA specification states that the valid data plane values for multicast +group ids (MulticastGroup_t) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target [24]. This means that, in the absence of +translation, the client must set the multicast_group_id field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special wildcard value which is used to read all the multicast groups +configured in the target, the multicast_group_id field must never be set to 0 +when performing a Write RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value. +

9.5.2. CloneSessionEntry

+

PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +clone_session_id identifier and a boolean flag clone in the packet +metadata. The clone_session_id serves as a handle to the clone attributes, +namely a set replicas of (egress port, instance) pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +CloneSessionEntry API. +

+

The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the clone_low_ttl control block is applied in the ingress +pipeline to create an ingress-to-egress clone. +

+
+
+
control clone_low_ttl(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ipv4.isValid() &&
+        hdr.ipv4.ttl <= LOW_TTL_THRESHOLD) {
+      smeta.clone_session_id = 10w100;
+      smeta.clone = true;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    clone_session_entry {
+      session_id: 100
+      replicas { egress_port: 0xfffffffd instance: 1 } # to CPU
+      class_of_service: 2
+      packet_length_bytes: 4096
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type CloneSessionId_t [24]). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes. +

+

The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port 0xfffffffd; see +Translation of Port Numbers). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port. +

+

If the clone_session_id data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created. +

+

A clone session may be inserted, modified or deleted as per the following +semantics: +

+
    +
  • INSERT: Add a new clone session entry bound to a set of egress ports and +replica IDs. The session_id is a uint32 and must be greater than 0 (see +explanation below), or the P4Runtime +server must return an INVALID_ARGUMENT error. The replica instance ID is +also a uint32, and its value may not exceed the maximum allowed by the +target for the EgressInstance_t type (0 is allowed), or the server must also +return an INVALID_ARGUMENT error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (class_of_service field). This value must be a valid +value for the PSA ClassOfService_t type, which supports runtime translation +by default [24], or the server must return +INVALID_ARGUMENT. See PSA Metadata +Translation for more information. The +packet_length_bytes field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +packet_length_bytes field is 0 (default), no truncation on the clone will be +performed. +
  • +
  • MODIFY: Modify the attributes of a given clone session entry, indexed by the +given clone_session_id. Same restrictions as INSERT apply here. +
  • +
  • DELETE: Delete the clone session indexed by the given +clone_session_id. Other fields need not be provided for this operation. Any +packet with their clone_session_id metadata in the data plane set to the +deleted session_id will no longer be cloned. +
+ +

When reading a clone session, only session_id is considered. All other fields +in CloneSessionEntry are ignored. To perform a wildcard Read on all +configured clone session entries, the session_id field must be set to 0, its +default value. The session_id field can never be equal to 0 in a Write +RPC. If it does, the server must return an INVALID_ARGUMENT error. +

9.5.2.1. Valid Values for session_id
+

The PSA specification states that the valid data plane values for clone +session ids (CloneSessionId_t) range from 0 to the maximum value supported by +the target [24]. Note that unlike for multicast group +ids, 0 is a valid data plane value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special wildcard value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a session_id +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is not enabled, we effectively +“lose” one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (e.g. because the target supports a very +limited number of clone sessions), one can enable translation on +CloneSessionId_t and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id. +

9.6. ValueSetEntry

+

Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the parse_trill_types state. +

+
+
+
state parse_l2 {
+  @id(1) value_set<ETH_TYPE_BITWIDTH>(MAX_TRILL_TYPES) trill_types;
+  extract(hdr.ethernet);
+  select (hdr.ethernet.eth_type) {
+    ETH_TYPE_IPV4: parse_ipv4;
+    ETH_TYPE_IPV6: parse_ipv6;
+    trill_types:   parse_trill_types;
+    _:             reject;
+  }
+}
+

The corresponding entry in the P4Info for this Value Set is: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "trill_types"
+  }
+  match {
+    id: 1
+    bitwidth: <ETH_TYPE_BITWIDTH>
+    match_type: EXACT
+  }
+  size: <MAX_TRILL_TYPES>
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0x22f3 }
+      }
+      match {
+        field_id: 1
+        exact { value: 0x893b }
+      }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the parse_trill_types state. +

+

A ValueSetEntry entity update message has the following fields: +

+
    +
  • +

    value_set_id is the uint32 identifier of the Value Set instance, as +defined in P4Info. +

  • +
  • +

    members is a repeated field of type ValueSetMember. When “selecting” +against a Value Set, every member will be considered and if at least one +“matches”, the corresponding parser transition will be taken. Each +ValueSetMember contains a repeated field of FieldMatch messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a ValueSetMember if and only if +it matches all its FieldMatch messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. FieldMatch messages in a ValueSetEntry follow +the same rules as in a TableEntry. +

+ +

A ValueSetEntry may only be modified. If the update type is INSERT or +DELETE, the server must return an INVALID_ARGUMENT error. If the update type +is MODIFY, the server writes the members given in the repeated field to the +Value Set entry indexed by the given value_set_id. The maximum number of +matches must not exceed the maximum size given by the size field in P4Info of +the Value Set, otherwise the server must return a RESOURCE_EXHAUSTED error. To +empty a Value Set (i.e. restore it to its initial state), the P4Runtime client +can perform a MODIFY update with an empty members repeated field. +

+

To facilitate read-write symmetry, the server must +return an ALREADY_EXISTS error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set. +

+

See Appendix A.3 for a more complex Value Set example. +

9.7. RegisterEntry

+

The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The RegisterEntry P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations. +

+

RegisterEntry has the following fields: +

+
    +
  • +

    register_id, which identifies the PSA Register extern instance which is +being accessed by the client; the register_id is specified by the P4Info +message. +

  • +
  • +

    index, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the RegisterEntry message +used for the request. When an index is provided , the server must validate +its value, and return INVALID_ARGUMENT for a negative index or +OUT_OF_RANGE if the index exceeds the size of the register array. +

  • +
  • +

    data: the data to be written to the array (if RegisterEntry is part of a +WriteRequest message) or the data read from the array (if RegisterEntry is +part of a ReadResponse message). The data field is a P4Data message and +must match the format described by the type_spec field of the corresponding +Register entry in the P4Info, or the server must return an INVALID_ARGUMENT +error. +

+

9.8. DigestEntry

+

A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly. +

+

The DigestEntry P4Runtime entity is used to configure how the device must +generate digest messages. The DigestEntry Protobuf message is not used to +carry digest data, which is done on the StreamChannel bidirectional stream +using the DigestList (digest data sent by the target to the client) and +DigestListAck (digest data acknowledgments sent by the client to the target) +Protobuf messages. +

+

In this section, we refer to the data learned by a single data plane call to +Digest<T>::pack as a “digest message” and we use “digest list” to designate +the list of digest messages bundled by the P4Runtime service in a single +DigestList stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are “duplicate” if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are “distinct” +if they are not duplicate. +

+

DigestEntry has the following fields: +

+
    +
  • +

    digest_id, which identifies the PSA Digest extern instance which emitted the +data; the digest_id is determined by the P4Info message. +

  • +
  • +

    config, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +digest_id; these parameters are: +

    +
      +
    • max_timeout_ns: the maximum server buffering delay in nanoseconds for an +outstanding digest message. +
    • +
    • max_list_size: the maximum digest list size in number of digest +messages sent by the server to the client as a single DigestList +Protobuf message. +
    • +
    • ack_timeout_ns: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data. +
    +
+ +

Here is the significance of the different Update types for DigestEntry: +

+
    +
  • INSERT: Enable server generation of DigestList messages for given digest +instance and use provided configuration parameters. +
  • +
  • MODIFY: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance. +
  • +
  • DELETE: Disable server generation of DigestList messages for given digest +instance. +
+ +

A server should buffer digest messages until either: +

+
    +
  • max_timeout_ns time has passed since the first digest message was added to +the empty buffer, or +
  • +
  • max_list_size distinct digest messages have been received from the +data plane and added to the buffer +
+ +

At which point the server should, with best effort, generate a DigestList +stream message with the buffer contents and send it to the master client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software. +

+

To avoid sending duplicate digest messages across different DigestList +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the master client indicates that it has received the +digest list and acted on it. The server must keep a “cache” containing the set +of all digest messages that have been sent, but not acknowledged yet by the +master client, up-to ack_timeout_ns in the past. The server must delete all +cache entries for a given digest list when they are at least ack_timeout_ns +old or when a matching DigestListAck message (i.e. with the same digest_id +and list_id fields as the DigestList message) is received. +

+

The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged DigestList messages. +

+

When max_timeout_ns is set to 0 and / or max_list_size is set to 1, the +server should, with best effort, generate a DigestList message for every +digest message generated by the data plane which is not already in the cache. If +ack_timeout_ns is set to 0, the cache must always be an empty set. If +max_list_size is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +max_timeout_ns configuration parameter. +

+

The P4Runtime server may empty the digest message cache in case of a client +mastership change. +

+

Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server: +

+
+
+
DigestStream stream;
+DigestCache cache;
+DigestBuffer buffers;
+
+// sends digest list when it is ready
+send_buffer(Id digest_id) {
+  buffer = buffers[digest_id];
+  stream.write(DigestList(buffer));
+  cache.merge(buffer);  // updates cache with new digest list
+  buffer.clear();
+}
+
+// callback which handles data plane digest messages from device
+handle_dataplane_digest(Digest msg) {
+  digest_id = msg.digest_id();
+  buffer = buffers[digest_id];
+  if (msg in cache OR msg in buffer) return;
+  buffer.enqueue(msg);
+  if (buffer.length() < max_list_size(digest_id)) return;
+  send_buffer(digest_id);
+}
+
+// callback which handles ack messages received on the stream
+handle_stream_ack(DigestListAck ack) {
+  // clear all cache entries matching the tuple (digest_id, list_id)
+  cache.erase( (ack.digest_id(), ack.list_id() )
+}
+
+// loop to enforce timeouts
+while (true) {
+  now = now();
+  // check for buffers that need to be sent
+  for ((digest_id, buffer) in buffers) {
+    if (now - buffer.first_enq_time() >= max_timeout_ns(digest_id))
+      send_buffer(buffer_id);
+  }
+  // check for expired entries in cache
+  for ((digest_id, list_id, sent_time) in cache) {
+    if (now - sent_time >= ack_timeout_ns(digest_id))
+      cache.erase( (digest_id, list_id) );
+  }
+  sleep(X);
+}

9.9. ExternEntry

+

This is used to support a P4 extern entity that is not part of PSA. It is +defined as: +

+
+
+
message ExternEntry {
+  uint32 extern_type_id = 1;
+  uint32 extern_id = 2;
+  google.protobuf.Any entry = 3;
+}
+

Each ExternEntry entity maps to an Extern message in the +P4Info and an ExternInstance message within that +message. The extern_type_id field must be equal to the one in +ExternEntry. The extern_id field must be equal to the ID included in the +preamble of the corresponding ExternInstance message. +

+

entry itself is embedded as an Any Protobuf message [31] to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on Extending P4Runtime for non-PSA +Architectures for more information. +

10. Error Reporting Messages

+

P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case. +

+

gRPC uses grpc::Status [32] to represent the status returned by an +RPC. It has 3 attributes: +

+
+
+
StatusCode code_;
+grpc::string error_message_;
+grpc::string binary_error_details_;
+

The code_ represents a canonical error [34] and describes the +overall RPC status. The error_message_ is a developer-facing error message, +which should be in English. The binary_error_details_ carries a serialized +google.rpc.Status message [28] message, which has 3 fields: +

+
+
+
int32 code = 1;  // see code.proto
+string message = 2;
+repeated google.protobuf.Any details = 3;
+

The code and message fields must be the same as code_ and error_message_ +fields from grpc::Status above. The details field is a list that consists of +p4.Error messages that carry error details for individual elements inside +batch-request RPCs (e.g. Write and Read). p4.Error includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices [34]. +

+

Figure 7 illustrates how these messages fit together. +

+
+

error-report +

+
+ +
Figure 7. P4Runtime Error Report Message Format
+

gRPC provides utility functions ExtractErrorDetails() and SetErrorDetails() +[33] to easily convert between grpc::Status and +google.rpc.Status. +

+

Please see sections on individual P4Runtime RPCs for details on how +grpc::Status is populated for reporting errors. +

+

Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on Stream Error +Reporting for more information. +

11. Atomicity of Individual Write and Read Operations

+

Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane apply +operation, and every single Write operation on a table that inserts, deletes, +or modifies one table entry, the apply operation should behave as if that +Write operation has not yet occurred, or as if the Write operation is +complete. The P4 program should never behave as if the Write operation is +partially complete. These guarantees also apply to extern instances: Read and +Write operations on extern entities must execute atomically relative to extern +data plane methods. +

+

The atomicity guarantees provided by P4Runtime for individual Read and Write +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification [23]. +

+

The P416 language introduces an @atomic annotation [14], to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the @atomic annotation for Write +operations, as well as non-wildcard Read operations, +relative to data plane execution. Consider the following P4 example written for +PSA: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024) r1;
+
+  apply {
+    // ...
+    @atomic {
+        Value_t v = r1.read((Index_t)1);
+        v = v + 1;
+        r1.write((Index_t)1, v);
+    }
+  }
+}
+

If a P4Runtime server is processing messages which write to Register r1 at +index 1, these writes must not happen between the data plane read and +write. +

+

Now let's consider the following example: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024, (Value_t)0 /* initial value */) r1;
+
+  apply {
+    @atomic {
+        r1.write((Index_t)1, (Value_t)100);
+        r1.write((Index_t)2, (Value_t)100);
+    }
+    @atomic {
+        r1.write((Index_t)1, (Value_t)200);
+        r1.write((Index_t)2, (Value_t)200);
+    }
+  }
+}
+

If a P4Runtime client issues a wildcard Read on Register r1, there is no +guarantee that r1[1] == r1[2] in the response, as the read for r1[1] may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for r1[2] may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read r1[1] and r1[2] separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +ReadRequest message) of individual read requests. Similar to a batch +ReadRequest, a wildcard read of a register can execute the reads of the +register array elements (r1[1], r1[2], ) in an arbitrary order relative +to each other. +

+

If the @atomic annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program. +

12. Write RPC

+

The Write RPC updates one or more P4 entities on the target. The request is +defined as follows: +

+
+
+
message WriteRequest {
+  uint64 device_id = 1;
+  uint64 role_id = 2;
+  Uint128 election_id = 3;
+  repeated Update updates = 4;
+  enum Atomicity {
+    CONTINUE_ON_ERROR = 0;
+    ROLLBACK_ON_ERROR = 1;
+    DATAPLANE_ATOMIC = 2;
+  }
+  Atomicity atomicity = 5;
+}
+

The device_id uniquely identifies the target P4 device. The role_id and +election_id define the client role and election-id as described in the +Master-Slave Arbitration and Controller +Replication +section. The server is expected to perform the following checks (in this order) +before processing the updates list: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role_id does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the master for (device_id, role_id) according to the +election_id value, the server must return a PERMISSION_DENIED error. +

  4. +
  5. +

    If the Write is attempted before a ForwardingPipelineConfig has been set, +the server must return a FAILED_PRECONDITION error. +

+ +

The updates field is a list of P4 entity updates to be applied. Each update is +defined as: +

+
+
+
message Update {
+  enum Type {
+    UNSPECIFIED = 0;
+    INSERT = 1;
+    MODIFY = 2;
+    DELETE = 3;
+  }
+  Type type = 1;
+  Entity entity = 2;
+}
+

This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a logical table (e.g. +CounterEntry) or an actual table (e.g. TableEntry) in the P4 data +plane. Each entity in the container is uniquely identified by its key. Please +refer to the P4 Entity Messages section for details on +what parts of the entity specification make up the key for each P4 entity. +

+

An update can be one of the following types: +

+
    +
  • +

    INSERT: Inserts the given P4 entity in the entity container. +The entity field always specifies the full state of the P4 entity. +If the entity already exists, an ALREADY_EXISTS error is returned, and +the existing entity remains unchanged. +If the entity is malformed, an INVALID_ARGUMENT error is returned. +If the entity cannot be inserted because the container is already full, +a RESOURCE_EXHAUSTED error is returned. +

  • +
  • +

    MODIFY: Modifies the P4 entity to its new specified state. This uses +assign or full-snapshot semantics, i.e. the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an INVALID_ARGUMENT error is usually returned (unless a +more specific error code applies [34]). If the entity does not +exist, a NOT_FOUND error is returned. +

  • +
  • +

    DELETE: Deletes the specified P4 entity. If the entity does not exist, a +NOT_FOUND error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored. +

+ +

If an update is not allowed under the given controller role, the server must +return a PERMISSION_DENIED error for this update. +

12.1. Batching and Ordering of Updates

+

P4Runtime supports batching of Write operations. The list of updates in a +WriteRequest is referred to as a batch. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of TableEntry entities). +

+

The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +WriteRequests can also be processed interleaved and/or in parallel. +However, the processing of requests must be strictly serializable. That +is, given a history $S$ of WriteRequests including the responses to those +requests, there must exist an order $L$ for all updates in $S$, such that: +

+
    +
  1. All updates from the same write request must appear as a contiguous +subsequence in $L$, but the order within that subsequence can be arbitrary. +
  2. +
  3. For two updates $u_1$ and $u_2$, if the write request containing $u_1$ +completed before the write request of $u_2$ was sent, then $u_1$ must appear +before $u_2$ in $L$. +
  4. +
  5. Executing all updates in $L$ sequentially must yield the same response for +every update as in $S$. +
  6. +
  7. The observable state of the switch after $S$ (e.g., through the Read RPC) +is identical to the one obtained by sequentially executing $L$. +
+ +

The Write RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the Write RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (e.g. inserting an ActionProfileMember +followed by pointing a TableEntry to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding Write RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate Write calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each Write call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one. +

12.2. Batch Atomicity

+

A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the Atomicity +enum. A P4Runtime server is required to support only the modes marked as +Required below: +

+
    +
  • +

    Required: CONTINUE_ON_ERROR: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that see each of +these intermediate stages. +

  • +
  • +

    Optional: ROLLBACK_ON_ERROR: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is all-or-none, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that see each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure. +

    +

    If a P4Runtime server does not support this option at all, an +UNIMPLEMENTED error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (e.g. it is +more straightforward to implement batches that contain only INSERT +operations, vs. those that contain DELETE operations), an +UNIMPLEMENTED error is returned when the batch cannot be executed +in a data plane-atomic way. +

  • +
  • +

    Optional: DATAPLANE_ATOMIC: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +transaction. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane's table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table. +

    +

    If a P4Runtime server does not support this option at all, an UNIMPLEMENTED +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an UNIMPLEMENTED error is returned when the batch +cannot be executed in a data plane-atomic way. +

+ +

There is no expectation that a given client must always use the same Atomicity +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use DATAPLANE_ATOMIC at one time and default behavior +(CONTINUE_ON_ERROR) at other times. +

12.3. Error Reporting

+

Please see section Error Reporting Messages for +information on error reporting messages and guidelines. P4Runtime server will +populate grpc::Status as follows: +

+
    +
  1. +

    If all batch updates succeeded, set grpc::Status::code_ to OK and do not +populate any other field. +

  2. +
  3. +

    If an error is encountered before even trying to attempt individual batch +updates, set grpc::Status::code_ that best describes that RPC-wide +error. For example, use UNAVAILABLE if the P4Runtime service is not yet +ready to handle requests. Set error_message_ to describe the issue. Do not +set error_details in this case. +

  4. +
  5. +

    Otherwise, if one or more updates in the batch (WriteRequest.updates) +failed, set grpc::Status::code_ to UNKNOWN. For example, one update in +the batch may fail with RESOURCE_EXHAUSTED and another with +INVALID_ARGUMENT. A p4.Error message is used to capture the status of +each and every update in the batch. The number of p4.Error messages packed +into google.rpc.Status.details field should therefore always match the +number of updates in the WriteRequest, and the order of +p4.Error messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +p4.Error should set the code to OK and omit other fields. +

+ +
+
+
# Example of a grpc::Status returned for a Write RPC with a batch of 3 updates.
+# The first and third updates encountered an error, while the second update
+# succeeded.
+code_ = 2  # UNKNOWN
+error_message_ = "Write failure."
+binary_error_details {
+  code: 2  # UNKNOWN
+  message: "Write failure."
+  details {
+    canonical_code: 8  # RESOURCE_EXHAUSTED
+    message: "Table is full."
+    space: "targetX-psa-vendorY"
+    code: 500  # ERR_TABLE_FULL
+  }
+  details {
+    canonical_code: 0  # OK
+  }
+  details {
+    canonical_code: 6  # ALREADY_EXISTS
+    message: "Entity already exists."
+    space: "targetX-psa-vendorY"
+    code: 600  # ERR_ENTITY_ALREADY_EXISTS
+  }
+}

13. Read RPC

+

The Read RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as: +

+
+
+
message ReadRequest {
+  uint64 device_id = 1;
+  repeated Entity entities = 2;
+}
+

The device_id uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +NOT_FOUND error. The entities repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server. +

+

Since ReadRequests do not mutate any state on the switch, they do not +require an election_id, and they do not require the presence of an open +StreamChannel between the server and client. +

+

The Read response consists of a sequence of messages (a gRPC stream) with +each message defined as: +

+
+
+
message ReadResponse {
+  repeated Entity entities = 1;
+}
+

The entities repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the Finish() method on the stream object +[10]). +

13.1. Nomenclature

+
+
request
+
An element of the p4.ReadRequest.entities repeated field. +
+
batch
+
Refers to the p4.ReadRequest.entities repeated field.
+

Each request acts as a query filter for that entity type. If a request fully +specifies the entity key, the Read operation should retrieve a single P4 +entity. Please refer to the P4 Entity Messages section +for details on what parts of the entity specification make up the entity key. +

13.2. Wildcard Reads

+

P4Runtime allows wildcard read of P4 entities. A request may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the P4 Entity Messages section for details on +what parts of the entity can be wildcarded in a given request. +

+

For example, in a request of type CounterEntry: +

+
    +
  • A default counter_id (0) implies a request to read all counter-entries for +all indirect counters. +
  • +
  • A particular (non-default) counter_id in conjunction with index unset +implies a request to read all counter-entries for the given indirect counter +ID. +
+ +

To read the entire forwarding state for a given device, the P4Runtime client can +generate the following ReadRequest: +

+
+
+
device_id: <ID>
+entities {
+  extern_entry { }  # read all extern instances for all supported extern types
+  table_entry { }  # read all table entries for all tables
+  action_profile_member { }  # read all members for all action profiles
+  action_profile_group { }  # read all groups for all action profiles
+  ...
+}
+

The entity oneof field in the Entity message must always be set, or the +server must return an INVALID_ARGUMENT error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty Entity message in the ReadRequest. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the entity oneof [20]. +

13.3. Batch Processing

+

A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type request +appears only once in the batch. +

+

A P4Runtime server will process the batch as follows: +

+
    +
  1. +

    Lock state (preventing new writes) and validate each request in the batch: +

    +
      +
    1. +

      If it is a valid request, perform the read; +

      +
        +
      1. If the read was successful, return the entities read in +ReadResponse stream. +
      2. +
      3. If the read failed (exception / critical-error), prepare a p4.Error +with code set to INTERNAL. +
      +
    2. +
    3. +

      If the request is invalid (invalid-argument, not-supported, etc.), +prepare a p4.Error with relevant canonical code to capture the error. +

    +
  2. +
  3. +

    Unlock the state (allowing new writes); +

  4. +
  5. +

    Close the ReadResponse stream and return a grpc::Status as follows: +

    +
      +
    1. +

      If no errors were encountered, set code to OK and do not populate any +other field. +

    2. +
    3. +

      Otherwise, the overall code should be set to UNKNOWN. See section +Error Reporting Messages for information +on error reporting messages and guidelines. Assemble a list of p4.Error +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +google.rpc.Status.details field. This behavior also matches Write +RPC. +

    +
+

13.3.1. Example

+

If a client asked to read {a,b,c,d} and b and d requests didn't +validate, the server will return entities corresponding to a and c, followed +by a status {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} in the +details field. +

+

The P4Runtime server is not required to perform any optimization (e.g. merge two +requests in the batch if one is a subset of other). As a result of this, it +is possible for the ReadResponse to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging. +

+

There is no requirement that each request in the batch will correspond to one +ReadResponse message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit. +

+

A P4Runtime server must be prepared to handle multiple concurrent Read RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (e.g. in a single-threaded architecture), it may choose to serialize +Read RPC processing. +

13.4. Parallelism of Read and Write Requests

+

A P4Runtime server may be implemented to serve at most one +ReadRequest or WriteRequest message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so. +

+

For example, imagine a client that wanted to use WriteRequest +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +WriteRequest messages with only a few updates to an ActionSelector +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +WriteRequest batch currently being processed, but it will not +complete for a significant amount of time. +

+

The restrictions on which a client may rely are: +

+
    +
  • The processing of any two WriteRequest messages W1 and W2 must +result in the same state as if one of them was completed before the +other began. +
  • +
  • For any WriteRequest W and any ReadRequest R, R must +return results consistent with a state where W has completed +processing, or W has not yet begun processing. +
+ +

For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a WriteRequest message it acquired a write lock for each stateful +object affected by the WriteRequest, and before starting the +processing of a ReadRequest message it acquired a read lock for each +stateful object accessed by the ReadRequest, such an implementation +meets all of the requirements above. +

+

It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, e.g. if the server somehow determined that two +WriteRequest messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly. +

14. SetForwardingPipelineConfig RPC

+

A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the SetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message SetForwardingPipelineConfigRequest {
+  enum Action {
+    UNSPECIFIED = 0;
+    VERIFY = 1;
+    VERIFY_AND_SAVE = 2;
+    VERIFY_AND_COMMIT = 3;
+    COMMIT = 4;
+    RECONCILE_AND_COMMIT = 5;
+  }
+  uint64 device_id = 1;
+  uint64 role_id = 2;
+  Uint128 election_id = 3;
+  Action action = 4;
+  ForwardingPipelineConfig config = 5;
+}
+

The server is expected to perform the following checks (in this order) +before performing the required action: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role_id does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the master for (device_id, role_id) according to the +election_id value, the server must return a PERMISSION_DENIED error. +

+ +

The action is the type of configuration action requested, it can be one of: +

+
    +
  • +

    VERIFY: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an INVALID_ARGUMENT +error if config is not provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_SAVE: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent Read / Write requests must refer to fields in the new +config. Returns an INVALID_ARGUMENT error if the forwarding config is not +provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_COMMIT: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an INVALID_ARGUMENT error if the forwarding config is not provided or if the +provided config cannot be realized. +

  • +
  • +

    COMMIT: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a NOT_FOUND error if no saved config +is found, i.e. if no VERIFY_AND_SAVE action preceded this one. Returns an +INVALID_ARGUMENT error if a config is provided with this message. +

  • +
  • +

    RECONCILE_AND_COMMIT: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an UNIMPLEMENTED error. For targets that support this option, an +INVALID_ARGUMENT error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target. +

+ +

The config field is a message of type ForwardingPipelineConfig that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(e.g. generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the Forwarding-Pipeline +Configuration section for details. +

+

A P4Runtime server running on a non-programmable device may not +support SetForwardingPipelineConfig (e.g. the forwarding-pipeline +config is part of the device's software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +UNIMPLEMENTED error. +

15. GetForwardingPipelineConfig RPC

+

The forwarding-pipeline configuration of the target can be retrieved by invoking +the GetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message GetForwardingPipelineConfigRequest {
+  enum ResponseType {
+    ALL = 0;
+    COOKIE_ONLY = 1;
+    P4INFO_AND_COOKIE = 2;
+    DEVICE_CONFIG_AND_COOKIE = 3;
+  }
+  uint64 device_id = 1;
+  ResponseType response_type = 2;
+}
+

The device_id uniquely identifies the target P4 device. A NOT_FOUND error is +returned if the device_id is not recognized by the P4Runtime server. +

+

The response_type is used to specify which fields to populate in the response, +its value can be one of: +

+
    +
  • +

    ALL: returns a ForwardingPipelineConfig with all fields +set as stored by the target. This is the default behaviour if the +response_type field is not set. +

  • +
  • +

    COOKIE_ONLY: reply by setting only the cookie field in the +ForwardingPipelineConfig, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message. +

  • +
  • +

    P4INFO_AND_COOKIE: reply by setting the p4info and cookie fields. +

  • +
  • +

    DEVICE_CONFIG_AND_COOKIE: reply by setting the p4_device_config and +cookie fields. +

+ +

The response contains the ForwardingPipelineConfig for the specified device: +

+
+
+
message GetForwardingPipelineConfigResponse {
+  ForwardingPipelineConfig config = 1;
+}
+

If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level config field will be unset in the response. Examples are +(i) a server that only allows configuration via SetForwardingPipelineConfig +but this RPC hasn't been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn't yet occurred. +

+

Once a forwarding-pipeline config is installed on the device (either via +SetForwardingPipelineConfig or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +config.p4_device_config will be empty / unset in the response, even if +response_type in the request was set to ALL. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the SetForwardingPipelineConfig RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +SetForwardingPipelineConfig, the value of config.cookie will be unset. +

+

If a P4Runtime server supports both SetForwardingPipelineConfig as well as +returning the p4_device_config, there should be read-write symmetry between +SetForwardingPipelineConfig and GetForwardingPipelineConfig RPCs. +

16. P4Runtime Stream Messages

16.1. Packet I/O

+

P4Runtime supports controller packet-in and packet-out by means of PacketIn +and PacketOut stream messages, respectively. +

+

PacketIn messages are sent by the P4Runtime server to the client. Conversely, +PacketOut messages are sent by the client to the server. Any PacketOut +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a StreamMessageResponse message with the error field set to +report the error to the client. See the section on Stream Error +Reporting for more information on error. +

+

As introduced in the ControllerPacketMetadata +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with @controller_header. The expected metadata is described +in the P4Info using the ControllerPacketMetadata messages. +

+

Both PacketIn and PacketOut stream messages share the same fields and are +defined as follows: +

+
+
+
// Packet sent from the controller to the switch.
+message PacketOut {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+// Packet sent from the switch to the controller.
+message PacketIn {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+message PacketMetadata {
+  // This refers to Metadata.id coming from P4Info ControllerPacketMetadata.
+  uint32 metadata_id = 1;
+  bytes value = 2;
+}
+
    +
  • +

    payload is used to carry the full packet content, including the headers. +

  • +
  • +

    metadata is a repeated field of PacketMetadata messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +ControllerPacketMetadata. Indeed, when a P4Runtime client (or server) +generates a PacketOut (or PacketIn) message, it needs to populate the +metadata field with as many values as in ControllerPacketMetadata.metadata +for the packet-out (or packet-in) case. Each PacketMetadata.value is a +binary string and must conform to the Bytestrings +requirements based on the corresponding P4Info +ControllerPacketMetadata.metadata specification. If the metadata field +does not match the P4Info specification, the server must drop the PacketOut +message and may generate a StreamMessageResponse message with the error +field set to report the error to the client which issued the PacketOut. See +the section on Stream Error Reporting for more +information on error. +

+

16.2. Master Arbitration Update

+

P4Runtime's master arbitration mechanism ensures that only the current master +can modify state on the switch, and that the election_id is monotonically +increasing. For example, the switch must finish all previous write operations +before changing masters, and must only accept write requests from the current +master. +

+

As explained earlier in this document, the controller uses the StreamChannel +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via Write RPC), +it needs to start a controller session and become a “master”. To do so, the +controller first opens a bidirectional stream channel to the server via +StreamChannel for each device and sends a StreamMessageRequest message. The +controller populates the MasterArbitrationUpdate field in this message using +its role_id and election_id and the device_id of the device, as explained +in detail in the Master-Slave Arbitration and Controller +Replication +section. For any given (device_id, role_id), the P4Runtime server keeps track +of the highest election_id that it has ever received. If a controller's +election_id is equal to the highest election_id that the server has ever +received, that controller is the master. All other controllers are slaves. Note +that it is possible that all controllers are slaves, and that there is no +master. There can be at most one master, because for any given +(device_id, role_id), each connected controller has a unique election_id. +

+

This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest election_id after such a restart. +However, across a full restart, the election_id must be +reset. In fact, a full restart is the only way to reset the election_id. +

+

The MasterArbitrationUpdate message is defined as follows: +

+
+
+
message Role {
+  // role_id for this role. Defined offline in agreement across the
+  // entire control plane.
+  uint64 id = 1;
+  // Describes the role configuration.
+  google.protobuf.Any config = 2;
+}
+
+message MasterArbitrationUpdate {
+  // Identifies the device (aka target or node or switching chip).
+  uint64 device_id = 1;
+  // The role for which the mastership is being arbitrated.
+  Role role = 2;
+  // The election_id (unique per role).
+  Uint128 election_id = 3;
+  // Switch populates this with OK for the client that is the master,
+  // and with an error status for all other connected clients (at
+  // every mastership change). The controller does not populate this
+  // field.
+  google.rpc.Status status = 4;
+}
+

Note that the status field in the MasterArbitrationUpdate message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a StreamMessageResponse message back to the controller, in which +it populates the MasterArbitrationUpdate message using the device_id, +role, and election_id it previously received from the controller. The server +also populates the status field in the MasterArbitrationUpdate according to +the rules in an earlier section. +

+

The sender need not specify an election_id. If the election_id is not +specified, the sender's election_id is considered lower than any +election_id, and the sender will thus never become master. This way, a +controller can choose to be a standby controller, in order to avoid master +“flapping” (if a standby controller connects to the switch shortly before the +actual master controller, therefore becoming master temporarily). +

16.3. Digest Messages

+

See the DigestEntry section. +

16.4. Table Idle Timeout Notification

+

When a table supports idle timeout (as per the P4Info message), the master +client can specify a TTL value for each entry in the table (see +Idle-timeout section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an IdleTimeoutNotification message on the +StreamChannel bidirectional stream to the master client. The master client can +then take the action of its choice, most likely remove the idle entry. +

+

The IdleTimeoutNotification Protobuf message has the following fields: +

+
    +
  • +

    timestamp: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server's local clock. +

  • +
  • +

    table_entry: a repeated field of entries which have expired. Each individual +entry is identified by a single TableEntry message. For each TableEntry, +the key fields (table_id, match and priority) must be set, along with +the controller_metadata field, the metadata field, and the +idle_timeout_ns field. Other fields may be set by the server but should be +ignored by the client. +

+ +

Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +IdleTimeoutNotification message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an IdleTimeoutNotification +message with an empty table_entry repeated field. +

+

After generating an idle notification, the P4Runtime server must “reset” the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the master client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle. +

+

Here is a reasonable pseudo-code implementation for idle timeout for table +entries: +

+
+
+
IdleTimeoutStream stream;
+
+scanning_interval = 10ms;
+
+while (true) {
+  // iterate over all tables which support idle timeout
+  for (table in tables) {
+    if (!table.idle_timeout_supported) continue;
+    // we coalesce all idle notifications for the same table in one
+    // message
+    IdleTimeoutNotification msg;
+    // read time_since_last_hit from device
+    entries = device.load_table_entries_from_hw(table);
+    for (entry in entries) {
+      if (entry.idle_timeout == 0) continue;  // no TTL
+      if (entry.time_since_last_hit < entry.idle_timeout) continue;
+      msg.table_entry_add(entry);
+      entry.reset_time_since_last_hit();
+    }
+    if (msg.table_entry_size() == 0) continue;  // no notifications
+    msg.set_timestamp(now());
+    stream.write(msg);
+  }
+  sleep(scanning_interval);
+}

16.5. Architecture-Specific Notifications

+

P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on StreamChannel, by including an Any Protobuf field [31] +named other in both StreamMessageRequest and StreamMessageResponse. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the PSA Digest +extern. See section on Extending P4Runtime for non-PSA +Architectures for more information. +

16.6. Stream Error Reporting

+

The P4Runtime server can asynchronously report errors which occur when +processing StreamMessageRequest messages, using the error message field (of +type StreamError) in StreamMessageResponse. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature. +

+

The StreamError message has the following fields: +

+
    +
  • canonical_code, which must be set to the appropriate canonical error code +[34]. +
  • +
  • message, an optional developer-facing error message describing the error. +
  • +
  • space and code, which are optional and can be used by vendors to provide +additional details on the error. code is a numeric error code drawn from a +vendor's chosen error space. +
  • +
  • details, which is a Protobuf oneof used to help the client identify which +StreamMessageRequest triggered the error. The server is required to set the +appropriate field in the oneof so that the client can identify which type +of stream message is responsible for the error (packet_out, +digest_list_ack or other), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid PacketOut message from the +client, the packet_out field (of type PacketOutError) should be set in +the details oneof, and the server may additionally set the packet_out +field in the PacketOutError sub-message (by copying it from the invalid +PacketOut message received on the stream channel) so that the client can +know exactly what packet-out triggered the error. +
+ +

The appropriate canonical error code [34] should be used when +populating the canonical_code field. For example: +

+
    +
  • if a controller is not allowed to send a PacketOut message under its +current role definition, the code should be set to PERMISSION_DENIED. +
  • +
  • if the metadata repeated field in PacketOut does not match the P4Info +definition, the code should be set to INVALID_ARGUMENT. It may be useful +for the server to set the packet_out field in this case, so that the client +can find out which set of metadata fields triggered the error. +
  • +
  • if the digest_id field in DigestListAck does not match any Digest entry +in P4Info, the code should be set to INVALID_ARGUMENT. +
+ +

The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, e.g. because of a +burst of PacketIn messages. +

+

Note that master-arbitration errors are never reported using the StreamError +message. Invalid MasterArbitrationUpdate messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section 5.3. +

16.6.1. Examples of StreamError Messages

+
    +
  • +

    Malformed packet-out metadata. If the server receives a PacketOut +message with a metadata field with id 7 which is not included in the P4Info +ControllerPacketMetadata message for “packet_out”, the server may send the +following StreamMessageResponse back to the client: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Unknown metadata field id 7."
    + packet_out {
    +   # copied from the PacketOut message received from the client
    +   packet_out {
    +     payload: ...
    +     metadata {
    +       id: 7
    +       name: "I_should_not_be_here"
    +       bitwidth: 32
    +     }
    +     # more metadata
    +   }
    + }
    +}
  • +
  • +

    Packet-out which exceeds the MTU. If the server receives a PacketOut +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following StreamMessageResponse: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Packet exceeds the MTU for port."
    + space: "targetX-psa-vendor1"
    + code: 123  # MTU_EXCEEDED
    + packet_out {
    +   # we do not set the packet_out field as it does not provide any
    +   # extra information to the client
    + }
    +}
+

17. Capabilities RPC

+

The Capabilities RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the CapabilitiesRequest message is empty and the CapabilitiesResponse +message only includes the p4runtime_api_version string field. This field must +be set to the full semantic version string [27] corresponding to the +version of the P4Runtime API implemented by the server, e.g. “1.1.0-rc.1”. +

+

Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three atomicity +modes for WriteRequest batches, two of them being +optional. In the future we may decide to leverage the CapabilitiesResponse +message to enable the server to report to the client which subset of these +atomicity modes is supported. +

+

The semantic version string included in CapabilitiesResponse can be used by +the client to determine which exact feature set is implemented by the server, +since minor releases may introduce new +functionality. However, because the Capabilities RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (i.e. an UNIMPLEMENTED error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0). +

18. Portability Considerations

18.1. PSA Metadata Translation

+

The Portable Switch Architecture (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +[24]. For such metadata, a translation between the controller's +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the @p4runtime_translation annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture. +

+
+

psa-metadata-translation +

+
+ +
Figure 8. P4Runtime Metadata Translation for the Portable Switch Architecture
+

Figure 8 illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller's 32 bit port +numbers to a target's 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch. +

18.1.1. Translation of Port Numbers

+

In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller's space and the PSA device's space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +user-defined P4 types, namely PortId_t and +PortIdInHeader_t, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in psa.p4 for +the PSA device in Switch 1. +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type bit<9> PortId_t;
+@p4runtime_translation("p4.org/psa/v1/PortIdInHeader_t", 32)
+type bit<32> PortIdInHeader_t;
+

The first argument to the @p4runtime_translation annotation is a URI that +indicates to the P4Runtime server which numerical mapping provided by the +out-of-band switch configuration mechanism to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports). +

+

An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows: +

+
+
+
enum SdnPort {
+  SDN_PORT_UNSPECIFIED = 0;
+
+  // SDN ports are numbered starting from 1.
+  SDN_PORT_MIN = 1;
+
+  // The maximum value of an SDN port (physical or logical).
+  SDN_PORT_MAX = 0xfffffeff;
+
+  // Reserved SDN port numbers (0xfffffff0 - 0xffffffff)
+
+  SDN_PORT_RECIRCULATE = 0xfffffffa;
+  SDN_PORT_CPU = 0xfffffffd;
+}
+

The switch config will map SDN_PORT_RECIRCULATE and SDN_PORT_CPU as well +as any SDN port number corresponding to a “regular” front-panel port to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation. +

+

The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs. +

18.1.2. Translation of Packet-IO Header Fields

+

Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  PortIdInHeader_t egress_port;
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  PortIdInHeader_t ingress_port;
+}
+

The header-level annotation @controller_header is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (egress_port) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI first argument to the @p4runtime_translation +annotation). Any subsequent reference to the egress_port field in the +data plane will use the translated value. PortIdInHeader_t is used in the +header definition instead of PortId_t to guarantee byte-aligned headers in +case this is required by the target. +

+

A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target's PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the ingress_port field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller. +

18.1.3. Translation of Match Fields

+

Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table's match key as shown in the example below: +

+
+
+
table t {
+  key = {
+    istd.ingress_port: exact;  // PSA standard metadata ingress port
+  }
+  actions = {
+    drop;
+  }
+}
+

Table t has an exact match on PSA standard metadata ingress port +(istd.ingress_port). Since the field is of type PortId_t, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in t from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table t is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values. +

+

Note that it may be infeasible to translate the value-mask pair for ternary +matches: LPM, TERNARY or RANGE match kinds. The P4Runtime server may +require that for these match kinds the port match be either de facto “exact” +(0xffffffff mask for TERNARY, prefix-length of 32 for LPM, or same low and +high bounds for RANGE) or “don't care”. +

18.1.4. Translation of Action Parameters

+

PortId_t type parameters can be part of a P4 action definition as shown in the +example below: +

+
+
+
action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+}
+
+table t {
+  key = {
+    hdr.h.f: exact;
+  }
+  actions = {
+    a;
+  }
+}
+

The controller may write entries in table t with action a to set the egress +port as shown in the P4 code above. The action parameter p is of type +PortId_t, which leads to a 32-bit bitwidth for p being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device. +

18.1.5. Port Translation for PSA Extern APIs

+

The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch field is +of type uint32 to carry the 32-bit SDN representation of the port being +watched. The P4Runtime server will translate the given watch port number into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device. +

+

The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type uint32 to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane. +

18.1.6. Using Port as an Index to a Register, Indirect Counter or Indirect Meter

+

P4Runtime supports using a translated value (PortId_t or any other translated +type for which the underlying built-in type is bit<W>) as an index to a +register, indirect counter, or indirect meter. +

+
+
+
Counter<bit<32> /* counter entry type */, PortId_t /* index type */>(
+  32w1024, PSA_CounterType_t.PACKETS) counter;
+action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+  counter.count(p);
+}
+

This P4 Counter declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
counters {
+  preamble {
+    id: 0x12000001
+    name: "counter"
+  }
+  spec {
+    unit: PACKETS
+  }
+  index_type_name {
+    name: "PortId_t"
+  }
+}
+

The controller may read and write counter values from indexed counter counter +using SDN port numbers as indices, and not device-specific port numbers. The +index_type_name field in the P4Info message is a signal to the P4Runtime +server that translation is required. +

19. P4Runtime Versioning

+

P4Runtime follows the Google guidelines for versioning cloud APIs +[6]. We use a MAJOR.MINOR.PATCH style version number scheme and +we increment the: +

+
    +
  • MAJOR version when we make incompatible API changes, +
  • +
  • MINOR version when we add functionality in a backwards-compatible manner, +
  • +
  • PATCH version when we make backwards-compatible bug fixes. +
+ +

The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is p4.v1 and the package +name for P4Info is p4.config.v1. Even though p4 and p4.config are two +different Protobuf packages, p4 depends on p4.config and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence. +

+

As recommended in [6], we may consider using pre-GA release +suffixes (such as alpha or beta) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1). +

+

Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner. [7] describes +what constitute a backwards-compatible change. We expect MAJOR version bumps +to be a rare event. +

+

Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor + patch version numbers in future releases. +

+

All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository [15] and the version label follows +semantic versioning rules [27]. +

20. Extending P4Runtime for non-PSA Architectures

+

P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place. +

+

When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names: +

+
    +
  • p4/[organization]/arch/config/<major version>/p4info.proto +
  • +
  • p4/[organization]/arch/<major version>/p4runtime.proto +
+ +

We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they “extend”. +

+

For the remainder of this section, we will refer to these two files as +p4info-ext and p4runtime-ext respectively. +

20.1. Extending P4Runtime for Architecture-Specific Externs

+

Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both p4info-ext and +p4runtime-ext. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example: +

+
+
+
// T must be a bit<W> type, it indicates the width of each counter cell
+extern MyNewPacketCounter<T> {
+  counter(bit<32> size);
+  increment(in bit<32> index);
+}

20.1.1. Extending the P4Info message

+
    +
  • Id prefixes 0x81 through 0xfe are reserved for architecture-specific +externs. It is recommended that p4info-ext include a P4Ids message based +on the one in p4info.proto that the P4 compiler can refer to when assigning +IDs to each extern instance. +
+ +
+
+
message P4Ids {
+  enum Prefix {
+    UNSPECIFIED = 0;
+    MY_NEW_PACKET_COUNTER = 0x81;
+  }
+}
+
    +
  • p4info-ext should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +p4.config.v1.ExternInstance message as the info +field, which is of type Any [31]. +
+ +
+
+
message MyNewPacketCounter {
+  // corresponds to the T type parameter in the P4 extern definition
+  p4.config.v1.P4DataTypeSpec type_spec = 1;
+  // constructor argument
+  int64 size = 2;
+}

20.1.2. Extending the P4Runtime Service

+

Just like p4info-ext, p4runtime-ext should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an ExternEntry message generated by the +P4Runtime client. +

+

Here is a possible Protobuf message for our MyNewPacketCounter P4 extern: +

+
+
+
// This message enables reading / writing data to the counter at the provided
+// index
+message MyNewPacketCounter {
+  int64 index = 1;
+  p4.v1.P4Data data = 2;
+}
+

P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an Any Protobuf field [31] named other +in both p4.v1.StreamMessageRequest and +p4.v1.StreamMessageResponse. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in p4runtime-ext and embed instances of these messages in +p4.v1.StreamMessageRequest and p4.v1.StreamMessageResponse as appropriate. +

20.2. Architecture-Specific Table Extensions

20.2.1. New Match Types

+

An architecture may introduce new table match types [12]. P4Runtime +accounts for this by providing the following hooks: +

+
    +
  • +

    The match field in p4.config.v1.MatchField (p4info.proto) is a oneof +which can be either one of the default match types (EXACT, LPM, TERNARY, +RANGE, or OPTIONAL) or an architecture-specific match type encoded as a +string. +

  • +
  • +

    The field_match_type field in p4.v1.FieldMatch (p4runtime.proto) is a +oneof which includes an Any Protobuf message [31] field +(other). p4info-ext should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in p4.v1.FieldMatch as the +other field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info. +

+

20.2.2. New Table Properties

+

An architecture may introduce additional table properties +[30]. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +p4.config.v1.Table message includes the other_properties Any Protobuf +field [31]. At the moment, there is not any mechanism to extend the +p4.v1.TableEntry message based on the value of architecture-specific table +properties, but we may include on in future versions of the API. +

21. Known Limitations of Current P4Runtime Version

+
    +
  • +

    FieldMatch, action Param, and controller packet metadata fields only +support unsigned bitstrings, i.e. values of one of the following types (not +the more general P4Data): +

    +
      +
    • bit<W> +
    • +
    • bool. Note that as far as the P4Info message contents and +thus controller software is concerned, such fields of type bool +will be indistinguishable from those that have been declared with +type bit<1>. P4Runtime server software will automatically +perform any conversion needed between the type bit<1> values in +P4Runtime messages and the data plane representation. +
    • +
    • an enum with underlying type bit<W> +
    • +
    • a type or typedef with an underlying type that is one of the above (or +in general a “chain” of type and/or typedef that eventually ends with +one of the types above) +
    +
  • +
  • +

    Support for PSA Random & Timestamp externs is postponed to a future minor +version update. +

  • +
  • +

    P4Info does not include information about which of a table's actions execute +which direct resource(s). +

  • +
  • +

    The default action for indirect match tables is restricted to a const +NoAction known at compile-time. +

  • +
  • +

    There is no mechanism for changing the value of the psa_empty_group_action +table property at runtime. +

  • +
  • +

    There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor + +patch version numbers. +

+

22. Security concerns for P4Runtime

+

Appropriate measures and security best practices need to be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. +

A. Appendix

A.1. Revision History

A.1.1. Changes in v1.2.0

+
    +
  • Add new OPTIONAL match kind. At the moment, OPTIONAL is only supported by +the v1model architecture [38], and not by PSA. It will eventually be +included in the core P4 language. +
  • +
  • Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists. +
  • +
  • Add a new metadata field of type bytes to TableEntry. This is more +flexible than the now deprecated controller_metadata field. +
  • +
  • Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +@id annotation. +
  • +
  • Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature. +
  • +
  • Support using string as the controller type in the @p4runtime_translation +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type. +
  • +
  • Add optional P4 source locations to both structured and unstructured +annotations. +
+

A.1.2. Changes in v1.1.0

+
    +
  • Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously. +
  • +
  • Add error field to stream messages sent by the server. +
  • +
  • Add Capabilities RPC to query the P4Runtime API version implemented by the +server. +
  • +
  • Support wildcard reads for multicast groups and clone sessions. +
  • +
  • Support for modifying direct resources of const tables. +
  • +
  • Support P4 user-defined types for Packet IO metadata fields. +
  • +
  • Clarify consistency requirements for Write and Read RPCs. +
  • +
  • Add Appendix providing implementation advice for avoiding common pitfalls: + +
      +
    • advice on setting gRPC Metadata Maximum Size +
    • +
    • advice on setting gRPC Server Maximum Receive Message Size +
  • +
  • Clarify limitations on supported types for FieldMatch, action Param, and +Packet IO metadata fields. +
  • +
  • Clarify that reading entire forwarding state with empty entity is not +supported. +
  • +
  • Document that @p4runtime_translation need only be supported when applied to +type declarations in P4. +
+

A.2. P4 Annotations

+

Table 7 lists P416 annotations introduced primarily for +the purpose of adding features for the P4Runtime API. +

+
+ + + + + + + + + + +
Annotation Description
@brief See section 6.1.3
@controller_header See section 6.4.6
@description See section 6.1.3
@id See section 6.3
@max_group_size See sections 6.4.3, 9.2.2
@pkginfo See section 6.2.1
@p4runtime_translation See sections 8.5.6, 18.1.1
+
+ +
Table 7. P4 annotations introduced by P4Runtime

A.3. A More Complex Value Set Example

+

This section includes a more complex Value Set example, with multiple matches of +different kinds. +

+
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+

This P4 Value Set declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

A P4Runtime client can set the membership for this Value Set with WriteRequest +messages similar to this one: +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xac }
+      }
+      # match for field_id 2 is missing => don't care match
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xdc }
+      }
+      match {
+        field_id: 2
+        ternary { value: 0x88 mask: 8f }
+      }
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+  }
+}

A.4. Guidelines for Implementations

+

This section contains practical advice for implementing P4Runtime clients and +servers. +

A.4.1. gRPC Metadata Maximum Size

+

In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the grpc.max_metadata_size gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the Write P4Runtime RPC. The Write RPC +returns an individual error for every item in a batch (see Section +12), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +RESOURCE_EXHAUSTED error, without any of the individual errors. +

+

To fix this problem, one can set the grpc.max_metadata_size option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it's +limit, as only the receiving side's limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every p4.Error, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +8192 + MAX_UPDATES_PER_WRITE * 100 bytes of metadata. +

+

For example, in C++, one can create a client channel as follows: +

+
+
+
const int MAX_UPDATES_PER_WRITE = 100;
+::grpc::ChannelArguments arguments;
+arguments.SetInt(GRPC_ARG_MAX_METADATA_SIZE, 8192 + MAX_UPDATES_PER_WRITE*100);
+return grpc::CreateCustomChannel(address, credentials, arguments);

A.4.2. gRPC Server Maximum Receive Message Size

+

At the time of writing, the default maximum receive message size in gRPC is 4MB + while the default maximum send message size is unlimited. This can be a +problem for the SetForwardingPipelineConfig RPC, since for some targets the +binary p4_device_config can exceed 4MB, in which case by default the P4Runtime +server would return an INVALID_ARGUMENT error. To a lesser extent, this may +affect the Write RPC as well, in case of extremely large batches. +

+

To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of p4_device_config for their target(s). This can be done by +setting the grpc.max_receive_message_length when building the gRPC server. +

+

For example, in C++, one can set the maximum receive message size as follows: +

+
+
+
const int MAX_RECEIVE_MESSAGE_SIZE = 128 * 1024 * 1024;  // 128MB
+::grpc::ServerBuilder server_builder;
+builder.AddListeningPort(/*...*/);
+builder.RegisterService(/*...*/);  // register P4Runtime service
+builder.SetMaxReceiveMessageSize(MAX_RECEIVE_MESSAGE_SIZE);
+builder.BuildAndStart();
+

On the client side, we recommend that P4Runtime clients do not use Write +batches larger than the default maximum receive message size (4MB) in case +the server did not deem necessary to increase the default value , unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB). +

+

References

+
+ +
[2]“A Two Rate Three Color Marker.” https://​tools.​ietf.​org/​html/​rfc2698.
+ + + + +
[7]“Google Cloud APIs Versioning - Backwards-Compatibility.” https://​cloud.​google.​com/​apis/​design/​versioning#​backwards_​compatibility.
+ +
[9]“gRPC Main Site.” https://​grpc.​io.
+ + + + + +
[15]“p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” https://​github.​com/​p4lang/​p4runtime.
+
[16]“p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.” https://​github.​com/​p4lang/​PI.
+ + +
[19]“Portable Switch Architecture Specification (v1.1.0).” https://​p4.​org/​p4-​spec/​docs/​PSA-​v1.​1.​0.​html.
+ + + + + + + +
[27]“Semantic Versioning.” https://​semver.​org/​.
+ + + + + + + +
[35]“The OpenConfig Project.” http://​openconfig.​net.
+ +
[37]“The Stratum Project.” https://​stratumproject.​org/​.
+ +
+
+
+ +
+

1.an enum type used as a field in a header must specify a +underlying type and representation for enum elements. +

+ + + diff --git a/spec/v1.2.0-rc.2/P4Runtime-Spec.log b/spec/v1.2.0-rc.2/P4Runtime-Spec.log new file mode 100644 index 00000000..feca8673 --- /dev/null +++ b/spec/v1.2.0-rc.2/P4Runtime-Spec.log @@ -0,0 +1,14554 @@ +This is XeTeX, Version 3.14159265-2.6-0.99992 (TeX Live 2015/Debian) (preloaded format=xelatex 2018.8.17) 23 JUN 2020 17:07 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**build/P4Runtime-Spec.tex +(./build/P4Runtime-Spec.tex +LaTeX2e <2016/02/01> +Babel <3.9q> and hyphenation patterns for 81 language(s) loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2014/09/29 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo +File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@section=\count80 +\c@subsection=\count81 +\c@subsubsection=\count82 +\c@paragraph=\count83 +\c@subparagraph=\count84 +\c@figure=\count85 +\c@table=\count86 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) (build/madoko2.sty (/usr/share/texlive/texmf-dist/tex/latex/colortbl/colortbl.sty +Package: colortbl 2012/02/13 v1.0a Color table columns (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty +Package: array 2014/10/28 v2.4c Tabular extension package (FMi) +\col@sep=\dimen103 +\extrarowheight=\dimen104 +\NC@list=\toks14 +\extratabsurround=\skip43 +\backup@length=\skip44 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty +Package: color 2016/01/03 v1.1b Standard LaTeX Color (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package color Info: Driver file: xetex.def on input line 143. +(/usr/share/texlive/texmf-dist/tex/xelatex/xetex-def/xetex.def +File: xetex.def 2015/09/11 v4.06 LaTeX color/graphics driver for XeTeX (TeX Live/RRM/JK) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +))) +\everycr=\toks15 +\minrowclearance=\skip45 +) (/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: xetex.def on input line 225. +LaTeX Info: Redefining \color on input line 702. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) (build/options.sty +Package: options 2015/03/01, Daan Leijen, Provides convenient path-value (or key-value) options +(/usr/share/texlive/texmf-dist/tex/latex/etoolbox/etoolbox.sty +Package: etoolbox 2015/08/02 v2.2a e-TeX tools for LaTeX (JAW) +\etb@tempcnta=\count87 +) +\opt@nesting=\count88 +\opt@idx=\count89 +\opt@choiceord=\count90 +) (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty +Package: iftex 2013/04/04 v0.2 Provides if(tex) conditional for PDFTeX, XeTeX, and LuaTeX +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2014/10/28 v1.0g Enhanced LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks16 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2016/01/03 v1.0q Standard LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2016/01/03 v1.10 sin cos tan (DPC) +) (/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg +File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live +) +Package graphics Info: Driver file: xetex.def on input line 95. +) +\Gin@req@height=\dimen105 +\Gin@req@width=\dimen106 +) (build/longfbox.sty +Package: longfbox 2015/12/01, Daan Leijen, Provides long fbox that can break over pages +(build/longbox.sty +Package: longbox 2015/12/01, Daan Leijen, Provides basic longbox that can break over pages +(/usr/share/texlive/texmf-dist/tex/latex/mdwtools/footnote.sty +Package: footnote 1997/01/28 1.13 Save footnotes around boxes +\fn@notes=\box26 +\fn@width=\dimen107 +) +\lb@prevdepth=\skip46 +\lb@freevspace=\skip47 +\lb@headbox=\box27 +\lb@savebox=\box28 +\lb@mainbox=\box29 +\lb@usevbox=\count91 +\lb@width=\skip48 +\lb@height=\skip49 +\lb@skiptop=\skip50 +\lb@skipright=\skip51 +\lb@skipbottom=\skip52 +\lb@skipleft=\skip53 +\lb@skipbreaktop=\skip54 +\lb@skipbreakbottom=\skip55 +\lb@outerwidth=\skip56 +\lb@extrasplit=\skip57 +\lb@textalign=\count92 +\lb@baseline=\count93 +\lb@neededvspace=\skip58 +\lb@splitheight=\skip59 +\lb@insurance=\skip60 +\/longbox/@part-height=\skip61 +\/longbox/@part-width=\skip62 +\/longbox/@part-depth=\skip63 +\/longbox/@content-box-height=\skip64 +\/longbox/@content-box-width=\skip65 +\/longbox/@content-box-depth=\skip66 +\/longbox/@breakat-previous=\skip67 +\/longbox/@lower=\skip68 +\/longbox/split-minimum=\skip69 +\/longbox/split-badness=\skip70 +\/longbox/raise=\skip71 +\/longbox/height=\skip72 +\/longbox/width=\skip73 +\/longbox/outer-height=\skip74 +\/longbox/outer-width=\skip75 +\/longbox/skip-top=\skip76 +\/longbox/skip-right=\skip77 +\/longbox/skip-bottom=\skip78 +\/longbox/skip-left=\skip79 +\/longbox/skip-break-bottom=\skip80 +\/longbox/skip-break-top=\skip81 +) (/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.sty +Package: pict2e 2016/02/05 v0.3b Improved picture commands (HjG,RN,JT) +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.cfg +File: pict2e.cfg 2016/02/05 v0.1u pict2e configuration for teTeX/TeXLive +) +Package pict2e Info: Driver file: xetex.def on input line 119. +Package pict2e Info: Driver file for pict2e: p2e-xetex.def on input line 121. +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/p2e-xetex.def +File: p2e-xetex.def 2016/02/05 v0.1u Driver-dependant file (RN,HjG,JT) +) +\pIIe@GRAPH=\toks17 +\@arclen=\dimen108 +\@arcrad=\dimen109 +\@tempdimd=\dimen110 +) (build/ellipse.sty +Package: ellipse 2004/11/05 v1.0 .dtx ellipse file +) +\fbox@oct=\count94 +\fbox@quad=\count95 +\fbox@diaq=\count96 +\fbox@sign=\count97 +\fbox@anglestart=\skip82 +\fbox@angleend=\skip83 +\fbox@dash=\skip84 +\fbox@dashskip=\skip85 +\fbox@anglecur=\skip86 +\fbox@dashangle=\skip87 +\fbox@dashskipangle=\skip88 +\fbox@delta=\skip89 +\fbox@from=\skip90 +\fbox@to=\skip91 +\/fbox/padding-top=\skip92 +\/fbox/padding-right=\skip93 +\/fbox/padding-bottom=\skip94 +\/fbox/padding-left=\skip95 +\/fbox/padding-break-top=\skip96 +\/fbox/padding-break-bottom=\skip97 +\/fbox/margin-top=\skip98 +\/fbox/margin-right=\skip99 +\/fbox/margin-bottom=\skip100 +\/fbox/margin-left=\skip101 +\/fbox/margin-break-top=\skip102 +\/fbox/margin-break-bottom=\skip103 +\/fbox/border-top-width=\skip104 +\/fbox/border-right-width=\skip105 +\/fbox/border-bottom-width=\skip106 +\/fbox/border-left-width=\skip107 +\/fbox/border-break-top-width=\skip108 +\/fbox/border-break-bottom-width=\skip109 +\/fbox/@lower=\skip110 +\/fbox/@padding-box-height=\skip111 +\/fbox/@padding-box-depth=\skip112 +\/fbox/@padding-box-width=\skip113 +\/fbox/@border-box-width=\skip114 +\/fbox/@border-box-height=\skip115 +\/fbox/@border-box-depth=\skip116 +\/fbox/@border-top-left-radius-x=\skip117 +\/fbox/@border-top-right-radius-x=\skip118 +\/fbox/@border-bottom-left-radius-x=\skip119 +\/fbox/@border-bottom-right-radius-x=\skip120 +\/fbox/@border-top-left-radius-y=\skip121 +\/fbox/@border-top-right-radius-y=\skip122 +\/fbox/@border-bottom-left-radius-y=\skip123 +\/fbox/@border-bottom-right-radius-y=\skip124 +\/fbox/@border-top-left-ix=\skip125 +\/fbox/@border-top-left-iy=\skip126 +\/fbox/@border-top-right-ix=\skip127 +\/fbox/@border-top-right-iy=\skip128 +\/fbox/@border-bottom-left-ix=\skip129 +\/fbox/@border-bottom-left-iy=\skip130 +\/fbox/@border-bottom-right-ix=\skip131 +\/fbox/@border-bottom-right-iy=\skip132 +\/fbox/@border-top-left-phi=\skip133 +\/fbox/@border-top-right-phi=\skip134 +\/fbox/@border-bottom-left-phi=\skip135 +\/fbox/@border-bottom-right-phi=\skip136 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2016/03/03 v2.15a AMS math features +\@mathmargin=\skip137 +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2000/06/29 v2.01 AMS text +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen111 +)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen112 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 1999/12/14 v2.01 operator names +) +\inf@bad=\count98 +LaTeX Info: Redefining \frac on input line 199. +\uproot@=\count99 +\leftroot@=\count100 +LaTeX Info: Redefining \overline on input line 297. +\classnum@=\count101 +\DOTSCASE@=\count102 +LaTeX Info: Redefining \ldots on input line 394. +LaTeX Info: Redefining \dots on input line 397. +LaTeX Info: Redefining \cdots on input line 518. +\Mathstrutbox@=\box30 +\strutbox@=\box31 +\big@size=\dimen113 +LaTeX Font Info: Redeclaring font encoding OML on input line 630. +LaTeX Font Info: Redeclaring font encoding OMS on input line 631. +\macc@depth=\count103 +\c@MaxMatrixCols=\count104 +\dotsspace@=\muskip10 +\c@parentequation=\count105 +\dspbrk@lvl=\count106 +\tag@help=\toks19 +\row@=\count107 +\column@=\count108 +\maxfields@=\count109 +\andhelp@=\toks20 +\eqnshift@=\dimen114 +\alignsep@=\dimen115 +\tagshift@=\dimen116 +\tagwidth@=\dimen117 +\totwidth@=\dimen118 +\lineht@=\dimen119 +\@envbody=\toks21 +\multlinegap=\skip138 +\multlinetaggap=\skip139 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2735. +LaTeX Info: Redefining \] on input line 2736. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +) (/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/stmaryrd.sty +Package: stmaryrd 1994/03/03 St Mary's Road symbol package +\symstmry=\mathgroup6 +LaTeX Font Info: Overwriting symbol font `stmry' in version `bold' +(Font) U/stmry/m/n --> U/stmry/b/n on input line 89. +) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty +Package: textcomp 2005/09/27 v1.99g Standard LaTeX package +Package textcomp Info: Sub-encoding information: +(textcomp) 5 = only ISO-Adobe without \textcurrency +(textcomp) 4 = 5 + \texteuro +(textcomp) 3 = 4 + \textohm +(textcomp) 2 = 3 + \textestimated + \textcurrency +(textcomp) 1 = TS1 - \textcircled - \t +(textcomp) 0 = TS1 (full) +(textcomp) Font families with sub-encoding setting implement +(textcomp) only a restricted character set as indicated. +(textcomp) Family '?' is the default used for unknown fonts. +(textcomp) See the documentation for details. +Package textcomp Info: Setting ? sub-encoding to TS1/1 on input line 79. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +) +LaTeX Info: Redefining \oldstylenums on input line 334. +Package textcomp Info: Setting cmr sub-encoding to TS1/0 on input line 349. +Package textcomp Info: Setting cmss sub-encoding to TS1/0 on input line 350. +Package textcomp Info: Setting cmtt sub-encoding to TS1/0 on input line 351. +Package textcomp Info: Setting cmvtt sub-encoding to TS1/0 on input line 352. +Package textcomp Info: Setting cmbr sub-encoding to TS1/0 on input line 353. +Package textcomp Info: Setting cmtl sub-encoding to TS1/0 on input line 354. +Package textcomp Info: Setting ccr sub-encoding to TS1/0 on input line 355. +Package textcomp Info: Setting ptm sub-encoding to TS1/4 on input line 356. +Package textcomp Info: Setting pcr sub-encoding to TS1/4 on input line 357. +Package textcomp Info: Setting phv sub-encoding to TS1/4 on input line 358. +Package textcomp Info: Setting ppl sub-encoding to TS1/3 on input line 359. +Package textcomp Info: Setting pag sub-encoding to TS1/4 on input line 360. +Package textcomp Info: Setting pbk sub-encoding to TS1/4 on input line 361. +Package textcomp Info: Setting pnc sub-encoding to TS1/4 on input line 362. +Package textcomp Info: Setting pzc sub-encoding to TS1/4 on input line 363. +Package textcomp Info: Setting bch sub-encoding to TS1/4 on input line 364. +Package textcomp Info: Setting put sub-encoding to TS1/5 on input line 365. +Package textcomp Info: Setting uag sub-encoding to TS1/5 on input line 366. +Package textcomp Info: Setting ugq sub-encoding to TS1/5 on input line 367. +Package textcomp Info: Setting ul8 sub-encoding to TS1/4 on input line 368. +Package textcomp Info: Setting ul9 sub-encoding to TS1/4 on input line 369. +Package textcomp Info: Setting augie sub-encoding to TS1/5 on input line 370. +Package textcomp Info: Setting dayrom sub-encoding to TS1/3 on input line 371. +Package textcomp Info: Setting dayroms sub-encoding to TS1/3 on input line 372. +Package textcomp Info: Setting pxr sub-encoding to TS1/0 on input line 373. +Package textcomp Info: Setting pxss sub-encoding to TS1/0 on input line 374. +Package textcomp Info: Setting pxtt sub-encoding to TS1/0 on input line 375. +Package textcomp Info: Setting txr sub-encoding to TS1/0 on input line 376. +Package textcomp Info: Setting txss sub-encoding to TS1/0 on input line 377. +Package textcomp Info: Setting txtt sub-encoding to TS1/0 on input line 378. +Package textcomp Info: Setting lmr sub-encoding to TS1/0 on input line 379. +Package textcomp Info: Setting lmdh sub-encoding to TS1/0 on input line 380. +Package textcomp Info: Setting lmss sub-encoding to TS1/0 on input line 381. +Package textcomp Info: Setting lmssq sub-encoding to TS1/0 on input line 382. +Package textcomp Info: Setting lmvtt sub-encoding to TS1/0 on input line 383. +Package textcomp Info: Setting lmtt sub-encoding to TS1/0 on input line 384. +Package textcomp Info: Setting qhv sub-encoding to TS1/0 on input line 385. +Package textcomp Info: Setting qag sub-encoding to TS1/0 on input line 386. +Package textcomp Info: Setting qbk sub-encoding to TS1/0 on input line 387. +Package textcomp Info: Setting qcr sub-encoding to TS1/0 on input line 388. +Package textcomp Info: Setting qcs sub-encoding to TS1/0 on input line 389. +Package textcomp Info: Setting qpl sub-encoding to TS1/0 on input line 390. +Package textcomp Info: Setting qtm sub-encoding to TS1/0 on input line 391. +Package textcomp Info: Setting qzc sub-encoding to TS1/0 on input line 392. +Package textcomp Info: Setting qhvc sub-encoding to TS1/0 on input line 393. +Package textcomp Info: Setting futs sub-encoding to TS1/4 on input line 394. +Package textcomp Info: Setting futx sub-encoding to TS1/4 on input line 395. +Package textcomp Info: Setting futj sub-encoding to TS1/4 on input line 396. +Package textcomp Info: Setting hlh sub-encoding to TS1/3 on input line 397. +Package textcomp Info: Setting hls sub-encoding to TS1/3 on input line 398. +Package textcomp Info: Setting hlst sub-encoding to TS1/3 on input line 399. +Package textcomp Info: Setting hlct sub-encoding to TS1/5 on input line 400. +Package textcomp Info: Setting hlx sub-encoding to TS1/5 on input line 401. +Package textcomp Info: Setting hlce sub-encoding to TS1/5 on input line 402. +Package textcomp Info: Setting hlcn sub-encoding to TS1/5 on input line 403. +Package textcomp Info: Setting hlcw sub-encoding to TS1/5 on input line 404. +Package textcomp Info: Setting hlcf sub-encoding to TS1/5 on input line 405. +Package textcomp Info: Setting pplx sub-encoding to TS1/3 on input line 406. +Package textcomp Info: Setting pplj sub-encoding to TS1/3 on input line 407. +Package textcomp Info: Setting ptmx sub-encoding to TS1/4 on input line 408. +Package textcomp Info: Setting ptmj sub-encoding to TS1/4 on input line 409. +) (/usr/share/texlive/texmf-dist/tex/latex/psnfss/pifont.sty +Package: pifont 2005/04/12 PSNFSS-v9.2a Pi font support (SPQR) +LaTeX Font Info: Try loading font information for U+pzd on input line 63. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upzd.fd +File: upzd.fd 2001/06/04 font definitions for U/pzd. +) +LaTeX Font Info: Try loading font information for U+psy on input line 64. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upsy.fd +File: upsy.fd 2001/06/04 font definitions for U/psy. +)) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2012/11/06 v6.83m Hypertext links for LaTeX +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO) +Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO) +Package hobsub Info: Skipping package `infwarerr' (already loaded). +Package hobsub Info: Skipping package `ltxcmds' (already loaded). +Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO) +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is not detected. +Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) +Package etexcmds Info: Could not find \expanded. +(etexcmds) That can mean that you are not using pdfTeX 1.50 or +(etexcmds) that some package has redefined \expanded. +(etexcmds) In the latter case, load this package earlier. +Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) +Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO) +Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: pdfTeX >= 1.30 not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode not found. +Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO) +Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO) +Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO) +Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO) +Package: xcolor-patch 2011/01/30 xcolor patch +Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO) +Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO) +Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO) +Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2011/03/04 v1.3 Hooks for auxiliary files (HO) +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) +) +\@linkdim=\dimen120 +\Hy@linkcounter=\count110 +\Hy@pagecounter=\count111 +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count112 +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Hyper figures OFF on input line 4443. +Package hyperref Info: Link nesting OFF on input line 4448. +Package hyperref Info: Hyper index ON on input line 4451. +Package hyperref Info: Plain pages OFF on input line 4458. +Package hyperref Info: Backreferencing OFF on input line 4463. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4688. +\c@Hy@tempcnt=\count113 +(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip11 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 5041. +\XeTeXLinkMargin=\dimen121 +\Fld@menulength=\count114 +\Field@Width=\dimen122 +\Fld@charsize=\dimen123 +Package hyperref Info: Hyper figures OFF on input line 6295. +Package hyperref Info: Link nesting OFF on input line 6300. +Package hyperref Info: Hyper index ON on input line 6303. +Package hyperref Info: backreferencing OFF on input line 6310. +Package hyperref Info: Link coloring OFF on input line 6315. +Package hyperref Info: Link coloring with OCG OFF on input line 6320. +Package hyperref Info: PDF/A mode OFF on input line 6325. +LaTeX Info: Redefining \ref on input line 6365. +LaTeX Info: Redefining \pageref on input line 6369. +\Hy@abspage=\count115 +\c@Item=\count116 +\c@Hfootnote=\count117 +) + +Package hyperref Message: Driver (autodetected): hxetex. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hxetex.def +File: hxetex.def 2012/11/06 v6.83m Hyperref driver for XeTeX +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def +File: puenc.def 2012/11/06 v6.83m Hyperref: PDF Unicode definition (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/stringenc.sty +Package: stringenc 2011/12/02 v1.10 Convert strings between diff. encodings (HO) +) +\pdfm@box=\box32 +\c@Hy@AnnotLevel=\count118 +\HyField@AnnotCount=\count119 +\Fld@listcount=\count120 +\c@bookmark@seq@number=\count121 +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO) +Package rerunfilecheck Info: Feature \pdfmdfivesum is not available +(rerunfilecheck) (e.g. pdfTeX or LuaTeX with package `pdftexcmds'). +(rerunfilecheck) Therefore file contents cannot be checked efficiently +(rerunfilecheck) and the loading of the package is aborted. +) +\Hy@SectionHShift=\skip140 +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bookmark.sty +Package: bookmark 2011/12/02 v1.24 PDF bookmarks (HO) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bkm-dvipdfm.def +File: bkm-dvipdfm.def 2011/12/02 v1.24 bookmark driver for dvipdfm (HO) +\BKM@id=\count122 +)) (/usr/share/texlive/texmf-dist/tex/latex/booktabs/booktabs.sty +Package: booktabs 2005/04/14 v1.61803 publication quality tables +\heavyrulewidth=\dimen124 +\lightrulewidth=\dimen125 +\cmidrulewidth=\dimen126 +\belowrulesep=\dimen127 +\belowbottomsep=\dimen128 +\aboverulesep=\dimen129 +\abovetopsep=\dimen130 +\cmidrulesep=\dimen131 +\cmidrulekern=\dimen132 +\defaultaddspace=\dimen133 +\@cmidla=\count123 +\@cmidlb=\count124 +\@aboverulesep=\dimen134 +\@belowrulesep=\dimen135 +\@thisruleclass=\count125 +\@lastruleclass=\count126 +\@thisrulewidth=\dimen136 +) (/usr/share/texlive/texmf-dist/tex/latex/tools/longtable.sty +Package: longtable 2014/10/28 v4.11 Multi-page Table package (DPC) +\LTleft=\skip141 +\LTright=\skip142 +\LTpre=\skip143 +\LTpost=\skip144 +\LTchunksize=\count127 +\LTcapwidth=\dimen137 +\LT@head=\box33 +\LT@firsthead=\box34 +\LT@foot=\box35 +\LT@lastfoot=\box36 +\LT@cols=\count128 +\LT@rows=\count129 +\c@LT@tables=\count130 +\c@LT@chunks=\count131 +\LT@p@ftn=\toks23 +) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Package: anyfontsize 2007/11/22 anyfontsize.sty by pts +) (/usr/share/texlive/texmf-dist/tex/latex/enumitem/enumitem.sty +Package: enumitem 2011/09/28 v3.5.2 Customized lists +\labelindent=\skip145 +\enit@outerparindent=\dimen138 +\enit@toks=\toks24 +\enit@inbox=\box37 +\enitdp@description=\count132 +) (/usr/share/texlive/texmf-dist/tex/latex/wrapfig/wrapfig.sty +\wrapoverhang=\dimen139 +\WF@size=\dimen140 +\c@WF@wrappedlines=\count133 +\WF@box=\box38 +\WF@everypar=\toks25 +Package: wrapfig 2003/01/31 v 3.6 +) (/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.sty (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty +Package: expl3 2016/01/19 v6377 L3 programming layer (loader) +(/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3-code.tex +Package: expl3 2016/01/19 v6377 L3 programming layer (code) +L3 Module: l3bootstrap 2016/01/01 v6339 L3 Bootstrap code +L3 Module: l3names 2015/12/21 v6328 L3 Namespace for primitives +L3 Module: l3basics 2015/11/22 v6315 L3 Basic definitions +L3 Module: l3expan 2015/09/10 v5983 L3 Argument expansion +L3 Module: l3tl 2015/09/29 v6121 L3 Token lists +L3 Module: l3str 2016/01/03 v6357 L3 Strings +L3 Module: l3seq 2015/08/05 v5777 L3 Sequences and stacks +L3 Module: l3int 2016/01/05 v6366 L3 Integers +\c_max_int=\count134 +\l_tmpa_int=\count135 +\l_tmpb_int=\count136 +\g_tmpa_int=\count137 +\g_tmpb_int=\count138 +L3 Module: l3quark 2015/08/17 v5855 L3 Quarks +L3 Module: l3prg 2015/11/01 v6216 L3 Control structures +\g__prg_map_int=\count139 +L3 Module: l3clist 2015/09/02 v5901 L3 Comma separated lists +L3 Module: l3token 2015/11/11 v6249 L3 Experimental token manipulation +L3 Module: l3prop 2016/01/05 v6366 L3 Property lists +L3 Module: l3msg 2015/09/28 v6113 L3 Messages +L3 Module: l3file 2015/12/03 v6317 L3 File and I/O operations +\l_iow_line_count_int=\count140 +\l__iow_target_count_int=\count141 +\l__iow_current_line_int=\count142 +\l__iow_current_word_int=\count143 +\l__iow_current_indentation_int=\count144 +L3 Module: l3skip 2016/01/05 v6366 L3 Dimensions and skips +\c_zero_dim=\dimen141 +\c_max_dim=\dimen142 +\l_tmpa_dim=\dimen143 +\l_tmpb_dim=\dimen144 +\g_tmpa_dim=\dimen145 +\g_tmpb_dim=\dimen146 +\c_zero_skip=\skip146 +\c_max_skip=\skip147 +\l_tmpa_skip=\skip148 +\l_tmpb_skip=\skip149 +\g_tmpa_skip=\skip150 +\g_tmpb_skip=\skip151 +\c_zero_muskip=\muskip12 +\c_max_muskip=\muskip13 +\l_tmpa_muskip=\muskip14 +\l_tmpb_muskip=\muskip15 +\g_tmpa_muskip=\muskip16 +\g_tmpb_muskip=\muskip17 +L3 Module: l3keys 2015/11/17 v6284 L3 Key-value interfaces +\g__keyval_level_int=\count145 +\l_keys_choice_int=\count146 +L3 Module: l3fp 2015/08/25 v5890 L3 Floating points +\c__fp_leading_shift_int=\count147 +\c__fp_middle_shift_int=\count148 +\c__fp_trailing_shift_int=\count149 +\c__fp_big_leading_shift_int=\count150 +\c__fp_big_middle_shift_int=\count151 +\c__fp_big_trailing_shift_int=\count152 +\c__fp_Bigg_leading_shift_int=\count153 +\c__fp_Bigg_middle_shift_int=\count154 +\c__fp_Bigg_trailing_shift_int=\count155 +L3 Module: l3box 2015/08/09 v5822 L3 Experimental boxes +\c_empty_box=\box39 +\l_tmpa_box=\box40 +\l_tmpb_box=\box41 +\g_tmpa_box=\box42 +\g_tmpb_box=\box43 +L3 Module: l3coffins 2015/08/06 v5789 L3 Coffin code layer +\l__coffin_internal_box=\box44 +\l__coffin_internal_dim=\dimen147 +\l__coffin_offset_x_dim=\dimen148 +\l__coffin_offset_y_dim=\dimen149 +\l__coffin_x_dim=\dimen150 +\l__coffin_y_dim=\dimen151 +\l__coffin_x_prime_dim=\dimen152 +\l__coffin_y_prime_dim=\dimen153 +\c_empty_coffin=\box45 +\l__coffin_aligned_coffin=\box46 +\l__coffin_aligned_internal_coffin=\box47 +\l_tmpa_coffin=\box48 +\l_tmpb_coffin=\box49 +\l__coffin_display_coffin=\box50 +\l__coffin_display_coord_coffin=\box51 +\l__coffin_display_pole_coffin=\box52 +\l__coffin_display_offset_dim=\dimen154 +\l__coffin_display_x_dim=\dimen155 +\l__coffin_display_y_dim=\dimen156 +L3 Module: l3color 2014/08/23 v5354 L3 Experimental color support +L3 Module: l3sys 2015/09/25 v6087 L3 Experimental system/runtime functions +L3 Module: l3candidates 2016/01/14 v6376 L3 Experimental additions to l3kernel +\l__box_top_dim=\dimen157 +\l__box_bottom_dim=\dimen158 +\l__box_left_dim=\dimen159 +\l__box_right_dim=\dimen160 +\l__box_top_new_dim=\dimen161 +\l__box_bottom_new_dim=\dimen162 +\l__box_left_new_dim=\dimen163 +\l__box_right_new_dim=\dimen164 +\l__box_internal_box=\box53 +\l__coffin_bounding_shift_dim=\dimen165 +\l__coffin_left_corner_dim=\dimen166 +\l__coffin_right_corner_dim=\dimen167 +\l__coffin_bottom_corner_dim=\dimen168 +\l__coffin_top_corner_dim=\dimen169 +\l__coffin_scaled_total_height_dim=\dimen170 +\l__coffin_scaled_width_dim=\dimen171 +L3 Module: l3luatex 2015/11/11 v6250 L3 Experimental LuaTeX-specific functions +) (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def +File: l3xdvidpfmx.def 2015/11/11 v6250 L3 Experimental driver: xdvipdfmx +)) (/usr/share/texlive/texmf-dist/tex/latex/l3packages/xparse/xparse.sty +Package: xparse 2016/01/19 v6377 L3 Experimental document command parser +\l__xparse_current_arg_int=\count156 +\l__xparse_m_args_int=\count157 +\l__xparse_mandatory_args_int=\count158 +\l__xparse_processor_int=\count159 +\l__xparse_v_nesting_int=\count160 +) +Package: fontspec 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec-xetex.sty +Package: fontspec-xetex 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +\l_fontspec_script_int=\count161 +\l_fontspec_language_int=\count162 +\l_fontspec_strnum_int=\count163 +\l__fontspec_tmpa_dim=\dimen172 +\l__fontspec_tmpb_dim=\dimen173 +\l__fontspec_tmpc_dim=\dimen174 +\g__file_internal_ior=\read1 +(/usr/share/texlive/texmf-dist/tex/latex/base/fontenc.sty +Package: fontenc 2005/09/27 v1.99g Standard LaTeX package +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1enc.def +File: eu1enc.def 2010/05/27 v0.1h Experimental Unicode font encodings +) +LaTeX Font Info: Try loading font information for EU1+lmr on input line 105. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmr.fd +File: eu1lmr.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) (/usr/share/texlive/texmf-dist/tex/xelatex/xunicode/xunicode.sty +File: xunicode.sty 2011/09/09 v0.981 provides access to latin accents and many other characters in Unicode lower plane +(/usr/share/texmf/tex/latex/tipa/t3enc.def +File: t3enc.def 2001/12/31 T3 encoding +LaTeX Font Info: Try loading font information for EU1+lmss on input line 357. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmss.fd +File: eu1lmss.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) +\tipaTiiicode=\count164 +\tipasavetokens=\toks26 +\tipachecktokens=\toks27 +) +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \__fontspec_post_arg:w with sig. 'mmO{}' on line 353. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \fontspec with sig. 'om' on line 355. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmainfont with sig. 'om' on line 365. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setsansfont with sig. 'om' on line 375. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmonofont with sig. 'om' on line 385. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathrm with sig. 'om' on line 399. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setboldmathrm with sig. 'om' on line 407. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathsf with sig. 'om' on line 415. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathtt with sig. 'om' on line 423. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfamily with sig. 'mom' on line 437. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontface with sig. 'mom' on line 453. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \defaultfontfeatures with sig. 't+om' on line 467. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \addfontfeatures with sig. 'm' on line 529. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfeature with sig. 'mm' on line 540. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newAATfeature with sig. 'mmmm' on line 548. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newopentypefeature with sig. 'mmm' on line 556. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeature with sig. 'mm' on line 577. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeatureoption with sig. 'mmm' on line 586. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontscript with sig. 'mm' on line 590. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontlanguage with sig. 'mm' on line 594. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \DeclareFontsExtensions with sig. 'm' on line 599. +................................................. +\l__fontspec_tmp_int=\count165 +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.cfg) +LaTeX Info: Redefining \itshape on input line 2705. +LaTeX Info: Redefining \slshape on input line 2710. +LaTeX Info: Redefining \scshape on input line 2715. +LaTeX Info: Redefining \upshape on input line 2720. +\l__fontspec_em_int=\count166 +\l__fontspec_emdef_int=\count167 +LaTeX Info: Redefining \em on input line 2736. +LaTeX Info: Redefining \emph on input line 2742. +LaTeX Info: Redefining \- on input line 2746. +................................................. +. LaTeX info: "xparse/redefine-command" +. +. Redefining command \oldstylenums with sig. 'm' on line 2841. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \liningnums with sig. 'm' on line 2845. +................................................. +)) +Package hyperref Info: Option `colorlinks' set `true' on input line 87. +\px=\skip152 +\c@md@targetcount=\count168 +\mdcompactskip=\skip153 +\mdcompacttopsep=\skip154 +\dim@rem=\skip155 +\dim@ch=\skip156 +\md@height=\skip157 +\dim@marginbottom=\skip158 +\dim@paddingbottom=\skip159 +\md@interaction=\count169 +\mddefinitionsskip=\skip160 +\md@captionlen=\skip161 +\mdtoclevel=\count170 +\c@mdtoclevelbold=\count171 +\c@mdtocleveldots=\count172 +\mdtocskip=\skip162 +\mdpreskip=\skip163 +\presp=\skip164 +LaTeX Font Info: Try loading font information for EU1+lmtt on input line 801. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmtt.fd +File: eu1lmtt.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +\md@postskip=\skip165 +\ppresp=\skip166 +\md@thmcaption=\box54 +\md@defaultcolwidth=\skip167 +\mdtabularskip=\skip168 +\mdbibindentunit=\skip169 +\c@md@authorcount=\count173 +\c@mdx@authorcount=\count174 +\c@@mdTargetCount=\count175 +\@snippetBox=\box55 +\@snippetWidth=\skip170 +\@snippetHeight=\skip171 +\@snippetDepth=\skip172 +\c@snippets=\count176 +) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty +Package: geometry 2010/09/12 v5.6 Page Geometry +\Gm@cnth=\count177 +\Gm@cntv=\count178 +\c@Gm@tempcnt=\count179 +\Gm@bindingoffset=\dimen175 +\Gm@wd@mp=\dimen176 +\Gm@odd@mp=\dimen177 +\Gm@even@mp=\dimen178 +\Gm@layoutwidth=\dimen179 +\Gm@layoutheight=\dimen180 +\Gm@layouthoffset=\dimen181 +\Gm@layoutvoffset=\dimen182 +\Gm@dimlist=\toks28 +) (/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +\fancy@headwidth=\skip173 +\f@ncyO@elh=\skip174 +\f@ncyO@erh=\skip175 +\f@ncyO@olh=\skip176 +\f@ncyO@orh=\skip177 +\f@ncyO@elf=\skip178 +\f@ncyO@erf=\skip179 +\f@ncyO@olf=\skip180 +\f@ncyO@orf=\skip181 +) (build/P4Runtime-Spec.aux + +LaTeX Warning: Label `sec-example' multiply defined. + +) +\openout1 = `P4Runtime-Spec.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for TS1+cmr on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1cmr.fd +File: ts1cmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions +) +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for EU1/lmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T3/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for T3+cmr on input line 14. +(/usr/share/texmf/tex/latex/tipa/t3cmr.fd +File: t3cmr.fd 2001/12/31 TIPA font definitions +) +LaTeX Font Info: ... okay on input line 14. +\AtBeginShipoutBox=\box56 +Package hyperref Info: Link coloring ON on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2012/10/27 v2.43 Cross-referencing by name of section +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO) +) +\c@section@level=\count180 +) +LaTeX Info: Redefining \ref on input line 14. +LaTeX Info: Redefining \pageref on input line 14. +LaTeX Info: Redefining \nameref on input line 14. +................................................. +. fontspec info: "setup-math" +. +. Adjusting the maths setup (use [no-math] to avoid this). +................................................. +\symlegacymaths=\mathgroup7 +LaTeX Font Info: Overwriting symbol font `legacymaths' in version `bold' +(Font) OT1/cmr/m/n --> OT1/cmr/bx/n on input line 14. +LaTeX Font Info: Redeclaring math accent \acute on input line 14. +LaTeX Font Info: Redeclaring math accent \grave on input line 14. +LaTeX Font Info: Redeclaring math accent \ddot on input line 14. +LaTeX Font Info: Redeclaring math accent \tilde on input line 14. +LaTeX Font Info: Redeclaring math accent \bar on input line 14. +LaTeX Font Info: Redeclaring math accent \breve on input line 14. +LaTeX Font Info: Redeclaring math accent \check on input line 14. +LaTeX Font Info: Redeclaring math accent \hat on input line 14. +LaTeX Font Info: Redeclaring math accent \dot on input line 14. +LaTeX Font Info: Redeclaring math accent \mathring on input line 14. +LaTeX Font Info: Redeclaring math symbol \Gamma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Delta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Theta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Lambda on input line 14. +LaTeX Font Info: Redeclaring math symbol \Xi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Pi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Sigma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Upsilon on input line 14. +LaTeX Font Info: Redeclaring math symbol \Phi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Psi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Omega on input line 14. +LaTeX Font Info: Redeclaring math symbol \mathdollar on input line 14. +LaTeX Font Info: Redeclaring symbol font `operators' on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `normal' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/cmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `bold' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/cmr/bx/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) EU1/lmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/cmr/m/it --> EU1/lmr/m/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/cmr/bx/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/cmss/m/n --> EU1/lmss/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/cmtt/m/n --> EU1/lmtt/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) EU1/lmr/m/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' +(Font) OT1/cmr/bx/it --> EU1/lmr/bx/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/cmss/bx/n --> EU1/lmss/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/cmtt/m/n --> EU1/lmtt/bx/n on input line 14. +*geometry* driver: auto-detecting +*geometry* detected driver: xetex +*geometry* verbose mode - [ preamble ] result: +* driver: xetex +* paper: +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: +* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt) +* v-part:(T,H,B)=(72.26999pt, 632.3625pt, 90.3375pt) +* \paperwidth=614.295pt +* \paperheight=794.96999pt +* \textwidth=469.75502pt +* \textheight=632.3625pt +* \oddsidemargin=0.0pt +* \evensidemargin=0.0pt +* \topmargin=-37.0pt +* \headheight=30.0pt +* \headsep=25.0pt +* \topskip=11.0pt +* \footskip=30.0pt +* \marginparwidth=59.0pt +* \marginparsep=10.0pt +* \columnsep=10.0pt +* \skip\footins=10.0pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +resolve font stack: UtopiaStd-Regular + +\g__fontspec_family_UtopiaStd-Regular_int=\count181 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'UtopiaStd-Regular(0)' created for font 'UtopiaStd-Regular' with +. options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;" +. - 'small caps' (m/sc) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;+smcp;" +................................................. + +resolved font stack 'UtopiaStd-Regular' to: UtopiaStd-Regular +LaTeX Font Info: Try loading font information for U+msa on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Try loading font information for U+msb on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Try loading font information for U+stmry on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/Ustmry.fd) + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/bx/n' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 35. + +resolve font stack: LuxiMono + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +\g__fontspec_family_LuxiMono_int=\count182 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'LuxiMono(0)' created for font 'LuxiMono' with options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: <->"LuxiMono/OT:" +. - 'small caps' (m/sc) with NFSS spec.: +................................................. + +resolved font stack 'LuxiMono' to: LuxiMono +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/se-ascii-print.def +File: se-ascii-print.def 2011/12/02 v1.10 stringenc: Printable ASCII characters +) [1 + +] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[2] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <10.95> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 299. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Font Warning: Font shape `EU1/LuxiMono(0)/bx/n' undefined +(Font) using `EU1/LuxiMono(0)/m/n' instead on input line 299. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[3] + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/m/it' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 509. + +[4] [5] [6] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[7] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/reference-architecture.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[8] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[9] +File: build/single-embedded-controller.png Graphic file (type QTm) + [10] +File: build/single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-controllers.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-ha-controllers.png Graphic file (type QTm) + [11] [12] [13] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[14] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[15] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <12> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 1493. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1493. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[16] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[17] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (53.84203pt too wide) in paragraph at lines 1790--1793 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For all slave controllers, \EU1/LuxiMono(0)/bx/n/8.2125 status \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set to non-OK (with \EU1/LuxiMono(0)/bx/n/8.2125 status.code \EU1/UtopiaStd-Regular(0)/m/it/10.95 set to \EU1/LuxiMono(0)/bx/n/8.2125 google.rpc.ALREADY_EXISTS\EU1/UtopiaStd-Regular(0)/m/it/10.95 ). + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[18] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1827. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1851. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[19] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1895. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[20] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[21] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[22] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2178. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[23] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2233. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[24] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[25] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[26] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (12.45624pt too wide) in paragraph at lines 2464--2477 + [] + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2500. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[27] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[28] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2691. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2751. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[29] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2824. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[30] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2905. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.59204pt too wide) in paragraph at lines 2959--2961 +[]\EU1/LuxiMono(0)/bx/n/8.2125 BYTES\EU1/UtopiaStd-Regular(0)/m/it/10.95 , which signifies that this meter can be configured with rates expressed in bytes/second. + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2984. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[31] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (18.74199pt too wide) in paragraph at lines 3001--3008 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 carrying P4 standard annotations \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_in") \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_out")\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[32] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3143. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[33] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[34] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[35] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3371. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3418. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[36] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3456. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[37] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[38] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[39] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[40] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[41] [42] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1629) in paragraph at lines 4060--4062 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For example, the following P4$[]$ objects involve complex types that need to be exposed in + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[43] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1454) in paragraph at lines 4108--4117 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 ification for all the named types in the P4$[]$ program. These named types are \EU1/LuxiMono(0)/bx/n/8.2125 struct\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 header\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + + +Underfull \hbox (badness 1831) in paragraph at lines 4108--4117 +\EU1/LuxiMono(0)/bx/n/8.2125 header_union\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 enum \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 serializable_enum\EU1/UtopiaStd-Regular(0)/m/it/10.95 ; for each of these we have a type specification mes- + [] + + +Underfull \hbox (badness 1845) in paragraph at lines 4108--4117 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 sage, respectively \EU1/LuxiMono(0)/bx/n/8.2125 P4StructTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnionTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4EnumTypeSpec \EU1/UtopiaStd-Regular(0)/m/it/10.95 and + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (33.06564pt too wide) in paragraph at lines 4143--4150 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 “binary string” types (\EU1/LuxiMono(0)/bx/n/8.2125 bit\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 int\EU1/UtopiaStd-Regular(0)/m/it/10.95 , and \EU1/LuxiMono(0)/bx/n/8.2125 varbit\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) are grouped together in the \EU1/LuxiMono(0)/bx/n/8.2125 P4BitstringLikeTypeSpec + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4160. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[44] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.46094pt too wide) in paragraph at lines 4197--4200 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 An invalid header union (i.e. all headers in the union are invalid) is represented by a \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnion + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[45] [46] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4334. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[47] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (24.68944pt too wide) in paragraph at lines 4422--4428 +[]\EU1/LuxiMono(0)/bx/n/8.2125 translated_type\EU1/UtopiaStd-Regular(0)/m/it/10.95 , if and only if the P4 \EU1/LuxiMono(0)/bx/n/8.2125 type \EU1/UtopiaStd-Regular(0)/m/it/10.95 declaration was annotated with \EU1/LuxiMono(0)/bx/n/8.2125 @p4runtime_translation\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[48] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[49] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (32.59732pt too wide) in paragraph at lines 4530--4536 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 in \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.MatchField\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.Action.Param \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.ControllerPacketMetadata.Metadata\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[50] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4637. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[51] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[52] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[53] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[54] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.53593pt too wide) in paragraph at lines 5093--5096 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 If the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 does not match the table description in the P4Info (e.g. the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 is \EU1/LuxiMono(0)/bx/n/8.2125 action_profile_member_id + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[55] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[56] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[57] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[58] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[59] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[60] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5666. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[61] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[62] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[63] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (9.29865pt too wide) in paragraph at lines 5949--5951 + []\EU1/lmr/bx/n/10.95 9.2.2.1.| Rules on Setting \EU1/LuxiMono(0)/bx/n/8.2125 max_size[] \EU1/UtopiaStd-Regular(0)/m/it/10.95 The valid values for \EU1/LuxiMono(0)/bx/n/8.2125 max_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 depend on the static \EU1/LuxiMono(0)/bx/n/8.2125 max_group_size + [] + +[64] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[65] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[66] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[67] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6237. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6277. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1331) in paragraph at lines 6280--6287 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 A direct counter is a direct resource associated with a \EU1/LuxiMono(0)/bx/n/8.2125 TableEntry \EU1/UtopiaStd-Regular(0)/m/it/10.95 (see [][]Direct Resources[][]). The + [] + +[68] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6354. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[69] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6447. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6478. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[70] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6555. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 6596. + + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 6596. + +[71] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6651. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6661. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[72] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[73] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6785. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[74] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.93839pt too wide) in paragraph at lines 6896--6898 +[]\EU1/LuxiMono(0)/bx/n/8.2125 MODIFY\EU1/UtopiaStd-Regular(0)/m/it/10.95 : Modify the attributes of a given clone session entry, indexed by the given \EU1/LuxiMono(0)/bx/n/8.2125 clone_session_id\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[75] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6934. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[76] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7070. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[77] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7114. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[78] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[79] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7312. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[80] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/error-report.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[81] +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <14.4> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 7436. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7436. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: Hyper reference `wildcard-reads' on page 82 undefined on input line 7458. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[82] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7538. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[83] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[84] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[85] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (34.34796pt too wide) in paragraph at lines 7822--7827 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If an error is encountered before even trying to attempt individual batch updates, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.66206pt too wide) in paragraph at lines 7831--7842 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 Otherwise, if one or more updates in the batch (\EU1/LuxiMono(0)/bx/n/8.2125 WriteRequest.updates\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) failed, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[86] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7878. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[87] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[88] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.4752pt too wide) in paragraph at lines 8107--8111 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 responding to \EU1/LuxiMono(0)/bx/n/8.2125 a \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 c\EU1/UtopiaStd-Regular(0)/m/it/10.95 , followed by a status \EU1/LuxiMono(0)/bx/n/8.2125 {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[89] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8193. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[90] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8316. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[91] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 8414--8417 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If a P4Runtime server supports both \EU1/LuxiMono(0)/bx/n/8.2125 SetForwardingPipelineConfig \EU1/UtopiaStd-Regular(0)/m/it/10.95 as well as returning the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[92] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[93] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[94] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[95] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[96] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8777. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[97] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8845. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/psa-metadata-translation.png Graphic file (type QTm) + [98] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[99] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[100] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[101] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[102] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[103] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 9355--9362 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 p4info-ext should include a Protobuf message definition for every extern type that can + [] + +[104] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 4036) in paragraph at lines 9410--9417 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 P4Runtime also supports streaming arbitrary Protobuf messages between the server and the + [] + + +Underfull \hbox (badness 1629) in paragraph at lines 9410--9417 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 client, by including an \EU1/LuxiMono(0)/bx/n/8.2125 Any \EU1/UtopiaStd-Regular(0)/m/it/10.95 Protobuf field [[][]31[][]] named \EU1/LuxiMono(0)/bx/n/8.2125 other \EU1/UtopiaStd-Regular(0)/m/it/10.95 in both \EU1/LuxiMono(0)/bx/n/8.2125 p4.v1.StreamMessageRequest + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[105] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[106] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1997) in paragraph at lines 9656--9658 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 Table [][]7[][] lists P4$[]$ annotations introduced primarily for the purpose of adding features for the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[107] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[108] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[109] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.61781pt too wide) in paragraph at lines 9803--9810 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 In gRPC, the status of a RPC request is sent as metadata, whose size is limited by the \EU1/LuxiMono(0)/bx/n/8.2125 grpc.max_metadata_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[110] +Underfull \hbox (badness 10000) in paragraph at lines 9894--9895 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Complex Types in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- p4- + [] + + +Underfull \hbox (badness 4001) in paragraph at lines 9906--9907 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Google Cloud APIs Versioning - Backwards-Compatibility.” [][]\EU1/lmtt/m/n/10.95 https:// cloud. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9915--9916 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “gRPC Streaming RPCs in C++.” [][]\EU1/lmtt/m/n/10.95 https:// grpc. io/ docs/ tutorials/ basic/ c. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9927--9928 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “P4 Concurrency Model.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9930--9931 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9945--9946 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Protobuf OneOf Backwards-Compatibility Issues.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + +[111] +Underfull \hbox (badness 10000) in paragraph at lines 9951--9952 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Action Selector.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# sec- action- + [] + + +Underfull \hbox (badness 2409) in paragraph at lines 9960--9961 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Empty Group Action Appendix.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9963--9964 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Select Expressions in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 1668) in paragraph at lines 9978--9979 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Any Protobuf Message.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ protocol- buffers/ docs/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9984--9985 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC C++ Error Details Library.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ grpc/ grpc/ blob/ master/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9987--9988 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC Canonical Status Codes.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ maps- booking/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9993--9994 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Protobuf MessageDifferencer in the C++ API.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9999--10000 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “v1model Architecture Definition.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ p4lang/ p4c/ blob/ master/ + [] + +[112] +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 10008. +[113] +Package atveryend Info: Empty hook `AfterLastShipout' on input line 10008. +(build/P4Runtime-Spec.aux) +Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 10008. +Package atveryend Info: Empty hook `AtEndAfterFileList' on input line 10008. + +LaTeX Font Warning: Some font shapes were not available, defaults substituted. + + +LaTeX Warning: There were undefined references. + + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 27547 strings out of 493638 + 517856 string characters out of 6146796 + 566451 words of memory out of 5000000 + 30649 multiletter control sequences out of 15000+600000 + 14633 words of font info for 98 fonts, out of 8000000 for 9000 + 1328 hyphenation exceptions out of 8191 + 48i,19n,81p,10429b,902s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on build/P4Runtime-Spec.pdf (113 pages). diff --git a/spec/v1.2.0-rc.2/P4Runtime-Spec.pdf b/spec/v1.2.0-rc.2/P4Runtime-Spec.pdf new file mode 100644 index 00000000..52fb9646 Binary files /dev/null and b/spec/v1.2.0-rc.2/P4Runtime-Spec.pdf differ diff --git a/spec/v1.2.0-rc.2/P4Runtime-Spec.tex b/spec/v1.2.0-rc.2/P4Runtime-Spec.tex new file mode 100644 index 00000000..7a935123 --- /dev/null +++ b/spec/v1.2.0-rc.2/P4Runtime-Spec.tex @@ -0,0 +1,10008 @@ +\documentclass[11pt]{article} +% generated by Madoko, version 1.1.4 +%mdk-data-line={1} + + +\usepackage[heading-base={2},section-num={False},bib-label={hide},fontspec={True}]{madoko2} +\usepackage[top=1in, bottom=1.25in, left=1in, right=1in]{geometry} +\usepackage{fancyhdr} +%mdk-data-line={11} + + \setlength{\headheight}{30pt} + \setlength{\emergencystretch}{2em} + +\begin{document} + + + +{\mdfontfamily{UtopiaStd-Regular} +%mdk-data-line={203} +\mdxtitleblockstart{} +%mdk-data-line={203} +\mdxtitle{{\sffamily{\bfseries\mdline{203}P4Runtime Specification}}}%mdk + +%mdk-data-line={206} +\mdxtitlenote{{\sffamily{\bfseries\mdline{206}version 1.2.0-rc.1}}}%mdk +\mdxauthorstart{} +%mdk-data-line={211} +\mdxauthorname{\mdline{211}The P4.org API Working Group}%mdk +\mdxauthorend +%mdk-data-line={220} +\mdxtitlefooter{{\sffamily{\bfseries\mdline{220}2020-06-23}}}%mdk +\mdtitleauthorrunning{}{}\mdxtitleblockend%mdk + +%mdk-data-line={205} +\begin{abstract}%mdk + +%mdk-data-line={206} +\noindent\mdline{206}P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.%mdk +%mdk +\end{abstract}%mdk +\mdline{214} +\begin{mdtoc}%mdk + +\section*{Contents}\label{sec-contents}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-introduction-and-scope}{\mdref{sec-introduction-and-scope}{1.\hspace*{0.5em}Introduction and Scope}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-language-version-applicability}{\mdref{sec-p4-language-version-applicability}{1.1.\hspace*{0.5em}P4 Language Version Applicability}}%mdk + +\mdtocitemx{sec-in-scope}{\mdref{sec-in-scope}{1.2.\hspace*{0.5em}In Scope}}%mdk + +\mdtocitemx{sec-not-in-scope}{\mdref{sec-not-in-scope}{1.3.\hspace*{0.5em}Not In Scope}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-terms-and-definitions}{\mdref{sec-terms-and-definitions}{2.\hspace*{0.5em}Terms and Definitions}}%mdk + +\mdtocitemx{sec-reference-architecture}{\mdref{sec-reference-architecture}{3.\hspace*{0.5em}Reference Architecture}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-idealized-workflow}{\mdref{sec-idealized-workflow}{3.1.\hspace*{0.5em}Idealized Workflow}}%mdk + +\mdtocitemx{sec-p4-as-behavioral-description-language}{\mdref{sec-p4-as-behavioral-description-language}{3.2.\hspace*{0.5em}P4 as a Behavioral Description Language}}%mdk + +\mdtocitemx{sec-alternative-workflows}{\mdref{sec-alternative-workflows}{3.3.\hspace*{0.5em}Alternative Workflows}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{\mdref{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{3.3.1.\hspace*{0.5em}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}}%mdk + +\mdtocitemx{sec-no-p4-source-available-p4info-available}{\mdref{sec-no-p4-source-available-p4info-available}{3.3.2.\hspace*{0.5em}No P4 Source Available, P4Info Available}}%mdk + +\mdtocitemx{sec-partial-p4info-and-p4-source-are-available}{\mdref{sec-partial-p4info-and-p4-source-are-available}{3.3.3.\hspace*{0.5em}Partial P4Info and P4 Source are Available}}%mdk + +\mdtocitemx{sec-p4info-role-based-subsets}{\mdref{sec-p4info-role-based-subsets}{3.3.4.\hspace*{0.5em}P4Info Role-Based Subsets}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-restarts}{\mdref{sec-restarts}{3.4.\hspace*{0.5em}P4Runtime State Across Restarts}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-controller-use-cases}{\mdref{sec-controller-use-cases}{4.\hspace*{0.5em}Controller Use-cases}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-single-embedded-controller}{\mdref{sec-single-embedded-controller}{4.1.\hspace*{0.5em}Single Embedded Controller}}%mdk + +\mdtocitemx{sec-single-remote-controller}{\mdref{sec-single-remote-controller}{4.2.\hspace*{0.5em}Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-single-remote-controller}{\mdref{sec-embedded-single-remote-controller}{4.3.\hspace*{0.5em}Embedded + Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-two-remote-controllers}{\mdref{sec-embedded-two-remote-controllers}{4.4.\hspace*{0.5em}Embedded + Two Remote Controllers}}%mdk + +\mdtocitemx{sec-embedded-controller-two-high-availability-remote-controllers}{\mdref{sec-embedded-controller-two-high-availability-remote-controllers}{4.5.\hspace*{0.5em}Embedded Controller + Two High-Availability Remote Controllers}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-master-slave-arbitration-and-controller-replication}{\mdref{sec-master-slave-arbitration-and-controller-replication}{5.\hspace*{0.5em}Master-Slave Arbitration and Controller Replication}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-default-role}{\mdref{sec-default-role}{5.1.\hspace*{0.5em}Default Role}}%mdk + +\mdtocitemx{sec-arbitration-role-config}{\mdref{sec-arbitration-role-config}{5.2.\hspace*{0.5em}Role Config}}%mdk + +\mdtocitemx{sec-mastership-updates}{\mdref{sec-mastership-updates}{5.3.\hspace*{0.5em}Rules for Handling \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}} Messages Received from Controllers}}%mdk + +\mdtocitemx{sec-mastership-notification}{\mdref{sec-mastership-notification}{5.4.\hspace*{0.5em}Mastership Notifications}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-the-p4info-message}{\mdref{sec-the-p4info-message}{6.\hspace*{0.5em}The P4Info Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-common-messages}{\mdref{sec-common-messages}{6.1.\hspace*{0.5em}Common Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-documentation-message}{\mdref{sec-documentation-message}{6.1.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}} Message}}%mdk + +\mdtocitemx{sec-preamble-message}{\mdref{sec-preamble-message}{6.1.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}} Message}}%mdk + +\mdtocitemx{sec-annotating-p4-entities-with-documentation}{\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3.\hspace*{0.5em}Annotating P4 Entities with \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}}%mdk + +\mdtocitemx{sec-structured-annotations}{\mdref{sec-structured-annotations}{6.1.4.\hspace*{0.5em}Structured Annotations}}%mdk + +\mdtocitemx{sec-sourcelocation-message}{\mdref{sec-sourcelocation-message}{6.1.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}} Message}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-pkginfo-message}{\mdref{sec-pkginfo-message}{6.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}} Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-annotating-p4-code-with-pkginfo}{\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1.\hspace*{0.5em}Annotating P4 code with PkgInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-id-allocation}{\mdref{sec-id-allocation}{6.3.\hspace*{0.5em}ID Allocation for P4Info Objects}}%mdk + +\mdtocitemx{sec-p4info-objects}{\mdref{sec-p4info-objects}{6.4.\hspace*{0.5em}P4Info Objects}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table}{\mdref{sec-table}{6.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}}%mdk + +\mdtocitemx{sec-action}{\mdref{sec-action}{6.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}}%mdk + +\mdtocitemx{sec-p4info-action-profile}{\mdref{sec-p4info-action-profile}{6.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}}%mdk + +\mdtocitemx{sec-counter-directcounter}{\mdref{sec-counter-directcounter}{6.4.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}}%mdk + +\mdtocitemx{sec-meter-directmeter}{\mdref{sec-meter-directmeter}{6.4.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}}%mdk + +\mdtocitemx{sec-controller-packet-meta}{\mdref{sec-controller-packet-meta}{6.4.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}}%mdk + +\mdtocitemx{sec-valueset}{\mdref{sec-valueset}{6.4.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}}%mdk + +\mdtocitemx{sec-register}{\mdref{sec-register}{6.4.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}}%mdk + +\mdtocitemx{sec-digest}{\mdref{sec-digest}{6.4.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}}%mdk + +\mdtocitemx{sec-p4info-extern}{\mdref{sec-p4info-extern}{6.4.10.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{\mdref{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{6.5.\hspace*{0.5em}Support for Arbitrary P4 Types with P4TypeInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-fwd-pipe-config}{\mdref{sec-p4-fwd-pipe-config}{7.\hspace*{0.5em}P4 Forwarding-Pipeline Configuration}}%mdk + +\mdtocitemx{sec-general-principles-for-message-formatting}{\mdref{sec-general-principles-for-message-formatting}{8.\hspace*{0.5em}General Principles for Message Formatting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-set-unset-protobuf-field}{\mdref{sec-set-unset-protobuf-field}{8.1.\hspace*{0.5em}Set / Unset Protobuf Field}}%mdk + +\mdtocitemx{sec-read-write-symmetry}{\mdref{sec-read-write-symmetry}{8.2.\hspace*{0.5em}Read-Write Symmetry}}%mdk + +\mdtocitemx{sec-zero-as-reserved-value}{\mdref{sec-zero-as-reserved-value}{8.3.\hspace*{0.5em}Zero as Reserved Value}}%mdk + +\mdtocitemx{sec-bytestrings}{\mdref{sec-bytestrings}{8.4.\hspace*{0.5em}Bytestrings}}%mdk + +\mdtocitemx{sec-representation-of-arbitrary-p4-types}{\mdref{sec-representation-of-arbitrary-p4-types}{8.5.\hspace*{0.5em}Representation of Arbitrary P4 Types}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-problem-statement}{\mdref{sec-problem-statement}{8.5.1.\hspace*{0.5em}Problem Statement}}%mdk + +\mdtocitemx{sec-p4-type-specifications-in-p4infoproto}{\mdref{sec-p4-type-specifications-in-p4infoproto}{8.5.2.\hspace*{0.5em}P4 Type Specifications in p4info.proto}}%mdk + +\mdtocitemx{sec-p4data-in-p4runtime-proto}{\mdref{sec-p4data-in-p4runtime-proto}{8.5.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}} in p4runtime.proto}}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{8.5.4.\hspace*{0.5em}Example}}%mdk + +\mdtocitemx{sec-enum-serializable-enum-and-error}{\mdref{sec-enum-serializable-enum-and-error}{8.5.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}, serializable \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}}%mdk + +\mdtocitemx{sec-user-defined-types}{\mdref{sec-user-defined-types}{8.5.6.\hspace*{0.5em}User-defined types}}%mdk + +\mdtocitemx{sec-trade-off-for-v1x-releases}{\mdref{sec-trade-off-for-v1x-releases}{8.5.7.\hspace*{0.5em}Trade-off for v1.x Releases}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-entity-msgs}{\mdref{sec-p4-entity-msgs}{9.\hspace*{0.5em}P4 Entity Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table-entry}{\mdref{sec-table-entry}{9.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-match-format}{\mdref{sec-match-format}{9.1.1.\hspace*{0.5em}Match Format}}%mdk + +\mdtocitemx{sec-action-specification}{\mdref{sec-action-specification}{9.1.2.\hspace*{0.5em}Action Specification}}%mdk + +\mdtocitemx{sec-default-entry}{\mdref{sec-default-entry}{9.1.3.\hspace*{0.5em}Default Entry}}%mdk + +\mdtocitemx{sec-constant-tables}{\mdref{sec-constant-tables}{9.1.4.\hspace*{0.5em}Constant Tables}}%mdk + +\mdtocitemx{sec-table-wildcard-reads}{\mdref{sec-table-wildcard-reads}{9.1.5.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-direct-resources}{\mdref{sec-direct-resources}{9.1.6.\hspace*{0.5em}Direct Resources}}%mdk + +\mdtocitemx{sec-idle-timeout}{\mdref{sec-idle-timeout}{9.1.7.\hspace*{0.5em}Idle-timeout}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-and-group}{\mdref{sec-action-profile-member-and-group}{9.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-programming}{\mdref{sec-action-profile-member-programming}{9.2.1.\hspace*{0.5em}Action Profile Member Programming}}%mdk + +\mdtocitemx{sec-action-profile-group-programming}{\mdref{sec-action-profile-group-programming}{9.2.2.\hspace*{0.5em}Action Profile Group Programming}}%mdk + +\mdtocitemx{sec-oneshot}{\mdref{sec-oneshot}{9.2.3.\hspace*{0.5em}One Shot Action Selector Programming}}%mdk + +\mdtocitemx{action-selector-constraints}{\mdref{action-selector-constraints}{9.2.4.\hspace*{0.5em}Constraints on action selector programming}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-counterentry-directcounterentry}{\mdref{sec-counterentry-directcounterentry}{9.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directcounterentry}{\mdref{sec-directcounterentry}{9.3.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\mdtocitemx{sec-counterentry}{\mdref{sec-counterentry}{9.3.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-meterentry-directmeterentry}{\mdref{sec-meterentry-directmeterentry}{9.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directmeterentry}{\mdref{sec-directmeterentry}{9.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\mdtocitemx{sec-meterentry}{\mdref{sec-meterentry}{9.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-packetreplicationengineentry}{\mdref{sec-packetreplicationengineentry}{9.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-multicastgroupentry}{\mdref{sec-multicastgroupentry}{9.5.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}}%mdk + +\mdtocitemx{sec-clonesessionentry}{\mdref{sec-clonesessionentry}{9.5.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-valuesetentry}{\mdref{sec-valuesetentry}{9.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}}%mdk + +\mdtocitemx{sec-registerentry}{\mdref{sec-registerentry}{9.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}}%mdk + +\mdtocitemx{sec-digestentry}{\mdref{sec-digestentry}{9.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}}%mdk + +\mdtocitemx{sec-extern-entry}{\mdref{sec-extern-entry}{9.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-error-reporting-messages}{\mdref{sec-error-reporting-messages}{10.\hspace*{0.5em}Error Reporting Messages}}%mdk + +\mdtocitemx{sec-atomicity-of-individual-write-and-read-operations}{\mdref{sec-atomicity-of-individual-write-and-read-operations}{11.\hspace*{0.5em}Atomicity of Individual \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} Operations}}%mdk + +\mdtocitemx{sec-write-rpc}{\mdref{sec-write-rpc}{12.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-batching-and-ordering-of-updates}{\mdref{sec-batching-and-ordering-of-updates}{12.1.\hspace*{0.5em}Batching and Ordering of Updates}}%mdk + +\mdtocitemx{sec-batch-atomicity}{\mdref{sec-batch-atomicity}{12.2.\hspace*{0.5em}Batch Atomicity}}%mdk + +\mdtocitemx{sec-error-reporting}{\mdref{sec-error-reporting}{12.3.\hspace*{0.5em}Error Reporting}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-read-rpc}{\mdref{sec-read-rpc}{13.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-nomenclature}{\mdref{sec-nomenclature}{13.1.\hspace*{0.5em}Nomenclature}}%mdk + +\mdtocitemx{sec-wildcard-reads}{\mdref{sec-wildcard-reads}{13.2.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-batch-processing}{\mdref{sec-batch-processing}{13.3.\hspace*{0.5em}Batch Processing}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{13.3.1.\hspace*{0.5em}Example}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-parallelism-of-read-and-write-requests}{\mdref{sec-parallelism-of-read-and-write-requests}{13.4.\hspace*{0.5em}Parallelism of Read and Write Requests}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-setforwardingpipelineconfig-rpc}{\mdref{sec-setforwardingpipelineconfig-rpc}{14.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-getforwardingpipelineconfig-rpc}{\mdref{sec-getforwardingpipelineconfig-rpc}{15.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-p4runtime-stream-messages}{\mdref{sec-p4runtime-stream-messages}{16.\hspace*{0.5em}P4Runtime Stream Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-packet-i_o}{\mdref{sec-packet-i_o}{16.1.\hspace*{0.5em}Packet I/O}}%mdk + +\mdtocitemx{sec-master-arbitration-update}{\mdref{sec-master-arbitration-update}{16.2.\hspace*{0.5em}Master Arbitration Update}}%mdk + +\mdtocitemx{sec-digest-messages}{\mdref{sec-digest-messages}{16.3.\hspace*{0.5em}Digest Messages}}%mdk + +\mdtocitemx{sec-table-idle-timeout-notification}{\mdref{sec-table-idle-timeout-notification}{16.4.\hspace*{0.5em}Table Idle Timeout Notification}}%mdk + +\mdtocitemx{sec-architecture-specific-notifications}{\mdref{sec-architecture-specific-notifications}{16.5.\hspace*{0.5em}Architecture-Specific Notifications}}%mdk + +\mdtocitemx{sec-stream-error-reporting}{\mdref{sec-stream-error-reporting}{16.6.\hspace*{0.5em}Stream Error Reporting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-examples-of-streamerror-messages}{\mdref{sec-examples-of-streamerror-messages}{16.6.1.\hspace*{0.5em}Examples of \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}} Messages}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-capabilities-rpc}{\mdref{sec-capabilities-rpc}{17.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}} RPC}}%mdk + +\mdtocitemx{sec-portability-considerations}{\mdref{sec-portability-considerations}{18.\hspace*{0.5em}Portability Considerations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-psa-metadata-translation}{\mdref{sec-psa-metadata-translation}{18.1.\hspace*{0.5em}PSA Metadata Translation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-translation-of-port-numbers}{\mdref{sec-translation-of-port-numbers}{18.1.1.\hspace*{0.5em}Translation of Port Numbers}}%mdk + +\mdtocitemx{sec-translation-of-packet-io-header-fields}{\mdref{sec-translation-of-packet-io-header-fields}{18.1.2.\hspace*{0.5em}Translation of Packet-IO Header Fields}}%mdk + +\mdtocitemx{sec-translation-of-match-fields}{\mdref{sec-translation-of-match-fields}{18.1.3.\hspace*{0.5em}Translation of Match Fields}}%mdk + +\mdtocitemx{sec-translation-of-action-parameters}{\mdref{sec-translation-of-action-parameters}{18.1.4.\hspace*{0.5em}Translation of Action Parameters}}%mdk + +\mdtocitemx{sec-port-translation-for-psa-extern-apis}{\mdref{sec-port-translation-for-psa-extern-apis}{18.1.5.\hspace*{0.5em}Port Translation for PSA Extern APIs}}%mdk + +\mdtocitemx{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{\mdref{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{18.1.6.\hspace*{0.5em}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-versioning}{\mdref{sec-p4runtime-versioning}{19.\hspace*{0.5em}P4Runtime Versioning}}%mdk + +\mdtocitemx{sec-extending-p4runtime}{\mdref{sec-extending-p4runtime}{20.\hspace*{0.5em}Extending P4Runtime for non-PSA Architectures}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-p4runtime-for-architecture-specific-externs}{\mdref{sec-extending-p4runtime-for-architecture-specific-externs}{20.1.\hspace*{0.5em}Extending P4Runtime for Architecture-Specific Externs}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-the-p4info-message}{\mdref{sec-extending-the-p4info-message}{20.1.1.\hspace*{0.5em}Extending the P4Info message}}%mdk + +\mdtocitemx{sec-extending-the-p4runtime-service}{\mdref{sec-extending-the-p4runtime-service}{20.1.2.\hspace*{0.5em}Extending the P4Runtime Service}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-architecture-specific-table-extensions}{\mdref{sec-architecture-specific-table-extensions}{20.2.\hspace*{0.5em}Architecture-Specific Table Extensions}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-new-match-types}{\mdref{sec-new-match-types}{20.2.1.\hspace*{0.5em}New Match Types}}%mdk + +\mdtocitemx{sec-new-table-properties}{\mdref{sec-new-table-properties}{20.2.2.\hspace*{0.5em}New Table Properties}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-known-limitations-of-current-p4runtime-version}{\mdref{sec-known-limitations-of-current-p4runtime-version}{21.\hspace*{0.5em}Known Limitations of Current P4Runtime Version}}%mdk + +\mdtocitemx{sec-security-concerns-for-p4runtime}{\mdref{sec-security-concerns-for-p4runtime}{22.\hspace*{0.5em}Security concerns for P4Runtime}}%mdk + +\mdtocitemx{sec-appendix}{\mdref{sec-appendix}{A.\hspace*{0.5em}Appendix}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-revision-history}{\mdref{sec-revision-history}{A.1.\hspace*{0.5em}Revision History}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-changes-in-v120}{\mdref{sec-changes-in-v120}{A.1.1.\hspace*{0.5em}Changes in v1.2.0}}%mdk + +\mdtocitemx{sec-changes-in-v110}{\mdref{sec-changes-in-v110}{A.1.2.\hspace*{0.5em}Changes in v1.1.0}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-annotations}{\mdref{sec-p4-annotations}{A.2.\hspace*{0.5em}P4 Annotations}}%mdk + +\mdtocitemx{sec-value-set-example}{\mdref{sec-value-set-example}{A.3.\hspace*{0.5em}A More Complex Value Set Example}}%mdk + +\mdtocitemx{sec-guidelines-for-implementations}{\mdref{sec-guidelines-for-implementations}{A.4.\hspace*{0.5em}Guidelines for Implementations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-grpc-metadata-maximum-size}{\mdref{sec-grpc-metadata-maximum-size}{A.4.1.\hspace*{0.5em}gRPC Metadata Maximum Size}}%mdk + +\mdtocitemx{sec-grpc-server-maximum-receive-message-size}{\mdref{sec-grpc-server-maximum-receive-message-size}{A.4.2.\hspace*{0.5em}gRPC Server Maximum Receive Message Size}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-bibliography}{\mdref{sec-bibliography}{References}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{215} +\begin{mdtoc}%mdk + +\section*{Figures}\label{sec-figures}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{fig-reference-architecture}{\mdref{fig-reference-architecture}{\mdcaptionlabel{1}. P4Runtime Reference Architecture.}}%mdk + +\mdtocitemx{fig-single-embedded-controller}{\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}. Use-Case: Single Embedded Controller}}%mdk + +\mdtocitemx{fig-single-remote-controller}{\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}. Use-Case: Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-single-remote-controller}{\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}. Use-Case: Embedded Plus Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-controllers}{\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}. Use-Case: Embedded Plus Two Remote Controllers}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-ha-controllers}{\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}. Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk + +\mdtocitemx{fig-error-report}{\mdref{fig-error-report}{\mdcaptionlabel{7}. P4Runtime Error Report Message Format}}%mdk + +\mdtocitemx{fig-psa-metadata-translation}{\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}. P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{216} +\begin{mdtoc}%mdk + +\section*{Tables}\label{sec-tables}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{tab-mapping-p4-obj-ids}{\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}. Mapping of P4Info object type to 8-bit ID prefix value}}%mdk + +\mdtocitemx{tab-format-p4-obj-ids}{\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}. Format of P4Info object IDs}}%mdk + +\mdtocitemx{tab-exmpl-p4-obj-ids}{\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}. Example of statically-assigned P4Info object IDs}}%mdk + +\mdtocitemx{tab-valid-bytestring-encoding}{\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}. Examples of Valid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-invalid-bytestring-encoding}{\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}. Examples of Invalid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-p4-type-usage}{\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}. P4 Type Usage}}%mdk + +\mdtocitemx{tab-p4-annotations}{\mdref{tab-p4-annotations}{\mdcaptionlabel{7}. P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk + +%mdk-data-line={218} +\section{\mdline{218}1.\hspace*{0.5em}\mdline{218}Introduction and Scope}\label{sec-introduction-and-scope}%mdk%mdk + +%mdk-data-line={220} +\noindent\mdline{220}This document is published by the \mdline{220}\emph{P4.org API Working Group}\mdline{220}, which was +chartered\mdline{221}~[\mdcite{p4apiwgcharter}{17}]\mdline{221} to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called \mdline{223}\emph{P4Runtime}\mdline{223}. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +\mdline{226}\href{https://github.com/p4lang/p4runtime/tree/master/proto}{https://github.com/p4lang/p4runtime/tree/master/proto}\mdline{226}.%mdk + +%mdk-data-line={228} +\subsection{\mdline{228}1.1.\hspace*{0.5em}\mdline{228}P4 Language Version Applicability}\label{sec-p4-language-version-applicability}%mdk%mdk + +%mdk-data-line={230} +\noindent\mdline{230}P4Runtime is designed to be implemented in conjunction with the P4\mdline{230}\mdsub{16}\mdline{230} language +version or later. P4\mdline{231}\mdsub{14}\mdline{231} programs should be translated into P4\mdline{231}\mdsub{16}\mdline{231} to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P4\mdline{233}\mdsub{16}\mdline{233} 1.0, but were introduced in P4\mdline{233}\mdsub{16}\mdline{233} 1.1.0\mdline{233}~[\mdcite{p4revisions110}{29}]\mdline{233}. For +this version of P4Runtime, we recommend using P4\mdline{234}\mdsub{16}\mdline{234} 1.2.1\mdline{234}~[\mdcite{p4spec}{1}]\mdline{234}.%mdk + +%mdk-data-line={236} +\subsection{\mdline{236}1.2.\hspace*{0.5em}\mdline{236}In Scope}\label{sec-in-scope}%mdk%mdk + +%mdk-data-line={238} +\noindent\mdline{238}This specification document defines the \mdline{238}\emph{semantics}\mdline{238} of \mdline{238}\emph{P4Runtime}\mdline{238} messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime:%mdk + +%mdk-data-line={242} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={242} +\item\mdline{242}Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA)\mdline{243}~[\mdcite{psa}{19}]\mdline{243} externs (\mdline{243}e.g.\mdline{243} Counters, Meters, Action +Profiles, \mdline{244}\dots{}\mdline{244}). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0.%mdk + +%mdk-data-line={246} +\item\mdline{246}Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism.%mdk + +%mdk-data-line={248} +\item\mdline{248}Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy.%mdk + +%mdk-data-line={251} +\item\mdline{251}Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities.%mdk + +%mdk-data-line={253} +\item\mdline{253}Packet I/O to enable streaming packets to \mdline{253}\&\mdline{253} from the control plane.%mdk + +%mdk-data-line={254} +\item\mdline{254}Batching support, with different atomicity guarantees.%mdk + +%mdk-data-line={255} +\item\mdline{255}In-the-field device-reconfiguration with a new P4 data plane.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={257} +\noindent\mdline{257}The following are in the scope of this specification document:%mdk + +%mdk-data-line={259} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={259} +\item\mdline{259}Rationale for the P4Runtime design.%mdk + +%mdk-data-line={260} +\item\mdline{260}Reference architecture and use-cases for deploying a P4Runtime service.%mdk + +%mdk-data-line={261} +\item\mdline{261}Detailed description of the API semantics.%mdk + +%mdk-data-line={262} +\item\mdline{262}Requirements for conformant implementations of the API.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={264} +\subsection{\mdline{264}1.3.\hspace*{0.5em}\mdline{264}Not In Scope}\label{sec-not-in-scope}%mdk%mdk + +%mdk-data-line={266} +\noindent\mdline{266}The following are not in scope of P4Runtime:%mdk + +%mdk-data-line={268} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={268} +\item\mdline{268}Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +\mdline{273}[\mdcite{openconfig}{35}]\mdline{273}. An open source implementation of these APIs is also in progress +as part of the Stratum project\mdline{274}~[\mdcite{stratum}{37}]\mdline{274}.%mdk + +%mdk-data-line={275} +\item\mdline{275}Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={280} +\noindent\mdline{280}The following are not in scope of this specification document:%mdk + +%mdk-data-line={282} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={282} +\item\mdline{282}Description of the P4 programming language; it is assumed that the reader is +already familiar with P4\mdline{283}\mdsub{16}\mdline{283}~[\mdcite{p4spec}{1}]\mdline{283}.%mdk + +%mdk-data-line={284} +\item\mdline{284}Descriptions of gRPC and Protobuf files in general.%mdk + +%mdk-data-line={285} +\item\mdline{285}Controller\mdline{285}~\mdref{sec-arbitration-role-config}{role}\mdline{285} definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={289} +\section{\mdline{289}2.\hspace*{0.5em}\mdline{289}Terms and Definitions}\label{sec-terms-and-definitions}%mdk%mdk + +%mdk-data-line={291} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries arbitration}}%mdk + +%mdk-data-line={291} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{291}Refers to the process through which P4Runtime ensures that at any given +time, there is a single master (\mdline{292}i.e.\mdline{292} a client with write access) for a given +role. Also referred to as \mdline{293}\textquotedblleft{}master-slave arbitration\textquotedblright{}\mdline{293}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries client}}%mdk + +%mdk-data-line={295} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{295}The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries COS}}%mdk + +%mdk-data-line={299} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{299}Class of Service. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries device}}%mdk + +%mdk-data-line={301} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{301}Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries entity}}%mdk + +%mdk-data-line={305} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{305}An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries gRPC}}%mdk + +%mdk-data-line={308} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{308}gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +\mdline{309}[\mdcite{grpc}{9}]\mdline{309}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries HA}}%mdk + +%mdk-data-line={311} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{311}High-Availability. Refers to a redundancy architecture. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Instrumentation}}%mdk + +%mdk-data-line={313} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{313}The part of the P4Runtime server which implements the calls to the device or +target native \mdline{314}\textquotedblleft{}SDK\textquotedblright{}\mdline{314} or backend. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries IPC}}%mdk + +%mdk-data-line={316} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{316}Inter-Process Communication. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Blob}}%mdk + +%mdk-data-line={318} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{318}A more colloquial term for P4 Device Config (Blob = Binary Large Object). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Device Config}}%mdk + +%mdk-data-line={320} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{320}The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its \mdline{322}\textquotedblleft{}program.\textquotedblright{}\mdline{322} +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4Info}}%mdk + +%mdk-data-line={324} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{324}Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4RT}}%mdk + +%mdk-data-line={328} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{328}Abbreviation for P4Runtime. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Protobuf (Protocol Buffers)}}%mdk + +%mdk-data-line={330} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{330}The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See\mdline{331}~[\mdcite{proto}{21}]\mdline{331}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries PSA}}%mdk + +%mdk-data-line={333} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{333}Portable Switch Architecture\mdline{333}~[\mdcite{psa}{19}]\mdline{333}; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RPC}}%mdk + +%mdk-data-line={337} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{337}Remote Procedure Call. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RTT}}%mdk + +%mdk-data-line={339} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{339}Round-trip time. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN}}%mdk + +%mdk-data-line={341} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{341}Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network \mdline{346}\emph{controller}\mdline{346}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN port}}%mdk + +%mdk-data-line={348} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{348}A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries server}}%mdk + +%mdk-data-line={352} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{352}The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries stream}}%mdk + +%mdk-data-line={356} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{356}Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (\mdline{357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{357}), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and master-slave arbitration, among other +things. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries switch config}}%mdk + +%mdk-data-line={362} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{362}Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries target}}%mdk + +%mdk-data-line={367} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{367}The hardware or software entity which \mdline{367}\textquotedblleft{}executes\textquotedblright{}\mdline{367} the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with \mdline{368}\textquotedblleft{}device\textquotedblright{}\mdline{368}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries URI}}%mdk + +%mdk-data-line={370} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{370}Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={374} +\section{\mdline{374}3.\hspace*{0.5em}\mdline{374}Reference Architecture}\label{sec-reference-architecture}%mdk%mdk + +%mdk-data-line={376} +\noindent\mdline{376}Figure\mdline{376}~\mdref{fig-reference-architecture}{\mdcaptionlabel{1}}\mdline{376} represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. A multi-master protocol allows more than +one controller to participate, and a role-based arbitration scheme ensures only +one controller has write access to each read/write entity, or the pipeline +config itself. Any controller may perform read access to any entity or the +pipeline config. Later sections describe this in detail. For the sake of +brevity, the term controller may refer to one or more controllers.%mdk + +%mdk-data-line={385} +\mdline{385}The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +\mdline{388}[\mdcite{p4runtimerepo}{15}]\mdline{388}. It may be compiled via protoc\mdline{388} \mdline{388}\textemdash{}\mdline{388} the Protobuf compiler\mdline{388} \mdline{388}\textemdash{}\mdline{388} +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server.%mdk + +%mdk-data-line={393} +\mdline{393}Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository\mdline{394}~[\mdcite{pirepo}{16}]\mdline{394}. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, \mdline{396}e.g.\mdline{396} via callbacks, thus reducing the burden of implementing +P4Runtime.%mdk + +%mdk-data-line={399} +\mdline{399}The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard.%mdk + +%mdk-data-line={403} +\mdline{403}The controller can also set the \mdline{403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{403}, which amounts to +installing and running the compiled P4 program output, which is included in the +\mdline{405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{405} Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +\mdline{407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{407} to retrieve the device config and the P4Info.%mdk + +%mdk-data-line={410} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={411} +\noindent\mdline{411}\includegraphics[keepaspectratio=true,height=7cm]{build/reference-architecture}{}\mdline{411}%mdk + +%mdk-data-line={412} +\mdhr{}%mdk + +%mdk-data-line={413} +\noindent\mdline{413}\mdcaption{\textbf{Figure~\mdcaptionlabel{1}.}~\mdcaptiontext{P4Runtime Reference Architecture.}}%mdk +%mdk +\end{mdcenter}\label{fig-reference-architecture}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={417} +\subsection{\mdline{417}3.1.\hspace*{0.5em}\mdline{417}Idealized Workflow}\label{sec-idealized-workflow}%mdk%mdk + +%mdk-data-line={419} +\noindent\mdline{419}In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the \mdline{420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{420} +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a \mdline{422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{422} +RPC. Metadata in the P4Info describes both the overall program itself +(\mdline{424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{424}) as well as all entity instances derived from the P4 program\mdline{424} \mdline{424}\textemdash{}\mdline{424} +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise \mdline{426}\textquotedblleft{}handle\textquotedblright{}\mdline{426} used in API +calls.%mdk + +%mdk-data-line={429} +\mdline{429}In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible.%mdk + +%mdk-data-line={435} +\mdline{435}In some use cases, it is expected that a controller will store a +collection of multiple P4 \mdline{436}\textquotedblleft{}packages\textquotedblright{}\mdline{436}, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the \mdline{438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{438} from the target via the +\mdline{439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineRequest}}}\mdline{439} RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state.%mdk + +%mdk-data-line={443} +\subsection{\mdline{443}3.2.\hspace*{0.5em}\mdline{443}P4 as a Behavioral Description Language}\label{sec-p4-as-behavioral-description-language}%mdk%mdk + +%mdk-data-line={445} +\noindent\mdline{445}P4 can be considered a behavioral description of a switching device which may or +may not execute \mdline{446}\textquotedblleft{}P4\textquotedblright{}\mdline{446} natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a \mdline{448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineRequest}}}\mdline{448} to +change its pipeline \mdline{449}\textquotedblleft{}program\textquotedblright{}\mdline{449}, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device.%mdk + +%mdk-data-line={455} +\mdline{455}While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API.%mdk + +%mdk-data-line={464} +\mdline{464}In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the \mdline{465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{465} +message as well as the embedded \mdline{466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{466} fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections.%mdk + +%mdk-data-line={470} +\subsection{\mdline{470}3.3.\hspace*{0.5em}\mdline{470}Alternative Workflows}\label{sec-alternative-workflows}%mdk%mdk + +%mdk-data-line={472} +\noindent\mdline{472}Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary.%mdk + +%mdk-data-line={476} +\subsubsection{\mdline{476}3.3.1.\hspace*{0.5em}\mdline{476}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}\label{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}%mdk%mdk + +%mdk-data-line={478} +\noindent\mdline{478}In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +\mdline{480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{480}. The device\mdline{480}'\mdline{480}s configuration might be derived via some other +means to implement the P4 source code\mdline{481}'\mdline{481}s intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane.%mdk + +%mdk-data-line={485} +\subsubsection{\mdline{485}3.3.2.\hspace*{0.5em}\mdline{485}No P4 Source Available, P4Info Available}\label{sec-no-p4-source-available-p4info-available}%mdk%mdk + +%mdk-data-line={487} +\noindent\mdline{487}In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are:%mdk + +%mdk-data-line={490} +\begin{enumerate}%mdk + +%mdk-data-line={490} +\item{} +%mdk-data-line={490} +\mdline{490}The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security.%mdk%mdk + +%mdk-data-line={493} +\item{} +%mdk-data-line={493} +\mdline{493}The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={496} +\noindent\mdline{496}As discussed in Section\mdline{496}~\mdref{sec-p4-as-behavioral-description-language}{3.2}\mdline{496}, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, \mdline{499}e.g.\mdline{499} documentation.%mdk + +%mdk-data-line={501} +\subsubsection{\mdline{501}3.3.3.\hspace*{0.5em}\mdline{501}Partial P4Info and P4 Source are Available}\label{sec-partial-p4info-and-p4-source-are-available}%mdk%mdk + +%mdk-data-line={503} +\noindent\mdline{503}In this situation, a subset of the target\mdline{503}'\mdline{503}s pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code.%mdk + +%mdk-data-line={510} +\subsubsection{\mdline{510}3.3.4.\hspace*{0.5em}\mdline{510}P4Info Role-Based Subsets}\label{sec-p4info-role-based-subsets}%mdk%mdk + +%mdk-data-line={512} +\noindent\mdline{512}In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more.%mdk + +%mdk-data-line={516} +\subsection{\mdline{516}3.4.\hspace*{0.5em}\mdline{516}P4Runtime State Across Restarts}\label{sec-restarts}%mdk%mdk + +%mdk-data-line={518} +\noindent\mdline{518}All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade.%mdk + +%mdk-data-line={524} +\section{\mdline{524}4.\hspace*{0.5em}\mdline{524}Controller Use-cases}\label{sec-controller-use-cases}%mdk%mdk + +%mdk-data-line={526} +\noindent\mdline{526}P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +\mdline{528}\mdref{sec-master-slave-arbitration-and-controller-replication}{section}\mdline{528}. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime\mdline{530}'\mdline{530}s flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex.%mdk + +%mdk-data-line={533} +\subsection{\mdline{533}4.1.\hspace*{0.5em}\mdline{533}Single Embedded Controller}\label{sec-single-embedded-controller}%mdk%mdk + +%mdk-data-line={535} +\noindent\mdline{535}Figure\mdline{535}~\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}}\mdline{535} shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases.%mdk + +%mdk-data-line={540} +\mdline{540}P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC.%mdk + +%mdk-data-line={545} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={546} +\noindent\mdline{546}\includegraphics[keepaspectratio=true,height=6cm]{build/single-embedded-controller}{}\mdline{546}%mdk + +%mdk-data-line={547} +\mdhr{}%mdk + +%mdk-data-line={548} +\noindent\mdline{548}\mdcaption{\textbf{Figure~\mdcaptionlabel{2}.}~\mdcaptiontext{Use-Case: Single Embedded Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-embedded-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={552} +\subsection{\mdline{552}4.2.\hspace*{0.5em}\mdline{552}Single Remote Controller}\label{sec-single-remote-controller}%mdk%mdk + +%mdk-data-line={554} +\noindent\mdline{554}Figure\mdline{554}~\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}}\mdline{554} shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections.%mdk + +%mdk-data-line={559} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={560} +\noindent\mdline{560}\includegraphics[keepaspectratio=true,height=7cm]{build/single-remote-controller}{}\mdline{560}%mdk + +%mdk-data-line={561} +\mdhr{}%mdk + +%mdk-data-line={562} +\noindent\mdline{562}\mdcaption{\textbf{Figure~\mdcaptionlabel{3}.}~\mdcaptiontext{Use-Case: Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={566} +\subsection{\mdline{566}4.3.\hspace*{0.5em}\mdline{566}Embedded\mdline{566} \mdline{566}+ Single Remote Controller}\label{sec-embedded-single-remote-controller}%mdk%mdk + +%mdk-data-line={568} +\noindent\mdline{568}Figure\mdline{568}~\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}}\mdline{568} illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller.%mdk + +%mdk-data-line={575} +\mdline{575}For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables.%mdk + +%mdk-data-line={579} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={580} +\noindent\mdline{580}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-single-remote-controller}{}\mdline{580}%mdk + +%mdk-data-line={581} +\mdhr{}%mdk + +%mdk-data-line={582} +\noindent\mdline{582}\mdcaption{\textbf{Figure~\mdcaptionlabel{4}.}~\mdcaptiontext{Use-Case: Embedded Plus Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={587} +\subsection{\mdline{587}4.4.\hspace*{0.5em}\mdline{587}Embedded\mdline{587} \mdline{587}+ Two Remote Controllers}\label{sec-embedded-two-remote-controllers}%mdk%mdk + +%mdk-data-line={589} +\noindent\mdline{589}Figure\mdline{589}~\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}}\mdline{589} illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +\mdline{592}e.g.\mdline{592} routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership.%mdk + +%mdk-data-line={595} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={596} +\noindent\mdline{596}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-controllers}{}\mdline{596}%mdk + +%mdk-data-line={597} +\mdhr{}%mdk + +%mdk-data-line={598} +\noindent\mdline{598}\mdcaption{\textbf{Figure~\mdcaptionlabel{5}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={603} +\subsection{\mdline{603}4.5.\hspace*{0.5em}\mdline{603}Embedded Controller\mdline{603} \mdline{603}+ Two High-Availability Remote Controllers}\label{sec-embedded-controller-two-high-availability-remote-controllers}%mdk%mdk + +%mdk-data-line={605} +\noindent\mdline{605}Figure\mdline{605}~\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}}\mdline{605} illustrates a single +embedded controller plus two remote controllers in an active-standby HA +(High-Availability) configuration. Controller \mdline{607}\#\mdline{607}1 is the active controller and is +in charge of some entities. If it fails, Controller \mdline{608}\#\mdline{608}2 takes over and manages +the tables formerly owned by Controller \mdline{609}\#\mdline{609}1. The mechanics of HA architectures +are beyond the scope of this document, but the P4Runtime multi-master +arbitration scheme supports it.%mdk + +%mdk-data-line={613} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={614} +\noindent\mdline{614}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-ha-controllers}{}\mdline{614}%mdk + +%mdk-data-line={615} +\mdhr{}%mdk + +%mdk-data-line={616} +\noindent\mdline{616}\mdcaption{\textbf{Figure~\mdcaptionlabel{6}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-ha-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={621} +\section{\mdline{621}5.\hspace*{0.5em}\mdline{621}Master-Slave Arbitration and Controller Replication}\label{sec-master-slave-arbitration-and-controller-replication}%mdk%mdk + +%mdk-data-line={624} +\noindent\mdline{624}The P4Runtime interface allows multiple controllers to be connected to the +P4Runtime server running on the device at the same time for the following +reasons:%mdk + +%mdk-data-line={628} +\begin{enumerate}%mdk + +%mdk-data-line={628} +\item{} +%mdk-data-line={628} +\mdline{628}Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, \mdline{629}\textquotedblleft{}roles\textquotedblright{}\mdline{629} (or \mdline{629}\textquotedblleft{}realms\textquotedblright{}\mdline{629}) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +master and the rest are slaves. Role definition, \mdline{632}i.e.\mdline{632} how P4 entities get +assigned to each role, is \mdline{633}\textbf{out-of-scope}\mdline{633} of this document.%mdk%mdk + +%mdk-data-line={635} +\item{} +%mdk-data-line={635} +\mdline{635}Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby slave controllers. These can already have a connection +open, which can help them become master more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={641} +\noindent\mdline{641}To support multiple controllers, P4Runtime uses the streaming channel (available +via \mdline{642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{642} RPC) for session management. The workflow is described as +follows:%mdk + +%mdk-data-line={645} +\begin{itemize}%mdk + +%mdk-data-line={645} +\item{} +%mdk-data-line={645} +\mdline{645}Each controller instance (\mdline{645}e.g.\mdline{645} a controller process) can participate in one or +more roles. For each (\mdline{646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{646}, \mdline{646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{646}), the controller receives an +\mdline{647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{647}. This \mdline{647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{647} can be the same for different roles and/or +devices, as long as the tuple (\mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{648}, \mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{648}, \mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{648}) is +unique. For each (\mdline{649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{649}, \mdline{649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{649}) that the controller wishes to +control, it establishes a \mdline{650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{650} with the P4Runtime server +responsible for that device, and sends a \mdline{651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{651} message +containing that tuple of (\mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{652}, \mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{652}, \mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{652}) values. The +P4Runtime server selects a master independently for each (\mdline{653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{653}, +\mdline{654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{654}) pair. The master is the client that has the highest \mdline{654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{654} +that the device has ever received for the same (\mdline{655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{655}, +\mdline{656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{656}) values. A connection between a controller instance and a device id +\mdline{657}\textemdash{}\mdline{657} which involves a persistent \mdline{657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{657} \mdline{657}\textemdash{}\mdline{657} can be referred to as a +P4Runtime client.%mdk + +%mdk-data-line={660} +\mdline{660}Note that the P4Runtime server does not assign a \mdline{660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{660} or \mdline{660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{660} to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the \mdline{662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{662} values used for each +\mdline{663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{663}. The P4Runtime server only keeps track of the (\mdline{663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{663}, +\mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{664}, \mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{664}) of each \mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{664} that has sent a successful +\mdline{665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{665} message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +\mdline{667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{667} message to identify which client is making the \mdline{667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{667}, +not only the \mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{668}. This enables controllers to re-use the same +numeric \mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{669} values across different (\mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{669}, \mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{669}) +pairs. P4Runtime does not require \mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{670} values be reused across such +different (\mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{671}, \mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{671}) pairs; it allows it.%mdk%mdk + +%mdk-data-line={673} +\item{} +%mdk-data-line={673} +\mdline{673}To start a controller session, a controller first opens a bidirectional stream +channel to the server via the \mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{674} RPC for each device. This stream +will be used for two purposes:%mdk + +%mdk-data-line={677} +\begin{itemize}%mdk + +%mdk-data-line={677} +\item{} +%mdk-data-line={677} +\mdline{677}\textbf{Session management:}\mdline{677} As soon as the controller opens the stream +channel, it sends a \mdline{678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{678} message to the switch. The +controller populates the \mdline{679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{679} field in this message +using its \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{680} and \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{680}, as well as the \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{680} of the +device. Note that the \mdline{681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{681} field in the \mdline{681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{681} is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below.%mdk%mdk + +%mdk-data-line={685} +\item{} +%mdk-data-line={685} +\mdline{685}\textbf{Streaming of notifications (e.g. digests) and packet I/O:}\mdline{685} The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the master controller can participate in packet +I/O. This feature is explained in more details in the\mdline{689}~\mdref{sec-packet-i_o}{Packet +I/O}\mdline{690} section.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={692} +\mdline{692}Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state.%mdk%mdk + +%mdk-data-line={695} +\item{} +%mdk-data-line={695} +\mdline{695}Note that the stream is opened per device. In case a switching platform has +multiple devices (\mdline{696}e.g.\mdline{696} multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different masters for different +devices. In this case, it is the responsibility of the P4Runtime server to +keep track of the master for each device (and role). More specifically, the +P4Runtime server will know which stream corresponds to the master controller +for each pair of (\mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{701}, \mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{701}) at any point of time.%mdk%mdk + +%mdk-data-line={703} +\item{} +%mdk-data-line={703} +\mdline{703}The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered \mdline{704}\textquotedblleft{}offline\textquotedblright{}\mdline{704} or +\mdline{705}\textquotedblleft{}dead\textquotedblright{}\mdline{705} as soon as its stream channel to the switch is broken. When a master +channel gets broken: (i) an advisory message is sent to all other controllers +for that \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{707} and \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{707}, as described in the +\mdline{708}\mdref{sec-mastership-notification}{following section}\mdline{708} (ii) the P4Runtime server +will be without a master, until a client sends a successful +\mdline{710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{710} (as per the rules in a +\mdline{711}\mdref{sec-mastership-updates}{later section}\mdline{711}).%mdk%mdk + +%mdk-data-line={713} +\item{} +%mdk-data-line={713} +\mdline{713}The mechanism via which the controller receives the P4Runtime server details +which includes the \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{714}, \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip}}}\mdline{714} and \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{714}, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +\mdline{718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{718}) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={723} +\noindent\mdline{723}gRPC enables the server to identify which client originated each message in the +\mdline{724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{724} stream. For example, the C++ gRPC library\mdline{724}~[\mdcite{grpcstreamc}{10}]\mdline{724} in +synchronous mode enables a server process to cause a function to be called when +a new client creates a \mdline{726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{726} stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +\mdline{728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{728} is closed normally (or broken, \mdline{728}e.g.\mdline{728} because a client process +unexpectedly terminated). Thus the server can easily associate all +\mdline{730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{730} messages received from the same client, because they are +processed within the context of the same function call.%mdk + +%mdk-data-line={733} +\mdline{733}A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{738}, \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{738}, and \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{738} in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods\mdline{740}~[\mdcite{grpcauth}{8}]\mdline{740} that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server.%mdk + +%mdk-data-line={744} +\subsection{\mdline{744}5.1.\hspace*{0.5em}\mdline{744}Default Role}\label{sec-default-role}%mdk%mdk + +%mdk-data-line={746} +\noindent\mdline{746}A controller can omit the role message in \mdline{746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{746}. This +implies the \mdline{747}\textquotedblleft{}default role\textquotedblright{}\mdline{747}, which corresponds to \mdline{747}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{747}. This +also implies that a default role has a \mdline{748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{748} of 0 (default). If using a +default role, all RPCs from the controller (\mdline{749}e.g.\mdline{749} \mdline{749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{749}) must set the \mdline{749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{749} +to 0.%mdk + +%mdk-data-line={752} +\subsection{\mdline{752}5.2.\hspace*{0.5em}\mdline{752}Role Config}\label{sec-arbitration-role-config}%mdk%mdk + +%mdk-data-line={754} +\noindent\mdline{754}The \mdline{754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{754} field in the \mdline{754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{754} message sent by the +controller describes the role configuration, \mdline{755}i.e.\mdline{755} which operations are in the +scope of a given role. In particular, the definition of a role may include the +following:%mdk + +%mdk-data-line={759} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={759} +\item\mdline{759}A list of P4 entities for which the controller may issue \mdline{759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{759} updates and +receive notification messages (\mdline{760}e.g.\mdline{760} \mdline{760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{760} and +\mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{761}).%mdk + +%mdk-data-line={762} +\item\mdline{762}Whether the controller is able to receive \mdline{762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{762} messages, along with a +filtering mechanism based on the values of the \mdline{763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{763} fields to +select which \mdline{764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{764} messages should be sent to the controller.%mdk + +%mdk-data-line={765} +\item\mdline{765}Whether the controller is able to send \mdline{765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{765} messages, along with a +filtering mechanism based on the values of the \mdline{766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{766} fields to +select which \mdline{767}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{767} messages are allowed to be sent by the controller.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={769} +\noindent\mdline{769}An unset \mdline{769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{769} implies \mdline{769}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{769} (similar to the default +role explained above). In order to support different role definition schemes, +\mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{771} is defined as an \mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{771} Protobuf message\mdline{771}~[\mdcite{protoany}{31}]\mdline{771}. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion.%mdk + +%mdk-data-line={776} +\mdline{776}It is the job of the P4Runtime server to remember the \mdline{776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{776} for every +\mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{777} and \mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{777} pair.%mdk + +%mdk-data-line={779} +\subsection{\mdline{779}5.3.\hspace*{0.5em}\mdline{779}Rules for Handling \mdline{779}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{779} Messages Received from Controllers}\label{sec-mastership-updates}%mdk%mdk + +%mdk-data-line={781} +\begin{enumerate}%mdk + +%mdk-data-line={781} +\item{} +%mdk-data-line={781} +\mdline{781}If the \mdline{781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{781} message is received for the first time on +this particular channel (\mdline{782}i.e.\mdline{782} for a newly connected controller):%mdk + +%mdk-data-line={784} +\begin{enumerate}%mdk + +%mdk-data-line={784} +\item{} +%mdk-data-line={784} +\mdline{784}If \mdline{784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{784} does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +\mdline{786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{786} error.%mdk%mdk + +%mdk-data-line={788} +\item{} +%mdk-data-line={788} +\mdline{788}If the \mdline{788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{788} is set and is already used by another controller for +the same (\mdline{789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{789}, \mdline{789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{789}), the P4Runtime server shall terminate +the stream by returning an \mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{790} error.%mdk%mdk + +%mdk-data-line={792} +\item{} +%mdk-data-line={792} +\mdline{792}If \mdline{792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{792} does not match the \mdline{792}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{792} scheme previously +agreed upon, the server must return an \mdline{793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{793} error.%mdk%mdk + +%mdk-data-line={795} +\item{} +%mdk-data-line={795} +\mdline{795}If the number of open streams for the given (\mdline{795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{795}, \mdline{795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{795}) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a \mdline{797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{797} error.%mdk%mdk + +%mdk-data-line={799} +\item{} +%mdk-data-line={799} +\mdline{799}Otherwise, the controller is added to a list of connected controllers for +the given (\mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{800}, \mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{800}) and the server remembers the +controllers \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{801}, \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{801} and \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{801} for this gRPC +channel. See below for the rules to determine if this controller becomes +a master or slave, and what notifications are sent as a consequence.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={805} +\item{} +%mdk-data-line={805} +\mdline{805}Otherwise, if the \mdline{805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{805} message is received from an +already connected controller:%mdk + +%mdk-data-line={808} +\begin{enumerate}%mdk + +%mdk-data-line={808} +\item{} +%mdk-data-line={808} +\mdline{808}If the \mdline{808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{808} does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{810} error.%mdk%mdk + +%mdk-data-line={812} +\item{} +%mdk-data-line={812} +\mdline{812}If the \mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{812} does not match the current \mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{812} assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{814} error. If the controller wishes to change its role, +it must close the current stream channel and open a new one.%mdk%mdk + +%mdk-data-line={817} +\item{} +%mdk-data-line={817} +\mdline{817}If \mdline{817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{817} does not match the \mdline{817}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{817} scheme previously +agreed upon, the server must return an \mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{818} error.%mdk%mdk + +%mdk-data-line={820} +\item{} +%mdk-data-line={820} +\mdline{820}If the \mdline{820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{820} is set and is already used by another controller +(excluding the controller making the request) for the same +(\mdline{822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{822}, \mdline{822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{822}), the P4Runtime server shall terminate the stream +by returning an \mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{823} error.%mdk%mdk + +%mdk-data-line={825} +\item{} +%mdk-data-line={825} +\mdline{825}If the \mdline{825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{825} matches the one assigned to this stream:%mdk + +%mdk-data-line={827} +\begin{enumerate}%mdk + +%mdk-data-line={827} +\item{} +%mdk-data-line={827} +\mdline{827}If the controller for this channel is the master, then the server +updates the \mdline{828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{828} to the one specified in the +\mdline{829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{829}. An advisory mastership message is sent to +all controllers for this \mdline{830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{830} and \mdline{830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{830} informing +them of the new \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{831}. Since the format of \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{831} is +out of scope for the P4Runtime specification, the server will send +the advisory message for every update, even if the master sets the +same \mdline{834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{834} as it has before. See the +\mdline{835}\mdref{sec-mastership-notification}{following section}\mdline{835} for the format of +the advisory message.%mdk%mdk + +%mdk-data-line={838} +\item{} +%mdk-data-line={838} +\mdline{838}If the controller is a slave, this is a no-op and the \mdline{838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{838} +is ignored. No response is sent to any controller.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={841} +\item{} +%mdk-data-line={841} +\mdline{841}Otherwise, the server updates the \mdline{841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{841} it has stored for this +controller. This change might cause a change in mastership (this +controller might become master, or the controller might have downgraded +itself to a slave, see below), as well as notifications being sent to one +or more controllers.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={847} +\noindent\mdline{847}If the \mdline{847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{847} is accepted by either of the two steps above +(cases 1.5. and 2.6. above), then the server determines if there are changes in +mastership. Let \mdline{849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{849} be the highest election ID the server has +ever seen for the given \mdline{850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{850} and \mdline{850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{850} (including the one of the +current master if there is one).%mdk + +%mdk-data-line={853} +\begin{enumerate}%mdk + +%mdk-data-line={853} +\item{} +%mdk-data-line={853} +\mdline{853}If \mdline{853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{853} is greater than or equal to \mdline{853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{853}, then the +controller becomes master. The server updates the role configuration to +\mdline{855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{855} for the given \mdline{855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{855}. Furthermore:%mdk + +%mdk-data-line={857} +\begin{enumerate}%mdk + +%mdk-data-line={857} +\item{} +%mdk-data-line={857} +\mdline{857}If there was no master for this \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{857} and \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{857} before and +there are no \mdline{858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{858} requests still processing from a previous master, +then the server immediately sends an advisory notification to all +controllers for this \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{860} and \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{860}. See the +\mdline{861}\mdref{sec-mastership-notification}{following section}\mdline{861} for the format of the +advisory message.%mdk%mdk + +%mdk-data-line={864} +\item{} +%mdk-data-line={864} +\mdline{864}If there was a previous master or \mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{864} requests in flight, then the +server carries out the following steps (in this order):%mdk + +%mdk-data-line={867} +\begin{enumerate}%mdk + +%mdk-data-line={867} +\item{} +%mdk-data-line={867} +\mdline{867}The server stops accepting \mdline{867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{867} requests from the previous master +(if there is one). At this point, the server will reject all \mdline{868}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{868} +requests with \mdline{869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{869}.%mdk%mdk + +%mdk-data-line={871} +\item{} +%mdk-data-line={871} +\mdline{871}The server notifies all controllers other than the new master of the +mastership change by sending the advisory notification described in +the\mdline{873}~\mdref{sec-mastership-notification}{following section}\mdline{873}.%mdk%mdk + +%mdk-data-line={875} +\item{} +%mdk-data-line={875} +\mdline{875}The server will finish processing any \mdline{875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{875} requests that have +already started. If there are errors, they are reported as usual to +the previous master. If the previous master has already disconnected, +any possible errors are dropped and not reported.%mdk%mdk + +%mdk-data-line={880} +\item{} +%mdk-data-line={880} +\mdline{880}The server now accepts the current controller as the new master, thus +accepting \mdline{881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{881} requests from this controller. The server updates +the highest election ID (\mdline{882}i.e.\mdline{882} \mdline{882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{882}) it has seen for +this \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{883} and \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{883} to \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{883}.%mdk%mdk + +%mdk-data-line={885} +\item{} +%mdk-data-line={885} +\mdline{885}The server notifies the new master by sending the advisory message +described in the\mdline{886}~\mdref{sec-mastership-notification}{following section}\mdline{886}.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={888} +\item{} +%mdk-data-line={888} +\mdline{888}Otherwise, the controller becomes a slave. If the controller was previously a +master (and downgraded itself), then an advisory message is sent to all +controllers for this \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{890} and \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{890}. Otherwise, the advisory +message is only sent to the controller that sent the initial +\mdline{892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{892}. See the +\mdline{893}\mdref{sec-mastership-notification}{following section}\mdline{893} for the format of the +advisory message.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={896} +\subsection{\mdline{896}5.4.\hspace*{0.5em}\mdline{896}Mastership Notifications}\label{sec-mastership-notification}%mdk%mdk + +%mdk-data-line={898} +\noindent\mdline{898}For any given \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{898} and \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{898}, any time a new master is chosen, a +master downgrades its status to a slave, a master disconnects, or the +\mdline{900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{900} is updated by the master, all controllers for that +(\mdline{901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{901}, \mdline{901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{901}) are informed of this by sending a +\mdline{902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{902}. The \mdline{902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{902} is populated as follows:%mdk + +%mdk-data-line={904} +\begin{itemize}%mdk + +%mdk-data-line={904} +\item{} +%mdk-data-line={904} +\mdline{904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{904} and \mdline{904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{904} as given.%mdk%mdk + +%mdk-data-line={906} +\item{} +%mdk-data-line={906} +\mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{906} is set to the role configuration the server received most +recently in a \mdline{907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{907} from a master.%mdk%mdk + +%mdk-data-line={909} +\item{} +%mdk-data-line={909} +\mdline{909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{909} is populated as follows:%mdk + +%mdk-data-line={911} +\begin{itemize}%mdk + +%mdk-data-line={911} +\item{} +%mdk-data-line={911} +\mdline{911}If there has not been any master at all, the election\mdline{911}\_\mdline{911}id is left unset.%mdk%mdk + +%mdk-data-line={913} +\item{} +%mdk-data-line={913} +\mdline{913}Otherwise, \mdline{913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{913} is set to the highest election ID that the server +has seen for this \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{914} and \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{914} (which is the \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{914} of +the current master if there is any).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={917} +\item{} +%mdk-data-line={917} +\mdline{917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{917} is set differently based on whether the notification is sent to the +master or a slave controller:%mdk + +%mdk-data-line={920} +\begin{itemize}%mdk + +%mdk-data-line={920} +\item{} +%mdk-data-line={920} +\mdline{920}If there is a master:%mdk + +%mdk-data-line={922} +\begin{itemize}%mdk + +%mdk-data-line={922} +\item{} +%mdk-data-line={922} +\mdline{922}For the master, \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{922} is OK (with \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{922} set to +\mdline{923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.OK}}}\mdline{923}).%mdk%mdk + +%mdk-data-line={925} +\item{} +%mdk-data-line={925} +\mdline{925}For all slave controllers, \mdline{925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{925} is set to non-OK (with +\mdline{926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{926} set to \mdline{926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.ALREADY\_EXISTS}}}\mdline{926}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={928} +\item{} +%mdk-data-line={928} +\mdline{928}Otherwise, if there is no master currently, for all slave controllers, +\mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{929} is set to non-OK (with \mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{929} set to +\mdline{930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.NOT\_FOUND}}}\mdline{930}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={932} +\noindent\mdline{932}Note that on mastership changes with outstanding \mdline{932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{932} request, some +notifications might be delayed, see the +\mdline{934}\mdref{sec-mastership-updates}{previous section}\mdline{934} for details.%mdk + +%mdk-data-line={936} +\section{\mdline{936}6.\hspace*{0.5em}\mdline{936}The P4Info Message}\label{sec-the-p4info-message}%mdk%mdk + +%mdk-data-line={938} +\noindent\mdline{938}The purpose of P4Info was described under +\mdline{939}\mdref{sec-reference-architecture}{Reference Architecture}\mdline{939}. +Here we describe the various +components.%mdk + +%mdk-data-line={943} +\subsection{\mdline{943}6.1.\hspace*{0.5em}\mdline{943}Common Messages}\label{sec-common-messages}%mdk%mdk + +%mdk-data-line={945} +\noindent\mdline{945}These messages appear nested within many other messages.%mdk + +%mdk-data-line={947} +\subsubsection{\mdline{947}6.1.1.\hspace*{0.5em}\mdline{947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{947} Message}\label{sec-documentation-message}%mdk%mdk + +%mdk-data-line={949} +\noindent\mdline{949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{949} is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers.%mdk + +%mdk-data-line={953} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={954} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Documentation~\{\\ +~~{\mdcolor{darkgreen}//~A~brief~description~of~something,~e.g.~one~sentence}\\ +~~{\bfseries{\mdcolor{navy}string}}~brief~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~A~more~verbose~description~of~something.}\\ +~~{\mdcolor{darkgreen}//~Multiline~is~accepted.~Markup~format~(if~any)~is~TBD.}\\ +~~{\bfseries{\mdcolor{navy}string}}~description~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={963} +\subsubsection{\mdline{963}6.1.2.\hspace*{0.5em}\mdline{963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{963} Message}\label{sec-preamble-message}%mdk%mdk + +%mdk-data-line={965} +\noindent\mdline{965}The preamble serves as the \mdline{965}\textquotedblleft{}descriptor\textquotedblright{}\mdline{965} for each entity and contains the unique +instance ID, name, alias, annotations and documentation.%mdk + +%mdk-data-line={968} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={969} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Preamble~\{\\ +~~{\mdcolor{darkgreen}//~ids~share~the~same~number-space;~e.g.~table~ids~cannot~overlap~with~counter}\\ +~~{\mdcolor{darkgreen}//~ids.~Even~though~this~is~irrelevant~to~this~proto~definition,~the~ids~are}\\ +~~{\mdcolor{darkgreen}//~allocated~in~such~a~way~that~it~is~possible~based~on~an~id~to~deduce~the}\\ +~~{\mdcolor{darkgreen}//~resource~type~(e.g.~table,~action,~counter,~...).~This~means~that~code}\\ +~~{\mdcolor{darkgreen}//~using~these~ids~can~detect~if~the~wrong~resource~type~is~used}\\ +~~{\mdcolor{darkgreen}//~somewhere.~This~also~means~that~ids~of~different~types~can~be~mixed}\\ +~~{\mdcolor{darkgreen}//~(e.g.~direct~resource~list~for~a~table)~without~ambiguity.~Note~that~id~0}\\ +~~{\mdcolor{darkgreen}//~is~reserved~and~means~"invalid~id".}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name~of~the~P4~object,~e.g.~c1.c2.ipv4\_lpm}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~an~alias~(alternative~name)~for~the~P4~object,~probably~shorter~than~its}\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name.~The~only~constraint~is~for~it~to~be~unique~with}\\ +~~{\mdcolor{darkgreen}//~respect~to~other~P4~objects~of~the~same~type.~By~default,~the~compiler~uses}\\ +~~{\mdcolor{darkgreen}//~the~shortest~suffix~of~the~name~that~uniquely~identifies~the~object.~For}\\ +~~{\mdcolor{darkgreen}//~example~if~the~P4~program~contains~two~tables~with~names~s.c1.t~and~s.c2.t,}\\ +~~{\mdcolor{darkgreen}//~the~default~aliases~will~respectively~be~c1.t~and~c2.t.~In~the~future,~the}\\ +~~{\mdcolor{darkgreen}//~P4~programmer~may~also~be~able~to~override~the~default~alias~for~any~P4}\\ +~~{\mdcolor{darkgreen}//~object~(TBD).}\\ +~~{\bfseries{\mdcolor{navy}string}}~alias~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~The~location~of~`annotations{}[i]`~is~given~by~`annotation\_locations{}[i]`.}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~SourceLocation~annotation\_locations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~Documentation~of~the~entity}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={999} +\subsubsection{\mdline{999}6.1.3.\hspace*{0.5em}\mdline{999}Annotating P4 Entities with \mdline{999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}\label{sec-annotating-p4-entities-with-documentation}%mdk%mdk + +%mdk-data-line={1001} +\noindent\mdline{1001}P4 entities may be annotated using the following annotations:%mdk + +%mdk-data-line={1003} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1004} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}(string...)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}(string...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1008} +\noindent\mdline{1008}Attaching either or both of these annotations to an entity will generate a +P4Info\mdline{1009}~\mdref{sec-documentation-message}{Documentation Message}\mdline{1009}, which in turn will +appear in the\mdline{1010}~\mdref{sec-preamble-message}{Preamble Message}\mdline{1010} for the entity.%mdk + +%mdk-data-line={1012} +\mdline{1012}The P4 compiler should not emit \mdline{1012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation}}}\mdline{1012} messages in the P4Info for these +specific cases; instead, it should generate the \mdline{1013}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1013} messages as +described.%mdk + +%mdk-data-line={1016} +\mdline{1016}The following example shows documentation annotations for a \mdline{1016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table}}}\mdline{1016} entity:%mdk + +%mdk-data-line={1018} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1019} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port.~\textbackslash{}}\\ +Uses~LPM~match~{\bfseries{\mdcolor{navy}type}}.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}table~my\_ipv4\_lkup~\{}\\ +{\mdcolor{maroon}~~...}\\ +{\mdcolor{maroon}\}}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1027} +\subsubsection{\mdline{1027}6.1.4.\hspace*{0.5em}\mdline{1027}Structured Annotations}\label{sec-structured-annotations}%mdk%mdk + +%mdk-data-line={1029} +\noindent\mdline{1029}P4 supports both unstructured and structured annotations\mdline{1029}~[\mdcite{p4annotations}{13}]\mdline{1029}. +Unstructured annotations of the form \mdline{1030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno1}}}\mdline{1030} or \mdline{1030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno2(body-content)}}}\mdline{1030} can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +\mdline{1033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno3{}[]}}}\mdline{1033} or \mdline{1033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno4{}[kvList\textbar{}expressionList]}}}\mdline{1033} have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this.%mdk + +%mdk-data-line={1038} +\mdline{1038}The annotations described up to this point, \mdline{1038}e.g.\mdline{1038} \mdline{1038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief()}}}\mdline{1038}, have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as \mdline{1040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1040} fields in the various \mdline{1040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{1040}s. +Similarly, structured annotations are represented in \mdline{1041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated\\ +StructuredAnnotation~structured\_annotations}}}\mdline{1042} fields which are siblings to the +unstructured \mdline{1043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1043}. The \mdline{1043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations}}}\mdline{1043} contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations.%mdk + +%mdk-data-line={1048} +\mdline{1048}The structured annotation messages are defined in p4types.proto.%mdk + +%mdk-data-line={1050} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1051} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~KeyValuePair~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~key~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Expression~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~KeyValuePairList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~KeyValuePair~kv\_pairs~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Expression~\{\\ +~~{\bfseries{\mdcolor{navy}oneof}}~value~\{\\ +~~~~{\bfseries{\mdcolor{navy}string}}~string\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~{\bfseries{\mdcolor{navy}int64}}~int64\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~{\bfseries{\mdcolor{navy}bool}}~bool\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~ExpressionList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Expression~expressions~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~StructuredAnnotation~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}oneof}}~body~\{\\ +~~~~ExpressionList~expression\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~KeyValuePairList~kv\_pair\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~Location~of~the~'@'~symbol~of~this~annotation~in~the~source~code.}\\ +~~SourceLocation~source\_location~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1083} +\noindent\mdline{1083}The \mdline{1083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1083} message can represent either a \mdline{1083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1083} +or an \mdline{1084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExpressionList}}}\mdline{1084}.%mdk + +%mdk-data-line={1086} +\mdline{1086}The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The \mdline{1087}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{1087} +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don\mdline{1089}'\mdline{1089}t match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler \mdline{1091}\emph{may}\mdline{1091} print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions.%mdk + +%mdk-data-line={1095} +\mdline{1095}The following invariants hold:%mdk + +%mdk-data-line={1097} +\begin{enumerate}%mdk + +%mdk-data-line={1097} +\item{} +%mdk-data-line={1097} +\mdline{1097}For any P4 entity, there are no two \mdline{1097}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1097}s that have the +same name.%mdk%mdk + +%mdk-data-line={1100} +\item{} +%mdk-data-line={1100} +\mdline{1100}Within a \mdline{1100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1100}, there are no two \mdline{1100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePair}}}\mdline{1100}s that have the +same \mdline{1101}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key.}}}\mdline{1101}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1103} +\paragraph{\mdline{1103}6.1.4.1.\hspace*{0.5em}\mdline{1103}Structured Annotation Examples}\label{sec-structured-annotation-examples}%mdk%mdk + +%mdk-data-line={1105} +\noindent\mdline{1105}We omit the \mdline{1105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}source\_location}}}\mdline{1105} field in the following examples.%mdk + +%mdk-data-line={1107} +\mdline{1107}\textbf{Empty Expression List}\mdline{1107}%mdk + +%mdk-data-line={1109} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1110} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}Empty}{\mdcolor{maroon}{}[]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1116} +\noindent\mdline{1116}The generated P4Info will contain the following.%mdk + +%mdk-data-line={1118} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1119} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}Empty}{\mdcolor{maroon}"}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1124} +\noindent\mdline{1124}\textbf{Mixed Expression List}\mdline{1124}%mdk + +%mdk-data-line={1126} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1127} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~TEXT\_CONST~"hello"}\\ +{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~NUM\_CONST~6}\\ +{\mdcolor{gray}@}{\mdcolor{gray}MixedExprList}{\mdcolor{maroon}{}[1,TEXT\_CONST,true,1==2,5+NUM\_CONST]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1135} +\noindent\mdline{1135}The generated P4Info will contain:%mdk + +%mdk-data-line={1137} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1138} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedExprList}{\mdcolor{maroon}"}\\ +~~expression\_list~\{\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}1}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}hello}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~true\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~false\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}11}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1160} +\noindent\mdline{1160}\textbf{kvList of Mixed Expressions}\mdline{1160}%mdk + +%mdk-data-line={1162} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1163} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}MixedKV}{\mdcolor{maroon}{}[label="text",~my\_bool=true,~int\_val=2*3]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1169} +\noindent\mdline{1169}The generated P4Info will contain:%mdk + +%mdk-data-line={1171} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1172} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedKV}{\mdcolor{maroon}"}\\ +~~kv\_pair\_list~\{\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}label}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}text}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}my\_bool}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~bool\_value:~true\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}int\_val}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~int64\_value:~{\mdcolor{purple}6}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1197} +\subsubsection{\mdline{1197}6.1.5.\hspace*{0.5em}\mdline{1197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1197} Message}\label{sec-sourcelocation-message}%mdk%mdk + +%mdk-data-line={1199} +\noindent\mdline{1199}A source location describes a location within a \mdline{1199}\emph{.p4}\mdline{1199}-source file. The +\mdline{1200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1200} message is defined in p4types.proto as follows:%mdk + +%mdk-data-line={1202} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1203} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Location~of~code~relative~to~a~given~source~file.}\\ +{\bfseries{\mdcolor{navy}message}}~SourceLocation~\{\\ +~~{\mdcolor{darkgreen}//~Path~to~the~source~file~(absolute~or~relative~to~the~working~directory).}\\ +~~{\bfseries{\mdcolor{navy}string}}~file~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Line~and~column~numbers~within~the~source~file,~1-based.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~line~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}int32}}~column~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1213} +\noindent\mdline{1213}We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations.%mdk + +%mdk-data-line={1218} +\mdline{1218}The \mdline{1218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1218} message associated with an annotation holds the location of +the \mdline{1219}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@}}}\mdline{1219} symbol introducing the annotation in the P4 source code; the message can +be found in the following place:%mdk + +%mdk-data-line={1222} +\begin{itemize}%mdk + +%mdk-data-line={1222} +\item{} +%mdk-data-line={1222} +\mdline{1222}For \mdline{1222}\textbf{unstructured annotations}\mdline{1222}, every message containing a field +\mdline{1223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1223} also contains a field +\mdline{1224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~SourceLocation~annotation\_locations}}}\mdline{1224}. The i-th member of +\mdline{1225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation\_locations}}}\mdline{1225} is the source location of the i-th member of +\mdline{1226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1226}.%mdk%mdk + +%mdk-data-line={1228} +\item{} +%mdk-data-line={1228} +\mdline{1228}For \mdline{1228}\textbf{structured annotations}\mdline{1228}, every \mdline{1228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1228} message contains +a field \mdline{1229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation~source\_location}}}\mdline{1229} holding its source location.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1232} +\subsection{\mdline{1232}6.2.\hspace*{0.5em}\mdline{1232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1232} Message}\label{sec-pkginfo-message}%mdk%mdk + +%mdk-data-line={1234} +\noindent\mdline{1234}The \mdline{1234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1234} message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. \mdline{1235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1235} can be extracted +and used to facilitate \mdline{1236}\textquotedblleft{}browsing\textquotedblright{}\mdline{1236} of available P4 programs from a +library. Although all fields are technically \mdline{1237}\textquotedblleft{}optional,\textquotedblright{}\mdline{1237} every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included.%mdk + +%mdk-data-line={1241} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1242} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Can~be~used~to~manage~multiple~P4~packages.}\\ +{\bfseries{\mdcolor{navy}message}}~PkgInfo~\{\\ +~~{\mdcolor{darkgreen}//~a~definitive~name~for~this~configuration,~e.g.~switch.p4\_v1.0}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~configuration~version,~free-format~string}\\ +~~{\bfseries{\mdcolor{navy}string}}~version~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~brief~and~detailed~descriptions}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~free-form;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~the~target~architecture,~e.g.~"psa"}\\ +~~{\bfseries{\mdcolor{navy}string}}~arch~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\mdcolor{darkgreen}//~organization~which~produced~the~configuration,~e.g.~"p4.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~organization~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~{\mdcolor{darkgreen}//~contact~info~for~support,e.g.~"tech-support@acme.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~contact~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~url~for~more~information,~e.g.~"http://support.p4.org/ref/p4/switch.p4\_v1.0"}\\ +~~{\bfseries{\mdcolor{navy}string}}~url~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}8};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~structured;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}9};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1265} +\subsubsection{\mdline{1265}6.2.1.\hspace*{0.5em}\mdline{1265}Annotating P4 code with PkgInfo}\label{sec-annotating-p4-code-with-pkginfo}%mdk%mdk + +%mdk-data-line={1267} +\noindent\mdline{1267}A P4 progam\mdline{1267}'\mdline{1267}s \mdline{1267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1267} may be declared using one or more of the following +annotations, attached to the \mdline{1268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1268} block only:%mdk + +%mdk-data-line={1270} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1271} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value{}[,key=value,...])}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("A~brief~description")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("A~longer\textbackslash{}}\\ +description{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@custom\_annotation(...)}\\ +{\mdcolor{maroon}@another\_custom\_annotation(...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1280} +\noindent\mdline{1280}Above we see several different types of annotations:%mdk + +%mdk-data-line={1282} +\begin{itemize}%mdk + +%mdk-data-line={1282} +\item{} +%mdk-data-line={1282} +\mdline{1282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1282} \mdline{1282}- This is used to populate a specific field within the \mdline{1282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1282} +message. Multiple \mdline{1283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1283} annotations are allowed. For compactness, +multiple key-value pairs can appear in a single \mdline{1284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1284} annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The \mdline{1286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{1286}s must be from +among the message fields inside \mdline{1287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1287}, for example, \mdline{1287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1287}, \mdline{1287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}version}}}\mdline{1287}, +etc. Each key-value pair assigns a value to the corresponding field inside the +single \mdline{1289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1289} message for the program\mdline{1289}'\mdline{1289}s P4Info. One exception is that the +\mdline{1290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1290} field of \mdline{1290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1290} must be expressed as individual +\mdline{1291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1291} and \mdline{1291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1291} annotations, see next bullets. The key \mdline{1291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}arch}}}\mdline{1291} will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself.%mdk%mdk + +%mdk-data-line={1295} +\item{} +%mdk-data-line={1295} +\mdline{1295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1295} \mdline{1295}- This will populate the \mdline{1295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.brief}}}\mdline{1295} message field.%mdk%mdk + +%mdk-data-line={1297} +\item{} +%mdk-data-line={1297} +\mdline{1297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1297} \mdline{1297}- This will populate the \mdline{1297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.description}}}\mdline{1297} message +field%mdk%mdk + +%mdk-data-line={1300} +\item{} +%mdk-data-line={1300} +\mdline{1300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@\textless{}anything~else\textgreater{}}}}\mdline{1300} \mdline{1300}- This will create a \mdline{1300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotation}}}\mdline{1300} entry%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1302} +\noindent\mdline{1302}Declaring one or more of these annotations on \mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1302} will +generate a single corresponding \mdline{1303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1303} message in the P4Info as described in +\mdline{1304}\mdref{sec-pkginfo-message}{PkgInfo Message}\mdline{1304}.%mdk + +%mdk-data-line={1306} +\mdline{1306}The following example shows \mdline{1306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1306} annotations using a mixture of single and +multiple key-value pairs. It also shows \mdline{1307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1307} and \mdline{1307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1307} annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the \mdline{1309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1309} message. The custom annotations will +be appended to the \mdline{1310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotations}}}\mdline{1310} list.%mdk + +%mdk-data-line={1312} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1313} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(name="switch.p4",version="2")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(organization="p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(contact="info@p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(url="www.p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("L2/L3~switch")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("L2/L3~switch.\textbackslash{}}\\ +Built~for~data-center~profile.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@my\_annotation1(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}@my\_annotation2(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}PSA\_Switch(IgPipeline,~PacketReplicationEngine(),~EgPipeline,}\\ +{\mdcolor{maroon}~~~~~~~~~~~BufferingQueueingEngine())~main;}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1326} +\subsection{\mdline{1326}6.3.\hspace*{0.5em}\mdline{1326}ID Allocation for P4Info Objects}\label{sec-id-allocation}%mdk%mdk + +%mdk-data-line={1328} +\noindent\mdline{1328}P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(\mdline{1332}e.g.\mdline{1332} table, action, counter, \mdline{1332}\dots{}\mdline{1332}). The most significant 8 bits of the ID +encodes the object type (as per Table\mdline{1333}~\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}}\mdline{1333}). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (\mdline{1335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.P4Ids.Prefix}}}\mdline{1335}). These values must +be used (\mdline{1336}e.g.\mdline{1336} by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table\mdline{1338}~\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}}\mdline{1338} shows the ID +layout.%mdk + +%mdk-data-line={1341} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1343} 8-bit prefix value}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1343} P4 object type}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{1345} 0x00}&\multicolumn{1}{|l|}{\mdline{1345} Reserved (unspecified)}\\ +\multicolumn{1}{|l}{\mdline{1346} 0x01}&\multicolumn{1}{|l|}{\mdline{1346} Action}\\ +\multicolumn{1}{|l}{\mdline{1347} 0x02}&\multicolumn{1}{|l|}{\mdline{1347} Table}\\ +\multicolumn{1}{|l}{\mdline{1348} 0x03}&\multicolumn{1}{|l|}{\mdline{1348} Value-set}\\ +\multicolumn{1}{|l}{\mdline{1349} 0x04}&\multicolumn{1}{|l|}{\mdline{1349} Controller header (header type with \mdline{1349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1349} annotation)}\\ +\multicolumn{1}{|l}{\mdline{1350} 0x05\mdline{1350}\dots{}\mdline{1350}0x0f}&\multicolumn{1}{|l|}{\mdline{1350} Reserved (for future P4 built-in objects)}\\ +\multicolumn{1}{|l}{\mdline{1351} 0x10}&\multicolumn{1}{|l|}{\mdline{1351} Reserved (start of PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1352} 0x11}&\multicolumn{1}{|l|}{\mdline{1352} PSA Action profiles / selectors}\\ +\multicolumn{1}{|l}{\mdline{1353} 0x12}&\multicolumn{1}{|l|}{\mdline{1353} PSA Counter}\\ +\multicolumn{1}{|l}{\mdline{1354} 0x13}&\multicolumn{1}{|l|}{\mdline{1354} PSA Direct counter}\\ +\multicolumn{1}{|l}{\mdline{1355} 0x14}&\multicolumn{1}{|l|}{\mdline{1355} PSA Meter}\\ +\multicolumn{1}{|l}{\mdline{1356} 0x15}&\multicolumn{1}{|l|}{\mdline{1356} PSA Direct meter}\\ +\multicolumn{1}{|l}{\mdline{1357} 0x16}&\multicolumn{1}{|l|}{\mdline{1357} PSA Register}\\ +\multicolumn{1}{|l}{\mdline{1358} 0x17}&\multicolumn{1}{|l|}{\mdline{1358} PSA Digest}\\ +\multicolumn{1}{|l}{\mdline{1359} 0x18\mdline{1359}\dots{}\mdline{1359}0x7f}&\multicolumn{1}{|l|}{\mdline{1359} Reserved (for future PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1360} 0x80}&\multicolumn{1}{|l|}{\mdline{1360} Reserved (start of vendor-specific extern types)}\\ +\multicolumn{1}{|l}{\mdline{1361} 0x81\mdline{1361}\dots{}\mdline{1361}0xfe}&\multicolumn{1}{|l|}{\mdline{1361} Vendor-specific extern types}\\ +\multicolumn{1}{|l}{\mdline{1362} 0xff}&\multicolumn{1}{|l|}{\mdline{1362} Reserved (max prefix value)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1364} +\mdhr{}%mdk + +%mdk-data-line={1365} +\noindent\mdline{1365}\mdcaption{\textbf{Table~\mdcaptionlabel{1}.}~\mdcaptiontext{Mapping of P4Info object type to 8-bit ID prefix value}}%mdk +%mdk +\end{mdcenter}\label{tab-mapping-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1368} +\begin{table}[h!]%mdk +\begin{mdblock}{text-align=center,breakable=true}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{cc}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1370} MSB bit 31 \mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}.. bit 24}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1370} bit 23 \mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}.. bit 0 LSB}}\\ + +\midrule +\multicolumn{1}{|c}{\mdline{1372} Object type prefix}&\multicolumn{1}{|c|}{\mdline{1372} Generated suffix (\mdline{1372}e.g.\mdline{1372} by the compiler)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1374} +\mdhr{}%mdk + +%mdk-data-line={1375} +\noindent\mdline{1375}\mdcaption{\textbf{Table~\mdcaptionlabel{2}.}~\mdcaptiontext{Format of P4Info object IDs}}%mdk%mdk +\end{mdblock}\label{tab-format-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1379} +\mdline{1379}It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with \mdline{1380}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1380} (see Table +\mdline{1381}\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}}\mdline{1381}). The compiler must honor the \mdline{1381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1381} annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (\mdline{1383}i.e.\mdline{1383} if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same \mdline{1385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1385} value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct.%mdk + +%mdk-data-line={1394} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth-7cm)/1}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{\mdinline{width=7cm}{{\bfseries\mdline{1396} P4 declaration(s)}}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1396} Compiler-allocated ID(s)}}\\ + +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1398} \mdline{1398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1398}}}&\multicolumn{1}{|l|}{\mdline{1398} 0x0212ab34}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1400} \mdline{1400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1400}}}&\multicolumn{1}{|l|}{\mdline{1400} \mdline{1400}\textbf{Error}\mdline{1400}(same ID suffixes for 2 objects of the same type)}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1401} \mdline{1401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tB...}}}\mdline{1401}}}&\multicolumn{1}{|l|}{\mdline{1401}}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1403} \mdline{1403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1403}}}&\multicolumn{1}{|l|}{\mdline{1403} 0x0212ab34}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1404} \mdline{1404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~action~act1...}}}\mdline{1404}}}&\multicolumn{1}{|l|}{\mdline{1404} 0x0112ab34}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1406} +\mdhr{}%mdk + +%mdk-data-line={1407} +\noindent\mdline{1407}\mdcaption{\textbf{Table~\mdcaptionlabel{3}.}~\mdcaptiontext{Example of statically-assigned P4Info object IDs}}%mdk +%mdk +\end{mdcenter}\label{tab-exmpl-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1410} +\mdline{1410}The \mdline{1410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1410} annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively).%mdk + +%mdk-data-line={1416} +\subsection{\mdline{1416}6.4.\hspace*{0.5em}\mdline{1416}P4Info Objects}\label{sec-p4info-objects}%mdk%mdk + +%mdk-data-line={1418} +\subsubsection{\mdline{1418}6.4.1.\hspace*{0.5em}\mdline{1418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}\label{sec-table}%mdk%mdk + +%mdk-data-line={1420} +\noindent\mdline{1420}Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields:%mdk + +%mdk-data-line={1423} +\begin{itemize}%mdk + +%mdk-data-line={1423} +\item{} +%mdk-data-line={1423} +\mdline{1423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1423}, a \mdline{1423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1423} message with the ID, name, and alias of this table.%mdk%mdk + +%mdk-data-line={1425} +\item{} +%mdk-data-line={1425} +\mdline{1425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1425}, a repeated field of type \mdline{1425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1425} representing the data to +be used to construct the lookup key matched in this table. Each \mdline{1426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1426} +message is defined with the following fields:%mdk + +%mdk-data-line={1429} +\begin{itemize}%mdk + +%mdk-data-line={1429} +\item{} +%mdk-data-line={1429} +\mdline{1429}id, the \mdline{1429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1429} identifier of this \mdline{1429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1429}, unique in the scope of +this table. No rules are prescribed on the way \mdline{1430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1430} IDs should be +allocated, as long as two \mdline{1431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1431} of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the \mdline{1435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1435} annotation, or let the compiler +choose them.%mdk%mdk + +%mdk-data-line={1438} +\item{} +%mdk-data-line={1438} +\mdline{1438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1438}, the string representing the name of this \mdline{1438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1438}.%mdk%mdk + +%mdk-data-line={1440} +\item{} +%mdk-data-line={1440} +\mdline{1440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1440}, a repeated field of strings, each one representing a P4 +annotation associated to this match field.%mdk%mdk + +%mdk-data-line={1443} +\item{} +%mdk-data-line={1443} +\mdline{1443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1443}, an \mdline{1443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1443} value set to the size in bits of this match field.%mdk%mdk + +%mdk-data-line={1445} +\item{} +%mdk-data-line={1445} +\mdline{1445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1445}, a \mdline{1445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{1445} describing the match behavior for this field; it can be +either:%mdk + +%mdk-data-line={1447} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1447} +\item\mdline{1447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1447}, an enum field of type \mdline{1447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchType}}}\mdline{1447}, which includes all +possible PSA match kinds.%mdk + +%mdk-data-line={1449} +\item\mdline{1449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_match\_type}}}\mdline{1449}, a string field which can be used to encode any +architecture-specific match type.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1452} +\item{} +%mdk-data-line={1452} +\mdline{1452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1452}, a \mdline{1452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1452} message describing this match field.%mdk%mdk + +%mdk-data-line={1454} +\item{} +%mdk-data-line={1454} +\mdline{1454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1454}, which indicates whether the match field has a\mdline{1454}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1455}; this is useful for +\mdline{1456}\mdref{sec-psa-metadata-translation}{translation}\mdline{1456}.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1458} +\item{} +%mdk-data-line={1458} +\mdline{1458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_refs}}}\mdline{1458}, a repeated \mdline{1458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1458} field representing the set of possible +actions for this table. The \mdline{1459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1459} message is used to reference an action +specified in the same P4Info message and it includes the following fields:%mdk + +%mdk-data-line={1461} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1461} +\item\mdline{1461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1461}, the \mdline{1461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1461} identifier of the action.%mdk + +%mdk-data-line={1462} +\item\mdline{1462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1462}, an enum value which can take one of three values: + \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1463}, \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1463} and \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1463}. The \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1463} of the + action is determined by the use of the P4 standard annotations + \mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1465} and \mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1465}~[\mdcite{p4actionannotations}{18}]\mdline{1465}. \mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1465} + (\mdline{1466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1466} annotation) means that the action can only appear within + the table, and never as the default action. \mdline{1467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1467} + (\mdline{1468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1468} annotation) means that the action can only be used as the + default action. \mdline{1469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1469} is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action.%mdk + +%mdk-data-line={1472} +\item\mdline{1472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1472}, a repeated string field, each one representing a P4 +annotation associated to the action \mdline{1473}\emph{reference}\mdline{1473} in this table.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1475} +\item{} +%mdk-data-line={1475} +\mdline{1475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\_default\_action\_id}}}\mdline{1475}, if this table has a constant default action, this +field will carry the \mdline{1476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1476} identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action\mdline{1479}'\mdline{1479}s +arguments.%mdk%mdk + +%mdk-data-line={1482} +\item{} +%mdk-data-line={1482} +\mdline{1482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation\_id}}}\mdline{1482}, the \mdline{1482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1482} identifier of the \mdline{1482}\textquotedblleft{}implementation\textquotedblright{}\mdline{1482} of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (\mdline{1485}e.g.\mdline{1485} a PSA \mdline{1485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1485} or \mdline{1485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{1485} +instance). The table is then referred to as an indirect match table.%mdk%mdk + +%mdk-data-line={1488} +\item{} +%mdk-data-line={1488} +\mdline{1488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_resource\_ids}}}\mdline{1488}, repeated \mdline{1488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1488} identifiers for all the direct +resources attached to this table, such as \mdline{1489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1489} and \mdline{1489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1489} +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2.%mdk%mdk + +%mdk-data-line={1495} +\item{} +%mdk-data-line={1495} +\mdline{1495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1495}, an \mdline{1495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1495} describing the desired number of table entries that the +target should support for the table. See the \mdline{1496}\textquotedblleft{}Size\textquotedblright{}\mdline{1496} subsection within the +\mdline{1497}\textquotedblleft{}Table Properties\textquotedblright{}\mdline{1497} section of the P4\mdline{1497}\mdsub{16}\mdline{1497} language specification for details +\mdline{1498}[\mdcite{p4tableproperties}{30}]\mdline{1498}.%mdk%mdk + +%mdk-data-line={1500} +\item{} +%mdk-data-line={1500} +\mdline{1500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_behavior}}}\mdline{1500}, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +\mdline{1502}\mdref{sec-idle-timeout}{Idle-Timeout}\mdline{1502} section). Value can be any of the +\mdline{1503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutBehavior}}}\mdline{1503} enum:%mdk + +%mdk-data-line={1504} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1504} +\item\mdline{1504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NO\_TIMEOUT}}}\mdline{1504} (default value), which means that idle timeout is not +supported for this table.%mdk + +%mdk-data-line={1506} +\item\mdline{1506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOTIFY\_CONTROL}}}\mdline{1506}, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +\mdline{1508}\mdref{sec-table-idle-timeout-notification}{Table Idle Timeout Notifications}\mdline{1508}).%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1510} +\item{} +%mdk-data-line={1510} +\mdline{1510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{1510}, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime.%mdk%mdk + +%mdk-data-line={1513} +\item{} +%mdk-data-line={1513} +\mdline{1513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{1513}, an \mdline{1513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1513} Protobuf message\mdline{1513}~[\mdcite{protoany}{31}]\mdline{1513} to embed +architecture-specific table properties\mdline{1514}~[\mdcite{p4tableproperties}{30}]\mdline{1514} which are not part +of the core P4 language or of the PSA architecture.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1517} +\subsubsection{\mdline{1517}6.4.2.\hspace*{0.5em}\mdline{1517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}\label{sec-action}%mdk%mdk + +%mdk-data-line={1519} +\noindent\mdline{1519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1519} messages are used to specify all possible actions of all match-action +tables.%mdk + +%mdk-data-line={1522} +\mdline{1522}The \mdline{1522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1522} message defines the following fields:%mdk + +%mdk-data-line={1524} +\begin{itemize}%mdk + +%mdk-data-line={1524} +\item{} +%mdk-data-line={1524} +\mdline{1524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1524}, a \mdline{1524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1524} message with the ID, name, and alias of this action%mdk%mdk + +%mdk-data-line={1526} +\item{} +%mdk-data-line={1526} +\mdline{1526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{1526}, a repeated field of \mdline{1526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1526} messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each \mdline{1528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1528} message contains the +following fields:%mdk + +%mdk-data-line={1530} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1530} +\item\mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1530}, the \mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1530} identifier of this parameter. No rules are prescribed +on the way \mdline{1531}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1531} IDs should be allocated, as long as two \mdline{1531}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1531} of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the \mdline{1535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1535} +annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1537} +\item\mdline{1537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1537}, the string representing the name of this parameter.%mdk + +%mdk-data-line={1538} +\item\mdline{1538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1538}, a repeated field of strings, each one representing a P4 +annotation associated to this parameter.%mdk + +%mdk-data-line={1540} +\item\mdline{1540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1540}, an \mdline{1540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1540} value set to the size in bits of this parameter.%mdk + +%mdk-data-line={1541} +\item\mdline{1541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1541}, which describes this parameter using a \mdline{1541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1541} message.%mdk + +%mdk-data-line={1542} +\item\mdline{1542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1542}, which indicates whether the action parameter has a +\mdline{1543}\mdref{sec-user-defined-types}{user-defined type}\mdline{1543}; this is useful for +\mdline{1544}\mdref{sec-psa-metadata-translation}{translation}\mdline{1544}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1546} +\subsubsection{\mdline{1546}6.4.3.\hspace*{0.5em}\mdline{1546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}\label{sec-p4info-action-profile}%mdk%mdk + +%mdk-data-line={1548} +\noindent\mdline{1548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1548} messages are used to specify all available instances of Action +Profile and Action Selector PSA externs.%mdk + +%mdk-data-line={1551} +\mdline{1551}PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile \mdline{1555}\emph{member}\mdline{1555}, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime.%mdk + +%mdk-data-line={1559} +\mdline{1559}PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into \mdline{1560}\emph{groups}\mdline{1560}. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime.%mdk + +%mdk-data-line={1569} +\mdline{1569}While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same \mdline{1570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1570} message to describe both.%mdk + +%mdk-data-line={1572} +\mdline{1572}The \mdline{1572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1572} message includes the following fields:%mdk + +%mdk-data-line={1574} +\begin{itemize}%mdk + +%mdk-data-line={1574} +\item{} +%mdk-data-line={1574} +\mdline{1574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1574}, a \mdline{1574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1574} message with the ID, name, and alias of this Action +Profile or Selector.%mdk%mdk + +%mdk-data-line={1577} +\item{} +%mdk-data-line={1577} +\mdline{1577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_ids}}}\mdline{1577}, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector.%mdk%mdk + +%mdk-data-line={1580} +\item{} +%mdk-data-line={1580} +\mdline{1580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}with\_selector}}}\mdline{1580}, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern.%mdk%mdk + +%mdk-data-line={1583} +\item{} +%mdk-data-line={1583} +\mdline{1583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1583}, an \mdline{1583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1583} representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups.%mdk%mdk + +%mdk-data-line={1587} +\item{} +%mdk-data-line={1587} +\mdline{1587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1587}, an \mdline{1587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1587} representing the maximum sum of all member +weights within any given selector group, in the case of an Action Selector, or +0 for an Action Profile. PSA programs can use the \mdline{1589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{1589} annotation +to provide this value for Action Selectors. If the annotation is omitted, the +P4Info field will default to 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1593} +\subsubsection{\mdline{1593}6.4.4.\hspace*{0.5em}\mdline{1593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1593} \mdline{1593}\&\mdline{1593} \mdline{1593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}\label{sec-counter-directcounter}%mdk%mdk + +%mdk-data-line={1595} +\noindent\mdline{1595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1595} and \mdline{1595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1595} messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is:%mdk + +%mdk-data-line={1601} +\begin{itemize}%mdk + +%mdk-data-line={1601} +\item{} +%mdk-data-line={1601} +\mdline{1601}Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index.%mdk%mdk + +%mdk-data-line={1605} +\item{} +%mdk-data-line={1605} +\mdline{1605}Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1608} +\noindent\mdline{1608}Both \mdline{1608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1608} and \mdline{1608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1608} messages share the following fields:%mdk + +%mdk-data-line={1610} +\begin{itemize}%mdk + +%mdk-data-line={1610} +\item{} +%mdk-data-line={1610} +\mdline{1610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1610}, a \mdline{1610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1610} message with the ID, name, and alias of this counter +extern instance.%mdk%mdk + +%mdk-data-line={1613} +\item{} +%mdk-data-line={1613} +\mdline{1613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1613}, a message of of type \mdline{1613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1613} used to describe the compile-time +configuration of this counter. Currently, the \mdline{1614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1614} message is used to +carry only the counter unit, which can be any of the \mdline{1615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec.Unit}}}\mdline{1615} enum +values:%mdk + +%mdk-data-line={1617} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1617} +\item\mdline{1617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1617}: reserved value.%mdk + +%mdk-data-line={1618} +\item\mdline{1618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1618}: byte counter.%mdk + +%mdk-data-line={1619} +\item\mdline{1619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1619}: packet counter.%mdk + +%mdk-data-line={1620} +\item\mdline{1620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BOTH}}}\mdline{1620}: combination of both byte and packet counter.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1622} +\noindent\mdline{1622}For indexed counters, the \mdline{1622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1622} message contains also a \mdline{1622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1622} field, an +\mdline{1623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1623} representing the maximum number of independent values that can be held +by this counter array. Conversely, the \mdline{1624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1624} message contains a +\mdline{1625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1625} field that carries the \mdline{1625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}unit32}}}\mdline{1625} identifier of the table to +which this direct counter is attached.%mdk + +%mdk-data-line={1628} +\mdline{1628}For indexed counters, the \mdline{1628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1628} message contains also an \mdline{1628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1628} +field, which indicates whether the index has a\mdline{1629}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1630}. This is useful for +\mdline{1631}\mdref{sec-psa-metadata-translation}{translation}\mdline{1631}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1632}).%mdk + +%mdk-data-line={1634} +\subsubsection{\mdline{1634}6.4.5.\hspace*{0.5em}\mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1634} \mdline{1634}\&\mdline{1634} \mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}\label{sec-meter-directmeter}%mdk%mdk + +%mdk-data-line={1636} +\noindent\mdline{1636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1636} and \mdline{1636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1636} messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is:%mdk + +%mdk-data-line={1642} +\begin{itemize}%mdk + +%mdk-data-line={1642} +\item{} +%mdk-data-line={1642} +\mdline{1642}Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +\mdline{1644}e.g.\mdline{1644} to set the rate threshold.%mdk%mdk + +%mdk-data-line={1646} +\item{} +%mdk-data-line={1646} +\mdline{1646}Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1649} +\noindent\mdline{1649}Both \mdline{1649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1649} and \mdline{1649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1649} messages share the following fields:%mdk + +%mdk-data-line={1651} +\begin{itemize}%mdk + +%mdk-data-line={1651} +\item{} +%mdk-data-line={1651} +\mdline{1651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1651}, a \mdline{1651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1651} message with the ID, name, and alias of this meter +extern instance.%mdk%mdk + +%mdk-data-line={1654} +\item{} +%mdk-data-line={1654} +\mdline{1654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1654}, a message of type \mdline{1654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1654} used to describe the capabilities of +this meter extern instance. Currently, the \mdline{1655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1655} message is used to +carry only the meter unit, which can be any of the \mdline{1656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Unit}}}\mdline{1656} enum +values:%mdk + +%mdk-data-line={1658} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1658} +\item\mdline{1658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1658}: reserved value.%mdk + +%mdk-data-line={1659} +\item\mdline{1659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1659}, which signifies that this meter can be configured with rates +expressed in bytes/second.%mdk + +%mdk-data-line={1661} +\item\mdline{1661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1661}, for rates expressed in packets/second.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1663} +\noindent\mdline{1663}For indexed meters, the \mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1663} message contains also a \mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1663} field, an \mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1663} +representing the maximum number of independent cells that can be held by this +meter. Conversely, the \mdline{1665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1665} message contains a \mdline{1665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1665} field +that carries the \mdline{1666}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1666} identifier of the table to which this direct meter is +attached.%mdk + +%mdk-data-line={1669} +\mdline{1669}For indexed meters, the \mdline{1669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1669} message contains also an \mdline{1669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1669} +field, which indicates whether the index has a\mdline{1670}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1671}. This is useful for +\mdline{1672}\mdref{sec-psa-metadata-translation}{translation}\mdline{1672}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1673}).%mdk + +%mdk-data-line={1675} +\subsubsection{\mdline{1675}6.4.6.\hspace*{0.5em}\mdline{1675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\label{sec-controller-packet-meta}%mdk%mdk + +%mdk-data-line={1677} +\noindent\mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1677} messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server.%mdk + +%mdk-data-line={1683} +\mdline{1683}When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet.%mdk + +%mdk-data-line={1689} +\mdline{1689}Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +\mdline{1691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_in")}}}\mdline{1691} and \mdline{1691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_out")}}}\mdline{1691}, +respectively. \mdline{1692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1692} messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages).%mdk + +%mdk-data-line={1697} +\mdline{1697}A P4Info message can contain at most two \mdline{1697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata~messages}}}\mdline{1697}, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields:%mdk + +%mdk-data-line={1701} +\begin{itemize}%mdk + +%mdk-data-line={1701} +\item{} +%mdk-data-line={1701} +\mdline{1701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1701}, a \mdline{1701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1701} message where \mdline{1701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble.name}}}\mdline{1701} is set to \mdline{1701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_in"}}}\mdline{1701} +and \mdline{1702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_out"}}}\mdline{1702} for packet-in and packet-out metadata, respectively.%mdk%mdk + +%mdk-data-line={1704} +\item{} +%mdk-data-line={1704} +\mdline{1704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{1704}, a repeated field of type \mdline{1704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1704}, where each \mdline{1704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1704} message +includes the following fields:%mdk + +%mdk-data-line={1706} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1706} +\item\mdline{1706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1706}, a \mdline{1706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1706} identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two \mdline{1707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1707} of the +same \mdline{1708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1708} message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the \mdline{1712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1712} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1713} +\item\mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1713}, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below).%mdk + +%mdk-data-line={1717} +\item\mdline{1717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1717}, a repeated field of strings, each one representing a P4 +annotation associated to this metadata.%mdk + +%mdk-data-line={1719} +\item\mdline{1719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1719}, an \mdline{1719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1719} representing the size in bits of this metadata.%mdk + +%mdk-data-line={1720} +\item\mdline{1720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1720}, which indicates whether the metadata field has a +\mdline{1721}\mdref{sec-user-defined-types}{user-defined type}\mdline{1721}; this is useful for +\mdline{1722}\mdref{sec-psa-metadata-translation}{translation}\mdline{1722}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1724} +\noindent\mdline{1724}As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding \mdline{1725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1725} +messages.%mdk + +%mdk-data-line={1728} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1729} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~egress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~port~where~the~packet}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~should~be~sent~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~queue\_id;~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~queue~ID~}{\mdcolor{darkgreen}*/}\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~ingress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~data~plane~port~ID~where}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~the~original~packet~was~received~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}1}\textgreater{}~is\_clone;~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~1~if~this~is~a~clone~of~the}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~original~packet~}{\mdcolor{darkgreen}*/}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1744} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1745} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868916615}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_out}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_out}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}egress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}queue\_id}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~\}\\ +\}\\ +\\ +controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868941301}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_in}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_in}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ingress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}is\_clone}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}1}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1782} +\noindent\mdline{1782}Note that the use of \mdline{1782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1782} is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages.%mdk + +%mdk-data-line={1788} +\subsubsection{\mdline{1788}6.4.7.\hspace*{0.5em}\mdline{1788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}\label{sec-valueset}%mdk%mdk + +%mdk-data-line={1790} +\noindent\mdline{1790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1790} messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P4\mdline{1793}\mdsub{16}\mdline{1793} +specification\mdline{1794}~[\mdcite{p4valuesets}{39}]\mdline{1794}.%mdk + +%mdk-data-line={1796} +\mdline{1796}The \mdline{1796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1796} message defines the following fields:%mdk + +%mdk-data-line={1798} +\begin{itemize}%mdk + +%mdk-data-line={1798} +\item{} +%mdk-data-line={1798} +\mdline{1798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1798}, a \mdline{1798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1798} message with the ID, name, and alias of this Value +Set.%mdk%mdk + +%mdk-data-line={1801} +\item{} +%mdk-data-line={1801} +\mdline{1801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1801}, a repeated field of \mdline{1801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1801} messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the \mdline{1804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1804} repeated field in the +\mdline{1805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{1805} message.%mdk%mdk + +%mdk-data-line={1807} +\item{} +%mdk-data-line={1807} +\mdline{1807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1807}, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +\mdline{1809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set}}}\mdline{1809} constructor call.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1811} +\noindent\mdline{1811}According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of \mdline{1814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1814}, +\mdline{1815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1815}, or \mdline{1815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1815}~[\mdcite{p4selectexpr}{26}]\mdline{1815}. The rest of this section looks at all 3 of +these cases and gives an example \mdline{1816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1816} message when appropriate.%mdk + +%mdk-data-line={1818} +\begin{enumerate}%mdk + +%mdk-data-line={1818} +\item{} +%mdk-data-line={1818} +\mdline{1818}If the type parameter is \mdline{1818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1818}, \mdline{1818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1818} will include exactly one +\mdline{1819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1819} message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used):%mdk + +%mdk-data-line={1822} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1822} +\item\mdline{1822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1822}: set to 1%mdk + +%mdk-data-line={1823} +\item\mdline{1823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1823}: set to the value of \mdline{1823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1823}%mdk + +%mdk-data-line={1824} +\item\mdline{1824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1824}: set to \mdline{1824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1824}%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1826} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1827} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}bit\textless{}8\textgreater{}~\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(hdr.f8)~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1830} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1831} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1845} +\begin{enumerate}[,start=2]%mdk + +%mdk-data-line={1845} +\item{} +%mdk-data-line={1845} +\mdline{1845}If the type parameter is a \mdline{1845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1845}, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program.%mdk%mdk + +%mdk-data-line={1850} +\item{} +%mdk-data-line={1850} +\mdline{1850}If the type parameter is a \mdline{1850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1850}, this version of P4Runtime requires that +all the fields of the struct be of type \mdline{1851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1851} (where \mdline{1851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1851} can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +\mdline{1854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1854} field will include one \mdline{1854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1854} message for each field in the +struct, with the following fields:%mdk + +%mdk-data-line={1857} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1857} +\item\mdline{1857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1857}: must be unique with respect to the other \mdline{1857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1857} entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +\mdline{1861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1861} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1862} +\item\mdline{1862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1862}: set to the name of the corresponding struct field.%mdk + +%mdk-data-line={1863} +\item\mdline{1863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1863}: set to the list of P4 annotations associated with the struct +field, except for the \mdline{1864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1864} annotation, if present (see the \mdline{1864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1864} field +below).%mdk + +%mdk-data-line={1866} +\item\mdline{1866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1866}: set to the value of \mdline{1866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1866} for the corresponding struct field.%mdk + +%mdk-data-line={1867} +\item\mdline{1867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1867}, which indicates whether the struct field has a\mdline{1867}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1868}; this is useful for +\mdline{1869}\mdref{sec-psa-metadata-translation}{translation}\mdline{1869}.%mdk + +%mdk-data-line={1870} +\item\mdline{1870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1870}: by default \mdline{1870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1870} is set to \mdline{1870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1870}; the P4 programmer can +specify a different match type by using the \mdline{1871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1871} annotation +\mdline{1872}[\mdcite{p4selectexpr}{26}]\mdline{1872}.%mdk + +%mdk-data-line={1873} +\item\mdline{1873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1873}: documentation associated with the struct field.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1875} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1876} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~bit\textless{}8\textgreater{}~f8;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(2)~@match(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(3)~@match(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1884} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1885} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1912} +\noindent\mdline{1912}In the above example, the \mdline{1912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1912} annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs.%mdk + +%mdk-data-line={1915} +\mdline{1915}Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a\mdline{1916}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1917} that resolves to a \mdline{1917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1917}, or a \mdline{1917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1917} where +one or more fields is a\mdline{1918}~\mdref{sec-user-defined-types}{user-defined type}\mdline{1918} that +resolves to a \mdline{1919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1919}. For each \mdline{1919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1919} that corresponds to a user-defined +type, the \mdline{1920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1920} field must be set to the appropriate value (\mdline{1920}i.e.\mdline{1920} the name +of the type).%mdk + +%mdk-data-line={1923} +\subsubsection{\mdline{1923}6.4.8.\hspace*{0.5em}\mdline{1923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}\label{sec-register}%mdk%mdk + +%mdk-data-line={1925} +\noindent\mdline{1925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1925} messages are used to specify all possible instances of Register PSA +externs.%mdk + +%mdk-data-line={1928} +\mdline{1928}Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime.%mdk + +%mdk-data-line={1932} +\mdline{1932}The \mdline{1932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1932} message defines the following fields:%mdk + +%mdk-data-line={1934} +\begin{itemize}%mdk + +%mdk-data-line={1934} +\item{} +%mdk-data-line={1934} +\mdline{1934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1934}, a \mdline{1934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1934} message with the ID, name, and alias of this register +instance.%mdk%mdk + +%mdk-data-line={1937} +\item{} +%mdk-data-line={1937} +\mdline{1937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1937}, which specifies the data type stored by this register, expressed +using a \mdline{1938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1938} message (see section on\mdline{1938}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary +P4 Types}\mdline{1939}).%mdk%mdk + +%mdk-data-line={1941} +\item{} +%mdk-data-line={1941} +\mdline{1941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1941}, an \mdline{1941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1941} value representing the total number of independent register +cells available.%mdk%mdk + +%mdk-data-line={1944} +\item{} +%mdk-data-line={1944} +\mdline{1944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1944}, which indicates whether the register index has a +\mdline{1945}\mdref{sec-user-defined-types}{user-defined type}\mdline{1945}. This is useful for +\mdline{1946}\mdref{sec-psa-metadata-translation}{translation}\mdline{1946}. The underlying built-in type +must be a fixed-width unsigned bitstring (\mdline{1947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1947}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1949} +\subsubsection{\mdline{1949}6.4.9.\hspace*{0.5em}\mdline{1949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}\label{sec-digest}%mdk%mdk + +%mdk-data-line={1951} +\noindent\mdline{1951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1951} messages are used to specify all possible instances of Packet Digest +PSA externs.%mdk + +%mdk-data-line={1954} +\mdline{1954}A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages.%mdk + +%mdk-data-line={1963} +\mdline{1963}The \mdline{1963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1963} message defines the following fields:%mdk + +%mdk-data-line={1965} +\begin{itemize}%mdk + +%mdk-data-line={1965} +\item{} +%mdk-data-line={1965} +\mdline{1965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1965}, a \mdline{1965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1965} message with the ID, name, and alias of this digest +instance.%mdk%mdk + +%mdk-data-line={1968} +\item{} +%mdk-data-line={1968} +\mdline{1968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1968}, which specifies the data type of an individual digest +notification using a \mdline{1969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1969} message (see section on\mdline{1969}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation +of Arbitrary P4 Types}\mdline{1970}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1972} +\subsubsection{\mdline{1972}6.4.10.\hspace*{0.5em}\mdline{1972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}\label{sec-p4info-extern}%mdk%mdk + +%mdk-data-line={1974} +\noindent\mdline{1974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1974} messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one \mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1977} message instance in P4Info. The \mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1977} message defines +the following fields:%mdk + +%mdk-data-line={1980} +\begin{itemize}%mdk + +%mdk-data-line={1980} +\item{} +%mdk-data-line={1980} +\mdline{1980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{1980}, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the\mdline{1981}~\mdref{sec-id-allocation}{reserved +range}\mdline{1982} \mdline{1982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{}[0x81,~0xfe]}}}\mdline{1982}. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture.%mdk%mdk + +%mdk-data-line={1987} +\item{} +%mdk-data-line={1987} +\mdline{1987}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_name}}}\mdline{1987}, which specifies the fully-qualified P4 name of the extern +type.%mdk%mdk + +%mdk-data-line={1990} +\item{} +%mdk-data-line={1990} +\mdline{1990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instances}}}\mdline{1990}, a repeated field of \mdline{1990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{1990} Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +\mdline{1992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{1992} in turn defines the following fields:%mdk + +%mdk-data-line={1994} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1994} +\item\mdline{1994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1994}, a \mdline{1994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1994} message with the ID, name, and alias of this digest +instance.%mdk + +%mdk-data-line={1996} +\item\mdline{1996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{1996}, an \mdline{1996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1996} Protobuf message\mdline{1996}~[\mdcite{protoany}{31}]\mdline{1996} which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for \mdline{1998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{1998} should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on\mdline{2000}~\mdref{sec-extending-p4runtime}{Extending +P4Runtime for non-PSA Architectures}\mdline{2001} for more +information.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2004} +\noindent\mdline{2004}If the P4 program does not include any instance of a given extern type, the +\mdline{2005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2005} message instance for that type should be omitted from the P4Info.%mdk + +%mdk-data-line={2007} +\subsection{\mdline{2007}6.5.\hspace*{0.5em}\mdline{2007}Support for Arbitrary P4 Types with P4TypeInfo}\label{sec-support-for-arbitrary-p4-types-with-p4typeinfo}%mdk%mdk + +%mdk-data-line={2009} +\noindent\mdline{2009}See section on\mdline{2009}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary P4 +Types}\mdline{2010}.%mdk + +%mdk-data-line={2012} +\section{\mdline{2012}7.\hspace*{0.5em}\mdline{2012}P4 Forwarding-Pipeline Configuration}\label{sec-p4-fwd-pipe-config}%mdk%mdk + +%mdk-data-line={2014} +\noindent\mdline{2014}The \mdline{2014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2014} captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the \mdline{2016}\textquotedblleft{}Device Configuration\textquotedblright{}\mdline{2016} and sometimes also referred to as +the \mdline{2017}\textquotedblleft{}P4 Blob\textquotedblright{}\mdline{2017}. It is defined as:%mdk + +%mdk-data-line={2019} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2020} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ForwardingPipelineConfig~\{\\ +~~config.P{\mdcolor{purple}4}Info~p4info~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~p4\_device\_config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}message}}~Cookie~\{\\ +~~~~{\bfseries{\mdcolor{navy}uint64}}~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~\}\\ +~~Cookie~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2030} +\noindent\mdline{2030}The \mdline{2030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{2030} field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic.%mdk + +%mdk-data-line={2033} +\mdline{2033}The \mdline{2033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{2033} is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new \mdline{2035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2035} on that target.%mdk + +%mdk-data-line={2037} +\mdline{2037}The \mdline{2037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{2037} field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a \mdline{2042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{2042} RPC. +When writing the config via a \mdline{2043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{2043} RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present.%mdk + +%mdk-data-line={2047} +\section{\mdline{2047}8.\hspace*{0.5em}\mdline{2047}General Principles for Message Formatting}\label{sec-general-principles-for-message-formatting}%mdk%mdk + +%mdk-data-line={2049} +\subsection{\mdline{2049}8.1.\hspace*{0.5em}\mdline{2049}Set / Unset Protobuf Field}\label{sec-set-unset-protobuf-field}%mdk%mdk + +%mdk-data-line={2051} +\noindent\mdline{2051}In Protobuf version 3 (\mdline{2051}\emph{proto3}\mdline{2051}), the default value for a message field is +\mdline{2052}\textquotedblleft{}unset\textquotedblright{}\mdline{2052}~[\mdcite{protodefaults}{4}]\mdline{2052}. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +\mdline{2057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2057} message, an \mdline{2057}\textquotedblleft{}unset\textquotedblright{}\mdline{2057} \mdline{2057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2057} field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the \mdline{2059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2059} message field is +set, a single entry will be read.%mdk + +%mdk-data-line={2062} +\mdline{2062}Let\mdline{2062}'\mdline{2062}s look at the counter example in more details. Based on this specification +document, the C++ server code which processes \mdline{2063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2063} messages may look +like this:%mdk + +%mdk-data-line={2065} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2066} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}auto}}~*counter\_entry~=~...\\ +{\bfseries{\mdcolor{navy}if}}~(counter\_entry-\textgreater{}has\_index())~\{\\ +~~{\bfseries{\mdcolor{navy}auto}}~index~=~counter\_entry-\textgreater{}index().index();\\ +~~read\_one\_entry(counter\_entry-\textgreater{}id(),~index);\\ +\}~{\bfseries{\mdcolor{navy}else}}~\{\\ +~~read\_all\_entries(counter\_entry-\textgreater{}id());\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2075} +\begin{enumerate}%mdk + +%mdk-data-line={2075} +\item{} +%mdk-data-line={2075} +\mdline{2075}Reading a single counter entry at index 0 in the counter array with id +\mdline{2076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textless{}id\textgreater{}}}}\mdline{2076}:%mdk + +%mdk-data-line={2077} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2077} +\item\mdline{2077}Here is the C++ client code: + +%mdk-data-line={2078} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2079} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});\\ +entry.mutable\_index();\\ +{\mdcolor{darkgreen}//~The~above~line~sets~the~index~field;~it~is~equivalent~to:}\\ +{\mdcolor{darkgreen}//~auto~*index~=~entry.mutable\_index();}\\ +{\mdcolor{darkgreen}//~index-\textgreater{}set\_index(0);}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2086} +\item\mdline{2086}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2087} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2088} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}\\ +index~\{\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2091} +\item\mdline{2091}\textbf{Expected behavior}\mdline{2091}: Counter entry at index 0 is read. Notice that the +\mdline{2092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2092} subfield is missing under the \mdline{2092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2092} field message of +\mdline{2093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2093} in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2098} +\item{} +%mdk-data-line={2098} +\mdline{2098}Reading all counter entries by leaving the \mdline{2098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2098} field unset%mdk + +%mdk-data-line={2099} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2099} +\item\mdline{2099}Here is the C++ client code: + +%mdk-data-line={2100} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2101} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2104} +\item\mdline{2104}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2105} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2106} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2108} +\item\mdline{2108}\textbf{Expected behavior}\mdline{2108}: All counter entries for the provided counter +instance are read. Notice that the \mdline{2109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2109} message field is unset (default +value) and is therefore omitted from the textual representation of the +message.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={2113} +\subsection{\mdline{2113}8.2.\hspace*{0.5em}\mdline{2113}Read-Write Symmetry}\label{sec-read-write-symmetry}%mdk%mdk + +%mdk-data-line={2115} +\noindent\mdline{2115}The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example:%mdk + +%mdk-data-line={2121} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2122} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}intended\_value~=~value\\ +\\ +status~=~server.write(intended\_value,~p4\_entity)\\ +observed\_value~=~server.read(p4\_entity)\\ +\\ +assert(intended\_value~==~observed\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2130} +\noindent\mdline{2130}To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If \mdline{2134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{2134} RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol\mdline{2137}'\mdline{2137}s complexities to the client implementations.%mdk + +%mdk-data-line={2139} +\mdline{2139}In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the \mdline{2142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2142} fields in a \mdline{2142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2142} message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +\mdline{2145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MessageDifferencer}}}\mdline{2145} class\mdline{2145}~[\mdcite{protomessagedifferencer}{36}]\mdline{2145} included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance.%mdk + +%mdk-data-line={2150} +\subsection{\mdline{2150}8.3.\hspace*{0.5em}\mdline{2150}Zero as Reserved Value}\label{sec-zero-as-reserved-value}%mdk%mdk + +%mdk-data-line={2152} +\noindent\mdline{2152}p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a \mdline{2153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{2153}. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a \mdline{2156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{2156} or a \mdline{2156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfigRequest}}}\mdline{2156}.%mdk + +%mdk-data-line={2158} +\subsection{\mdline{2158}8.4.\hspace*{0.5em}\mdline{2158}Bytestrings}\label{sec-bytestrings}%mdk%mdk + +%mdk-data-line={2160} +\noindent\mdline{2160}P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (\mdline{2162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2162}) or signed (\mdline{2162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2162}), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +\mdline{2165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2165} Protobuf type. The correct bitwidth\mdline{2165} \mdline{2165}\textemdash{}\mdline{2165} as per the P4 program\mdline{2165} \mdline{2165}\textemdash{}\mdline{2165} of +each integer variable exposed through P4Runtime is specified in the P4Info +message.%mdk + +%mdk-data-line={2169} +\mdline{2169}The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals:%mdk + +%mdk-data-line={2172} +\begin{itemize}%mdk + +%mdk-data-line={2172} +\item{} +%mdk-data-line={2172} +\mdline{2172}It ensures that a properly encoded binary string\mdline{2172}'\mdline{2172}s integer value conforms +to the P4Info-specified bitwidth.%mdk%mdk + +%mdk-data-line={2175} +\item{} +%mdk-data-line={2175} +\mdline{2175}It supports\mdline{2175}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2175}.%mdk%mdk + +%mdk-data-line={2177} +\item{} +%mdk-data-line={2177} +\mdline{2177}It helps facilitate non-disruptive P4 program updates.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2179} +\noindent\mdline{2179}In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type \mdline{2184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2184} and/or \mdline{2184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2184}.%mdk + +%mdk-data-line={2186} +\mdline{2186}Note that this representation does \mdline{2186}\emph{not}\mdline{2186} make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range.%mdk + +%mdk-data-line={2195} +\mdline{2195}In the P4Runtime API version 1.0, values of table key fields, action parameters, +and fields in packet-in and packet-out headers between a device and the +controller (see\mdline{2197}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{2197}), may not be of type \mdline{2197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2197}. +The rules for encoding signed values thus only apply to messages of type +\mdline{2199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2199} (see\mdline{2199}~\mdref{sec-p4data-in-p4runtime-proto}{8.5.3}\mdline{2199}).%mdk + +%mdk-data-line={2201} +\mdline{2201}For a value of type \mdline{2201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2201}, the fewest number of bits required to represent +the integer value \mdline{2202}$V > 0$\mdline{2202} is the smallest integer \mdline{2202}$A$\mdline{2202} such that \mdline{2202}$V \leq 2^A -1$\mdline{2203}.%mdk + +%mdk-data-line={2205} +\mdline{2205}For a value of type \mdline{2205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2205}, the fewest number of bits required to represent +the integer value \mdline{2206}$V \neq 0$\mdline{2206} in 2\mdline{2206}'\mdline{2206}s complement form is the smallest integer \mdline{2206}$A$\mdline{2206} +such that \mdline{2207}$-2^{A-1} \leq V \leq 2^{A-1} - 1$\mdline{2207}.%mdk + +%mdk-data-line={2209} +\mdline{2209}As a special case, define that the value \mdline{2209}$V=0$\mdline{2209} requires at least \mdline{2209}$A=1$\mdline{2209} bit to +represent, regardless of whether it is signed or unsigned.%mdk + +%mdk-data-line={2212} +\mdline{2212}The shortest possible binary string for an integer \mdline{2212}$V$\mdline{2212} that needs \mdline{2212}$A$\mdline{2212} bits to +represent it is computed as:%mdk + +%mdk-data-line={2214} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2215} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size~=~floor(({\mdcolor{teal}A}~+~{\mdcolor{purple}7})~/~{\mdcolor{purple}8})}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2218} +\noindent\mdline{2218}Binary strings with the byte length computed as \mdline{2218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2218} promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies.%mdk + +%mdk-data-line={2222} +\mdline{2222}Any additional bits in the bytes sent for an unsigned integer value (type +\mdline{2223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2223}) must be 0. If additional bytes are transmitted above the +\mdline{2224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2224} minimum required, they must be filled with 0.%mdk + +%mdk-data-line={2226} +\mdline{2226}Any additional bits in the bytes sent for a signed integer value (type \mdline{2226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2226}) +must be copies of the sign bit, \mdline{2227}i.e.\mdline{2227} 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +\mdline{2229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2229} minimum required, they must be filled with copies of the +sign bit, \mdline{2230}i.e.\mdline{2230} 0 for non-negative values, or 0xff for negative values. In 2\mdline{2230}'\mdline{2230}s +complement representation, this is called \mdline{2231}\textquotedblleft{}sign extension\textquotedblright{}\mdline{2231}, and leaves the +numeric value represented unchanged.%mdk + +%mdk-data-line={2234} +\mdline{2234}Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value.%mdk + +%mdk-data-line={2240} +\mdline{2240}For a received bitstring expected to fit within a \mdline{2240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2240} type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring\mdline{2242}'\mdline{2242}s width is \mdline{2242}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2242} bits or less.%mdk + +%mdk-data-line={2244} +\mdline{2244}For a received bitstring expected to fit within an \mdline{2244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2244} type, the value it +represents is in range if, after \mdline{2245}\textquotedblleft{}undoing sign extension\textquotedblright{}\mdline{2245}, the remaining bit +string\mdline{2246}'\mdline{2246}s width is \mdline{2246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2246} bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other.%mdk + +%mdk-data-line={2252} +\mdline{2252}If the string\mdline{2252}'\mdline{2252}s byte length is zero, the server always rejects the string.%mdk + +%mdk-data-line={2254} +\mdline{2254}When the server rejects a binary string due to any of the previous criteria, +it returns an \mdline{2255}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2255} error.%mdk + +%mdk-data-line={2257} +\mdline{2257}For all binary strings, P4Runtime uses big-endian (\mdline{2257}i.e.\mdline{2257} network) byte-order. +For signed integer values (\mdline{2258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2258} P4 type), P4Runtime uses the same two\mdline{2258}'\mdline{2258}s +complement bitwise representation as P4. Table\mdline{2259}~\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}}\mdline{2259} +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above.%mdk + +%mdk-data-line={2263} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2265} P4 type}}&\multicolumn{1}{|c}{{\bfseries\mdline{2265} Integer value}}&\multicolumn{1}{|c}{{\bfseries\mdline{2265} P4Runtime binary string}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2265} Read-write symmetry}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2267} \mdline{2267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2267}}&\multicolumn{1}{|l}{\mdline{2267} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2267} \mdline{2267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2267}}&\multicolumn{1}{|l|}{\mdline{2267} yes}\\ +\multicolumn{1}{|l}{\mdline{2268} \mdline{2268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2268}}&\multicolumn{1}{|l}{\mdline{2268} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2268} \mdline{2268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2268}}&\multicolumn{1}{|l|}{\mdline{2268} no}\\ +\multicolumn{1}{|l}{\mdline{2269} \mdline{2269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2269}}&\multicolumn{1}{|l}{\mdline{2269} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2269} \mdline{2269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2269}}&\multicolumn{1}{|l|}{\mdline{2269} yes}\\ +\multicolumn{1}{|l}{\mdline{2270} \mdline{2270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2270}}&\multicolumn{1}{|l}{\mdline{2270} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2270} \mdline{2270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x30\textbackslash{}x64}}}\mdline{2270}}&\multicolumn{1}{|l|}{\mdline{2270} yes}\\ +\multicolumn{1}{|l}{\mdline{2271} \mdline{2271}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2271}}&\multicolumn{1}{|l}{\mdline{2271} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2271} \mdline{2271}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x30\textbackslash{}x64}}}\mdline{2271}}&\multicolumn{1}{|l|}{\mdline{2271} no}\\ +\multicolumn{1}{|l}{\mdline{2272} \mdline{2272}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2272}}&\multicolumn{1}{|l}{\mdline{2272} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2272} \mdline{2272}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2272}}&\multicolumn{1}{|l|}{\mdline{2272} no}\\ +\multicolumn{1}{|l}{\mdline{2273} \mdline{2273}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2273}}&\multicolumn{1}{|l}{\mdline{2273} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2273} \mdline{2273}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2273}}&\multicolumn{1}{|l|}{\mdline{2273} yes}\\ +\multicolumn{1}{|l}{\mdline{2274} \mdline{2274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2274}}&\multicolumn{1}{|l}{\mdline{2274} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2274} \mdline{2274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00\textbackslash{}x63}}}\mdline{2274}}&\multicolumn{1}{|l|}{\mdline{2274} no}\\ +\multicolumn{1}{|l}{\mdline{2275} \mdline{2275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2275}}&\multicolumn{1}{|l}{\mdline{2275} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2275} \mdline{2275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2275}}&\multicolumn{1}{|l|}{\mdline{2275} yes}\\ +\multicolumn{1}{|l}{\mdline{2276} \mdline{2276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2276}}&\multicolumn{1}{|l}{\mdline{2276} \mdline{2276}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2276} \mdline{2276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x9d}}}\mdline{2276}}&\multicolumn{1}{|l|}{\mdline{2276} yes}\\ +\multicolumn{1}{|l}{\mdline{2277} \mdline{2277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2277}}&\multicolumn{1}{|l}{\mdline{2277} \mdline{2277}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2277} \mdline{2277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xff\textbackslash{}x9d}}}\mdline{2277}}&\multicolumn{1}{|l|}{\mdline{2277} no}\\ +\multicolumn{1}{|l}{\mdline{2278} \mdline{2278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2278}}&\multicolumn{1}{|l}{\mdline{2278} \mdline{2278}-739 (-0x2e3)}&\multicolumn{1}{|l}{\mdline{2278} \mdline{2278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xfd\textbackslash{}x1d}}}\mdline{2278}}&\multicolumn{1}{|l|}{\mdline{2278} yes}\\ +\multicolumn{1}{|l}{\mdline{2279} \mdline{2279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2279}}&\multicolumn{1}{|l}{\mdline{2279} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2279} \mdline{2279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00}}}\mdline{2279}}&\multicolumn{1}{|l|}{\mdline{2279} no}\\ +\multicolumn{1}{|l}{\mdline{2280} \mdline{2280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2280}}&\multicolumn{1}{|l}{\mdline{2280} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2280} \mdline{2280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00}}}\mdline{2280}}&\multicolumn{1}{|l|}{\mdline{2280} yes}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2282} +\mdhr{}%mdk + +%mdk-data-line={2283} +\noindent\mdline{2283}\mdcaption{\textbf{Table~\mdcaptionlabel{4}.}~\mdcaptiontext{Examples of Valid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-valid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2285} +\mdline{2285}Table\mdline{2285}~\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}}\mdline{2285} shows some examples of invalid +P4Runtime binary strings:%mdk + +%mdk-data-line={2288} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2290} P4 type}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2290} P4Runtime binary string}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2292} \mdline{2292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2292}}&\multicolumn{1}{|l|}{\mdline{2292} \mdline{2292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x63}}}\mdline{2292}}\\ +\multicolumn{1}{|l}{\mdline{2293} \mdline{2293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2293}}&\multicolumn{1}{|l|}{\mdline{2293} \mdline{2293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2293}}\\ +\multicolumn{1}{|l}{\mdline{2294} \mdline{2294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2294}}&\multicolumn{1}{|l|}{\mdline{2294} \mdline{2294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2294}}\\ +\multicolumn{1}{|l}{\mdline{2295} \mdline{2295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2295}}&\multicolumn{1}{|l|}{\mdline{2295} \mdline{2295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x10\textbackslash{}x63}}}\mdline{2295}}\\ +\multicolumn{1}{|l}{\mdline{2296} \mdline{2296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2296}}&\multicolumn{1}{|l|}{\mdline{2296} \mdline{2296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2296}}\\ +\multicolumn{1}{|l}{\mdline{2297} \mdline{2297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2297}}&\multicolumn{1}{|l|}{\mdline{2297} \mdline{2297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x40\textbackslash{}x63}}}\mdline{2297}}\\ +\multicolumn{1}{|l}{\mdline{2298} \mdline{2298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2298}}&\multicolumn{1}{|l|}{\mdline{2298} \mdline{2298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x9d}}}\mdline{2298}}\\ +\multicolumn{1}{|l}{\mdline{2299} \mdline{2299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2299}}&\multicolumn{1}{|l|}{\mdline{2299} \mdline{2299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x8d\textbackslash{}x1d}}}\mdline{2299}}\\ +\multicolumn{1}{|l}{\mdline{2300} \mdline{2300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2300}}&\multicolumn{1}{|l|}{\mdline{2300} \mdline{2300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2300}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2302} +\mdhr{}%mdk + +%mdk-data-line={2303} +\noindent\mdline{2303}\mdcaption{\textbf{Table~\mdcaptionlabel{5}.}~\mdcaptiontext{Examples of Invalid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-invalid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2305} +\mdline{2305}As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from \mdline{2310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2310} to \mdline{2310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2310}, a server +running the \mdline{2311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2311} version of the P4 program will accept requests from +clients that remain on the \mdline{2312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2312} P4Runtime version.%mdk + +%mdk-data-line={2314} +\mdline{2314}Despite the server\mdline{2314}'\mdline{2314}s binary string flexibility for P4 program update support, +the client and server must both remain aware of the +\mdline{2316}\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2316} +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values.%mdk + +%mdk-data-line={2321} +\mdline{2321}Representation of variable-length integer values (\mdline{2321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2321} P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the \mdline{2323}\emph{dynamic-length}\mdline{2323} of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an \mdline{2326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2326} error code otherwise.%mdk + +%mdk-data-line={2328} +\subsection{\mdline{2328}8.5.\hspace*{0.5em}\mdline{2328}Representation of Arbitrary P4 Types}\label{sec-representation-of-arbitrary-p4-types}%mdk%mdk + +%mdk-data-line={2330} +\subsubsection{\mdline{2330}8.5.1.\hspace*{0.5em}\mdline{2330}Problem Statement}\label{sec-problem-statement}%mdk%mdk + +%mdk-data-line={2332} +\noindent\mdline{2332}The P4\mdline{2332}\mdsub{16}\mdline{2332} language includes more complex types than just binary strings +\mdline{2333}[\mdcite{p4complextypes}{3}]\mdline{2333}. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table\mdline{2336}~\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}}\mdline{2336} shows the different +P4\mdline{2337}\mdsub{16}\mdline{2337} types and how they are allowed to be used, as per the P4\mdline{2337}\mdsub{16}\mdline{2337} +specification.%mdk + +%mdk-data-line={2340} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|l}{{\bfseries\mdline{2342}}}&\multicolumn{3}{|c|}{{\bfseries\mdline{2342} Container type}}\\ +\cmidrule{2-2}\cmidrule{3-3}\cmidrule{4-4} +\multicolumn{1}{|l}{{\bfseries\mdline{2344} Element type}}&\multicolumn{1}{|l}{{\bfseries\mdline{2344} header}}&\multicolumn{1}{|l}{{\bfseries\mdline{2344} header\mdline{2344}\_\mdline{2344}union}}&\multicolumn{1}{|l|}{{\bfseries\mdline{2344} struct or tuple}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2346} \mdline{2346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2346}}&\multicolumn{1}{|l}{\mdline{2346} allowed}&\multicolumn{1}{|l}{\mdline{2346} error}&\multicolumn{1}{|l|}{\mdline{2346} allowed}\\ +\multicolumn{1}{|l}{\mdline{2347} \mdline{2347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2347}}&\multicolumn{1}{|l}{\mdline{2347} allowed}&\multicolumn{1}{|l}{\mdline{2347} error}&\multicolumn{1}{|l|}{\mdline{2347} allowed}\\ +\multicolumn{1}{|l}{\mdline{2348} \mdline{2348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2348}}&\multicolumn{1}{|l}{\mdline{2348} allowed}&\multicolumn{1}{|l}{\mdline{2348} error}&\multicolumn{1}{|l|}{\mdline{2348} allowed}\\ +\multicolumn{1}{|l}{\mdline{2349} \mdline{2349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int}}}\mdline{2349}}&\multicolumn{1}{|l}{\mdline{2349} error}&\multicolumn{1}{|l}{\mdline{2349} error}&\multicolumn{1}{|l|}{\mdline{2349} error}\\ +\multicolumn{1}{|l}{\mdline{2350} \mdline{2350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}void}}}\mdline{2350}}&\multicolumn{1}{|l}{\mdline{2350} error}&\multicolumn{1}{|l}{\mdline{2350} error}&\multicolumn{1}{|l|}{\mdline{2350} error}\\ +\multicolumn{1}{|l}{\mdline{2351} \mdline{2351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2351}}&\multicolumn{1}{|l}{\mdline{2351} error}&\multicolumn{1}{|l}{\mdline{2351} error}&\multicolumn{1}{|l|}{\mdline{2351} allowed}\\ +\multicolumn{1}{|l}{\mdline{2352} \mdline{2352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_kind}}}\mdline{2352}}&\multicolumn{1}{|l}{\mdline{2352} error}&\multicolumn{1}{|l}{\mdline{2352} error}&\multicolumn{1}{|l|}{\mdline{2352} error}\\ +\multicolumn{1}{|l}{\mdline{2353} \mdline{2353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2353}}&\multicolumn{1}{|l}{\mdline{2353} error}&\multicolumn{1}{|l}{\mdline{2353} error}&\multicolumn{1}{|l|}{\mdline{2353} allowed}\\ +\multicolumn{1}{|l}{\mdline{2354} \mdline{2354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2354}}&\multicolumn{1}{|l}{\mdline{2354} allowed\mdline{2354}\mdfootnote{1}{%mdk-data-line={2364} +%mdk-data-line={2364} +\noindent\mdline{2364}an \mdline{2364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2364} type used as a field in a \mdline{2364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2364} must specify a +underlying type and representation for \mdline{2365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2365} elements.%mdk +\label{fn-enum_header}%mdk%mdk +}\mdline{2354}}&\multicolumn{1}{|l}{\mdline{2354} error}&\multicolumn{1}{|l|}{\mdline{2354} allowed}\\ +\multicolumn{1}{|l}{\mdline{2355} \mdline{2355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2355}}&\multicolumn{1}{|l}{\mdline{2355} error}&\multicolumn{1}{|l}{\mdline{2355} allowed}&\multicolumn{1}{|l|}{\mdline{2355} allowed}\\ +\multicolumn{1}{|l}{\mdline{2356} header stack}&\multicolumn{1}{|l}{\mdline{2356} error}&\multicolumn{1}{|l}{\mdline{2356} error}&\multicolumn{1}{|l|}{\mdline{2356} allowed}\\ +\multicolumn{1}{|l}{\mdline{2357} \mdline{2357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2357}}&\multicolumn{1}{|l}{\mdline{2357} error}&\multicolumn{1}{|l}{\mdline{2357} error}&\multicolumn{1}{|l|}{\mdline{2357} allowed}\\ +\multicolumn{1}{|l}{\mdline{2358} \mdline{2358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2358}}&\multicolumn{1}{|l}{\mdline{2358} error}&\multicolumn{1}{|l}{\mdline{2358} error}&\multicolumn{1}{|l|}{\mdline{2358} allowed}\\ +\multicolumn{1}{|l}{\mdline{2359} \mdline{2359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2359}}&\multicolumn{1}{|l}{\mdline{2359} error}&\multicolumn{1}{|l}{\mdline{2359} error}&\multicolumn{1}{|l|}{\mdline{2359} allowed}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2361} +\mdhr{}%mdk + +%mdk-data-line={2362} +\noindent\mdline{2362}\mdcaption{\textbf{Table~\mdcaptionlabel{6}.}~\mdcaptiontext{P4 Type Usage}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-type-usage}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2367} +\mdline{2367}For example, the following P4\mdline{2367}\mdsub{16}\mdline{2367} objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects.%mdk + +%mdk-data-line={2370} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2371} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}{\bfseries{\mdcolor{navy}tuple}}\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}4}\textgreater{},~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~\textgreater{}~\textgreater{}()~digest\_complex;\\ +digest\_complex.pack(\{~hdr.ipv4.version,~hdr.ipv4.protocol~\});\\ +{\mdcolor{darkgreen}//~...}\\ +{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2381} +\noindent\mdline{2381}One solution would be to use only binary string (\mdline{2381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2381} type) in +p4runtime.proto and to define a custom serialization format for complex P4\mdline{2382}\mdsub{16}\mdline{2382} +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P4\mdline{2389}\mdsub{16}\mdline{2389} types.%mdk + +%mdk-data-line={2391} +\subsubsection{\mdline{2391}8.5.2.\hspace*{0.5em}\mdline{2391}P4 Type Specifications in p4info.proto}\label{sec-p4-type-specifications-in-p4infoproto}%mdk%mdk + +%mdk-data-line={2393} +\noindent\mdline{2393}In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type \mdline{2397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip\_t}}}\mdline{2397}, which is a header union with 2 possible headers: +\mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4}}}\mdline{2398} with type \mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4\_t}}}\mdline{2398} and \mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6}}}\mdline{2398} with type \mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6\_t}}}\mdline{2398}. Similarly, they need to +know the field layout for both of these header types.%mdk + +%mdk-data-line={2401} +\mdline{2401}To achieve this we introduce 2 main Protobuf messages: \mdline{2401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2401} and +\mdline{2402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2402}.%mdk + +%mdk-data-line={2404} +\mdline{2404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2404} is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P4\mdline{2405}\mdsub{16}\mdline{2405} program. These +named types are \mdline{2406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2406}, \mdline{2406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2406}, \mdline{2406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2406}, \mdline{2406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2406} and +\mdline{2407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2407}; for each of these we have a type specification message, +respectively \mdline{2408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructTypeSpec}}}\mdline{2408}, \mdline{2408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderTypeSpec}}}\mdline{2408}, \mdline{2408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionTypeSpec}}}\mdline{2408}, +\mdline{2409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4EnumTypeSpec}}}\mdline{2409} and \mdline{2409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4SerializableEnumTypeSpec}}}\mdline{2409}. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. \mdline{2411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2411} also includes the list of parser errors for the program, as +a \mdline{2412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4ErrorTypeSpec}}}\mdline{2412} message.%mdk + +%mdk-data-line={2414} +\mdline{2414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2414} is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each \mdline{2416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2416} message corresponds to a compile-time type in the +original P4\mdline{2417}\mdsub{16}\mdline{2417} program (\mdline{2417}e.g.\mdline{2417} the type parameter of an extern). This +compile-time type is represented as a Protobuf \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2418}, which can be:%mdk + +%mdk-data-line={2420} +\begin{itemize}%mdk + +%mdk-data-line={2420} +\item{} +%mdk-data-line={2420} +\mdline{2420}a string representing the name of the type in case of a named type (\mdline{2420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2420}, +\mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2421}, \mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2421}, \mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2421}, \mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2421} or user-defined \mdline{2421}\textquotedblleft{}new\textquotedblright{}\mdline{2421} +\mdline{2422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2422}),%mdk%mdk + +%mdk-data-line={2424} +\item{} +%mdk-data-line={2424} +\mdline{2424}an empty Protobuf message for \mdline{2424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2424} and \mdline{2424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2424}, or%mdk%mdk + +%mdk-data-line={2426} +\item{} +%mdk-data-line={2426} +\mdline{2426}a Protobuf message for other anonymous types (\mdline{2426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2426}, \mdline{2426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2426}, \mdline{2426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2426}, +\mdline{2427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2427} or stack). The \mdline{2427}\textquotedblleft{}binary string\textquotedblright{}\mdline{2427} types (\mdline{2427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2427}, \mdline{2427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2427}, and +\mdline{2428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2428}) are grouped together in the \mdline{2428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4BitstringLikeTypeSpec}}}\mdline{2428} message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf \mdline{2430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2430} +type).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2433} +\noindent\mdline{2433}For all P4\mdline{2433}\mdsub{16}\mdline{2433} compound types (\mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2433}, and \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2433}), +the order of \mdline{2434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2434} in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P4\mdline{2436}\mdsub{16}\mdline{2436} declaration. The same goes for the order of members of an \mdline{2436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2436} +(serializable or not) or members of \mdline{2437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2437}.%mdk + +%mdk-data-line={2439} +\subsubsection{\mdline{2439}8.5.3.\hspace*{0.5em}\mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2439} in p4runtime.proto}\label{sec-p4data-in-p4runtime-proto}%mdk%mdk + +%mdk-data-line={2441} +\noindent\mdline{2441}P4Runtime uses the \mdline{2441}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2441} message to represent values of arbitrary types. The +P4Runtime client must generate correct \mdline{2442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2442} messages based on the type +specification information included in P4Info. The \mdline{2443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2443} message was designed +to introduce little overhead compared to using binary strings in the most common +case (P4\mdline{2445}\mdsub{16}\mdline{2445} \mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2445} type).%mdk + +%mdk-data-line={2447} +\mdline{2447}Just like its P4Info counterpart\mdline{2447} \mdline{2447}- \mdline{2447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2447} \mdline{2447}-, \mdline{2447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2447} uses a Protobuf +\mdline{2448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2448} to represent all possible values.%mdk + +%mdk-data-line={2450} +\mdline{2450}We define a canonical representation for \mdline{2450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2450} messages\mdline{2450} \mdline{2450}\textemdash{}\mdline{2450} therefore +guaranteeing read-write symmetry\mdline{2451} \mdline{2451}\textemdash{}\mdline{2451} by introducing the following requirements:%mdk + +%mdk-data-line={2453} +\begin{itemize}%mdk + +%mdk-data-line={2453} +\item{} +%mdk-data-line={2453} +\mdline{2453}The order of \mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2453} in \mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructLike}}}\mdline{2453} and the order of \mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2453} in +\mdline{2454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2454} must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P4\mdline{2455}\mdsub{16}\mdline{2455} type +declaration.%mdk%mdk + +%mdk-data-line={2458} +\item{} +%mdk-data-line={2458} +\mdline{2458}An invalid header is represented by a \mdline{2458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2458} message where the \mdline{2458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_valid}}}\mdline{2458} +field is false and the \mdline{2459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2459} repeated field is empty.%mdk%mdk + +%mdk-data-line={2461} +\item{} +%mdk-data-line={2461} +\mdline{2461}An invalid header union (\mdline{2461}i.e.\mdline{2461} all headers in the union are invalid) is +represented by a \mdline{2462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnion}}}\mdline{2462} message where the \mdline{2462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header\_name}}}\mdline{2462} is the +empty string (default value for the field) and the \mdline{2463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header}}}\mdline{2463} is unset.%mdk%mdk + +%mdk-data-line={2465} +\item{} +%mdk-data-line={2465} +\mdline{2465}The order of \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2465} in \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStack}}}\mdline{2465} and \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStack}}}\mdline{2465} is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the \mdline{2467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2467} field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding \mdline{2469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStackTypeSpec}}}\mdline{2469} or +\mdline{2470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStackTypeSpec}}}\mdline{2470} message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2472} +\subsubsection{\mdline{2472}8.5.4.\hspace*{0.5em}\mdline{2472}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={2474} +\noindent\mdline{2474}Let\mdline{2474}'\mdline{2474}s look at the Register example again:%mdk + +%mdk-data-line={2476} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2477} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2484} +\noindent\mdline{2484}Here\mdline{2484}'\mdline{2484}s the corresponding entry in the P4Info message:%mdk + +%mdk-data-line={2486} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2487} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}registers~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}369119267}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~\}\\ +~~type\_spec~\{\\ +~~~~header\_union~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~size:~{\mdcolor{purple}128}\\ +\}\\ +type\_info~\{\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~header\_unions~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2543} +\noindent\mdline{2543}Here\mdline{2543}'\mdline{2543}s a \mdline{2543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.WriteRequest}}}\mdline{2543} to set the value of \mdline{2543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_ip{}[12]}}}\mdline{2543}:%mdk + +%mdk-data-line={2545} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2546} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}update~\{\\ +~~type:~INSERT\\ +~~entity~\{\\ +~~~~register\_entry~\{\\ +~~~~~~register\_id:~{\mdcolor{purple}369119267}\\ +~~~~~~index~\{\\ +~~~~~~~~index:~{\mdcolor{purple}12}\\ +~~~~~~\}\\ +~~~~~~data~\{\\ +~~~~~~~~header\_union~\{\\ +~~~~~~~~~~valid\_header\_name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~~~valid\_header~\{\\ +~~~~~~~~~~~~is\_valid:~true\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x04}{\mdcolor{maroon}"}\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{darkgreen}\#~...}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2569} +\subsubsection{\mdline{2569}8.5.5.\hspace*{0.5em}\mdline{2569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2569}, serializable \mdline{2569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2569} and \mdline{2569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}\label{sec-enum-serializable-enum-and-error}%mdk%mdk + +%mdk-data-line={2571} +\noindent\mdline{2571}P4\mdline{2571}\mdsub{16}\mdline{2571} supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or \mdline{2572}\textquotedblleft{}unsafe\textquotedblright{}\mdline{2572} enum) +\mdline{2573}[\mdcite{p4enums}{5}]\mdline{2573}. For \mdline{2573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2573} types with no underlying type\mdline{2573} \mdline{2573}\textemdash{}\mdline{2573} as well as \mdline{2573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2573} \mdline{2573}\textemdash{}\mdline{2573} +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in \mdline{2576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2576} to represent \mdline{2576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2576} and +\mdline{2577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2577} values.%mdk + +%mdk-data-line={2579} +\mdline{2579}Serializable \mdline{2579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2579} types have an underlying fixed-width unsigned integer +representation (\mdline{2580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2580}). All named enum members must be assigned an integer +value by the P4 programmer, but \mdline{2581}\emph{not all}\mdline{2581} valid numeric values for the +underlying type need to have a corresponding name. \mdline{2582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2582} includes the +mapping between entry name and entry value. When providing serializable enum +values through \mdline{2584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2584}, one must use the assigned integer value (\mdline{2584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum\_value}}}\mdline{2584} +bytestring field). P4Runtime does not provide a way for the client to use the +name\mdline{2586} \mdline{2586}\textemdash{}\mdline{2586} even when the enum member has one\mdline{2586} \mdline{2586}\textemdash{}\mdline{2586} instead of the value, as it makes +it easier for the server to respect the\mdline{2587}~\mdref{sec-read-write-symmetry}{read-write +symmetry}\mdline{2588} principle.%mdk + +%mdk-data-line={2590} +\subsubsection{\mdline{2590}8.5.6.\hspace*{0.5em}\mdline{2590}User-defined types}\label{sec-user-defined-types}%mdk%mdk + +%mdk-data-line={2592} +\noindent\mdline{2592}P4\mdline{2592}\mdsub{16}\mdline{2592} enables programmers to introduce new types\mdline{2592}~[\mdcite{p4newtypes}{11}]\mdline{2592}. While similar +to \mdline{2593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{2593}, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +\mdline{2596}\mdref{sec-psa-metadata-translation}{translation}\mdline{2596}. When introducing a new type, the +declaration can be annotated with \mdline{2597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2597} to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for\mdline{2599}~\mdref{sec-translation-of-port-numbers}{port numbers}\mdline{2599}, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. \mdline{2602}\textbf{The \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}} annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}})}\mdline{2604}. The type exposed to the control plane (referred to as the +\mdline{2605}\emph{controller\_type}\mdline{2605}) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a \mdline{2607}\emph{URI}\mdline{2607} (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the \mdline{2609}\emph{controller\_type}\mdline{2609} of the values exposed to the control plane. The +\mdline{2610}\emph{controller\_type}\mdline{2610} can be either \mdline{2610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2610} where \mdline{2610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2610} is any positive integer, or +\mdline{2611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{2611}, or a positive integer \mdline{2611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2611} which has the same meaning as \mdline{2611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2611}. +Specifying just an integer is deprecated.%mdk + +%mdk-data-line={2614} +\mdline{2614}It is recommended that the URI includes at least the P4 architecture name and +the type name.%mdk + +%mdk-data-line={2617} +\mdline{2617}A \mdline{2617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2617} annotation need not have any effect if it is used to +annotate anything in a P4 program other than a \mdline{2618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2618} declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect.%mdk + +%mdk-data-line={2622} +\mdline{2622}User-defined types are specified using the \mdline{2622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{2622} message, which has +the following fields:%mdk + +%mdk-data-line={2625} +\begin{itemize}%mdk + +%mdk-data-line={2625} +\item{} +%mdk-data-line={2625} +\mdline{2625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}representation}}}\mdline{2625}, a Protobuf \mdline{2625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2625} specifying how values of this type are +exchanged between client and server; it can be either:%mdk + +%mdk-data-line={2628} +\begin{itemize}%mdk + +%mdk-data-line={2628} +\item{} +%mdk-data-line={2628} +\mdline{2628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2628}, if and only if no \mdline{2628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2628} annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 \mdline{2630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2630} declaration is itself a +user-defined type, \mdline{2631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2631} is obtained by \mdline{2631}\textquotedblleft{}walking\textquotedblright{}\mdline{2631} the chain of +\mdline{2632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2632} declarations recursively until a built-in type (\mdline{2632}e.g.\mdline{2632} \mdline{2632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2632}) is +found.%mdk%mdk + +%mdk-data-line={2635} +\item{} +%mdk-data-line={2635} +\mdline{2635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}translated\_type}}}\mdline{2635}, if and only if the P4 \mdline{2635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2635} declaration was annotated +with \mdline{2636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2636}. It is of type \mdline{2636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeTranslation}}}\mdline{2636}, +which itself has two fields\mdline{2637} \mdline{2637}\textemdash{}\mdline{2637} \mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uri}}}\mdline{2637} and either \mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_string}}}\mdline{2637} or +\mdline{2638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_bitwidth}}}\mdline{2638} \mdline{2638}\textemdash{}\mdline{2638}, which map to the two input parameters to the +annotation.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2641} +\item{} +%mdk-data-line={2641} +\mdline{2641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{2641}, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2644} +\noindent\mdline{2644}For example, an architecture\mdline{2644} \mdline{2644}\textemdash{}\mdline{2644} in this case PSA\mdline{2644} \mdline{2644}\textemdash{}\mdline{2644} may introduce a new type +for port numbers:%mdk + +%mdk-data-line={2646} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2647} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~string,~e.g.~"eth0".}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~32-bit~integer,~e.g.~0xffffffff.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{darkgreen}//~Same~as~above.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_32\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_32\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2660} +\noindent\mdline{2660}In this case, the P4Info message would include the following \mdline{2660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2660} +messages:%mdk + +%mdk-data-line={2663} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2664} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_string:~\{\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2701} +\noindent\mdline{2701}Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (\mdline{2702}e.g.\mdline{2702} through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over \mdline{2704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2704} to enable users +to overwrite annotations included as part of the P4 architecture definition.%mdk + +%mdk-data-line={2707} +\subsubsection{\mdline{2707}8.5.7.\hspace*{0.5em}\mdline{2707}Trade-off for v1.x Releases}\label{sec-trade-off-for-v1x-releases}%mdk%mdk + +%mdk-data-line={2709} +\noindent\mdline{2709}For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +\mdline{2710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2710} with \mdline{2710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2710} in the \mdline{2710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{2710} message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +\mdline{2713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2713} to provide action parameter values and controller metadata +values. However \mdline{2714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2714} is used whenever appropriate for PSA externs and we +encourage the use of \mdline{2715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2715} in architecture-specific extensions.%mdk + +%mdk-data-line={2717} +\mdline{2717}In order to support\mdline{2717}~\mdref{sec-psa-metadata-translation}{translation}\mdline{2717} for action +parameters and match fields, we include a \mdline{2718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2718} field in +\mdline{2719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{2719}, \mdline{2719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Action.Param}}}\mdline{2719} and +\mdline{2720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ControllerPacketMetadata.Metadata}}}\mdline{2720}. In addition, the \mdline{2720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2720} +field for all of these message types must abide by the following rule when +\mdline{2722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2722} names a translated user-defined type:%mdk + +%mdk-data-line={2724} +\begin{itemize}%mdk + +%mdk-data-line={2724} +\item{} +%mdk-data-line={2724} +\mdline{2724}If the \mdline{2724}\emph{controller\_type}\mdline{2724} is a fixed-width unsigned bitstring, the \mdline{2724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2724} +field must be set to the bitwidth of the \mdline{2725}\emph{controller\_type}\mdline{2725}. This information +is redundant with the one included in the \mdline{2726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2726} entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent.%mdk%mdk + +%mdk-data-line={2732} +\item{} +%mdk-data-line={2732} +\mdline{2732}Otherwise (\mdline{2732}i.e.\mdline{2732}, if the \mdline{2732}\emph{controller\_type}\mdline{2732} is a string), the \mdline{2732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2732} must +be \mdline{2733}\textquotedblleft{}unset\textquotedblright{}\mdline{2733}, which, in Protobuf version 3, is the same as setting the field to +0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2736} +\noindent\mdline{2736}For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types:%mdk + +%mdk-data-line={2738} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2739} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{navy}@}{\mdcolor{navy}name}{\mdcolor{maroon}(".t")}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~meta.port1:~exact;~~{\mdcolor{darkgreen}//~meta.port1~has~type~PortId\_String\_t}\\ +~~~~meta.port2:~exact;~~{\mdcolor{darkgreen}//~meta.port2~has~type~PortId\_Bit32\_t}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2757} +\noindent\mdline{2757}This table would have the following representation in the generated P4Info +message:%mdk + +%mdk-data-line={2759} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2760} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tables~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}34728461}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port1}{\mdcolor{maroon}"}\\ +~~~~{\mdcolor{darkgreen}\#~notice~that~bitwidth~is~unset}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port2}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~{\mdcolor{darkgreen}\#~...}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2788} +\section{\mdline{2788}9.\hspace*{0.5em}\mdline{2788}P4 Entity Messages}\label{sec-p4-entity-msgs}%mdk%mdk + +%mdk-data-line={2790} +\noindent\mdline{2790}P4Runtime covers P4 entities that are either part of the P4\mdline{2790}\mdsub{16}\mdline{2790} language, or +defined as PSA externs. The sections below describe the messages for each +supported entity.%mdk + +%mdk-data-line={2794} +\subsection{\mdline{2794}9.1.\hspace*{0.5em}\mdline{2794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}\label{sec-table-entry}%mdk%mdk + +%mdk-data-line={2796} +\noindent\mdline{2796}The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action\mdline{2798}'\mdline{2798}s +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification.%mdk + +%mdk-data-line={2804} +\mdline{2804}P4Runtime supports inserting, modifying, deleting and reading table entries with +the \mdline{2805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2805} entity, which has the following fields:%mdk + +%mdk-data-line={2807} +\begin{itemize}%mdk + +%mdk-data-line={2807} +\item{} +%mdk-data-line={2807} +\mdline{2807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2807}, which identifies the table instance; the \mdline{2807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2807} is determined +by the P4Info message.%mdk%mdk + +%mdk-data-line={2810} +\item{} +%mdk-data-line={2810} +\mdline{2810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2810}, a repeated field of \mdline{2810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2810} messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration.%mdk%mdk + +%mdk-data-line={2814} +\item{} +%mdk-data-line={2814} +\mdline{2814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2814}, which indicates which of the table\mdline{2814}'\mdline{2814}s actions to execute in case of +match and with which argument values.%mdk%mdk + +%mdk-data-line={2817} +\item{} +%mdk-data-line={2817} +\mdline{2817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2817}, a 32-bit integer used to order entries when the table\mdline{2817}'\mdline{2817}s match key +includes an optional, ternary or range match.%mdk%mdk + +%mdk-data-line={2820} +\item{} +%mdk-data-line={2820} +\mdline{2820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2820}, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +\mdline{2824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{2824} field.%mdk%mdk + +%mdk-data-line={2826} +\item{} +%mdk-data-line={2826} +\mdline{2826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{2826}, an arbitrary \mdline{2826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2826} value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry.%mdk%mdk + +%mdk-data-line={2831} +\item{} +%mdk-data-line={2831} +\mdline{2831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2831}, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See\mdline{2832}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2833} section for more information.%mdk%mdk + +%mdk-data-line={2835} +\item{} +%mdk-data-line={2835} +\mdline{2835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2835}, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See\mdline{2836}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2837} section for more information.%mdk%mdk + +%mdk-data-line={2839} +\item{} +%mdk-data-line={2839} +\mdline{2839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2839}, a boolean flag which indicates whether the table entry is +the default entry for the table. See\mdline{2840}~\mdref{sec-default-entry}{Default entry}\mdline{2840} +section for more information.%mdk%mdk + +%mdk-data-line={2843} +\item{} +%mdk-data-line={2843} +\mdline{2843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2843} and \mdline{2843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2843}, which are two fields used to +implement idle-timeout support for the table, if applicable. See +\mdline{2845}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{2845} section for more information.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2847} +\noindent\mdline{2847}The \mdline{2847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2847} field must be set to a non-zero value if the match key includes a +ternary match (\mdline{2848}i.e.\mdline{2848} in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an \mdline{2849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{2849}, \mdline{2849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2849} or +\mdline{2850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2850} match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches.%mdk + +%mdk-data-line={2859} +\mdline{2859}The \mdline{2859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2859} and \mdline{2859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2859} fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for \mdline{2861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2861} and \mdline{2861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{2861} updates. When deleting +an entry, these key fields (along with \mdline{2862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2862}) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a \mdline{2864}\emph{keyless}\mdline{2864} +table (the table has an empty match key), the server must reject all attempts to +\mdline{2866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2866} a match entry and return an \mdline{2866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2866} error.%mdk + +%mdk-data-line={2868} +\mdline{2868}The number of match entries that a table \mdline{2868}\emph{should}\mdline{2868} support is indicated in P4Info +(\mdline{2869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2869} field of \mdline{2869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{2869} message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P4\mdline{2870}\mdsub{16}\mdline{2870} specification for the +\mdline{2871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2871} property\mdline{2871}~[\mdcite{p4tableproperties}{30}]\mdline{2871}. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +\mdline{2875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{2875} when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached.%mdk + +%mdk-data-line={2880} +\subsubsection{\mdline{2880}9.1.1.\hspace*{0.5em}\mdline{2880}Match Format}\label{sec-match-format}%mdk%mdk + +%mdk-data-line={2882} +\noindent\mdline{2882}The bytes fields in the \mdline{2882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2882} message follow the format described in +\mdline{2883}\mdref{sec-bytestrings}{Bytestrings}\mdline{2883}.%mdk + +%mdk-data-line={2885} +\mdline{2885}For \mdline{2885}\textquotedblleft{}don't care\textquotedblright{}\mdline{2885} matches, the P4Runtime client must omit the field\mdline{2885}'\mdline{2885}s entire +\mdline{2886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2886} entry when building the \mdline{2886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2886} repeated field of the \mdline{2886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2886} +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for \mdline{2888}\textquotedblleft{}don't care\textquotedblright{}\mdline{2888} matches, which is needed +to ensure\mdline{2889}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2889}. For PSA match types, +a \mdline{2890}\textquotedblleft{}don't care\textquotedblright{}\mdline{2890} match for a specific match key field is defined as follows:%mdk + +%mdk-data-line={2892} +\begin{itemize}%mdk + +%mdk-data-line={2892} +\item{} +%mdk-data-line={2892} +\mdline{2892}For a \mdline{2892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2892} match, it is logically equivalent to a mask of zeros.%mdk%mdk + +%mdk-data-line={2894} +\item{} +%mdk-data-line={2894} +\mdline{2894}For a \mdline{2894}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{2894} match, it is logically equivalent to a wildcard match.%mdk%mdk + +%mdk-data-line={2896} +\item{} +%mdk-data-line={2896} +\mdline{2896}For an \mdline{2896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2896} match, it is logically equivalent to a prefix\mdline{2896}\_\mdline{2896}len of zero.%mdk%mdk + +%mdk-data-line={2898} +\item{} +%mdk-data-line={2898} +\mdline{2898}For a \mdline{2898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2898} match, it is logically equivalent to a range which includes all +possible values for the field.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2901} +\noindent\mdline{2901}Note that there is no \mdline{2901}\textquotedblleft{}don't care\textquotedblright{}\mdline{2901} value for \mdline{2901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2901} matches and therefore exact +match fields can never be omitted from the \mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2902} message.%mdk + +%mdk-data-line={2904} +\mdline{2904}The following example shows a P4Runtime message that treats a \mdline{2904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2904} field +as a \mdline{2905}\textquotedblleft{}don't care\textquotedblright{}\mdline{2905} match. The P4 program defines table \mdline{2905}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{2905} with \mdline{2905}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2905} +and \mdline{2906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2906} fields in its match key:%mdk + +%mdk-data-line={2908} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2909} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~ternary;\\ +~~~~istd.ingress\_port:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2920} +\noindent\mdline{2920}In this P4Runtime request, the client omits the table\mdline{2920}'\mdline{2920}s \mdline{2920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2920} field +from the repeated \mdline{2921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2921} field to indicate a \mdline{2921}\textquotedblleft{}don't care\textquotedblright{}\mdline{2921} match. As shown +below, the \mdline{2922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2922} specifies only the \mdline{2922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2922} field given by \mdline{2922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id:~2}}}\mdline{2922}.%mdk + +%mdk-data-line={2924} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2925} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}33554439}~~{\mdcolor{darkgreen}\#~Table~t's~ID.}\\ +~~~~match~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~field\_id~1~is~not~present~to~use~the~don't~care~ternary~value.}\\ +~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~exact~\{\\ +~~~~~~~~value:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x20}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~action~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~Action~selection~goes~here.}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2943} +\noindent\mdline{2943}For every member of the \mdline{2943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2943} repeated \mdline{2943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2943} field, \mdline{2943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id}}}\mdline{2943} must be +a valid id for the table, as per the P4Info, and one of the fields in +\mdline{2945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{2945} must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an \mdline{2947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2947} error code.%mdk + +%mdk-data-line={2949} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2949} +\item\mdline{2949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2949} match + +%mdk-data-line={2950} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2950} +\item\mdline{2950}The binary string encoding of the value must conform to the +\mdline{2951}\mdref{sec-bytestrings}{Bytestrings}\mdline{2951} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2953} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2954} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.exact().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2957} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2957} +\item\mdline{2957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2957} match + +%mdk-data-line={2958} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2958} +\item\mdline{2958}The binary string encoding of the value (when present) must conform to the +\mdline{2959}\mdref{sec-bytestrings}{Bytestrings}\mdline{2959} requirements.%mdk + +%mdk-data-line={2960} +\item\mdline{2960}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2960} match must be omitted.%mdk + +%mdk-data-line={2961} +\item\mdline{2961}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2961} bits must be 0 in value.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2963} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2964} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.lpm().value()))\\ +\\ +pLen~=~match.lpm().prefix\_len()\\ +assert(pLen~\textgreater{}~0)\\ +\\ +trailing\_zeros~=~countTrailingZeros(match.lpm().value())\\ +assert(trailing\_zeros~\textgreater{}=~field\_bits~-~pLen)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2973} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2973} +\item\mdline{2973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2973} match + +%mdk-data-line={2974} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2974} +\item\mdline{2974}The binary string encoding of the value (when present) and mask (when +present) must conform to the\mdline{2975}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2975} requirements.%mdk + +%mdk-data-line={2976} +\item\mdline{2976}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2976} match must be omitted.%mdk + +%mdk-data-line={2977} +\item\mdline{2977}Masked bits must be 0 in value. This constraint taken together +with the\mdline{2978}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2978} requirements means that the +value\mdline{2979}'\mdline{2979}s binary string is never longer than the mask\mdline{2979}'\mdline{2979}s binary string. +When the value\mdline{2980}'\mdline{2980}s string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2984} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2985} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.ternary().value()))\\ +assert(BytestringValid(match.ternary().mask()))\\ +assert(match.ternary().value().size()~\textless{}=~match.ternary().mask().size());\\ +\\ +value~=~parseInteger(match.ternary().value())\\ +mask~=~parseInteger(match.ternary().mask())\\ +\\ +assert(mask~!=~0)\\ +\\ +assert(value~\&~mask~==~value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2997} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2997} +\item\mdline{2997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2997} match + +%mdk-data-line={2998} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2998} +\item\mdline{2998}The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the\mdline{2999}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2999} +requirements.%mdk + +%mdk-data-line={3001} +\item\mdline{3001}Low bound must be less than or equal to the high bound.%mdk + +%mdk-data-line={3002} +\item\mdline{3002}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3002} match must be omitted.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3004} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3005} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.range().low()))\\ +assert(BytestringValid(match.range().high()))\\ +\\ +low~=~parseInteger(match.range().low())\\ +high~=~parseInteger(match.range().high())\\ +\\ +assert(low~\textless{}=~high)\\ +\\ +assert(low~!=~min\_field\_value~\textbar{}\textbar{}~high~!=~max\_field\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3016} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3016} +\item\mdline{3016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3016} match + +%mdk-data-line={3017} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3017} +\item\mdline{3017}The binary string encoding of the value must conform to the +\mdline{3018}\mdref{sec-bytestrings}{Bytestrings}\mdline{3018} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3020} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3021} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.optional().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3024} +\subsubsection{\mdline{3024}9.1.2.\hspace*{0.5em}\mdline{3024}Action Specification}\label{sec-action-specification}%mdk%mdk + +%mdk-data-line={3026} +\noindent\mdline{3026}The \mdline{3026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3026} \mdline{3026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3026} field must be set for every \mdline{3026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3026} update but may be +left unset for \mdline{3027}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3027} updates, in which case the action specification for the +table entry will not be modified (if a \mdline{3028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3028} update has an unset action field +and does not modify any direct resource attached to the table then the \mdline{3029}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3029} +update is a no-op). Based on the implementation property value of the P4 table, +the \mdline{3031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3031} in the \mdline{3031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3031} message will either be:%mdk + +%mdk-data-line={3033} +\begin{itemize}%mdk + +%mdk-data-line={3033} +\item{} +%mdk-data-line={3033} +\mdline{3033}an \mdline{3033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3033} specification for direct tables (with no P4 \mdline{3033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3033} +property)%mdk%mdk + +%mdk-data-line={3036} +\item{} +%mdk-data-line={3036} +\mdline{3036}an action profile member id for indirect tables for which the \mdline{3036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3036} +property is an action profile with no selector.%mdk%mdk + +%mdk-data-line={3039} +\item{} +%mdk-data-line={3039} +\mdline{3039}an action profile member id or group id for indirect tables for which the +\mdline{3040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3040} property is an action profile with selector.%mdk%mdk + +%mdk-data-line={3042} +\item{} +%mdk-data-line={3042} +\mdline{3042}an \mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3042} specification for indirect tables for +which the \mdline{3043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3043} property is an action profile with +selector. This usage is described in\mdline{3044}~\mdref{sec-oneshot}{One Shot Action Selector +Programming}\mdline{3045}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3047} +\noindent\mdline{3047}If the \mdline{3047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3047} does not match the table description in the P4Info (\mdline{3047}e.g.\mdline{3047} the +\mdline{3048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3048} is \mdline{3048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member\_id}}}\mdline{3048} for a direct table), the server must +return an \mdline{3049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3049} error code.%mdk + +%mdk-data-line={3051} +\mdline{3051}The \mdline{3051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3051} Protobuf message has the following fields:%mdk + +%mdk-data-line={3053} +\begin{itemize}%mdk + +%mdk-data-line={3053} +\item{} +%mdk-data-line={3053} +\mdline{3053}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3053}, which identifies the action instance; the \mdline{3053}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3053} is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an \mdline{3055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3055} error +code. If the client uses a valid \mdline{3056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3056} for the table but does not +respect the action scope specified in P4Info (\mdline{3057}e.g.\mdline{3057} tries to set a \mdline{3057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{3057} +action as the default action), the server must return a \mdline{3058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3058} +error code.%mdk%mdk + +%mdk-data-line={3061} +\item{} +%mdk-data-line={3061} +\mdline{3061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{3061}: a repeated Protobuf field of action parameter values, each encoded +as a \mdline{3062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{3062} message. For each parameter, \mdline{3062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}param\_id}}}\mdline{3062} must be valid for the +action (as per the P4Info) and value must follow the format described in +\mdline{3064}\mdref{sec-bytestrings}{Bytestrings}\mdline{3064}. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an \mdline{3066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3066} error code +if a parameter id is missing, if an extra parameter\mdline{3067} \mdline{3067}\textemdash{}\mdline{3067} id not found in the +P4Info\mdline{3068} \mdline{3068}\textemdash{}\mdline{3068} was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +\mdline{3070}\mdref{sec-bytestrings}{Bytestrings}\mdline{3070} format.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3072} +\noindent\mdline{3072}For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a \mdline{3074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3074} error code.%mdk + +%mdk-data-line={3076} +\subsubsection{\mdline{3076}9.1.3.\hspace*{0.5em}\mdline{3076}Default Entry}\label{sec-default-entry}%mdk%mdk + +%mdk-data-line={3078} +\noindent\mdline{3078}According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer\mdline{3079} \mdline{3079}\textemdash{}\mdline{3079} or defaults to \mdline{3079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3079} +(which is a no-op) otherwise\mdline{3080} \mdline{3080}\textemdash{}\mdline{3080} and assuming it is not declared as \mdline{3080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3080}, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3082} and \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3082} updates on the default entry and the +P4Runtime server must return an \mdline{3083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3083} error code if the client +attempts one.%mdk + +%mdk-data-line={3086} +\mdline{3086}The default entry is identified by setting the \mdline{3086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3086} boolean field +to true. When this flag is set to true, the repeated \mdline{3087}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3087} field must be empty +and the \mdline{3088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3088} field must be set to zero, otherwise the P4Runtime server +must return an \mdline{3089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3089} error code. When performing a \mdline{3089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3089} update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its \mdline{3093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3093} and \mdline{3093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3093} value as well as the +configurations for its\mdline{3094}~\mdref{sec-direct-resources}{direct resources}\mdline{3094} will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a \mdline{3096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3096} +error code if the client attempts to modify it.%mdk + +%mdk-data-line={3099} +\mdline{3099}Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to\mdline{3100}~\mdref{sec-direct-resources}{direct resources}\mdline{3100}.%mdk + +%mdk-data-line={3102} +\mdline{3102}In this P4Runtime release, we have decided to restrict the default entry for +indirect tables\mdline{3103} \mdline{3103}\textemdash{}\mdline{3103} tables with an ActionProfile or ActionSelector +\mdline{3104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3104} property\mdline{3104} \mdline{3104}\textemdash{}\mdline{3104} to a constant \mdline{3104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3104} action entry, with the +hope that it would simplify the implementation of the P4Runtime service.%mdk + +%mdk-data-line={3107} +\subsubsection{\mdline{3107}9.1.4.\hspace*{0.5em}\mdline{3107}Constant Tables}\label{sec-constant-tables}%mdk%mdk + +%mdk-data-line={3109} +\noindent\mdline{3109}Constant tables are defined as tables whose match entries are immutable. They +are identified by the \mdline{3110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3110} flag in P4Info.%mdk + +%mdk-data-line={3112} +\mdline{3112}The only write updates which are allowed for constant tables are \mdline{3112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3112} +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +\mdline{3116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3116} error. Just like any table entry \mdline{3116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3116} request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a \mdline{3120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3120} error.%mdk + +%mdk-data-line={3122} +\mdline{3122}The contents of const tables can be queried by the client through a +\mdline{3123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3123}. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: \mdline{3124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3124}, \mdline{3124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3124}, \mdline{3124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3124}, +\mdline{3125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3125}, and \mdline{3125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3125} (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the \mdline{3128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3128} field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P4\mdline{3130}\mdsub{16}\mdline{3130} does not support assigning explicit priorities to static +entries. When a priority value is required (\mdline{3131}e.g.\mdline{3131} for tables including \mdline{3131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3131}, +\mdline{3132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3132} or \mdline{3132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3132} matches), it is inferred based on the order in which +entries appear in the table declaration.%mdk + +%mdk-data-line={3135} +\subsubsection{\mdline{3135}9.1.5.\hspace*{0.5em}\mdline{3135}Wildcard Reads}\label{sec-table-wildcard-reads}%mdk%mdk + +%mdk-data-line={3137} +\noindent\mdline{3137}When performing a \mdline{3137}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3137}, the P4Runtime client can select all entries +from one or all tables on the target and use several of the \mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3138} fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as \mdline{3142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3142} and \mdline{3142}\textquotedblleft{}unset\textquotedblright{}\mdline{3142} for message fields such as \mdline{3142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3142}. The following +fields may be used to select and filter results:%mdk + +%mdk-data-line={3145} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3145} +\item\mdline{3145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3145}: If default (0), entries from all tables\mdline{3145} \mdline{3145}\textemdash{}\mdline{3145} including constant +tables\mdline{3146} \mdline{3146}\textemdash{}\mdline{3146} will be selected and no other filter can be used. Otherwise only +the specified table will be considered.%mdk + +%mdk-data-line={3148} +\item\mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3148}: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned.%mdk + +%mdk-data-line={3152} +\item\mdline{3152}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3152}: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an \mdline{3153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3153} (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id.%mdk + +%mdk-data-line={3159} +\item\mdline{3159}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3159}: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value.%mdk + +%mdk-data-line={3162} +\item\mdline{3162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3162}: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +\mdline{3164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3164} value.%mdk + +%mdk-data-line={3165} +\item\mdline{3165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3165}: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided \mdline{3167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3167} value.%mdk + +%mdk-data-line={3168} +\item\mdline{3168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3168}: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3172} +\noindent\mdline{3172}For example, in order to read all entries from all tables from device 3, the +client can use the following \mdline{3173}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3173} message.%mdk + +%mdk-data-line={3175} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3176} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0}\\ +~~~~priority:~{\mdcolor{purple}0}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3187} +\noindent\mdline{3187}In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following \mdline{3188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3188} +message:%mdk + +%mdk-data-line={3191} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3192} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~priority:~{\mdcolor{purple}11}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3203} +\noindent\mdline{3203}The canonical representation of \mdline{3203}\textquotedblleft{}don't care\textquotedblright{}\mdline{3203} matches, combined with the ability +to do a wildcard read on all table entries by leaving the \mdline{3204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3204} field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single \mdline{3206}\textquotedblleft{}don't care\textquotedblright{}\mdline{3206} entry or to do a wildcard +read. If a table has no fields with match kind \mdline{3207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3207}, it is possible via +P4Runtime to add an entry that is \mdline{3208}\textquotedblleft{}don't care\textquotedblright{}\mdline{3208} for all fields (\mdline{3208}i.e.\mdline{3208} has an empty +\mdline{3209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3209} field) but is not the default entry (\mdline{3209}i.e.\mdline{3209} \mdline{3209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3209} is +false). When reading this entry from the table, there is no way to read \mdline{3210}\emph{only}\mdline{3210} +that entry from the table, because it would require providing an unset \mdline{3211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3211} +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single \mdline{3214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{3214} match:%mdk + +%mdk-data-line={3216} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3217} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;~fwd;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3227} +\noindent\mdline{3227}The following \mdline{3227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3227} message can be used to add 2 entries:%mdk + +%mdk-data-line={3228} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3229} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{~{\mdcolor{darkgreen}\#~don't~care~entry}\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +~~table~entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~match~\{\\ +~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~lpm~\{\\ +~~~~~~~~value:~{\mdcolor{purple}0x0a000000}\\ +~~~~~~~~prefix\_len:~{\mdcolor{purple}8}\\ +~~~~~~\}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3248} +\noindent\mdline{3248}The first entry is a \mdline{3248}\textquotedblleft{}don't care\textquotedblright{}\mdline{3248} entry, while the second one matches all +\mdline{3249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}10.0.0.0/8}}}\mdline{3249} addresses. The second entry has higher priority than the first one.%mdk + +%mdk-data-line={3251} +\mdline{3251}The following \mdline{3251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3251} message will return \mdline{3251}\emph{all}\mdline{3251} entries in the table, not +just the \mdline{3252}\textquotedblleft{}don't care\textquotedblright{}\mdline{3252} entry.%mdk + +%mdk-data-line={3253} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3254} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3262} +\noindent\mdline{3262}This issue also exists for tables with \mdline{3262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3262}, \mdline{3262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3262}, and \mdline{3262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3262} +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the \mdline{3265}\textquotedblleft{}don't care\textquotedblright{}\mdline{3265} entry will be returned to the +client. If the client uses distinct priority values for all entries\mdline{3266} \mdline{3266}\textemdash{}\mdline{3266} which is +strongly recommended to achieve\mdline{3267}~\mdref{sec-table-entry}{deterministic behavior}\mdline{3267} \mdline{3267}\textemdash{}\mdline{3267}, +then there is no ambiguity because the wildcard read will actually return a +single entry (the \mdline{3269}\textquotedblleft{}don't care\textquotedblright{}\mdline{3269} entry) as long as the \mdline{3269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3269} field is set to +the correct value.%mdk + +%mdk-data-line={3272} +\subsubsection{\mdline{3272}9.1.6.\hspace*{0.5em}\mdline{3272}Direct Resources}\label{sec-direct-resources}%mdk%mdk + +%mdk-data-line={3274} +\noindent\mdline{3274}In addition to the \mdline{3274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3274} and \mdline{3274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3274} entities, +P4Runtime support reading and writing direct resources as part of the +\mdline{3276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3276} message. This is convenient for two reasons:%mdk + +%mdk-data-line={3278} +\begin{itemize}%mdk + +%mdk-data-line={3278} +\item{} +%mdk-data-line={3278} +\mdline{3278}A table entry and its direct resources can be read with a single entity when +doing a \mdline{3279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{3279} RPC call%mdk%mdk + +%mdk-data-line={3281} +\item{} +%mdk-data-line={3281} +\mdline{3281}The initial configuration for an entry\mdline{3281}'\mdline{3281}s direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can \mdline{3286}\textquotedblleft{}hit\textquotedblright{}\mdline{3286} the table entry without +executing the appropriate meter entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3289} +\noindent\mdline{3289}Once the table entry has been inserted, the P4Runtime client is free to use the +\mdline{3290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3290} and \mdline{3290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3290} messages for read and write +operations on \mdline{3291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3291} and \mdline{3291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3291} instances. For example, it is +usually more convenient as well as more efficient to use \mdline{3292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3292} to +query a counter entry value rather than use \mdline{3293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3293}, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry.%mdk + +%mdk-data-line={3297} +\mdline{3297}The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does \mdline{3298}\emph{not}\mdline{3298} need to be \mdline{3298}\textquotedblleft{}executed\textquotedblright{}\mdline{3298} in +every action bound to the table. It is an error to provide a direct resource +configuration in a \mdline{3300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3300} message when programming an action that does not +execute the direct resource, and the server must return an \mdline{3301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3301} +error code.%mdk + +%mdk-data-line={3304} +\mdline{3304}We leverage Protobuf\mdline{3304}'\mdline{3304}s ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the \mdline{3306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3306} message. The list below describes how +the server must handle the \mdline{3307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3307} and \mdline{3307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3307} fields for read and +write requests, based on whether the fields are set or not. We do not cover +error cases in the list, \mdline{3309}i.e.\mdline{3309} we assume that we are dealing with a table which +is assigned a direct counter / a direct meter, and that the action being used +for the table entry \mdline{3311}\textquotedblleft{}executes\textquotedblright{}\mdline{3311} the direct resource appropriately.%mdk + +%mdk-data-line={3313} +\begin{itemize}%mdk + +%mdk-data-line={3313} +\item{} +%mdk-data-line={3313} +\mdline{3313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3313} field%mdk + +%mdk-data-line={3314} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3314} +\item\mdline{3314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3314} + +%mdk-data-line={3315} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3315} +\item\mdline{3315}if \mdline{3315}\textbf{unset}\mdline{3315}: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets).%mdk + +%mdk-data-line={3317} +\item\mdline{3317}if \mdline{3317}\textbf{set}\mdline{3317}: The initial configuration for the meter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3319} +\item\mdline{3319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3319} + +%mdk-data-line={3320} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3320} +\item\mdline{3320}if \mdline{3320}\textbf{unset}\mdline{3320}: The meter entry\mdline{3320}'\mdline{3320}s configuration is reset to the default +(meter returns GREEN for all packets).%mdk + +%mdk-data-line={3322} +\item\mdline{3322}if \mdline{3322}\textbf{set}\mdline{3322}: The value provided by the client is used to re-configure +the meter entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3324} +\item\mdline{3324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3324} + +%mdk-data-line={3325} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3325} +\item\mdline{3325}if \mdline{3325}\textbf{unset}\mdline{3325}: The response does not include the meter entry\mdline{3325}'\mdline{3325}s +configuration (\mdline{3326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3326} is unset in the response).%mdk + +%mdk-data-line={3327} +\item\mdline{3327}if \mdline{3327}\textbf{set}\mdline{3327}: If the meter entry\mdline{3327}'\mdline{3327}s configuration is the default +configuration, \mdline{3328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3328} is unset in the response. Otherwise, the +response includes the meter entry\mdline{3329}'\mdline{3329}s configuration that was written by +the client earlier. This respects the \mdline{3330}\textquotedblleft{}read-write symmetry\textquotedblright{}\mdline{3330} principle.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3332} +\item{} +%mdk-data-line={3332} +\mdline{3332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3332} field%mdk + +%mdk-data-line={3333} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3333} +\item\mdline{3333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3333} + +%mdk-data-line={3334} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3334} +\item\mdline{3334}if \mdline{3334}\textbf{unset}\mdline{3334}: The initial value for the counter entry is the default +(0).%mdk + +%mdk-data-line={3336} +\item\mdline{3336}if \mdline{3336}\textbf{set}\mdline{3336}: The initial value for the counter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3338} +\item\mdline{3338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3338} + +%mdk-data-line={3339} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3339} +\item\mdline{3339}if \mdline{3339}\textbf{unset}\mdline{3339}: The counter entry\mdline{3339}'\mdline{3339}s value is not changed.%mdk + +%mdk-data-line={3340} +\item\mdline{3340}if \mdline{3340}\textbf{set}\mdline{3340}: The value provided by the client is written to the counter +entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3342} +\item\mdline{3342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3342} + +%mdk-data-line={3343} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3343} +\item\mdline{3343}if \mdline{3343}\textbf{unset}\mdline{3343}: The response does not include the counter entry\mdline{3343}'\mdline{3343}s value +(\mdline{3344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3344} is unset in the response).%mdk + +%mdk-data-line={3345} +\item\mdline{3345}if \mdline{3345}\textbf{set}\mdline{3345}: The response includes the counter entry\mdline{3345}'\mdline{3345}s value read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3348} +\noindent\mdline{3348}In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +\mdline{3350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3350} field unset when inserting \mdline{3350}\textbf{or modifying}\mdline{3350} a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the \mdline{3352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3352} message +(\mdline{3353}i.e.\mdline{3353} the \mdline{3353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3353} field must be set to match the existing configuration).%mdk + +%mdk-data-line={3355} +\subsubsection{\mdline{3355}9.1.7.\hspace*{0.5em}\mdline{3355}Idle-timeout}\label{sec-idle-timeout}%mdk%mdk + +%mdk-data-line={3357} +\noindent\mdline{3357}P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not \mdline{3359}\textquotedblleft{}hit\textquotedblright{}\mdline{3359} (\mdline{3359}i.e.\mdline{3359} not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification\mdline{3361} \mdline{3361}\textemdash{}\mdline{3361} using the +\mdline{3362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3362} message\mdline{3362} \mdline{3362}\textemdash{}\mdline{3362} to the master client, which can then take +action, such as remove the idle table entry.%mdk + +%mdk-data-line={3365} +\mdline{3365}Two fields of the \mdline{3365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3365} Protobuf message are used to implement idle +timeout:%mdk + +%mdk-data-line={3368} +\begin{itemize}%mdk + +%mdk-data-line={3368} +\item{} +%mdk-data-line={3368} +\mdline{3368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3368}: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, \mdline{3369}i.e.\mdline{3369} no +\mdline{3370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3370} message will ever be generated for this entry. When +a client reads a \mdline{3371}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3371}, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry.%mdk%mdk + +%mdk-data-line={3375} +\item{} +%mdk-data-line={3375} +\mdline{3375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3375}: a Protobuf message with a single field (\mdline{3375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{3375}) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The \mdline{3377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3377} field must be unset for a +\mdline{3378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3378} write. When reading a table entry, \mdline{3378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3378} must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3383} +\noindent\mdline{3383}These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an \mdline{3385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3385} error code if at least one of these +conditions is met:%mdk + +%mdk-data-line={3388} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3388} +\item\mdline{3388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3388} is set to a non-zero value, or%mdk + +%mdk-data-line={3389} +\item\mdline{3389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3389} is set%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3391} +\noindent\mdline{3391}The target should do its best to approximate the \mdline{3391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3391} value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the \mdline{3394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3394} write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for \mdline{3396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3396}.%mdk + +%mdk-data-line={3398} +\mdline{3398}P4Runtime does not support idle timeout for default entries. When the +\mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3399} flag is set in a \mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3399} message, \mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3399} +must be set to 0 (default) and \mdline{3400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3400} must be unset. If the +server receives a \mdline{3401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3401} message which violates this, it must return an +\mdline{3402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3402} error.%mdk + +%mdk-data-line={3404} +\mdline{3404}For more information about idle timeout, in particular regarding +\mdline{3405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3405}, please refer to the\mdline{3405}~\mdref{sec-table-idle-timeout-notification}{Table idle timeout +notifications}\mdline{3406} section.%mdk + +%mdk-data-line={3408} +\subsection{\mdline{3408}9.2.\hspace*{0.5em}\mdline{3408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3408} \mdline{3408}\&\mdline{3408} \mdline{3408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}\label{sec-action-profile-member-and-group}%mdk%mdk + +%mdk-data-line={3410} +\noindent\mdline{3410}P4Runtime defines an API for programming a PSA ActionProfile extern using +\mdline{3411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3411} messages. A PSA ActionSelector extern can be programmed +using both \mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3412} and \mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3412} messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table \mdline{3416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3416} for L3 routing, implemented with an action +selector \mdline{3417}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3417}.%mdk + +%mdk-data-line={3419} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3420} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector(HashAlgorithm.crc32,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}size~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w1024,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}output\_width~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w10)~as;\\ +\\ +{\bfseries{\mdcolor{navy}action}}~set\_nhop(PortId\_t~p,~EthAddr~smac,~EthAddr~dmac)~\{\\ +~~istd.egress\_port~=~p;\\ +~~hdr.ethernet.smac~=~smac;\\ +~~hdr.ethernet.dmac~=~dmac;\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;~~{\mdcolor{darkgreen}//~LPM~on~destination~IP~address}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~set\_nhop;\\ +~~\}\\ +~~implementation~=~as;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3441} +\noindent\mdline{3441}When programming table \mdline{3441}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3441} in the example above, a P4Runtime client should +specify the \mdline{3442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3442} in the \mdline{3442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3442} to be a reference to either an +action profile member or group. The reference is a non-zero \mdline{3443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3443} identifier +that uniquely identifies a member or group programmed in the action selector +\mdline{3445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3445}.%mdk + +%mdk-data-line={3447} +\mdline{3447}If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata.%mdk + +%mdk-data-line={3452} +\mdline{3452}If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata.%mdk + +%mdk-data-line={3463} +\subsubsection{\mdline{3463}9.2.1.\hspace*{0.5em}\mdline{3463}Action Profile Member Programming}\label{sec-action-profile-member-programming}%mdk%mdk + +%mdk-data-line={3465} +\noindent\mdline{3465}Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a \mdline{3466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3466} identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the \mdline{3468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3468} +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the \mdline{3470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3470} attributes of the +tables \mdline{3471}\emph{must have an identical list of P4 actions}\mdline{3471}. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector.%mdk + +%mdk-data-line={3475} +\mdline{3475}An \mdline{3475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3475} entity update message has the following fields:%mdk + +%mdk-data-line={3477} +\begin{itemize}%mdk + +%mdk-data-line={3477} +\item{} +%mdk-data-line={3477} +\mdline{3477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3477} is the \mdline{3477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3477} identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3480} +\item{} +%mdk-data-line={3480} +\mdline{3480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3480} is the non-zero \mdline{3480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3480} identifier of the action profile member +entry being updated.%mdk%mdk + +%mdk-data-line={3483} +\item{} +%mdk-data-line={3483} +\mdline{3483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3483} is the specification of the P4 action instance bound to the action +profile member entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3486} +\noindent\mdline{3486}An action profile member may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3489} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3489} +\item\mdline{3489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3489}: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an \mdline{3491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3491} error +code. The action specification must be provided, or the server must return +\mdline{3493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3493}. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return \mdline{3495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3495}.%mdk + +%mdk-data-line={3496} +\item\mdline{3496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3496}: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return \mdline{3497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3497}, +and the action specification must be provided, or the server must return +\mdline{3499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3499}.%mdk + +%mdk-data-line={3500} +\item\mdline{3500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3500}: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a \mdline{3501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3501} error code. The member +must not be part of an action profile group, or the server must return +\mdline{3503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3503}. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return \mdline{3506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3506}. \mdline{3506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3506} and \mdline{3506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3506} are the only +fields that are considered when performing a \mdline{3507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3507} and every other field +will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3510} +\noindent\mdline{3510}When reading, an \mdline{3510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3510} message with \mdline{3510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3510} and +\mdline{3511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3511} equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with \mdline{3512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3512} equal to the id of +an existing ActionProfile or ActionSelector object, and a \mdline{3513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3513} equal to +0, will read all members of that specified object.%mdk + +%mdk-data-line={3516} +\subsubsection{\mdline{3516}9.2.2.\hspace*{0.5em}\mdline{3516}Action Profile Group Programming}\label{sec-action-profile-group-programming}%mdk%mdk + +%mdk-data-line={3518} +\noindent\mdline{3518}Action profile groups are entries in an ActionSelector and are referenced by a +\mdline{3519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3519} identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type.%mdk + +%mdk-data-line={3523} +\mdline{3523}Within a single ActionSelector object, the \mdline{3523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3523} values used to identify its +members are in a separate \mdline{3524}\textquoteleft{}scope\textquoteright{}\mdline{3524} from the \mdline{3524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3524} values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5.%mdk + +%mdk-data-line={3528} +\mdline{3528}There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it.%mdk + +%mdk-data-line={3534} +\mdline{3534}An \mdline{3534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3534} entity update message has the following fields:%mdk + +%mdk-data-line={3536} +\begin{itemize}%mdk + +%mdk-data-line={3536} +\item{} +%mdk-data-line={3536} +\mdline{3536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3536} is the \mdline{3536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3536} identifier of the PSA ActionSelector +extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3539} +\item{} +%mdk-data-line={3539} +\mdline{3539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3539} is the non-zero \mdline{3539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3539} identifier of the action profile group +entry being updated.%mdk%mdk + +%mdk-data-line={3542} +\item{} +%mdk-data-line={3542} +\mdline{3542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3542} is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields:%mdk + +%mdk-data-line={3545} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3545} +\item\mdline{3545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3545} for looking up the member table in the selector.%mdk + +%mdk-data-line={3546} +\item\mdline{3546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3546} specifying the probability of the member\mdline{3546}'\mdline{3546}s selection at +runtime. 0 is not a valid \mdline{3547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3547} value and the server must return +\mdline{3548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3548} if the client attempts to use it.%mdk + +%mdk-data-line={3549} +\item\mdline{3549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3549} is the controller-defined 32-bit port number that the member\mdline{3549}'\mdline{3549}s +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +\mdline{3552}\mdref{action-selector-constraints}{9.2.4}\mdline{3552} for notes on the behavior if all members in +a group are excluded for this reason. If \mdline{3553}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3553} is 0, then the member is +always included in the selection, regardless of the status of any port of +the device. The value must be 0 or the SDN port number of an existing +port on the device, otherwise the server must return \mdline{3556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3556}.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3558} +\item{} +%mdk-data-line={3558} +\mdline{3558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3558} is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +\mdline{3560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3560} update. See the subsection below for the\mdline{3560}~\mdref{sec-max-size-rules}{rules on setting +\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\mdline{3561}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3563} +\noindent\mdline{3563}An action profile group may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3566} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3566} +\item\mdline{3566}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3566}: Add a new group entry bound to a set of existing action profile +members. \mdline{3567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}The~group\_id}}}\mdline{3567} must be different from ids of already programmed +groups for that selector, or the server must return an \mdline{3568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3568} error +code. All members specified in the group must exist in the selector, or the +server must return \mdline{3570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3570}. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target.%mdk + +%mdk-data-line={3572} +\item\mdline{3572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3572}: Modify the member set specification of an existing group entry. An +entry with the \mdline{3573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3573} must exist, or the server must return +\mdline{3574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3574}. All members specified in the group entry must exist in the +selector, or the server must return \mdline{3575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3575}. The value of \mdline{3575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3575} must +be identical to the value used when inserting the group, otherwise an +\mdline{3577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3577} error is returned.%mdk + +%mdk-data-line={3578} +\item\mdline{3578}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3578}: Delete the group entry and deallocate the \mdline{3578}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3578}. The group must +not be referenced in the table action of any table entry, or the server must +return a \mdline{3580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3580} error code. If the \mdline{3580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3580} is invalid, the +server must return \mdline{3581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3581}. \mdline{3581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3581} and \mdline{3581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3581} are the +only fields that are considered when performing a \mdline{3582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3582} and every other +field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3585} +\noindent\mdline{3585}When setting the group membership with \mdline{3585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3585} or \mdline{3585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3585}, the \mdline{3585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3585} +repeated field must not include duplicates, \mdline{3586}i.e.\mdline{3586} members with the same +\mdline{3587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3587}. The \mdline{3587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3587} field is used instead to logically \mdline{3587}\textquotedblleft{}repeat\textquotedblright{}\mdline{3587} the member +inside the group.%mdk + +%mdk-data-line={3590} +\mdline{3590}It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation \mdline{3591}\textquotedblleft{}stores\textquotedblright{}\mdline{3591} the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made.%mdk + +%mdk-data-line={3595} +\mdline{3595}When reading, an \mdline{3595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3595} message with \mdline{3595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3595} and +\mdline{3596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3596} equal to 0 will read all groups of all ActionSelector objects. A +message with \mdline{3597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3597} equal to the id of an existing ActionSelector +object, and a \mdline{3598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3598} equal to 0, will read all groups of that one specified +object.%mdk + +%mdk-data-line={3601} +\paragraph{\mdline{3601}9.2.2.1.\hspace*{0.5em}\mdline{3601}Rules on Setting \mdline{3601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\label{sec-max-size-rules}%mdk%mdk + +%mdk-data-line={3603} +\noindent\mdline{3603}The valid values for \mdline{3603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3603} depend on the static \mdline{3603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3603} included +in the P4Info message:%mdk + +%mdk-data-line={3606} +\begin{itemize}%mdk + +%mdk-data-line={3606} +\item{} +%mdk-data-line={3606} +\mdline{3606}If \mdline{3606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3606} is greater than 0, then \mdline{3606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3606} must be greater than 0, +and less than or equal to \mdline{3607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3607}. We assume that the target can +support selector groups for which the sum of all member weights is up to +\mdline{3609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3609}, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If \mdline{3610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3610} is greater than \mdline{3610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3610}, the server +must return \mdline{3611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3611}.%mdk%mdk + +%mdk-data-line={3613} +\item{} +%mdk-data-line={3613} +\mdline{3613}Otherwise (\mdline{3613}i.e.\mdline{3613} if \mdline{3613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3613} is 0), the P4Runtime client can set +\mdline{3614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3614} to any value greater than or equal to 0.%mdk + +%mdk-data-line={3616} +\begin{itemize}%mdk + +%mdk-data-line={3616} +\item{} +%mdk-data-line={3616} +\mdline{3616}A \mdline{3616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3616} of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (\mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3619} or \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3619}), the target must return a +\mdline{3620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3620} error.%mdk%mdk + +%mdk-data-line={3622} +\item{} +%mdk-data-line={3622} +\mdline{3622}If \mdline{3622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3622} is greater than 0 and the value is not supported by the +target, the server must return a \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3623} error at +group-creation time.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3626} +\subsubsection{\mdline{3626}9.2.3.\hspace*{0.5em}\mdline{3626}One Shot Action Selector Programming}\label{sec-oneshot}%mdk%mdk + +%mdk-data-line={3628} +\noindent\mdline{3628}P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids.%mdk + +%mdk-data-line={3634} +\mdline{3634}One shots are programmed by choosing the \mdline{3634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3634} message as the +\mdline{3635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3635}. The \mdline{3635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3635} message consists of a set of +\mdline{3636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3636} messages, which in turn have the following fields:%mdk + +%mdk-data-line={3638} +\begin{itemize}%mdk + +%mdk-data-line={3638} +\item{} +%mdk-data-line={3638} +\mdline{3638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3638} is one of the actions specified by the table that is being +programmed.%mdk%mdk + +%mdk-data-line={3641} +\item{} +%mdk-data-line={3641} +\mdline{3641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3641} specifying the probability of the action\mdline{3641}'\mdline{3641}s selection at runtime. 0 is +not a valid \mdline{3642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3642} value and the server must return \mdline{3642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3642} if +the client attempts to use it. The sum of all weights across all +\mdline{3644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3644} messages for that \mdline{3644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3644} message must +not exceed the \mdline{3645}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3645} specificed in the P4Info (if greater than 0), +or the server must return \mdline{3646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3646}.%mdk%mdk + +%mdk-data-line={3648} +\item{} +%mdk-data-line={3648} +\mdline{3648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3648} is the controller-defined 32-bit port number that the action\mdline{3648}'\mdline{3648}s +liveness depends on. At runtime, the action must be excluded from selection if +the watch port is down. See Section +\mdline{3651}\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{3651} for more details on the \mdline{3651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3651} field, +which also apply for one shot action selector programming.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3655} +\noindent\mdline{3655}Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics.%mdk + +%mdk-data-line={3660} +\mdline{3660}To preserve read-write symmetry, an implementation must answer \mdline{3660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3660}s +with the original one shot messages. It may not return a desugared version of +the one shot message.%mdk + +%mdk-data-line={3664} +\mdline{3664}For example, consider the action selector table defined +\mdline{3665}\mdref{sec-action-profile-member-and-group}{here}\mdline{3665}. This table could be programmed +with the following one shot update:%mdk + +%mdk-data-line={3668} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3669} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{\\ +~~~~action\_profile\_action\_set~\{\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}1}\\ +~~~~~~~~watch:~{\mdcolor{purple}1}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}2}\\ +~~~~~~~~watch:~{\mdcolor{purple}2}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}3}\\ +~~~~~~~~watch:~{\mdcolor{purple}3}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3694} +\noindent\mdline{3694}Which would be equivalent to the following updates, where \mdline{3694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GROUP\_ID}}}\mdline{3694}, +\mdline{3695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_1}}}\mdline{3695}, \mdline{3695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_2}}}\mdline{3695}, and \mdline{3695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_3}}}\mdline{3695} are unused ids:%mdk + +%mdk-data-line={3697} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3698} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_1\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_2\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_3\\ +~~action~\{~~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +\}\\ +action\_profile\_group~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~group\_id:~GROUP\_ID\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_1\\ +~~~~weight:~{\mdcolor{purple}1}\\ +~~~~watch:~{\mdcolor{purple}1}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_2\\ +~~~~weight:~{\mdcolor{purple}2}\\ +~~~~watch:~{\mdcolor{purple}2}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_3\\ +~~~~weight:~{\mdcolor{purple}3}\\ +~~~~watch:~{\mdcolor{purple}3}\\ +~~\}\\ +\}\\ +table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{~action\_profile\_group\_id:~GROUP\_ID~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3739} +\noindent\mdline{3739}Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure\mdline{3740}~\mdref{sec-batching-and-ordering-of-updates}{correct ordering between the dependent +updates}\mdline{3741}. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct \mdline{3743}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3743} batches are required.%mdk + +%mdk-data-line={3745} +\mdline{3745}It is possible to include several \mdline{3745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3745} messages with the same +exact \mdline{3746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3746} specification in one \mdline{3746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3746} message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the \mdline{3748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3748} field. Note that to preserve read-write symmetry, the server +must not coalesce multiple \mdline{3749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3749} messages with the same \mdline{3749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3749} +specification into one.%mdk + +%mdk-data-line={3752} +\mdline{3752}All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with \mdline{3753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3753} and +\mdline{3754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3754} messages. Programming some entries with one shots, and +other entries with \mdline{3755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3755} and \mdline{3755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3755} messages is +not allowed, and the server must return the error code \mdline{3756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3756} in +that case.%mdk + +%mdk-data-line={3759} +\mdline{3759}A P4Runtime server \mdline{3759}\emph{must}\mdline{3759} support the one shot style of programming tables with +an action selector implementation. Support for the \mdline{3760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3760} and +\mdline{3761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3761} style is \mdline{3761}\emph{optional}\mdline{3761}. If \mdline{3761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3761} and +\mdline{3762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3762} are not supported by a server, it must return an +\mdline{3763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3763} error for every \mdline{3763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3763} or \mdline{3763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3763} +message that it receives.%mdk + +%mdk-data-line={3766} +\subsubsection{\mdline{3766}9.2.4.\hspace*{0.5em}\mdline{3766}Constraints on action selector programming}\label{action-selector-constraints}%mdk%mdk + +%mdk-data-line={3768} +\noindent\mdline{3768}The PSA specification states that the following features are \mdline{3768}\emph{optional}\mdline{3768} in +action selector implementations\mdline{3769}~[\mdcite{psaactionselector}{22}]\mdline{3769}:%mdk + +%mdk-data-line={3771} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3771} +\item\mdline{3771}Support for non-empty groups where in the same group, different members are +bound to different actions.%mdk + +%mdk-data-line={3773} +\item\mdline{3773}Predictable data plane behavior when a matched table entry points to an empty +group.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={3776} +\noindent\mdline{3776}For 1., if a client tries to \mdline{3776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3776} or \mdline{3776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3776} a group with members bound to +different actions, the server should return \mdline{3777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3777} if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return \mdline{3783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3783} (modifying the action parameter values must be +supported, however).%mdk + +%mdk-data-line={3786} +\mdline{3786}PSA 1.1 introduces the \mdline{3786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3786} table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. \mdline{3790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3790} is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of \mdline{3793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3793} at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +\mdline{3795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3795}. Even when \mdline{3795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3795} is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of \mdline{3799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3799} mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming.%mdk + +%mdk-data-line={3804} +\mdline{3804}The PSA specification includes a discussion on how to implement +\mdline{3805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3805} in software in the P4Runtime server +\mdline{3806}[\mdcite{psaemptygroupactionappendix}{25}]\mdline{3806}.%mdk + +%mdk-data-line={3808} +\mdline{3808}If a P4Runtime implementation does support \mdline{3808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3808}, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down.%mdk + +%mdk-data-line={3812} +\mdline{3812}If a P4Runtime implementation does not support \mdline{3812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3812}, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down.%mdk + +%mdk-data-line={3818} +\subsection{\mdline{3818}9.3.\hspace*{0.5em}\mdline{3818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3818} \mdline{3818}\&\mdline{3818} \mdline{3818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-counterentry-directcounterentry}%mdk%mdk + +%mdk-data-line={3820} +\noindent\mdline{3820}PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The \mdline{3822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3822} +P4Runtime message can be used for all three types of PSA counters\mdline{3823} \mdline{3823}\textemdash{}\mdline{3823} \mdline{3823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{3823}, +\mdline{3824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{3824} and \mdline{3824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3824} \mdline{3824}\textemdash{}\mdline{3824} and consists of the following fields:%mdk + +%mdk-data-line={3826} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3826} +\item\mdline{3826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3826} is an \mdline{3826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3826}, corresponding to the number of octets.%mdk + +%mdk-data-line={3827} +\item\mdline{3827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3827} is an \mdline{3827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3827}, corresponding to the number of packets.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3829} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3830} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterData~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~byte\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}int64}}~packet\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3836} +\noindent\mdline{3836}P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of \mdline{3837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3837} and \mdline{3837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3837} fields, which +is equivalent to specifying the counter type \mdline{3838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3838}. Counters may +be defined as direct or indirect (indexed) instances.%mdk + +%mdk-data-line={3841} +\subsubsection{\mdline{3841}9.3.1.\hspace*{0.5em}\mdline{3841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-directcounterentry}%mdk%mdk + +%mdk-data-line={3843} +\noindent\mdline{3843}A direct counter is a direct resource associated with a \mdline{3843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3843} (see +\mdline{3844}\mdref{sec-direct-resources}{Direct Resources}\mdline{3844}). The \mdline{3844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3844} field of the +\mdline{3845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3845} message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +\mdline{3848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3848} message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed.%mdk + +%mdk-data-line={3851} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3852} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectCounterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3858} +\noindent\mdline{3858}A \mdline{3858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3858} may only include an \mdline{3858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3858} message of type \mdline{3858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3858} with a +\mdline{3859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3859}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3861} +\begin{itemize}%mdk + +%mdk-data-line={3861} +\item{} +%mdk-data-line={3861} +\mdline{3861}the \mdline{3861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3861} field must match \mdline{3861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry.match}}}\mdline{3861} of the table entry +to which this direct counter entry is associated. If a matching \mdline{3862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3862} +is not found, the server returns the error code \mdline{3863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3863}.%mdk%mdk + +%mdk-data-line={3865} +\item{} +%mdk-data-line={3865} +\mdline{3865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3865} is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3869} +\noindent\mdline{3869}Specifying \mdline{3869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3869} in an \mdline{3869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3869} message of type \mdline{3869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3869} or +\mdline{3870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3870} is not allowed, and the server must return the error code +\mdline{3871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3871} in that case.%mdk + +%mdk-data-line={3873} +\mdline{3873}A client may use \mdline{3873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3873} in two ways to read the contents of a +\mdline{3874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3874}:%mdk + +%mdk-data-line={3876} +\begin{itemize}%mdk + +%mdk-data-line={3876} +\item{} +%mdk-data-line={3876} +\mdline{3876}As a direct resource associated with a table entry, request the server to +return the counter value in the \mdline{3877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3877} field of the \mdline{3877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3877} message +(see\mdline{3878}~\mdref{sec-direct-resources}{Direct resources}\mdline{3878}).%mdk%mdk + +%mdk-data-line={3880} +\item{} +%mdk-data-line={3880} +\mdline{3880}Explicitly request the counter value by including the \mdline{3880}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3880} in +the \mdline{3881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3881}. The \mdline{3881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3881} field must match the \mdline{3881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3881} +whose counter is being read. If no such entry is found, the server returns the +error code \mdline{3883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3883}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3885} +\subsubsection{\mdline{3885}9.3.2.\hspace*{0.5em}\mdline{3885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}\label{sec-counterentry}%mdk%mdk + +%mdk-data-line={3887} +\noindent\mdline{3887}An indirect or indexed counter is not associated with a specific \mdline{3887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3887} +and may be updated independently of any action. It may be read or written using +the P4Runtime \mdline{3889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3889} message whose fields are defined as follows:%mdk + +%mdk-data-line={3891} +\begin{itemize}%mdk + +%mdk-data-line={3891} +\item{} +%mdk-data-line={3891} +\mdline{3891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3891} is a \mdline{3891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3891}, the unique identifier for the counter.%mdk%mdk + +%mdk-data-line={3893} +\item{} +%mdk-data-line={3893} +\mdline{3893}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3893} is a Protobuf message that encapsulates an \mdline{3893}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3893}, used to index into +the counter array.%mdk%mdk + +%mdk-data-line={3896} +\item{} +%mdk-data-line={3896} +\mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3896} is a Protobuf message of type \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3896}, which represents the +counter value.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3899} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3900} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~counter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3907} +\noindent\mdline{3907}The \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3907} can only be used in a \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3907} with the \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3907} update +type. The P4Runtime server must return an \mdline{3908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3908} error code for +update types \mdline{3909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3909} and \mdline{3909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3909}. By default all the counter entries in the +array have default value 0.%mdk + +%mdk-data-line={3912} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3912} +\item\mdline{3912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3912}: Server returns the error code \mdline{3912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3912}.%mdk + +%mdk-data-line={3913} +\item\mdline{3913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3913}: Modify an indirect counter instance whose unique id is \mdline{3913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3913} +and array index is specified by \mdline{3914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3914}. The counter value is set to the value +specified by the client in the \mdline{3915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3915} field. Note that the counter value is +not modified if this Protobuf field is not set. If \mdline{3916}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3916} is omitted all +counter values in the array will be set to the value provided by the +client. The server must return \mdline{3918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3918} for a negative index value +and \mdline{3919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3919} if the index value exceeds the size of the counter array.%mdk + +%mdk-data-line={3920} +\item\mdline{3920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3920}: Server returns the error code \mdline{3920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3920}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3922} +\noindent\mdline{3922}A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a \mdline{3923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3923} by including a \mdline{3923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3923} +entity for each of the instances, specifying the \mdline{3924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3924} and +\mdline{3925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3925}. Wildcard reads are also supported as follows.%mdk + +%mdk-data-line={3927} +\begin{itemize}%mdk + +%mdk-data-line={3927} +\item{} +%mdk-data-line={3927} +\mdline{3927}If the \mdline{3927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3927} field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the \mdline{3928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3928}.%mdk%mdk + +%mdk-data-line={3930} +\item{} +%mdk-data-line={3930} +\mdline{3930}If the \mdline{3930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3930} field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id \mdline{3931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3931}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3933} +\subsection{\mdline{3933}9.4.\hspace*{0.5em}\mdline{3933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3933} \mdline{3933}\&\mdline{3933} \mdline{3933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-meterentry-directmeterentry}%mdk%mdk + +%mdk-data-line={3935} +\noindent\mdline{3935}Meters are an advanced mechanism for keeping statistics, involving stateful +\mdline{3936}\textquotedblleft{}marking\textquotedblright{}\mdline{3936} and usually \mdline{3936}\textquotedblleft{}throttling\textquotedblright{}\mdline{3936} of packets based on configured rates of +traffic. The PSA metering function is based on the \mdline{3937}\emph{Two Rate Three Color Marker}\mdline{3937} +(trTCM) defined in RFC 2698\mdline{3938}~[\mdcite{rfc2698}{2}]\mdline{3938}. The trTCM meters an arbitrary packet +stream using two configured rates\mdline{3939} \mdline{3939}\textemdash{}\mdline{3939} the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes\mdline{3940} \mdline{3940}\textemdash{}\mdline{3940} and +\mdline{3941}\textquotedblleft{}marks\textquotedblright{}\mdline{3941} its packets as GREEN, YELLOW or RED based on the observed rate.%mdk + +%mdk-data-line={3943} +\mdline{3943}A meter may be configured as a direct or indirect instance, similar to a +counter. The \mdline{3944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{3944} P4Runtime message represents meter configuration.%mdk + +%mdk-data-line={3946} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3947} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterConfig~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~cir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~Committed~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~cburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};~~{\mdcolor{darkgreen}//~Committed~Burst~Size}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};~~{\mdcolor{darkgreen}//~Peak~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};~~{\mdcolor{darkgreen}//~Peak~Burst~Size}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3955} +\subsubsection{\mdline{3955}9.4.1.\hspace*{0.5em}\mdline{3955}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-directmeterentry}%mdk%mdk + +%mdk-data-line={3957} +\noindent\mdline{3957}A direct meter is a direct resource associated with a \mdline{3957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3957} (see\mdline{3957}~\mdref{sec-direct-resources}{Direct +resources}\mdline{3958}). The \mdline{3958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3958} field of the \mdline{3958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3958} +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +\mdline{3962}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3962} message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed.%mdk + +%mdk-data-line={3965} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3966} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectMeterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3972} +\noindent\mdline{3972}A \mdline{3972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3972} may only include an \mdline{3972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3972} message of type \mdline{3972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3972} with a +\mdline{3973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3973}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3975} +\begin{itemize}%mdk + +%mdk-data-line={3975} +\item{} +%mdk-data-line={3975} +\mdline{3975}the \mdline{3975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3975} field must match the match key of the \mdline{3975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3975} +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching \mdline{3977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3977} is not found, +the server returns the error code \mdline{3978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3978}.%mdk%mdk + +%mdk-data-line={3980} +\item{} +%mdk-data-line={3980} +\mdline{3980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3980} is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3984} +\noindent\mdline{3984}Specifying \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3984} in an \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3984} message of type \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3984} or +\mdline{3985}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3985} is not allowed, and the server must return the error code +\mdline{3986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3986} in that case.%mdk + +%mdk-data-line={3988} +\mdline{3988}A client may use \mdline{3988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3988} in two ways to read a \mdline{3988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3988} config.%mdk + +%mdk-data-line={3990} +\begin{itemize}%mdk + +%mdk-data-line={3990} +\item{} +%mdk-data-line={3990} +\mdline{3990}As a direct resource associated with a table entry, request the server to +return the meter config in the \mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3991} field of the \mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3991} +message (see\mdline{3992}~\mdref{sec-direct-resources}{Direct resources}\mdline{3992}).%mdk%mdk + +%mdk-data-line={3994} +\item{} +%mdk-data-line={3994} +\mdline{3994}Explicitly request the meter configuration by including the \mdline{3994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3994} +in the \mdline{3995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3995}. The \mdline{3995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3995} field must match the +\mdline{3996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3996} whose meter config is being read. If no such entry is found, the +server returns the error code \mdline{3997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3997}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3999} +\subsubsection{\mdline{3999}9.4.2.\hspace*{0.5em}\mdline{3999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}\label{sec-meterentry}%mdk%mdk + +%mdk-data-line={4001} +\noindent\mdline{4001}An indirect or indexed meter is not associated with a specific \mdline{4001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4001} and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime \mdline{4003}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4003} message whose fields are defined as +follows:%mdk + +%mdk-data-line={4006} +\begin{itemize}%mdk + +%mdk-data-line={4006} +\item{} +%mdk-data-line={4006} +\mdline{4006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4006} is a \mdline{4006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4006}, the unique identifier for the meter.%mdk%mdk + +%mdk-data-line={4008} +\item{} +%mdk-data-line={4008} +\mdline{4008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4008} is a Protobuf message that encapsulates an \mdline{4008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4008}, used to index into +a meter array.%mdk%mdk + +%mdk-data-line={4011} +\item{} +%mdk-data-line={4011} +\mdline{4011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4011} is a Protobuf message of type \mdline{4011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{4011}, which represents the +meter configuration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4014} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4015} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~meter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4022} +\noindent\mdline{4022}The \mdline{4022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4022} can only be used in a \mdline{4022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4022} with the \mdline{4022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4022} update +type. The P4Runtime server must return an \mdline{4023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4023} error code for +update types \mdline{4024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4024} and \mdline{4024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4024}. By default all the meter entries in the +array have a default configuration (GREEN for all packets).%mdk + +%mdk-data-line={4027} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4027} +\item\mdline{4027}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4027}: Server returns the error code \mdline{4027}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4027}.%mdk + +%mdk-data-line={4028} +\item\mdline{4028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4028}: Modify an indirect meter instance whose unique id is \mdline{4028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4028} and +array index is specified by \mdline{4029}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4029}. The meter is reconfigured using the +\mdline{4030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4030} field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the \mdline{4032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4032} field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if \mdline{4034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4034} is unset). The server must return \mdline{4034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4034} for a +negative index value and \mdline{4035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4035} if the index value exceeds the size of +the meter array.%mdk + +%mdk-data-line={4037} +\item\mdline{4037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4037}: Server returns the error code \mdline{4037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4037}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4039} +\noindent\mdline{4039}A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a \mdline{4040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4040} by including a \mdline{4040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4040} entity for each +of the instances, specifying the \mdline{4041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4041} and \mdline{4041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4041}. Wildcard reads are also +supported as follows:%mdk + +%mdk-data-line={4044} +\begin{itemize}%mdk + +%mdk-data-line={4044} +\item{} +%mdk-data-line={4044} +\mdline{4044}If the \mdline{4044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4044} field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the \mdline{4045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4045}.%mdk%mdk + +%mdk-data-line={4047} +\item{} +%mdk-data-line={4047} +\mdline{4047}If the \mdline{4047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4047} field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id \mdline{4048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4048}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4050} +\subsection{\mdline{4050}9.5.\hspace*{0.5em}\mdline{4050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}\label{sec-packetreplicationengineentry}%mdk%mdk + +%mdk-data-line={4052} +\noindent\mdline{4052}The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets.%mdk + +%mdk-data-line={4058} +\subsubsection{\mdline{4058}9.5.1.\hspace*{0.5em}\mdline{4058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}\label{sec-multicastgroupentry}%mdk%mdk + +%mdk-data-line={4060} +\noindent\mdline{4060}Multicasting is achieved in PSA programs by setting the \mdline{4060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4060} +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the \mdline{4063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4063} API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example.%mdk + +%mdk-data-line={4068} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4069} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~arp\_multicast({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ethernet.isValid()~\&\&\\ +~~~~~~~~hdr.ethernet.eth\_type~==~ETH\_TYPE\_ARP)~\{\\ +~~~~~~smeta.multicast\_group~=~(MulticastGroup\_t)~{\mdcolor{purple}1};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4079} +\noindent\mdline{4079}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4082} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4083} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~multicast\_group\_entry~\{\\ +~~~~~~multicast\_group\_id:~{\mdcolor{purple}1}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}5}~instance:~{\mdcolor{purple}1}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}12}~instance:~{\mdcolor{purple}2}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}18}~instance:~{\mdcolor{purple}3}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}24}~instance:~{\mdcolor{purple}4}~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4097} +\noindent\mdline{4097}As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +\mdline{4102}\mdref{sec-translation-of-port-numbers}{PSA Metadata Translation}\mdline{4102} section.%mdk + +%mdk-data-line={4104} +\mdline{4104}The egress packets may be distinguished for further processing in the egress +using the \mdline{4105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4105} metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 \mdline{4107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4107} metadata is set to a value that is not +programmed in the PRE, then the packet is dropped.%mdk + +%mdk-data-line={4110} +\mdline{4110}A multicast group may be inserted, modified or deleted as per the following +semantics.%mdk + +%mdk-data-line={4113} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4113} +\item\mdline{4113}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4113}: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The \mdline{4114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4114} field is a \mdline{4114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4114} and must be greater +than 0 (see explanation\mdline{4115}~\mdref{sec-valid-values-for-mg-id}{below}\mdline{4115}), or the +P4Runtime server must return an \mdline{4116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4116} error. The replica +\mdline{4117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4117} ID is also a \mdline{4117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4117}, and its value may not exceed the maximum +allowed by the target for the \mdline{4118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4118} type (0 is allowed), or the +server must return an \mdline{4119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4119} error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of \mdline{4121}\emph{both}\mdline{4121} \mdline{4121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{4121} and \mdline{4121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4121}, or the server +must return \mdline{4122}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4122}.%mdk + +%mdk-data-line={4123} +\item\mdline{4123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4123}: Modify the set of replicas for a given multicast group entry, +indexed by the given \mdline{4124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4124}. Same restrictions as \mdline{4124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4124} apply +here.%mdk + +%mdk-data-line={4126} +\item\mdline{4126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4126}: Delete the multicast group indexed by the given +\mdline{4127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4127}. The replicas need not be provided for this +operation. Any packets with their \mdline{4128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4128} metadata in the data plane +set to the deleted \mdline{4129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4129} will be dropped.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4131} +\noindent\mdline{4131}When reading a multicast group, only \mdline{4131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4131} is considered. All +other fields in \mdline{4132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4132} are ignored. To perform a \mdline{4132}\emph{wildcard}\mdline{4132} +\mdline{4133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4133} on all configured multicast group entries, the \mdline{4133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4133} field +must be set to 0, its default value.%mdk + +%mdk-data-line={4136} +\paragraph{\mdline{4136}9.5.1.1.\hspace*{0.5em}\mdline{4136}Valid Values for \mdline{4136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}}\label{sec-valid-values-for-mg-id}%mdk%mdk + +%mdk-data-line={4138} +\noindent\mdline{4138}The PSA specification states that the valid \mdline{4138}\emph{data plane}\mdline{4138} values for multicast +group ids (\mdline{4139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroup\_t}}}\mdline{4139}) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target\mdline{4141}~[\mdcite{psatranslation}{24}]\mdline{4141}. This means that, in the absence of +translation, the client must set the \mdline{4142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4142} field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special \mdline{4144}\emph{wildcard}\mdline{4144} value which is used to read all the multicast groups +configured in the target, the \mdline{4145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4145} field must never be set to 0 +when performing a \mdline{4146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4146} RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value.%mdk + +%mdk-data-line={4151} +\subsubsection{\mdline{4151}9.5.2.\hspace*{0.5em}\mdline{4151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}\label{sec-clonesessionentry}%mdk%mdk + +%mdk-data-line={4153} +\noindent\mdline{4153}PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +\mdline{4157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4157} identifier and a boolean flag \mdline{4157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone}}}\mdline{4157} in the packet +metadata. The \mdline{4158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4158} serves as a handle to the clone attributes, +namely a set \mdline{4159}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}replicas}}}\mdline{4159} of \mdline{4159}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(egress~port,~instance)}}}\mdline{4159} pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +\mdline{4162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4162} API.%mdk + +%mdk-data-line={4164} +\mdline{4164}The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the \mdline{4167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_low\_ttl}}}\mdline{4167} control block is applied in the ingress +pipeline to create an ingress-to-egress clone.%mdk + +%mdk-data-line={4170} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4171} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~clone\_low\_ttl({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ipv4.isValid()~\&\&\\ +~~~~~~~~hdr.ipv4.ttl~\textless{}=~LOW\_TTL\_THRESHOLD)~\{\\ +~~~~~~smeta.clone\_session\_id~=~{\mdcolor{purple}10}w100;\\ +~~~~~~smeta.clone~=~{\bfseries{\mdcolor{navy}true}};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4183} +\noindent\mdline{4183}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4186} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4187} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~clone\_session\_entry~\{\\ +~~~~~~session\_id:~{\mdcolor{purple}100}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}0xfffffffd}~instance:~{\mdcolor{purple}1}~\}~{\mdcolor{darkgreen}\#~to~CPU}\\ +~~~~~~class\_of\_service:~{\mdcolor{purple}2}\\ +~~~~~~packet\_length\_bytes:~{\mdcolor{purple}4096}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4200} +\noindent\mdline{4200}As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type \mdline{4204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4204}~[\mdcite{psatranslation}{24}]\mdline{4204}). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes.%mdk + +%mdk-data-line={4209} +\mdline{4209}The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port \mdline{4210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfffffffd}}}\mdline{4210}; see +\mdline{4211}\mdref{sec-translation-of-port-numbers}{Translation of Port Numbers}\mdline{4211}). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port.%mdk + +%mdk-data-line={4214} +\mdline{4214}If the \mdline{4214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4214} data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created.%mdk + +%mdk-data-line={4217} +\mdline{4217}A clone session may be inserted, modified or deleted as per the following +semantics:%mdk + +%mdk-data-line={4220} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4220} +\item\mdline{4220}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4220}: Add a new clone session entry bound to a set of egress ports and +replica IDs. The \mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4221} is a \mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4221} and must be greater than 0 (see +explanation\mdline{4222}~\mdref{sec-valid-values-for-session-id}{below}\mdline{4222}), or the P4Runtime +server must return an \mdline{4223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4223} error. The replica \mdline{4223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4223} ID is +also a \mdline{4224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4224}, and its value may not exceed the maximum allowed by the +target for the \mdline{4225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4225} type (0 is allowed), or the server must also +return an \mdline{4226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4226} error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (\mdline{4229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}class\_of\_service}}}\mdline{4229} field). This value must be a valid +value for the PSA \mdline{4230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ClassOfService\_t}}}\mdline{4230} type, which supports runtime translation +by default\mdline{4231}~[\mdcite{psatranslation}{24}]\mdline{4231}, or the server must return +\mdline{4232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4232}. See\mdline{4232}~\mdref{sec-translation-of-port-numbers}{PSA Metadata +Translation}\mdline{4233} for more information. The +\mdline{4234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4234} field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +\mdline{4236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4236} field is 0 (default), no truncation on the clone will be +performed.%mdk + +%mdk-data-line={4238} +\item\mdline{4238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4238}: Modify the attributes of a given clone session entry, indexed by the +given \mdline{4239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4239}. Same restrictions as \mdline{4239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4239} apply here.%mdk + +%mdk-data-line={4240} +\item\mdline{4240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4240}: Delete the clone session indexed by the given +\mdline{4241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4241}. Other fields need not be provided for this operation. Any +packet with their \mdline{4242}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4242} metadata in the data plane set to the +deleted \mdline{4243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4243} will no longer be cloned.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4245} +\noindent\mdline{4245}When reading a clone session, only \mdline{4245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4245} is considered. All other fields +in \mdline{4246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4246} are ignored. To perform a \mdline{4246}\emph{wildcard}\mdline{4246} \mdline{4246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4246} on all +configured clone session entries, the \mdline{4247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4247} field must be set to 0, its +default value. The \mdline{4248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4248} field can never be equal to 0 in a \mdline{4248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4248} +RPC. If it does, the server must return an \mdline{4249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4249} error.%mdk + +%mdk-data-line={4251} +\paragraph{\mdline{4251}9.5.2.1.\hspace*{0.5em}\mdline{4251}Valid Values for \mdline{4251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}}\label{sec-valid-values-for-session-id}%mdk%mdk + +%mdk-data-line={4253} +\noindent\mdline{4253}The PSA specification states that the valid \mdline{4253}\emph{data plane}\mdline{4253} values for clone +session ids (\mdline{4254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4254}) range from 0 to the maximum value supported by +the target\mdline{4255}~[\mdcite{psatranslation}{24}]\mdline{4255}. Note that unlike for\mdline{4255}~\mdref{sec-valid-values-for-mg-id}{multicast group +ids}\mdline{4256}, 0 is a valid \mdline{4256}\emph{data plane}\mdline{4256} value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special \mdline{4258}\emph{wildcard}\mdline{4258} value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a \mdline{4259}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4259} +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is \mdline{4261}\emph{not}\mdline{4261} enabled, we effectively +\mdline{4262}\textquotedblleft{}lose\textquotedblright{}\mdline{4262} one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (\mdline{4263}e.g.\mdline{4263} because the target supports a very +limited number of clone sessions), one can enable translation on +\mdline{4265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4265} and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id.%mdk + +%mdk-data-line={4268} +\subsection{\mdline{4268}9.6.\hspace*{0.5em}\mdline{4268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}\label{sec-valuesetentry}%mdk%mdk + +%mdk-data-line={4270} +\noindent\mdline{4270}Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the \mdline{4274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4274} state.%mdk + +%mdk-data-line={4276} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4277} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}state}}~parse\_l2~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}(MAX\_TRILL\_TYPES)~trill\_types;}\\ +~~extract(hdr.ethernet);\\ +~~{\bfseries{\mdcolor{navy}select}}~(hdr.ethernet.eth\_type)~\{\\ +~~~~ETH\_TYPE\_IPV4:~parse\_ipv4;\\ +~~~~ETH\_TYPE\_IPV6:~parse\_ipv6;\\ +~~~~trill\_types:~~~parse\_trill\_types;\\ +~~~~\_:~~~~~~~~~~~~~reject;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4289} +\noindent\mdline{4289}The corresponding entry in the P4Info for this Value Set is:%mdk + +%mdk-data-line={4291} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4292} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}trill\_types}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~\textless{}MAX\_TRILL\_TYPES\textgreater{}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4306} +\noindent\mdline{4306}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4309} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4310} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x22f3}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x893b}~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4328} +\noindent\mdline{4328}As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the \mdline{4330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4330} state.%mdk + +%mdk-data-line={4332} +\mdline{4332}A \mdline{4332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4332} entity update message has the following fields:%mdk + +%mdk-data-line={4334} +\begin{itemize}%mdk + +%mdk-data-line={4334} +\item{} +%mdk-data-line={4334} +\mdline{4334}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4334} is the \mdline{4334}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4334} identifier of the Value Set instance, as +defined in P4Info.%mdk%mdk + +%mdk-data-line={4337} +\item{} +%mdk-data-line={4337} +\mdline{4337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4337} is a repeated field of type \mdline{4337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4337}. When \mdline{4337}\textquotedblleft{}selecting\textquotedblright{}\mdline{4337} +against a Value Set, every member will be considered and if at least one +\mdline{4339}\textquotedblleft{}matches\textquotedblright{}\mdline{4339}, the corresponding parser transition will be taken. Each +\mdline{4340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4340} contains a repeated field of \mdline{4340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4340} messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a \mdline{4342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4342} if and only if +it matches all its \mdline{4343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4343} messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. \mdline{4345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4345} messages in a \mdline{4345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4345} follow +the\mdline{4346}~\mdref{sec-match-format}{same rules}\mdline{4346} as in a \mdline{4346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4346}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4348} +\noindent\mdline{4348}A \mdline{4348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4348} may only be modified. If the update type is \mdline{4348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4348} or +\mdline{4349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4349}, the server must return an \mdline{4349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4349} error. If the update type +is \mdline{4350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4350}, the server writes the members given in the repeated field to the +Value Set entry indexed by the given \mdline{4351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4351}. The maximum number of +matches must not exceed the maximum size given by the \mdline{4352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{4352} field in P4Info of +the Value Set, otherwise the server must return a \mdline{4353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4353} error. To +empty a Value Set (\mdline{4354}i.e.\mdline{4354} restore it to its initial state), the P4Runtime client +can perform a \mdline{4355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4355} update with an empty \mdline{4355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4355} repeated field.%mdk + +%mdk-data-line={4357} +\mdline{4357}To facilitate\mdline{4357}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{4357}, the server must +return an \mdline{4358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4358} error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set.%mdk + +%mdk-data-line={4364} +\mdline{4364}See Appendix\mdline{4364}~\mdref{sec-value-set-example}{A.3}\mdline{4364} for a more complex Value Set example.%mdk + +%mdk-data-line={4366} +\subsection{\mdline{4366}9.7.\hspace*{0.5em}\mdline{4366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}\label{sec-registerentry}%mdk%mdk + +%mdk-data-line={4368} +\noindent\mdline{4368}The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The \mdline{4369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4369} P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations.%mdk + +%mdk-data-line={4373} +\mdline{4373}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4373} has the following fields:%mdk + +%mdk-data-line={4375} +\begin{itemize}%mdk + +%mdk-data-line={4375} +\item{} +%mdk-data-line={4375} +\mdline{4375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4375}, which identifies the PSA Register extern instance which is +being accessed by the client; the \mdline{4376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4376} is specified by the P4Info +message.%mdk%mdk + +%mdk-data-line={4379} +\item{} +%mdk-data-line={4379} +\mdline{4379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4379}, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the \mdline{4381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4381} message +used for the request. When an \mdline{4382}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4382} is provided , the server must validate +its value, and return \mdline{4383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4383} for a negative index or +\mdline{4384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4384} if the index exceeds the size of the register array.%mdk%mdk + +%mdk-data-line={4386} +\item{} +%mdk-data-line={4386} +\mdline{4386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4386}: the data to be written to the array (if \mdline{4386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4386} is part of a +\mdline{4387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4387} message) or the data read from the array (if \mdline{4387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4387} is +part of a \mdline{4388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4388} message). The \mdline{4388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4388} field is a \mdline{4388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{4388} message and +must match the format described by the \mdline{4389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{4389} field of the corresponding +Register entry in the P4Info, or the server must return an \mdline{4390}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4390} +error.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4393} +\subsection{\mdline{4393}9.8.\hspace*{0.5em}\mdline{4393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}\label{sec-digestentry}%mdk%mdk + +%mdk-data-line={4395} +\noindent\mdline{4395}A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly.%mdk + +%mdk-data-line={4400} +\mdline{4400}The \mdline{4400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4400} P4Runtime entity is used to \mdline{4400}\textbf{configure}\mdline{4400} how the device must +generate digest messages. The \mdline{4401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4401} Protobuf message is not used to +carry digest data, which is done on the \mdline{4402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4402} bidirectional stream +using the \mdline{4403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4403} (digest data sent by the target to the client) and +\mdline{4404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4404} (digest data acknowledgments sent by the client to the target) +Protobuf messages.%mdk + +%mdk-data-line={4407} +\mdline{4407}In this section, we refer to the data learned by a single data plane call to +\mdline{4408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}T\textgreater{}::pack}}}\mdline{4408} as a \mdline{4408}\textquotedblleft{}digest message\textquotedblright{}\mdline{4408} and we use \mdline{4408}\textquotedblleft{}digest list\textquotedblright{}\mdline{4408} to designate +the list of digest messages bundled by the P4Runtime service in a single +\mdline{4410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4410} stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are \mdline{4412}\textquotedblleft{}duplicate\textquotedblright{}\mdline{4412} if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are \mdline{4413}\textquotedblleft{}distinct\textquotedblright{}\mdline{4413} +if they are not duplicate.%mdk + +%mdk-data-line={4416} +\mdline{4416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4416} has the following fields:%mdk + +%mdk-data-line={4418} +\begin{itemize}%mdk + +%mdk-data-line={4418} +\item{} +%mdk-data-line={4418} +\mdline{4418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4418}, which identifies the PSA Digest extern instance which emitted the +data; the \mdline{4419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4419} is determined by the P4Info message.%mdk%mdk + +%mdk-data-line={4421} +\item{} +%mdk-data-line={4421} +\mdline{4421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4421}, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +\mdline{4423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4423}; these parameters are:%mdk + +%mdk-data-line={4425} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4425} +\item\mdline{4425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4425}: the maximum server buffering delay in nanoseconds for an +outstanding digest message.%mdk + +%mdk-data-line={4427} +\item\mdline{4427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4427}: the maximum digest list size\mdline{4427} \mdline{4427}\textemdash{}\mdline{4427} in number of digest +messages\mdline{4428} \mdline{4428}\textemdash{}\mdline{4428} sent by the server to the client as a single \mdline{4428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4428} +Protobuf message.%mdk + +%mdk-data-line={4430} +\item\mdline{4430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4430}: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4434} +\noindent\mdline{4434}Here is the significance of the different \mdline{4434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4434} types for \mdline{4434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4434}:%mdk + +%mdk-data-line={4436} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4436} +\item\mdline{4436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4436}: Enable server generation of \mdline{4436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4436} messages for given digest +instance and use provided configuration parameters.%mdk + +%mdk-data-line={4438} +\item\mdline{4438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4438}: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance.%mdk + +%mdk-data-line={4440} +\item\mdline{4440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4440}: Disable server generation of \mdline{4440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4440} messages for given digest +instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4443} +\noindent\mdline{4443}A server should buffer digest messages until either:%mdk + +%mdk-data-line={4445} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4445} +\item\mdline{4445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4445} time has passed since the first digest message was added to +the empty buffer, or%mdk + +%mdk-data-line={4447} +\item\mdline{4447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4447} \mdline{4447}\emph{distinct}\mdline{4447} digest messages have been received from the +data plane and added to the buffer%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4450} +\noindent\mdline{4450}At which point the server should, with best effort, generate a \mdline{4450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4450} +stream message with the buffer contents and send it to the master client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software.%mdk + +%mdk-data-line={4456} +\mdline{4456}To avoid sending duplicate digest messages across different \mdline{4456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4456} +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the master client indicates that it has received the +digest list and acted on it. The server must keep a \mdline{4459}\textquotedblleft{}cache\textquotedblright{}\mdline{4459} containing the set +of all digest messages that have been sent, but not acknowledged yet by the +master client, up-to \mdline{4461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4461} in the past. The server must delete all +cache entries for a given digest list when they are at least \mdline{4462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4462} +old or when a matching \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4463} message (\mdline{4463}i.e.\mdline{4463} with the same \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4463} +and \mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}list\_id}}}\mdline{4464} fields as the \mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4464} message) is received.%mdk + +%mdk-data-line={4466} +\mdline{4466}The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged \mdline{4471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4471} messages.%mdk + +%mdk-data-line={4473} +\mdline{4473}When \mdline{4473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4473} is set to 0 and / or \mdline{4473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4473} is set to 1, the +server should, with best effort, generate a \mdline{4474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4474} message for every +digest message generated by the data plane which is not already in the cache. If +\mdline{4476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4476} is set to 0, the cache must always be an empty set. If +\mdline{4477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4477} is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +\mdline{4479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4479} configuration parameter.%mdk + +%mdk-data-line={4481} +\mdline{4481}The P4Runtime server may empty the digest message cache in case of a client +mastership change.%mdk + +%mdk-data-line={4484} +\mdline{4484}Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server:%mdk + +%mdk-data-line={4487} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4488} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestStream~stream;\\ +DigestCache~cache;\\ +DigestBuffer~buffers;\\ +\\ +{\mdcolor{darkgreen}//~sends~digest~list~when~it~is~ready}\\ +send\_buffer(Id~digest\_id)~\{\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~stream.write(DigestList(buffer));\\ +~~cache.merge(buffer);~~{\mdcolor{darkgreen}//~updates~cache~with~new~digest~list}\\ +~~buffer.clear();\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~data~plane~digest~messages~from~device}\\ +handle\_dataplane\_digest(Digest~msg)~\{\\ +~~digest\_id~=~msg.digest\_id();\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~{\bfseries{\mdcolor{navy}if}}~(msg~in~cache~{\mdcolor{teal}OR}~msg~in~buffer)~{\bfseries{\mdcolor{navy}return}};\\ +~~buffer.enqueue(msg);\\ +~~{\bfseries{\mdcolor{navy}if}}~(buffer.length()~\textless{}~max\_list\_size(digest\_id))~{\bfseries{\mdcolor{navy}return}};\\ +~~send\_buffer(digest\_id);\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~ack~messages~received~on~the~stream}\\ +handle\_stream\_ack(DigestListAck~ack)~\{\\ +~~{\mdcolor{darkgreen}//~clear~all~cache~entries~matching~the~tuple~(digest\_id,~list\_id)}\\ +~~cache.erase(~(ack.digest\_id(),~ack.list\_id()~)\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~loop~to~enforce~timeouts}\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~now~=~now();\\ +~~{\mdcolor{darkgreen}//~check~for~buffers~that~need~to~be~sent}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~buffer)~in~buffers)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~buffer.first\_enq\_time()~\textgreater{}=~max\_timeout\_ns(digest\_id))\\ +~~~~~~send\_buffer(buffer\_id);\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~check~for~expired~entries~in~cache}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~list\_id,~sent\_time)~in~cache)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~sent\_time~\textgreater{}=~ack\_timeout\_ns(digest\_id))\\ +~~~~~~cache.erase(~(digest\_id,~list\_id)~);\\ +~~\}\\ +~~sleep({\mdcolor{teal}X});\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4533} +\subsection{\mdline{4533}9.9.\hspace*{0.5em}\mdline{4533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\label{sec-extern-entry}%mdk%mdk + +%mdk-data-line={4535} +\noindent\mdline{4535}This is used to support a P4 extern entity that is not part of PSA. It is +defined as:%mdk + +%mdk-data-line={4538} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4539} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ExternEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_type\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~google.protobuf.Any~entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4546} +\noindent\mdline{4546}Each \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4546} entity maps to an \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{4546} message in the +\mdline{4547}\mdref{sec-p4info-extern}{P4Info}\mdline{4547} and an \mdline{4547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4547} message within that +message. The \mdline{4548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{4548} field must be equal to the one in +\mdline{4549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4549}. The \mdline{4549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_id}}}\mdline{4549} field must be equal to the ID included in the +\mdline{4550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{4550} of the corresponding \mdline{4550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4550} message.%mdk + +%mdk-data-line={4552} +\mdline{4552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entry}}}\mdline{4552} itself is embedded as an \mdline{4552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{4552} Protobuf message\mdline{4552}~[\mdcite{protoany}{31}]\mdline{4552} to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on\mdline{4556}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{4557} for more information.%mdk + +%mdk-data-line={4559} +\section{\mdline{4559}10.\hspace*{0.5em}\mdline{4559}Error Reporting Messages}\label{sec-error-reporting-messages}%mdk%mdk + +%mdk-data-line={4561} +\noindent\mdline{4561}P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case.%mdk + +%mdk-data-line={4565} +\mdline{4565}gRPC uses \mdline{4565}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4565}~[\mdcite{grpcstatus}{32}]\mdline{4565} to represent the status returned by an +RPC. It has 3 attributes:%mdk + +%mdk-data-line={4568} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4569} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StatusCode~code\_;\\ +{\mdcolor{navy}grpc::}string~error\_message\_;\\ +{\mdcolor{navy}grpc::}string~binary\_error\_details\_;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4574} +\noindent\mdline{4574}The \mdline{4574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4574} represents a canonical error\mdline{4574}~[\mdcite{grpcstatuscodes}{34}]\mdline{4574} and describes the +overall RPC status. The \mdline{4575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4575} is a developer-facing error message, +which should be in English. The \mdline{4576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}binary\_error\_details\_}}}\mdline{4576} carries a serialized +\mdline{4577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4577} message\mdline{4577}~[\mdcite{protostatus}{28}]\mdline{4577} message, which has 3 fields:%mdk + +%mdk-data-line={4579} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4580} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}int32}}~code~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~see~code.proto}\\ +{\bfseries{\mdcolor{navy}string}}~{\bfseries{\mdcolor{navy}message}}~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +{\bfseries{\mdcolor{navy}repeated}}~google.protobuf.Any~details~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4585} +\noindent\mdline{4585}The code and message fields must be the same as \mdline{4585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4585} and \mdline{4585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4585} +fields from \mdline{4586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4586} above. The \mdline{4586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{4586} field is a list that consists of +\mdline{4587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4587} messages that carry error details for individual elements inside +batch-request RPCs (\mdline{4588}e.g.\mdline{4588} \mdline{4588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4588} and \mdline{4588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4588}). \mdline{4588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4588} includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices\mdline{4592}~[\mdcite{grpcstatuscodes}{34}]\mdline{4592}.%mdk + +%mdk-data-line={4594} +\mdline{4594}Figure\mdline{4594}~\mdref{fig-error-report}{\mdcaptionlabel{7}}\mdline{4594} illustrates how these messages fit together.%mdk + +%mdk-data-line={4596} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={4597} +\noindent\mdline{4597}\includegraphics[keepaspectratio=true,width=\dimwidth{0.70}]{build/error-report}{}\mdline{4597}%mdk + +%mdk-data-line={4598} +\mdhr{}%mdk + +%mdk-data-line={4599} +\noindent\mdline{4599}\mdcaption{\textbf{Figure~\mdcaptionlabel{7}.}~\mdcaptiontext{P4Runtime Error Report Message Format}}%mdk +%mdk +\end{mdcenter}\label{fig-error-report}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={4601} +\noindent\mdline{4601}gRPC provides utility functions \mdline{4601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExtractErrorDetails()}}}\mdline{4601} and \mdline{4601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetErrorDetails()}}}\mdline{4601} +\mdline{4602}[\mdcite{grpcerrordetails}{33}]\mdline{4602} to easily convert between \mdline{4602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4602} and +\mdline{4603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4603}.%mdk + +%mdk-data-line={4605} +\mdline{4605}Please see sections on individual P4Runtime RPCs for details on how +\mdline{4606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4606} is populated for reporting errors.%mdk + +%mdk-data-line={4608} +\mdline{4608}Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on\mdline{4611}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{4612} for more information.%mdk + +%mdk-data-line={4614} +\section{\mdline{4614}11.\hspace*{0.5em}\mdline{4614}Atomicity of Individual \mdline{4614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4614} and \mdline{4614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4614} Operations}\label{sec-atomicity-of-individual-write-and-read-operations}%mdk%mdk + +%mdk-data-line={4616} +\noindent\mdline{4616}Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane \mdline{4617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4617} +operation, and every single \mdline{4618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4618} operation on a table that inserts, deletes, +or modifies one table entry, the \mdline{4619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4619} operation should behave as if that +\mdline{4620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4620} operation has not yet occurred, or as if the \mdline{4620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4620} operation is +complete. The P4 program should never behave as if the \mdline{4621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4621} operation is +partially complete. These guarantees also apply to extern instances: \mdline{4622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4622} and +\mdline{4623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4623} operations on extern entities must execute atomically relative to extern +data plane methods.%mdk + +%mdk-data-line={4626} +\mdline{4626}The atomicity guarantees provided by P4Runtime for individual \mdline{4626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4626} and \mdline{4626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4626} +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification\mdline{4628}~[\mdcite{psaatomicityofcontrolplaneops}{23}]\mdline{4628}.%mdk + +%mdk-data-line={4630} +\mdline{4630}The P4\mdline{4630}\mdsub{16}\mdline{4630} language introduces an \mdline{4630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4630} annotation\mdline{4630}~[\mdcite{p4concurrency}{14}]\mdline{4630}, to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the \mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4632} annotation for \mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4632} +operations, as well as\mdline{4633}~\mdref{wildcard-reads}{non-wildcard \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} operations}\mdline{4633}, +relative to data plane execution. Consider the following P4 example written for +PSA:%mdk + +%mdk-data-line={4637} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4638} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024)~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\mdcolor{darkgreen}//~...}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~Value\_t~v~=~r1.read((Index\_t){\mdcolor{purple}1});\\ +~~~~~~~~v~=~v~+~{\mdcolor{purple}1};\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~v);\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4654} +\noindent\mdline{4654}If a P4Runtime server is processing messages which write to Register \mdline{4654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4654} at +index \mdline{4655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}1}}}\mdline{4655}, these writes must not happen between the data plane \mdline{4655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}read}}}\mdline{4655} and +\mdline{4656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}write}}}\mdline{4656}.%mdk + +%mdk-data-line={4658} +\mdline{4658}Now let\mdline{4658}'\mdline{4658}s consider the following example:%mdk + +%mdk-data-line={4660} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4661} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024,~(Value\_t){\mdcolor{purple}0}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~initial~value~}{\mdcolor{darkgreen}*/})~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}100});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}100});\\ +~~~~\}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}200});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}200});\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4679} +\noindent\mdline{4679}If a P4Runtime client issues a \mdline{4679}\emph{wildcard}\mdline{4679} \mdline{4679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4679} on Register \mdline{4679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4679}, there is no +guarantee that \mdline{4680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]~==~r1{}[2]}}}\mdline{4680} in the response, as the read for \mdline{4680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4680} may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for \mdline{4682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4682} may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read \mdline{4684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4684} and \mdline{4684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4684} separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +\mdline{4687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4687} message) of individual read requests. Similar to a batch +\mdline{4688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4688}, a wildcard read of a register can execute the reads of the +register array elements (\mdline{4689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4689}, \mdline{4689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4689}, \mdline{4689}\dots{}\mdline{4689}) in an arbitrary order relative +to each other.%mdk + +%mdk-data-line={4692} +\mdline{4692}If the \mdline{4692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4692} annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program.%mdk + +%mdk-data-line={4696} +\section{\mdline{4696}12.\hspace*{0.5em}\mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4696} RPC}\label{sec-write-rpc}%mdk%mdk + +%mdk-data-line={4698} +\noindent\mdline{4698}The \mdline{4698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4698} RPC updates one or more P4 entities on the target. The request is +defined as follows:%mdk + +%mdk-data-line={4701} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4702} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~WriteRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint64}}~role\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Update~updates~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\bfseries{\mdcolor{navy}enum}}~Atomicity~\{\\ +~~~~CONTINUE\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~ROLLBACK\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~DATAPLANE\_ATOMIC~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~\}\\ +~~Atomicity~atomicity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4716} +\noindent\mdline{4716}The \mdline{4716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4716} uniquely identifies the target P4 device. The \mdline{4716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4716} and +\mdline{4717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4717} define the client role and election-id as described in the +\mdline{4718}\mdref{sec-master-slave-arbitration-and-controller-replication}{Master-Slave Arbitration and Controller +Replication}\mdline{4719} +section. The server is expected to perform the following checks (in this order) +before processing the \mdline{4721}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}updates}}}\mdline{4721} list:%mdk + +%mdk-data-line={4723} +\begin{enumerate}%mdk + +%mdk-data-line={4723} +\item{} +%mdk-data-line={4723} +\mdline{4723}If \mdline{4723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4723} does not match any of the devices known to the P4Runtime +server or if \mdline{4724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4724} does not match any of the roles for the device, the +server must return a \mdline{4725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4725} error.%mdk%mdk + +%mdk-data-line={4727} +\item{} +%mdk-data-line={4727} +\mdline{4727}If the client is not the master for (\mdline{4727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4727}, \mdline{4727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4727}) according to the +\mdline{4728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4728} value, the server must return a \mdline{4728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4728} error.%mdk%mdk + +%mdk-data-line={4730} +\item{} +%mdk-data-line={4730} +\mdline{4730}If the \mdline{4730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4730} is attempted before a \mdline{4730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4730} has been set, +the server must return a \mdline{4731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{4731} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4733} +\noindent\mdline{4733}The updates field is a list of P4 entity updates to be applied. Each update is +defined as:%mdk + +%mdk-data-line={4736} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4737} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Update~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Type~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~INSERT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~MODIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DELETE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~Type~type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Entity~entity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4749} +\noindent\mdline{4749}This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a \mdline{4750}\emph{logical}\mdline{4750} table (\mdline{4750}e.g.\mdline{4750} +\mdline{4751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4751}) or an actual table (\mdline{4751}e.g.\mdline{4751} \mdline{4751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4751}) in the P4 data +plane. Each entity in the container is uniquely identified by its \mdline{4752}\emph{key}\mdline{4752}. Please +refer to the\mdline{4753}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4753} section for details on +what parts of the entity specification make up the \mdline{4754}\emph{key}\mdline{4754} for each P4 entity.%mdk + +%mdk-data-line={4756} +\mdline{4756}An update can be one of the following types:%mdk + +%mdk-data-line={4758} +\begin{itemize}%mdk + +%mdk-data-line={4758} +\item{} +%mdk-data-line={4758} +\mdline{4758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4758}: Inserts the given P4 entity in the entity container. +The \mdline{4759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{4759} field always specifies the full state of the P4 entity. +If the entity already exists, an \mdline{4760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4760} error is returned, and +the existing entity remains unchanged. +If the entity is malformed, an \mdline{4762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4762} error is returned. +If the entity cannot be inserted because the container is already full, +a \mdline{4764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4764} error is returned.%mdk%mdk + +%mdk-data-line={4766} +\item{} +%mdk-data-line={4766} +\mdline{4766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4766}: Modifies the P4 entity to its new specified state. This uses +\mdline{4767}\emph{assign}\mdline{4767} or \mdline{4767}\emph{full-snapshot}\mdline{4767} semantics, \mdline{4767}i.e.\mdline{4767} the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an \mdline{4769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4769} error is usually returned (unless a +more specific error code applies\mdline{4770}~[\mdcite{grpcstatuscodes}{34}]\mdline{4770}). If the entity does not +exist, a \mdline{4771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4771} error is returned.%mdk%mdk + +%mdk-data-line={4773} +\item{} +%mdk-data-line={4773} +\mdline{4773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4773}: Deletes the specified P4 entity. If the entity does not exist, a +\mdline{4774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4774} error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4777} +\noindent\mdline{4777}If an update is not allowed under the given controller role, the server must +return a \mdline{4778}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4778} error for this update.%mdk + +%mdk-data-line={4780} +\subsection{\mdline{4780}12.1.\hspace*{0.5em}\mdline{4780}Batching and Ordering of Updates}\label{sec-batching-and-ordering-of-updates}%mdk%mdk + +%mdk-data-line={4782} +\noindent\mdline{4782}P4Runtime supports batching of \mdline{4782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4782} operations. The list of updates in a +\mdline{4783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4783} is referred to as a \mdline{4783}\emph{batch}\mdline{4783}. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of \mdline{4785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4785} entities).%mdk + +%mdk-data-line={4787} +\mdline{4787}The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +\mdline{4789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4789}s can also be processed interleaved and/or in parallel. +However, \mdline{4790}\textbf{the processing of requests must be strictly serializable}\mdline{4790}. That +is, given a history \mdline{4791}$S$\mdline{4791} of \mdline{4791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4791}s including the responses to those +requests, there must exist an order \mdline{4792}$L$\mdline{4792} for all updates in \mdline{4792}$S$\mdline{4792}, such that:%mdk + +%mdk-data-line={4794} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4794} +\item\mdline{4794}All updates from the same write request must appear as a contiguous +subsequence in \mdline{4795}$L$\mdline{4795}, but the order within that subsequence can be arbitrary.%mdk + +%mdk-data-line={4796} +\item\mdline{4796}For two updates \mdline{4796}$u_1$\mdline{4796} and \mdline{4796}$u_2$\mdline{4796}, if the write request containing \mdline{4796}$u_1$\mdline{4796} +completed before the write request of \mdline{4797}$u_2$\mdline{4797} was sent, then \mdline{4797}$u_1$\mdline{4797} must appear +before \mdline{4798}$u_2$\mdline{4798} in \mdline{4798}$L$\mdline{4798}.%mdk + +%mdk-data-line={4799} +\item\mdline{4799}Executing all updates in \mdline{4799}$L$\mdline{4799} sequentially must yield the same response for +every update as in \mdline{4800}$S$\mdline{4800}.%mdk + +%mdk-data-line={4801} +\item\mdline{4801}The observable state of the switch after \mdline{4801}$S$\mdline{4801} (\mdline{4801}e.g.\mdline{4801}, through the \mdline{4801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4801} RPC) +is identical to the one obtained by sequentially executing \mdline{4802}$L$\mdline{4802}.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4804} +\noindent\mdline{4804}The \mdline{4804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4804} RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the \mdline{4805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4805} RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (\mdline{4808}e.g.\mdline{4808} inserting an \mdline{4808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4808} +followed by pointing a \mdline{4809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4809} to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding \mdline{4811}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4811} RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate \mdline{4815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4815} calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each \mdline{4816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4816} call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one.%mdk + +%mdk-data-line={4821} +\subsection{\mdline{4821}12.2.\hspace*{0.5em}\mdline{4821}Batch Atomicity}\label{sec-batch-atomicity}%mdk%mdk + +%mdk-data-line={4823} +\noindent\mdline{4823}A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the \mdline{4824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4824} +enum. A P4Runtime server is required to support only the modes marked as +\mdline{4826}\emph{Required}\mdline{4826} below:%mdk + +%mdk-data-line={4828} +\begin{itemize}%mdk + +%mdk-data-line={4828} +\item{} +%mdk-data-line={4828} +\mdline{4828}\emph{Required}\mdline{4828}: \mdline{4828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4828}: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that \mdline{4832}\emph{see}\mdline{4832} each of +these intermediate stages.%mdk%mdk + +%mdk-data-line={4835} +\item{} +%mdk-data-line={4835} +\mdline{4835}\emph{Optional}\mdline{4835}: \mdline{4835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ROLLBACK\_ON\_ERROR}}}\mdline{4835}: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is \mdline{4839}\emph{all-or-none}\mdline{4839}, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that \mdline{4843}\emph{see}\mdline{4843} each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure.%mdk + +%mdk-data-line={4848} +\mdline{4848}If a P4Runtime server does not support this option at all, an +\mdline{4849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4849} error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (\mdline{4850}e.g.\mdline{4850} it is +more straightforward to implement batches that contain only \mdline{4851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4851} +operations, vs. those that contain \mdline{4852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4852} operations), an +\mdline{4853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4853} error is returned when the batch cannot be executed +in a data plane-atomic way.%mdk%mdk + +%mdk-data-line={4856} +\item{} +%mdk-data-line={4856} +\mdline{4856}\emph{Optional}\mdline{4856}: \mdline{4856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4856}: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +\mdline{4860}\emph{transaction}\mdline{4860}. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane\mdline{4862}'\mdline{4862}s table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table.%mdk + +%mdk-data-line={4869} +\mdline{4869}If a P4Runtime server does not support this option at all, an \mdline{4869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4869} +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an \mdline{4871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4871} error is returned when the batch +cannot be executed in a data plane-atomic way.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4874} +\noindent\mdline{4874}There is no expectation that a given client must always use the same \mdline{4874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4874} +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use \mdline{4877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4877} at one time and default behavior +(\mdline{4878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4878}) at other times.%mdk + +%mdk-data-line={4880} +\subsection{\mdline{4880}12.3.\hspace*{0.5em}\mdline{4880}Error Reporting}\label{sec-error-reporting}%mdk%mdk + +%mdk-data-line={4882} +\noindent\mdline{4882}Please see section\mdline{4882}~\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{4882} for +information on error reporting messages and guidelines. P4Runtime server will +populate \mdline{4884}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4884} as follows:%mdk + +%mdk-data-line={4886} +\begin{enumerate}%mdk + +%mdk-data-line={4886} +\item{} +%mdk-data-line={4886} +\mdline{4886}If all batch updates succeeded, set \mdline{4886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4886} to \mdline{4886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4886} and do not +populate any other field.%mdk%mdk + +%mdk-data-line={4889} +\item{} +%mdk-data-line={4889} +\mdline{4889}If an error is encountered before even trying to attempt individual batch +updates, set \mdline{4890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4890} that best describes that RPC-wide +error. For example, use \mdline{4891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNAVAILABLE}}}\mdline{4891} if the P4Runtime service is not yet +ready to handle requests. Set \mdline{4892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4892} to describe the issue. Do not +set \mdline{4893}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_details}}}\mdline{4893} in this case.%mdk%mdk + +%mdk-data-line={4895} +\item{} +%mdk-data-line={4895} +\mdline{4895}Otherwise, if one or more updates in the batch (\mdline{4895}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest.updates}}}\mdline{4895}) +failed, set \mdline{4896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4896} to \mdline{4896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{4896}. For example, one update in +the batch may fail with \mdline{4897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4897} and another with +\mdline{4898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4898}. A \mdline{4898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4898} message is used to capture the status of +each and every update in the batch. The number of \mdline{4899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4899} messages packed +into \mdline{4900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{4900} field should therefore always match the +number of updates in the \mdline{4901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4901}, and the order of +\mdline{4902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4902} messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +\mdline{4904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4904} should set the code to \mdline{4904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4904} and omit other fields.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4906} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4907} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}\#~Example~of~a~grpc::Status~returned~for~a~Write~RPC~with~a~batch~of~3~updates.}\\ +{\mdcolor{darkgreen}\#~The~first~and~third~updates~encountered~an~error,~while~the~second~update}\\ +{\mdcolor{darkgreen}\#~succeeded.}\\ +code\_~=~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +error\_message\_~=~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +binary\_error\_details~\{\\ +~~code:~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}8}~~{\mdcolor{darkgreen}\#~RESOURCE\_EXHAUSTED}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Table~is~full.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}500}~~{\mdcolor{darkgreen}\#~ERR\_TABLE\_FULL}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}0}~~{\mdcolor{darkgreen}\#~OK}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}6}~~{\mdcolor{darkgreen}\#~ALREADY\_EXISTS}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Entity~already~exists.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}600}~~{\mdcolor{darkgreen}\#~ERR\_ENTITY\_ALREADY\_EXISTS}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4933} +\section{\mdline{4933}13.\hspace*{0.5em}\mdline{4933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4933} RPC}\label{sec-read-rpc}%mdk%mdk + +%mdk-data-line={4935} +\noindent\mdline{4935}The \mdline{4935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4935} RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as:%mdk + +%mdk-data-line={4938} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4939} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4945} +\noindent\mdline{4945}The \mdline{4945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4945} uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +\mdline{4947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4947} error. The \mdline{4947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{4947} repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server.%mdk + +%mdk-data-line={4950} +\mdline{4950}Since \mdline{4950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4950}s do not mutate any state on the switch, they do not +require an \mdline{4951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4951}, and they do not require the presence of an open +\mdline{4952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4952} between the server and client.%mdk + +%mdk-data-line={4954} +\mdline{4954}The \mdline{4954}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read~}}}\mdline{4954}response consists of a sequence of messages (a gRPC \mdline{4954}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}stream}}}\mdline{4954}) with +each message defined as:%mdk + +%mdk-data-line={4957} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4958} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadResponse~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4963} +\noindent\mdline{4963}The \mdline{4963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{4963} repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the \mdline{4967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Finish()}}}\mdline{4967} method on the stream object +\mdline{4968}[\mdcite{grpcstreamc}{10}]\mdline{4968}).%mdk + +%mdk-data-line={4970} +\subsection{\mdline{4970}13.1.\hspace*{0.5em}\mdline{4970}Nomenclature}\label{sec-nomenclature}%mdk%mdk + +%mdk-data-line={4972} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries request}}%mdk + +%mdk-data-line={4972} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{4972}An element of the \mdline{4972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{4972} repeated field. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries batch}}%mdk + +%mdk-data-line={4974} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{4974}Refers to the \mdline{4974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{4974} repeated field.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={4977} +\noindent\mdline{4977}Each \mdline{4977}\emph{request}\mdline{4977} acts as a query filter for that entity type. If a \mdline{4977}\emph{request}\mdline{4977} fully +specifies the entity key, the \mdline{4978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4978} operation should retrieve a single P4 +entity. Please refer to the\mdline{4979}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4979} section +for details on what parts of the entity specification make up the entity \mdline{4980}\emph{key}\mdline{4980}.%mdk + +%mdk-data-line={4982} +\subsection{\mdline{4982}13.2.\hspace*{0.5em}\mdline{4982}Wildcard Reads}\label{sec-wildcard-reads}%mdk%mdk + +%mdk-data-line={4984} +\noindent\mdline{4984}P4Runtime allows wildcard read of P4 entities. A \mdline{4984}\emph{request}\mdline{4984} may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the\mdline{4986}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4986} section for details on +what parts of the entity can be wildcarded in a given \mdline{4987}\emph{request}\mdline{4987}.%mdk + +%mdk-data-line={4989} +\mdline{4989}For example, in a \mdline{4989}\emph{request}\mdline{4989} of type \mdline{4989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4989}:%mdk + +%mdk-data-line={4991} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4991} +\item\mdline{4991}A default \mdline{4991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4991} (0) implies a request to read all counter-entries for +all indirect counters.%mdk + +%mdk-data-line={4993} +\item\mdline{4993}A particular (non-default) \mdline{4993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4993} in conjunction with \mdline{4993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4993} unset +implies a request to read all counter-entries for the given indirect counter +ID.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4997} +\noindent\mdline{4997}To read the entire forwarding state for a given device, the P4Runtime client can +generate the following \mdline{4998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4998}:%mdk + +%mdk-data-line={5000} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5001} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~\textless{}ID\textgreater{}\\ +entities~\{\\ +~~extern\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~extern~instances~for~all~supported~extern~types}\\ +~~table\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~table~entries~for~all~tables}\\ +~~action\_profile\_member~\{~\}~~{\mdcolor{darkgreen}\#~read~all~members~for~all~action~profiles}\\ +~~action\_profile\_group~\{~\}~~{\mdcolor{darkgreen}\#~read~all~groups~for~all~action~profiles}\\ +~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5011} +\noindent\mdline{5011}The \mdline{5011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5011} oneof field in the \mdline{5011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5011} message must always be set, or the +server must return an \mdline{5012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5012} error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty \mdline{5014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5014} message in the \mdline{5014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5014}. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the \mdline{5016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5016} oneof\mdline{5016}~[\mdcite{protooneofbackwardscompatibility}{20}]\mdline{5016}.%mdk + +%mdk-data-line={5018} +\subsection{\mdline{5018}13.3.\hspace*{0.5em}\mdline{5018}Batch Processing}\label{sec-batch-processing}%mdk%mdk + +%mdk-data-line={5020} +\noindent\mdline{5020}A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type \mdline{5021}\emph{request}\mdline{5021} +appears only once in the batch.%mdk + +%mdk-data-line={5024} +\mdline{5024}A P4Runtime server will process the batch as follows:%mdk + +%mdk-data-line={5026} +\begin{enumerate}%mdk + +%mdk-data-line={5026} +\item{} +%mdk-data-line={5026} +\mdline{5026}Lock state (preventing new writes) and validate each \mdline{5026}\emph{request}\mdline{5026} in the batch:%mdk + +%mdk-data-line={5028} +\begin{enumerate}%mdk + +%mdk-data-line={5028} +\item{} +%mdk-data-line={5028} +\mdline{5028}If it is a valid \mdline{5028}\emph{request}\mdline{5028}, perform the read;%mdk + +%mdk-data-line={5030} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5030} +\item\mdline{5030}If the read was successful, return the entities read in +\mdline{5031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5031} stream.%mdk + +%mdk-data-line={5032} +\item\mdline{5032}If the read failed (exception / critical-error), prepare a \mdline{5032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5032} +with code set to \mdline{5033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INTERNAL}}}\mdline{5033}.%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5035} +\item{} +%mdk-data-line={5035} +\mdline{5035}If the \mdline{5035}\emph{request}\mdline{5035} is invalid (invalid-argument, not-supported, etc.), +prepare a \mdline{5036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5036} with relevant canonical code to capture the error.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5038} +\item{} +%mdk-data-line={5038} +\mdline{5038}Unlock the state (allowing new writes);%mdk%mdk + +%mdk-data-line={5040} +\item{} +%mdk-data-line={5040} +\mdline{5040}Close the \mdline{5040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5040} stream and return a \mdline{5040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5040} as follows:%mdk + +%mdk-data-line={5042} +\begin{enumerate}%mdk + +%mdk-data-line={5042} +\item{} +%mdk-data-line={5042} +\mdline{5042}If no errors were encountered, set code to \mdline{5042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{5042} and do not populate any +other field.%mdk%mdk + +%mdk-data-line={5045} +\item{} +%mdk-data-line={5045} +\mdline{5045}Otherwise, the overall code should be set to \mdline{5045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{5045}. See section +\mdline{5046}\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{5046} for information +on error reporting messages and guidelines. Assemble a list of \mdline{5047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5047} +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +\mdline{5051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{5051} field. This behavior also matches \mdline{5051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5051} +RPC.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5054} +\subsubsection{\mdline{5054}13.3.1.\hspace*{0.5em}\mdline{5054}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={5056} +\noindent\mdline{5056}If a client asked to read \mdline{5056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{a,b,c,d\}}}}\mdline{5056} and \mdline{5056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}b}}}\mdline{5056} and \mdline{5056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}d}}}\mdline{5056} \mdline{5056}\emph{requests}\mdline{5056} didn\mdline{5056}'\mdline{5056}t +validate, the server will return entities corresponding to \mdline{5057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5057} and \mdline{5057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}c}}}\mdline{5057}, followed +by a status \mdline{5058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{p4.Error(OK),~p4.Error(xxx),~p4.Error(yyy),~p4.Error(OK)\}}}}\mdline{5058} in the +\mdline{5059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5059} field.%mdk + +%mdk-data-line={5061} +\mdline{5061}The P4Runtime server is not required to perform any optimization (\mdline{5061}e.g.\mdline{5061} merge two +\mdline{5062}\emph{requests}\mdline{5062} in the \mdline{5062}\emph{batch}\mdline{5062} if one is a subset of other). As a result of this, it +is possible for the \mdline{5063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5063} to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging.%mdk + +%mdk-data-line={5066} +\mdline{5066}There is no requirement that each request in the batch will correspond to one +\mdline{5067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5067} message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit.%mdk + +%mdk-data-line={5072} +\mdline{5072}A P4Runtime server must be prepared to handle multiple concurrent \mdline{5072}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5072} RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (\mdline{5077}e.g.\mdline{5077} in a single-threaded architecture), it may choose to serialize +\mdline{5078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5078} RPC processing.%mdk + +%mdk-data-line={5080} +\subsection{\mdline{5080}13.4.\hspace*{0.5em}\mdline{5080}Parallelism of Read and Write Requests}\label{sec-parallelism-of-read-and-write-requests}%mdk%mdk + +%mdk-data-line={5082} +\noindent\mdline{5082}A P4Runtime server may be implemented to serve at most one +\mdline{5083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5083} or \mdline{5083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5083} message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so.%mdk + +%mdk-data-line={5088} +\mdline{5088}For example, imagine a client that wanted to use \mdline{5088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5088} +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +\mdline{5092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5092} messages with only a few updates to an \mdline{5092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{5092} +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +\mdline{5095}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5095} batch currently being processed, but it will not +complete for a significant amount of time.%mdk + +%mdk-data-line={5098} +\mdline{5098}The restrictions on which a client may rely are:%mdk + +%mdk-data-line={5100} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5100} +\item\mdline{5100}The processing of any two \mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5100} messages \mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W1}}}\mdline{5100} and \mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W2}}}\mdline{5100} must +result in the same state as if one of them was completed before the +other began.%mdk + +%mdk-data-line={5103} +\item\mdline{5103}For any \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5103} \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5103} and any \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5103} \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5103}, \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5103} must +return results consistent with a state where \mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5104} has completed +processing, or \mdline{5105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5105} has not yet begun processing.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5107} +\noindent\mdline{5107}For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a \mdline{5110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5110} message it acquired a write lock for each stateful +object affected by the \mdline{5111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5111}, and before starting the +processing of a \mdline{5112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5112} message it acquired a read lock for each +stateful object accessed by the \mdline{5113}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5113}, such an implementation +meets all of the requirements above.%mdk + +%mdk-data-line={5116} +\mdline{5116}It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, \mdline{5118}e.g.\mdline{5118} if the server somehow determined that two +\mdline{5119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5119} messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly.%mdk + +%mdk-data-line={5125} +\section{\mdline{5125}14.\hspace*{0.5em}\mdline{5125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5125} RPC}\label{sec-setforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5127} +\noindent\mdline{5127}A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the \mdline{5128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig~RPC}}}\mdline{5128}. The request is defined as:%mdk + +%mdk-data-line={5130} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5131} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~SetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Action~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~VERIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~VERIFY\_AND\_SAVE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~VERIFY\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~~~COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~~~RECONCILE\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint64}}~role\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~Action~action~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5148} +\noindent\mdline{5148}The server is expected to perform the following checks (in this order) +before performing the required \mdline{5149}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{5149}:%mdk + +%mdk-data-line={5151} +\begin{enumerate}%mdk + +%mdk-data-line={5151} +\item{} +%mdk-data-line={5151} +\mdline{5151}If \mdline{5151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5151} does not match any of the devices known to the P4Runtime +server or if \mdline{5152}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{5152} does not match any of the roles for the device, the +server must return a \mdline{5153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5153} error.%mdk%mdk + +%mdk-data-line={5155} +\item{} +%mdk-data-line={5155} +\mdline{5155}If the client is not the master for (\mdline{5155}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5155}, \mdline{5155}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{5155}) according to the +\mdline{5156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5156} value, the server must return a \mdline{5156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5156} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5158} +\noindent\mdline{5158}The action is the type of configuration action requested, it can be one of:%mdk + +%mdk-data-line={5160} +\begin{itemize}%mdk + +%mdk-data-line={5160} +\item{} +%mdk-data-line={5160} +\mdline{5160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY}}}\mdline{5160}: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an \mdline{5161}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5161} +error if config is not provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5164} +\item{} +%mdk-data-line={5164} +\mdline{5164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5164}: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent \mdline{5166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5166} / \mdline{5166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5166} requests must refer to fields in the new +config. Returns an \mdline{5167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5167} error if the forwarding config is not +provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5170} +\item{} +%mdk-data-line={5170} +\mdline{5170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_COMMIT}}}\mdline{5170}: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an \mdline{5172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5172} error if the forwarding config is not provided or if the +provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5175} +\item{} +%mdk-data-line={5175} +\mdline{5175}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COMMIT}}}\mdline{5175}: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a \mdline{5178}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5178} error if no saved config +is found, \mdline{5179}i.e.\mdline{5179} if no \mdline{5179}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5179} action preceded this one. Returns an +\mdline{5180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5180} error if a config is provided with this message.%mdk%mdk + +%mdk-data-line={5182} +\item{} +%mdk-data-line={5182} +\mdline{5182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RECONCILE\_AND\_COMMIT}}}\mdline{5182}: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5188} error. For targets that support this option, an +\mdline{5189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5189} error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5193} +\noindent\mdline{5193}The \mdline{5193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5193} field is a message of type \mdline{5193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5193} that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(\mdline{5195}e.g.\mdline{5195} generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the\mdline{5196}~\mdref{sec-p4-fwd-pipe-config}{Forwarding-Pipeline +Configuration}\mdline{5197} section for details.%mdk + +%mdk-data-line={5199} +\mdline{5199}A P4Runtime server running on a non-programmable device may not +support \mdline{5200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5200} (\mdline{5200}e.g.\mdline{5200} the forwarding-pipeline +config is part of the device\mdline{5201}'\mdline{5201}s software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +\mdline{5203}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5203} error.%mdk + +%mdk-data-line={5205} +\section{\mdline{5205}15.\hspace*{0.5em}\mdline{5205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5205} RPC}\label{sec-getforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5207} +\noindent\mdline{5207}The forwarding-pipeline configuration of the target can be retrieved by invoking +the \mdline{5208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig~RPC}}}\mdline{5208}. The request is defined as:%mdk + +%mdk-data-line={5210} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5211} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~ResponseType~\{\\ +~~~~ALL~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~COOKIE\_ONLY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~P{\mdcolor{purple}4}INFO\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DEVICE\_CONFIG\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~ResponseType~response\_type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5223} +\noindent\mdline{5223}The \mdline{5223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5223} uniquely identifies the target P4 device. A \mdline{5223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5223} error is +returned if the \mdline{5224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5224} is not recognized by the P4Runtime server.%mdk + +%mdk-data-line={5226} +\mdline{5226}The \mdline{5226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5226} is used to specify which fields to populate in the response, +its value can be one of:%mdk + +%mdk-data-line={5229} +\begin{itemize}%mdk + +%mdk-data-line={5229} +\item{} +%mdk-data-line={5229} +\mdline{5229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5229}: returns a \mdline{5229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5229} with all fields +set as stored by the target. This is the default behaviour if the +\mdline{5231}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5231} field is not set.%mdk%mdk + +%mdk-data-line={5233} +\item{} +%mdk-data-line={5233} +\mdline{5233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COOKIE\_ONLY}}}\mdline{5233}: reply by setting only the \mdline{5233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5233} field in the +\mdline{5234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5234}, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message.%mdk%mdk + +%mdk-data-line={5238} +\item{} +%mdk-data-line={5238} +\mdline{5238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4INFO\_AND\_COOKIE}}}\mdline{5238}: reply by setting the \mdline{5238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{5238} and \mdline{5238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5238} fields.%mdk%mdk + +%mdk-data-line={5240} +\item{} +%mdk-data-line={5240} +\mdline{5240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEVICE\_CONFIG\_AND\_COOKIE}}}\mdline{5240}: reply by setting the \mdline{5240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5240} and +\mdline{5241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5241} fields.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5243} +\noindent\mdline{5243}The response contains the \mdline{5243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5243} for the specified device:%mdk + +%mdk-data-line={5245} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5246} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigResponse~\{\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5251} +\noindent\mdline{5251}If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level \mdline{5252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5252} field will be unset in the response. Examples are +(i) a server that only allows configuration via \mdline{5253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5253} +but this RPC hasn\mdline{5254}'\mdline{5254}t been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn\mdline{5255}'\mdline{5255}t yet occurred.%mdk + +%mdk-data-line={5257} +\mdline{5257}Once a forwarding-pipeline config is installed on the device (either via +\mdline{5258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5258} or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +\mdline{5260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.p4\_device\_config}}}\mdline{5260} will be empty / unset in the response, even if +\mdline{5261}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5261} in the request was set to \mdline{5261}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5261}. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the \mdline{5263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5263} RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +\mdline{5265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5265}, the value of \mdline{5265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.cookie}}}\mdline{5265} will be unset.%mdk + +%mdk-data-line={5267} +\mdline{5267}If a P4Runtime server supports both \mdline{5267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5267} as well as +returning the \mdline{5268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5268}, there should be read-write symmetry between +\mdline{5269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5269} and \mdline{5269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5269} RPCs.%mdk + +%mdk-data-line={5271} +\section{\mdline{5271}16.\hspace*{0.5em}\mdline{5271}P4Runtime Stream Messages}\label{sec-p4runtime-stream-messages}%mdk%mdk + +%mdk-data-line={5273} +\subsection{\mdline{5273}16.1.\hspace*{0.5em}\mdline{5273}Packet I/O}\label{sec-packet-i_o}%mdk%mdk + +%mdk-data-line={5275} +\noindent\mdline{5275}P4Runtime supports controller packet-in and packet-out by means of \mdline{5275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5275} +and \mdline{5276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5276} stream messages, respectively.%mdk + +%mdk-data-line={5278} +\mdline{5278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5278} messages are sent by the P4Runtime server to the client. Conversely, +\mdline{5279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5279} messages are sent by the client to the server. Any \mdline{5279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5279} +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a \mdline{5282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5282} message with the \mdline{5282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5282} field set to +report the error to the client. See the section on\mdline{5283}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{5284} for more information on \mdline{5284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5284}.%mdk + +%mdk-data-line={5286} +\mdline{5286}As introduced in the\mdline{5286}~\mdref{sec-controller-packet-meta}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\mdline{5286} +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with \mdline{5288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5288}. The expected metadata is described +in the P4Info using the \mdline{5289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5289} messages.%mdk + +%mdk-data-line={5291} +\mdline{5291}Both \mdline{5291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5291} and \mdline{5291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5291} stream messages share the same fields and are +defined as follows:%mdk + +%mdk-data-line={5294} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5295} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Packet~sent~from~the~controller~to~the~switch.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketOut~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~Packet~sent~from~the~switch~to~the~controller.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketIn~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~PacketMetadata~\{\\ +~~{\mdcolor{darkgreen}//~This~refers~to~Metadata.id~coming~from~P4Info~ControllerPacketMetadata.}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~metadata\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5314} +\begin{itemize}%mdk + +%mdk-data-line={5314} +\item{} +%mdk-data-line={5314} +\mdline{5314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}payload}}}\mdline{5314} is used to carry the full packet content, including the headers.%mdk%mdk + +%mdk-data-line={5316} +\item{} +%mdk-data-line={5316} +\mdline{5316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5316} is a repeated field of \mdline{5316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{5316} messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +\mdline{5319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5319}. Indeed, when a P4Runtime client (or server) +generates a \mdline{5320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5320} (or \mdline{5320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5320}) message, it needs to populate the +\mdline{5321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5321} field with as many values as in \mdline{5321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{5321} +for the packet-out (or packet-in) case. Each \mdline{5322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata.value}}}\mdline{5322} is a +binary string and must conform to the\mdline{5323}~\mdref{sec-bytestrings}{Bytestrings}\mdline{5323} +requirements based on the corresponding P4Info +\mdline{5325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{5325} specification. If the \mdline{5325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5325} field +does not match the P4Info specification, the server must drop the \mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5326} +message and may generate a \mdline{5327}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5327} message with the \mdline{5327}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5327} +field set to report the error to the client which issued the \mdline{5328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5328}. See +the section on\mdline{5329}~\mdref{sec-stream-error-reporting}{Stream Error Reporting}\mdline{5329} for more +information on \mdline{5330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5330}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5332} +\subsection{\mdline{5332}16.2.\hspace*{0.5em}\mdline{5332}Master Arbitration Update}\label{sec-master-arbitration-update}%mdk%mdk + +%mdk-data-line={5334} +\noindent\mdline{5334}P4Runtime\mdline{5334}'\mdline{5334}s master arbitration mechanism ensures that only the current master +can modify state on the switch, and that the \mdline{5335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5335} is monotonically +increasing. For example, the switch must finish all previous write operations +before changing masters, and must only accept write requests from the current +master.%mdk + +%mdk-data-line={5340} +\mdline{5340}As explained earlier in this document, the controller uses the \mdline{5340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5340} +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via \mdline{5342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5342} RPC), +it needs to start a controller session and become a \mdline{5343}\textquotedblleft{}master\textquotedblright{}\mdline{5343}. To do so, the +controller first opens a bidirectional stream channel to the server via +\mdline{5345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5345} for each device and sends a \mdline{5345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5345} message. The +controller populates the \mdline{5346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5346} field in this message using +its \mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{5347} and \mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5347} and the \mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5347} of the device, as explained +in detail in the\mdline{5348}~\mdref{sec-master-slave-arbitration-and-controller-replication}{Master-Slave Arbitration and Controller +Replication}\mdline{5349} +section. For any given \mdline{5350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role\_id)}}}\mdline{5350}, the P4Runtime server keeps track +of the highest \mdline{5351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5351} that it has ever received. If a controller\mdline{5351}'\mdline{5351}s +\mdline{5352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5352} is equal to the highest \mdline{5352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5352} that the server has ever +received, that controller is the master. All other controllers are slaves. Note +that it is possible that all controllers are slaves, and that there is no +master. There can be at most one master, because for any given +\mdline{5356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role\_id)}}}\mdline{5356}, each connected controller has a unique \mdline{5356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5356}.%mdk + +%mdk-data-line={5358} +\mdline{5358}This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest \mdline{5359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5359} after such a restart. +However, across a\mdline{5360}~\mdref{sec-restarts}{full restart}\mdline{5360}, the \mdline{5360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5360} must be +reset. In fact, a full restart is the only way to reset the \mdline{5361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5361}.%mdk + +%mdk-data-line={5363} +\mdline{5363}The \mdline{5363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5363} message is defined as follows:%mdk + +%mdk-data-line={5365} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5366} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Role~\{\\ +~~{\mdcolor{darkgreen}//~role\_id~for~this~role.~Defined~offline~in~agreement~across~the}\\ +~~{\mdcolor{darkgreen}//~entire~control~plane.}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Describes~the~role~configuration.}\\ +~~google.protobuf.Any~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~MasterArbitrationUpdate~\{\\ +~~{\mdcolor{darkgreen}//~Identifies~the~device~(aka~target~or~node~or~switching~chip).}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~The~role~for~which~the~mastership~is~being~arbitrated.}\\ +~~Role~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~The~election\_id~(unique~per~role).}\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Switch~populates~this~with~OK~for~the~client~that~is~the~master,}\\ +~~{\mdcolor{darkgreen}//~and~with~an~error~status~for~all~other~connected~clients~(at}\\ +~~{\mdcolor{darkgreen}//~every~mastership~change).~The~controller~does~not~populate~this}\\ +~~{\mdcolor{darkgreen}//~field.}\\ +~~google.{\bfseries{\mdcolor{navy}rpc}}.Status~status~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5389} +\noindent\mdline{5389}Note that the \mdline{5389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5389} field in the \mdline{5389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5389} message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a \mdline{5391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5391} message back to the controller, in which +it populates the \mdline{5392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5392} message using the \mdline{5392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5392}, +\mdline{5393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5393}, and \mdline{5393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5393} it previously received from the controller. The server +also populates the \mdline{5394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5394} field in the \mdline{5394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5394} according to +the rules in an\mdline{5395}~\mdref{sec-mastership-updates}{earlier section}\mdline{5395}.%mdk + +%mdk-data-line={5397} +\mdline{5397}The sender need not specify an \mdline{5397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5397}. If the \mdline{5397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5397} is not +specified, the sender\mdline{5398}'\mdline{5398}s \mdline{5398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5398} is considered lower than any +\mdline{5399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5399}, and the sender will thus never become master. This way, a +controller can choose to be a standby controller, in order to avoid master +\mdline{5401}\textquotedblleft{}flapping\textquotedblright{}\mdline{5401} (if a standby controller connects to the switch shortly before the +actual master controller, therefore becoming master temporarily).%mdk + +%mdk-data-line={5405} +\subsection{\mdline{5405}16.3.\hspace*{0.5em}\mdline{5405}Digest Messages}\label{sec-digest-messages}%mdk%mdk + +%mdk-data-line={5407} +\noindent\mdline{5407}See the\mdline{5407}~\mdref{sec-digestentry}{DigestEntry}\mdline{5407} section.%mdk + +%mdk-data-line={5409} +\subsection{\mdline{5409}16.4.\hspace*{0.5em}\mdline{5409}Table Idle Timeout Notification}\label{sec-table-idle-timeout-notification}%mdk%mdk + +%mdk-data-line={5411} +\noindent\mdline{5411}When a table supports idle timeout (as per the P4Info message), the master +client can specify a TTL value for each entry in the table (see +\mdline{5413}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{5413} section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an \mdline{5415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5415} message on the +\mdline{5416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5416} bidirectional stream to the master client. The master client can +then take the action of its choice, most likely remove the idle entry.%mdk + +%mdk-data-line={5419} +\mdline{5419}The \mdline{5419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5419} Protobuf message has the following fields:%mdk + +%mdk-data-line={5421} +\begin{itemize}%mdk + +%mdk-data-line={5421} +\item{} +%mdk-data-line={5421} +\mdline{5421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}timestamp}}}\mdline{5421}: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server\mdline{5422}'\mdline{5422}s local clock.%mdk%mdk + +%mdk-data-line={5424} +\item{} +%mdk-data-line={5424} +\mdline{5424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5424}: a repeated field of entries which have expired. Each individual +entry is identified by a single \mdline{5425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5425} message. For each \mdline{5425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5425}, +the \mdline{5426}\emph{key}\mdline{5426} fields (\mdline{5426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{5426}, \mdline{5426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{5426} and \mdline{5426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{5426}) must be set, along with +the \mdline{5427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{5427} field, the \mdline{5427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5427} field, and the +\mdline{5428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{5428} field. Other fields may be set by the server but should be +ignored by the client.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5431} +\noindent\mdline{5431}Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +\mdline{5433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5433} message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an \mdline{5438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5438} +message with an empty \mdline{5439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5439} repeated field.%mdk + +%mdk-data-line={5441} +\mdline{5441}After generating an idle notification, the P4Runtime server must \mdline{5441}\textquotedblleft{}reset\textquotedblright{}\mdline{5441} the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the master client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle.%mdk + +%mdk-data-line={5448} +\mdline{5448}Here is a reasonable pseudo-code implementation for idle timeout for table +entries:%mdk + +%mdk-data-line={5451} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5452} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutStream~stream;\\ +\\ +scanning\_interval~=~{\mdcolor{purple}10}ms;\\ +\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~{\mdcolor{darkgreen}//~iterate~over~all~tables~which~support~idle~timeout}\\ +~~{\bfseries{\mdcolor{navy}for}}~(table~in~tables)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(!table.idle\_timeout\_supported)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~{\mdcolor{darkgreen}//~we~coalesce~all~idle~notifications~for~the~same~table~in~one}\\ +~~~~{\mdcolor{darkgreen}//~message}\\ +~~~~IdleTimeoutNotification~msg;\\ +~~~~{\mdcolor{darkgreen}//~read~time\_since\_last\_hit~from~device}\\ +~~~~entries~=~device.load\_table\_entries\_from\_hw(table);\\ +~~~~{\bfseries{\mdcolor{navy}for}}~(entry~in~entries)~\{\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.idle\_timeout~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~TTL}\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.time\_since\_last\_hit~\textless{}~entry.idle\_timeout)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~~~msg.table\_entry\_add(entry);\\ +~~~~~~entry.reset\_time\_since\_last\_hit();\\ +~~~~\}\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(msg.table\_entry\_size()~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~notifications}\\ +~~~~msg.set\_timestamp(now());\\ +~~~~stream.write(msg);\\ +~~\}\\ +~~sleep(scanning\_interval);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5479} +\subsection{\mdline{5479}16.5.\hspace*{0.5em}\mdline{5479}Architecture-Specific Notifications}\label{sec-architecture-specific-notifications}%mdk%mdk + +%mdk-data-line={5481} +\noindent\mdline{5481}P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on \mdline{5482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5482}, by including an \mdline{5482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5482} Protobuf field\mdline{5482}~[\mdcite{protoany}{31}]\mdline{5482} +named \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5483} in both \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5483} and \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5483}. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the\mdline{5485}~\mdref{sec-digestentry}{PSA \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}} +extern}\mdline{5486}. See section on\mdline{5486}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{5487} for more information.%mdk + +%mdk-data-line={5489} +\subsection{\mdline{5489}16.6.\hspace*{0.5em}\mdline{5489}Stream Error Reporting}\label{sec-stream-error-reporting}%mdk%mdk + +%mdk-data-line={5491} +\noindent\mdline{5491}The P4Runtime server can asynchronously report errors which occur when +processing \mdline{5492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5492} messages, using the \mdline{5492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5492} message field (of +type \mdline{5493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5493}) in \mdline{5493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5493}. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature.%mdk + +%mdk-data-line={5497} +\mdline{5497}The \mdline{5497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5497} message has the following fields:%mdk + +%mdk-data-line={5499} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5499} +\item\mdline{5499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5499}, which must be set to the appropriate canonical error code +\mdline{5500}[\mdcite{grpcstatuscodes}{34}]\mdline{5500}.%mdk + +%mdk-data-line={5501} +\item\mdline{5501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{5501}, an optional developer-facing error message describing the error.%mdk + +%mdk-data-line={5502} +\item\mdline{5502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5502} and \mdline{5502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5502}, which are optional and can be used by vendors to provide +additional details on the error. \mdline{5503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5503} is a numeric error code drawn from a +vendor\mdline{5504}'\mdline{5504}s chosen error \mdline{5504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5504}.%mdk + +%mdk-data-line={5505} +\item\mdline{5505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5505}, which is a Protobuf \mdline{5505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5505} used to help the client identify which +\mdline{5506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5506} triggered the error. The server is required to set the +appropriate field in the \mdline{5507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5507} so that the client can identify which type +of stream message is responsible for the error (\mdline{5508}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5508}, +\mdline{5509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_list\_ack}}}\mdline{5509} or \mdline{5509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5509}), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid \mdline{5511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5511} message from the +client, the \mdline{5512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5512} field (of type \mdline{5512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError)}}}\mdline{5512} should be set in +the \mdline{5513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5513} \mdline{5513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5513}, and the server may additionally set the \mdline{5513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5513} +field in the \mdline{5514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError}}}\mdline{5514} sub-message (by copying it from the invalid +\mdline{5515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5515} message received on the stream channel) so that the client can +know exactly what packet-out triggered the error.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5518} +\noindent\mdline{5518}The appropriate canonical error code\mdline{5518}~[\mdcite{grpcstatuscodes}{34}]\mdline{5518} should be used when +populating the \mdline{5519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5519} field. For example:%mdk + +%mdk-data-line={5521} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5521} +\item\mdline{5521}if a controller is not allowed to send a \mdline{5521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5521} message under its +current role definition, the code should be set to \mdline{5522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5522}.%mdk + +%mdk-data-line={5523} +\item\mdline{5523}if the \mdline{5523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5523} repeated field in \mdline{5523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5523} does not match the P4Info +definition, the code should be set to \mdline{5524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5524}. It may be useful +for the server to set the \mdline{5525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5525} field in this case, so that the client +can find out which set of metadata fields triggered the error.%mdk + +%mdk-data-line={5527} +\item\mdline{5527}if the \mdline{5527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{5527} field in \mdline{5527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{5527} does not match any \mdline{5527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{5527} entry +in P4Info, the code should be set to \mdline{5528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5528}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5530} +\noindent\mdline{5530}The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, \mdline{5531}e.g.\mdline{5531} because of a +burst of \mdline{5532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5532} messages.%mdk + +%mdk-data-line={5534} +\mdline{5534}Note that master-arbitration errors are never reported using the \mdline{5534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5534} +message. Invalid \mdline{5535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5535} messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section\mdline{5537}~\mdref{sec-mastership-updates}{5.3}\mdline{5537}.%mdk + +%mdk-data-line={5539} +\subsubsection{\mdline{5539}16.6.1.\hspace*{0.5em}\mdline{5539}Examples of \mdline{5539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5539} Messages}\label{sec-examples-of-streamerror-messages}%mdk%mdk + +%mdk-data-line={5541} +\begin{itemize}%mdk + +%mdk-data-line={5541} +\item{} +%mdk-data-line={5541} +\mdline{5541}\textbf{Malformed packet-out metadata.}\mdline{5541} If the server receives a \mdline{5541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5541} +message with a \mdline{5542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5542} field with id 7 which is not included in the P4Info +\mdline{5543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5543} message for \mdline{5543}\textquotedblleft{}packet\_out\textquotedblright{}\mdline{5543}, the server may send the +following \mdline{5544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5544} back to the client:%mdk + +%mdk-data-line={5545} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5546} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Unknown~metadata~field~id~7.}{\mdcolor{maroon}"}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~copied~from~the~PacketOut~message~received~from~the~client}\\ +~~~packet\_out~\{\\ +~~~~~payload:~...\\ +~~~~~metadata~\{\\ +~~~~~~~id:~{\mdcolor{purple}7}\\ +~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}I\_should\_not\_be\_here}{\mdcolor{maroon}"}\\ +~~~~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~~\}\\ +~~~~~{\mdcolor{darkgreen}\#~more~metadata}\\ +~~~\}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={5564} +\item{} +%mdk-data-line={5564} +\mdline{5564}\textbf{Packet-out which exceeds the MTU.}\mdline{5564} If the server receives a \mdline{5564}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5564} +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following \mdline{5567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5567}:%mdk + +%mdk-data-line={5568} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5569} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Packet~exceeds~the~MTU~for~port.}{\mdcolor{maroon}"}\\ +~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendor1}{\mdcolor{maroon}"}\\ +~code:~{\mdcolor{purple}123}~~{\mdcolor{darkgreen}\#~MTU\_EXCEEDED}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~we~do~not~set~the~packet\_out~field~as~it~does~not~provide~any}\\ +~~~{\mdcolor{darkgreen}\#~extra~information~to~the~client}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5581} +\section{\mdline{5581}17.\hspace*{0.5em}\mdline{5581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5581} RPC}\label{sec-capabilities-rpc}%mdk%mdk + +%mdk-data-line={5583} +\noindent\mdline{5583}The \mdline{5583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5583} RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the \mdline{5585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesRequest}}}\mdline{5585} message is empty and the \mdline{5585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5585} +message only includes the \mdline{5586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_api\_version}}}\mdline{5586} string field. This field must +be set to the full semantic version string\mdline{5587}~[\mdcite{semver}{27}]\mdline{5587} corresponding to the +version of the P4Runtime API implemented by the server, \mdline{5588}e.g.\mdline{5588} \mdline{5588}\textquotedblleft{}1.1.0-rc.1\textquotedblright{}\mdline{5588}.%mdk + +%mdk-data-line={5590} +\mdline{5590}Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three\mdline{5591}~\mdref{sec-batch-atomicity}{atomicity +modes}\mdline{5592} for \mdline{5592}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5592} batches, two of them being +optional. In the future we may decide to leverage the \mdline{5593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5593} +message to enable the server to report to the client which subset of these +atomicity modes is supported.%mdk + +%mdk-data-line={5597} +\mdline{5597}The semantic version string included in \mdline{5597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5597} can be used by +the client to determine which exact feature set is implemented by the server, +since\mdline{5599}~\mdref{sec-p4runtime-versioning}{minor releases}\mdline{5599} may introduce new +functionality. However, because the \mdline{5600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5600} RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (\mdline{5602}i.e.\mdline{5602} an \mdline{5602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5602} error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0).%mdk + +%mdk-data-line={5606} +\section{\mdline{5606}18.\hspace*{0.5em}\mdline{5606}Portability Considerations}\label{sec-portability-considerations}%mdk%mdk + +%mdk-data-line={5608} +\subsection{\mdline{5608}18.1.\hspace*{0.5em}\mdline{5608}PSA Metadata Translation}\label{sec-psa-metadata-translation}%mdk%mdk + +%mdk-data-line={5610} +\noindent\mdline{5610}The \mdline{5610}\emph{Portable Switch Architecture}\mdline{5610} (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +\mdline{5614}[\mdcite{psatranslation}{24}]\mdline{5614}. For such metadata, a translation between the controller\mdline{5614}'\mdline{5614}s +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the \mdline{5618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5618} annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture.%mdk + +%mdk-data-line={5622} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={5623} +\noindent\mdline{5623}\includegraphics[keepaspectratio=true,height=7cm]{build/psa-metadata-translation}{}\mdline{5623}%mdk + +%mdk-data-line={5624} +\mdhr{}%mdk + +%mdk-data-line={5625} +\noindent\mdline{5625}\mdcaption{\textbf{Figure~\mdcaptionlabel{8}.}~\mdcaptiontext{P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdcenter}\label{fig-psa-metadata-translation}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={5629} +\noindent\mdline{5629}Figure\mdline{5629}~\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}}\mdline{5629} illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller\mdline{5635}'\mdline{5635}s 32 bit port +numbers to a target\mdline{5636}'\mdline{5636}s 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch.%mdk + +%mdk-data-line={5640} +\subsubsection{\mdline{5640}18.1.1.\hspace*{0.5em}\mdline{5640}Translation of Port Numbers}\label{sec-translation-of-port-numbers}%mdk%mdk + +%mdk-data-line={5642} +\noindent\mdline{5642}In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller\mdline{5643}'\mdline{5643}s space and the PSA device\mdline{5643}'\mdline{5643}s space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +\mdline{5647}\mdref{sec-user-defined-types}{user-defined P4 types}\mdline{5647}, namely \mdline{5647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5647} and +\mdline{5648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5648}, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in \mdline{5651}\emph{psa.p4}\mdline{5651} for +the PSA device in Switch 1.%mdk + +%mdk-data-line={5654} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5655} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_t;\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortIdInHeader\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~PortIdInHeader\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5661} +\noindent\mdline{5661}The first argument to the \mdline{5661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5661} annotation is a URI that +indicates to the P4Runtime server which numerical mapping\mdline{5662} \mdline{5662}\textemdash{}\mdline{5662} provided by the +out-of-band switch configuration mechanism\mdline{5663} \mdline{5663}\textemdash{}\mdline{5663} to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports).%mdk + +%mdk-data-line={5667} +\mdline{5667}An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows:%mdk + +%mdk-data-line={5673} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5674} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}enum}}~SdnPort~\{\\ +~~SDN\_PORT\_UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +\\ +~~{\mdcolor{darkgreen}//~SDN~ports~are~numbered~starting~from~1.}\\ +~~SDN\_PORT\_MIN~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\\ +~~{\mdcolor{darkgreen}//~The~maximum~value~of~an~SDN~port~(physical~or~logical).}\\ +~~SDN\_PORT\_MAX~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffeff};\\ +\\ +~~{\mdcolor{darkgreen}//~Reserved~SDN~port~numbers~(0xfffffff0~-~0xffffffff)}\\ +\\ +~~SDN\_PORT\_RECIRCULATE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffa};\\ +~~SDN\_PORT\_CPU~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffd};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5690} +\noindent\mdline{5690}The switch config will map \mdline{5690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_RECIRCULATE}}}\mdline{5690} and \mdline{5690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_CPU}}}\mdline{5690} \mdline{5690}\textemdash{}\mdline{5690} as well +as any SDN port number corresponding to a \mdline{5691}\textquotedblleft{}regular\textquotedblright{}\mdline{5691} front-panel port\mdline{5691} \mdline{5691}\textemdash{}\mdline{5691} to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation.%mdk + +%mdk-data-line={5695} +\mdline{5695}The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs.%mdk + +%mdk-data-line={5698} +\subsubsection{\mdline{5698}18.1.2.\hspace*{0.5em}\mdline{5698}Translation of Packet-IO Header Fields}\label{sec-translation-of-packet-io-header-fields}%mdk%mdk + +%mdk-data-line={5700} +\noindent\mdline{5700}Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:.%mdk + +%mdk-data-line={5703} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5704} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~PortIdInHeader\_t~egress\_port;\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~PortIdInHeader\_t~ingress\_port;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5715} +\noindent\mdline{5715}The header-level annotation \mdline{5715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5715} is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (\mdline{5719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5719}) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI\mdline{5723} \mdline{5723}\textemdash{}\mdline{5723} first argument to the \mdline{5723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5723} +annotation). Any subsequent reference to the \mdline{5724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5724} field in the +data plane will use the translated value. \mdline{5725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5725} is used in the +header definition instead of \mdline{5726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5726} to guarantee byte-aligned headers in +case this is required by the target.%mdk + +%mdk-data-line={5729} +\mdline{5729}A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target\mdline{5731}'\mdline{5731}s PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the \mdline{5733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ingress\_port}}}\mdline{5733} field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller.%mdk + +%mdk-data-line={5739} +\subsubsection{\mdline{5739}18.1.3.\hspace*{0.5em}\mdline{5739}Translation of Match Fields}\label{sec-translation-of-match-fields}%mdk%mdk + +%mdk-data-line={5741} +\noindent\mdline{5741}Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table\mdline{5742}'\mdline{5742}s match key as shown in the example below:%mdk + +%mdk-data-line={5744} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5745} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~istd.ingress\_port:~exact;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~ingress~port}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5755} +\noindent\mdline{5755}Table \mdline{5755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5755} has an exact match on PSA standard metadata ingress port +(\mdline{5756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}istd.ingress\_port}}}\mdline{5756}). Since the field is of type \mdline{5756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5756}, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in \mdline{5759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5759} from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table \mdline{5764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5764} is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values.%mdk + +%mdk-data-line={5768} +\mdline{5768}Note that it may be infeasible to translate the value-mask pair for ternary +matches: \mdline{5769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5769}, \mdline{5769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5769} or \mdline{5769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5769} match kinds. The P4Runtime server may +require that for these match kinds the port match be either \mdline{5770}\emph{de facto}\mdline{5770} \mdline{5770}\textquotedblleft{}exact\textquotedblright{}\mdline{5770} +(0xffffffff mask for \mdline{5771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5771}, prefix-length of 32 for \mdline{5771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5771}, or same low and +high bounds for \mdline{5772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5772}) or \mdline{5772}\textquotedblleft{}don't care\textquotedblright{}\mdline{5772}.%mdk + +%mdk-data-line={5774} +\subsubsection{\mdline{5774}18.1.4.\hspace*{0.5em}\mdline{5774}Translation of Action Parameters}\label{sec-translation-of-action-parameters}%mdk%mdk + +%mdk-data-line={5776} +\noindent\mdline{5776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5776} type parameters can be part of a P4 action definition as shown in the +example below:%mdk + +%mdk-data-line={5779} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5780} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.h.f:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~a;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5794} +\noindent\mdline{5794}The controller may write entries in table \mdline{5794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5794} with action \mdline{5794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5794} to set the egress +port as shown in the P4 code above. The action parameter \mdline{5795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5795} is of type +\mdline{5796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5796}, which leads to a 32-bit bitwidth for \mdline{5796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5796} being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device.%mdk + +%mdk-data-line={5802} +\subsubsection{\mdline{5802}18.1.5.\hspace*{0.5em}\mdline{5802}Port Translation for PSA Extern APIs}\label{sec-port-translation-for-psa-extern-apis}%mdk%mdk + +%mdk-data-line={5804} +\noindent\mdline{5804}The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch field is +of type \mdline{5810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5810} to carry the 32-bit SDN representation of the port being +watched. The P4Runtime server will translate the given watch port number into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device.%mdk + +%mdk-data-line={5815} +\mdline{5815}The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type \mdline{5817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5817} to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane.%mdk + +%mdk-data-line={5821} +\subsubsection{\mdline{5821}18.1.6.\hspace*{0.5em}\mdline{5821}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}\label{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}%mdk%mdk + +%mdk-data-line={5823} +\noindent\mdline{5823}P4Runtime supports using a translated value (\mdline{5823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5823} or any other translated +type for which the underlying built-in type is \mdline{5824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5824}) as an index to a +register, indirect counter, or indirect meter.%mdk + +%mdk-data-line={5827} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5828} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~counter~entry~type~}{\mdcolor{darkgreen}*/},~PortId\_t~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~index~type~}{\mdcolor{darkgreen}*/}\textgreater{}(\\ +~~{\mdcolor{purple}32}w1024,~PSA\_CounterType\_t.PACKETS)~counter;\\ +{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +~~counter.count(p);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5836} +\noindent\mdline{5836}This P4 Counter declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={5839} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5840} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counters~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x12000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}counter}{\mdcolor{maroon}"}\\ +~~\}\\ +~~spec~\{\\ +~~~~unit:~PACKETS\\ +~~\}\\ +~~index\_type\_name~\{\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5854} +\noindent\mdline{5854}The controller may read and write counter values from indexed counter \mdline{5854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter}}}\mdline{5854} +using SDN port numbers as indices, and not device-specific port numbers. The +\mdline{5856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{5856} field in the P4Info message is a signal to the P4Runtime +server that translation is required.%mdk + +%mdk-data-line={5859} +\section{\mdline{5859}19.\hspace*{0.5em}\mdline{5859}P4Runtime Versioning}\label{sec-p4runtime-versioning}%mdk%mdk + +%mdk-data-line={5861} +\noindent\mdline{5861}P4Runtime follows the Google guidelines for versioning cloud APIs +\mdline{5862}[\mdcite{apiversioning}{6}]\mdline{5862}. We use a \mdline{5862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR.MINOR.PATCH}}}\mdline{5862} style version number scheme and +we increment the:%mdk + +%mdk-data-line={5865} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5865} +\item\mdline{5865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5865} version when we make incompatible API changes,%mdk + +%mdk-data-line={5866} +\item\mdline{5866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MINOR}}}\mdline{5866} version when we add functionality in a backwards-compatible manner,%mdk + +%mdk-data-line={5867} +\item\mdline{5867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PATCH}}}\mdline{5867} version when we make backwards-compatible bug fixes.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5869} +\noindent\mdline{5869}The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is \mdline{5871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1}}}\mdline{5871} and the package +name for P4Info is \mdline{5872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1}}}\mdline{5872}. Even though \mdline{5872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5872} and \mdline{5872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5872} are two +different Protobuf packages, \mdline{5873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5873} depends on \mdline{5873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5873} and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence.%mdk + +%mdk-data-line={5877} +\mdline{5877}As recommended in\mdline{5877}~[\mdcite{apiversioning}{6}]\mdline{5877}, we may consider using pre-GA release +suffixes (such as \mdline{5878}\emph{alpha}\mdline{5878} or \mdline{5878}\emph{beta}\mdline{5878}) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1).%mdk + +%mdk-data-line={5882} +\mdline{5882}Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner.\mdline{5883}~[\mdcite{apiversioningbackwardscompatibility}{7}]\mdline{5883} describes +what constitute a backwards-compatible change. We expect \mdline{5884}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5884} version bumps +to be a \mdline{5885}\textbf{rare}\mdline{5885} event.%mdk + +%mdk-data-line={5887} +\mdline{5887}Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor\mdline{5892} \mdline{5892}+ patch version numbers in future releases.%mdk + +%mdk-data-line={5894} +\mdline{5894}All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository\mdline{5895}~[\mdcite{p4runtimerepo}{15}]\mdline{5895} and the version label follows +semantic versioning rules\mdline{5896}~[\mdcite{semver}{27}]\mdline{5896}.%mdk + +%mdk-data-line={5898} +\section{\mdline{5898}20.\hspace*{0.5em}\mdline{5898}Extending P4Runtime for non-PSA Architectures}\label{sec-extending-p4runtime}%mdk%mdk + +%mdk-data-line={5900} +\noindent\mdline{5900}P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place.%mdk + +%mdk-data-line={5908} +\mdline{5908}When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names:%mdk + +%mdk-data-line={5912} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5912} +\item\mdline{5912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/config/\textless{}major~version\textgreater{}/p4info.proto}}}\mdline{5912}%mdk + +%mdk-data-line={5913} +\item\mdline{5913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/\textless{}major~version\textgreater{}/p4runtime.proto}}}\mdline{5913}%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5915} +\noindent\mdline{5915}We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they \mdline{5916}\textquotedblleft{}extend\textquotedblright{}\mdline{5916}.%mdk + +%mdk-data-line={5918} +\mdline{5918}For the remainder of this section, we will refer to these two files as +\mdline{5919}\emph{p4info-ext}\mdline{5919} and \mdline{5919}\emph{p4runtime-ext}\mdline{5919} respectively.%mdk + +%mdk-data-line={5921} +\subsection{\mdline{5921}20.1.\hspace*{0.5em}\mdline{5921}Extending P4Runtime for Architecture-Specific Externs}\label{sec-extending-p4runtime-for-architecture-specific-externs}%mdk%mdk + +%mdk-data-line={5923} +\noindent\mdline{5923}Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both \mdline{5924}\emph{p4info-ext}\mdline{5924} and +\mdline{5925}\emph{p4runtime-ext}\mdline{5925}. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example:%mdk + +%mdk-data-line={5929} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5930} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~T~must~be~a~bit\textless{}W\textgreater{}~type,~it~indicates~the~width~of~each~counter~cell}\\ +{\bfseries{\mdcolor{navy}extern}}~MyNewPacketCounter\textless{}T\textgreater{}~\{\\ +~~counter({\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~size);\\ +~~increment({\bfseries{\mdcolor{navy}in}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~index);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5937} +\subsubsection{\mdline{5937}20.1.1.\hspace*{0.5em}\mdline{5937}Extending the P4Info message}\label{sec-extending-the-p4info-message}%mdk%mdk + +%mdk-data-line={5939} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5939} +\item\mdline{5939}Id prefixes \mdline{5939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0x81}}}\mdline{5939} through \mdline{5939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfe}}}\mdline{5939} are reserved for architecture-specific +externs. It is recommended that \mdline{5940}\emph{p4info-ext}\mdline{5940} include a \mdline{5940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Ids}}}\mdline{5940} message based +on the one in p4info.proto that the P4 compiler can refer to when\mdline{5941}~\mdref{sec-id-allocation}{assigning +IDs}\mdline{5942} to each extern instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5944} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5945} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~P{\mdcolor{purple}4}Ids~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Prefix~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~MY\_NEW\_PACKET\_COUNTER~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0x81};\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5953} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5953} +\item\mdline{5953}\emph{p4info-ext}\mdline{5953} should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +\mdline{5957}\mdref{sec-p4info-extern}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ExternInstance}}}}\mdline{5957} message as the \mdline{5957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{5957} +field, which is of type \mdline{5958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5958}~[\mdcite{protoany}{31}]\mdline{5958}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5960} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5961} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\mdcolor{darkgreen}//~corresponds~to~the~T~type~parameter~in~the~P4~extern~definition}\\ +~~p4.config.v1.P{\mdcolor{purple}4}DataTypeSpec~type\_spec~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~constructor~argument}\\ +~~{\bfseries{\mdcolor{navy}int64}}~size~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5969} +\subsubsection{\mdline{5969}20.1.2.\hspace*{0.5em}\mdline{5969}Extending the P4Runtime Service}\label{sec-extending-the-p4runtime-service}%mdk%mdk + +%mdk-data-line={5971} +\noindent\mdline{5971}Just like \mdline{5971}\emph{p4info-ext}\mdline{5971}, \mdline{5971}\emph{p4runtime-ext}\mdline{5971} should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an\mdline{5976}~\mdref{sec-extern-entry}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\mdline{5976} message generated by the +P4Runtime client.%mdk + +%mdk-data-line={5979} +\mdline{5979}Here is a possible Protobuf message for our \mdline{5979}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyNewPacketCounter}}}\mdline{5979} P4 extern:%mdk + +%mdk-data-line={5980} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5981} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~This~message~enables~reading~/~writing~data~to~the~counter~at~the~provided}\\ +{\mdcolor{darkgreen}//~index}\\ +{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~p4.v1.P{\mdcolor{purple}4}Data~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5989} +\noindent\mdline{5989}P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an \mdline{5990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5990} Protobuf field\mdline{5990}~[\mdcite{protoany}{31}]\mdline{5990} named \mdline{5990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5990} +in both \mdline{5991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{5991} and +\mdline{5992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{5992}. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in \mdline{5994}\emph{p4runtime-ext}\mdline{5994} and embed instances of these messages in +\mdline{5995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{5995} and \mdline{5995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{5995} as appropriate.%mdk + +%mdk-data-line={5997} +\subsection{\mdline{5997}20.2.\hspace*{0.5em}\mdline{5997}Architecture-Specific Table Extensions}\label{sec-architecture-specific-table-extensions}%mdk%mdk + +%mdk-data-line={5999} +\subsubsection{\mdline{5999}20.2.1.\hspace*{0.5em}\mdline{5999}New Match Types}\label{sec-new-match-types}%mdk%mdk + +%mdk-data-line={6001} +\noindent\mdline{6001}An architecture may introduce new table match types\mdline{6001}~[\mdcite{p4matchtypes}{12}]\mdline{6001}. P4Runtime +accounts for this by providing the following hooks:%mdk + +%mdk-data-line={6004} +\begin{itemize}%mdk + +%mdk-data-line={6004} +\item{} +%mdk-data-line={6004} +\mdline{6004}The \mdline{6004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{6004} field in \mdline{6004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{6004} (p4info.proto) is a \mdline{6004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6004} +which can be either one of the default match types (\mdline{6005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{6005}, \mdline{6005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{6005}, \mdline{6005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{6005}, +\mdline{6006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{6006}, or \mdline{6006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6006}) or an architecture-specific match type encoded as a +string.%mdk%mdk + +%mdk-data-line={6009} +\item{} +%mdk-data-line={6009} +\mdline{6009}The \mdline{6009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{6009} field in \mdline{6009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6009} (p4runtime.proto) is a +\mdline{6010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6010} which includes an \mdline{6010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6010} Protobuf message\mdline{6010}~[\mdcite{protoany}{31}]\mdline{6010} field +(\mdline{6011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6011}). \mdline{6011}\emph{p4info-ext}\mdline{6011} should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in \mdline{6014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6014} as the +\mdline{6015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6015} field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6018} +\subsubsection{\mdline{6018}20.2.2.\hspace*{0.5em}\mdline{6018}New Table Properties}\label{sec-new-table-properties}%mdk%mdk + +%mdk-data-line={6020} +\noindent\mdline{6020}An architecture may introduce additional table properties +\mdline{6021}[\mdcite{p4tableproperties}{30}]\mdline{6021}. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +\mdline{6023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Table}}}\mdline{6023} message includes the \mdline{6023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{6023} \mdline{6023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6023} Protobuf +field\mdline{6024}~[\mdcite{protoany}{31}]\mdline{6024}. At the moment, there is not any mechanism to extend the +\mdline{6025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.TableEntry}}}\mdline{6025} message based on the value of architecture-specific table +properties, but we may include on in future versions of the API.%mdk + +%mdk-data-line={6028} +\section{\mdline{6028}21.\hspace*{0.5em}\mdline{6028}Known Limitations of Current P4Runtime Version}\label{sec-known-limitations-of-current-p4runtime-version}%mdk%mdk + +%mdk-data-line={6030} +\begin{itemize}%mdk + +%mdk-data-line={6030} +\item{} +%mdk-data-line={6030} +\mdline{6030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6030}, action \mdline{6030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6030}, and controller packet metadata fields only +support unsigned bitstrings, \mdline{6031}i.e.\mdline{6031} values of one of the following types (not +the more general \mdline{6032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{6032}):%mdk + +%mdk-data-line={6033} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6033} +\item\mdline{6033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6033}%mdk + +%mdk-data-line={6034} +\item\mdline{6034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6034}. Note that as far as the \mdline{6034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Info}}}\mdline{6034} message contents and +thus controller software is concerned, such fields of type \mdline{6035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6035} +will be indistinguishable from those that have been declared with +type \mdline{6037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6037}. P4Runtime server software will automatically +perform any conversion needed between the type \mdline{6038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6038} values in +P4Runtime messages and the data plane representation.%mdk + +%mdk-data-line={6040} +\item\mdline{6040}an \mdline{6040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{6040} with underlying type \mdline{6040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6040}%mdk + +%mdk-data-line={6041} +\item\mdline{6041}a \mdline{6041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6041} or \mdline{6041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6041} with an underlying type that is one of the above (or +in general a \mdline{6042}\textquotedblleft{}chain\textquotedblright{}\mdline{6042} of \mdline{6042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6042} and/or \mdline{6042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6042} that eventually ends with +one of the types above)%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6045} +\item{} +%mdk-data-line={6045} +\mdline{6045}Support for PSA Random \mdline{6045}\&\mdline{6045} Timestamp externs is postponed to a future minor +version update.%mdk%mdk + +%mdk-data-line={6048} +\item{} +%mdk-data-line={6048} +\mdline{6048}P4Info does not include information about which of a table\mdline{6048}'\mdline{6048}s actions execute +which direct resource(s).%mdk%mdk + +%mdk-data-line={6051} +\item{} +%mdk-data-line={6051} +\mdline{6051}The default action for indirect match tables is restricted to a \mdline{6051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\\ +NoAction}}}\mdline{6052} known at compile-time.%mdk%mdk + +%mdk-data-line={6054} +\item{} +%mdk-data-line={6054} +\mdline{6054}There is no mechanism for changing the value of the \mdline{6054}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{6054} +table property at runtime.%mdk%mdk + +%mdk-data-line={6057} +\item{} +%mdk-data-line={6057} +\mdline{6057}There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor\mdline{6058} \mdline{6058}+ +patch version numbers.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6061} +\section{\mdline{6061}22.\hspace*{0.5em}\mdline{6061}Security concerns for P4Runtime}\label{sec-security-concerns-for-p4runtime}%mdk%mdk + +%mdk-data-line={6063} +\noindent\mdline{6063}Appropriate measures and security best practices need to be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client.%mdk + +%mdk-data-line={6070} +\section{\mdline{6070}A.\hspace*{0.5em}\mdline{6070}Appendix}\label{sec-appendix}%mdk%mdk + +%mdk-data-line={6072} +\subsection{\mdline{6072}A.1.\hspace*{0.5em}\mdline{6072}Revision History}\label{sec-revision-history}%mdk%mdk + +%mdk-data-line={6074} +\subsubsection{\mdline{6074}A.1.1.\hspace*{0.5em}\mdline{6074}Changes in v1.2.0}\label{sec-changes-in-v120}%mdk%mdk + +%mdk-data-line={6076} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6076} +\item\mdline{6076}Add new \mdline{6076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6076} match kind. At the moment, \mdline{6076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6076} is only supported by +the v1model architecture\mdline{6077}~[\mdcite{v1model}{38}]\mdline{6077}, and not by PSA. It will eventually be +included in the core P4 language.%mdk + +%mdk-data-line={6079} +\item\mdline{6079}Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists.%mdk + +%mdk-data-line={6081} +\item\mdline{6081}Add a new \mdline{6081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6081} field of type \mdline{6081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{6081} to \mdline{6081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{6081}. This is more +flexible than the now deprecated \mdline{6082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{6082} field.%mdk + +%mdk-data-line={6083} +\item\mdline{6083}Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +\mdline{6085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6085} annotation.%mdk + +%mdk-data-line={6086} +\item\mdline{6086}Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature.%mdk + +%mdk-data-line={6088} +\item\mdline{6088}Support using \mdline{6088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{6088} as the controller type in the \mdline{6088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6088} +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type.%mdk + +%mdk-data-line={6091} +\item\mdline{6091}Add optional P4 source locations to both structured and unstructured +annotations.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6094} +\subsubsection{\mdline{6094}A.1.2.\hspace*{0.5em}\mdline{6094}Changes in v1.1.0}\label{sec-changes-in-v110}%mdk%mdk + +%mdk-data-line={6096} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6096} +\item\mdline{6096}Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously.%mdk + +%mdk-data-line={6102} +\item\mdline{6102}Add \mdline{6102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{6102} field to stream messages sent by the server.%mdk + +%mdk-data-line={6103} +\item\mdline{6103}Add \mdline{6103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6103} RPC to query the P4Runtime API version implemented by the +server.%mdk + +%mdk-data-line={6105} +\item\mdline{6105}Support wildcard reads for multicast groups and clone sessions.%mdk + +%mdk-data-line={6106} +\item\mdline{6106}Support for modifying direct resources of const tables.%mdk + +%mdk-data-line={6107} +\item\mdline{6107}Support P4 user-defined types for Packet IO metadata fields.%mdk + +%mdk-data-line={6108} +\item\mdline{6108}Clarify consistency requirements for \mdline{6108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6108} and \mdline{6108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{6108} RPCs.%mdk + +%mdk-data-line={6109} +\item\mdline{6109}Add Appendix providing implementation advice for avoiding common pitfalls: + +%mdk-data-line={6110} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6110} +\item\mdline{6110}advice on setting gRPC Metadata Maximum Size%mdk + +%mdk-data-line={6111} +\item\mdline{6111}advice on setting gRPC Server Maximum Receive Message Size%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6112} +\item\mdline{6112}Clarify limitations on supported types for \mdline{6112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6112}, action \mdline{6112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6112}, and +Packet IO metadata fields.%mdk + +%mdk-data-line={6114} +\item\mdline{6114}Clarify that reading entire forwarding state with empty \mdline{6114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{6114} is not +supported.%mdk + +%mdk-data-line={6116} +\item\mdline{6116}Document that \mdline{6116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6116} need only be supported when applied to +type declarations in P4.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6119} +\subsection{\mdline{6119}A.2.\hspace*{0.5em}\mdline{6119}P4 Annotations}\label{sec-p4-annotations}%mdk%mdk + +%mdk-data-line={6121} +\noindent\mdline{6121}Table\mdline{6121}~\mdref{tab-p4-annotations}{\mdcaptionlabel{7}}\mdline{6121} lists P4\mdline{6121}\mdsub{16}\mdline{6121} annotations introduced primarily for +the purpose of adding features for the P4Runtime API.%mdk + +%mdk-data-line={6124} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{6126} Annotation}}&\multicolumn{1}{|c|}{{\bfseries\mdline{6126} Description}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{6128} \mdline{6128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{6128}}&\multicolumn{1}{|l|}{\mdline{6128} See section\mdline{6128}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6128}}\\ +\multicolumn{1}{|l}{\mdline{6129} \mdline{6129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{6129}}&\multicolumn{1}{|l|}{\mdline{6129} See section\mdline{6129}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{6129}}\\ +\multicolumn{1}{|l}{\mdline{6130} \mdline{6130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{6130}}&\multicolumn{1}{|l|}{\mdline{6130} See section\mdline{6130}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6130}}\\ +\multicolumn{1}{|l}{\mdline{6131} \mdline{6131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6131}}&\multicolumn{1}{|l|}{\mdline{6131} See section\mdline{6131}~\mdref{sec-id-allocation}{6.3}\mdline{6131}}\\ +\multicolumn{1}{|l}{\mdline{6132} \mdline{6132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{6132}}&\multicolumn{1}{|l|}{\mdline{6132} See sections\mdline{6132}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{6132},\mdline{6132}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{6132}}\\ +\multicolumn{1}{|l}{\mdline{6133} \mdline{6133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{6133}}&\multicolumn{1}{|l|}{\mdline{6133} See section\mdline{6133}~\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1}\mdline{6133}}\\ +\multicolumn{1}{|l}{\mdline{6134} \mdline{6134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6134}}&\multicolumn{1}{|l|}{\mdline{6134} See sections\mdline{6134}~\mdref{sec-user-defined-types}{8.5.6}\mdline{6134},\mdline{6134}~\mdref{sec-translation-of-port-numbers}{18.1.1}\mdline{6134}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={6136} +\mdhr{}%mdk + +%mdk-data-line={6137} +\noindent\mdline{6137}\mdcaption{\textbf{Table~\mdcaptionlabel{7}.}~\mdcaptiontext{P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-annotations}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={6140} +\subsection{\mdline{6140}A.3.\hspace*{0.5em}\mdline{6140}A More Complex Value Set Example}\label{sec-value-set-example}%mdk%mdk + +%mdk-data-line={6142} +\noindent\mdline{6142}This section includes a more complex Value Set example, with multiple matches of +different kinds.%mdk + +%mdk-data-line={6145} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6146} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6155} +\noindent\mdline{6155}This P4 Value Set declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={6158} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6159} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6186} +\noindent\mdline{6186}A P4Runtime client can set the membership for this Value Set with \mdline{6186}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6186} +messages similar to this one:%mdk + +%mdk-data-line={6189} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6190} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xac}~\}\\ +~~~~~~\}\\ +~~~~~~{\mdcolor{darkgreen}\#~match~for~field\_id~2~is~missing~=\textgreater{}~don't~care~match}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xdc}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~~~ternary~\{~value:~{\mdcolor{purple}0x88}~mask:~{\mdcolor{purple}8}f~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6224} +\subsection{\mdline{6224}A.4.\hspace*{0.5em}\mdline{6224}Guidelines for Implementations}\label{sec-guidelines-for-implementations}%mdk%mdk + +%mdk-data-line={6226} +\noindent\mdline{6226}This section contains practical advice for implementing P4Runtime clients and +servers.%mdk + +%mdk-data-line={6229} +\subsubsection{\mdline{6229}A.4.1.\hspace*{0.5em}\mdline{6229}gRPC Metadata Maximum Size}\label{sec-grpc-metadata-maximum-size}%mdk%mdk + +%mdk-data-line={6231} +\noindent\mdline{6231}In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the \mdline{6232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6232} gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the \mdline{6233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6233} P4Runtime RPC. The \mdline{6233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6233} RPC +returns an individual error for every item in a batch (see Section +\mdline{6235}\mdref{sec-write-rpc}{12}\mdline{6235}), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +\mdline{6237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{6237} error, without any of the individual errors.%mdk + +%mdk-data-line={6239} +\mdline{6239}To fix this problem, one can set the \mdline{6239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6239} option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it\mdline{6241}'\mdline{6241}s +limit, as only the receiving side\mdline{6242}'\mdline{6242}s limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every \mdline{6244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{6244}, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +\mdline{6246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}8192~+~MAX\_UPDATES\_PER\_WRITE~*~100}}}\mdline{6246} bytes of metadata.%mdk + +%mdk-data-line={6248} +\mdline{6248}For example, in C++, one can create a client channel as follows:%mdk + +%mdk-data-line={6249} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6250} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}~=~{\mdcolor{purple}100};\\ +::{\mdcolor{navy}grpc::}ChannelArguments~arguments;\\ +arguments{\bfseries{\mdcolor{navy}.}}SetInt({\mdcolor{teal}GRPC\_ARG\_MAX\_METADATA\_SIZE},~{\mdcolor{purple}8192}~+~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}*{\mdcolor{purple}100});\\ +{\bfseries{\mdcolor{navy}return}}~{\mdcolor{navy}grpc::}CreateCustomChannel(address,~credentials,~arguments);}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6256} +\subsubsection{\mdline{6256}A.4.2.\hspace*{0.5em}\mdline{6256}gRPC Server Maximum Receive Message Size}\label{sec-grpc-server-maximum-receive-message-size}%mdk%mdk + +%mdk-data-line={6258} +\noindent\mdline{6258}At the time of writing, the default maximum receive message size in gRPC is 4MB +\mdline{6259}\textemdash{}\mdline{6259} while the default maximum send message size is unlimited. This can be a +problem for the \mdline{6260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{6260} RPC, since for some targets the +binary \mdline{6261}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6261} can exceed 4MB, in which case by default the P4Runtime +server would return an \mdline{6262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6262} error. To a lesser extent, this may +affect the \mdline{6263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6263} RPC as well, in case of extremely large batches.%mdk + +%mdk-data-line={6265} +\mdline{6265}To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of \mdline{6267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6267} for their target(s). This can be done by +setting the \mdline{6268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_receive\_message\_length}}}\mdline{6268} when building the gRPC server.%mdk + +%mdk-data-line={6270} +\mdline{6270}For example, in C++, one can set the maximum receive message size as follows:%mdk + +%mdk-data-line={6271} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6272} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE}~=~{\mdcolor{purple}128}~*~{\mdcolor{purple}1024}~*~{\mdcolor{purple}1024};~~{\mdcolor{darkgreen}//~128MB}\\ +::{\mdcolor{navy}grpc::}ServerBuilder~server\_builder;\\ +builder{\bfseries{\mdcolor{navy}.}}AddListeningPort({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});\\ +builder{\bfseries{\mdcolor{navy}.}}RegisterService({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});~~{\mdcolor{darkgreen}//~register~P4Runtime~service}\\ +builder{\bfseries{\mdcolor{navy}.}}SetMaxReceiveMessageSize({\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE});\\ +builder{\bfseries{\mdcolor{navy}.}}BuildAndStart();}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6280} +\noindent\mdline{6280}On the client side, we recommend that P4Runtime clients do not use \mdline{6280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6280} +batches larger than the default maximum receive message size (4MB)\mdline{6281} \mdline{6281}\textemdash{}\mdline{6281} in case +the server did not deem necessary to increase the default value\mdline{6282} \mdline{6282}\textemdash{}\mdline{6282}, unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB).%mdk + +%mdk-data-line={6288;build/P4Runtime-Spec-bib.bbl.mdk:1} +%mdk-data-line={6288;build/P4Runtime-Spec-bib.bbl.mdk:2} +\mdsetrefname{References}%mdk +{\mdbibindent{0}%mdk +\begin{thebibliography}{39}%mdk +\label{sec-bibliography}%mdk + +%mdk-data-line={references.bib:68} +\bibitem{p4spec}\mdbibitemlabel{{}[1]}\textquotedblleft{}$P4_{16}$ 1.2.1 Specification.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html}}.\label{p4spec}%mdk%mdk + +%mdk-data-line={references.bib:134} +\bibitem{rfc2698}\mdbibitemlabel{{}[2]}\textquotedblleft{}A Two Rate Three Color Marker.\textquotedblright{} \href{https://tools.ietf.org/html/rfc2698}{{\ttfamily https://\hspace{0pt}tools.\hspace{0pt}ietf.\hspace{0pt}org/\hspace{0pt}html/\hspace{0pt}rfc2698}}.\label{rfc2698}%mdk%mdk + +%mdk-data-line={references.bib:32} +\bibitem{p4complextypes}\mdbibitemlabel{{}[3]}\textquotedblleft{}Complex Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-p4-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}p4-\hspace{0pt}type}}.\label{p4complextypes}%mdk%mdk + +%mdk-data-line={references.bib:37} +\bibitem{protodefaults}\mdbibitemlabel{{}[4]}\textquotedblleft{}Default Values for Protobuf 3 ($proto3$) Fields.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23default}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}default}}.\label{protodefaults}%mdk%mdk + +%mdk-data-line={references.bib:78} +\bibitem{p4enums}\mdbibitemlabel{{}[5]}\textquotedblleft{}Enums in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-enum-types}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}enum-\hspace{0pt}types}}.\label{p4enums}%mdk%mdk + +%mdk-data-line={references.bib:119} +\bibitem{apiversioning}\mdbibitemlabel{{}[6]}\textquotedblleft{}Google Cloud APIs Versioning.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning}}.\label{apiversioning}%mdk%mdk + +%mdk-data-line={references.bib:124} +\bibitem{apiversioningbackwardscompatibility}\mdbibitemlabel{{}[7]}\textquotedblleft{}Google Cloud APIs Versioning - Backwards-Compatibility.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning\%23backwards_compatibility}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning\#\hspace{0pt}backwards\_\hspace{0pt}compatibility}}.\label{apiversioningbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:149} +\bibitem{grpcauth}\mdbibitemlabel{{}[8]}\textquotedblleft{}gRPC Authentication.\textquotedblright{} \href{https://grpc.io/docs/guides/auth.html}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}guides/\hspace{0pt}auth.\hspace{0pt}html}}.\label{grpcauth}%mdk%mdk + +%mdk-data-line={references.bib:7} +\bibitem{grpc}\mdbibitemlabel{{}[9]}\textquotedblleft{}gRPC Main Site.\textquotedblright{} \href{https://grpc.io}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io}}.\label{grpc}%mdk%mdk + +%mdk-data-line={references.bib:144} +\bibitem{grpcstreamc}\mdbibitemlabel{{}[10]}\textquotedblleft{}gRPC Streaming RPCs in C++.\textquotedblright{} \href{https://grpc.io/docs/tutorials/basic/c.html\%23streaming-rpcs}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}tutorials/\hspace{0pt}basic/\hspace{0pt}c.\hspace{0pt}html\#\hspace{0pt}streaming-\hspace{0pt}rpcs}}.\label{grpcstreamc}%mdk%mdk + +%mdk-data-line={references.bib:114} +\bibitem{p4newtypes}\mdbibitemlabel{{}[11]}\textquotedblleft{}Introducing New Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-newtype}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}newtype}}.\label{p4newtypes}%mdk%mdk + +%mdk-data-line={references.bib:139} +\bibitem{p4matchtypes}\mdbibitemlabel{{}[12]}\textquotedblleft{}Match Types in P4.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-match-kind-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}match-\hspace{0pt}kind-\hspace{0pt}type}}.\label{p4matchtypes}%mdk%mdk + +%mdk-data-line={references.bib:194} +\bibitem{p4annotations}\mdbibitemlabel{{}[13]}\textquotedblleft{}P4 Annotations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-annotations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}annotations}}.\label{p4annotations}%mdk%mdk + +%mdk-data-line={references.bib:174} +\bibitem{p4concurrency}\mdbibitemlabel{{}[14]}\textquotedblleft{}P4 Concurrency Model.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-concurrency}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}concurrency}}.\label{p4concurrency}%mdk%mdk + +%mdk-data-line={references.bib:1} +\bibitem{p4runtimerepo}\mdbibitemlabel{{}[15]}\textquotedblleft{}p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.\textquotedblright{} \href{https://github.com/p4lang/p4runtime}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4runtime}}.\label{p4runtimerepo}%mdk%mdk + +%mdk-data-line={references.bib:42} +\bibitem{pirepo}\mdbibitemlabel{{}[16]}\textquotedblleft{}p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.\textquotedblright{} \href{https://github.com/p4lang/PI}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}PI}}.\label{pirepo}%mdk%mdk + +%mdk-data-line={references.bib:109} +\bibitem{p4apiwgcharter}\mdbibitemlabel{{}[17]}\textquotedblleft{}P4.org API Working Group Charter.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4_API_WG_charter.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4\_\hspace{0pt}API\_\hspace{0pt}WG\_\hspace{0pt}charter.\hspace{0pt}html}}.\label{p4apiwgcharter}%mdk%mdk + +%mdk-data-line={references.bib:154} +\bibitem{p4actionannotations}\mdbibitemlabel{{}[18]}\textquotedblleft{}P4 Standard Annotations on Table Actions.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-action-anno}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}action-\hspace{0pt}anno}}.\label{p4actionannotations}%mdk%mdk + +%mdk-data-line={references.bib:73} +\bibitem{psa}\mdbibitemlabel{{}[19]}\textquotedblleft{}Portable Switch Architecture Specification (v1.1.0).\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html}}.\label{psa}%mdk%mdk + +%mdk-data-line={references.bib:189} +\bibitem{protooneofbackwardscompatibility}\mdbibitemlabel{{}[20]}\textquotedblleft{}Protobuf OneOf Backwards-Compatibility Issues.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23backwards-compatibility-issues}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}backwards-\hspace{0pt}compatibility-\hspace{0pt}issues}}.\label{protooneofbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:12} +\bibitem{proto}\mdbibitemlabel{{}[21]}\textquotedblleft{}Protocol Buffers Main Site.\textquotedblright{} \href{https://developers.google.com/protocol-buffers}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers}}.\label{proto}%mdk%mdk + +%mdk-data-line={references.bib:159} +\bibitem{psaactionselector}\mdbibitemlabel{{}[22]}\textquotedblleft{}PSA Action Selector.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-action-selector}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}action-\hspace{0pt}selector}}.\label{psaactionselector}%mdk%mdk + +%mdk-data-line={references.bib:169} +\bibitem{psaatomicityofcontrolplaneops}\mdbibitemlabel{{}[23]}\textquotedblleft{}PSA Atomicity of Control Plane Operations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-atomicity-of-control-plane-api-operations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}atomicity-\hspace{0pt}of-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}api-\hspace{0pt}operations}}.\label{psaatomicityofcontrolplaneops}%mdk%mdk + +%mdk-data-line={references.bib:179} +\bibitem{psatranslation}\mdbibitemlabel{{}[24]}\textquotedblleft{}PSA Data Plane vs Control Plane Types.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-data-plane-vs-control-plane-values}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}data-\hspace{0pt}plane-\hspace{0pt}vs-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}values}}.\label{psatranslation}%mdk%mdk + +%mdk-data-line={references.bib:164} +\bibitem{psaemptygroupactionappendix}\mdbibitemlabel{{}[25]}\textquotedblleft{}PSA Empty Group Action Appendix.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23appendix-empty-action-selector-groups}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}appendix-\hspace{0pt}empty-\hspace{0pt}action-\hspace{0pt}selector-\hspace{0pt}groups}}.\label{psaemptygroupactionappendix}%mdk%mdk + +%mdk-data-line={references.bib:58} +\bibitem{p4selectexpr}\mdbibitemlabel{{}[26]}\textquotedblleft{}Select Expressions in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-select}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}select}}.\label{p4selectexpr}%mdk%mdk + +%mdk-data-line={references.bib:129} +\bibitem{semver}\mdbibitemlabel{{}[27]}\textquotedblleft{}Semantic Versioning.\textquotedblright{} \href{https://semver.org/}{{\ttfamily https://\hspace{0pt}semver.\hspace{0pt}org/\hspace{0pt}}}.\label{semver}%mdk%mdk + +%mdk-data-line={references.bib:98} +\bibitem{protostatus}\mdbibitemlabel{{}[28]}\textquotedblleft{}Status.proto:the Protobuf Status Message.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}src/\hspace{0pt}proto/\hspace{0pt}grpc/\hspace{0pt}status/\hspace{0pt}status.\hspace{0pt}proto}}.\label{protostatus}%mdk%mdk + +%mdk-data-line={references.bib:63} +\bibitem{p4revisions110}\mdbibitemlabel{{}[29]}\textquotedblleft{}Summary of Changes Made in $P4_{16}$ Version 1.1.0.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-summary-of-changes-made-in-version-110}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}summary-\hspace{0pt}of-\hspace{0pt}changes-\hspace{0pt}made-\hspace{0pt}in-\hspace{0pt}version-\hspace{0pt}110}}.\label{p4revisions110}%mdk%mdk + +%mdk-data-line={references.bib:48} +\bibitem{p4tableproperties}\mdbibitemlabel{{}[30]}\textquotedblleft{}Table Properties in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-props}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}props}}.\label{p4tableproperties}%mdk%mdk + +%mdk-data-line={references.bib:83} +\bibitem{protoany}\mdbibitemlabel{{}[31]}\textquotedblleft{}The Any Protobuf Message.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23any}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}any}}.\label{protoany}%mdk%mdk + +%mdk-data-line={references.bib:88} +\bibitem{grpcstatus}\mdbibitemlabel{{}[32]}\textquotedblleft{}The gRPC $Status$ Class.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/status.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}impl/\hspace{0pt}codegen/\hspace{0pt}status.\hspace{0pt}h}}.\label{grpcstatus}%mdk%mdk + +%mdk-data-line={references.bib:104} +\bibitem{grpcerrordetails}\mdbibitemlabel{{}[33]}\textquotedblleft{}The gRPC C++ Error Details Library.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/support/error_details.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}support/\hspace{0pt}error\_\hspace{0pt}details.\hspace{0pt}h}}.\label{grpcerrordetails}%mdk%mdk + +%mdk-data-line={references.bib:93} +\bibitem{grpcstatuscodes}\mdbibitemlabel{{}[34]}\textquotedblleft{}The gRPC Canonical Status Codes.\textquotedblright{} \href{https://developers.google.com/maps-booking/reference/grpc-api/status_codes}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}maps-\hspace{0pt}booking/\hspace{0pt}reference/\hspace{0pt}grpc-\hspace{0pt}api/\hspace{0pt}status\_\hspace{0pt}codes}}.\label{grpcstatuscodes}%mdk%mdk + +%mdk-data-line={references.bib:22} +\bibitem{openconfig}\mdbibitemlabel{{}[35]}\textquotedblleft{}The OpenConfig Project.\textquotedblright{} \href{http://openconfig.net}{{\ttfamily http://\hspace{0pt}openconfig.\hspace{0pt}net}}.\label{openconfig}%mdk%mdk + +%mdk-data-line={references.bib:184} +\bibitem{protomessagedifferencer}\mdbibitemlabel{{}[36]}\textquotedblleft{}The Protobuf MessageDifferencer in the C++ API.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.util.message_differencer}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}reference/\hspace{0pt}cpp/\hspace{0pt}google.\hspace{0pt}protobuf.\hspace{0pt}util.\hspace{0pt}message\_\hspace{0pt}differencer}}.\label{protomessagedifferencer}%mdk%mdk + +%mdk-data-line={references.bib:27} +\bibitem{stratum}\mdbibitemlabel{{}[37]}\textquotedblleft{}The Stratum Project.\textquotedblright{} \href{https://stratumproject.org/}{{\ttfamily https://\hspace{0pt}stratumproject.\hspace{0pt}org/\hspace{0pt}}}.\label{stratum}%mdk%mdk + +%mdk-data-line={references.bib:199} +\bibitem{v1model}\mdbibitemlabel{{}[38]}\textquotedblleft{}v1model Architecture Definition.\textquotedblright{} \href{https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4c/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}p4include/\hspace{0pt}v1model.\hspace{0pt}p4}}.\label{v1model}%mdk%mdk + +%mdk-data-line={references.bib:53} +\bibitem{p4valuesets}\mdbibitemlabel{{}[39]}\textquotedblleft{}Value Sets in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-value-set}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}value-\hspace{0pt}set}}.\label{p4valuesets}%mdk%mdk +\par%mdk +\end{thebibliography}}%mdk%mdk +}%mdk + + +\end{document} diff --git a/spec/v1.2.0-rc.2/ellipse.sty b/spec/v1.2.0-rc.2/ellipse.sty new file mode 100644 index 00000000..7c0ecb3e --- /dev/null +++ b/spec/v1.2.0-rc.2/ellipse.sty @@ -0,0 +1,318 @@ +%% +%% This is file `ellipse.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ellipse.dtx (with options: `package') +%% +%% Copyright (C) 2015 +%% Daan Leijen +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". +%% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{ellipse} + [2004/11/05 v1.0 .dtx ellipse file] +\RequirePackage{pict2e} + +\providecommand*\pIIe@csedef[1]{\expandafter\edef\csname #1\endcsname} +\newcommand*\pIIe@ellip@csqrt[3]{% + \@ovxx=#1\relax + \ifdim\@ovxx<\z@\@ovxx-\@ovxx\fi + \@ovyy=#2\relax + \ifdim\@ovyy<\z@\@ovyy-\@ovyy\fi + \edef\pIIe@csname{@csqrt(\number\@ovxx,\number\@ovyy)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@ellip@csqrt@% + \pIIe@csedef{\pIIe@csname}{\the\dimen@}% + #3\dimen@ + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} +\newcommand*\pIIe@ellip@csqrt@{% + \@ovdx\@ovxx + \advance\@ovdx by \@ovyy + \dimen@0.7071067\@ovdx + \ifdim\dimen@<\@ovyy\dimen@\@ovyy\fi + \ifdim\dimen@<\@ovxx\dimen@\@ovxx\fi + \ifdim\@ovdx<128\p@ + \edef\@tempa{\strip@pt\@ovxx}% + \@ovxx\@tempa\@ovxx + \edef\@tempa{\strip@pt\@ovyy}% + \@ovyy\@tempa\@ovyy + \advance\@ovxx by \@ovyy + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \fi +} + +\newcommand*\pIIe@atan@{% + \@tempdima\dimen@ + \@tempdimb\@tempdima + \ifdim\@tempdimb<\z@\@tempdimb-\@tempdimb\fi + \dimen@0.0663\@tempdimb + \advance\dimen@ 0.2447pt\relax + \advance\@tempdimb -1pt\relax + \edef\@tempa{\strip@pt\@tempdimb}% + \dimen@\@tempa\dimen@ + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \dimen@-\dimen@ + \advance\dimen@ 0.7853\@tempdima +} + +\newcommand*\pIIe@atantwo[3]{% + \edef\pIIe@csname{@atan2(\number\dimexpr#1\relax,\number\dimexpr#2\relax)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@atantwo@{#1}{#2}{#3}% + \pIIe@csedef{\pIIe@csname}{\the\dimexpr#3\relax}% + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} + +\newcommand*\pIIe@atantwo@[3]{% + \@tempdima\dimexpr#2\relax + \@tempdimb\dimexpr#1\relax + \ifdim\@tempdima=\z@\relax + \ifdim\@tempdimb>\z@\relax\dimen@90\p@ + \else\ifdim\@tempdimb<\z@\relax\dimen@-90\p@ + \else\dimen@0\p@ + \fi\fi + \else + \@tempdimd\z@ + \ifdim\@tempdima<\z@\relax + \ifdim\@tempdimb<\z@\relax\@tempdimd-180\p@ + \else\@tempdimd180\p@ + \fi + \fi + \dimen@\dimexpr1pt * \@tempdimb/\@tempdima\relax + \@tempdimc\dimen@ + \ifdim\@tempdimc<\z@\relax\@tempdimc-\@tempdimc\fi + \ifdim\@tempdimc>\p@\relax + \dimen@\dimexpr1pt * \@tempdima/\@tempdimb\relax + \ifdim\dimen@<\z@\relax\def\@tempsign{-}\else\def\@tempsign{}\fi + \pIIe@atan@ + \dimen@-\dimen@ + \advance\dimen@ by \@tempsign1.5707pt\relax + \else + \pIIe@atan@ + \fi + \dimen@57.29578\dimen@ + \advance\dimen@ by \@tempdimd + \fi + #3\dimen@% +} + +\newcommand*\pIIe@noneto[2]{} +\newcommand*\pIIe@ellip@sincost@[2]{% + \CalculateSin{#1}% + \CalculateCos{#1}% + \@tempdima\UseSin{#1}\p@ + \@tempdimb\UseCos{#1}\p@ + \ifdim\@tempdima=\p@\relax + \pIIe@csedef{@ellipsin#2}{1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else\ifdim\@tempdima=-\p@\relax + \pIIe@csedef{@ellipsin#2}{-1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else + \@tempdimc\@ellipratio\dimexpr1pt * \@tempdima/\@tempdimb\relax + %\typeout{ i#2=\the\@tempdimc, sin(#1)=\the\@tempdima}% + \pIIe@ellip@csqrt{\p@}{\@tempdimc}\@tempdimd + \ifdim\@tempdimb<\z@\relax\@tempdimd-\@tempdimd\fi + \pIIe@csedef{@ellipsin#2}{\strip@pt\dimexpr1pt * \@tempdimc/\@tempdimd\relax}% + \pIIe@csedef{@ellipcos#2}{\strip@pt\dimexpr1pt * \p@/\@tempdimd\relax}% + \fi\fi +} + +\newcommand*\pIIe@ellip@sincost[2]{% + %\typeout{ calc sin cos: angles (#1,#2), radii: (\the\@ovro,\the\@ovri)}% + \edef\@ellipratio{\strip@pt\dimexpr1pt * \@ovro/\@ovri\relax}% + \pIIe@ellip@sincost@{#1}{one}% + \pIIe@ellip@sincost@{#2}{two}% + %\typeout{ sincos(a=#1)=(\@ellipsinone,\@ellipcosone), sincos(a=#2)=(\@ellipsintwo,\@ellipcostwo), }% +} +\newcommand*\pIIe@omega[3]{% + \@tempdima\csname @ellipcos#3\endcsname\@ovro + \advance\@tempdima by #1\relax + \@tempdimb\csname @ellipsin#3\endcsname\@ovri + \advance\@tempdimb by #2\relax +} + +\newcommand*\pIIe@omegai[1]{% + \@tempdimc\csname @ellipsin#1\endcsname\@ovro + \@tempdimc-\@tempdimc + \@tempdimd\csname @ellipcos#1\endcsname\@ovri +} + +\newcommand*\pIIe@ellip@kappa{% + \@ovyy\@ellipsinone\p@ + \@ovxx\@ellipcosone\p@ + \@tempdima\@ellipcostwo\@ovyy + \@tempdima-\@tempdima + \advance\@tempdima by \@ellipsintwo\@ovxx + \@tempdimb\@ellipcostwo\@ovxx + \advance\@tempdimb by \@ellipsintwo\@ovyy + \ifdim\@tempdima=\z@\relax + \edef\@ellipkappa{0}% + \else + \dimen@\dimexpr1pt - \@tempdimb\relax + \dimen@\dimexpr1pt * \dimen@/\@tempdima\relax + \pIIe@ellip@csqrt{2\p@}{1.73205\dimen@}{\dimen@}% + \advance\dimen@ by -\p@ + \divide\dimen@ by 3% + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \edef\@ellipkappa{\strip@pt\dimen@}% + \fi + %\typeout{ calculated kappa: \@ellipkappa}% +} + +\newcommand*\pIIe@elliparc@[5]{% + %\typeout{elliparc: #1, center: (#2, #3), radius (\the\@ovro, \the\@ovri),angle (#4, #5)}% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \pIIe@ellip@sincost{#4}{#5}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@t[5]{% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \CalculateSin{#4}\CalculateCos{#4}% + \edef\@ellipsinone{\UseSin{#4}}% + \edef\@ellipcosone{\UseCos{#4}}% + \CalculateSin{#5}\CalculateCos{#5}% + \edef\@ellipsintwo{\UseSin{#5}}% + \edef\@ellipcostwo{\UseCos{#5}}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@draw[2]{% + \pIIe@ellip@kappa% + \pIIe@omega{#1}{#2}{one}% + %\typeout{ point one: (\the\@tempdima,\the\@tempdimb)}% + \@ellip@startto\@tempdima\@tempdimb + \pIIe@omegai{one}% + \advance\@tempdima by \@ellipkappa\@tempdimc + \advance\@tempdimb by \@ellipkappa\@tempdimd + \pIIe@add@nums\@tempdima\@tempdimb + %\typeout{ control one: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@omega{#1}{#2}{two}% + \pIIe@omegai{two}% + \@tempdimc\@ellipkappa\@tempdimc + \@tempdimd\@ellipkappa\@tempdimd + \@tempdimc-\@tempdimc + \@tempdimd-\@tempdimd + \advance\@tempdimc by \@tempdima + \advance\@tempdimd by \@tempdimb + \pIIe@add@nums\@tempdimc\@tempdimd + %\typeout{ control two: (\the\@tempdimc,\the\@tempdimd)}% + \pIIe@add@CP\@tempdima\@tempdimb + %\typeout{ point two: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@addtoGraph\pIIe@curveto@op +} +\newcommand*\pIIe@elliparc[7][0]{% + \@ovro #4\relax + \@ovri #5\relax + \iffalse%dim\@ovro=\@ovri + \pIIe@arc[#1]{#2}{#3}{#4}{#6}{#7} + \else + \ifdim \@ovro<\z@ \pIIe@badcircarg\else + \ifdim \@ovri<\z@ \pIIe@badcircarg\else + \@arclen #7\p@ \advance\@arclen -#6\p@ + \ifdim \@arclen<\z@ \def\@tempsign{-}\else\def\@tempsign{}\fi + \ifdim \@tempsign\@arclen>720\p@ + \PackageWarning {ellipse}{The arc angle is reduced to -720..720}% + \@whiledim \@tempsign\@arclen>720\p@ \do {\advance\@arclen-\@tempsign360\p@}% + \@tempdima #6\p@ \advance\@tempdima \@arclen + \edef\@angleend{\strip@pt\@tempdima}% + \pIIe@@elliparc{#1}{#2}{#3}{#6}{\@angleend}% + \else + \pIIe@@elliparc{#1}{#2}{#3}{#6}{#7}% + \fi + \fi + \fi + \fi +} +\newcommand*\pIIe@@elliparc[5]{% + \begingroup + \ifdim \@tempsign\@arclen>90\p@ + \divide\@arclen 2% + \@tempdima #4\p@\advance\@tempdima by \@arclen + \edef\@anglemid{\strip@pt\@tempdima}% + \def\@tempa{\pIIe@@elliparc{#1}{#2}{#3}{#4}}% + \expandafter\@tempa\expandafter{\@anglemid}% + \def\@tempa{\pIIe@@elliparc{2}{#2}{#3}}% + \expandafter\@tempa\expandafter{\@anglemid}{#5}% + \else + \pIIe@elliparc@{#1}{#2}{#3}{#4}{#5}% + \fi + \endgroup +}% + +\newcommand*\pIIeelliparc[7][0]{% + \@killglue + \pIIe@elliparc[#1]{#2\unitlength}{#3\unitlength}{#4\unitlength}{#5\unitlength}{#6}{#7}% + \ignorespaces% +} +\ifx\undefined\elliparc\else + \PackageWarning{ellipse}{\protect\elliparc\space is redefined}% +\fi +\let\elliparc\pIIeelliparc + +\newcommand*\pIIeearc + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\newcommand*\pIIe@earc@[3][0,360]{\pIIe@earc@@(#1){#2}{#3}} +\def\pIIe@earc@@(#1,#2)#3#4{% + \if@tempswa + \pIIe@moveto\z@\z@ + \pIIe@elliparc{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@closepath\pIIe@fillGraph + \else + \pIIe@elliparc[1]{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@strokeGraph + \fi} +\ifx\undefined\earc\else + \PackageWarning{ellipse}{\protect\earc\space is redefined}% +\fi +\let\earc\pIIeearc + +\newcommand*\pIIeellipse + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\let\ellipse\pIIeellipse + +\endinput +%% +%% End of file `ellipse.sty'. diff --git a/spec/v1.2.0-rc.2/embedded-plus-single-remote-controller.png b/spec/v1.2.0-rc.2/embedded-plus-single-remote-controller.png new file mode 100644 index 00000000..2e0f1803 Binary files /dev/null and b/spec/v1.2.0-rc.2/embedded-plus-single-remote-controller.png differ diff --git a/spec/v1.2.0-rc.2/embedded-plus-single-remote-controller.svg b/spec/v1.2.0-rc.2/embedded-plus-single-remote-controller.svg new file mode 100644 index 00000000..9fe2ce9c --- /dev/null +++ b/spec/v1.2.0-rc.2/embedded-plus-single-remote-controller.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spec/v1.2.0-rc.2/embedded-plus-two-remote-controllers.png b/spec/v1.2.0-rc.2/embedded-plus-two-remote-controllers.png new file mode 100644 index 00000000..b6dc04fc Binary files /dev/null and b/spec/v1.2.0-rc.2/embedded-plus-two-remote-controllers.png differ diff --git a/spec/v1.2.0-rc.2/embedded-plus-two-remote-controllers.svg b/spec/v1.2.0-rc.2/embedded-plus-two-remote-controllers.svg new file mode 100644 index 00000000..0f97ba38 --- /dev/null +++ b/spec/v1.2.0-rc.2/embedded-plus-two-remote-controllers.svg @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + + + Entities + + + + + + + \ No newline at end of file diff --git a/spec/v1.2.0-rc.2/embedded-plus-two-remote-ha-controllers.png b/spec/v1.2.0-rc.2/embedded-plus-two-remote-ha-controllers.png new file mode 100644 index 00000000..f663e9bf Binary files /dev/null and b/spec/v1.2.0-rc.2/embedded-plus-two-remote-ha-controllers.png differ diff --git a/spec/v1.2.0-rc.2/embedded-plus-two-remote-ha-controllers.svg b/spec/v1.2.0-rc.2/embedded-plus-two-remote-ha-controllers.svg new file mode 100644 index 00000000..710111fa --- /dev/null +++ b/spec/v1.2.0-rc.2/embedded-plus-two-remote-ha-controllers.svg @@ -0,0 +1,510 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + Master (Active) + + + + + + Slave (Standby) + + + + + + + \ No newline at end of file diff --git a/spec/v1.2.0-rc.2/error-report.png b/spec/v1.2.0-rc.2/error-report.png new file mode 100644 index 00000000..766cb77f Binary files /dev/null and b/spec/v1.2.0-rc.2/error-report.png differ diff --git a/spec/v1.2.0-rc.2/error-report.svg b/spec/v1.2.0-rc.2/error-report.svg new file mode 100644 index 00000000..a2709a72 --- /dev/null +++ b/spec/v1.2.0-rc.2/error-report.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StatusCode error_code_; // canonical error codestring error_message_;string binary_error_details_; // serialized google.rpc.Status + + + + + + + + + + + + + google.rpc.Status + + + + + + int32 error_code; // canonical error codestring message;repeated Any details; // P4Error + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + + + p4.Error + + + + + + p4.Error + + + + + + + + + + + + + + + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + grpc::Status + + + + + + + \ No newline at end of file diff --git a/spec/v1.2.0-rc.2/longbox.sty b/spec/v1.2.0-rc.2/longbox.sty new file mode 100644 index 00000000..cab48934 --- /dev/null +++ b/spec/v1.2.0-rc.2/longbox.sty @@ -0,0 +1,853 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longbox}[2015/12/01, Daan Leijen, Provides basic longbox that can break over pages] +\RequirePackage{options} + +\@ifclassloaded{beamer}{% + \newcommand\lb@savefootnotes{}% + \newcommand\lb@restorefootnotes{}% +}% +{\RequirePackage{footnote}% + \newcommand\lb@savefootnotes{\savenotes}% + \newcommand\lb@restorefootnotes{\spewnotes}% +} + + +% -------------------------------------------------------- +% Debugging +% -------------------------------------------------------- + +\newcommand*\lb@debug[1]{% + \ontoggle{lb@debug}{\typeout{longbox debug: #1}}% +} +\newcommand*\lb@typeout[1]{% + \ontoggle{lb@verbose}{\typeout{longbox: #1}}% +} +\newcommand*\lb@warncannotsplit{% + \PackageWarning{longbox}{Cannot split box; it seems you are using a non-splittable contents}% +} +\newcommand*\lb@warnbadsplit[1]{% + \PackageWarning{longbox}{Bad split (underful vbox by \the#1)}% +} + + +% -------------------------------------------------------- +% Utilities for LaTeX internals +% -------------------------------------------------------- + +% Suppress the indentation on the following paragraph +\providecommand\nofirstindent{\@afterindentfalse\@afterheading} + +% Suppress the paragraph skip on the following paragraph +\providecommand\nofirstparskip{\addvskip{-\parskip}} + +% In contrast to addvspace, addvskip is not suppressed in a minipage +\providecommand\addvskip[1]{% + \ifvmode + \ifdim\lastskip=\z@ + \vskip #1\relax + \else + \@tempskipb#1\relax\@xaddvskip + \fi + \else\@noitemerr\fi +} + + +% Skip to 0.3\baselineskip multiple taking prevdepth into account. +\newskip\lb@prevdepth +\newcommand\lb@skiptobaseline{% + \global\lb@prevdepth=-\@m\p@\relax + \ifvmode + \ifdim\lastskip=\z@\relax + \ifdim\prevdepth=-\@m\p@\else + \dimen@\prevdepth + % Calculate the modulus of the previous depth with 0.3|\baselineskip| in |\dimen@|. + \@tempcnta\prevdepth + \@tempskipa=0.3\baselineskip\relax + \@tempcntb=\@tempskipa\relax + \divide \@tempcnta by \@tempcntb + \dimen@\prevdepth + \advance\dimen@ -\@tempcnta\@tempskipa + % Skip back by that amount, and then skip by 0.3|\baselineskip|. + \vskip -\dimen@ + \vskip \@tempskipa\relax + \global\lb@prevdepth=\@tempskipa\relax + \fi + \fi + \fi +} + +% unvbox a box, and return a vbox with a given background color +% \unvcolorbox{}{} +\newcommand\unvcolorbox[2]{% + \ifoptionblank{#1}{\vbox{\unvbox#2}}{% + \lb@debug{vcolorbox: #1}% + \vbox{\offinterlineskip + \hbox to \z@{\vbox to \z@{\optioncolor{#1}\hrule\@width\wd#2\@height\ht#2\@depth\dp#2\vss}\hss}% + \unvbox#2% + }% + }% +} + +% create a vbox with a given background color +\newcommand\vcolorbox[2]{% + \eifblank{#1}{\vbox{#2}}{% + \setbox\z@=\vbox{#2}\relax + \unvcolorbox{#1}{\z@}% + }% +}% + +% -------------------------------------------------------- +% The following macros come from mdframed +% -------------------------------------------------------- + +% Determine the amount of free space left on the current page +\newlength\lb@freevspace +\newcommand*\lb@setfreevspace@page{% + \lb@debug{ determine free space}% + \bgroup\@nobreakfalse\addpenalty\z@\egroup% + \penalty\@M\relax\vskip 2\baselineskip\relax% + \penalty9999\relax\vskip -2\baselineskip\relax% + \penalty9999% + \ifdim\pagegoal=\maxdimen\relax% + \lb@freevspace=\vsize% + \else + \lb@freevspace=\dimexpr\pagegoal-\pagetotal-\parskip\relax% + \fi + \lb@debug{free space: \the\lb@freevspace, in page: \the\textheight, vsize=\the\vsize}% +} + +\newcommand*\lb@shiftdim[2]{% + %\letoption{#1}\lb@list + \expandafter\lb@setheadtail@#1,\relax + \eifblank{\lb@head}{}{\option@invoke{/longbox/@breakat-previous}{\lb@head}}% + #2\option{/longbox/@breakat-previous}% + \eifblank{\lb@tail}{}{\let#1\lb@tail}% push back tail +} +\def\lb@comma{,}% +\def\lb@setheadtail@#1,#2\relax{% + \def\lb@head{#1}% + \def\lb@tail{#2}% adds commas! +} + +\newcommand*\lb@setfreevspace{% + \eifblank{\lb@breakat}{\lb@setfreevspace@page}{% + \def\lb@eject{\par}%no eject + \lb@extrasplit=\z@\relax% + \lb@shiftdim{\lb@breakat}\lb@freevspace + \ifdim\lb@freevspace>\z@\else\lb@setfreevspace@page\fi + }% +} + + +% Suppress overfull-underfull vbox messages +\newcommand*\lb@ignorevbadness{% + \edef\lb@currentvbadness{\the\vbadness}% + \edef\lb@currentvfuzz{\the\vfuzz}% + \vbadness=\@M\relax% + \vfuzz=\maxdimen\relax% + \afterassignment\lb@restorevbadness +} +\newcommand*\lb@restorevbadness{% + \vbadness=\lb@currentvbadness\relax + \vfuzz=\lb@currentvfuzz\relax +} + + +% -------------------------------------------------------- +% The 'long vbox' (lvbox) environment collects long material +% into a long \vbox, instead of a \hbox like a lrbox in latex. +% The collected box can contain any box, minipage, lrbox, fbox etc, +% but not outer-par material like a figure. Footnotes can be +% dealt with useing lb@savefootnotes. +% +% The material is typeset in a \vbox according to a given width. +% inside the environment, the boolean 'inlvbox' is true. +% +% \begin{lvbox}{}{} +% -------------------------------------------------------- + +\newif\ifinlvbox +\newcommand\lvbox[4]{% + \setbox#1\vbox\bgroup + \begingroup + \inlvboxtrue + % reset defaults + \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\par\@@par + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + % set margin and linewidth + \leftmargin=#2\relax\rightmargin=#4\relax + \@totalleftmargin=\leftmargin% + %\leftskip=#2\relax\rightskip=#4\relax\@rightskip=#4\relax + \linewidth=#3\relax + % set primitive tex margins + \leftskip=\@totalleftmargin% + \rightskip=\rightmargin% + \@rightskip=\rightmargin% + \hsize=\dimexpr\@totalleftmargin+\linewidth+\rightmargin\relax + \columnwidth\hsize + \textwidth\hsize + \nofirstindent + %\nofirstparskip +} +\def\endlvbox{\endgroup\egroup} + + + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + + +\newsavebox\lb@headbox +\newsavebox\lb@savebox +\newsavebox\lb@mainbox + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@setbaseline[1]{% + %\typeout{ set baseline, \the\dp#1,\the\ht#1}% + \ifcase\lb@baseline% + \relax%bottom + \or%middle + \setbox#1=\vbox{\hbox{\lower \dimexpr(\dp#1 + \ht#1)/2 - \dp#1\relax\vbox{\unvbox#1}}}% + \or%top + \setbox#1=\vtop{\unvbox#1}% + \fi + %\typeout{ .new dim: \the\dp#1, \the\ht#1}% +} + + +\@ifundefined{define@key}{}% + {\define@key{longbox}{options}{\options{#1}\option{/longbox/adjust-options}}}% + +\newcommand*\lb@render@breakbox{% + %\typeout{render breakbox entry (in output routine), height=\the\bb@height}% + \bb@restorekeys{longbox}% + \lb@skiptop=\ifbb@isfirst\option{/longbox/skip-top}\else\option{/longbox/skip-break-top}\fi\relax + \lb@skipbottom=\ifbb@islast\option{/longbox/skip-bottom}\else\option{/longbox/skip-break-bottom}\fi\relax + \lb@skipbreaktop=\ifbb@isfirst 0pt\else\option{/longbox/skip-break-top}\fi + \lb@skipbreakbottom=\ifbb@islast 0pt\else\option{/longbox/skip-break-bottom}\fi + %\typeout{ render: skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom, break-top=\the\dimexpr\option{/longbox/skip-bottom}}% + \options{% + /longbox/@part-height=\bb@height + \lb@skipbreaktop + \lb@skipbreakbottom, + /longbox/@part-width=\option{/longbox/width} + \option{/longbox/skip-left} + \option{/longbox/skip-right},%\bb@width, + /longbox/@part-depth=0pt, + /longbox/@part-needtop=\ifbb@isfirst true\else false\fi, + /longbox/@part-needbottom=\ifbb@islast true\else false\fi, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-depth=\option{/longbox/@part-depth}, + }% + %\typeout{breakbox: width=\expandafter\the\option{/longbox/width}, \the\bb@width, \the\dimexpr\option{/longbox/@part-width}}% + \vbox{% + \kern -\lb@skipbreaktop% todo: move to breakbox? + \option{/longbox/render}% + \kern -\lb@skipbreakbottom + }% +} + +\newcommand*\lb@render@vbox[1]{% + \lb@debug{render vbox entry}% + \lb@restoreoptions + \lb@skiptop=\dimexpr\iftoggle{/longbox/@part-needtop}{\option{/longbox/skip-top}}{\option{/longbox/skip-break-top}}\relax + \lb@skipbottom=\dimexpr\iftoggle{/longbox/@part-needbottom}{\option{/longbox/skip-bottom}}{\option{/longbox/skip-break-bottom}}\relax + %\typeout{ skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom}% + % add top skip while maintaining the baseline. + \ifdim\lb@skiptop=\z@\relax\else + \setbox\z@=\vtop{\unvcopy#1}% + \dimen@=\ht\z@ + \setbox#1=\vbox{\offinterlineskip + \hrule width \z@ height \dimexpr\dimen@ + \lb@skiptop\relax depth -\dimen@ + \unvbox#1% + }% + \fi + % add bottom skip while maintaining the baseline. + \ifdim\lb@skipbottom=\z@\relax\else + \dimen@=\dp#1% + \setbox#1=\vbox{\offinterlineskip\unvbox#1\hrule width \z@ height -\dimen@ depth \dimexpr\dimen@ + \lb@skipbottom\relax}% + \fi + \lb@setbaseline{#1}% + \options{% + /longbox/@part-height=\dimexpr\ht#1 + \dp#1\relax, + /longbox/@part-width=\dimexpr\wd#1 + \option{/longbox/skip-left} + \option{/longbox/skip-right}\relax, + /longbox/@part-depth=\dp#1, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-depth=\option{/longbox/@part-depth} - \lb@skipbottom, + }% + %\typeout{ longbox: height=\the\dimexpr\option{/longbox/@content-box-height}, outer height=\the\dimexpr\option{/longbox/@part-height}\relax}% + % lower the box depending on vertical alignment + \ifcase\option{/longbox/vertical-align/@ord}\relax + \@tempdima\z@ + \or + %bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%middle + \@tempdima\dimexpr0.5\option{/longbox/@part-height} - \option{/longbox/@part-depth}\relax + \or%top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%text-bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%text-top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%super + \@tempdima=-0.9ex% + \or%sub + \@tempdima=0.7ex% + \else + \@tempdima\z@ + \fi + \advance\@tempdima by -\option{/longbox/raise}% + \option@invoke{/longbox/@lower}{\@tempdima}% + \noindent\hbox{\lower \@tempdima\vbox{\offinterlineskip + \hbox to \z@{% + \vbox to \z@{% + \hbox{\lower \option{/longbox/@part-height}\vbox{\offinterlineskip{\option{/longbox/render}}}}% + \vss}% + \hss + }% + \hbox{% + \ifdim\option{/longbox/skip-left}=\z@\else\hskip\option{/longbox/skip-left}\fi + \box#1% + \ifdim\option{/longbox/skip-right}=\z@\else\hskip\option{/longbox/skip-right}\fi + %$\box#1% + }% + }}% +} + +\newcommand*\lb@single@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} +\newcommand*\lb@first@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@middle@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@last@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand*\lb@env@start{% + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore +} + +\newcount\lb@usevbox +\newlength\lb@width +\newlength\lb@height +\newlength\lb@skiptop +\newlength\lb@skipright +\newlength\lb@skipbottom +\newlength\lb@skipleft +\newlength\lb@skipbreaktop +\newlength\lb@skipbreakbottom +\newlength\lb@outerwidth +\newlength\lb@extrasplit +\newcount\lb@textalign +\newcount\lb@baseline +\newtoggle{lb@baselineskip}% +\newtoggle{lb@breakable}% +\newtoggle{lb@debug}% +\newtoggle{lb@verbose}% +\def\lb@breakat{}% +\def\lb@halign{}% +\def\lb@eject{}% +\def\lb@insertafter{} +\def\lb@insertbefore{} + +\newcommand*\lb@peekoptions[1]{% + % process options inside a group and just set necessary parameters + % this way, nested boxes don't influence each other's parameters + \begingroup + \options{#1}% + \option{/longbox/adjust-options}% + \protected@edef\lb@temp{\endgroup + \lb@width=\the\dimexpr\option{/longbox/width}\relax + \lb@height=\the\dimexpr\option{/longbox/height}\relax + \lb@textalign=\the\numexpr\option{/longbox/text-align/@ord}\relax + \lb@baseline=\the\numexpr\option{/longbox/baseline/@ord}\relax + \lb@skiptop=\the\dimexpr\option{/longbox/skip-top}\relax + \lb@skipright=\the\dimexpr\option{/longbox/skip-right}\relax + \lb@skipbottom=\the\dimexpr\option{/longbox/skip-bottom}\relax + \lb@skipleft=\the\dimexpr\option{/longbox/skip-left}\relax + \lb@skipbreaktop=\the\dimexpr\option{/longbox/skip-break-top}\relax + \lb@skipbreakbottom=\the\dimexpr\option{/longbox/skip-break-bottom}\relax + \lb@usevbox=\iftoggle{/longbox/use-vbox}{1}{0}\relax + \lb@outerwidth=\the\dimexpr\option{/longbox/outer-width}\relax + \lb@extrasplit=\the\dimexpr\option{/longbox/split-minimum}\relax + \def\noexpand\lb@insertafter{\option{/longbox/insert-after}}% + \def\noexpand\lb@insertbefore{\option{/longbox/insert-before}}% + \def\noexpand\lb@breakat{\option{/longbox/breakat}}% + \def\noexpand\lb@halign{\option{/longbox/height-align}}% + \def\noexpand\lb@eject{\option{/longbox/eject}}% + \noexpand\csname toggle\iftoggle{/longbox/baseline-skip}{true}{false}\endcsname{lb@baselineskip}% + \noexpand\csname toggle\iftoggle{/longbox/breakable}{true}{false}\endcsname{lb@breakable}% + \noexpand\csname toggle\iftoggle{/longbox/debug}{true}{false}\endcsname{lb@debug}% + \noexpand\csname toggle\iftoggle{/longbox/verbose}{true}{false}\endcsname{lb@verbose}% + }% + \lb@temp +} + +\newenvironment{longbox@env}[2]{% + % save options + \lb@peekoptions{#1,#2}% + % + \ifnum\lb@usevbox=0\relax + \lb@debug{start breakbox}% + \let\bb@render\lb@render@breakbox + \bb@savekeys{longbox}{options={#1,#2,outer-width=\the\lb@outerwidth}}% + \iftoggle{lb@baselineskip}{\typeout{**insert bskip}}{\typeout{**suppress bskip}\vskip 1pt}% + \begin{breakbox}% + \ifdim\lb@skiptop=\z@\relax\else\vspace{\lb@skiptop}\fi% + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \begin{bb@margins}{\lb@skipleft}{\dimen@}% + \else + \lb@debug{start vbox}% + \def\lb@restoreoptions{\options{#1,#2}\option{/longbox/adjust-options}}% + \lb@savefootnotes + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \lb@debug{ width=\the\lb@width, linewidth=\the\linewidth, skipleft=\the\lb@skipleft, right=\the\lb@skipright, total right=\the\dimen@}% + \iftoggle{lb@baselineskip}{\lb@skiptobaseline}{\lb@prevdepth=-\@m pt}% + \lvbox{\lb@mainbox}{0pt}{\lb@width}{0pt}%{\lb@skipleft}{\lb@width}{\lb@skipright}% + \prevdepth=\lb@prevdepth + \fi + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore + \begingroup +}{% + \par\unskip + \endgroup + \lb@insertafter + %\ifdim\lb@skipbottom=\z@\relax\else\vskip\lb@skipbottom\fi% + \ifnum\lb@usevbox=0\relax + \end{bb@margins}% + \ifdim\lb@skipbottom=\z@\relax\else\hrule width \z@ height \lb@skipbottom\fi%\vspace{\lb@skipbottom}\fi% + \iftoggle{lb@baselineskip}{}{\vskip 1sp}% + \end{breakbox}% + \lb@debug{end breakbox}% + \else + \ontoggle{lb@baselineskip}{\lb@skiptobaseline}% + \endlvbox% + \lb@debug{initial lvbox: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@processbox + %\setbox\lb@mainbox=\hbox{\lower \lb@skipbottom\vbox{\offinterlineskip\unvbox\lb@mainbox}}% + \lb@restorefootnotes + \lb@debug{end vbox}% + \fi +} + +\newcommand\longbox@cmd[3]{% + \begingroup + %\options{/options/collectunknown,/longbox/scoped,#2}% set scoped options first + %\option{/longbox/scoped/@adjust-options}% + \lb@peekoptions{#1,#2}% + \leavevmode + %\setbox\lb@mainbox=\hbox{% + % \begingroup + % #3% + % \endgroup + %}% + \setbox\lb@mainbox=\hbox{% + \begingroup + \ifcase\lb@textalign\relax + %default=left + \or%left + \or\hss%center + \or\hss%right + \else%justify + \fi + \lb@insertbefore + #3% + \lb@insertafter + \ifnum\lb@textalign<3\relax\hss\fi% default,left,center + \endgroup + }% + \options{#1,#2}% + \ifdim\option{/longbox/width}=-1sp\relax + \options{/longbox/width=\wd\lb@mainbox}%set to natural width + \fi + \option{/longbox/adjust-options}% + % make it a vbox + \setbox\lb@mainbox=\vbox{\offinterlineskip% + \hbox to \option{/longbox/width}{% + \unhbox\lb@mainbox + }% + }% + \def\lb@restoreoptions{}% + \letoption{/longbox/height-align}\lb@halign + \lb@height=\option{/longbox/height}\relax + \lb@baseline=\option{/longbox/baseline/@ord}\relax + \lb@processbox + \endgroup +} + +\newcommand\lb@processbox{% + \ifdim\lb@height<0pt\relax + \lb@setbaseline{\lb@mainbox}% + \else + \lb@restrictheight + \fi + \lb@typesetbox +} + +\newcommand\lb@typesetbox{% + \ifinlvbox + \iftoggle{lb@breakable}{% + %\lb@debug{disable breakable due to nesting of long-boxes}% + \togglefalse{lb@breakable}% + }{}% + \fi + \ifhmode\lb@single@{\lb@mainbox}\else\lb@typeset\fi +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@restrictheight{% + \lb@typeout{restrict height to \the\lb@height}% + \lb@splitheight=\lb@height% + %lb@debug{before height split: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + %split failed.. do nothing + \lb@debug{could not restrict height}% + \else + % store splitted off content in the mainbox (and discard the rest) + \setbox\lb@mainbox\vbox{\unvbox\lb@headbox}% + \lb@debug{restricted height to \the\ht\lb@mainbox}% + \fi + % set baseline + \lb@setbaseline{\lb@mainbox}% + % height align + %\letoption{/longbox/height-align}\lb@halign + \eifstrequal{\lb@halign}{bottom}% + {\setbox\lb@mainbox=\vbox{\hbox{\vbox to \lb@splitheight{\vss\unvbox\lb@mainbox}}}}% + {\eifstrequal{\lb@halign}{middle}% + {\dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\hbox{% + \lower \dimexpr0.5\dimen@ + \dp\lb@mainbox\relax% + \vbox to \lb@splitheight{\vss\unvbox\lb@mainbox\vss}}}}% + {% default is top + \dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\vtop to \lb@splitheight{\box\lb@mainbox\vss}}% + }% + }% +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newlength\lb@neededvspace +\newcommand\lb@typeset[1][0pt]{% + \iftoggle{lb@breakable}{% + \lb@setfreevspace + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skiptop+\lb@skipbottom\relax}% + \lb@debug{needed: \the\lb@neededvspace, available: \the\lb@freevspace}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@single@{\lb@mainbox}% + \else + \lb@typeout{longbox needs splitting}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skiptop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \ifdim\dimexpr\lb@freevspace + #1\relax<\textheight\relax % test if we were at a fresh page.. (and prevent infinite recursion) + \lb@debug{failed to split the box, inserting a page break}% + \hrule \@height\z@ \@width\hsize + \lb@eject% + \lb@typeset[\textheight]% try again, but pass \textheight to guard against infinite recursion + \else + % on a fresh page we should not fail anymore.. just output as is.. + % lb@warncannotsplit + \lb@single@{\lb@mainbox}% + \fi + \else + % first part success + \lb@typeout{first part splitted}% + \lb@first@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest + \fi + \fi + }{%\else + \lb@debug{unbreakable box}% + \lb@single@{\lb@mainbox}% always directly output an unbreakable box + }% +} + +\newcommand\lb@typesetrest{% + \lb@setfreevspace% + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skipbottom+\lb@skipbreaktop\relax}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@typeout{output last part of box}% + \lb@last@{\lb@mainbox}% + \else + \lb@debug{split box further}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skipbreaktop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \lb@typeout{failed to split box!}% + \lb@last@{\lb@mainbox}% + \else + % middle part success + \lb@typeout{output middle part of box}% + \lb@middle@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest% continue the iteration... + \fi + \fi +} + +% -------------------------------------------------------- +% Split a long vbox over multiple pages. +% This code is based on similar code in the mdframed package +% -------------------------------------------------------- + +\newlength\lb@splitheight +\newlength\lb@insurance % tiny extra space to ensure our box will really fit +\setlength\lb@insurance{1pt} + +% expects split target height in lb@splitheight, and splits off the start of lb@mainbox to lb@headbox +\newcommand\lb@splitbox{% + \ifdim\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax>\lb@splitheight\relax + % the main box is larger than our target split height.. + \ifdim\lb@extrasplit>\lb@splitheight\relax + % not enough space to bother + \lb@typeout{not enough space on page for a split}% + \setbox\lb@headbox=\vbox{}% empty head + \else + % try a split; lower the split height a bit so we are sure to fit + \advance\lb@splitheight -\lb@insurance\relax + \lb@debug{split: \the\lb@splitheight, from \the\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax}% + \setbox\lb@savebox=\vbox{\unvcopy\lb@mainbox}% save original + \lb@trysplit{\lb@splitheight}% + \ifdim\dimexpr\ht\lb@headbox + \dp\lb@headbox>\lb@splitheight\relax + % too big, bad split. Try other splits.. iterate N times with 1 or 5pt less before giving up + \dimen@=\lb@splitheight\relax + \@tempcnta=\z@\relax + \loop + \ifdim\dimexpr\ht\lb@headbox+\dp\lb@headbox\relax>\lb@splitheight\relax + \ifnum\@tempcnta<50% + \advance\dimen@ by -\p@\relax% try a slightly smaller height.. + \else + \advance\dimen@ by -5\p@\relax% try larger increase after 50pt.. + \fi + \advance\@tempcnta by \@ne\relax + \lb@ignorevbadness + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \lb@trysplit{\dimen@}% + \ifdim\lb@extrasplit<\dimen@\relax\else\lb@splitstop\fi % don't try to split too small + \ifnum\@tempcnta<100\relax\else\lb@splitstop\fi % and not more than N attempts + \repeat% + \ifnum\@tempcnta<100\relax + \dimen@=\dimexpr\lb@splitheight - \ht\lb@headbox - \dp\lb@headbox\relax + \ifdim\dimen@>\option{/longbox/split-badness}\relax + \lb@warnbadsplit{\dimen@}% + \fi + \fi + \fi + \fi + \else + % mainbox fits in our target lb@splitheight + \setbox\lb@headbox=\vbox{\unvbox\lb@mainbox}% + \setbox\lb@mainbox=\vbox{}% + \fi +} + +\newcommand\lb@splitstop{% + \lb@typeout{cannot find a good split}% + \let\iterate\relax + \lb@warncannotsplit + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \setbox\lb@headbox=\vbox{}% empty head + \@tempcnta=\@M\relax +} + +\newcommand\lb@trysplit[1]{% try to split at given height + \lb@typeout{try to split at: \the\dimexpr #1\relax}% + \lb@ignorevbadness + \setbox\lb@headbox=\vsplit\lb@mainbox to #1\relax% + \setbox\lb@headbox=\vbox{\unvbox\lb@headbox}% + \setbox\lb@mainbox=\vbox{\unvbox\lb@mainbox}% +} + +% -------------------------------------------------------- +% The longbox environment uses options to set its options +% -------------------------------------------------------- + + +% keys and styles that can be set once globally +\options{% + /longbox/.new family, +}% + +\options{/longbox,% + % computed + @part-needtop/.new toggle, + @part-needbottom/.new toggle, + @part-height/.new length, + @part-width/.new length, + @part-depth/.new length, + @content-box-height/.new length, + @content-box-width/.new length, + @content-box-depth/.new length, + @breakat-previous/.new length, + @lower/.new length, + % + debug/.new toggle, + verbose/.new toggle, + render/.new value =\lb@render@fbox, + adjust-options/.new value = {\longbox@adjustoptions}, + eject/.new value = {\protect\vfill\protect\eject}, + use-vbox/.new toggle = true, + split-minimum/.new length = {1.5\baselineskip}, + split-badness/.new length = \baselineskip, + % + height-align/.new choice= {top,middle,bottom}, + baseline/.new choice = {bottom,middle,top}, + text-align/.new choice = {default,left,center,right,justify}, + vertical-align/.new choice = {baseline,bottom,middle,top,text-bottom,text-top,super,sub}, + raise/.new length = {0pt}, + baseline-skip/.new toggle =true, + % + height/.new length = -1sp, + width/.new length = -1sp, + outer-height/.new length= -1sp, + outer-width/.new length = -1sp, + insert-before/.new value= {}, + insert-after/.new value = {}, + breakat/.new value = {}, + breakable/.new toggle = false, + skip/.new style = {skip-top=#1,skip-right=#1,skip-bottom=#1,skip-left=#1}, + skip-top/.new length, + skip-right/.new length, + skip-bottom/.new length, + skip-left/.new length, + skip-break-bottom/.new length, + skip-break-top/.new length, +} + +\newcommand\longbox@adjustoptions{% + %\typeout{ standard longbox adjustoptions}% + \lb@debug{ current width=\the\dimexpr\option{/longbox/width}, outer=\the\dimexpr\option{/longbox/outer-width}, linewidth=\the\linewidth}% + \ontoggle{/longbox/debug}{\option@invoke{/longbox/verbose}{true}}% + % adjust height + \ifdim\option{/longbox/height}=-1sp\relax + \ifdim\option{/longbox/outer-height}=-1sp\else + \option@invoke{/longbox/height}% + {\option{/longbox/outer-height}-\option{/longbox/skip-top}-\option{/longbox/skip-bottom}}% + \fi + \fi + % set width + \ifdim\option{/longbox/width}=-1sp\relax + \ifdim\option{/longbox/outer-width}=-1sp\relax + \option@invoke{/longbox/outer-width}{\linewidth}% + \fi + \dimen@=\dimexpr\option{/longbox/outer-width}-\option{/longbox/skip-left}-\option{/longbox/skip-right}\relax + \ifdim\dimen@<\z@\relax\dimen@=\z@\fi + \option@invoke{/longbox/width}{\dimen@}% + \fi + % use a breakbox whenever we are in external vertical mode and not width or height restricted. + \iftoggle{/longbox/use-vbox}{}{% + \ifinner\toggletrue{/longbox/use-vbox}\else + \ifhmode\toggletrue{/longbox/use-vbox}\else + \ifdim\option{/longbox/height}>-1sp\toggletrue{/longbox/use-vbox}\else + \iftoggle{/longbox/breakable}{}{\toggletrue{/longbox/use-vbox}}% + \ifoptionblank{/longbox/breakat}{}{\toggletrue{/longbox/use-vbox}}% + \fi\fi\fi + }% +} + +\newenvironment{longbox}[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \begin{longbox@env}{/longbox}{#1}% +}{\end{longbox@env}} + +\newcommand\lbox[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \longbox@cmd{/longbox}{#1}% +} + +\newcommand*\lb@render@fbox{% + %\typeout{render defaultbox: bgcolor=\bb@bgcolor, needtop=\iftoggle{/longbox/@part-needtop}{true}{false}}% + \@ovdx=\dimexpr\option{/longbox/@part-width} - 2\fboxrule\relax% + \@ovdy=\dimexpr\option{/longbox/@part-height}\relax% + \iftoggle{/longbox/@part-needbottom}% + {\@tempdima=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdima=\dimexpr\fboxrule + \bb@stickout\relax + \advance\bb@height by \@tempdima + \advance\@ovdy by \@tempdima}% + \iftoggle{/longbox/@part-needtop}% + {\@tempdimb=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdimb=\dimexpr\bb@stickout\relax + \advance\bb@height by \@tempdimb + \advance\@ovdy by \@tempdimb}% + % + \hbox{\lower \@tempdima\vbox{% + \vskip -\@tempdimb + \ontoggle{/longbox/@part-needtop}{\lb@debug{toprule wd=\expandafter\the\option{/longbox/width}}\hrule width \option{/longbox/@part-width} height \fboxrule}% + \hbox{% + \vrule width \fboxrule height \@ovdy% + \ifx\bb@bgcolor\@empty + \vrule width \@ovdx height \z@\relax + \else + {\color{\bb@bgcolor}\vrule width \@ovdx height \@ovdy}% + \fi + \vrule width \fboxrule height \@ovdy% + }% + \ontoggle{/longbox/@part-needbottom}{\hrule width \option{/longbox/@part-width} height \fboxrule}% + }}% +} \ No newline at end of file diff --git a/spec/v1.2.0-rc.2/longfbox.sty b/spec/v1.2.0-rc.2/longfbox.sty new file mode 100644 index 00000000..0df01331 --- /dev/null +++ b/spec/v1.2.0-rc.2/longfbox.sty @@ -0,0 +1,1344 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longfbox}[2015/12/01, Daan Leijen, Provides long fbox that can break over pages] + +\RequirePackage{options} +\RequirePackage{longbox} +\RequirePackage{pict2e} +\RequirePackage{ellipse} + +% -------------------------------------------------------- +% Dimension calulations +% -------------------------------------------------------- + +% dimmin/dimmax return minimum or maximum dimension +\providecommand\dim@min[2]{\ifdim#1>#2#2\else #1\fi} +\providecommand\dim@max[2]{\ifdim#1>#2#1\else #2\fi} + +\newcommand*\option@dimmin[2]{\dim@min{\option{#1}}{\option{#2}}} +\newcommand*\option@dimmax[2]{\dim@max{\option{#1}}{\option{#2}}} + + +% -------------------------------------------------------- +% Add a new 'sides' option type +% -------------------------------------------------------- + +\options{ + /handlers/new sides/.new handler = []{ + \ifblank{#2}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#1-top={##1}, #1-right={##2}, #1-bottom={##3}, #1-left={##4}}}}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#2}}}% + \optionsalso{ + #1/.new cmdx = {##1,##2,##3,##4,##5\relax}{,,,,\relax}{% + \ifblank{##2##3##4}{\option{#1/@cmd@sides}{##1}{##1}{##1}{##1}}% + {\ifblank{##3##4}{\option{#1/@cmd@sides}{##1}{##2}{##1}{##2}}% + {\ifblank{##4}{\option{#1/@cmd@sides}{##1}{##2}{##3}{##2}}% + {\option{#1/@cmd@sides}{##1}{##2}{##3}{##4}}% + }% + }% + }, + #1/.type = sides, + }% + },% +} + +\newcommand*\optionlengthlimit[3]{% len, min, max + \letoption{#1}\opt@temp + \ifdim\opt@temp<\dimexpr#2\relax + \option@invoke{#1}{#2}% + \else\ifdim\opt@temp>\dimexpr#3\relax + \option@invoke{#1}{#3}% + \fi\fi +} + +\newcommand*\optionradiuslimit[4]{% r1, r2, min, max + \letoption{#1}\opt@tempa + \letoption{#2}\opt@tempb + \ifdim\opt@tempa<\dimexpr#3\relax\option@invoke{#1}{#3}\fi + \ifdim\opt@tempb<\dimexpr#3\relax\option@invoke{#2}{#3}\fi + \ifdim\dimexpr\opt@tempa + \opt@tempb\relax=\z@\relax\else + \ifdim\dimexpr\opt@tempa+\opt@tempb\relax>\dimexpr#4\relax + \edef\opt@perc{\the\numexpr(\number\dimexpr#4\relax)/% + (\number\dimexpr(\opt@tempa+\opt@tempb)/100\relax)}% + %\typeout{scale:\the\opt@tempa,\the\opt@tempb, by \opt@perc percent to make \the\dimexpr#4\relax}% + \edef\opt@temp{\dimexpr\opt@perc\dimexpr\the\opt@tempa\relax / 100\relax}% + \option@einvoke{#1}{\opt@temp}% + \option@einvoke{#2}{\dimexpr#4 - \opt@temp\relax}% + %\typeout{ scaled to: \the\opt@temp,\the\dimexpr#4 - \opt@temp\relax}% + \fi + \fi +} + + +% \begin{macro}{\trig@atantan} +% \marg{a}\marg{b}\marg{$\alpha$}{dimen$_\mathit{reg}$}\\ +% Assigns $\atan_2(\frac{\sin(\alpha)}{b},\frac{\cos(\alpha)}{a})$ to dimension register \textit{dimen$_\mathit{reg}$}, +% where $a$ and $b$ are dimensions. +% Returns $\alpha$ when $a = b$, or when $a=0$ or $b=0$. +% \begin{macrocode} +\newcommand*\trig@atantan[4]{% + %\typeout{ atantan:(\the#1,\the#2,\the#3, #4)}% + \@tempdima\dimexpr#1\relax + \@tempdimb\dimexpr#2\relax +% \end{macrocode} +% If $a = b$, we have a circle and the result is $\alpha$. +% \begin{macrocode} + \ifdim\@tempdima=\@tempdimb + #4\dimexpr#3\relax + \else\ifdim\@tempdima=\z@ + #4\dimexpr#3\relax + \else\ifdim\@tempdimb=\z@ + #4\dimexpr#3\relax + \else + \edef\trig@temp{\strip@pt\dimexpr#3\relax}% + \CalculateSin{\trig@temp}\CalculateCos{\trig@temp}% + \@tempdimc\dimexpr1\p@ * \dimexpr\UseSin{\trig@temp}\p@\relax/\@tempdimb\relax + \@tempdimd\dimexpr1\p@ * \dimexpr\UseCos{\trig@temp}\p@\relax/\@tempdima\relax + \pIIe@atantwo{\@tempdimc}{\@tempdimd}\dimen@ + \ifdim\dimen@<\z@ + \ifdim\dimexpr#3\relax<\z@\else\advance\dimen@360\p@\fi + \fi + \@tempdima\dimexpr#3 - \dimen@\relax + \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi + \ifdim\@tempdima<360\p@\else\advance\dimen@360\p@\fi + %\typeout{atan: \the\dimexpr#3\relax versus. \the\dimen@ }% + #4\dimen@ + \fi\fi\fi +} +% \end{macrocode} +% \end{macro} + +% rough approximation of the perimeter; +% if |radius-x == radius-y| = 0 (a circle), the approximation is precise. +% otherwise, works best when |angle2-angle1| <= 45 and gets worse from there on. +\newcommand*\ellip@letarcperimeter[5]{% 'radius-x', 'radius-y', 'angle-1', 'angle-2', '\result' + \@tempdima\dimexpr#3\relax + \@tempdimb\dimexpr#4\relax + \@tempdimc\dimexpr\@tempdima - \@tempdimb\relax + \ifdim\@tempdimc<\z@\@tempdimc-\@tempdimc\fi + \ifdim#1=#2\relax% circle? + \edef\@tempa{\strip@pt\@tempdimc}% angle difference delta as factor + \dimen@\@tempa\dimexpr#1\relax% r*delta + \dimen@0.017453\dimen@% (2*pi/360) * r * delta = 2*pi*r * (delta/360) + \else% ellipse: take the distance between the points on the ellipse, works pretty good if delta <= 45, and ok'ish for delta <= 90 + \@ovro\dimexpr#1\relax + \@ovri\dimexpr#2\relax + \edef\fbox@tempa{\strip@pt\@tempdima}% + \edef\fbox@tempb{\strip@pt\@tempdimb}% + \pIIe@ellip@sincost{\fbox@tempa}{\fbox@tempb}% + \@tempdima\@ellipcosone\@ovro + \@tempdimb\@ellipsinone\@ovri + \@tempdimc\@ellipcostwo\@ovro + \@tempdimd\@ellipsintwo\@ovri + \advance\@tempdimc by -\@tempdima% + \advance\@tempdimd by -\@tempdimb% + \pIIe@ellip@csqrt{\@tempdimc}{\@tempdimd}{\dimen@}% + %\typeout{ distance: \the\dimen@, from (x,y)=(\the\@tempdimc,\the\@tempdimd), radii=(\the#1,\the#2), angles=(\the#3,\the#4)}% + \fi + \edef#5{\the\dimen@}% +} + + +% ------------------------------------------------------------------------------ +% Borders using the picture environment +% ------------------------------------------------------------------------------ + +\newcommand*\fbox@border@pict{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \begingroup + \hbox{% + \unitlength\p@ + \begin{picture}(0,0)(0,\optionunit{/fbox/@border-box-height})% bottom-left is origin + % markers + \ontoggle{/fbox/show-markers}{% + \linethickness{\option{/fbox/marker-width}}% + \optioncolor{/fbox/marker-color}% + \fbox@rect{0pt}{0pt}{\option{/fbox/@border-box-width}}{\option{/fbox/@border-box-height}}% + \fbox@rect{\option{/fbox/border-left-width}}{\option{/fbox/border-\fbox@bottom-width}}% + {\option{/fbox/@border-box-width}-\option{/fbox/border-right-width}}% + {\option{/fbox/@border-box-height}-\option{/fbox/border-\fbox@top-width}}%S + }% + %compute corner coordinates + \fbox@border@calccorners + %put down the background color + \fbox@border@colorbackground + \option{/fbox/picture-insert-before}% + %put down the sides + \fbox@border@side{3}{-2}{0}%top + \fbox@border@side{5}{-4}{3}%left + \fbox@border@side{-6}{7}{2}%bottom + \fbox@border@side{-8}{1}{1}%right + \end{picture}% + }% + \endgroup + \fi +} + +\newcommand*\fbox@border@pict@after{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \letoption{/fbox/picture-insert-after}\fbox@insertafter + \eifblank{\fbox@insertafter}{}{% + \begingroup + \hbox{% + \begin{picture}(0,0)(0,0)% bottom-left is origin + \fbox@insertafter + \end{picture}% + }% + \endgroup + }% + \fi +} + +\newcommand*\fbox@border@side[3]{% + \fbox@setoct@angles{#1}% + \edef\fbox@style{\option{/fbox/border-\fbox@side-style}}% + \optioncolor{/fbox/border-\fbox@side-color}% + \option{/fbox/picture-side-insert-before}% + \ifcsdef{fbox@border@pict@\fbox@style}% + {\csuse{fbox@border@pict@\fbox@style}{#1}{#2}{#3}}% + {\PackageWarning{longfbox}{Unknown style "\fbox@style". Using "solid" instead.}% + \fbox@border@pict@solid{#1}{#2}{#3}}% + \option{/fbox/picture-side-insert-after}% +} + +% ------------------------------------------------------------------------------ +% Define standard border styles for the picture environment +% +% a style has the form \fbox@border@pict@ + + + + + + +
+
+
+
P4Runtime Specification
+
version 1.2.0
+
+
+
The P4.org API Working Group
+
2020-07-06
+
+

Abstract. P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.

+ + +

1. Introduction and Scope

+

This document is published by the P4.org API Working Group, which was +chartered [17] to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called P4Runtime. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +https://github.com/p4lang/p4runtime/tree/v1.2.0/proto. +

1.1. P4 Language Version Applicability

+

P4Runtime is designed to be implemented in conjunction with the P416 language +version or later. P414 programs should be translated into P416 to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P416 1.0, but were introduced in P416 1.1.0 [29]. For +this version of P4Runtime, we recommend using P416 1.2.1 [1]. +

1.2. In Scope

+

This specification document defines the semantics of P4Runtime messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime: +

+
    +
  • Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA) [19] externs (e.g. Counters, Meters, Action +Profiles, ). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0. +
  • +
  • Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism. +
  • +
  • Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy. +
  • +
  • Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities. +
  • +
  • Packet I/O to enable streaming packets to & from the control plane. +
  • +
  • Batching support, with different atomicity guarantees. +
  • +
  • In-the-field device-reconfiguration with a new P4 data plane. +
+ +

The following are in the scope of this specification document: +

+
    +
  • Rationale for the P4Runtime design. +
  • +
  • Reference architecture and use-cases for deploying a P4Runtime service. +
  • +
  • Detailed description of the API semantics. +
  • +
  • Requirements for conformant implementations of the API. +
+

1.3. Not In Scope

+

The following are not in scope of P4Runtime: +

+
    +
  • Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +[35]. An open source implementation of these APIs is also in progress +as part of the Stratum project [37]. +
  • +
  • Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures. +
+ +

The following are not in scope of this specification document: +

+
    +
  • Description of the P4 programming language; it is assumed that the reader is +already familiar with P416 [1]. +
  • +
  • Descriptions of gRPC and Protobuf files in general. +
  • +
  • Controller role definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme. +
+

2. Terms and Definitions

+
+
arbitration
+
Refers to the process through which P4Runtime ensures that at any given +time, there is a single master (i.e. a client with write access) for a given +role. Also referred to as “master-slave arbitration”. +
+
client
+
The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +
+
COS
+
Class of Service. +
+
device
+
Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +
+
entity
+
An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +
+
gRPC
+
gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +[9]. +
+
HA
+
High-Availability. Refers to a redundancy architecture. +
+
Instrumentation
+
The part of the P4Runtime server which implements the calls to the device or +target native “SDK” or backend. +
+
IPC
+
Inter-Process Communication. +
+
P4 Blob
+
A more colloquial term for P4 Device Config (Blob = Binary Large Object). +
+
P4 Device Config
+
The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its “program.” +
+
P4Info
+
Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +
+
P4RT
+
Abbreviation for P4Runtime. +
+
Protobuf (Protocol Buffers)
+
The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See [21]. +
+
PSA
+
Portable Switch Architecture [19]; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +
+
RPC
+
Remote Procedure Call. +
+
RTT
+
Round-trip time. +
+
SDN
+
Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network controller. +
+
SDN port
+
A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +
+
server
+
The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +
+
stream
+
Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (StreamChannel), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and master-slave arbitration, among other +things. +
+
switch config
+
Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +
+
target
+
The hardware or software entity which “executes” the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with “device”. +
+
URI
+
Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.

3. Reference Architecture

+

Figure 1 represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. A multi-master protocol allows more than +one controller to participate, and a role-based arbitration scheme ensures only +one controller has write access to each read/write entity, or the pipeline +config itself. Any controller may perform read access to any entity or the +pipeline config. Later sections describe this in detail. For the sake of +brevity, the term controller may refer to one or more controllers. +

+

The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +[15]. It may be compiled via protoc the Protobuf compiler +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server. +

+

Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository [16]. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, e.g. via callbacks, thus reducing the burden of implementing +P4Runtime. +

+

The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard. +

+

The controller can also set the ForwardingPipelineConfig, which amounts to +installing and running the compiled P4 program output, which is included in the +p4_device_config Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +ForwardingPipelineConfig to retrieve the device config and the P4Info. +

+
+

reference-architecture +

+
+ +
Figure 1. P4Runtime Reference Architecture.

3.1. Idealized Workflow

+

In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the ForwardingPipelineConfig +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a SetForwardingPipelineConfig +RPC. Metadata in the P4Info describes both the overall program itself +(PkgInfo) as well as all entity instances derived from the P4 program +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise “handle” used in API +calls. +

+

In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible. +

+

In some use cases, it is expected that a controller will store a +collection of multiple P4 “packages”, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the ForwardingPipelineConfig from the target via the +GetForwardingPipelineRequest RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state. +

3.2. P4 as a Behavioral Description Language

+

P4 can be considered a behavioral description of a switching device which may or +may not execute “P4” natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a SetForwardingPipelineRequest to +change its pipeline “program”, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device. +

+

While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API. +

+

In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the PkgInfo +message as well as the embedded doc fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections. +

3.3. Alternative Workflows

+

Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary. +

3.3.1. P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config

+

In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +p4_device_config. The device's configuration might be derived via some other +means to implement the P4 source code's intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane. +

3.3.2. No P4 Source Available, P4Info Available

+

In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are: +

+
    +
  1. +

    The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security. +

  2. +
  3. +

    The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info. +

+ +

As discussed in Section 3.2, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, e.g. documentation. +

3.3.3. Partial P4Info and P4 Source are Available

+

In this situation, a subset of the target's pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code. +

3.3.4. P4Info Role-Based Subsets

+

In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more. +

3.4. P4Runtime State Across Restarts

+

All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade. +

4. Controller Use-cases

+

P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +section. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime's flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex. +

4.1. Single Embedded Controller

+

Figure 2 shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases. +

+

P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC. +

+
+

single-embedded-controller +

+
+ +
Figure 2. Use-Case: Single Embedded Controller

4.2. Single Remote Controller

+

Figure 3 shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections. +

+
+

single-remote-controller +

+
+ +
Figure 3. Use-Case: Single Remote Controller

4.3. Embedded + Single Remote Controller

+

Figure 4 illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller. +

+

For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables. +

+
+

embedded-plus-single-remote-controller +

+
+ +
Figure 4. Use-Case: Embedded Plus Single Remote Controller

4.4. Embedded + Two Remote Controllers

+

Figure 5 illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +e.g. routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership. +

+
+

embedded-plus-two-remote-controllers +

+
+ +
Figure 5. Use-Case: Embedded Plus Two Remote Controllers

4.5. Embedded Controller + Two High-Availability Remote Controllers

+

Figure 6 illustrates a single +embedded controller plus two remote controllers in an active-standby HA +(High-Availability) configuration. Controller #1 is the active controller and is +in charge of some entities. If it fails, Controller #2 takes over and manages +the tables formerly owned by Controller #1. The mechanics of HA architectures +are beyond the scope of this document, but the P4Runtime multi-master +arbitration scheme supports it. +

+
+

embedded-plus-two-remote-ha-controllers +

+
+ +
Figure 6. Use-Case: Embedded Plus Two Remote High-Availability Controllers

5. Master-Slave Arbitration and Controller Replication

+

The P4Runtime interface allows multiple controllers to be connected to the +P4Runtime server running on the device at the same time for the following +reasons: +

+
    +
  1. +

    Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, “roles” (or “realms”) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +master and the rest are slaves. Role definition, i.e. how P4 entities get +assigned to each role, is out-of-scope of this document. +

  2. +
  3. +

    Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby slave controllers. These can already have a connection +open, which can help them become master more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved. +

+ +

To support multiple controllers, P4Runtime uses the streaming channel (available +via StreamChannel RPC) for session management. The workflow is described as +follows: +

+
    +
  • +

    Each controller instance (e.g. a controller process) can participate in one or +more roles. For each (device_id, role_id), the controller receives an +election_id. This election_id can be the same for different roles and/or +devices, as long as the tuple (device_id, role_id, election_id) is +unique. For each (device_id, role_id) that the controller wishes to +control, it establishes a StreamChannel with the P4Runtime server +responsible for that device, and sends a MasterArbitrationUpdate message +containing that tuple of (device_id, role_id, election_id) values. The +P4Runtime server selects a master independently for each (device_id, +role_id) pair. The master is the client that has the highest election_id +that the device has ever received for the same (device_id, +role_id) values. A connection between a controller instance and a device id + which involves a persistent StreamChannel can be referred to as a +P4Runtime client. +

    +

    Note that the P4Runtime server does not assign a role_id or election_id to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the election_id values used for each +StreamChannel. The P4Runtime server only keeps track of the (device_id, +role_id, election_id) of each StreamChannel that has sent a successful +MasterArbitrationUpdate message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +WriteRequest message to identify which client is making the WriteRequest, +not only the election_id. This enables controllers to re-use the same +numeric election_id values across different (device_id, role_id) +pairs. P4Runtime does not require election_id values be reused across such +different (device_id, role_id) pairs; it allows it. +

  • +
  • +

    To start a controller session, a controller first opens a bidirectional stream +channel to the server via the StreamChannel RPC for each device. This stream +will be used for two purposes: +

    +
      +
    • +

      Session management: As soon as the controller opens the stream +channel, it sends a StreamMessageRequest message to the switch. The +controller populates the MasterArbitrationUpdate field in this message +using its role_id and election_id, as well as the device_id of the +device. Note that the status field in the MasterArbitrationUpdate is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below. +

    • +
    • +

      Streaming of notifications (e.g. digests) and packet I/O: The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the master controller can participate in packet +I/O. This feature is explained in more details in the Packet +I/O section. +

    + +

    Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state. +

  • +
  • +

    Note that the stream is opened per device. In case a switching platform has +multiple devices (e.g. multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different masters for different +devices. In this case, it is the responsibility of the P4Runtime server to +keep track of the master for each device (and role). More specifically, the +P4Runtime server will know which stream corresponds to the master controller +for each pair of (device_id, role_id) at any point of time. +

  • +
  • +

    The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered “offline” or +“dead” as soon as its stream channel to the switch is broken. When a master +channel gets broken: (i) an advisory message is sent to all other controllers +for that device_id and role_id, as described in the +following section (ii) the P4Runtime server +will be without a master, until a client sends a successful +MasterArbitrationUpdate (as per the rules in a +later section). +

  • +
  • +

    The mechanism via which the controller receives the P4Runtime server details +which includes the device_id, ip and port, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +device_id) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks. +

+ +

gRPC enables the server to identify which client originated each message in the +StreamChannel stream. For example, the C++ gRPC library [10] in +synchronous mode enables a server process to cause a function to be called when +a new client creates a StreamChannel stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +StreamChannel is closed normally (or broken, e.g. because a client process +unexpectedly terminated). Thus the server can easily associate all +StreamChannel messages received from the same client, because they are +processed within the context of the same function call. +

+

A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values device_id, role_id, and election_id in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods [8] that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server. +

5.1. Default Role

+

A controller can omit the role message in MasterArbitrationUpdate. This +implies the “default role”, which corresponds to “full pipeline access”. This +also implies that a default role has a role.id of 0 (default). If using a +default role, all RPCs from the controller (e.g. Write) must set the role_id +to 0. +

5.2. Role Config

+

The role.config field in the MasterArbitrationUpdate message sent by the +controller describes the role configuration, i.e. which operations are in the +scope of a given role. In particular, the definition of a role may include the +following: +

+
    +
  • A list of P4 entities for which the controller may issue Write updates and +receive notification messages (e.g. DigestList and +IdleTimeoutNotification). +
  • +
  • Whether the controller is able to receive PacketIn messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketIn messages should be sent to the controller. +
  • +
  • Whether the controller is able to send PacketOut messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketOut messages are allowed to be sent by the controller. +
+ +

An unset role.config implies “full pipeline access” (similar to the default +role explained above). In order to support different role definition schemes, +role.config is defined as an Any Protobuf message [31]. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion. +

+

It is the job of the P4Runtime server to remember the role.config for every +device_id and role_id pair. +

5.3. Rules for Handling MasterArbitrationUpdate Messages Received from Controllers

+
    +
  1. +

    If the MasterArbitrationUpdate message is received for the first time on +this particular channel (i.e. for a newly connected controller): +

    +
      +
    1. +

      If device_id does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +NOT_FOUND error. +

    2. +
    3. +

      If the election_id is set and is already used by another controller for +the same (device_id, role_id), the P4Runtime server shall terminate +the stream by returning an INVALID_ARGUMENT error. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the number of open streams for the given (device_id, role_id) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a RESOURCE_EXHAUSTED error. +

    8. +
    9. +

      Otherwise, the controller is added to a list of connected controllers for +the given (device_id, role_id) and the server remembers the +controllers device_id, role_id and election_id for this gRPC +channel. See below for the rules to determine if this controller becomes +a master or slave, and what notifications are sent as a consequence. +

    +
  2. +
  3. +

    Otherwise, if the MasterArbitrationUpdate message is received from an +already connected controller: +

    +
      +
    1. +

      If the device_id does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. +

    2. +
    3. +

      If the role.id does not match the current role_id assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. If the controller wishes to change its role, +it must close the current stream channel and open a new one. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the election_id is set and is already used by another controller +(excluding the controller making the request) for the same +(device_id, role_id), the P4Runtime server shall terminate the stream +by returning an INVALID_ARGUMENT error. +

    8. +
    9. +

      If the election_id matches the one assigned to this stream: +

      +
        +
      1. +

        If the controller for this channel is the master, then the server +updates the role.config to the one specified in the +MasterArbitrationUpdate. An advisory mastership message is sent to +all controllers for this device_id and role_id informing +them of the new role.config. Since the format of role.config is +out of scope for the P4Runtime specification, the server will send +the advisory message for every update, even if the master sets the +same role.config as it has before. See the +following section for the format of +the advisory message. +

      2. +
      3. +

        If the controller is a slave, this is a no-op and the role.config +is ignored. No response is sent to any controller. +

      +
    10. +
    11. +

      Otherwise, the server updates the election_id it has stored for this +controller. This change might cause a change in mastership (this +controller might become master, or the controller might have downgraded +itself to a slave, see below), as well as notifications being sent to one +or more controllers. +

    +
+ +

If the MasterArbitrationUpdate is accepted by either of the two steps above +(cases 1.5. and 2.6. above), then the server determines if there are changes in +mastership. Let election_id_past be the highest election ID the server has +ever seen for the given device_id and role_id (including the one of the +current master if there is one). +

+
    +
  1. +

    If election_id is greater than or equal to election_id_past, then the +controller becomes master. The server updates the role configuration to +role.config for the given role.id. Furthermore: +

    +
      +
    1. +

      If there was no master for this device_id and role_id before and +there are no Write requests still processing from a previous master, +then the server immediately sends an advisory notification to all +controllers for this device_id and role_id. See the +following section for the format of the +advisory message. +

    2. +
    3. +

      If there was a previous master or Write requests in flight, then the +server carries out the following steps (in this order): +

      +
        +
      1. +

        The server stops accepting Write requests from the previous master +(if there is one). At this point, the server will reject all Write +requests with PERMISSION_DENIED. +

      2. +
      3. +

        The server notifies all controllers other than the new master of the +mastership change by sending the advisory notification described in +the following section. +

      4. +
      5. +

        The server will finish processing any Write requests that have +already started. If there are errors, they are reported as usual to +the previous master. If the previous master has already disconnected, +any possible errors are dropped and not reported. +

      6. +
      7. +

        The server now accepts the current controller as the new master, thus +accepting Write requests from this controller. The server updates +the highest election ID (i.e. election_id_past) it has seen for +this device_id and role_id to election_id. +

      8. +
      9. +

        The server notifies the new master by sending the advisory message +described in the following section. +

      +
    +
  2. +
  3. +

    Otherwise, the controller becomes a slave. If the controller was previously a +master (and downgraded itself), then an advisory message is sent to all +controllers for this device_id and role_id. Otherwise, the advisory +message is only sent to the controller that sent the initial +MasterArbitrationUpdate. See the +following section for the format of the +advisory message. +

+

5.4. Mastership Notifications

+

For any given device_id and role_id, any time a new master is chosen, a +master downgrades its status to a slave, a master disconnects, or the +role.config is updated by the master, all controllers for that +(device_id, role_id) are informed of this by sending a +StreamMessageResponse. The MasterArbitrationUpdate is populated as follows: +

+
    +
  • +

    device_id and role.id as given. +

  • +
  • +

    role.config is set to the role configuration the server received most +recently in a MasterArbitrationUpdate from a master. +

  • +
  • +

    election_id is populated as follows: +

    +
      +
    • +

      If there has not been any master at all, the election_id is left unset. +

    • +
    • +

      Otherwise, election_id is set to the highest election ID that the server +has seen for this device_id and role_id (which is the election_id of +the current master if there is any). +

    +
  • +
  • +

    status is set differently based on whether the notification is sent to the +master or a slave controller: +

    +
      +
    • +

      If there is a master: +

      +
        +
      • +

        For the master, status is OK (with status.code set to +google.rpc.OK). +

      • +
      • +

        For all slave controllers, status is set to non-OK (with +status.code set to google.rpc.ALREADY_EXISTS). +

      +
    • +
    • +

      Otherwise, if there is no master currently, for all slave controllers, +status is set to non-OK (with status.code set to +google.rpc.NOT_FOUND). +

    +
+ +

Note that on mastership changes with outstanding Write request, some +notifications might be delayed, see the +previous section for details. +

6. The P4Info Message

+

The purpose of P4Info was described under +Reference Architecture. +Here we describe the various +components. +

6.1. Common Messages

+

These messages appear nested within many other messages. +

6.1.1. Documentation Message

+

Documentation is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers. +

+
+
+
message Documentation {
+  // A brief description of something, e.g. one sentence
+  string brief = 1;
+  // A more verbose description of something.
+  // Multiline is accepted. Markup format (if any) is TBD.
+  string description = 2;
+}

6.1.2. Preamble Message

+

The preamble serves as the “descriptor” for each entity and contains the unique +instance ID, name, alias, annotations and documentation. +

+
+
+
message Preamble {
+  // ids share the same number-space; e.g. table ids cannot overlap with counter
+  // ids. Even though this is irrelevant to this proto definition, the ids are
+  // allocated in such a way that it is possible based on an id to deduce the
+  // resource type (e.g. table, action, counter, ...). This means that code
+  // using these ids can detect if the wrong resource type is used
+  // somewhere. This also means that ids of different types can be mixed
+  // (e.g. direct resource list for a table) without ambiguity. Note that id 0
+  // is reserved and means "invalid id".
+  uint32 id = 1;
+  // fully qualified name of the P4 object, e.g. c1.c2.ipv4_lpm
+  string name = 2;
+  // an alias (alternative name) for the P4 object, probably shorter than its
+  // fully qualified name. The only constraint is for it to be unique with
+  // respect to other P4 objects of the same type. By default, the compiler uses
+  // the shortest suffix of the name that uniquely identifies the object. For
+  // example if the P4 program contains two tables with names s.c1.t and s.c2.t,
+  // the default aliases will respectively be c1.t and c2.t. In the future, the
+  // P4 programmer may also be able to override the default alias for any P4
+  // object (TBD).
+  string alias = 3;
+  repeated string annotations = 4;
+  // The location of `annotations[i]` is given by `annotation_locations[i]`.
+  repeated SourceLocation annotation_locations = 7;
+  // Documentation of the entity
+  Documentation doc = 5;
+  repeated StructuredAnnotation structured_annotations = 6;
+}

6.1.3. Annotating P4 Entities with Documentation

+

P4 entities may be annotated using the following annotations: +

+
+
+
@brief(string...)
+@description(string...)
+

Attaching either or both of these annotations to an entity will generate a +P4Info Documentation Message, which in turn will +appear in the Preamble Message for the entity. +

+

The P4 compiler should not emit annotation messages in the P4Info for these +specific cases; instead, it should generate the Documentation messages as +described. +

+

The following example shows documentation annotations for a table entity: +

+
+
+
@brief("Match IPv4 addresses to next-hop MAC and port")
+@description("Match IPv4 addresses to next-hop MAC and port. \
+Uses LPM match type.")
+table my_ipv4_lkup {
+  ...
+}

6.1.4. Structured Annotations

+

P4 supports both unstructured and structured annotations [13]. +Unstructured annotations of the form MyAnno1 or MyAnno2(body-content) can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +MyAnno3[] or MyAnno4[kvList|expressionList] have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this. +

+

The annotations described up to this point, e.g. @brief(), have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as repeated string annotations fields in the various messages. +Similarly, structured annotations are represented in repeated +StructuredAnnotation structured_annotations fields which are siblings to the +unstructured annotations. The structured_annotations contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations. +

+

The structured annotation messages are defined in p4types.proto. +

+
+
+
message KeyValuePair {
+  string key = 1;
+  Expression value = 2;
+}
+
+message KeyValuePairList {
+  repeated KeyValuePair kv_pairs = 1;
+}
+
+message Expression {
+  oneof value {
+    string string_value = 1;
+    int64 int64_value = 2;
+    bool bool_value = 3;
+  }
+}
+
+message ExpressionList {
+  repeated Expression expressions = 1;
+}
+
+message StructuredAnnotation {
+  string name = 1;
+  oneof body {
+    ExpressionList expression_list = 2;
+    KeyValuePairList kv_pair_list = 3;
+  }
+  // Location of the '@' symbol of this annotation in the source code.
+  SourceLocation source_location = 4;
+}
+

The StructuredAnnotation message can represent either a KeyValuePairList +or an ExpressionList. +

+

The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The p4c +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don't match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler may print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions. +

+

The following invariants hold: +

+
    +
  1. +

    For any P4 entity, there are no two StructuredAnnotations that have the +same name. +

  2. +
  3. +

    Within a KeyValuePairList, there are no two KeyValuePairs that have the +same key. +

+
6.1.4.1. Structured Annotation Examples
+

We omit the source_location field in the following examples. +

+

Empty Expression List +

+
+
+
@Empty[]
+table t {
+    ...
+}
+

The generated P4Info will contain the following. +

+
+
+
structured_annotations {
+  name: "Empty"
+}
+

Mixed Expression List +

+
+
+
#define TEXT_CONST "hello"
+#define NUM_CONST 6
+@MixedExprList[1,TEXT_CONST,true,1==2,5+NUM_CONST]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedExprList"
+  expression_list {
+    expressions {
+      int64_value: 1
+    }
+    expressions {
+      string_value: "hello"
+    }
+    expressions {
+      bool_value: true
+    }
+    expressions {
+      bool_value: false
+    }
+    expressions {
+      int64_value: 11
+    }
+  }
+}
+

kvList of Mixed Expressions +

+
+
+
@MixedKV[label="text", my_bool=true, int_val=2*3]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedKV"
+  kv_pair_list {
+    kv_pairs {
+      key: "label"
+      value {
+        string_value: "text"
+      }
+    }
+    kv_pairs {
+      key: "my_bool"
+      value {
+        bool_value: true
+      }
+    }
+    kv_pairs {
+      key: "int_val"
+      value {
+        int64_value: 6
+      }
+    }
+  }
+}

6.1.5. SourceLocation Message

+

A source location describes a location within a .p4-source file. The +SourceLocation message is defined in p4types.proto as follows: +

+
+
+
// Location of code relative to a given source file.
+message SourceLocation {
+  // Path to the source file (absolute or relative to the working directory).
+  string file = 1;
+  // Line and column numbers within the source file, 1-based.
+  int32 line = 2;
+  int32 column = 3;
+}
+

We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations. +

+

The SourceLocation message associated with an annotation holds the location of +the @ symbol introducing the annotation in the P4 source code; the message can +be found in the following place: +

+
    +
  • +

    For unstructured annotations, every message containing a field +repeated string annotations also contains a field +repeated SourceLocation annotation_locations. The i-th member of +annotation_locations is the source location of the i-th member of +annotations. +

  • +
  • +

    For structured annotations, every StructuredAnnotation message contains +a field SourceLocation source_location holding its source location. +

+

6.2. PkgInfo Message

+

The PkgInfo message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. PkgInfo can be extracted +and used to facilitate “browsing” of available P4 programs from a +library. Although all fields are technically “optional,” every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included. +

+
+
+
// Can be used to manage multiple P4 packages.
+message PkgInfo {
+  // a definitive name for this configuration, e.g. switch.p4_v1.0
+  string name = 1;
+  // configuration version, free-format string
+  string version = 2;
+  // brief and detailed descriptions
+  Documentation doc = 3;
+  // Miscellaneous metadata, free-form; a way to extend PkgInfo
+  repeated string annotations = 4;
+  // the target architecture, e.g. "psa"
+  string arch = 5;
+  // organization which produced the configuration, e.g. "p4.org"
+  string organization = 6;
+  // contact info for support,e.g. "tech-support@acme.org"
+  string contact = 7;
+  // url for more information, e.g. "http://support.p4.org/ref/p4/switch.p4_v1.0"
+  string url = 8;
+  // Miscellaneous metadata, structured; a way to extend PkgInfo
+  repeated StructuredAnnotation structured_annotations = 9;
+}

6.2.1. Annotating P4 code with PkgInfo

+

A P4 progam's PkgInfo may be declared using one or more of the following +annotations, attached to the main block only: +

+
+
+
@pkginfo(key=value)
+@pkginfo(key=value[,key=value,...])
+@brief("A brief description")
+@description("A longer\
+description")
+@custom_annotation(...)
+@another_custom_annotation(...)
+

Above we see several different types of annotations: +

+
    +
  • +

    @pkginfo - This is used to populate a specific field within the PkgInfo +message. Multiple @pkginfo annotations are allowed. For compactness, +multiple key-value pairs can appear in a single @pkginfo annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The keys must be from +among the message fields inside PkgInfo, for example, name, version, +etc. Each key-value pair assigns a value to the corresponding field inside the +single PkgInfo message for the program's P4Info. One exception is that the +Documentation field of PkgInfo must be expressed as individual +@description and @brief annotations, see next bullets. The key arch will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself. +

  • +
  • +

    @brief - This will populate the PkgInfo.doc.brief message field. +

  • +
  • +

    @description - This will populate the PkgInfo.doc.description message +field +

  • +
  • +

    @<anything else> - This will create a PkgInfo.annotation entry +

+ +

Declaring one or more of these annotations on main will +generate a single corresponding PkgInfo message in the P4Info as described in +PkgInfo Message. +

+

The following example shows @pkginfo annotations using a mixture of single and +multiple key-value pairs. It also shows @brief and @description annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the PkgInfo message. The custom annotations will +be appended to the PkgInfo.annotations list. +

+
+
+
@pkginfo(name="switch.p4",version="2")
+@pkginfo(organization="p4.org")
+@pkginfo(contact="info@p4.org")
+@pkginfo(url="www.p4.org")
+@brief("L2/L3 switch")
+@description("L2/L3 switch.\
+Built for data-center profile.")
+@my_annotation1(...) // Not well-known, this will appear in PkgInfo annotations
+@my_annotation2(...) // Not well-known, this will appear in PkgInfo annotations
+PSA_Switch(IgPipeline, PacketReplicationEngine(), EgPipeline,
+           BufferingQueueingEngine()) main;

6.3. ID Allocation for P4Info Objects

+

P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(e.g. table, action, counter, ). The most significant 8 bits of the ID +encodes the object type (as per Table 1). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (p4.config.v1.P4Ids.Prefix). These values must +be used (e.g. by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table 2 shows the ID +layout. +

+
+ + + + + + + + + + + + + + + + + + + + + +
8-bit prefix value P4 object type
0x00 Reserved (unspecified)
0x01 Action
0x02 Table
0x03 Value-set
0x04 Controller header (header type with @controller_header annotation)
0x050x0f Reserved (for future P4 built-in objects)
0x10 Reserved (start of PSA extern types)
0x11 PSA Action profiles / selectors
0x12 PSA Counter
0x13 PSA Direct counter
0x14 PSA Meter
0x15 PSA Direct meter
0x16 PSA Register
0x17 PSA Digest
0x180x7f Reserved (for future PSA extern types)
0x80 Reserved (start of vendor-specific extern types)
0x810xfe Vendor-specific extern types
0xff Reserved (max prefix value)
+
+ +
Table 1. Mapping of P4Info object type to 8-bit ID prefix value
+
+ + + + +
MSB bit 31 .. bit 24 bit 23 .. bit 0 LSB
Object type prefix Generated suffix (e.g. by the compiler)
+
+ +
Table 2. Format of P4Info object IDs
+

It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with @id (see Table +3). The compiler must honor the @id annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (i.e. if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same @id value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct. +

+
+ + + + + + + + + + +
P4 declaration(s) Compiler-allocated ID(s)
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) table tA... Error(same ID suffixes for 2 objects of the same type)
@id(0x12ab34) table tB...
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) action act1... 0x0112ab34
+
+ +
Table 3. Example of statically-assigned P4Info object IDs
+

The @id annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively). +

6.4. P4Info Objects

6.4.1. Table

+

Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this table. +

  • +
  • +

    match_fields, a repeated field of type MatchField representing the data to +be used to construct the lookup key matched in this table. Each MatchField +message is defined with the following fields: +

    +
      +
    • +

      id, the uint32 identifier of this MatchField, unique in the scope of +this table. No rules are prescribed on the way MatchField IDs should be +allocated, as long as two MatchField of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the @id annotation, or let the compiler +choose them. +

    • +
    • +

      name, the string representing the name of this MatchField. +

    • +
    • +

      annotations, a repeated field of strings, each one representing a P4 +annotation associated to this match field. +

    • +
    • +

      bitwidth, an int32 value set to the size in bits of this match field. +

    • +
    • +

      match, a oneof describing the match behavior for this field; it can be +either: +

      +
        +
      • match_type, an enum field of type MatchType, which includes all +possible PSA match kinds. +
      • +
      • other_match_type, a string field which can be used to encode any +architecture-specific match type. +
      +
    • +
    • +

      doc, a Documentation message describing this match field. +

    • +
    • +

      type_name, which indicates whether the match field has a user-defined +type; this is useful for +translation. +

    +
  • +
  • +

    action_refs, a repeated ActionRef field representing the set of possible +actions for this table. The ActionRef message is used to reference an action +specified in the same P4Info message and it includes the following fields: +

    +
      +
    • id, the uint32 identifier of the action. +
    • +
    • scope, an enum value which can take one of three values: + TABLE_AND_DEFAULT, TABLE_ONLY and DEFAULT_ONLY. The scope of the + action is determined by the use of the P4 standard annotations + @tableonly and @defaultonly [18]. TABLE_ONLY + (@tableonly annotation) means that the action can only appear within + the table, and never as the default action. DEFAULT_ONLY + (@defaultonly annotation) means that the action can only be used as the + default action. TABLE_AND_DEFAULT is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action. +
    • +
    • annotations, a repeated string field, each one representing a P4 +annotation associated to the action reference in this table. +
    +
  • +
  • +

    const_default_action_id, if this table has a constant default action, this +field will carry the uint32 identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action's +arguments. +

  • +
  • +

    implementation_id, the uint32 identifier of the “implementation” of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (e.g. a PSA ActionProfile or ActionSelector +instance). The table is then referred to as an indirect match table. +

  • +
  • +

    direct_resource_ids, repeated uint32 identifiers for all the direct +resources attached to this table, such as DirectMeter and DirectCounter +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2. +

  • +
  • +

    size, an int64 describing the desired number of table entries that the +target should support for the table. See the “Size” subsection within the +“Table Properties” section of the P416 language specification for details +[30]. +

  • +
  • +

    idle_timeout_behavior, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +Idle-Timeout section). Value can be any of the +IdleTimeoutBehavior enum: +

    +
      +
    • NO_TIMEOUT (default value), which means that idle timeout is not +supported for this table. +
    • +
    • NOTIFY_CONTROL, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +Table Idle Timeout Notifications). +
    +
  • +
  • +

    is_const_table, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime. +

  • +
  • +

    other_properties, an Any Protobuf message [31] to embed +architecture-specific table properties [30] which are not part +of the core P4 language or of the PSA architecture. +

+

6.4.2. Action

+

Action messages are used to specify all possible actions of all match-action +tables. +

+

The Action message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this action +

  • +
  • +

    params, a repeated field of Param messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each Param message contains the +following fields: +

    +
      +
    • id, the uint32 identifier of this parameter. No rules are prescribed +on the way Param IDs should be allocated, as long as two Param of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the @id +annotation, or let the compiler choose them. +
    • +
    • name, the string representing the name of this parameter. +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this parameter. +
    • +
    • bitwidth, an int32 value set to the size in bits of this parameter. +
    • +
    • doc, which describes this parameter using a Documentation message. +
    • +
    • type_name, which indicates whether the action parameter has a +user-defined type; this is useful for +translation. +
    +
+

6.4.3. ActionProfile

+

ActionProfile messages are used to specify all available instances of Action +Profile and Action Selector PSA externs. +

+

PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile member, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime. +

+

PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into groups. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime. +

+

While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same ActionProfile message to describe both. +

+

The ActionProfile message includes the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Action +Profile or Selector. +

  • +
  • +

    table_ids, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector. +

  • +
  • +

    with_selector, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern. +

  • +
  • +

    size, an int64 representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups. +

  • +
  • +

    max_group_size, an int32 representing the maximum sum of all member +weights within any given selector group, in the case of an Action Selector, or +0 for an Action Profile. PSA programs can use the @max_group_size annotation +to provide this value for Action Selectors. If the annotation is omitted, the +P4Info field will default to 0. +

+

6.4.4. Counter & DirectCounter

+

Counter and DirectCounter messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is: +

+
    +
  • +

    Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index. +

  • +
  • +

    Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table. +

+ +

Both Counter and DirectCounter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this counter +extern instance. +

  • +
  • +

    spec, a message of of type CounterSpec used to describe the compile-time +configuration of this counter. Currently, the CounterSpec message is used to +carry only the counter unit, which can be any of the CounterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES: byte counter. +
    • +
    • PACKETS: packet counter. +
    • +
    • BOTH: combination of both byte and packet counter. +
    +
+ +

For indexed counters, the Counter message contains also a size field, an +int64 representing the maximum number of independent values that can be held +by this counter array. Conversely, the DirectCounter message contains a +direct_table_id field that carries the unit32 identifier of the table to +which this direct counter is attached. +

+

For indexed counters, the Counter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.5. Meter & DirectMeter

+

Meter and DirectMeter messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is: +

+
    +
  • +

    Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +e.g. to set the rate threshold. +

  • +
  • +

    Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table. +

+ +

Both Meter and DirectMeter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this meter +extern instance. +

  • +
  • +

    spec, a message of type MeterSpec used to describe the capabilities of +this meter extern instance. Currently, the MeterSpec message is used to +carry only the meter unit, which can be any of the MeterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES, which signifies that this meter can be configured with rates +expressed in bytes/second. +
    • +
    • PACKETS, for rates expressed in packets/second. +
    +
+ +

For indexed meters, the Meter message contains also a size field, an int64 +representing the maximum number of independent cells that can be held by this +meter. Conversely, the DirectMeter message contains a direct_table_id field +that carries the uint32 identifier of the table to which this direct meter is +attached. +

+

For indexed meters, the Meter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.6. ControllerPacketMetadata

+

ControllerPacketMetadata messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server. +

+

When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet. +

+

Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +@controller_header("packet_in") and @controller_header("packet_out"), +respectively. ControllerPacketMetadata messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages). +

+

A P4Info message can contain at most two ControllerPacketMetadata messages, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message where preamble.name is set to "packet_in" +and "packet_out" for packet-in and packet-out metadata, respectively. +

  • +
  • +

    metadata, a repeated field of type Metadata, where each Metadata message +includes the following fields: +

    +
      +
    • id, a uint32 identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two Metadata of the +same ControllerPacketMetadata message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the @id annotation, or let the compiler choose them. +
    • +
    • name, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below). +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this metadata. +
    • +
    • bitwidth, an int32 representing the size in bits of this metadata. +
    • +
    • type_name, which indicates whether the metadata field has a +user-defined type; this is useful for +translation. +
    +
+ +

As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding ControllerPacketMetadata +messages. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  bit<9> egress_port; /* suggested port where the packet
+                         should be sent */
+  bit<8> queue_id;    /* suggested queue ID */
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  bit<9> ingress_port; /* data plane port ID where
+                          the original packet was received */
+  bit<1> is_clone;     /* 1 if this is a clone of the
+                          original packet */
+}
+
+
+
controller_packet_metadata {
+  preamble {
+    id: 2868916615
+    name: "packet_out"
+    annotations: "@controller_header(\"packet_out\")"
+  }
+  metadata {
+    id: 1
+    name: "egress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "queue_id"
+    bitwidth: 8
+  }
+}
+
+controller_packet_metadata {
+  preamble {
+    id: 2868941301
+    name: "packet_in"
+    annotations: "@controller_header(\"packet_in\")"
+  }
+  metadata {
+    id: 1
+    name: "ingress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "is_clone"
+    bitwidth: 1
+  }
+}
+

Note that the use of @controller_header is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages. +

6.4.7. ValueSet

+

ValueSet messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P416 +specification [39]. +

+

The ValueSet message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Value +Set. +

  • +
  • +

    match, a repeated field of MatchField messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the match_fields repeated field in the +Table message. +

  • +
  • +

    size, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +value_set constructor call. +

+ +

According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of bit<W>, +tuple, or struct [26]. The rest of this section looks at all 3 of +these cases and gives an example ValueSet message when appropriate. +

+
    +
  1. +

    If the type parameter is bit<W>, match will include exactly one +MatchField message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used): +

    +
      +
    • id: set to 1 +
    • +
    • bitwidth: set to the value of W +
    • +
    • match_type: set to EXACT +
    +
+ +
+
+
@id(1) value_set<bit<8> >(4) pvs;
+select (hdr.f8) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    bitwidth: 8
+    match_type: EXACT
+  }
+  size: 4
+}
+
    +
  1. +

    If the type parameter is a tuple, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program. +

  2. +
  3. +

    If the type parameter is a struct, this version of P4Runtime requires that +all the fields of the struct be of type bit<W> (where W can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +match field will include one MatchField message for each field in the +struct, with the following fields: +

    +
      +
    • id: must be unique with respect to the other match entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +@id annotation, or let the compiler choose them. +
    • +
    • name: set to the name of the corresponding struct field. +
    • +
    • annotations: set to the list of P4 annotations associated with the struct +field, except for the @match annotation, if present (see the match field +below). +
    • +
    • bitwidth: set to the value of W for the corresponding struct field. +
    • +
    • type_name, which indicates whether the struct field has a user-defined +type; this is useful for +translation. +
    • +
    • match: by default match_type is set to EXACT; the P4 programmer can +specify a different match type by using the @match annotation +[26]. +
    • +
    • doc: documentation associated with the struct field. +
    +
+ +
+
+
struct match_t {
+  @id(1) bit<8> f8;
+  @id(2) @match(ternary) bit<16> f16;
+  @id(3) @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

In the above example, the @id annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs. +

+

Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a user-defined +type that resolves to a bit<W>, or a struct where +one or more fields is a user-defined type that +resolves to a bit<W>. For each MatchField that corresponds to a user-defined +type, the type_name field must be set to the appropriate value (i.e. the name +of the type). +

6.4.8. Register

+

Register messages are used to specify all possible instances of Register PSA +externs. +

+

Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime. +

+

The Register message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this register +instance. +

  • +
  • +

    type_spec, which specifies the data type stored by this register, expressed +using a P4DataTypeSpec message (see section on Representation of Arbitrary +P4 Types). +

  • +
  • +

    size, an int32 value representing the total number of independent register +cells available. +

  • +
  • +

    index_type_name, which indicates whether the register index has a +user-defined type. This is useful for +translation. The underlying built-in type +must be a fixed-width unsigned bitstring (bit<W>). +

+

6.4.9. Digest

+

Digest messages are used to specify all possible instances of Packet Digest +PSA externs. +

+

A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages. +

+

The Digest message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this digest +instance. +

  • +
  • +

    type_spec, which specifies the data type of an individual digest +notification using a P4DataTypeSpec message (see section on Representation +of Arbitrary P4 Types). +

+

6.4.10. Extern

+

Extern messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one Extern message instance in P4Info. The Extern message defines +the following fields: +

+
    +
  • +

    extern_type_id, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the reserved +range [0x81, 0xfe]. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture. +

  • +
  • +

    extern_type_name, which specifies the fully-qualified P4 name of the extern +type. +

  • +
  • +

    instances, a repeated field of ExternInstance Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +ExternInstance in turn defines the following fields: +

    +
      +
    • preamble, a Preamble message with the ID, name, and alias of this digest +instance. +
    • +
    • info, an Any Protobuf message [31] which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for info should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on Extending +P4Runtime for non-PSA Architectures for more +information. +
    +
+ +

If the P4 program does not include any instance of a given extern type, the +Extern message instance for that type should be omitted from the P4Info. +

6.5. Support for Arbitrary P4 Types with P4TypeInfo

+

See section on Representation of Arbitrary P4 +Types. +

7. P4 Forwarding-Pipeline Configuration

+

The ForwardingPipelineConfig captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the “Device Configuration” and sometimes also referred to as +the “P4 Blob”. It is defined as: +

+
+
+
message ForwardingPipelineConfig {
+  config.P4Info p4info = 1;
+  bytes p4_device_config = 2;
+  message Cookie {
+    uint64 cookie = 1;
+  }
+  Cookie cookie = 3;
+}
+

The p4info field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic. +

+

The p4_device_config is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new ForwardingPipelineConfig on that target. +

+

The cookie field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a GetForwardingPipelineConfig RPC. +When writing the config via a SetForwardingPipelineConfig RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present. +

8. General Principles for Message Formatting

8.1. Set / Unset Protobuf Field

+

In Protobuf version 3 (proto3), the default value for a message field is +“unset” [4]. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +CounterEntry message, an “unset” index field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the index message field is +set, a single entry will be read. +

+

Let's look at the counter example in more details. Based on this specification +document, the C++ server code which processes CounterEntry messages may look +like this: +

+
+
+
auto *counter_entry = ...
+if (counter_entry->has_index()) {
+  auto index = counter_entry->index().index();
+  read_one_entry(counter_entry->id(), index);
+} else {
+  read_all_entries(counter_entry->id());
+}
+
    +
  1. +

    Reading a single counter entry at index 0 in the counter array with id +<id>: +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
      +entry.mutable_index();
      +// The above line sets the index field; it is equivalent to:
      +// auto *index = entry.mutable_index();
      +// index->set_index(0);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
      +index {}
    • +
    • Expected behavior: Counter entry at index 0 is read. Notice that the +index subfield is missing under the index field message of +CounterEntry in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages. +
    +
  2. +
  3. +

    Reading all counter entries by leaving the index field unset +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
    • +
    • Expected behavior: All counter entries for the provided counter +instance are read. Notice that the index message field is unset (default +value) and is therefore omitted from the textual representation of the +message. +
    +
+

8.2. Read-Write Symmetry

+

The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example: +

+
+
+
intended_value = value
+
+status = server.write(intended_value, p4_entity)
+observed_value = server.read(p4_entity)
+
+assert(intended_value == observed_value)
+

To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If Read RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol's complexities to the client implementations. +

+

In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the match fields in a TableEntry message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +MessageDifferencer class [36] included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance. +

8.3. Zero as Reserved Value

+

p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a uint32. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a WriteRequest or a SetForwardingPipelineConfigRequest. +

8.4. Bytestrings

+

P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (bit<W>) or signed (int<W>), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +bytes Protobuf type. The correct bitwidth as per the P4 program of +each integer variable exposed through P4Runtime is specified in the P4Info +message. +

+

The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals: +

+
    +
  • +

    It ensures that a properly encoded binary string's integer value conforms +to the P4Info-specified bitwidth. +

  • +
  • +

    It supports read-write symmetry. +

  • +
  • +

    It helps facilitate non-disruptive P4 program updates. +

+ +

In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type bit<W> and/or int<W>. +

+

Note that this representation does not make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range. +

+

In the P4Runtime API version 1.0, values of table key fields, action parameters, +and fields in packet-in and packet-out headers between a device and the +controller (see 6.4.6), may not be of type int<W>. +The rules for encoding signed values thus only apply to messages of type +P4Data (see 8.5.3). +

+

For a value of type bit<W>, the fewest number of bits required to represent +the integer value $V > 0$ is the smallest integer $A$ such that $V \leq 2^A -1$. +

+

For a value of type int<W>, the fewest number of bits required to represent +the integer value $V \neq 0$ in 2's complement form is the smallest integer $A$ +such that $-2^{A-1} \leq V \leq 2^{A-1} - 1$. +

+

As a special case, define that the value $V=0$ requires at least $A=1$ bit to +represent, regardless of whether it is signed or unsigned. +

+

The shortest possible binary string for an integer $V$ that needs $A$ bits to +represent it is computed as: +

+
+
+
minimum_string_size = floor((A + 7) / 8)
+

Binary strings with the byte length computed as minimum_string_size promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies. +

+

Any additional bits in the bytes sent for an unsigned integer value (type +bit<W>) must be 0. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with 0. +

+

Any additional bits in the bytes sent for a signed integer value (type int<W>) +must be copies of the sign bit, i.e. 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with copies of the +sign bit, i.e. 0 for non-negative values, or 0xff for negative values. In 2's +complement representation, this is called “sign extension”, and leaves the +numeric value represented unchanged. +

+

Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value. +

+

For a received bitstring expected to fit within a bit<W> type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring's width is W bits or less. +

+

For a received bitstring expected to fit within an int<W> type, the value it +represents is in range if, after “undoing sign extension”, the remaining bit +string's width is W bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other. +

+

If the string's byte length is zero, the server always rejects the string. +

+

When the server rejects a binary string due to any of the previous criteria, +it returns an OUT_OF_RANGE error. +

+

For all binary strings, P4Runtime uses big-endian (i.e. network) byte-order. +For signed integer values (int<W> P4 type), P4Runtime uses the same two's +complement bitwise representation as P4. Table 4 +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above. +

+
+ + + + + + + + + + + + + + + + + +
P4 type Integer value P4Runtime binary string Read-write symmetry
bit<8> 99 (0x63) \x63 yes
bit<16> 99 (0x63) \x00\x63 no
bit<16> 99 (0x63) \x63 yes
bit<16> 12388 (0x3064) \x30\x64 yes
bit<16> 12388 (0x3064) \x00\x30\x64 no
bit<12> 99 (0x63) \x00\x63 no
bit<12> 99 (0x63) \x63 yes
bit<12> 99 (0x63) \x00\x00\x63 no
int<8> 99 (0x63) \x63 yes
int<8> -99 (-0x63) \x9d yes
int<8> -99 (-0x63) \xff\x9d no
int<12> -739 (-0x2e3) \xfd\x1d yes
int<16> 0 (0x0) \x00\x00 no
int<16> 0 (0x0) \x00 yes
+
+ +
Table 4. Examples of Valid Bytestring Encoding
+

Table 5 shows some examples of invalid +P4Runtime binary strings: +

+
+ + + + + + + + + + + + +
P4 type P4Runtime binary string
bit<8> \x01\x63
bit<8> empty string
bit<16> \x01\x00\x63
bit<12> \x10\x63
bit<12> \x01\x00\x63
bit<12> \x00\x40\x63
int<8> \x00\x9d
int<12> \x8d\x1d
int<16> empty string
+
+ +
Table 5. Examples of Invalid Bytestring Encoding
+

As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from bit<8> to bit<9>, a server +running the bit<9> version of the P4 program will accept requests from +clients that remain on the bit<8> P4Runtime version. +

+

Despite the server's binary string flexibility for P4 program update support, +the client and server must both remain aware of the +read-write symmetry +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values. +

+

Representation of variable-length integer values (varbit<W> P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the dynamic-length of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an OUT_OF_RANGE error code otherwise. +

8.5. Representation of Arbitrary P4 Types

8.5.1. Problem Statement

+

The P416 language includes more complex types than just binary strings +[3]. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table 6 shows the different +P416 types and how they are allowed to be used, as per the P416 +specification. +

+
+ + + + + + + + + + + + + + + + + + + +
Container type
Element type header header_union struct or tuple
bit<W> allowed error allowed
int<W> allowed error allowed
varbit<W> allowed error allowed
int error error error
void error error error
error error error allowed
match_kind error error error
bool error error allowed
enum allowed1 error allowed
header error allowed allowed
header stack error error allowed
header_union error error allowed
struct error error allowed
tuple error error allowed
+
+ +
Table 6. P4 Type Usage
+

For example, the following P416 objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects. +

+
+
+
Digest<tuple<bit<4>, bit<8> > >() digest_complex;
+digest_complex.pack({ hdr.ipv4.version, hdr.ipv4.protocol });
+// ...
+header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

One solution would be to use only binary string (bytes type) in +p4runtime.proto and to define a custom serialization format for complex P416 +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P416 types. +

8.5.2. P4 Type Specifications in p4info.proto

+

In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type ip_t, which is a header union with 2 possible headers: +ipv4 with type ipv4_t and ipv6 with type ipv6_t. Similarly, they need to +know the field layout for both of these header types. +

+

To achieve this we introduce 2 main Protobuf messages: P4TypeInfo and +P4DataTypeSpec. +

+

P4TypeInfo is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P416 program. These +named types are struct, header, header_union, enum and +serializable_enum; for each of these we have a type specification message, +respectively P4StructTypeSpec, P4HeaderTypeSpec, P4HeaderUnionTypeSpec, +P4EnumTypeSpec and P4SerializableEnumTypeSpec. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. P4TypeInfo also includes the list of parser errors for the program, as +a P4ErrorTypeSpec message. +

+

P4DataTypeSpec is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each P4DataTypeSpec message corresponds to a compile-time type in the +original P416 program (e.g. the type parameter of an extern). This +compile-time type is represented as a Protobuf oneof, which can be: +

+
    +
  • +

    a string representing the name of the type in case of a named type (struct, +header, header_union, enum, serializable_enum or user-defined “new” +type), +

  • +
  • +

    an empty Protobuf message for bool and error, or +

  • +
  • +

    a Protobuf message for other anonymous types (bit<W>, int<W>, varbit<W>, +tuple or stack). The “binary string” types (bit<W>, int<W>, and +varbit<W>) are grouped together in the P4BitstringLikeTypeSpec message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf bytes +type). +

+ +

For all P416 compound types (tuple, struct, header, and header_union), +the order of members in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P416 declaration. The same goes for the order of members of an enum +(serializable or not) or members of error. +

8.5.3. P4Data in p4runtime.proto

+

P4Runtime uses the P4Data message to represent values of arbitrary types. The +P4Runtime client must generate correct P4Data messages based on the type +specification information included in P4Info. The P4Data message was designed +to introduce little overhead compared to using binary strings in the most common +case (P416 bit<W> type). +

+

Just like its P4Info counterpart - P4DataTypeSpec -, P4Data uses a Protobuf +oneof to represent all possible values. +

+

We define a canonical representation for P4Data messages therefore +guaranteeing read-write symmetry by introducing the following requirements: +

+
    +
  • +

    The order of members in P4StructLike and the order of bitstrings in +P4Header must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P416 type +declaration. +

  • +
  • +

    An invalid header is represented by a P4Header message where the is_valid +field is false and the bitstrings repeated field is empty. +

  • +
  • +

    An invalid header union (i.e. all headers in the union are invalid) is +represented by a P4HeaderUnion message where the valid_header_name is the +empty string (default value for the field) and the valid_header is unset. +

  • +
  • +

    The order of entries in P4HeaderStack and P4HeaderUnionStack is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the entries field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding P4HeaderStackTypeSpec or +P4HeaderUnionStackTypeSpec message. +

+

8.5.4. Example

+

Let's look at the Register example again: +

+
+
+
header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

Here's the corresponding entry in the P4Info message: +

+
+
+
registers {
+  preamble {
+    id: 369119267
+    name: "register_ip"
+    alias: "register_ip"
+  }
+  type_spec {
+    header_union {
+      name: "ip_t"
+    }
+  }
+  size: 128
+}
+type_info {
+  headers {
+    key: "ipv4_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  headers {
+    key: "ipv6_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  header_unions {
+    key: "ip_t"
+    value {
+      members {
+        name: "ipv4"
+        header {
+          name: "ipv4_t"
+        }
+      }
+      members {
+        name: "ipv6"
+        header {
+          name: "ipv6_t"
+        }
+      }
+    }
+  }
+}
+

Here's a p4.WriteRequest to set the value of register_ip[12]: +

+
+
+
update {
+  type: INSERT
+  entity {
+    register_entry {
+      register_id: 369119267
+      index {
+        index: 12
+      }
+      data {
+        header_union {
+          valid_header_name: "ipv4"
+          valid_header {
+            is_valid: true
+            bitstrings: "\x04"
+            bitstrings: # ...
+          }
+        }
+      }
+    }
+  }
+}

8.5.5. enum, serializable enum and error

+

P416 supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or “unsafe” enum) +[5]. For enum types with no underlying type as well as error +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in P4Data to represent enum and +error values. +

+

Serializable enum types have an underlying fixed-width unsigned integer +representation (bit<W>). All named enum members must be assigned an integer +value by the P4 programmer, but not all valid numeric values for the +underlying type need to have a corresponding name. P4TypeInfo includes the +mapping between entry name and entry value. When providing serializable enum +values through P4Data, one must use the assigned integer value (enum_value +bytestring field). P4Runtime does not provide a way for the client to use the +name even when the enum member has one instead of the value, as it makes +it easier for the server to respect the read-write +symmetry principle. +

8.5.6. User-defined types

+

P416 enables programmers to introduce new types [11]. While similar +to typedef, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +translation. When introducing a new type, the +declaration can be annotated with @p4runtime_translation to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for port numbers, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. The @p4runtime_translation annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (bit<W>). The type exposed to the control plane (referred to as the +controller_type) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a URI (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the controller_type of the values exposed to the control plane. The +controller_type can be either bit<W> where W is any positive integer, or +string, or a positive integer W which has the same meaning as bit<W>. +Specifying just an integer is deprecated. +

+

It is recommended that the URI includes at least the P4 architecture name and +the type name. +

+

A @p4runtime_translation annotation need not have any effect if it is used to +annotate anything in a P4 program other than a type declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect. +

+

User-defined types are specified using the P4NewTypeSpec message, which has +the following fields: +

+
    +
  • +

    representation, a Protobuf oneof specifying how values of this type are +exchanged between client and server; it can be either: +

    +
      +
    • +

      original_type, if and only if no @p4runtime_translation annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 type declaration is itself a +user-defined type, original_type is obtained by “walking” the chain of +type declarations recursively until a built-in type (e.g. bit<W>) is +found. +

    • +
    • +

      translated_type, if and only if the P4 type declaration was annotated +with @p4runtime_translation. It is of type P4NewTypeTranslation, +which itself has two fields uri and either sdn_string or +sdn_bitwidth , which map to the two input parameters to the +annotation. +

    +
  • +
  • +

    annotations, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration. +

+ +

For example, an architecture in this case PSA may introduce a new type +for port numbers: +

+
+
+
// Controller refers to ports as a string, e.g. "eth0".
+@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+// Controller refers to ports as a 32-bit integer, e.g. 0xffffffff.
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+// Same as above.
+@p4runtime_translation("p4.org/psa/v1/PortId_32_t", 32)
+type bit<9> PortId_32_t;
+

In this case, the P4Info message would include the following P4TypeInfo +messages: +

+
+
+
type_info {
+  new_types {
+    key: "PortId_String_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_String_t"
+        sdn_string: {}
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_Bit32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_Bit32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+

Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (e.g. through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over @p4runtime_translation to enable users +to overwrite annotations included as part of the P4 architecture definition. +

8.5.7. Trade-off for v1.x Releases

+

For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +bytes with P4Data in the p4.v1.FieldMatch message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +bytes to provide action parameter values and controller metadata +values. However P4Data is used whenever appropriate for PSA externs and we +encourage the use of P4Data in architecture-specific extensions. +

+

In order to support translation for action +parameters and match fields, we include a type_name field in +p4.config.v1.MatchField, p4.config.v1.Action.Param and +p4.config.v1.ControllerPacketMetadata.Metadata. In addition, the bitwidth +field for all of these message types must abide by the following rule when +type_name names a translated user-defined type: +

+
    +
  • +

    If the controller_type is a fixed-width unsigned bitstring, the bitwidth +field must be set to the bitwidth of the controller_type. This information +is redundant with the one included in the P4TypeInfo entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent. +

  • +
  • +

    Otherwise (i.e., if the controller_type is a string), the bitwidth must +be “unset”, which, in Protobuf version 3, is the same as setting the field to +0. +

+ +

For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types: +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+@name(".t")
+table t {
+  key = {
+    meta.port1: exact;  // meta.port1 has type PortId_String_t
+    meta.port2: exact;  // meta.port2 has type PortId_Bit32_t
+  }
+  actions = {
+    drop;
+  }
+}
+

This table would have the following representation in the generated P4Info +message: +

+
+
+
tables {
+  preamble {
+    id: 34728461
+    name: "t"
+    alias: "t"
+  }
+  match_fields {
+    id: 1
+    name: "meta.port1"
+    # notice that bitwidth is unset
+    match_type: EXACT
+    type_name {
+      name: "PortId_String_t"
+    }
+  }
+  match_fields {
+    id: 2
+    name: "meta.port2"
+    bitwidth: 32
+    match_type: EXACT
+    type_name {
+      name: "PortId_Bit32_t"
+    }
+  }
+  # ...
+}

9. P4 Entity Messages

+

P4Runtime covers P4 entities that are either part of the P416 language, or +defined as PSA externs. The sections below describe the messages for each +supported entity. +

9.1. TableEntry

+

The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action's +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification. +

+

P4Runtime supports inserting, modifying, deleting and reading table entries with +the TableEntry entity, which has the following fields: +

+
    +
  • +

    table_id, which identifies the table instance; the table_id is determined +by the P4Info message. +

  • +
  • +

    match, a repeated field of FieldMatch messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration. +

  • +
  • +

    action, which indicates which of the table's actions to execute in case of +match and with which argument values. +

  • +
  • +

    priority, a 32-bit integer used to order entries when the table's match key +includes an optional, ternary or range match. +

  • +
  • +

    controller_metadata, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +metadata field. +

  • +
  • +

    metadata, an arbitrary bytes value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. +

  • +
  • +

    meter_config, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    counter_data, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    is_default_action, a boolean flag which indicates whether the table entry is +the default entry for the table. See Default entry +section for more information. +

  • +
  • +

    idle_timeout_ns and time_since_last_hit, which are two fields used to +implement idle-timeout support for the table, if applicable. See +Idle-timeout section for more information. +

+ +

The priority field must be set to a non-zero value if the match key includes a +ternary match (i.e. in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an OPTIONAL, TERNARY or +RANGE match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches. +

+

The match and priority fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for MODIFY and DELETE updates. When deleting +an entry, these key fields (along with is_default_action) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a keyless +table (the table has an empty match key), the server must reject all attempts to +INSERT a match entry and return an INVALID_ARGUMENT error. +

+

The number of match entries that a table should support is indicated in P4Info +(size field of Table message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P416 specification for the +size property [30]. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +RESOURCE_EXHAUSTED when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached. +

9.1.1. Match Format

+

The bytes fields in the FieldMatch message follow the format described in +Bytestrings. +

+

For “don't care” matches, the P4Runtime client must omit the field's entire +FieldMatch entry when building the match repeated field of the TableEntry +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for “don't care” matches, which is needed +to ensure read-write symmetry. For PSA match types, +a “don't care” match for a specific match key field is defined as follows: +

+
    +
  • +

    For a TERNARY match, it is logically equivalent to a mask of zeros. +

  • +
  • +

    For a OPTIONAL match, it is logically equivalent to a wildcard match. +

  • +
  • +

    For an LPM match, it is logically equivalent to a prefix_len of zero. +

  • +
  • +

    For a RANGE match, it is logically equivalent to a range which includes all +possible values for the field. +

+ +

Note that there is no “don't care” value for EXACT matches and therefore exact +match fields can never be omitted from the TableEntry message. +

+

The following example shows a P4Runtime message that treats a TERNARY field +as a “don't care” match. The P4 program defines table t with TERNARY +and EXACT fields in its match key: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: ternary;
+    istd.ingress_port: exact;
+  }
+  actions = {
+    drop;
+  }
+}
+

In this P4Runtime request, the client omits the table's TERNARY field +from the repeated match field to indicate a “don't care” match. As shown +below, the match specifies only the EXACT field given by field_id: 2. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 33554439  # Table t's ID.
+    match {
+      # field_id 1 is not present to use the don't care ternary value.
+      field_id: 2
+      exact {
+        value: "\x20"
+      }
+    }
+    action {
+      # Action selection goes here.
+    }
+  }
+}
+

For every member of the TableEntry repeated match field, field_id must be +a valid id for the table, as per the P4Info, and one of the fields in +field_match_type must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an INVALID_ARGUMENT error code. +

+
    +
  • EXACT match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.exact().value()))
+
    +
  • LPM match + +
      +
    • The binary string encoding of the value (when present) must conform to the +Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • “Don't care” bits must be 0 in value. +
+ +
+
+
assert(BytestringValid(match.lpm().value()))
+
+pLen = match.lpm().prefix_len()
+assert(pLen > 0)
+
+trailing_zeros = countTrailingZeros(match.lpm().value())
+assert(trailing_zeros >= field_bits - pLen)
+
    +
  • TERNARY match + +
      +
    • The binary string encoding of the value (when present) and mask (when +present) must conform to the Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • Masked bits must be 0 in value. This constraint taken together +with the Bytestrings requirements means that the +value's binary string is never longer than the mask's binary string. +When the value's string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask. +
+ +
+
+
assert(BytestringValid(match.ternary().value()))
+assert(BytestringValid(match.ternary().mask()))
+assert(match.ternary().value().size() <= match.ternary().mask().size());
+
+value = parseInteger(match.ternary().value())
+mask = parseInteger(match.ternary().mask())
+
+assert(mask != 0)
+
+assert(value & mask == value)
+
    +
  • RANGE match + +
      +
    • The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the Bytestrings +requirements. +
    • +
    • Low bound must be less than or equal to the high bound. +
    • +
    • “Don't care” match must be omitted. +
+ +
+
+
assert(BytestringValid(match.range().low()))
+assert(BytestringValid(match.range().high()))
+
+low = parseInteger(match.range().low())
+high = parseInteger(match.range().high())
+
+assert(low <= high)
+
+assert(low != min_field_value || high != max_field_value)
+
    +
  • OPTIONAL match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.optional().value()))

9.1.2. Action Specification

+

The TableEntry action field must be set for every INSERT update but may be +left unset for MODIFY updates, in which case the action specification for the +table entry will not be modified (if a MODIFY update has an unset action field +and does not modify any direct resource attached to the table then the MODIFY +update is a no-op). Based on the implementation property value of the P4 table, +the oneof in the TableAction message will either be: +

+
    +
  • +

    an Action specification for direct tables (with no P4 implementation +property) +

  • +
  • +

    an action profile member id for indirect tables for which the implementation +property is an action profile with no selector. +

  • +
  • +

    an action profile member id or group id for indirect tables for which the +implementation property is an action profile with selector. +

  • +
  • +

    an ActionProfileActionSet specification for indirect tables for +which the implementation property is an action profile with +selector. This usage is described in One Shot Action Selector +Programming +

+ +

If the oneof does not match the table description in the P4Info (e.g. the +oneof is action_profile_member_id for a direct table), the server must +return an INVALID_ARGUMENT error code. +

+

The Action Protobuf message has the following fields: +

+
    +
  • +

    action_id, which identifies the action instance; the action_id is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an INVALID_ARGUMENT error +code. If the client uses a valid action_id for the table but does not +respect the action scope specified in P4Info (e.g. tries to set a TABLE_ONLY +action as the default action), the server must return a PERMISSION_DENIED +error code. +

  • +
  • +

    params: a repeated Protobuf field of action parameter values, each encoded +as a Param message. For each parameter, param_id must be valid for the +action (as per the P4Info) and value must follow the format described in +Bytestrings. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an INVALID_ARGUMENT error code +if a parameter id is missing, if an extra parameter id not found in the +P4Info was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +Bytestrings format. +

+ +

For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a NOT_FOUND error code. +

9.1.3. Default Entry

+

According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer or defaults to NoAction +(which is a no-op) otherwise and assuming it is not declared as const, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow INSERT and DELETE updates on the default entry and the +P4Runtime server must return an INVALID_ARGUMENT error code if the client +attempts one. +

+

The default entry is identified by setting the is_default_action boolean field +to true. When this flag is set to true, the repeated match field must be empty +and the priority field must be set to zero, otherwise the P4Runtime server +must return an INVALID_ARGUMENT error code. When performing a MODIFY update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its controller_metadata and metadata value as well as the +configurations for its direct resources will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a PERMISSION_DENIED +error code if the client attempts to modify it. +

+

Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to direct resources. +

+

In this P4Runtime release, we have decided to restrict the default entry for +indirect tables tables with an ActionProfile or ActionSelector +implementation property to a constant NoAction action entry, with the +hope that it would simplify the implementation of the P4Runtime service. +

9.1.4. Constant Tables

+

Constant tables are defined as tables whose match entries are immutable. They +are identified by the is_const_table flag in P4Info. +

+

The only write updates which are allowed for constant tables are MODIFY +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +PERMISSION_DENIED error. Just like any table entry MODIFY request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a PERMISSION_DENIED error. +

+

The contents of const tables can be queried by the client through a +ReadRequest. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: table_id, match, action, +is_default_action, and priority (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the priority field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P416 does not support assigning explicit priorities to static +entries. When a priority value is required (e.g. for tables including RANGE, +TERNARY or OPTIONAL matches), it is inferred based on the order in which +entries appear in the table declaration. +

9.1.5. Wildcard Reads

+

When performing a ReadRequest, the P4Runtime client can select all entries +from one or all tables on the target and use several of the TableEntry fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as priority and “unset” for message fields such as match. The following +fields may be used to select and filter results: +

+
    +
  • table_id: If default (0), entries from all tables including constant +tables will be selected and no other filter can be used. Otherwise only +the specified table will be considered. +
  • +
  • match: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned. +
  • +
  • action: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an action_id (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id. +
  • +
  • priority: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value. +
  • +
  • controller_metadata: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +controller_metadata value. +
  • +
  • metadata: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided metadata value. +
  • +
  • is_default_action: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered. +
+ +

For example, in order to read all entries from all tables from device 3, the +client can use the following ReadRequest message. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0
+    priority: 0
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following ReadRequest +message: +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+    priority: 11
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

The canonical representation of “don't care” matches, combined with the ability +to do a wildcard read on all table entries by leaving the match field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single “don't care” entry or to do a wildcard +read. If a table has no fields with match kind EXACT, it is possible via +P4Runtime to add an entry that is “don't care” for all fields (i.e. has an empty +match field) but is not the default entry (i.e. is_default_action is +false). When reading this entry from the table, there is no way to read only +that entry from the table, because it would require providing an unset match +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single LPM match: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: lpm;
+  }
+  actions = {
+    drop; fwd;
+  }
+}
+

The following WriteRequest message can be used to add 2 entries: +

+
+
+
device_id: 3
+entities {
+  table_entry { # don't care entry
+    table_id: 0x0212ab34
+    # ...
+  }
+  table entry {
+    table_id: 0x0212ab34
+    match {
+      field_id: 1
+      lpm {
+        value: 0x0a000000
+        prefix_len: 8
+      }
+    # ...
+  }
+}
+

The first entry is a “don't care” entry, while the second one matches all +10.0.0.0/8 addresses. The second entry has higher priority than the first one. +

+

The following ReadRequest message will return all entries in the table, not +just the “don't care” entry. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+  }
+}
+

This issue also exists for tables with TERNARY, RANGE, and OPTIONAL +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the “don't care” entry will be returned to the +client. If the client uses distinct priority values for all entries which is +strongly recommended to achieve deterministic behavior , +then there is no ambiguity because the wildcard read will actually return a +single entry (the “don't care” entry) as long as the priority field is set to +the correct value. +

9.1.6. Direct Resources

+

In addition to the DirectCounterEntry and DirectMeterEntry entities, +P4Runtime support reading and writing direct resources as part of the +TableEntry message. This is convenient for two reasons: +

+
    +
  • +

    A table entry and its direct resources can be read with a single entity when +doing a Read RPC call +

  • +
  • +

    The initial configuration for an entry's direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can “hit” the table entry without +executing the appropriate meter entry. +

+ +

Once the table entry has been inserted, the P4Runtime client is free to use the +DirectCounterEntry and DirectMeterEntry messages for read and write +operations on DirectCounter and DirectMeter instances. For example, it is +usually more convenient as well as more efficient to use DirectCounterEntry to +query a counter entry value rather than use TableEntry, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry. +

+

The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does not need to be “executed” in +every action bound to the table. It is an error to provide a direct resource +configuration in a TableEntry message when programming an action that does not +execute the direct resource, and the server must return an INVALID_ARGUMENT +error code. +

+

We leverage Protobuf's ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the TableEntry message. The list below describes how +the server must handle the meter_config and counter_data fields for read and +write requests, based on whether the fields are set or not. We do not cover +error cases in the list, i.e. we assume that we are dealing with a table which +is assigned a direct counter / a direct meter, and that the action being used +for the table entry “executes” the direct resource appropriately. +

+
    +
  • +

    meter_config field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets). +
      • +
      • if set: The initial configuration for the meter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The meter entry's configuration is reset to the default +(meter returns GREEN for all packets). +
      • +
      • if set: The value provided by the client is used to re-configure +the meter entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the meter entry's +configuration (meter_config is unset in the response). +
      • +
      • if set: If the meter entry's configuration is the default +configuration, meter_config is unset in the response. Otherwise, the +response includes the meter entry's configuration that was written by +the client earlier. This respects the “read-write symmetry” principle. +
    +
  • +
  • +

    counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for the counter entry is the default +(0). +
      • +
      • if set: The initial value for the counter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The counter entry's value is not changed. +
      • +
      • if set: The value provided by the client is written to the counter +entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the counter entry's value +(counter_data is unset in the response). +
      • +
      • if set: The response includes the counter entry's value read from +the target. +
    +
+ +

In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +meter_config field unset when inserting or modifying a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the TableEntry message +(i.e. the meter_config field must be set to match the existing configuration). +

9.1.7. Idle-timeout

+

P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not “hit” (i.e. not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification using the +IdleTimeoutNotification message to the master client, which can then take +action, such as remove the idle table entry. +

+

Two fields of the TableEntry Protobuf message are used to implement idle +timeout: +

+
    +
  • +

    idle_timeout_ns: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, i.e. no +IdleTimeoutNotification message will ever be generated for this entry. When +a client reads a TableEntry, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry. +

  • +
  • +

    time_since_last_hit: a Protobuf message with a single field (elapsed_ns) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The time_since_last_hit field must be unset for a +TableEntry write. When reading a table entry, time_since_last_hit must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0. +

+ +

These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an INVALID_ARGUMENT error code if at least one of these +conditions is met: +

+
    +
  • idle_timeout_ns is set to a non-zero value, or +
  • +
  • time_since_last_hit is set +
+ +

The target should do its best to approximate the idle_timeout_ns value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the TableEntry write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for time_since_last_hit. +

+

P4Runtime does not support idle timeout for default entries. When the +is_default_action flag is set in a TableEntry message, idle_timeout_ns +must be set to 0 (default) and time_since_last_hit must be unset. If the +server receives a TableEntry message which violates this, it must return an +INVALID_ARGUMENT error. +

+

For more information about idle timeout, in particular regarding +IdleTimeoutNotification, please refer to the Table idle timeout +notifications section. +

9.2. ActionProfileMember & ActionProfileGroup

+

P4Runtime defines an API for programming a PSA ActionProfile extern using +ActionProfileMember messages. A PSA ActionSelector extern can be programmed +using both ActionProfileMember and ActionProfileGroup messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table t for L3 routing, implemented with an action +selector as. +

+
+
+
ActionSelector(HashAlgorithm.crc32,
+               /*size = */ 32w1024,
+               /*output_width = */ 32w10) as;
+
+action set_nhop(PortId_t p, EthAddr smac, EthAddr dmac) {
+  istd.egress_port = p;
+  hdr.ethernet.smac = smac;
+  hdr.ethernet.dmac = dmac;
+}
+
+table t {
+  key = {
+    hdr.ipv4.dip: lpm;  // LPM on destination IP address
+  }
+  actions = {
+    set_nhop;
+  }
+  implementation = as;
+}
+

When programming table t in the example above, a P4Runtime client should +specify the TableAction in the TableEntry to be a reference to either an +action profile member or group. The reference is a non-zero uint32 identifier +that uniquely identifies a member or group programmed in the action selector +as. +

+

If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata. +

+

If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata. +

9.2.1. Action Profile Member Programming

+

Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a uint32 identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the actions +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the actions attributes of the +tables must have an identical list of P4 actions. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector. +

+

An ActionProfileMember entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info. +

  • +
  • +

    member_id is the non-zero uint32 identifier of the action profile member +entry being updated. +

  • +
  • +

    action is the specification of the P4 action instance bound to the action +profile member entry. +

+ +

An action profile member may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an ALREADY_EXISTS error +code. The action specification must be provided, or the server must return +INVALID_ARGUMENT. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return RESOURCE_EXHAUSTED. +
  • +
  • MODIFY: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return NOT_FOUND, +and the action specification must be provided, or the server must return +INVALID_ARGUMENT. +
  • +
  • DELETE: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a NOT_FOUND error code. The member +must not be part of an action profile group, or the server must return +FAILED_PRECONDITION. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return FAILED_PRECONDITION. action_profile_id and member_id are the only +fields that are considered when performing a DELETE and every other field +will be ignored. +
+ +

When reading, an ActionProfileMember message with action_profile_id and +member_id equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with action_profile_id equal to the id of +an existing ActionProfile or ActionSelector object, and a member_id equal to +0, will read all members of that specified object. +

9.2.2. Action Profile Group Programming

+

Action profile groups are entries in an ActionSelector and are referenced by a +uint32 identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type. +

+

Within a single ActionSelector object, the uint32 values used to identify its +members are in a separate ‘scope’ from the uint32 values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5. +

+

There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it. +

+

An ActionProfileGroup entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionSelector +extern instance, as defined in P4Info. +

  • +
  • +

    group_id is the non-zero uint32 identifier of the action profile group +entry being updated. +

  • +
  • +

    members is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields: +

    +
      +
    • member_id for looking up the member table in the selector. +
    • +
    • weight specifying the probability of the member's selection at +runtime. 0 is not a valid weight value and the server must return +INVALID_ARGUMENT if the client attempts to use it. +
    • +
    • watch is the controller-defined 32-bit port number that the member's +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +9.2.4 for notes on the behavior if all members in +a group are excluded for this reason. If watch is 0, then the member is +always included in the selection, regardless of the status of any port of +the device. The value must be 0 or the SDN port number of an existing +port on the device, otherwise the server must return INVALID_ARGUMENT. +
    +
  • +
  • +

    max_size is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +MODIFY update. See the subsection below for the rules on setting +max_size. +

+ +

An action profile group may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new group entry bound to a set of existing action profile +members. The group_id must be different from ids of already programmed +groups for that selector, or the server must return an ALREADY_EXISTS error +code. All members specified in the group must exist in the selector, or the +server must return NOT_FOUND. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target. +
  • +
  • MODIFY: Modify the member set specification of an existing group entry. An +entry with the group_id must exist, or the server must return +NOT_FOUND. All members specified in the group entry must exist in the +selector, or the server must return NOT_FOUND. The value of max_size must +be identical to the value used when inserting the group, otherwise an +INVALID_ARGUMENT error is returned. +
  • +
  • DELETE: Delete the group entry and deallocate the group_id. The group must +not be referenced in the table action of any table entry, or the server must +return a FAILED_PRECONDITION error code. If the group_id is invalid, the +server must return NOT_FOUND. action_profile_id and group_id are the +only fields that are considered when performing a DELETE and every other +field will be ignored. +
+ +

When setting the group membership with INSERT or MODIFY, the members +repeated field must not include duplicates, i.e. members with the same +member_id. The weight field is used instead to logically “repeat” the member +inside the group. +

+

It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation “stores” the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made. +

+

When reading, an ActionProfileGroup message with action_profile_id and +group_id equal to 0 will read all groups of all ActionSelector objects. A +message with action_profile_id equal to the id of an existing ActionSelector +object, and a group_id equal to 0, will read all groups of that one specified +object. +

9.2.2.1. Rules on Setting max_size
+

The valid values for max_size depend on the static max_group_size included +in the P4Info message: +

+
    +
  • +

    If max_group_size is greater than 0, then max_size must be greater than 0, +and less than or equal to max_group_size. We assume that the target can +support selector groups for which the sum of all member weights is up to +max_group_size, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If max_size is greater than max_group_size, the server +must return INVALID_ARGUMENT. +

  • +
  • +

    Otherwise (i.e. if max_group_size is 0), the P4Runtime client can set +max_size to any value greater than or equal to 0. +

    +
      +
    • +

      A max_size of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (INSERT or MODIFY), the target must return a +RESOURCE_EXHAUSTED error. +

    • +
    • +

      If max_size is greater than 0 and the value is not supported by the +target, the server must return a RESOURCE_EXHAUSTED error at +group-creation time. +

    +
+

9.2.3. One Shot Action Selector Programming

+

P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids. +

+

One shots are programmed by choosing the ActionProfileActionSet message as the +TableAction. The ActionProfileActionSet message consists of a set of +ActionProfileAction messages, which in turn have the following fields: +

+
    +
  • +

    action is one of the actions specified by the table that is being +programmed. +

  • +
  • +

    weight specifying the probability of the action's selection at runtime. 0 is +not a valid weight value and the server must return INVALID_ARGUMENT if +the client attempts to use it. The sum of all weights across all +ActionProfileAction messages for that ActionProfileActionSet message must +not exceed the max_group_size specificed in the P4Info (if greater than 0), +or the server must return INVALID_ARGUMENT. +

  • +
  • +

    watch is the controller-defined 32-bit port number that the action's +liveness depends on. At runtime, the action must be excluded from selection if +the watch port is down. See Section +9.2.2 for more details on the watch field, +which also apply for one shot action selector programming. +

+ +

Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics. +

+

To preserve read-write symmetry, an implementation must answer ReadRequests +with the original one shot messages. It may not return a desugared version of +the one shot message. +

+

For example, consider the action selector table defined +here. This table could be programmed +with the following one shot update: +

+
+
+
table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action {
+    action_profile_action_set {
+      action_profile_actions {
+        action { /* set nexthop 1 */ }
+        weight: 1
+        watch: 1
+      }
+      action_profile_actions {
+        action { /* set nexthop 2 */ }
+        weight: 2
+        watch: 2
+      }
+      action_profile_actions {
+        action { /* set nexthop 3 */ }
+        weight: 3
+        watch: 3
+      }
+    }
+  }
+}
+

Which would be equivalent to the following updates, where GROUP_ID, +MEMBER_ID_1, MEMBER_ID_2, and MEMBER_ID_3 are unused ids: +

+
+
+
action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_1
+  action { /* set nexthop 1 */ }
+}
+action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_2
+  action { /* set nexthop 2 */ }
+}
+action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_3
+  action {  /* set nexthop 3 */ }
+}
+action_profile_group {
+  action_profile_id: 0x11ab12cd
+  group_id: GROUP_ID
+  members {
+    member_id: MEMBER_ID_1
+    weight: 1
+    watch: 1
+  }
+  members {
+    member_id: MEMBER_ID_2
+    weight: 2
+    watch: 2
+  }
+  members {
+    member_id: MEMBER_ID_3
+    weight: 3
+    watch: 3
+  }
+}
+table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action { action_profile_group_id: GROUP_ID }
+}
+

Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure correct ordering between the dependent +updates. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct WriteRequest batches are required. +

+

It is possible to include several ActionProfileAction messages with the same +exact action specification in one ActionProfileActionSet message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the weight field. Note that to preserve read-write symmetry, the server +must not coalesce multiple ActionProfileAction messages with the same action +specification into one. +

+

All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with ActionProfileMember and +ActionProfileGroup messages. Programming some entries with one shots, and +other entries with ActionProfileMember and ActionProfileGroup messages is +not allowed, and the server must return the error code INVALID_ARGUMENT in +that case. +

+

A P4Runtime server must support the one shot style of programming tables with +an action selector implementation. Support for the ActionProfileMember and +ActionProfileGroup style is optional. If ActionProfileMember and +ActionProfileGroup are not supported by a server, it must return an +UNIMPLEMENTED error for every ActionProfileMember or ActionProfileGroup +message that it receives. +

9.2.4. Constraints on action selector programming

+

The PSA specification states that the following features are optional in +action selector implementations [22]: +

+
    +
  1. Support for non-empty groups where in the same group, different members are +bound to different actions. +
  2. +
  3. Predictable data plane behavior when a matched table entry points to an empty +group. +
+ +

For 1., if a client tries to INSERT or MODIFY a group with members bound to +different actions, the server should return UNIMPLEMENTED if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return UNIMPLEMENTED (modifying the action parameter values must be +supported, however). +

+

PSA 1.1 introduces the psa_empty_group_action table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. psa_empty_group_action is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of psa_empty_group_action at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +NoAction. Even when psa_empty_group_action is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of psa_empty_group_action mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming. +

+

The PSA specification includes a discussion on how to implement +psa_empty_group_action in software in the P4Runtime server +[25]. +

+

If a P4Runtime implementation does support psa_empty_group_action, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down. +

+

If a P4Runtime implementation does not support psa_empty_group_action, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down. +

9.3. CounterEntry & DirectCounterEntry

+

PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The CounterData +P4Runtime message can be used for all three types of PSA counters PACKETS, +BYTES and PACKETS_AND_BYTES and consists of the following fields: +

+
    +
  • byte_count is an int64, corresponding to the number of octets. +
  • +
  • packet_count is an int64, corresponding to the number of packets. +
+ +
+
+
message CounterData {
+  int64 byte_count = 1;
+  int64 packet_count = 2;
+}
+

P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of byte_count and packet_count fields, which +is equivalent to specifying the counter type PACKETS_AND_BYTES. Counters may +be defined as direct or indirect (indexed) instances. +

9.3.1. DirectCounterEntry

+

A direct counter is a direct resource associated with a TableEntry (see +Direct Resources). The counter_data field of the +TableEntry message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +DirectCounterEntry message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed. +

+
+
+
message DirectCounterEntry {
+  TableEntry table_entry = 1;
+  CounterData data = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectCounterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match TableEntry.match of the table entry +to which this direct counter entry is associated. If a matching TableEntry +is not found, the server returns the error code NOT_FOUND. +

  • +
  • +

    data is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified. +

+ +

Specifying DirectCounterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read the contents of a +DirectCounter: +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the counter value in the counter_data field of the TableEntry message +(see Direct resources). +

  • +
  • +

    Explicitly request the counter value by including the DirectCounterEntry in +the ReadRequest. The table_entry.match field must match the TableEntry +whose counter is being read. If no such entry is found, the server returns the +error code NOT_FOUND. +

+

9.3.2. CounterEntry

+

An indirect or indexed counter is not associated with a specific TableEntry +and may be updated independently of any action. It may be read or written using +the P4Runtime CounterEntry message whose fields are defined as follows: +

+
    +
  • +

    counter_id is a uint32, the unique identifier for the counter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +the counter array. +

  • +
  • +

    data is a Protobuf message of type CounterData, which represents the +counter value. +

+ +
+
+
message CounterEntry {
+  uint32 counter_id = 1;
+  Index index = 2;
+  CounterData data = 3;
+}
+

The CounterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the counter entries in the +array have default value 0. +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect counter instance whose unique id is counter_id +and array index is specified by index. The counter value is set to the value +specified by the client in the data field. Note that the counter value is +not modified if this Protobuf field is not set. If index is omitted all +counter values in the array will be set to the value provided by the +client. The server must return INVALID_ARGUMENT for a negative index value +and OUT_OF_RANGE if the index value exceeds the size of the counter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a ReadRequest by including a CounterEntry +entity for each of the instances, specifying the counter_id and +index. Wildcard reads are also supported as follows. +

+
    +
  • +

    If the counter_id field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id counter_id. +

+

9.4. MeterEntry & DirectMeterEntry

+

Meters are an advanced mechanism for keeping statistics, involving stateful +“marking” and usually “throttling” of packets based on configured rates of +traffic. The PSA metering function is based on the Two Rate Three Color Marker +(trTCM) defined in RFC 2698 [2]. The trTCM meters an arbitrary packet +stream using two configured rates the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes and +“marks” its packets as GREEN, YELLOW or RED based on the observed rate. +

+

A meter may be configured as a direct or indirect instance, similar to a +counter. The MeterConfig P4Runtime message represents meter configuration. +

+
+
+
message MeterConfig {
+  int64 cir = 1;  // Committed Information Rate
+  int64 cburst = 2;  // Committed Burst Size
+  int64 pir = 3;  // Peak Information Rate
+  int64 pburst = 4;  // Peak Burst Size
+}

9.4.1. DirectMeterEntry

+

A direct meter is a direct resource associated with a TableEntry (see Direct +resources). The meter_config field of the TableEntry +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +DirectMeterEntry message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed. +

+
+
+
message DirectMeterEntry {
+  TableEntry table_entry = 1;
+  MeterConfig config = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectMeterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match the match key of the TableEntry +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching TableEntry is not found, +the server returns the error code NOT_FOUND. +

  • +
  • +

    config is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets). +

+ +

Specifying DirectMeterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read a DirectMeter config. +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the meter config in the meter_config field of the TableEntry +message (see Direct resources). +

  • +
  • +

    Explicitly request the meter configuration by including the DirectMeterEntry +in the ReadRequest. The table_entry.match field must match the +TableEntry whose meter config is being read. If no such entry is found, the +server returns the error code NOT_FOUND. +

+

9.4.2. MeterEntry

+

An indirect or indexed meter is not associated with a specific TableEntry and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime MeterEntry message whose fields are defined as +follows: +

+
    +
  • +

    meter_id is a uint32, the unique identifier for the meter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +a meter array. +

  • +
  • +

    config is a Protobuf message of type MeterConfig, which represents the +meter configuration. +

+ +
+
+
message MeterEntry {
+  uint32 meter_id = 1;
+  Index index = 2;
+  MeterConfig config = 3;
+}
+

The MeterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the meter entries in the +array have a default configuration (GREEN for all packets). +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect meter instance whose unique id is meter_id and +array index is specified by index. The meter is reconfigured using the +config field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the index field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if config is unset). The server must return INVALID_ARGUMENT for a +negative index value and OUT_OF_RANGE if the index value exceeds the size of +the meter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a ReadRequest by including a MeterEntry entity for each +of the instances, specifying the meter_id and index. Wildcard reads are also +supported as follows: +

+
    +
  • +

    If the meter_id field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id meter_id. +

+

9.5. PacketReplicationEngineEntry

+

The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets. +

9.5.1. MulticastGroupEntry

+

Multicasting is achieved in PSA programs by setting the multicast_group +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the MulticastGroupEntry API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example. +

+
+
+
control arp_multicast(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ethernet.isValid() &&
+        hdr.ethernet.eth_type == ETH_TYPE_ARP) {
+      smeta.multicast_group = (MulticastGroup_t) 1;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    multicast_group_entry {
+      multicast_group_id: 1
+      replicas { egress_port: 5 instance: 1 }
+      replicas { egress_port: 12 instance: 2 }
+      replicas { egress_port: 18 instance: 3 }
+      replicas { egress_port: 24 instance: 4 }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +PSA Metadata Translation section. +

+

The egress packets may be distinguished for further processing in the egress +using the instance metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 multicast_group metadata is set to a value that is not +programmed in the PRE, then the packet is dropped. +

+

A multicast group may be inserted, modified or deleted as per the following +semantics. +

+
    +
  • INSERT: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The multicast_group_id field is a uint32 and must be greater +than 0 (see explanation below), or the +P4Runtime server must return an INVALID_ARGUMENT error. The replica +instance ID is also a uint32, and its value may not exceed the maximum +allowed by the target for the EgressInstance_t type (0 is allowed), or the +server must return an INVALID_ARGUMENT error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of both egress_port and instance, or the server +must return INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify the set of replicas for a given multicast group entry, +indexed by the given multicast_group_id. Same restrictions as INSERT apply +here. +
  • +
  • DELETE: Delete the multicast group indexed by the given +multicast_group_id. The replicas need not be provided for this +operation. Any packets with their multicast_group metadata in the data plane +set to the deleted multicast_group_id will be dropped. +
+ +

When reading a multicast group, only multicast_group_id is considered. All +other fields in MulticastGroupEntry are ignored. To perform a wildcard +Read on all configured multicast group entries, the multicast_group_id field +must be set to 0, its default value. +

9.5.1.1. Valid Values for multicast_group_id
+

The PSA specification states that the valid data plane values for multicast +group ids (MulticastGroup_t) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target [24]. This means that, in the absence of +translation, the client must set the multicast_group_id field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special wildcard value which is used to read all the multicast groups +configured in the target, the multicast_group_id field must never be set to 0 +when performing a Write RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value. +

9.5.2. CloneSessionEntry

+

PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +clone_session_id identifier and a boolean flag clone in the packet +metadata. The clone_session_id serves as a handle to the clone attributes, +namely a set replicas of (egress port, instance) pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +CloneSessionEntry API. +

+

The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the clone_low_ttl control block is applied in the ingress +pipeline to create an ingress-to-egress clone. +

+
+
+
control clone_low_ttl(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ipv4.isValid() &&
+        hdr.ipv4.ttl <= LOW_TTL_THRESHOLD) {
+      smeta.clone_session_id = 10w100;
+      smeta.clone = true;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    clone_session_entry {
+      session_id: 100
+      replicas { egress_port: 0xfffffffd instance: 1 } # to CPU
+      class_of_service: 2
+      packet_length_bytes: 4096
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type CloneSessionId_t [24]). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes. +

+

The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port 0xfffffffd; see +Translation of Port Numbers). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port. +

+

If the clone_session_id data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created. +

+

A clone session may be inserted, modified or deleted as per the following +semantics: +

+
    +
  • INSERT: Add a new clone session entry bound to a set of egress ports and +replica IDs. The session_id is a uint32 and must be greater than 0 (see +explanation below), or the P4Runtime +server must return an INVALID_ARGUMENT error. The replica instance ID is +also a uint32, and its value may not exceed the maximum allowed by the +target for the EgressInstance_t type (0 is allowed), or the server must also +return an INVALID_ARGUMENT error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (class_of_service field). This value must be a valid +value for the PSA ClassOfService_t type, which supports runtime translation +by default [24], or the server must return +INVALID_ARGUMENT. See PSA Metadata +Translation for more information. The +packet_length_bytes field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +packet_length_bytes field is 0 (default), no truncation on the clone will be +performed. +
  • +
  • MODIFY: Modify the attributes of a given clone session entry, indexed by the +given clone_session_id. Same restrictions as INSERT apply here. +
  • +
  • DELETE: Delete the clone session indexed by the given +clone_session_id. Other fields need not be provided for this operation. Any +packet with their clone_session_id metadata in the data plane set to the +deleted session_id will no longer be cloned. +
+ +

When reading a clone session, only session_id is considered. All other fields +in CloneSessionEntry are ignored. To perform a wildcard Read on all +configured clone session entries, the session_id field must be set to 0, its +default value. The session_id field can never be equal to 0 in a Write +RPC. If it does, the server must return an INVALID_ARGUMENT error. +

9.5.2.1. Valid Values for session_id
+

The PSA specification states that the valid data plane values for clone +session ids (CloneSessionId_t) range from 0 to the maximum value supported by +the target [24]. Note that unlike for multicast group +ids, 0 is a valid data plane value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special wildcard value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a session_id +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is not enabled, we effectively +“lose” one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (e.g. because the target supports a very +limited number of clone sessions), one can enable translation on +CloneSessionId_t and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id. +

9.6. ValueSetEntry

+

Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the parse_trill_types state. +

+
+
+
state parse_l2 {
+  @id(1) value_set<ETH_TYPE_BITWIDTH>(MAX_TRILL_TYPES) trill_types;
+  extract(hdr.ethernet);
+  select (hdr.ethernet.eth_type) {
+    ETH_TYPE_IPV4: parse_ipv4;
+    ETH_TYPE_IPV6: parse_ipv6;
+    trill_types:   parse_trill_types;
+    _:             reject;
+  }
+}
+

The corresponding entry in the P4Info for this Value Set is: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "trill_types"
+  }
+  match {
+    id: 1
+    bitwidth: <ETH_TYPE_BITWIDTH>
+    match_type: EXACT
+  }
+  size: <MAX_TRILL_TYPES>
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0x22f3 }
+      }
+      match {
+        field_id: 1
+        exact { value: 0x893b }
+      }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the parse_trill_types state. +

+

A ValueSetEntry entity update message has the following fields: +

+
    +
  • +

    value_set_id is the uint32 identifier of the Value Set instance, as +defined in P4Info. +

  • +
  • +

    members is a repeated field of type ValueSetMember. When “selecting” +against a Value Set, every member will be considered and if at least one +“matches”, the corresponding parser transition will be taken. Each +ValueSetMember contains a repeated field of FieldMatch messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a ValueSetMember if and only if +it matches all its FieldMatch messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. FieldMatch messages in a ValueSetEntry follow +the same rules as in a TableEntry. +

+ +

A ValueSetEntry may only be modified. If the update type is INSERT or +DELETE, the server must return an INVALID_ARGUMENT error. If the update type +is MODIFY, the server writes the members given in the repeated field to the +Value Set entry indexed by the given value_set_id. The maximum number of +matches must not exceed the maximum size given by the size field in P4Info of +the Value Set, otherwise the server must return a RESOURCE_EXHAUSTED error. To +empty a Value Set (i.e. restore it to its initial state), the P4Runtime client +can perform a MODIFY update with an empty members repeated field. +

+

To facilitate read-write symmetry, the server must +return an ALREADY_EXISTS error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set. +

+

See Appendix A.3 for a more complex Value Set example. +

9.7. RegisterEntry

+

The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The RegisterEntry P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations. +

+

RegisterEntry has the following fields: +

+
    +
  • +

    register_id, which identifies the PSA Register extern instance which is +being accessed by the client; the register_id is specified by the P4Info +message. +

  • +
  • +

    index, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the RegisterEntry message +used for the request. When an index is provided , the server must validate +its value, and return INVALID_ARGUMENT for a negative index or +OUT_OF_RANGE if the index exceeds the size of the register array. +

  • +
  • +

    data: the data to be written to the array (if RegisterEntry is part of a +WriteRequest message) or the data read from the array (if RegisterEntry is +part of a ReadResponse message). The data field is a P4Data message and +must match the format described by the type_spec field of the corresponding +Register entry in the P4Info, or the server must return an INVALID_ARGUMENT +error. +

+

9.8. DigestEntry

+

A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly. +

+

The DigestEntry P4Runtime entity is used to configure how the device must +generate digest messages. The DigestEntry Protobuf message is not used to +carry digest data, which is done on the StreamChannel bidirectional stream +using the DigestList (digest data sent by the target to the client) and +DigestListAck (digest data acknowledgments sent by the client to the target) +Protobuf messages. +

+

In this section, we refer to the data learned by a single data plane call to +Digest<T>::pack as a “digest message” and we use “digest list” to designate +the list of digest messages bundled by the P4Runtime service in a single +DigestList stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are “duplicate” if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are “distinct” +if they are not duplicate. +

+

DigestEntry has the following fields: +

+
    +
  • +

    digest_id, which identifies the PSA Digest extern instance which emitted the +data; the digest_id is determined by the P4Info message. +

  • +
  • +

    config, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +digest_id; these parameters are: +

    +
      +
    • max_timeout_ns: the maximum server buffering delay in nanoseconds for an +outstanding digest message. +
    • +
    • max_list_size: the maximum digest list size in number of digest +messages sent by the server to the client as a single DigestList +Protobuf message. +
    • +
    • ack_timeout_ns: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data. +
    +
+ +

Here is the significance of the different Update types for DigestEntry: +

+
    +
  • INSERT: Enable server generation of DigestList messages for given digest +instance and use provided configuration parameters. +
  • +
  • MODIFY: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance. +
  • +
  • DELETE: Disable server generation of DigestList messages for given digest +instance. +
+ +

A server should buffer digest messages until either: +

+
    +
  • max_timeout_ns time has passed since the first digest message was added to +the empty buffer, or +
  • +
  • max_list_size distinct digest messages have been received from the +data plane and added to the buffer +
+ +

At which point the server should, with best effort, generate a DigestList +stream message with the buffer contents and send it to the master client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software. +

+

To avoid sending duplicate digest messages across different DigestList +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the master client indicates that it has received the +digest list and acted on it. The server must keep a “cache” containing the set +of all digest messages that have been sent, but not acknowledged yet by the +master client, up-to ack_timeout_ns in the past. The server must delete all +cache entries for a given digest list when they are at least ack_timeout_ns +old or when a matching DigestListAck message (i.e. with the same digest_id +and list_id fields as the DigestList message) is received. +

+

The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged DigestList messages. +

+

When max_timeout_ns is set to 0 and / or max_list_size is set to 1, the +server should, with best effort, generate a DigestList message for every +digest message generated by the data plane which is not already in the cache. If +ack_timeout_ns is set to 0, the cache must always be an empty set. If +max_list_size is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +max_timeout_ns configuration parameter. +

+

The P4Runtime server may empty the digest message cache in case of a client +mastership change. +

+

Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server: +

+
+
+
DigestStream stream;
+DigestCache cache;
+DigestBuffer buffers;
+
+// sends digest list when it is ready
+send_buffer(Id digest_id) {
+  buffer = buffers[digest_id];
+  stream.write(DigestList(buffer));
+  cache.merge(buffer);  // updates cache with new digest list
+  buffer.clear();
+}
+
+// callback which handles data plane digest messages from device
+handle_dataplane_digest(Digest msg) {
+  digest_id = msg.digest_id();
+  buffer = buffers[digest_id];
+  if (msg in cache OR msg in buffer) return;
+  buffer.enqueue(msg);
+  if (buffer.length() < max_list_size(digest_id)) return;
+  send_buffer(digest_id);
+}
+
+// callback which handles ack messages received on the stream
+handle_stream_ack(DigestListAck ack) {
+  // clear all cache entries matching the tuple (digest_id, list_id)
+  cache.erase( (ack.digest_id(), ack.list_id() )
+}
+
+// loop to enforce timeouts
+while (true) {
+  now = now();
+  // check for buffers that need to be sent
+  for ((digest_id, buffer) in buffers) {
+    if (now - buffer.first_enq_time() >= max_timeout_ns(digest_id))
+      send_buffer(buffer_id);
+  }
+  // check for expired entries in cache
+  for ((digest_id, list_id, sent_time) in cache) {
+    if (now - sent_time >= ack_timeout_ns(digest_id))
+      cache.erase( (digest_id, list_id) );
+  }
+  sleep(X);
+}

9.9. ExternEntry

+

This is used to support a P4 extern entity that is not part of PSA. It is +defined as: +

+
+
+
message ExternEntry {
+  uint32 extern_type_id = 1;
+  uint32 extern_id = 2;
+  google.protobuf.Any entry = 3;
+}
+

Each ExternEntry entity maps to an Extern message in the +P4Info and an ExternInstance message within that +message. The extern_type_id field must be equal to the one in +ExternEntry. The extern_id field must be equal to the ID included in the +preamble of the corresponding ExternInstance message. +

+

entry itself is embedded as an Any Protobuf message [31] to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on Extending P4Runtime for non-PSA +Architectures for more information. +

10. Error Reporting Messages

+

P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case. +

+

gRPC uses grpc::Status [32] to represent the status returned by an +RPC. It has 3 attributes: +

+
+
+
StatusCode code_;
+grpc::string error_message_;
+grpc::string binary_error_details_;
+

The code_ represents a canonical error [34] and describes the +overall RPC status. The error_message_ is a developer-facing error message, +which should be in English. The binary_error_details_ carries a serialized +google.rpc.Status message [28] message, which has 3 fields: +

+
+
+
int32 code = 1;  // see code.proto
+string message = 2;
+repeated google.protobuf.Any details = 3;
+

The code and message fields must be the same as code_ and error_message_ +fields from grpc::Status above. The details field is a list that consists of +p4.Error messages that carry error details for individual elements inside +batch-request RPCs (e.g. Write and Read). p4.Error includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices [34]. +

+

Figure 7 illustrates how these messages fit together. +

+
+

error-report +

+
+ +
Figure 7. P4Runtime Error Report Message Format
+

gRPC provides utility functions ExtractErrorDetails() and SetErrorDetails() +[33] to easily convert between grpc::Status and +google.rpc.Status. +

+

Please see sections on individual P4Runtime RPCs for details on how +grpc::Status is populated for reporting errors. +

+

Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on Stream Error +Reporting for more information. +

11. Atomicity of Individual Write and Read Operations

+

Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane apply +operation, and every single Write operation on a table that inserts, deletes, +or modifies one table entry, the apply operation should behave as if that +Write operation has not yet occurred, or as if the Write operation is +complete. The P4 program should never behave as if the Write operation is +partially complete. These guarantees also apply to extern instances: Read and +Write operations on extern entities must execute atomically relative to extern +data plane methods. +

+

The atomicity guarantees provided by P4Runtime for individual Read and Write +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification [23]. +

+

The P416 language introduces an @atomic annotation [14], to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the @atomic annotation for Write +operations, as well as non-wildcard Read operations, +relative to data plane execution. Consider the following P4 example written for +PSA: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024) r1;
+
+  apply {
+    // ...
+    @atomic {
+        Value_t v = r1.read((Index_t)1);
+        v = v + 1;
+        r1.write((Index_t)1, v);
+    }
+  }
+}
+

If a P4Runtime server is processing messages which write to Register r1 at +index 1, these writes must not happen between the data plane read and +write. +

+

Now let's consider the following example: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024, (Value_t)0 /* initial value */) r1;
+
+  apply {
+    @atomic {
+        r1.write((Index_t)1, (Value_t)100);
+        r1.write((Index_t)2, (Value_t)100);
+    }
+    @atomic {
+        r1.write((Index_t)1, (Value_t)200);
+        r1.write((Index_t)2, (Value_t)200);
+    }
+  }
+}
+

If a P4Runtime client issues a wildcard Read on Register r1, there is no +guarantee that r1[1] == r1[2] in the response, as the read for r1[1] may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for r1[2] may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read r1[1] and r1[2] separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +ReadRequest message) of individual read requests. Similar to a batch +ReadRequest, a wildcard read of a register can execute the reads of the +register array elements (r1[1], r1[2], ) in an arbitrary order relative +to each other. +

+

If the @atomic annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program. +

12. Write RPC

+

The Write RPC updates one or more P4 entities on the target. The request is +defined as follows: +

+
+
+
message WriteRequest {
+  uint64 device_id = 1;
+  uint64 role_id = 2;
+  Uint128 election_id = 3;
+  repeated Update updates = 4;
+  enum Atomicity {
+    CONTINUE_ON_ERROR = 0;
+    ROLLBACK_ON_ERROR = 1;
+    DATAPLANE_ATOMIC = 2;
+  }
+  Atomicity atomicity = 5;
+}
+

The device_id uniquely identifies the target P4 device. The role_id and +election_id define the client role and election-id as described in the +Master-Slave Arbitration and Controller +Replication +section. The server is expected to perform the following checks (in this order) +before processing the updates list: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role_id does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the master for (device_id, role_id) according to the +election_id value, the server must return a PERMISSION_DENIED error. +

  4. +
  5. +

    If the Write is attempted before a ForwardingPipelineConfig has been set, +the server must return a FAILED_PRECONDITION error. +

+ +

The updates field is a list of P4 entity updates to be applied. Each update is +defined as: +

+
+
+
message Update {
+  enum Type {
+    UNSPECIFIED = 0;
+    INSERT = 1;
+    MODIFY = 2;
+    DELETE = 3;
+  }
+  Type type = 1;
+  Entity entity = 2;
+}
+

This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a logical table (e.g. +CounterEntry) or an actual table (e.g. TableEntry) in the P4 data +plane. Each entity in the container is uniquely identified by its key. Please +refer to the P4 Entity Messages section for details on +what parts of the entity specification make up the key for each P4 entity. +

+

An update can be one of the following types: +

+
    +
  • +

    INSERT: Inserts the given P4 entity in the entity container. +The entity field always specifies the full state of the P4 entity. +If the entity already exists, an ALREADY_EXISTS error is returned, and +the existing entity remains unchanged. +If the entity is malformed, an INVALID_ARGUMENT error is returned. +If the entity cannot be inserted because the container is already full, +a RESOURCE_EXHAUSTED error is returned. +

  • +
  • +

    MODIFY: Modifies the P4 entity to its new specified state. This uses +assign or full-snapshot semantics, i.e. the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an INVALID_ARGUMENT error is usually returned (unless a +more specific error code applies [34]). If the entity does not +exist, a NOT_FOUND error is returned. +

  • +
  • +

    DELETE: Deletes the specified P4 entity. If the entity does not exist, a +NOT_FOUND error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored. +

+ +

If an update is not allowed under the given controller role, the server must +return a PERMISSION_DENIED error for this update. +

12.1. Batching and Ordering of Updates

+

P4Runtime supports batching of Write operations. The list of updates in a +WriteRequest is referred to as a batch. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of TableEntry entities). +

+

The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +WriteRequests can also be processed interleaved and/or in parallel. +However, the processing of requests must be strictly serializable. That +is, given a history $S$ of WriteRequests including the responses to those +requests, there must exist an order $L$ for all updates in $S$, such that: +

+
    +
  1. All updates from the same write request must appear as a contiguous +subsequence in $L$, but the order within that subsequence can be arbitrary. +
  2. +
  3. For two updates $u_1$ and $u_2$, if the write request containing $u_1$ +completed before the write request of $u_2$ was sent, then $u_1$ must appear +before $u_2$ in $L$. +
  4. +
  5. Executing all updates in $L$ sequentially must yield the same response for +every update as in $S$. +
  6. +
  7. The observable state of the switch after $S$ (e.g., through the Read RPC) +is identical to the one obtained by sequentially executing $L$. +
+ +

The Write RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the Write RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (e.g. inserting an ActionProfileMember +followed by pointing a TableEntry to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding Write RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate Write calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each Write call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one. +

12.2. Batch Atomicity

+

A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the Atomicity +enum. A P4Runtime server is required to support only the modes marked as +Required below: +

+
    +
  • +

    Required: CONTINUE_ON_ERROR: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that see each of +these intermediate stages. +

  • +
  • +

    Optional: ROLLBACK_ON_ERROR: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is all-or-none, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that see each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure. +

    +

    If a P4Runtime server does not support this option at all, an +UNIMPLEMENTED error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (e.g. it is +more straightforward to implement batches that contain only INSERT +operations, vs. those that contain DELETE operations), an +UNIMPLEMENTED error is returned when the batch cannot be executed +in a data plane-atomic way. +

  • +
  • +

    Optional: DATAPLANE_ATOMIC: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +transaction. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane's table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table. +

    +

    If a P4Runtime server does not support this option at all, an UNIMPLEMENTED +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an UNIMPLEMENTED error is returned when the batch +cannot be executed in a data plane-atomic way. +

+ +

There is no expectation that a given client must always use the same Atomicity +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use DATAPLANE_ATOMIC at one time and default behavior +(CONTINUE_ON_ERROR) at other times. +

12.3. Error Reporting

+

Please see section Error Reporting Messages for +information on error reporting messages and guidelines. P4Runtime server will +populate grpc::Status as follows: +

+
    +
  1. +

    If all batch updates succeeded, set grpc::Status::code_ to OK and do not +populate any other field. +

  2. +
  3. +

    If an error is encountered before even trying to attempt individual batch +updates, set grpc::Status::code_ that best describes that RPC-wide +error. For example, use UNAVAILABLE if the P4Runtime service is not yet +ready to handle requests. Set error_message_ to describe the issue. Do not +set error_details in this case. +

  4. +
  5. +

    Otherwise, if one or more updates in the batch (WriteRequest.updates) +failed, set grpc::Status::code_ to UNKNOWN. For example, one update in +the batch may fail with RESOURCE_EXHAUSTED and another with +INVALID_ARGUMENT. A p4.Error message is used to capture the status of +each and every update in the batch. The number of p4.Error messages packed +into google.rpc.Status.details field should therefore always match the +number of updates in the WriteRequest, and the order of +p4.Error messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +p4.Error should set the code to OK and omit other fields. +

+ +
+
+
# Example of a grpc::Status returned for a Write RPC with a batch of 3 updates.
+# The first and third updates encountered an error, while the second update
+# succeeded.
+code_ = 2  # UNKNOWN
+error_message_ = "Write failure."
+binary_error_details {
+  code: 2  # UNKNOWN
+  message: "Write failure."
+  details {
+    canonical_code: 8  # RESOURCE_EXHAUSTED
+    message: "Table is full."
+    space: "targetX-psa-vendorY"
+    code: 500  # ERR_TABLE_FULL
+  }
+  details {
+    canonical_code: 0  # OK
+  }
+  details {
+    canonical_code: 6  # ALREADY_EXISTS
+    message: "Entity already exists."
+    space: "targetX-psa-vendorY"
+    code: 600  # ERR_ENTITY_ALREADY_EXISTS
+  }
+}

13. Read RPC

+

The Read RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as: +

+
+
+
message ReadRequest {
+  uint64 device_id = 1;
+  repeated Entity entities = 2;
+}
+

The device_id uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +NOT_FOUND error. The entities repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server. +

+

Since ReadRequests do not mutate any state on the switch, they do not +require an election_id, and they do not require the presence of an open +StreamChannel between the server and client. +

+

The Read response consists of a sequence of messages (a gRPC stream) with +each message defined as: +

+
+
+
message ReadResponse {
+  repeated Entity entities = 1;
+}
+

The entities repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the Finish() method on the stream object +[10]). +

13.1. Nomenclature

+
+
request
+
An element of the p4.ReadRequest.entities repeated field. +
+
batch
+
Refers to the p4.ReadRequest.entities repeated field.
+

Each request acts as a query filter for that entity type. If a request fully +specifies the entity key, the Read operation should retrieve a single P4 +entity. Please refer to the P4 Entity Messages section +for details on what parts of the entity specification make up the entity key. +

13.2. Wildcard Reads

+

P4Runtime allows wildcard read of P4 entities. A request may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the P4 Entity Messages section for details on +what parts of the entity can be wildcarded in a given request. +

+

For example, in a request of type CounterEntry: +

+
    +
  • A default counter_id (0) implies a request to read all counter-entries for +all indirect counters. +
  • +
  • A particular (non-default) counter_id in conjunction with index unset +implies a request to read all counter-entries for the given indirect counter +ID. +
+ +

To read the entire forwarding state for a given device, the P4Runtime client can +generate the following ReadRequest: +

+
+
+
device_id: <ID>
+entities {
+  extern_entry { }  # read all extern instances for all supported extern types
+  table_entry { }  # read all table entries for all tables
+  action_profile_member { }  # read all members for all action profiles
+  action_profile_group { }  # read all groups for all action profiles
+  ...
+}
+

The entity oneof field in the Entity message must always be set, or the +server must return an INVALID_ARGUMENT error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty Entity message in the ReadRequest. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the entity oneof [20]. +

13.3. Batch Processing

+

A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type request +appears only once in the batch. +

+

A P4Runtime server will process the batch as follows: +

+
    +
  1. +

    Lock state (preventing new writes) and validate each request in the batch: +

    +
      +
    1. +

      If it is a valid request, perform the read; +

      +
        +
      1. If the read was successful, return the entities read in +ReadResponse stream. +
      2. +
      3. If the read failed (exception / critical-error), prepare a p4.Error +with code set to INTERNAL. +
      +
    2. +
    3. +

      If the request is invalid (invalid-argument, not-supported, etc.), +prepare a p4.Error with relevant canonical code to capture the error. +

    +
  2. +
  3. +

    Unlock the state (allowing new writes); +

  4. +
  5. +

    Close the ReadResponse stream and return a grpc::Status as follows: +

    +
      +
    1. +

      If no errors were encountered, set code to OK and do not populate any +other field. +

    2. +
    3. +

      Otherwise, the overall code should be set to UNKNOWN. See section +Error Reporting Messages for information +on error reporting messages and guidelines. Assemble a list of p4.Error +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +google.rpc.Status.details field. This behavior also matches Write +RPC. +

    +
+

13.3.1. Example

+

If a client asked to read {a,b,c,d} and b and d requests didn't +validate, the server will return entities corresponding to a and c, followed +by a status {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} in the +details field. +

+

The P4Runtime server is not required to perform any optimization (e.g. merge two +requests in the batch if one is a subset of other). As a result of this, it +is possible for the ReadResponse to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging. +

+

There is no requirement that each request in the batch will correspond to one +ReadResponse message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit. +

+

A P4Runtime server must be prepared to handle multiple concurrent Read RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (e.g. in a single-threaded architecture), it may choose to serialize +Read RPC processing. +

13.4. Parallelism of Read and Write Requests

+

A P4Runtime server may be implemented to serve at most one +ReadRequest or WriteRequest message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so. +

+

For example, imagine a client that wanted to use WriteRequest +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +WriteRequest messages with only a few updates to an ActionSelector +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +WriteRequest batch currently being processed, but it will not +complete for a significant amount of time. +

+

The restrictions on which a client may rely are: +

+
    +
  • The processing of any two WriteRequest messages W1 and W2 must +result in the same state as if one of them was completed before the +other began. +
  • +
  • For any WriteRequest W and any ReadRequest R, R must +return results consistent with a state where W has completed +processing, or W has not yet begun processing. +
+ +

For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a WriteRequest message it acquired a write lock for each stateful +object affected by the WriteRequest, and before starting the +processing of a ReadRequest message it acquired a read lock for each +stateful object accessed by the ReadRequest, such an implementation +meets all of the requirements above. +

+

It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, e.g. if the server somehow determined that two +WriteRequest messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly. +

14. SetForwardingPipelineConfig RPC

+

A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the SetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message SetForwardingPipelineConfigRequest {
+  enum Action {
+    UNSPECIFIED = 0;
+    VERIFY = 1;
+    VERIFY_AND_SAVE = 2;
+    VERIFY_AND_COMMIT = 3;
+    COMMIT = 4;
+    RECONCILE_AND_COMMIT = 5;
+  }
+  uint64 device_id = 1;
+  uint64 role_id = 2;
+  Uint128 election_id = 3;
+  Action action = 4;
+  ForwardingPipelineConfig config = 5;
+}
+

The server is expected to perform the following checks (in this order) +before performing the required action: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role_id does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the master for (device_id, role_id) according to the +election_id value, the server must return a PERMISSION_DENIED error. +

+ +

The action is the type of configuration action requested, it can be one of: +

+
    +
  • +

    VERIFY: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an INVALID_ARGUMENT +error if config is not provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_SAVE: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent Read / Write requests must refer to fields in the new +config. Returns an INVALID_ARGUMENT error if the forwarding config is not +provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_COMMIT: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an INVALID_ARGUMENT error if the forwarding config is not provided or if the +provided config cannot be realized. +

  • +
  • +

    COMMIT: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a NOT_FOUND error if no saved config +is found, i.e. if no VERIFY_AND_SAVE action preceded this one. Returns an +INVALID_ARGUMENT error if a config is provided with this message. +

  • +
  • +

    RECONCILE_AND_COMMIT: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an UNIMPLEMENTED error. For targets that support this option, an +INVALID_ARGUMENT error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target. +

+ +

The config field is a message of type ForwardingPipelineConfig that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(e.g. generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the Forwarding-Pipeline +Configuration section for details. +

+

A P4Runtime server running on a non-programmable device may not +support SetForwardingPipelineConfig (e.g. the forwarding-pipeline +config is part of the device's software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +UNIMPLEMENTED error. +

15. GetForwardingPipelineConfig RPC

+

The forwarding-pipeline configuration of the target can be retrieved by invoking +the GetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message GetForwardingPipelineConfigRequest {
+  enum ResponseType {
+    ALL = 0;
+    COOKIE_ONLY = 1;
+    P4INFO_AND_COOKIE = 2;
+    DEVICE_CONFIG_AND_COOKIE = 3;
+  }
+  uint64 device_id = 1;
+  ResponseType response_type = 2;
+}
+

The device_id uniquely identifies the target P4 device. A NOT_FOUND error is +returned if the device_id is not recognized by the P4Runtime server. +

+

The response_type is used to specify which fields to populate in the response, +its value can be one of: +

+
    +
  • +

    ALL: returns a ForwardingPipelineConfig with all fields +set as stored by the target. This is the default behaviour if the +response_type field is not set. +

  • +
  • +

    COOKIE_ONLY: reply by setting only the cookie field in the +ForwardingPipelineConfig, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message. +

  • +
  • +

    P4INFO_AND_COOKIE: reply by setting the p4info and cookie fields. +

  • +
  • +

    DEVICE_CONFIG_AND_COOKIE: reply by setting the p4_device_config and +cookie fields. +

+ +

The response contains the ForwardingPipelineConfig for the specified device: +

+
+
+
message GetForwardingPipelineConfigResponse {
+  ForwardingPipelineConfig config = 1;
+}
+

If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level config field will be unset in the response. Examples are +(i) a server that only allows configuration via SetForwardingPipelineConfig +but this RPC hasn't been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn't yet occurred. +

+

Once a forwarding-pipeline config is installed on the device (either via +SetForwardingPipelineConfig or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +config.p4_device_config will be empty / unset in the response, even if +response_type in the request was set to ALL. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the SetForwardingPipelineConfig RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +SetForwardingPipelineConfig, the value of config.cookie will be unset. +

+

If a P4Runtime server supports both SetForwardingPipelineConfig as well as +returning the p4_device_config, there should be read-write symmetry between +SetForwardingPipelineConfig and GetForwardingPipelineConfig RPCs. +

16. P4Runtime Stream Messages

16.1. Packet I/O

+

P4Runtime supports controller packet-in and packet-out by means of PacketIn +and PacketOut stream messages, respectively. +

+

PacketIn messages are sent by the P4Runtime server to the client. Conversely, +PacketOut messages are sent by the client to the server. Any PacketOut +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a StreamMessageResponse message with the error field set to +report the error to the client. See the section on Stream Error +Reporting for more information on error. +

+

As introduced in the ControllerPacketMetadata +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with @controller_header. The expected metadata is described +in the P4Info using the ControllerPacketMetadata messages. +

+

Both PacketIn and PacketOut stream messages share the same fields and are +defined as follows: +

+
+
+
// Packet sent from the controller to the switch.
+message PacketOut {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+// Packet sent from the switch to the controller.
+message PacketIn {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+message PacketMetadata {
+  // This refers to Metadata.id coming from P4Info ControllerPacketMetadata.
+  uint32 metadata_id = 1;
+  bytes value = 2;
+}
+
    +
  • +

    payload is used to carry the full packet content, including the headers. +

  • +
  • +

    metadata is a repeated field of PacketMetadata messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +ControllerPacketMetadata. Indeed, when a P4Runtime client (or server) +generates a PacketOut (or PacketIn) message, it needs to populate the +metadata field with as many values as in ControllerPacketMetadata.metadata +for the packet-out (or packet-in) case. Each PacketMetadata.value is a +binary string and must conform to the Bytestrings +requirements based on the corresponding P4Info +ControllerPacketMetadata.metadata specification. If the metadata field +does not match the P4Info specification, the server must drop the PacketOut +message and may generate a StreamMessageResponse message with the error +field set to report the error to the client which issued the PacketOut. See +the section on Stream Error Reporting for more +information on error. +

+

16.2. Master Arbitration Update

+

P4Runtime's master arbitration mechanism ensures that only the current master +can modify state on the switch, and that the election_id is monotonically +increasing. For example, the switch must finish all previous write operations +before changing masters, and must only accept write requests from the current +master. +

+

As explained earlier in this document, the controller uses the StreamChannel +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via Write RPC), +it needs to start a controller session and become a “master”. To do so, the +controller first opens a bidirectional stream channel to the server via +StreamChannel for each device and sends a StreamMessageRequest message. The +controller populates the MasterArbitrationUpdate field in this message using +its role_id and election_id and the device_id of the device, as explained +in detail in the Master-Slave Arbitration and Controller +Replication +section. For any given (device_id, role_id), the P4Runtime server keeps track +of the highest election_id that it has ever received. If a controller's +election_id is equal to the highest election_id that the server has ever +received, that controller is the master. All other controllers are slaves. Note +that it is possible that all controllers are slaves, and that there is no +master. There can be at most one master, because for any given +(device_id, role_id), each connected controller has a unique election_id. +

+

This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest election_id after such a restart. +However, across a full restart, the election_id must be +reset. In fact, a full restart is the only way to reset the election_id. +

+

The MasterArbitrationUpdate message is defined as follows: +

+
+
+
message Role {
+  // role_id for this role. Defined offline in agreement across the
+  // entire control plane.
+  uint64 id = 1;
+  // Describes the role configuration.
+  google.protobuf.Any config = 2;
+}
+
+message MasterArbitrationUpdate {
+  // Identifies the device (aka target or node or switching chip).
+  uint64 device_id = 1;
+  // The role for which the mastership is being arbitrated.
+  Role role = 2;
+  // The election_id (unique per role).
+  Uint128 election_id = 3;
+  // Switch populates this with OK for the client that is the master,
+  // and with an error status for all other connected clients (at
+  // every mastership change). The controller does not populate this
+  // field.
+  google.rpc.Status status = 4;
+}
+

Note that the status field in the MasterArbitrationUpdate message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a StreamMessageResponse message back to the controller, in which +it populates the MasterArbitrationUpdate message using the device_id, +role, and election_id it previously received from the controller. The server +also populates the status field in the MasterArbitrationUpdate according to +the rules in an earlier section. +

+

The sender need not specify an election_id. If the election_id is not +specified, the sender's election_id is considered lower than any +election_id, and the sender will thus never become master. This way, a +controller can choose to be a standby controller, in order to avoid master +“flapping” (if a standby controller connects to the switch shortly before the +actual master controller, therefore becoming master temporarily). +

16.3. Digest Messages

+

See the DigestEntry section. +

16.4. Table Idle Timeout Notification

+

When a table supports idle timeout (as per the P4Info message), the master +client can specify a TTL value for each entry in the table (see +Idle-timeout section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an IdleTimeoutNotification message on the +StreamChannel bidirectional stream to the master client. The master client can +then take the action of its choice, most likely remove the idle entry. +

+

The IdleTimeoutNotification Protobuf message has the following fields: +

+
    +
  • +

    timestamp: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server's local clock. +

  • +
  • +

    table_entry: a repeated field of entries which have expired. Each individual +entry is identified by a single TableEntry message. For each TableEntry, +the key fields (table_id, match and priority) must be set, along with +the controller_metadata field, the metadata field, and the +idle_timeout_ns field. Other fields may be set by the server but should be +ignored by the client. +

+ +

Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +IdleTimeoutNotification message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an IdleTimeoutNotification +message with an empty table_entry repeated field. +

+

After generating an idle notification, the P4Runtime server must “reset” the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the master client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle. +

+

Here is a reasonable pseudo-code implementation for idle timeout for table +entries: +

+
+
+
IdleTimeoutStream stream;
+
+scanning_interval = 10ms;
+
+while (true) {
+  // iterate over all tables which support idle timeout
+  for (table in tables) {
+    if (!table.idle_timeout_supported) continue;
+    // we coalesce all idle notifications for the same table in one
+    // message
+    IdleTimeoutNotification msg;
+    // read time_since_last_hit from device
+    entries = device.load_table_entries_from_hw(table);
+    for (entry in entries) {
+      if (entry.idle_timeout == 0) continue;  // no TTL
+      if (entry.time_since_last_hit < entry.idle_timeout) continue;
+      msg.table_entry_add(entry);
+      entry.reset_time_since_last_hit();
+    }
+    if (msg.table_entry_size() == 0) continue;  // no notifications
+    msg.set_timestamp(now());
+    stream.write(msg);
+  }
+  sleep(scanning_interval);
+}

16.5. Architecture-Specific Notifications

+

P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on StreamChannel, by including an Any Protobuf field [31] +named other in both StreamMessageRequest and StreamMessageResponse. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the PSA Digest +extern. See section on Extending P4Runtime for non-PSA +Architectures for more information. +

16.6. Stream Error Reporting

+

The P4Runtime server can asynchronously report errors which occur when +processing StreamMessageRequest messages, using the error message field (of +type StreamError) in StreamMessageResponse. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature. +

+

The StreamError message has the following fields: +

+
    +
  • canonical_code, which must be set to the appropriate canonical error code +[34]. +
  • +
  • message, an optional developer-facing error message describing the error. +
  • +
  • space and code, which are optional and can be used by vendors to provide +additional details on the error. code is a numeric error code drawn from a +vendor's chosen error space. +
  • +
  • details, which is a Protobuf oneof used to help the client identify which +StreamMessageRequest triggered the error. The server is required to set the +appropriate field in the oneof so that the client can identify which type +of stream message is responsible for the error (packet_out, +digest_list_ack or other), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid PacketOut message from the +client, the packet_out field (of type PacketOutError) should be set in +the details oneof, and the server may additionally set the packet_out +field in the PacketOutError sub-message (by copying it from the invalid +PacketOut message received on the stream channel) so that the client can +know exactly what packet-out triggered the error. +
+ +

The appropriate canonical error code [34] should be used when +populating the canonical_code field. For example: +

+
    +
  • if a controller is not allowed to send a PacketOut message under its +current role definition, the code should be set to PERMISSION_DENIED. +
  • +
  • if the metadata repeated field in PacketOut does not match the P4Info +definition, the code should be set to INVALID_ARGUMENT. It may be useful +for the server to set the packet_out field in this case, so that the client +can find out which set of metadata fields triggered the error. +
  • +
  • if the digest_id field in DigestListAck does not match any Digest entry +in P4Info, the code should be set to INVALID_ARGUMENT. +
+ +

The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, e.g. because of a +burst of PacketIn messages. +

+

Note that master-arbitration errors are never reported using the StreamError +message. Invalid MasterArbitrationUpdate messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section 5.3. +

16.6.1. Examples of StreamError Messages

+
    +
  • +

    Malformed packet-out metadata. If the server receives a PacketOut +message with a metadata field with id 7 which is not included in the P4Info +ControllerPacketMetadata message for “packet_out”, the server may send the +following StreamMessageResponse back to the client: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Unknown metadata field id 7."
    + packet_out {
    +   # copied from the PacketOut message received from the client
    +   packet_out {
    +     payload: ...
    +     metadata {
    +       id: 7
    +       name: "I_should_not_be_here"
    +       bitwidth: 32
    +     }
    +     # more metadata
    +   }
    + }
    +}
  • +
  • +

    Packet-out which exceeds the MTU. If the server receives a PacketOut +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following StreamMessageResponse: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Packet exceeds the MTU for port."
    + space: "targetX-psa-vendor1"
    + code: 123  # MTU_EXCEEDED
    + packet_out {
    +   # we do not set the packet_out field as it does not provide any
    +   # extra information to the client
    + }
    +}
+

17. Capabilities RPC

+

The Capabilities RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the CapabilitiesRequest message is empty and the CapabilitiesResponse +message only includes the p4runtime_api_version string field. This field must +be set to the full semantic version string [27] corresponding to the +version of the P4Runtime API implemented by the server, e.g. “1.1.0-rc.1”. +

+

Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three atomicity +modes for WriteRequest batches, two of them being +optional. In the future we may decide to leverage the CapabilitiesResponse +message to enable the server to report to the client which subset of these +atomicity modes is supported. +

+

The semantic version string included in CapabilitiesResponse can be used by +the client to determine which exact feature set is implemented by the server, +since minor releases may introduce new +functionality. However, because the Capabilities RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (i.e. an UNIMPLEMENTED error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0). +

18. Portability Considerations

18.1. PSA Metadata Translation

+

The Portable Switch Architecture (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +[24]. For such metadata, a translation between the controller's +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the @p4runtime_translation annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture. +

+
+

psa-metadata-translation +

+
+ +
Figure 8. P4Runtime Metadata Translation for the Portable Switch Architecture
+

Figure 8 illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller's 32 bit port +numbers to a target's 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch. +

18.1.1. Translation of Port Numbers

+

In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller's space and the PSA device's space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +user-defined P4 types, namely PortId_t and +PortIdInHeader_t, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in psa.p4 for +the PSA device in Switch 1. +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type bit<9> PortId_t;
+@p4runtime_translation("p4.org/psa/v1/PortIdInHeader_t", 32)
+type bit<32> PortIdInHeader_t;
+

The first argument to the @p4runtime_translation annotation is a URI that +indicates to the P4Runtime server which numerical mapping provided by the +out-of-band switch configuration mechanism to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports). +

+

An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows: +

+
+
+
enum SdnPort {
+  SDN_PORT_UNSPECIFIED = 0;
+
+  // SDN ports are numbered starting from 1.
+  SDN_PORT_MIN = 1;
+
+  // The maximum value of an SDN port (physical or logical).
+  SDN_PORT_MAX = 0xfffffeff;
+
+  // Reserved SDN port numbers (0xfffffff0 - 0xffffffff)
+
+  SDN_PORT_RECIRCULATE = 0xfffffffa;
+  SDN_PORT_CPU = 0xfffffffd;
+}
+

The switch config will map SDN_PORT_RECIRCULATE and SDN_PORT_CPU as well +as any SDN port number corresponding to a “regular” front-panel port to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation. +

+

The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs. +

18.1.2. Translation of Packet-IO Header Fields

+

Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  PortIdInHeader_t egress_port;
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  PortIdInHeader_t ingress_port;
+}
+

The header-level annotation @controller_header is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (egress_port) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI first argument to the @p4runtime_translation +annotation). Any subsequent reference to the egress_port field in the +data plane will use the translated value. PortIdInHeader_t is used in the +header definition instead of PortId_t to guarantee byte-aligned headers in +case this is required by the target. +

+

A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target's PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the ingress_port field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller. +

18.1.3. Translation of Match Fields

+

Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table's match key as shown in the example below: +

+
+
+
table t {
+  key = {
+    istd.ingress_port: exact;  // PSA standard metadata ingress port
+  }
+  actions = {
+    drop;
+  }
+}
+

Table t has an exact match on PSA standard metadata ingress port +(istd.ingress_port). Since the field is of type PortId_t, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in t from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table t is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values. +

+

Note that it may be infeasible to translate the value-mask pair for ternary +matches: LPM, TERNARY or RANGE match kinds. The P4Runtime server may +require that for these match kinds the port match be either de facto “exact” +(0xffffffff mask for TERNARY, prefix-length of 32 for LPM, or same low and +high bounds for RANGE) or “don't care”. +

18.1.4. Translation of Action Parameters

+

PortId_t type parameters can be part of a P4 action definition as shown in the +example below: +

+
+
+
action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+}
+
+table t {
+  key = {
+    hdr.h.f: exact;
+  }
+  actions = {
+    a;
+  }
+}
+

The controller may write entries in table t with action a to set the egress +port as shown in the P4 code above. The action parameter p is of type +PortId_t, which leads to a 32-bit bitwidth for p being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device. +

18.1.5. Port Translation for PSA Extern APIs

+

The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch field is +of type uint32 to carry the 32-bit SDN representation of the port being +watched. The P4Runtime server will translate the given watch port number into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device. +

+

The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type uint32 to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane. +

18.1.6. Using Port as an Index to a Register, Indirect Counter or Indirect Meter

+

P4Runtime supports using a translated value (PortId_t or any other translated +type for which the underlying built-in type is bit<W>) as an index to a +register, indirect counter, or indirect meter. +

+
+
+
Counter<bit<32> /* counter entry type */, PortId_t /* index type */>(
+  32w1024, PSA_CounterType_t.PACKETS) counter;
+action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+  counter.count(p);
+}
+

This P4 Counter declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
counters {
+  preamble {
+    id: 0x12000001
+    name: "counter"
+  }
+  spec {
+    unit: PACKETS
+  }
+  index_type_name {
+    name: "PortId_t"
+  }
+}
+

The controller may read and write counter values from indexed counter counter +using SDN port numbers as indices, and not device-specific port numbers. The +index_type_name field in the P4Info message is a signal to the P4Runtime +server that translation is required. +

19. P4Runtime Versioning

+

P4Runtime follows the Google guidelines for versioning cloud APIs +[6]. We use a MAJOR.MINOR.PATCH style version number scheme and +we increment the: +

+
    +
  • MAJOR version when we make incompatible API changes, +
  • +
  • MINOR version when we add functionality in a backwards-compatible manner, +
  • +
  • PATCH version when we make backwards-compatible bug fixes. +
+ +

The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is p4.v1 and the package +name for P4Info is p4.config.v1. Even though p4 and p4.config are two +different Protobuf packages, p4 depends on p4.config and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence. +

+

As recommended in [6], we may consider using pre-GA release +suffixes (such as alpha or beta) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1). +

+

Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner. [7] describes +what constitute a backwards-compatible change. We expect MAJOR version bumps +to be a rare event. +

+

Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor + patch version numbers in future releases. +

+

All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository [15] and the version label follows +semantic versioning rules [27]. +

20. Extending P4Runtime for non-PSA Architectures

+

P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place. +

+

When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names: +

+
    +
  • p4/[organization]/arch/config/<major version>/p4info.proto +
  • +
  • p4/[organization]/arch/<major version>/p4runtime.proto +
+ +

We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they “extend”. +

+

For the remainder of this section, we will refer to these two files as +p4info-ext and p4runtime-ext respectively. +

20.1. Extending P4Runtime for Architecture-Specific Externs

+

Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both p4info-ext and +p4runtime-ext. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example: +

+
+
+
// T must be a bit<W> type, it indicates the width of each counter cell
+extern MyNewPacketCounter<T> {
+  counter(bit<32> size);
+  increment(in bit<32> index);
+}

20.1.1. Extending the P4Info message

+
    +
  • Id prefixes 0x81 through 0xfe are reserved for architecture-specific +externs. It is recommended that p4info-ext include a P4Ids message based +on the one in p4info.proto that the P4 compiler can refer to when assigning +IDs to each extern instance. +
+ +
+
+
message P4Ids {
+  enum Prefix {
+    UNSPECIFIED = 0;
+    MY_NEW_PACKET_COUNTER = 0x81;
+  }
+}
+
    +
  • p4info-ext should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +p4.config.v1.ExternInstance message as the info +field, which is of type Any [31]. +
+ +
+
+
message MyNewPacketCounter {
+  // corresponds to the T type parameter in the P4 extern definition
+  p4.config.v1.P4DataTypeSpec type_spec = 1;
+  // constructor argument
+  int64 size = 2;
+}

20.1.2. Extending the P4Runtime Service

+

Just like p4info-ext, p4runtime-ext should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an ExternEntry message generated by the +P4Runtime client. +

+

Here is a possible Protobuf message for our MyNewPacketCounter P4 extern: +

+
+
+
// This message enables reading / writing data to the counter at the provided
+// index
+message MyNewPacketCounter {
+  int64 index = 1;
+  p4.v1.P4Data data = 2;
+}
+

P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an Any Protobuf field [31] named other +in both p4.v1.StreamMessageRequest and +p4.v1.StreamMessageResponse. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in p4runtime-ext and embed instances of these messages in +p4.v1.StreamMessageRequest and p4.v1.StreamMessageResponse as appropriate. +

20.2. Architecture-Specific Table Extensions

20.2.1. New Match Types

+

An architecture may introduce new table match types [12]. P4Runtime +accounts for this by providing the following hooks: +

+
    +
  • +

    The match field in p4.config.v1.MatchField (p4info.proto) is a oneof +which can be either one of the default match types (EXACT, LPM, TERNARY, +RANGE, or OPTIONAL) or an architecture-specific match type encoded as a +string. +

  • +
  • +

    The field_match_type field in p4.v1.FieldMatch (p4runtime.proto) is a +oneof which includes an Any Protobuf message [31] field +(other). p4info-ext should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in p4.v1.FieldMatch as the +other field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info. +

+

20.2.2. New Table Properties

+

An architecture may introduce additional table properties +[30]. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +p4.config.v1.Table message includes the other_properties Any Protobuf +field [31]. At the moment, there is not any mechanism to extend the +p4.v1.TableEntry message based on the value of architecture-specific table +properties, but we may include on in future versions of the API. +

21. Known Limitations of Current P4Runtime Version

+
    +
  • +

    FieldMatch, action Param, and controller packet metadata fields only +support unsigned bitstrings, i.e. values of one of the following types (not +the more general P4Data): +

    +
      +
    • bit<W> +
    • +
    • bool. Note that as far as the P4Info message contents and +thus controller software is concerned, such fields of type bool +will be indistinguishable from those that have been declared with +type bit<1>. P4Runtime server software will automatically +perform any conversion needed between the type bit<1> values in +P4Runtime messages and the data plane representation. +
    • +
    • an enum with underlying type bit<W> +
    • +
    • a type or typedef with an underlying type that is one of the above (or +in general a “chain” of type and/or typedef that eventually ends with +one of the types above) +
    +
  • +
  • +

    Support for PSA Random & Timestamp externs is postponed to a future minor +version update. +

  • +
  • +

    P4Info does not include information about which of a table's actions execute +which direct resource(s). +

  • +
  • +

    The default action for indirect match tables is restricted to a const +NoAction known at compile-time. +

  • +
  • +

    There is no mechanism for changing the value of the psa_empty_group_action +table property at runtime. +

  • +
  • +

    There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor + +patch version numbers. +

+

22. Security concerns for P4Runtime

+

Appropriate measures and security best practices need to be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. +

A. Appendix

A.1. Revision History

A.1.1. Changes in v1.2.0

+
    +
  • Add new OPTIONAL match kind. At the moment, OPTIONAL is only supported by +the v1model architecture [38], and not by PSA. It will eventually be +included in the core P4 language. +
  • +
  • Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists. +
  • +
  • Add a new metadata field of type bytes to TableEntry. This is more +flexible than the now deprecated controller_metadata field. +
  • +
  • Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +@id annotation. +
  • +
  • Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature. +
  • +
  • Support using string as the controller type in the @p4runtime_translation +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type. +
  • +
  • Add optional P4 source locations to both structured and unstructured +annotations. +
+

A.1.2. Changes in v1.1.0

+
    +
  • Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously. +
  • +
  • Add error field to stream messages sent by the server. +
  • +
  • Add Capabilities RPC to query the P4Runtime API version implemented by the +server. +
  • +
  • Support wildcard reads for multicast groups and clone sessions. +
  • +
  • Support for modifying direct resources of const tables. +
  • +
  • Support P4 user-defined types for Packet IO metadata fields. +
  • +
  • Clarify consistency requirements for Write and Read RPCs. +
  • +
  • Add Appendix providing implementation advice for avoiding common pitfalls: + +
      +
    • advice on setting gRPC Metadata Maximum Size +
    • +
    • advice on setting gRPC Server Maximum Receive Message Size +
  • +
  • Clarify limitations on supported types for FieldMatch, action Param, and +Packet IO metadata fields. +
  • +
  • Clarify that reading entire forwarding state with empty entity is not +supported. +
  • +
  • Document that @p4runtime_translation need only be supported when applied to +type declarations in P4. +
+

A.2. P4 Annotations

+

Table 7 lists P416 annotations introduced primarily for +the purpose of adding features for the P4Runtime API. +

+
+ + + + + + + + + + +
Annotation Description
@brief See section 6.1.3
@controller_header See section 6.4.6
@description See section 6.1.3
@id See section 6.3
@max_group_size See sections 6.4.3, 9.2.2
@pkginfo See section 6.2.1
@p4runtime_translation See sections 8.5.6, 18.1.1
+
+ +
Table 7. P4 annotations introduced by P4Runtime

A.3. A More Complex Value Set Example

+

This section includes a more complex Value Set example, with multiple matches of +different kinds. +

+
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+

This P4 Value Set declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

A P4Runtime client can set the membership for this Value Set with WriteRequest +messages similar to this one: +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xac }
+      }
+      # match for field_id 2 is missing => don't care match
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xdc }
+      }
+      match {
+        field_id: 2
+        ternary { value: 0x88 mask: 8f }
+      }
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+  }
+}

A.4. Guidelines for Implementations

+

This section contains practical advice for implementing P4Runtime clients and +servers. +

A.4.1. gRPC Metadata Maximum Size

+

In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the grpc.max_metadata_size gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the Write P4Runtime RPC. The Write RPC +returns an individual error for every item in a batch (see Section +12), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +RESOURCE_EXHAUSTED error, without any of the individual errors. +

+

To fix this problem, one can set the grpc.max_metadata_size option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it's +limit, as only the receiving side's limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every p4.Error, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +8192 + MAX_UPDATES_PER_WRITE * 100 bytes of metadata. +

+

For example, in C++, one can create a client channel as follows: +

+
+
+
const int MAX_UPDATES_PER_WRITE = 100;
+::grpc::ChannelArguments arguments;
+arguments.SetInt(GRPC_ARG_MAX_METADATA_SIZE, 8192 + MAX_UPDATES_PER_WRITE*100);
+return grpc::CreateCustomChannel(address, credentials, arguments);

A.4.2. gRPC Server Maximum Receive Message Size

+

At the time of writing, the default maximum receive message size in gRPC is 4MB + while the default maximum send message size is unlimited. This can be a +problem for the SetForwardingPipelineConfig RPC, since for some targets the +binary p4_device_config can exceed 4MB, in which case by default the P4Runtime +server would return an INVALID_ARGUMENT error. To a lesser extent, this may +affect the Write RPC as well, in case of extremely large batches. +

+

To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of p4_device_config for their target(s). This can be done by +setting the grpc.max_receive_message_length when building the gRPC server. +

+

For example, in C++, one can set the maximum receive message size as follows: +

+
+
+
const int MAX_RECEIVE_MESSAGE_SIZE = 128 * 1024 * 1024;  // 128MB
+::grpc::ServerBuilder server_builder;
+builder.AddListeningPort(/*...*/);
+builder.RegisterService(/*...*/);  // register P4Runtime service
+builder.SetMaxReceiveMessageSize(MAX_RECEIVE_MESSAGE_SIZE);
+builder.BuildAndStart();
+

On the client side, we recommend that P4Runtime clients do not use Write +batches larger than the default maximum receive message size (4MB) in case +the server did not deem necessary to increase the default value , unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB). +

+

References

+
+ +
[2]“A Two Rate Three Color Marker.” https://​tools.​ietf.​org/​html/​rfc2698.
+ + + + +
[7]“Google Cloud APIs Versioning - Backwards-Compatibility.” https://​cloud.​google.​com/​apis/​design/​versioning#​backwards_​compatibility.
+ +
[9]“gRPC Main Site.” https://​grpc.​io.
+ + + + + +
[15]“p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” https://​github.​com/​p4lang/​p4runtime.
+
[16]“p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.” https://​github.​com/​p4lang/​PI.
+ + +
[19]“Portable Switch Architecture Specification (v1.1.0).” https://​p4.​org/​p4-​spec/​docs/​PSA-​v1.​1.​0.​html.
+ + + + + + + +
[27]“Semantic Versioning.” https://​semver.​org/​.
+ + + + + + + +
[35]“The OpenConfig Project.” http://​openconfig.​net.
+ +
[37]“The Stratum Project.” https://​stratumproject.​org/​.
+ +
+
+
+ +
+

1.an enum type used as a field in a header must specify a +underlying type and representation for enum elements. +

+ + + diff --git a/spec/v1.2.0/P4Runtime-Spec.log b/spec/v1.2.0/P4Runtime-Spec.log new file mode 100644 index 00000000..655f5155 --- /dev/null +++ b/spec/v1.2.0/P4Runtime-Spec.log @@ -0,0 +1,14554 @@ +This is XeTeX, Version 3.14159265-2.6-0.99992 (TeX Live 2015/Debian) (preloaded format=xelatex 2018.8.17) 6 JUL 2020 19:30 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**build/P4Runtime-Spec.tex +(./build/P4Runtime-Spec.tex +LaTeX2e <2016/02/01> +Babel <3.9q> and hyphenation patterns for 81 language(s) loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2014/09/29 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo +File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@section=\count80 +\c@subsection=\count81 +\c@subsubsection=\count82 +\c@paragraph=\count83 +\c@subparagraph=\count84 +\c@figure=\count85 +\c@table=\count86 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) (build/madoko2.sty (/usr/share/texlive/texmf-dist/tex/latex/colortbl/colortbl.sty +Package: colortbl 2012/02/13 v1.0a Color table columns (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty +Package: array 2014/10/28 v2.4c Tabular extension package (FMi) +\col@sep=\dimen103 +\extrarowheight=\dimen104 +\NC@list=\toks14 +\extratabsurround=\skip43 +\backup@length=\skip44 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty +Package: color 2016/01/03 v1.1b Standard LaTeX Color (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package color Info: Driver file: xetex.def on input line 143. +(/usr/share/texlive/texmf-dist/tex/xelatex/xetex-def/xetex.def +File: xetex.def 2015/09/11 v4.06 LaTeX color/graphics driver for XeTeX (TeX Live/RRM/JK) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +))) +\everycr=\toks15 +\minrowclearance=\skip45 +) (/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: xetex.def on input line 225. +LaTeX Info: Redefining \color on input line 702. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) (build/options.sty +Package: options 2015/03/01, Daan Leijen, Provides convenient path-value (or key-value) options +(/usr/share/texlive/texmf-dist/tex/latex/etoolbox/etoolbox.sty +Package: etoolbox 2015/08/02 v2.2a e-TeX tools for LaTeX (JAW) +\etb@tempcnta=\count87 +) +\opt@nesting=\count88 +\opt@idx=\count89 +\opt@choiceord=\count90 +) (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty +Package: iftex 2013/04/04 v0.2 Provides if(tex) conditional for PDFTeX, XeTeX, and LuaTeX +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2014/10/28 v1.0g Enhanced LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks16 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2016/01/03 v1.0q Standard LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2016/01/03 v1.10 sin cos tan (DPC) +) (/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg +File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live +) +Package graphics Info: Driver file: xetex.def on input line 95. +) +\Gin@req@height=\dimen105 +\Gin@req@width=\dimen106 +) (build/longfbox.sty +Package: longfbox 2015/12/01, Daan Leijen, Provides long fbox that can break over pages +(build/longbox.sty +Package: longbox 2015/12/01, Daan Leijen, Provides basic longbox that can break over pages +(/usr/share/texlive/texmf-dist/tex/latex/mdwtools/footnote.sty +Package: footnote 1997/01/28 1.13 Save footnotes around boxes +\fn@notes=\box26 +\fn@width=\dimen107 +) +\lb@prevdepth=\skip46 +\lb@freevspace=\skip47 +\lb@headbox=\box27 +\lb@savebox=\box28 +\lb@mainbox=\box29 +\lb@usevbox=\count91 +\lb@width=\skip48 +\lb@height=\skip49 +\lb@skiptop=\skip50 +\lb@skipright=\skip51 +\lb@skipbottom=\skip52 +\lb@skipleft=\skip53 +\lb@skipbreaktop=\skip54 +\lb@skipbreakbottom=\skip55 +\lb@outerwidth=\skip56 +\lb@extrasplit=\skip57 +\lb@textalign=\count92 +\lb@baseline=\count93 +\lb@neededvspace=\skip58 +\lb@splitheight=\skip59 +\lb@insurance=\skip60 +\/longbox/@part-height=\skip61 +\/longbox/@part-width=\skip62 +\/longbox/@part-depth=\skip63 +\/longbox/@content-box-height=\skip64 +\/longbox/@content-box-width=\skip65 +\/longbox/@content-box-depth=\skip66 +\/longbox/@breakat-previous=\skip67 +\/longbox/@lower=\skip68 +\/longbox/split-minimum=\skip69 +\/longbox/split-badness=\skip70 +\/longbox/raise=\skip71 +\/longbox/height=\skip72 +\/longbox/width=\skip73 +\/longbox/outer-height=\skip74 +\/longbox/outer-width=\skip75 +\/longbox/skip-top=\skip76 +\/longbox/skip-right=\skip77 +\/longbox/skip-bottom=\skip78 +\/longbox/skip-left=\skip79 +\/longbox/skip-break-bottom=\skip80 +\/longbox/skip-break-top=\skip81 +) (/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.sty +Package: pict2e 2016/02/05 v0.3b Improved picture commands (HjG,RN,JT) +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.cfg +File: pict2e.cfg 2016/02/05 v0.1u pict2e configuration for teTeX/TeXLive +) +Package pict2e Info: Driver file: xetex.def on input line 119. +Package pict2e Info: Driver file for pict2e: p2e-xetex.def on input line 121. +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/p2e-xetex.def +File: p2e-xetex.def 2016/02/05 v0.1u Driver-dependant file (RN,HjG,JT) +) +\pIIe@GRAPH=\toks17 +\@arclen=\dimen108 +\@arcrad=\dimen109 +\@tempdimd=\dimen110 +) (build/ellipse.sty +Package: ellipse 2004/11/05 v1.0 .dtx ellipse file +) +\fbox@oct=\count94 +\fbox@quad=\count95 +\fbox@diaq=\count96 +\fbox@sign=\count97 +\fbox@anglestart=\skip82 +\fbox@angleend=\skip83 +\fbox@dash=\skip84 +\fbox@dashskip=\skip85 +\fbox@anglecur=\skip86 +\fbox@dashangle=\skip87 +\fbox@dashskipangle=\skip88 +\fbox@delta=\skip89 +\fbox@from=\skip90 +\fbox@to=\skip91 +\/fbox/padding-top=\skip92 +\/fbox/padding-right=\skip93 +\/fbox/padding-bottom=\skip94 +\/fbox/padding-left=\skip95 +\/fbox/padding-break-top=\skip96 +\/fbox/padding-break-bottom=\skip97 +\/fbox/margin-top=\skip98 +\/fbox/margin-right=\skip99 +\/fbox/margin-bottom=\skip100 +\/fbox/margin-left=\skip101 +\/fbox/margin-break-top=\skip102 +\/fbox/margin-break-bottom=\skip103 +\/fbox/border-top-width=\skip104 +\/fbox/border-right-width=\skip105 +\/fbox/border-bottom-width=\skip106 +\/fbox/border-left-width=\skip107 +\/fbox/border-break-top-width=\skip108 +\/fbox/border-break-bottom-width=\skip109 +\/fbox/@lower=\skip110 +\/fbox/@padding-box-height=\skip111 +\/fbox/@padding-box-depth=\skip112 +\/fbox/@padding-box-width=\skip113 +\/fbox/@border-box-width=\skip114 +\/fbox/@border-box-height=\skip115 +\/fbox/@border-box-depth=\skip116 +\/fbox/@border-top-left-radius-x=\skip117 +\/fbox/@border-top-right-radius-x=\skip118 +\/fbox/@border-bottom-left-radius-x=\skip119 +\/fbox/@border-bottom-right-radius-x=\skip120 +\/fbox/@border-top-left-radius-y=\skip121 +\/fbox/@border-top-right-radius-y=\skip122 +\/fbox/@border-bottom-left-radius-y=\skip123 +\/fbox/@border-bottom-right-radius-y=\skip124 +\/fbox/@border-top-left-ix=\skip125 +\/fbox/@border-top-left-iy=\skip126 +\/fbox/@border-top-right-ix=\skip127 +\/fbox/@border-top-right-iy=\skip128 +\/fbox/@border-bottom-left-ix=\skip129 +\/fbox/@border-bottom-left-iy=\skip130 +\/fbox/@border-bottom-right-ix=\skip131 +\/fbox/@border-bottom-right-iy=\skip132 +\/fbox/@border-top-left-phi=\skip133 +\/fbox/@border-top-right-phi=\skip134 +\/fbox/@border-bottom-left-phi=\skip135 +\/fbox/@border-bottom-right-phi=\skip136 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2016/03/03 v2.15a AMS math features +\@mathmargin=\skip137 +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2000/06/29 v2.01 AMS text +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen111 +)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen112 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 1999/12/14 v2.01 operator names +) +\inf@bad=\count98 +LaTeX Info: Redefining \frac on input line 199. +\uproot@=\count99 +\leftroot@=\count100 +LaTeX Info: Redefining \overline on input line 297. +\classnum@=\count101 +\DOTSCASE@=\count102 +LaTeX Info: Redefining \ldots on input line 394. +LaTeX Info: Redefining \dots on input line 397. +LaTeX Info: Redefining \cdots on input line 518. +\Mathstrutbox@=\box30 +\strutbox@=\box31 +\big@size=\dimen113 +LaTeX Font Info: Redeclaring font encoding OML on input line 630. +LaTeX Font Info: Redeclaring font encoding OMS on input line 631. +\macc@depth=\count103 +\c@MaxMatrixCols=\count104 +\dotsspace@=\muskip10 +\c@parentequation=\count105 +\dspbrk@lvl=\count106 +\tag@help=\toks19 +\row@=\count107 +\column@=\count108 +\maxfields@=\count109 +\andhelp@=\toks20 +\eqnshift@=\dimen114 +\alignsep@=\dimen115 +\tagshift@=\dimen116 +\tagwidth@=\dimen117 +\totwidth@=\dimen118 +\lineht@=\dimen119 +\@envbody=\toks21 +\multlinegap=\skip138 +\multlinetaggap=\skip139 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2735. +LaTeX Info: Redefining \] on input line 2736. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +) (/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/stmaryrd.sty +Package: stmaryrd 1994/03/03 St Mary's Road symbol package +\symstmry=\mathgroup6 +LaTeX Font Info: Overwriting symbol font `stmry' in version `bold' +(Font) U/stmry/m/n --> U/stmry/b/n on input line 89. +) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty +Package: textcomp 2005/09/27 v1.99g Standard LaTeX package +Package textcomp Info: Sub-encoding information: +(textcomp) 5 = only ISO-Adobe without \textcurrency +(textcomp) 4 = 5 + \texteuro +(textcomp) 3 = 4 + \textohm +(textcomp) 2 = 3 + \textestimated + \textcurrency +(textcomp) 1 = TS1 - \textcircled - \t +(textcomp) 0 = TS1 (full) +(textcomp) Font families with sub-encoding setting implement +(textcomp) only a restricted character set as indicated. +(textcomp) Family '?' is the default used for unknown fonts. +(textcomp) See the documentation for details. +Package textcomp Info: Setting ? sub-encoding to TS1/1 on input line 79. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +) +LaTeX Info: Redefining \oldstylenums on input line 334. +Package textcomp Info: Setting cmr sub-encoding to TS1/0 on input line 349. +Package textcomp Info: Setting cmss sub-encoding to TS1/0 on input line 350. +Package textcomp Info: Setting cmtt sub-encoding to TS1/0 on input line 351. +Package textcomp Info: Setting cmvtt sub-encoding to TS1/0 on input line 352. +Package textcomp Info: Setting cmbr sub-encoding to TS1/0 on input line 353. +Package textcomp Info: Setting cmtl sub-encoding to TS1/0 on input line 354. +Package textcomp Info: Setting ccr sub-encoding to TS1/0 on input line 355. +Package textcomp Info: Setting ptm sub-encoding to TS1/4 on input line 356. +Package textcomp Info: Setting pcr sub-encoding to TS1/4 on input line 357. +Package textcomp Info: Setting phv sub-encoding to TS1/4 on input line 358. +Package textcomp Info: Setting ppl sub-encoding to TS1/3 on input line 359. +Package textcomp Info: Setting pag sub-encoding to TS1/4 on input line 360. +Package textcomp Info: Setting pbk sub-encoding to TS1/4 on input line 361. +Package textcomp Info: Setting pnc sub-encoding to TS1/4 on input line 362. +Package textcomp Info: Setting pzc sub-encoding to TS1/4 on input line 363. +Package textcomp Info: Setting bch sub-encoding to TS1/4 on input line 364. +Package textcomp Info: Setting put sub-encoding to TS1/5 on input line 365. +Package textcomp Info: Setting uag sub-encoding to TS1/5 on input line 366. +Package textcomp Info: Setting ugq sub-encoding to TS1/5 on input line 367. +Package textcomp Info: Setting ul8 sub-encoding to TS1/4 on input line 368. +Package textcomp Info: Setting ul9 sub-encoding to TS1/4 on input line 369. +Package textcomp Info: Setting augie sub-encoding to TS1/5 on input line 370. +Package textcomp Info: Setting dayrom sub-encoding to TS1/3 on input line 371. +Package textcomp Info: Setting dayroms sub-encoding to TS1/3 on input line 372. +Package textcomp Info: Setting pxr sub-encoding to TS1/0 on input line 373. +Package textcomp Info: Setting pxss sub-encoding to TS1/0 on input line 374. +Package textcomp Info: Setting pxtt sub-encoding to TS1/0 on input line 375. +Package textcomp Info: Setting txr sub-encoding to TS1/0 on input line 376. +Package textcomp Info: Setting txss sub-encoding to TS1/0 on input line 377. +Package textcomp Info: Setting txtt sub-encoding to TS1/0 on input line 378. +Package textcomp Info: Setting lmr sub-encoding to TS1/0 on input line 379. +Package textcomp Info: Setting lmdh sub-encoding to TS1/0 on input line 380. +Package textcomp Info: Setting lmss sub-encoding to TS1/0 on input line 381. +Package textcomp Info: Setting lmssq sub-encoding to TS1/0 on input line 382. +Package textcomp Info: Setting lmvtt sub-encoding to TS1/0 on input line 383. +Package textcomp Info: Setting lmtt sub-encoding to TS1/0 on input line 384. +Package textcomp Info: Setting qhv sub-encoding to TS1/0 on input line 385. +Package textcomp Info: Setting qag sub-encoding to TS1/0 on input line 386. +Package textcomp Info: Setting qbk sub-encoding to TS1/0 on input line 387. +Package textcomp Info: Setting qcr sub-encoding to TS1/0 on input line 388. +Package textcomp Info: Setting qcs sub-encoding to TS1/0 on input line 389. +Package textcomp Info: Setting qpl sub-encoding to TS1/0 on input line 390. +Package textcomp Info: Setting qtm sub-encoding to TS1/0 on input line 391. +Package textcomp Info: Setting qzc sub-encoding to TS1/0 on input line 392. +Package textcomp Info: Setting qhvc sub-encoding to TS1/0 on input line 393. +Package textcomp Info: Setting futs sub-encoding to TS1/4 on input line 394. +Package textcomp Info: Setting futx sub-encoding to TS1/4 on input line 395. +Package textcomp Info: Setting futj sub-encoding to TS1/4 on input line 396. +Package textcomp Info: Setting hlh sub-encoding to TS1/3 on input line 397. +Package textcomp Info: Setting hls sub-encoding to TS1/3 on input line 398. +Package textcomp Info: Setting hlst sub-encoding to TS1/3 on input line 399. +Package textcomp Info: Setting hlct sub-encoding to TS1/5 on input line 400. +Package textcomp Info: Setting hlx sub-encoding to TS1/5 on input line 401. +Package textcomp Info: Setting hlce sub-encoding to TS1/5 on input line 402. +Package textcomp Info: Setting hlcn sub-encoding to TS1/5 on input line 403. +Package textcomp Info: Setting hlcw sub-encoding to TS1/5 on input line 404. +Package textcomp Info: Setting hlcf sub-encoding to TS1/5 on input line 405. +Package textcomp Info: Setting pplx sub-encoding to TS1/3 on input line 406. +Package textcomp Info: Setting pplj sub-encoding to TS1/3 on input line 407. +Package textcomp Info: Setting ptmx sub-encoding to TS1/4 on input line 408. +Package textcomp Info: Setting ptmj sub-encoding to TS1/4 on input line 409. +) (/usr/share/texlive/texmf-dist/tex/latex/psnfss/pifont.sty +Package: pifont 2005/04/12 PSNFSS-v9.2a Pi font support (SPQR) +LaTeX Font Info: Try loading font information for U+pzd on input line 63. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upzd.fd +File: upzd.fd 2001/06/04 font definitions for U/pzd. +) +LaTeX Font Info: Try loading font information for U+psy on input line 64. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upsy.fd +File: upsy.fd 2001/06/04 font definitions for U/psy. +)) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2012/11/06 v6.83m Hypertext links for LaTeX +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO) +Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO) +Package hobsub Info: Skipping package `infwarerr' (already loaded). +Package hobsub Info: Skipping package `ltxcmds' (already loaded). +Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO) +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is not detected. +Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) +Package etexcmds Info: Could not find \expanded. +(etexcmds) That can mean that you are not using pdfTeX 1.50 or +(etexcmds) that some package has redefined \expanded. +(etexcmds) In the latter case, load this package earlier. +Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) +Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO) +Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: pdfTeX >= 1.30 not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode not found. +Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO) +Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO) +Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO) +Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO) +Package: xcolor-patch 2011/01/30 xcolor patch +Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO) +Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO) +Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO) +Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2011/03/04 v1.3 Hooks for auxiliary files (HO) +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) +) +\@linkdim=\dimen120 +\Hy@linkcounter=\count110 +\Hy@pagecounter=\count111 +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count112 +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Hyper figures OFF on input line 4443. +Package hyperref Info: Link nesting OFF on input line 4448. +Package hyperref Info: Hyper index ON on input line 4451. +Package hyperref Info: Plain pages OFF on input line 4458. +Package hyperref Info: Backreferencing OFF on input line 4463. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4688. +\c@Hy@tempcnt=\count113 +(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip11 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 5041. +\XeTeXLinkMargin=\dimen121 +\Fld@menulength=\count114 +\Field@Width=\dimen122 +\Fld@charsize=\dimen123 +Package hyperref Info: Hyper figures OFF on input line 6295. +Package hyperref Info: Link nesting OFF on input line 6300. +Package hyperref Info: Hyper index ON on input line 6303. +Package hyperref Info: backreferencing OFF on input line 6310. +Package hyperref Info: Link coloring OFF on input line 6315. +Package hyperref Info: Link coloring with OCG OFF on input line 6320. +Package hyperref Info: PDF/A mode OFF on input line 6325. +LaTeX Info: Redefining \ref on input line 6365. +LaTeX Info: Redefining \pageref on input line 6369. +\Hy@abspage=\count115 +\c@Item=\count116 +\c@Hfootnote=\count117 +) + +Package hyperref Message: Driver (autodetected): hxetex. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hxetex.def +File: hxetex.def 2012/11/06 v6.83m Hyperref driver for XeTeX +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def +File: puenc.def 2012/11/06 v6.83m Hyperref: PDF Unicode definition (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/stringenc.sty +Package: stringenc 2011/12/02 v1.10 Convert strings between diff. encodings (HO) +) +\pdfm@box=\box32 +\c@Hy@AnnotLevel=\count118 +\HyField@AnnotCount=\count119 +\Fld@listcount=\count120 +\c@bookmark@seq@number=\count121 +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO) +Package rerunfilecheck Info: Feature \pdfmdfivesum is not available +(rerunfilecheck) (e.g. pdfTeX or LuaTeX with package `pdftexcmds'). +(rerunfilecheck) Therefore file contents cannot be checked efficiently +(rerunfilecheck) and the loading of the package is aborted. +) +\Hy@SectionHShift=\skip140 +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bookmark.sty +Package: bookmark 2011/12/02 v1.24 PDF bookmarks (HO) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bkm-dvipdfm.def +File: bkm-dvipdfm.def 2011/12/02 v1.24 bookmark driver for dvipdfm (HO) +\BKM@id=\count122 +)) (/usr/share/texlive/texmf-dist/tex/latex/booktabs/booktabs.sty +Package: booktabs 2005/04/14 v1.61803 publication quality tables +\heavyrulewidth=\dimen124 +\lightrulewidth=\dimen125 +\cmidrulewidth=\dimen126 +\belowrulesep=\dimen127 +\belowbottomsep=\dimen128 +\aboverulesep=\dimen129 +\abovetopsep=\dimen130 +\cmidrulesep=\dimen131 +\cmidrulekern=\dimen132 +\defaultaddspace=\dimen133 +\@cmidla=\count123 +\@cmidlb=\count124 +\@aboverulesep=\dimen134 +\@belowrulesep=\dimen135 +\@thisruleclass=\count125 +\@lastruleclass=\count126 +\@thisrulewidth=\dimen136 +) (/usr/share/texlive/texmf-dist/tex/latex/tools/longtable.sty +Package: longtable 2014/10/28 v4.11 Multi-page Table package (DPC) +\LTleft=\skip141 +\LTright=\skip142 +\LTpre=\skip143 +\LTpost=\skip144 +\LTchunksize=\count127 +\LTcapwidth=\dimen137 +\LT@head=\box33 +\LT@firsthead=\box34 +\LT@foot=\box35 +\LT@lastfoot=\box36 +\LT@cols=\count128 +\LT@rows=\count129 +\c@LT@tables=\count130 +\c@LT@chunks=\count131 +\LT@p@ftn=\toks23 +) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Package: anyfontsize 2007/11/22 anyfontsize.sty by pts +) (/usr/share/texlive/texmf-dist/tex/latex/enumitem/enumitem.sty +Package: enumitem 2011/09/28 v3.5.2 Customized lists +\labelindent=\skip145 +\enit@outerparindent=\dimen138 +\enit@toks=\toks24 +\enit@inbox=\box37 +\enitdp@description=\count132 +) (/usr/share/texlive/texmf-dist/tex/latex/wrapfig/wrapfig.sty +\wrapoverhang=\dimen139 +\WF@size=\dimen140 +\c@WF@wrappedlines=\count133 +\WF@box=\box38 +\WF@everypar=\toks25 +Package: wrapfig 2003/01/31 v 3.6 +) (/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.sty (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty +Package: expl3 2016/01/19 v6377 L3 programming layer (loader) +(/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3-code.tex +Package: expl3 2016/01/19 v6377 L3 programming layer (code) +L3 Module: l3bootstrap 2016/01/01 v6339 L3 Bootstrap code +L3 Module: l3names 2015/12/21 v6328 L3 Namespace for primitives +L3 Module: l3basics 2015/11/22 v6315 L3 Basic definitions +L3 Module: l3expan 2015/09/10 v5983 L3 Argument expansion +L3 Module: l3tl 2015/09/29 v6121 L3 Token lists +L3 Module: l3str 2016/01/03 v6357 L3 Strings +L3 Module: l3seq 2015/08/05 v5777 L3 Sequences and stacks +L3 Module: l3int 2016/01/05 v6366 L3 Integers +\c_max_int=\count134 +\l_tmpa_int=\count135 +\l_tmpb_int=\count136 +\g_tmpa_int=\count137 +\g_tmpb_int=\count138 +L3 Module: l3quark 2015/08/17 v5855 L3 Quarks +L3 Module: l3prg 2015/11/01 v6216 L3 Control structures +\g__prg_map_int=\count139 +L3 Module: l3clist 2015/09/02 v5901 L3 Comma separated lists +L3 Module: l3token 2015/11/11 v6249 L3 Experimental token manipulation +L3 Module: l3prop 2016/01/05 v6366 L3 Property lists +L3 Module: l3msg 2015/09/28 v6113 L3 Messages +L3 Module: l3file 2015/12/03 v6317 L3 File and I/O operations +\l_iow_line_count_int=\count140 +\l__iow_target_count_int=\count141 +\l__iow_current_line_int=\count142 +\l__iow_current_word_int=\count143 +\l__iow_current_indentation_int=\count144 +L3 Module: l3skip 2016/01/05 v6366 L3 Dimensions and skips +\c_zero_dim=\dimen141 +\c_max_dim=\dimen142 +\l_tmpa_dim=\dimen143 +\l_tmpb_dim=\dimen144 +\g_tmpa_dim=\dimen145 +\g_tmpb_dim=\dimen146 +\c_zero_skip=\skip146 +\c_max_skip=\skip147 +\l_tmpa_skip=\skip148 +\l_tmpb_skip=\skip149 +\g_tmpa_skip=\skip150 +\g_tmpb_skip=\skip151 +\c_zero_muskip=\muskip12 +\c_max_muskip=\muskip13 +\l_tmpa_muskip=\muskip14 +\l_tmpb_muskip=\muskip15 +\g_tmpa_muskip=\muskip16 +\g_tmpb_muskip=\muskip17 +L3 Module: l3keys 2015/11/17 v6284 L3 Key-value interfaces +\g__keyval_level_int=\count145 +\l_keys_choice_int=\count146 +L3 Module: l3fp 2015/08/25 v5890 L3 Floating points +\c__fp_leading_shift_int=\count147 +\c__fp_middle_shift_int=\count148 +\c__fp_trailing_shift_int=\count149 +\c__fp_big_leading_shift_int=\count150 +\c__fp_big_middle_shift_int=\count151 +\c__fp_big_trailing_shift_int=\count152 +\c__fp_Bigg_leading_shift_int=\count153 +\c__fp_Bigg_middle_shift_int=\count154 +\c__fp_Bigg_trailing_shift_int=\count155 +L3 Module: l3box 2015/08/09 v5822 L3 Experimental boxes +\c_empty_box=\box39 +\l_tmpa_box=\box40 +\l_tmpb_box=\box41 +\g_tmpa_box=\box42 +\g_tmpb_box=\box43 +L3 Module: l3coffins 2015/08/06 v5789 L3 Coffin code layer +\l__coffin_internal_box=\box44 +\l__coffin_internal_dim=\dimen147 +\l__coffin_offset_x_dim=\dimen148 +\l__coffin_offset_y_dim=\dimen149 +\l__coffin_x_dim=\dimen150 +\l__coffin_y_dim=\dimen151 +\l__coffin_x_prime_dim=\dimen152 +\l__coffin_y_prime_dim=\dimen153 +\c_empty_coffin=\box45 +\l__coffin_aligned_coffin=\box46 +\l__coffin_aligned_internal_coffin=\box47 +\l_tmpa_coffin=\box48 +\l_tmpb_coffin=\box49 +\l__coffin_display_coffin=\box50 +\l__coffin_display_coord_coffin=\box51 +\l__coffin_display_pole_coffin=\box52 +\l__coffin_display_offset_dim=\dimen154 +\l__coffin_display_x_dim=\dimen155 +\l__coffin_display_y_dim=\dimen156 +L3 Module: l3color 2014/08/23 v5354 L3 Experimental color support +L3 Module: l3sys 2015/09/25 v6087 L3 Experimental system/runtime functions +L3 Module: l3candidates 2016/01/14 v6376 L3 Experimental additions to l3kernel +\l__box_top_dim=\dimen157 +\l__box_bottom_dim=\dimen158 +\l__box_left_dim=\dimen159 +\l__box_right_dim=\dimen160 +\l__box_top_new_dim=\dimen161 +\l__box_bottom_new_dim=\dimen162 +\l__box_left_new_dim=\dimen163 +\l__box_right_new_dim=\dimen164 +\l__box_internal_box=\box53 +\l__coffin_bounding_shift_dim=\dimen165 +\l__coffin_left_corner_dim=\dimen166 +\l__coffin_right_corner_dim=\dimen167 +\l__coffin_bottom_corner_dim=\dimen168 +\l__coffin_top_corner_dim=\dimen169 +\l__coffin_scaled_total_height_dim=\dimen170 +\l__coffin_scaled_width_dim=\dimen171 +L3 Module: l3luatex 2015/11/11 v6250 L3 Experimental LuaTeX-specific functions +) (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def +File: l3xdvidpfmx.def 2015/11/11 v6250 L3 Experimental driver: xdvipdfmx +)) (/usr/share/texlive/texmf-dist/tex/latex/l3packages/xparse/xparse.sty +Package: xparse 2016/01/19 v6377 L3 Experimental document command parser +\l__xparse_current_arg_int=\count156 +\l__xparse_m_args_int=\count157 +\l__xparse_mandatory_args_int=\count158 +\l__xparse_processor_int=\count159 +\l__xparse_v_nesting_int=\count160 +) +Package: fontspec 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec-xetex.sty +Package: fontspec-xetex 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +\l_fontspec_script_int=\count161 +\l_fontspec_language_int=\count162 +\l_fontspec_strnum_int=\count163 +\l__fontspec_tmpa_dim=\dimen172 +\l__fontspec_tmpb_dim=\dimen173 +\l__fontspec_tmpc_dim=\dimen174 +\g__file_internal_ior=\read1 +(/usr/share/texlive/texmf-dist/tex/latex/base/fontenc.sty +Package: fontenc 2005/09/27 v1.99g Standard LaTeX package +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1enc.def +File: eu1enc.def 2010/05/27 v0.1h Experimental Unicode font encodings +) +LaTeX Font Info: Try loading font information for EU1+lmr on input line 105. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmr.fd +File: eu1lmr.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) (/usr/share/texlive/texmf-dist/tex/xelatex/xunicode/xunicode.sty +File: xunicode.sty 2011/09/09 v0.981 provides access to latin accents and many other characters in Unicode lower plane +(/usr/share/texmf/tex/latex/tipa/t3enc.def +File: t3enc.def 2001/12/31 T3 encoding +LaTeX Font Info: Try loading font information for EU1+lmss on input line 357. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmss.fd +File: eu1lmss.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) +\tipaTiiicode=\count164 +\tipasavetokens=\toks26 +\tipachecktokens=\toks27 +) +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \__fontspec_post_arg:w with sig. 'mmO{}' on line 353. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \fontspec with sig. 'om' on line 355. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmainfont with sig. 'om' on line 365. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setsansfont with sig. 'om' on line 375. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmonofont with sig. 'om' on line 385. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathrm with sig. 'om' on line 399. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setboldmathrm with sig. 'om' on line 407. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathsf with sig. 'om' on line 415. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathtt with sig. 'om' on line 423. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfamily with sig. 'mom' on line 437. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontface with sig. 'mom' on line 453. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \defaultfontfeatures with sig. 't+om' on line 467. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \addfontfeatures with sig. 'm' on line 529. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfeature with sig. 'mm' on line 540. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newAATfeature with sig. 'mmmm' on line 548. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newopentypefeature with sig. 'mmm' on line 556. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeature with sig. 'mm' on line 577. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeatureoption with sig. 'mmm' on line 586. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontscript with sig. 'mm' on line 590. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontlanguage with sig. 'mm' on line 594. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \DeclareFontsExtensions with sig. 'm' on line 599. +................................................. +\l__fontspec_tmp_int=\count165 +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.cfg) +LaTeX Info: Redefining \itshape on input line 2705. +LaTeX Info: Redefining \slshape on input line 2710. +LaTeX Info: Redefining \scshape on input line 2715. +LaTeX Info: Redefining \upshape on input line 2720. +\l__fontspec_em_int=\count166 +\l__fontspec_emdef_int=\count167 +LaTeX Info: Redefining \em on input line 2736. +LaTeX Info: Redefining \emph on input line 2742. +LaTeX Info: Redefining \- on input line 2746. +................................................. +. LaTeX info: "xparse/redefine-command" +. +. Redefining command \oldstylenums with sig. 'm' on line 2841. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \liningnums with sig. 'm' on line 2845. +................................................. +)) +Package hyperref Info: Option `colorlinks' set `true' on input line 87. +\px=\skip152 +\c@md@targetcount=\count168 +\mdcompactskip=\skip153 +\mdcompacttopsep=\skip154 +\dim@rem=\skip155 +\dim@ch=\skip156 +\md@height=\skip157 +\dim@marginbottom=\skip158 +\dim@paddingbottom=\skip159 +\md@interaction=\count169 +\mddefinitionsskip=\skip160 +\md@captionlen=\skip161 +\mdtoclevel=\count170 +\c@mdtoclevelbold=\count171 +\c@mdtocleveldots=\count172 +\mdtocskip=\skip162 +\mdpreskip=\skip163 +\presp=\skip164 +LaTeX Font Info: Try loading font information for EU1+lmtt on input line 801. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmtt.fd +File: eu1lmtt.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +\md@postskip=\skip165 +\ppresp=\skip166 +\md@thmcaption=\box54 +\md@defaultcolwidth=\skip167 +\mdtabularskip=\skip168 +\mdbibindentunit=\skip169 +\c@md@authorcount=\count173 +\c@mdx@authorcount=\count174 +\c@@mdTargetCount=\count175 +\@snippetBox=\box55 +\@snippetWidth=\skip170 +\@snippetHeight=\skip171 +\@snippetDepth=\skip172 +\c@snippets=\count176 +) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty +Package: geometry 2010/09/12 v5.6 Page Geometry +\Gm@cnth=\count177 +\Gm@cntv=\count178 +\c@Gm@tempcnt=\count179 +\Gm@bindingoffset=\dimen175 +\Gm@wd@mp=\dimen176 +\Gm@odd@mp=\dimen177 +\Gm@even@mp=\dimen178 +\Gm@layoutwidth=\dimen179 +\Gm@layoutheight=\dimen180 +\Gm@layouthoffset=\dimen181 +\Gm@layoutvoffset=\dimen182 +\Gm@dimlist=\toks28 +) (/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +\fancy@headwidth=\skip173 +\f@ncyO@elh=\skip174 +\f@ncyO@erh=\skip175 +\f@ncyO@olh=\skip176 +\f@ncyO@orh=\skip177 +\f@ncyO@elf=\skip178 +\f@ncyO@erf=\skip179 +\f@ncyO@olf=\skip180 +\f@ncyO@orf=\skip181 +) (build/P4Runtime-Spec.aux + +LaTeX Warning: Label `sec-example' multiply defined. + +) +\openout1 = `P4Runtime-Spec.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for TS1+cmr on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1cmr.fd +File: ts1cmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions +) +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for EU1/lmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T3/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for T3+cmr on input line 14. +(/usr/share/texmf/tex/latex/tipa/t3cmr.fd +File: t3cmr.fd 2001/12/31 TIPA font definitions +) +LaTeX Font Info: ... okay on input line 14. +\AtBeginShipoutBox=\box56 +Package hyperref Info: Link coloring ON on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2012/10/27 v2.43 Cross-referencing by name of section +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO) +) +\c@section@level=\count180 +) +LaTeX Info: Redefining \ref on input line 14. +LaTeX Info: Redefining \pageref on input line 14. +LaTeX Info: Redefining \nameref on input line 14. +................................................. +. fontspec info: "setup-math" +. +. Adjusting the maths setup (use [no-math] to avoid this). +................................................. +\symlegacymaths=\mathgroup7 +LaTeX Font Info: Overwriting symbol font `legacymaths' in version `bold' +(Font) OT1/cmr/m/n --> OT1/cmr/bx/n on input line 14. +LaTeX Font Info: Redeclaring math accent \acute on input line 14. +LaTeX Font Info: Redeclaring math accent \grave on input line 14. +LaTeX Font Info: Redeclaring math accent \ddot on input line 14. +LaTeX Font Info: Redeclaring math accent \tilde on input line 14. +LaTeX Font Info: Redeclaring math accent \bar on input line 14. +LaTeX Font Info: Redeclaring math accent \breve on input line 14. +LaTeX Font Info: Redeclaring math accent \check on input line 14. +LaTeX Font Info: Redeclaring math accent \hat on input line 14. +LaTeX Font Info: Redeclaring math accent \dot on input line 14. +LaTeX Font Info: Redeclaring math accent \mathring on input line 14. +LaTeX Font Info: Redeclaring math symbol \Gamma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Delta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Theta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Lambda on input line 14. +LaTeX Font Info: Redeclaring math symbol \Xi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Pi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Sigma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Upsilon on input line 14. +LaTeX Font Info: Redeclaring math symbol \Phi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Psi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Omega on input line 14. +LaTeX Font Info: Redeclaring math symbol \mathdollar on input line 14. +LaTeX Font Info: Redeclaring symbol font `operators' on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `normal' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/cmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `bold' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/cmr/bx/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) EU1/lmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/cmr/m/it --> EU1/lmr/m/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/cmr/bx/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/cmss/m/n --> EU1/lmss/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/cmtt/m/n --> EU1/lmtt/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) EU1/lmr/m/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' +(Font) OT1/cmr/bx/it --> EU1/lmr/bx/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/cmss/bx/n --> EU1/lmss/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/cmtt/m/n --> EU1/lmtt/bx/n on input line 14. +*geometry* driver: auto-detecting +*geometry* detected driver: xetex +*geometry* verbose mode - [ preamble ] result: +* driver: xetex +* paper: +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: +* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt) +* v-part:(T,H,B)=(72.26999pt, 632.3625pt, 90.3375pt) +* \paperwidth=614.295pt +* \paperheight=794.96999pt +* \textwidth=469.75502pt +* \textheight=632.3625pt +* \oddsidemargin=0.0pt +* \evensidemargin=0.0pt +* \topmargin=-37.0pt +* \headheight=30.0pt +* \headsep=25.0pt +* \topskip=11.0pt +* \footskip=30.0pt +* \marginparwidth=59.0pt +* \marginparsep=10.0pt +* \columnsep=10.0pt +* \skip\footins=10.0pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +resolve font stack: UtopiaStd-Regular + +\g__fontspec_family_UtopiaStd-Regular_int=\count181 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'UtopiaStd-Regular(0)' created for font 'UtopiaStd-Regular' with +. options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;" +. - 'small caps' (m/sc) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;+smcp;" +................................................. + +resolved font stack 'UtopiaStd-Regular' to: UtopiaStd-Regular +LaTeX Font Info: Try loading font information for U+msa on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Try loading font information for U+msb on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Try loading font information for U+stmry on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/Ustmry.fd) + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/bx/n' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 35. + +resolve font stack: LuxiMono + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +\g__fontspec_family_LuxiMono_int=\count182 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'LuxiMono(0)' created for font 'LuxiMono' with options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: <->"LuxiMono/OT:" +. - 'small caps' (m/sc) with NFSS spec.: +................................................. + +resolved font stack 'LuxiMono' to: LuxiMono +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/se-ascii-print.def +File: se-ascii-print.def 2011/12/02 v1.10 stringenc: Printable ASCII characters +) [1 + +] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[2] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <10.95> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 299. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Font Warning: Font shape `EU1/LuxiMono(0)/bx/n' undefined +(Font) using `EU1/LuxiMono(0)/m/n' instead on input line 299. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[3] + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/m/it' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 509. + +[4] [5] [6] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[7] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/reference-architecture.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[8] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[9] +File: build/single-embedded-controller.png Graphic file (type QTm) + [10] +File: build/single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-controllers.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-ha-controllers.png Graphic file (type QTm) + [11] [12] [13] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[14] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[15] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <12> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 1493. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1493. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1493. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[16] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[17] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (53.84203pt too wide) in paragraph at lines 1790--1793 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For all slave controllers, \EU1/LuxiMono(0)/bx/n/8.2125 status \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set to non-OK (with \EU1/LuxiMono(0)/bx/n/8.2125 status.code \EU1/UtopiaStd-Regular(0)/m/it/10.95 set to \EU1/LuxiMono(0)/bx/n/8.2125 google.rpc.ALREADY_EXISTS\EU1/UtopiaStd-Regular(0)/m/it/10.95 ). + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[18] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1827. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1827. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1851. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1851. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[19] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1895. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1895. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[20] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[21] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[22] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2178. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2178. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[23] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2233. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2233. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[24] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[25] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[26] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (12.45624pt too wide) in paragraph at lines 2464--2477 + [] + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2500. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[27] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[28] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2691. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2691. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2751. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[29] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2824. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[30] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2905. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2905. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.59204pt too wide) in paragraph at lines 2959--2961 +[]\EU1/LuxiMono(0)/bx/n/8.2125 BYTES\EU1/UtopiaStd-Regular(0)/m/it/10.95 , which signifies that this meter can be configured with rates expressed in bytes/second. + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2984. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2984. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[31] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (18.74199pt too wide) in paragraph at lines 3001--3008 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 carrying P4 standard annotations \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_in") \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_out")\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[32] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3143. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3143. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[33] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[34] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[35] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3371. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3418. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3418. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[36] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3456. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[37] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[38] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[39] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[40] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[41] [42] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1629) in paragraph at lines 4060--4062 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For example, the following P4$[]$ objects involve complex types that need to be exposed in + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[43] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1454) in paragraph at lines 4108--4117 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 ification for all the named types in the P4$[]$ program. These named types are \EU1/LuxiMono(0)/bx/n/8.2125 struct\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 header\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + + +Underfull \hbox (badness 1831) in paragraph at lines 4108--4117 +\EU1/LuxiMono(0)/bx/n/8.2125 header_union\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 enum \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 serializable_enum\EU1/UtopiaStd-Regular(0)/m/it/10.95 ; for each of these we have a type specification mes- + [] + + +Underfull \hbox (badness 1845) in paragraph at lines 4108--4117 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 sage, respectively \EU1/LuxiMono(0)/bx/n/8.2125 P4StructTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnionTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4EnumTypeSpec \EU1/UtopiaStd-Regular(0)/m/it/10.95 and + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (33.06564pt too wide) in paragraph at lines 4143--4150 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 “binary string” types (\EU1/LuxiMono(0)/bx/n/8.2125 bit\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 int\EU1/UtopiaStd-Regular(0)/m/it/10.95 , and \EU1/LuxiMono(0)/bx/n/8.2125 varbit\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) are grouped together in the \EU1/LuxiMono(0)/bx/n/8.2125 P4BitstringLikeTypeSpec + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4160. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4160. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[44] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.46094pt too wide) in paragraph at lines 4197--4200 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 An invalid header union (i.e. all headers in the union are invalid) is represented by a \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnion + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[45] [46] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4334. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4334. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[47] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (24.68944pt too wide) in paragraph at lines 4422--4428 +[]\EU1/LuxiMono(0)/bx/n/8.2125 translated_type\EU1/UtopiaStd-Regular(0)/m/it/10.95 , if and only if the P4 \EU1/LuxiMono(0)/bx/n/8.2125 type \EU1/UtopiaStd-Regular(0)/m/it/10.95 declaration was annotated with \EU1/LuxiMono(0)/bx/n/8.2125 @p4runtime_translation\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[48] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[49] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (32.59732pt too wide) in paragraph at lines 4530--4536 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 in \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.MatchField\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.Action.Param \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.ControllerPacketMetadata.Metadata\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[50] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4637. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4637. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[51] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[52] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[53] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[54] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.53593pt too wide) in paragraph at lines 5093--5096 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 If the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 does not match the table description in the P4Info (e.g. the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 is \EU1/LuxiMono(0)/bx/n/8.2125 action_profile_member_id + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[55] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[56] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[57] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[58] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[59] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[60] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5666. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5666. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[61] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[62] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[63] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (9.29865pt too wide) in paragraph at lines 5949--5951 + []\EU1/lmr/bx/n/10.95 9.2.2.1.| Rules on Setting \EU1/LuxiMono(0)/bx/n/8.2125 max_size[] \EU1/UtopiaStd-Regular(0)/m/it/10.95 The valid values for \EU1/LuxiMono(0)/bx/n/8.2125 max_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 depend on the static \EU1/LuxiMono(0)/bx/n/8.2125 max_group_size + [] + +[64] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[65] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[66] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[67] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6237. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6237. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6277. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6277. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1331) in paragraph at lines 6280--6287 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 A direct counter is a direct resource associated with a \EU1/LuxiMono(0)/bx/n/8.2125 TableEntry \EU1/UtopiaStd-Regular(0)/m/it/10.95 (see [][]Direct Resources[][]). The + [] + +[68] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6354. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6354. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[69] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6447. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6447. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6478. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6478. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[70] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6555. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6555. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 6596. + + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 6596. + +[71] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6651. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6661. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6661. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[72] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[73] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6785. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6785. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[74] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.93839pt too wide) in paragraph at lines 6896--6898 +[]\EU1/LuxiMono(0)/bx/n/8.2125 MODIFY\EU1/UtopiaStd-Regular(0)/m/it/10.95 : Modify the attributes of a given clone session entry, indexed by the given \EU1/LuxiMono(0)/bx/n/8.2125 clone_session_id\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[75] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6934. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[76] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7070. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7070. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[77] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7114. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7114. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[78] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[79] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7312. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7312. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[80] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/error-report.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[81] +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <14.4> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 7436. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7436. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7436. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: Hyper reference `wildcard-reads' on page 82 undefined on input line 7458. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[82] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7538. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[83] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[84] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[85] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (34.34796pt too wide) in paragraph at lines 7822--7827 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If an error is encountered before even trying to attempt individual batch updates, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.66206pt too wide) in paragraph at lines 7831--7842 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 Otherwise, if one or more updates in the batch (\EU1/LuxiMono(0)/bx/n/8.2125 WriteRequest.updates\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) failed, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[86] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7878. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7878. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[87] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[88] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.4752pt too wide) in paragraph at lines 8107--8111 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 responding to \EU1/LuxiMono(0)/bx/n/8.2125 a \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 c\EU1/UtopiaStd-Regular(0)/m/it/10.95 , followed by a status \EU1/LuxiMono(0)/bx/n/8.2125 {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[89] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8193. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[90] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8316. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[91] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 8414--8417 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If a P4Runtime server supports both \EU1/LuxiMono(0)/bx/n/8.2125 SetForwardingPipelineConfig \EU1/UtopiaStd-Regular(0)/m/it/10.95 as well as returning the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[92] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[93] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[94] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[95] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[96] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8777. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8777. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[97] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8845. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8845. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/psa-metadata-translation.png Graphic file (type QTm) + [98] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[99] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[100] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[101] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[102] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[103] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 9355--9362 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 p4info-ext should include a Protobuf message definition for every extern type that can + [] + +[104] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 4036) in paragraph at lines 9410--9417 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 P4Runtime also supports streaming arbitrary Protobuf messages between the server and the + [] + + +Underfull \hbox (badness 1629) in paragraph at lines 9410--9417 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 client, by including an \EU1/LuxiMono(0)/bx/n/8.2125 Any \EU1/UtopiaStd-Regular(0)/m/it/10.95 Protobuf field [[][]31[][]] named \EU1/LuxiMono(0)/bx/n/8.2125 other \EU1/UtopiaStd-Regular(0)/m/it/10.95 in both \EU1/LuxiMono(0)/bx/n/8.2125 p4.v1.StreamMessageRequest + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[105] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[106] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1997) in paragraph at lines 9656--9658 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 Table [][]7[][] lists P4$[]$ annotations introduced primarily for the purpose of adding features for the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[107] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[108] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[109] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.61781pt too wide) in paragraph at lines 9803--9810 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 In gRPC, the status of a RPC request is sent as metadata, whose size is limited by the \EU1/LuxiMono(0)/bx/n/8.2125 grpc.max_metadata_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[110] +Underfull \hbox (badness 10000) in paragraph at lines 9894--9895 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Complex Types in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- p4- + [] + + +Underfull \hbox (badness 4001) in paragraph at lines 9906--9907 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Google Cloud APIs Versioning - Backwards-Compatibility.” [][]\EU1/lmtt/m/n/10.95 https:// cloud. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9915--9916 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “gRPC Streaming RPCs in C++.” [][]\EU1/lmtt/m/n/10.95 https:// grpc. io/ docs/ tutorials/ basic/ c. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9927--9928 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “P4 Concurrency Model.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9930--9931 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9945--9946 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Protobuf OneOf Backwards-Compatibility Issues.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + +[111] +Underfull \hbox (badness 10000) in paragraph at lines 9951--9952 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Action Selector.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# sec- action- + [] + + +Underfull \hbox (badness 2409) in paragraph at lines 9960--9961 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Empty Group Action Appendix.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9963--9964 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Select Expressions in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 1668) in paragraph at lines 9978--9979 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Any Protobuf Message.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ protocol- buffers/ docs/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9984--9985 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC C++ Error Details Library.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ grpc/ grpc/ blob/ master/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9987--9988 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC Canonical Status Codes.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ maps- booking/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9993--9994 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Protobuf MessageDifferencer in the C++ API.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9999--10000 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “v1model Architecture Definition.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ p4lang/ p4c/ blob/ master/ + [] + +[112] +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 10008. +[113] +Package atveryend Info: Empty hook `AfterLastShipout' on input line 10008. +(build/P4Runtime-Spec.aux) +Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 10008. +Package atveryend Info: Empty hook `AtEndAfterFileList' on input line 10008. + +LaTeX Font Warning: Some font shapes were not available, defaults substituted. + + +LaTeX Warning: There were undefined references. + + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 27547 strings out of 493638 + 517856 string characters out of 6146796 + 566446 words of memory out of 5000000 + 30649 multiletter control sequences out of 15000+600000 + 14633 words of font info for 98 fonts, out of 8000000 for 9000 + 1328 hyphenation exceptions out of 8191 + 48i,19n,81p,10429b,902s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on build/P4Runtime-Spec.pdf (113 pages). diff --git a/spec/v1.2.0/P4Runtime-Spec.pdf b/spec/v1.2.0/P4Runtime-Spec.pdf new file mode 100644 index 00000000..80b89d50 Binary files /dev/null and b/spec/v1.2.0/P4Runtime-Spec.pdf differ diff --git a/spec/v1.2.0/P4Runtime-Spec.tex b/spec/v1.2.0/P4Runtime-Spec.tex new file mode 100644 index 00000000..d9c40891 --- /dev/null +++ b/spec/v1.2.0/P4Runtime-Spec.tex @@ -0,0 +1,10008 @@ +\documentclass[11pt]{article} +% generated by Madoko, version 1.1.4 +%mdk-data-line={1} + + +\usepackage[heading-base={2},section-num={False},bib-label={hide},fontspec={True}]{madoko2} +\usepackage[top=1in, bottom=1.25in, left=1in, right=1in]{geometry} +\usepackage{fancyhdr} +%mdk-data-line={11} + + \setlength{\headheight}{30pt} + \setlength{\emergencystretch}{2em} + +\begin{document} + + + +{\mdfontfamily{UtopiaStd-Regular} +%mdk-data-line={203} +\mdxtitleblockstart{} +%mdk-data-line={203} +\mdxtitle{{\sffamily{\bfseries\mdline{203}P4Runtime Specification}}}%mdk + +%mdk-data-line={206} +\mdxtitlenote{{\sffamily{\bfseries\mdline{206}version 1.2.0}}}%mdk +\mdxauthorstart{} +%mdk-data-line={211} +\mdxauthorname{\mdline{211}The P4.org API Working Group}%mdk +\mdxauthorend +%mdk-data-line={220} +\mdxtitlefooter{{\sffamily{\bfseries\mdline{220}2020-07-06}}}%mdk +\mdtitleauthorrunning{}{}\mdxtitleblockend%mdk + +%mdk-data-line={205} +\begin{abstract}%mdk + +%mdk-data-line={206} +\noindent\mdline{206}P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.%mdk +%mdk +\end{abstract}%mdk +\mdline{214} +\begin{mdtoc}%mdk + +\section*{Contents}\label{sec-contents}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-introduction-and-scope}{\mdref{sec-introduction-and-scope}{1.\hspace*{0.5em}Introduction and Scope}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-language-version-applicability}{\mdref{sec-p4-language-version-applicability}{1.1.\hspace*{0.5em}P4 Language Version Applicability}}%mdk + +\mdtocitemx{sec-in-scope}{\mdref{sec-in-scope}{1.2.\hspace*{0.5em}In Scope}}%mdk + +\mdtocitemx{sec-not-in-scope}{\mdref{sec-not-in-scope}{1.3.\hspace*{0.5em}Not In Scope}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-terms-and-definitions}{\mdref{sec-terms-and-definitions}{2.\hspace*{0.5em}Terms and Definitions}}%mdk + +\mdtocitemx{sec-reference-architecture}{\mdref{sec-reference-architecture}{3.\hspace*{0.5em}Reference Architecture}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-idealized-workflow}{\mdref{sec-idealized-workflow}{3.1.\hspace*{0.5em}Idealized Workflow}}%mdk + +\mdtocitemx{sec-p4-as-behavioral-description-language}{\mdref{sec-p4-as-behavioral-description-language}{3.2.\hspace*{0.5em}P4 as a Behavioral Description Language}}%mdk + +\mdtocitemx{sec-alternative-workflows}{\mdref{sec-alternative-workflows}{3.3.\hspace*{0.5em}Alternative Workflows}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{\mdref{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{3.3.1.\hspace*{0.5em}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}}%mdk + +\mdtocitemx{sec-no-p4-source-available-p4info-available}{\mdref{sec-no-p4-source-available-p4info-available}{3.3.2.\hspace*{0.5em}No P4 Source Available, P4Info Available}}%mdk + +\mdtocitemx{sec-partial-p4info-and-p4-source-are-available}{\mdref{sec-partial-p4info-and-p4-source-are-available}{3.3.3.\hspace*{0.5em}Partial P4Info and P4 Source are Available}}%mdk + +\mdtocitemx{sec-p4info-role-based-subsets}{\mdref{sec-p4info-role-based-subsets}{3.3.4.\hspace*{0.5em}P4Info Role-Based Subsets}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-restarts}{\mdref{sec-restarts}{3.4.\hspace*{0.5em}P4Runtime State Across Restarts}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-controller-use-cases}{\mdref{sec-controller-use-cases}{4.\hspace*{0.5em}Controller Use-cases}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-single-embedded-controller}{\mdref{sec-single-embedded-controller}{4.1.\hspace*{0.5em}Single Embedded Controller}}%mdk + +\mdtocitemx{sec-single-remote-controller}{\mdref{sec-single-remote-controller}{4.2.\hspace*{0.5em}Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-single-remote-controller}{\mdref{sec-embedded-single-remote-controller}{4.3.\hspace*{0.5em}Embedded + Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-two-remote-controllers}{\mdref{sec-embedded-two-remote-controllers}{4.4.\hspace*{0.5em}Embedded + Two Remote Controllers}}%mdk + +\mdtocitemx{sec-embedded-controller-two-high-availability-remote-controllers}{\mdref{sec-embedded-controller-two-high-availability-remote-controllers}{4.5.\hspace*{0.5em}Embedded Controller + Two High-Availability Remote Controllers}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-master-slave-arbitration-and-controller-replication}{\mdref{sec-master-slave-arbitration-and-controller-replication}{5.\hspace*{0.5em}Master-Slave Arbitration and Controller Replication}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-default-role}{\mdref{sec-default-role}{5.1.\hspace*{0.5em}Default Role}}%mdk + +\mdtocitemx{sec-arbitration-role-config}{\mdref{sec-arbitration-role-config}{5.2.\hspace*{0.5em}Role Config}}%mdk + +\mdtocitemx{sec-mastership-updates}{\mdref{sec-mastership-updates}{5.3.\hspace*{0.5em}Rules for Handling \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}} Messages Received from Controllers}}%mdk + +\mdtocitemx{sec-mastership-notification}{\mdref{sec-mastership-notification}{5.4.\hspace*{0.5em}Mastership Notifications}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-the-p4info-message}{\mdref{sec-the-p4info-message}{6.\hspace*{0.5em}The P4Info Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-common-messages}{\mdref{sec-common-messages}{6.1.\hspace*{0.5em}Common Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-documentation-message}{\mdref{sec-documentation-message}{6.1.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}} Message}}%mdk + +\mdtocitemx{sec-preamble-message}{\mdref{sec-preamble-message}{6.1.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}} Message}}%mdk + +\mdtocitemx{sec-annotating-p4-entities-with-documentation}{\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3.\hspace*{0.5em}Annotating P4 Entities with \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}}%mdk + +\mdtocitemx{sec-structured-annotations}{\mdref{sec-structured-annotations}{6.1.4.\hspace*{0.5em}Structured Annotations}}%mdk + +\mdtocitemx{sec-sourcelocation-message}{\mdref{sec-sourcelocation-message}{6.1.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}} Message}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-pkginfo-message}{\mdref{sec-pkginfo-message}{6.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}} Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-annotating-p4-code-with-pkginfo}{\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1.\hspace*{0.5em}Annotating P4 code with PkgInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-id-allocation}{\mdref{sec-id-allocation}{6.3.\hspace*{0.5em}ID Allocation for P4Info Objects}}%mdk + +\mdtocitemx{sec-p4info-objects}{\mdref{sec-p4info-objects}{6.4.\hspace*{0.5em}P4Info Objects}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table}{\mdref{sec-table}{6.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}}%mdk + +\mdtocitemx{sec-action}{\mdref{sec-action}{6.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}}%mdk + +\mdtocitemx{sec-p4info-action-profile}{\mdref{sec-p4info-action-profile}{6.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}}%mdk + +\mdtocitemx{sec-counter-directcounter}{\mdref{sec-counter-directcounter}{6.4.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}}%mdk + +\mdtocitemx{sec-meter-directmeter}{\mdref{sec-meter-directmeter}{6.4.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}}%mdk + +\mdtocitemx{sec-controller-packet-meta}{\mdref{sec-controller-packet-meta}{6.4.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}}%mdk + +\mdtocitemx{sec-valueset}{\mdref{sec-valueset}{6.4.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}}%mdk + +\mdtocitemx{sec-register}{\mdref{sec-register}{6.4.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}}%mdk + +\mdtocitemx{sec-digest}{\mdref{sec-digest}{6.4.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}}%mdk + +\mdtocitemx{sec-p4info-extern}{\mdref{sec-p4info-extern}{6.4.10.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{\mdref{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{6.5.\hspace*{0.5em}Support for Arbitrary P4 Types with P4TypeInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-fwd-pipe-config}{\mdref{sec-p4-fwd-pipe-config}{7.\hspace*{0.5em}P4 Forwarding-Pipeline Configuration}}%mdk + +\mdtocitemx{sec-general-principles-for-message-formatting}{\mdref{sec-general-principles-for-message-formatting}{8.\hspace*{0.5em}General Principles for Message Formatting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-set-unset-protobuf-field}{\mdref{sec-set-unset-protobuf-field}{8.1.\hspace*{0.5em}Set / Unset Protobuf Field}}%mdk + +\mdtocitemx{sec-read-write-symmetry}{\mdref{sec-read-write-symmetry}{8.2.\hspace*{0.5em}Read-Write Symmetry}}%mdk + +\mdtocitemx{sec-zero-as-reserved-value}{\mdref{sec-zero-as-reserved-value}{8.3.\hspace*{0.5em}Zero as Reserved Value}}%mdk + +\mdtocitemx{sec-bytestrings}{\mdref{sec-bytestrings}{8.4.\hspace*{0.5em}Bytestrings}}%mdk + +\mdtocitemx{sec-representation-of-arbitrary-p4-types}{\mdref{sec-representation-of-arbitrary-p4-types}{8.5.\hspace*{0.5em}Representation of Arbitrary P4 Types}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-problem-statement}{\mdref{sec-problem-statement}{8.5.1.\hspace*{0.5em}Problem Statement}}%mdk + +\mdtocitemx{sec-p4-type-specifications-in-p4infoproto}{\mdref{sec-p4-type-specifications-in-p4infoproto}{8.5.2.\hspace*{0.5em}P4 Type Specifications in p4info.proto}}%mdk + +\mdtocitemx{sec-p4data-in-p4runtime-proto}{\mdref{sec-p4data-in-p4runtime-proto}{8.5.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}} in p4runtime.proto}}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{8.5.4.\hspace*{0.5em}Example}}%mdk + +\mdtocitemx{sec-enum-serializable-enum-and-error}{\mdref{sec-enum-serializable-enum-and-error}{8.5.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}, serializable \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}}%mdk + +\mdtocitemx{sec-user-defined-types}{\mdref{sec-user-defined-types}{8.5.6.\hspace*{0.5em}User-defined types}}%mdk + +\mdtocitemx{sec-trade-off-for-v1x-releases}{\mdref{sec-trade-off-for-v1x-releases}{8.5.7.\hspace*{0.5em}Trade-off for v1.x Releases}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-entity-msgs}{\mdref{sec-p4-entity-msgs}{9.\hspace*{0.5em}P4 Entity Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table-entry}{\mdref{sec-table-entry}{9.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-match-format}{\mdref{sec-match-format}{9.1.1.\hspace*{0.5em}Match Format}}%mdk + +\mdtocitemx{sec-action-specification}{\mdref{sec-action-specification}{9.1.2.\hspace*{0.5em}Action Specification}}%mdk + +\mdtocitemx{sec-default-entry}{\mdref{sec-default-entry}{9.1.3.\hspace*{0.5em}Default Entry}}%mdk + +\mdtocitemx{sec-constant-tables}{\mdref{sec-constant-tables}{9.1.4.\hspace*{0.5em}Constant Tables}}%mdk + +\mdtocitemx{sec-table-wildcard-reads}{\mdref{sec-table-wildcard-reads}{9.1.5.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-direct-resources}{\mdref{sec-direct-resources}{9.1.6.\hspace*{0.5em}Direct Resources}}%mdk + +\mdtocitemx{sec-idle-timeout}{\mdref{sec-idle-timeout}{9.1.7.\hspace*{0.5em}Idle-timeout}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-and-group}{\mdref{sec-action-profile-member-and-group}{9.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-programming}{\mdref{sec-action-profile-member-programming}{9.2.1.\hspace*{0.5em}Action Profile Member Programming}}%mdk + +\mdtocitemx{sec-action-profile-group-programming}{\mdref{sec-action-profile-group-programming}{9.2.2.\hspace*{0.5em}Action Profile Group Programming}}%mdk + +\mdtocitemx{sec-oneshot}{\mdref{sec-oneshot}{9.2.3.\hspace*{0.5em}One Shot Action Selector Programming}}%mdk + +\mdtocitemx{action-selector-constraints}{\mdref{action-selector-constraints}{9.2.4.\hspace*{0.5em}Constraints on action selector programming}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-counterentry-directcounterentry}{\mdref{sec-counterentry-directcounterentry}{9.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directcounterentry}{\mdref{sec-directcounterentry}{9.3.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\mdtocitemx{sec-counterentry}{\mdref{sec-counterentry}{9.3.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-meterentry-directmeterentry}{\mdref{sec-meterentry-directmeterentry}{9.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directmeterentry}{\mdref{sec-directmeterentry}{9.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\mdtocitemx{sec-meterentry}{\mdref{sec-meterentry}{9.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-packetreplicationengineentry}{\mdref{sec-packetreplicationengineentry}{9.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-multicastgroupentry}{\mdref{sec-multicastgroupentry}{9.5.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}}%mdk + +\mdtocitemx{sec-clonesessionentry}{\mdref{sec-clonesessionentry}{9.5.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-valuesetentry}{\mdref{sec-valuesetentry}{9.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}}%mdk + +\mdtocitemx{sec-registerentry}{\mdref{sec-registerentry}{9.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}}%mdk + +\mdtocitemx{sec-digestentry}{\mdref{sec-digestentry}{9.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}}%mdk + +\mdtocitemx{sec-extern-entry}{\mdref{sec-extern-entry}{9.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-error-reporting-messages}{\mdref{sec-error-reporting-messages}{10.\hspace*{0.5em}Error Reporting Messages}}%mdk + +\mdtocitemx{sec-atomicity-of-individual-write-and-read-operations}{\mdref{sec-atomicity-of-individual-write-and-read-operations}{11.\hspace*{0.5em}Atomicity of Individual \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} Operations}}%mdk + +\mdtocitemx{sec-write-rpc}{\mdref{sec-write-rpc}{12.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-batching-and-ordering-of-updates}{\mdref{sec-batching-and-ordering-of-updates}{12.1.\hspace*{0.5em}Batching and Ordering of Updates}}%mdk + +\mdtocitemx{sec-batch-atomicity}{\mdref{sec-batch-atomicity}{12.2.\hspace*{0.5em}Batch Atomicity}}%mdk + +\mdtocitemx{sec-error-reporting}{\mdref{sec-error-reporting}{12.3.\hspace*{0.5em}Error Reporting}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-read-rpc}{\mdref{sec-read-rpc}{13.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-nomenclature}{\mdref{sec-nomenclature}{13.1.\hspace*{0.5em}Nomenclature}}%mdk + +\mdtocitemx{sec-wildcard-reads}{\mdref{sec-wildcard-reads}{13.2.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-batch-processing}{\mdref{sec-batch-processing}{13.3.\hspace*{0.5em}Batch Processing}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{13.3.1.\hspace*{0.5em}Example}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-parallelism-of-read-and-write-requests}{\mdref{sec-parallelism-of-read-and-write-requests}{13.4.\hspace*{0.5em}Parallelism of Read and Write Requests}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-setforwardingpipelineconfig-rpc}{\mdref{sec-setforwardingpipelineconfig-rpc}{14.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-getforwardingpipelineconfig-rpc}{\mdref{sec-getforwardingpipelineconfig-rpc}{15.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-p4runtime-stream-messages}{\mdref{sec-p4runtime-stream-messages}{16.\hspace*{0.5em}P4Runtime Stream Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-packet-i_o}{\mdref{sec-packet-i_o}{16.1.\hspace*{0.5em}Packet I/O}}%mdk + +\mdtocitemx{sec-master-arbitration-update}{\mdref{sec-master-arbitration-update}{16.2.\hspace*{0.5em}Master Arbitration Update}}%mdk + +\mdtocitemx{sec-digest-messages}{\mdref{sec-digest-messages}{16.3.\hspace*{0.5em}Digest Messages}}%mdk + +\mdtocitemx{sec-table-idle-timeout-notification}{\mdref{sec-table-idle-timeout-notification}{16.4.\hspace*{0.5em}Table Idle Timeout Notification}}%mdk + +\mdtocitemx{sec-architecture-specific-notifications}{\mdref{sec-architecture-specific-notifications}{16.5.\hspace*{0.5em}Architecture-Specific Notifications}}%mdk + +\mdtocitemx{sec-stream-error-reporting}{\mdref{sec-stream-error-reporting}{16.6.\hspace*{0.5em}Stream Error Reporting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-examples-of-streamerror-messages}{\mdref{sec-examples-of-streamerror-messages}{16.6.1.\hspace*{0.5em}Examples of \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}} Messages}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-capabilities-rpc}{\mdref{sec-capabilities-rpc}{17.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}} RPC}}%mdk + +\mdtocitemx{sec-portability-considerations}{\mdref{sec-portability-considerations}{18.\hspace*{0.5em}Portability Considerations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-psa-metadata-translation}{\mdref{sec-psa-metadata-translation}{18.1.\hspace*{0.5em}PSA Metadata Translation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-translation-of-port-numbers}{\mdref{sec-translation-of-port-numbers}{18.1.1.\hspace*{0.5em}Translation of Port Numbers}}%mdk + +\mdtocitemx{sec-translation-of-packet-io-header-fields}{\mdref{sec-translation-of-packet-io-header-fields}{18.1.2.\hspace*{0.5em}Translation of Packet-IO Header Fields}}%mdk + +\mdtocitemx{sec-translation-of-match-fields}{\mdref{sec-translation-of-match-fields}{18.1.3.\hspace*{0.5em}Translation of Match Fields}}%mdk + +\mdtocitemx{sec-translation-of-action-parameters}{\mdref{sec-translation-of-action-parameters}{18.1.4.\hspace*{0.5em}Translation of Action Parameters}}%mdk + +\mdtocitemx{sec-port-translation-for-psa-extern-apis}{\mdref{sec-port-translation-for-psa-extern-apis}{18.1.5.\hspace*{0.5em}Port Translation for PSA Extern APIs}}%mdk + +\mdtocitemx{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{\mdref{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{18.1.6.\hspace*{0.5em}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-versioning}{\mdref{sec-p4runtime-versioning}{19.\hspace*{0.5em}P4Runtime Versioning}}%mdk + +\mdtocitemx{sec-extending-p4runtime}{\mdref{sec-extending-p4runtime}{20.\hspace*{0.5em}Extending P4Runtime for non-PSA Architectures}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-p4runtime-for-architecture-specific-externs}{\mdref{sec-extending-p4runtime-for-architecture-specific-externs}{20.1.\hspace*{0.5em}Extending P4Runtime for Architecture-Specific Externs}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-the-p4info-message}{\mdref{sec-extending-the-p4info-message}{20.1.1.\hspace*{0.5em}Extending the P4Info message}}%mdk + +\mdtocitemx{sec-extending-the-p4runtime-service}{\mdref{sec-extending-the-p4runtime-service}{20.1.2.\hspace*{0.5em}Extending the P4Runtime Service}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-architecture-specific-table-extensions}{\mdref{sec-architecture-specific-table-extensions}{20.2.\hspace*{0.5em}Architecture-Specific Table Extensions}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-new-match-types}{\mdref{sec-new-match-types}{20.2.1.\hspace*{0.5em}New Match Types}}%mdk + +\mdtocitemx{sec-new-table-properties}{\mdref{sec-new-table-properties}{20.2.2.\hspace*{0.5em}New Table Properties}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-known-limitations-of-current-p4runtime-version}{\mdref{sec-known-limitations-of-current-p4runtime-version}{21.\hspace*{0.5em}Known Limitations of Current P4Runtime Version}}%mdk + +\mdtocitemx{sec-security-concerns-for-p4runtime}{\mdref{sec-security-concerns-for-p4runtime}{22.\hspace*{0.5em}Security concerns for P4Runtime}}%mdk + +\mdtocitemx{sec-appendix}{\mdref{sec-appendix}{A.\hspace*{0.5em}Appendix}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-revision-history}{\mdref{sec-revision-history}{A.1.\hspace*{0.5em}Revision History}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-changes-in-v120}{\mdref{sec-changes-in-v120}{A.1.1.\hspace*{0.5em}Changes in v1.2.0}}%mdk + +\mdtocitemx{sec-changes-in-v110}{\mdref{sec-changes-in-v110}{A.1.2.\hspace*{0.5em}Changes in v1.1.0}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-annotations}{\mdref{sec-p4-annotations}{A.2.\hspace*{0.5em}P4 Annotations}}%mdk + +\mdtocitemx{sec-value-set-example}{\mdref{sec-value-set-example}{A.3.\hspace*{0.5em}A More Complex Value Set Example}}%mdk + +\mdtocitemx{sec-guidelines-for-implementations}{\mdref{sec-guidelines-for-implementations}{A.4.\hspace*{0.5em}Guidelines for Implementations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-grpc-metadata-maximum-size}{\mdref{sec-grpc-metadata-maximum-size}{A.4.1.\hspace*{0.5em}gRPC Metadata Maximum Size}}%mdk + +\mdtocitemx{sec-grpc-server-maximum-receive-message-size}{\mdref{sec-grpc-server-maximum-receive-message-size}{A.4.2.\hspace*{0.5em}gRPC Server Maximum Receive Message Size}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-bibliography}{\mdref{sec-bibliography}{References}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{215} +\begin{mdtoc}%mdk + +\section*{Figures}\label{sec-figures}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{fig-reference-architecture}{\mdref{fig-reference-architecture}{\mdcaptionlabel{1}. P4Runtime Reference Architecture.}}%mdk + +\mdtocitemx{fig-single-embedded-controller}{\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}. Use-Case: Single Embedded Controller}}%mdk + +\mdtocitemx{fig-single-remote-controller}{\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}. Use-Case: Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-single-remote-controller}{\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}. Use-Case: Embedded Plus Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-controllers}{\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}. Use-Case: Embedded Plus Two Remote Controllers}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-ha-controllers}{\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}. Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk + +\mdtocitemx{fig-error-report}{\mdref{fig-error-report}{\mdcaptionlabel{7}. P4Runtime Error Report Message Format}}%mdk + +\mdtocitemx{fig-psa-metadata-translation}{\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}. P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{216} +\begin{mdtoc}%mdk + +\section*{Tables}\label{sec-tables}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{tab-mapping-p4-obj-ids}{\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}. Mapping of P4Info object type to 8-bit ID prefix value}}%mdk + +\mdtocitemx{tab-format-p4-obj-ids}{\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}. Format of P4Info object IDs}}%mdk + +\mdtocitemx{tab-exmpl-p4-obj-ids}{\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}. Example of statically-assigned P4Info object IDs}}%mdk + +\mdtocitemx{tab-valid-bytestring-encoding}{\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}. Examples of Valid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-invalid-bytestring-encoding}{\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}. Examples of Invalid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-p4-type-usage}{\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}. P4 Type Usage}}%mdk + +\mdtocitemx{tab-p4-annotations}{\mdref{tab-p4-annotations}{\mdcaptionlabel{7}. P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk + +%mdk-data-line={218} +\section{\mdline{218}1.\hspace*{0.5em}\mdline{218}Introduction and Scope}\label{sec-introduction-and-scope}%mdk%mdk + +%mdk-data-line={220} +\noindent\mdline{220}This document is published by the \mdline{220}\emph{P4.org API Working Group}\mdline{220}, which was +chartered\mdline{221}~[\mdcite{p4apiwgcharter}{17}]\mdline{221} to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called \mdline{223}\emph{P4Runtime}\mdline{223}. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +\mdline{226}\href{https://github.com/p4lang/p4runtime/tree/v1.2.0/proto}{https://github.com/p4lang/p4runtime/tree/v1.2.0/proto}\mdline{226}.%mdk + +%mdk-data-line={228} +\subsection{\mdline{228}1.1.\hspace*{0.5em}\mdline{228}P4 Language Version Applicability}\label{sec-p4-language-version-applicability}%mdk%mdk + +%mdk-data-line={230} +\noindent\mdline{230}P4Runtime is designed to be implemented in conjunction with the P4\mdline{230}\mdsub{16}\mdline{230} language +version or later. P4\mdline{231}\mdsub{14}\mdline{231} programs should be translated into P4\mdline{231}\mdsub{16}\mdline{231} to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P4\mdline{233}\mdsub{16}\mdline{233} 1.0, but were introduced in P4\mdline{233}\mdsub{16}\mdline{233} 1.1.0\mdline{233}~[\mdcite{p4revisions110}{29}]\mdline{233}. For +this version of P4Runtime, we recommend using P4\mdline{234}\mdsub{16}\mdline{234} 1.2.1\mdline{234}~[\mdcite{p4spec}{1}]\mdline{234}.%mdk + +%mdk-data-line={236} +\subsection{\mdline{236}1.2.\hspace*{0.5em}\mdline{236}In Scope}\label{sec-in-scope}%mdk%mdk + +%mdk-data-line={238} +\noindent\mdline{238}This specification document defines the \mdline{238}\emph{semantics}\mdline{238} of \mdline{238}\emph{P4Runtime}\mdline{238} messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime:%mdk + +%mdk-data-line={242} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={242} +\item\mdline{242}Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA)\mdline{243}~[\mdcite{psa}{19}]\mdline{243} externs (\mdline{243}e.g.\mdline{243} Counters, Meters, Action +Profiles, \mdline{244}\dots{}\mdline{244}). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0.%mdk + +%mdk-data-line={246} +\item\mdline{246}Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism.%mdk + +%mdk-data-line={248} +\item\mdline{248}Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy.%mdk + +%mdk-data-line={251} +\item\mdline{251}Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities.%mdk + +%mdk-data-line={253} +\item\mdline{253}Packet I/O to enable streaming packets to \mdline{253}\&\mdline{253} from the control plane.%mdk + +%mdk-data-line={254} +\item\mdline{254}Batching support, with different atomicity guarantees.%mdk + +%mdk-data-line={255} +\item\mdline{255}In-the-field device-reconfiguration with a new P4 data plane.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={257} +\noindent\mdline{257}The following are in the scope of this specification document:%mdk + +%mdk-data-line={259} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={259} +\item\mdline{259}Rationale for the P4Runtime design.%mdk + +%mdk-data-line={260} +\item\mdline{260}Reference architecture and use-cases for deploying a P4Runtime service.%mdk + +%mdk-data-line={261} +\item\mdline{261}Detailed description of the API semantics.%mdk + +%mdk-data-line={262} +\item\mdline{262}Requirements for conformant implementations of the API.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={264} +\subsection{\mdline{264}1.3.\hspace*{0.5em}\mdline{264}Not In Scope}\label{sec-not-in-scope}%mdk%mdk + +%mdk-data-line={266} +\noindent\mdline{266}The following are not in scope of P4Runtime:%mdk + +%mdk-data-line={268} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={268} +\item\mdline{268}Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +\mdline{273}[\mdcite{openconfig}{35}]\mdline{273}. An open source implementation of these APIs is also in progress +as part of the Stratum project\mdline{274}~[\mdcite{stratum}{37}]\mdline{274}.%mdk + +%mdk-data-line={275} +\item\mdline{275}Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={280} +\noindent\mdline{280}The following are not in scope of this specification document:%mdk + +%mdk-data-line={282} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={282} +\item\mdline{282}Description of the P4 programming language; it is assumed that the reader is +already familiar with P4\mdline{283}\mdsub{16}\mdline{283}~[\mdcite{p4spec}{1}]\mdline{283}.%mdk + +%mdk-data-line={284} +\item\mdline{284}Descriptions of gRPC and Protobuf files in general.%mdk + +%mdk-data-line={285} +\item\mdline{285}Controller\mdline{285}~\mdref{sec-arbitration-role-config}{role}\mdline{285} definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={289} +\section{\mdline{289}2.\hspace*{0.5em}\mdline{289}Terms and Definitions}\label{sec-terms-and-definitions}%mdk%mdk + +%mdk-data-line={291} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries arbitration}}%mdk + +%mdk-data-line={291} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{291}Refers to the process through which P4Runtime ensures that at any given +time, there is a single master (\mdline{292}i.e.\mdline{292} a client with write access) for a given +role. Also referred to as \mdline{293}\textquotedblleft{}master-slave arbitration\textquotedblright{}\mdline{293}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries client}}%mdk + +%mdk-data-line={295} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{295}The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries COS}}%mdk + +%mdk-data-line={299} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{299}Class of Service. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries device}}%mdk + +%mdk-data-line={301} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{301}Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries entity}}%mdk + +%mdk-data-line={305} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{305}An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries gRPC}}%mdk + +%mdk-data-line={308} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{308}gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +\mdline{309}[\mdcite{grpc}{9}]\mdline{309}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries HA}}%mdk + +%mdk-data-line={311} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{311}High-Availability. Refers to a redundancy architecture. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Instrumentation}}%mdk + +%mdk-data-line={313} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{313}The part of the P4Runtime server which implements the calls to the device or +target native \mdline{314}\textquotedblleft{}SDK\textquotedblright{}\mdline{314} or backend. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries IPC}}%mdk + +%mdk-data-line={316} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{316}Inter-Process Communication. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Blob}}%mdk + +%mdk-data-line={318} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{318}A more colloquial term for P4 Device Config (Blob = Binary Large Object). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Device Config}}%mdk + +%mdk-data-line={320} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{320}The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its \mdline{322}\textquotedblleft{}program.\textquotedblright{}\mdline{322} +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4Info}}%mdk + +%mdk-data-line={324} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{324}Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4RT}}%mdk + +%mdk-data-line={328} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{328}Abbreviation for P4Runtime. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Protobuf (Protocol Buffers)}}%mdk + +%mdk-data-line={330} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{330}The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See\mdline{331}~[\mdcite{proto}{21}]\mdline{331}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries PSA}}%mdk + +%mdk-data-line={333} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{333}Portable Switch Architecture\mdline{333}~[\mdcite{psa}{19}]\mdline{333}; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RPC}}%mdk + +%mdk-data-line={337} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{337}Remote Procedure Call. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RTT}}%mdk + +%mdk-data-line={339} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{339}Round-trip time. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN}}%mdk + +%mdk-data-line={341} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{341}Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network \mdline{346}\emph{controller}\mdline{346}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN port}}%mdk + +%mdk-data-line={348} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{348}A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries server}}%mdk + +%mdk-data-line={352} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{352}The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries stream}}%mdk + +%mdk-data-line={356} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{356}Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (\mdline{357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{357}), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and master-slave arbitration, among other +things. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries switch config}}%mdk + +%mdk-data-line={362} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{362}Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries target}}%mdk + +%mdk-data-line={367} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{367}The hardware or software entity which \mdline{367}\textquotedblleft{}executes\textquotedblright{}\mdline{367} the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with \mdline{368}\textquotedblleft{}device\textquotedblright{}\mdline{368}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries URI}}%mdk + +%mdk-data-line={370} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{370}Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={374} +\section{\mdline{374}3.\hspace*{0.5em}\mdline{374}Reference Architecture}\label{sec-reference-architecture}%mdk%mdk + +%mdk-data-line={376} +\noindent\mdline{376}Figure\mdline{376}~\mdref{fig-reference-architecture}{\mdcaptionlabel{1}}\mdline{376} represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. A multi-master protocol allows more than +one controller to participate, and a role-based arbitration scheme ensures only +one controller has write access to each read/write entity, or the pipeline +config itself. Any controller may perform read access to any entity or the +pipeline config. Later sections describe this in detail. For the sake of +brevity, the term controller may refer to one or more controllers.%mdk + +%mdk-data-line={385} +\mdline{385}The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +\mdline{388}[\mdcite{p4runtimerepo}{15}]\mdline{388}. It may be compiled via protoc\mdline{388} \mdline{388}\textemdash{}\mdline{388} the Protobuf compiler\mdline{388} \mdline{388}\textemdash{}\mdline{388} +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server.%mdk + +%mdk-data-line={393} +\mdline{393}Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository\mdline{394}~[\mdcite{pirepo}{16}]\mdline{394}. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, \mdline{396}e.g.\mdline{396} via callbacks, thus reducing the burden of implementing +P4Runtime.%mdk + +%mdk-data-line={399} +\mdline{399}The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard.%mdk + +%mdk-data-line={403} +\mdline{403}The controller can also set the \mdline{403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{403}, which amounts to +installing and running the compiled P4 program output, which is included in the +\mdline{405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{405} Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +\mdline{407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{407} to retrieve the device config and the P4Info.%mdk + +%mdk-data-line={410} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={411} +\noindent\mdline{411}\includegraphics[keepaspectratio=true,height=7cm]{build/reference-architecture}{}\mdline{411}%mdk + +%mdk-data-line={412} +\mdhr{}%mdk + +%mdk-data-line={413} +\noindent\mdline{413}\mdcaption{\textbf{Figure~\mdcaptionlabel{1}.}~\mdcaptiontext{P4Runtime Reference Architecture.}}%mdk +%mdk +\end{mdcenter}\label{fig-reference-architecture}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={417} +\subsection{\mdline{417}3.1.\hspace*{0.5em}\mdline{417}Idealized Workflow}\label{sec-idealized-workflow}%mdk%mdk + +%mdk-data-line={419} +\noindent\mdline{419}In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the \mdline{420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{420} +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a \mdline{422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{422} +RPC. Metadata in the P4Info describes both the overall program itself +(\mdline{424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{424}) as well as all entity instances derived from the P4 program\mdline{424} \mdline{424}\textemdash{}\mdline{424} +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise \mdline{426}\textquotedblleft{}handle\textquotedblright{}\mdline{426} used in API +calls.%mdk + +%mdk-data-line={429} +\mdline{429}In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible.%mdk + +%mdk-data-line={435} +\mdline{435}In some use cases, it is expected that a controller will store a +collection of multiple P4 \mdline{436}\textquotedblleft{}packages\textquotedblright{}\mdline{436}, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the \mdline{438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{438} from the target via the +\mdline{439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineRequest}}}\mdline{439} RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state.%mdk + +%mdk-data-line={443} +\subsection{\mdline{443}3.2.\hspace*{0.5em}\mdline{443}P4 as a Behavioral Description Language}\label{sec-p4-as-behavioral-description-language}%mdk%mdk + +%mdk-data-line={445} +\noindent\mdline{445}P4 can be considered a behavioral description of a switching device which may or +may not execute \mdline{446}\textquotedblleft{}P4\textquotedblright{}\mdline{446} natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a \mdline{448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineRequest}}}\mdline{448} to +change its pipeline \mdline{449}\textquotedblleft{}program\textquotedblright{}\mdline{449}, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device.%mdk + +%mdk-data-line={455} +\mdline{455}While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API.%mdk + +%mdk-data-line={464} +\mdline{464}In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the \mdline{465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{465} +message as well as the embedded \mdline{466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{466} fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections.%mdk + +%mdk-data-line={470} +\subsection{\mdline{470}3.3.\hspace*{0.5em}\mdline{470}Alternative Workflows}\label{sec-alternative-workflows}%mdk%mdk + +%mdk-data-line={472} +\noindent\mdline{472}Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary.%mdk + +%mdk-data-line={476} +\subsubsection{\mdline{476}3.3.1.\hspace*{0.5em}\mdline{476}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}\label{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}%mdk%mdk + +%mdk-data-line={478} +\noindent\mdline{478}In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +\mdline{480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{480}. The device\mdline{480}'\mdline{480}s configuration might be derived via some other +means to implement the P4 source code\mdline{481}'\mdline{481}s intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane.%mdk + +%mdk-data-line={485} +\subsubsection{\mdline{485}3.3.2.\hspace*{0.5em}\mdline{485}No P4 Source Available, P4Info Available}\label{sec-no-p4-source-available-p4info-available}%mdk%mdk + +%mdk-data-line={487} +\noindent\mdline{487}In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are:%mdk + +%mdk-data-line={490} +\begin{enumerate}%mdk + +%mdk-data-line={490} +\item{} +%mdk-data-line={490} +\mdline{490}The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security.%mdk%mdk + +%mdk-data-line={493} +\item{} +%mdk-data-line={493} +\mdline{493}The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={496} +\noindent\mdline{496}As discussed in Section\mdline{496}~\mdref{sec-p4-as-behavioral-description-language}{3.2}\mdline{496}, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, \mdline{499}e.g.\mdline{499} documentation.%mdk + +%mdk-data-line={501} +\subsubsection{\mdline{501}3.3.3.\hspace*{0.5em}\mdline{501}Partial P4Info and P4 Source are Available}\label{sec-partial-p4info-and-p4-source-are-available}%mdk%mdk + +%mdk-data-line={503} +\noindent\mdline{503}In this situation, a subset of the target\mdline{503}'\mdline{503}s pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code.%mdk + +%mdk-data-line={510} +\subsubsection{\mdline{510}3.3.4.\hspace*{0.5em}\mdline{510}P4Info Role-Based Subsets}\label{sec-p4info-role-based-subsets}%mdk%mdk + +%mdk-data-line={512} +\noindent\mdline{512}In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more.%mdk + +%mdk-data-line={516} +\subsection{\mdline{516}3.4.\hspace*{0.5em}\mdline{516}P4Runtime State Across Restarts}\label{sec-restarts}%mdk%mdk + +%mdk-data-line={518} +\noindent\mdline{518}All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade.%mdk + +%mdk-data-line={524} +\section{\mdline{524}4.\hspace*{0.5em}\mdline{524}Controller Use-cases}\label{sec-controller-use-cases}%mdk%mdk + +%mdk-data-line={526} +\noindent\mdline{526}P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +\mdline{528}\mdref{sec-master-slave-arbitration-and-controller-replication}{section}\mdline{528}. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime\mdline{530}'\mdline{530}s flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex.%mdk + +%mdk-data-line={533} +\subsection{\mdline{533}4.1.\hspace*{0.5em}\mdline{533}Single Embedded Controller}\label{sec-single-embedded-controller}%mdk%mdk + +%mdk-data-line={535} +\noindent\mdline{535}Figure\mdline{535}~\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}}\mdline{535} shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases.%mdk + +%mdk-data-line={540} +\mdline{540}P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC.%mdk + +%mdk-data-line={545} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={546} +\noindent\mdline{546}\includegraphics[keepaspectratio=true,height=6cm]{build/single-embedded-controller}{}\mdline{546}%mdk + +%mdk-data-line={547} +\mdhr{}%mdk + +%mdk-data-line={548} +\noindent\mdline{548}\mdcaption{\textbf{Figure~\mdcaptionlabel{2}.}~\mdcaptiontext{Use-Case: Single Embedded Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-embedded-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={552} +\subsection{\mdline{552}4.2.\hspace*{0.5em}\mdline{552}Single Remote Controller}\label{sec-single-remote-controller}%mdk%mdk + +%mdk-data-line={554} +\noindent\mdline{554}Figure\mdline{554}~\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}}\mdline{554} shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections.%mdk + +%mdk-data-line={559} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={560} +\noindent\mdline{560}\includegraphics[keepaspectratio=true,height=7cm]{build/single-remote-controller}{}\mdline{560}%mdk + +%mdk-data-line={561} +\mdhr{}%mdk + +%mdk-data-line={562} +\noindent\mdline{562}\mdcaption{\textbf{Figure~\mdcaptionlabel{3}.}~\mdcaptiontext{Use-Case: Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={566} +\subsection{\mdline{566}4.3.\hspace*{0.5em}\mdline{566}Embedded\mdline{566} \mdline{566}+ Single Remote Controller}\label{sec-embedded-single-remote-controller}%mdk%mdk + +%mdk-data-line={568} +\noindent\mdline{568}Figure\mdline{568}~\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}}\mdline{568} illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller.%mdk + +%mdk-data-line={575} +\mdline{575}For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables.%mdk + +%mdk-data-line={579} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={580} +\noindent\mdline{580}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-single-remote-controller}{}\mdline{580}%mdk + +%mdk-data-line={581} +\mdhr{}%mdk + +%mdk-data-line={582} +\noindent\mdline{582}\mdcaption{\textbf{Figure~\mdcaptionlabel{4}.}~\mdcaptiontext{Use-Case: Embedded Plus Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={587} +\subsection{\mdline{587}4.4.\hspace*{0.5em}\mdline{587}Embedded\mdline{587} \mdline{587}+ Two Remote Controllers}\label{sec-embedded-two-remote-controllers}%mdk%mdk + +%mdk-data-line={589} +\noindent\mdline{589}Figure\mdline{589}~\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}}\mdline{589} illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +\mdline{592}e.g.\mdline{592} routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership.%mdk + +%mdk-data-line={595} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={596} +\noindent\mdline{596}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-controllers}{}\mdline{596}%mdk + +%mdk-data-line={597} +\mdhr{}%mdk + +%mdk-data-line={598} +\noindent\mdline{598}\mdcaption{\textbf{Figure~\mdcaptionlabel{5}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={603} +\subsection{\mdline{603}4.5.\hspace*{0.5em}\mdline{603}Embedded Controller\mdline{603} \mdline{603}+ Two High-Availability Remote Controllers}\label{sec-embedded-controller-two-high-availability-remote-controllers}%mdk%mdk + +%mdk-data-line={605} +\noindent\mdline{605}Figure\mdline{605}~\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}}\mdline{605} illustrates a single +embedded controller plus two remote controllers in an active-standby HA +(High-Availability) configuration. Controller \mdline{607}\#\mdline{607}1 is the active controller and is +in charge of some entities. If it fails, Controller \mdline{608}\#\mdline{608}2 takes over and manages +the tables formerly owned by Controller \mdline{609}\#\mdline{609}1. The mechanics of HA architectures +are beyond the scope of this document, but the P4Runtime multi-master +arbitration scheme supports it.%mdk + +%mdk-data-line={613} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={614} +\noindent\mdline{614}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-ha-controllers}{}\mdline{614}%mdk + +%mdk-data-line={615} +\mdhr{}%mdk + +%mdk-data-line={616} +\noindent\mdline{616}\mdcaption{\textbf{Figure~\mdcaptionlabel{6}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-ha-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={621} +\section{\mdline{621}5.\hspace*{0.5em}\mdline{621}Master-Slave Arbitration and Controller Replication}\label{sec-master-slave-arbitration-and-controller-replication}%mdk%mdk + +%mdk-data-line={624} +\noindent\mdline{624}The P4Runtime interface allows multiple controllers to be connected to the +P4Runtime server running on the device at the same time for the following +reasons:%mdk + +%mdk-data-line={628} +\begin{enumerate}%mdk + +%mdk-data-line={628} +\item{} +%mdk-data-line={628} +\mdline{628}Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, \mdline{629}\textquotedblleft{}roles\textquotedblright{}\mdline{629} (or \mdline{629}\textquotedblleft{}realms\textquotedblright{}\mdline{629}) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +master and the rest are slaves. Role definition, \mdline{632}i.e.\mdline{632} how P4 entities get +assigned to each role, is \mdline{633}\textbf{out-of-scope}\mdline{633} of this document.%mdk%mdk + +%mdk-data-line={635} +\item{} +%mdk-data-line={635} +\mdline{635}Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby slave controllers. These can already have a connection +open, which can help them become master more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={641} +\noindent\mdline{641}To support multiple controllers, P4Runtime uses the streaming channel (available +via \mdline{642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{642} RPC) for session management. The workflow is described as +follows:%mdk + +%mdk-data-line={645} +\begin{itemize}%mdk + +%mdk-data-line={645} +\item{} +%mdk-data-line={645} +\mdline{645}Each controller instance (\mdline{645}e.g.\mdline{645} a controller process) can participate in one or +more roles. For each (\mdline{646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{646}, \mdline{646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{646}), the controller receives an +\mdline{647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{647}. This \mdline{647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{647} can be the same for different roles and/or +devices, as long as the tuple (\mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{648}, \mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{648}, \mdline{648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{648}) is +unique. For each (\mdline{649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{649}, \mdline{649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{649}) that the controller wishes to +control, it establishes a \mdline{650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{650} with the P4Runtime server +responsible for that device, and sends a \mdline{651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{651} message +containing that tuple of (\mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{652}, \mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{652}, \mdline{652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{652}) values. The +P4Runtime server selects a master independently for each (\mdline{653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{653}, +\mdline{654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{654}) pair. The master is the client that has the highest \mdline{654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{654} +that the device has ever received for the same (\mdline{655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{655}, +\mdline{656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{656}) values. A connection between a controller instance and a device id +\mdline{657}\textemdash{}\mdline{657} which involves a persistent \mdline{657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{657} \mdline{657}\textemdash{}\mdline{657} can be referred to as a +P4Runtime client.%mdk + +%mdk-data-line={660} +\mdline{660}Note that the P4Runtime server does not assign a \mdline{660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{660} or \mdline{660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{660} to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the \mdline{662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{662} values used for each +\mdline{663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{663}. The P4Runtime server only keeps track of the (\mdline{663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{663}, +\mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{664}, \mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{664}) of each \mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{664} that has sent a successful +\mdline{665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{665} message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +\mdline{667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{667} message to identify which client is making the \mdline{667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{667}, +not only the \mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{668}. This enables controllers to re-use the same +numeric \mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{669} values across different (\mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{669}, \mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{669}) +pairs. P4Runtime does not require \mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{670} values be reused across such +different (\mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{671}, \mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{671}) pairs; it allows it.%mdk%mdk + +%mdk-data-line={673} +\item{} +%mdk-data-line={673} +\mdline{673}To start a controller session, a controller first opens a bidirectional stream +channel to the server via the \mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{674} RPC for each device. This stream +will be used for two purposes:%mdk + +%mdk-data-line={677} +\begin{itemize}%mdk + +%mdk-data-line={677} +\item{} +%mdk-data-line={677} +\mdline{677}\textbf{Session management:}\mdline{677} As soon as the controller opens the stream +channel, it sends a \mdline{678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{678} message to the switch. The +controller populates the \mdline{679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{679} field in this message +using its \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{680} and \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{680}, as well as the \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{680} of the +device. Note that the \mdline{681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{681} field in the \mdline{681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{681} is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below.%mdk%mdk + +%mdk-data-line={685} +\item{} +%mdk-data-line={685} +\mdline{685}\textbf{Streaming of notifications (e.g. digests) and packet I/O:}\mdline{685} The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the master controller can participate in packet +I/O. This feature is explained in more details in the\mdline{689}~\mdref{sec-packet-i_o}{Packet +I/O}\mdline{690} section.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={692} +\mdline{692}Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state.%mdk%mdk + +%mdk-data-line={695} +\item{} +%mdk-data-line={695} +\mdline{695}Note that the stream is opened per device. In case a switching platform has +multiple devices (\mdline{696}e.g.\mdline{696} multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different masters for different +devices. In this case, it is the responsibility of the P4Runtime server to +keep track of the master for each device (and role). More specifically, the +P4Runtime server will know which stream corresponds to the master controller +for each pair of (\mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{701}, \mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{701}) at any point of time.%mdk%mdk + +%mdk-data-line={703} +\item{} +%mdk-data-line={703} +\mdline{703}The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered \mdline{704}\textquotedblleft{}offline\textquotedblright{}\mdline{704} or +\mdline{705}\textquotedblleft{}dead\textquotedblright{}\mdline{705} as soon as its stream channel to the switch is broken. When a master +channel gets broken: (i) an advisory message is sent to all other controllers +for that \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{707} and \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{707}, as described in the +\mdline{708}\mdref{sec-mastership-notification}{following section}\mdline{708} (ii) the P4Runtime server +will be without a master, until a client sends a successful +\mdline{710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{710} (as per the rules in a +\mdline{711}\mdref{sec-mastership-updates}{later section}\mdline{711}).%mdk%mdk + +%mdk-data-line={713} +\item{} +%mdk-data-line={713} +\mdline{713}The mechanism via which the controller receives the P4Runtime server details +which includes the \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{714}, \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip}}}\mdline{714} and \mdline{714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{714}, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +\mdline{718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{718}) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={723} +\noindent\mdline{723}gRPC enables the server to identify which client originated each message in the +\mdline{724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{724} stream. For example, the C++ gRPC library\mdline{724}~[\mdcite{grpcstreamc}{10}]\mdline{724} in +synchronous mode enables a server process to cause a function to be called when +a new client creates a \mdline{726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{726} stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +\mdline{728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{728} is closed normally (or broken, \mdline{728}e.g.\mdline{728} because a client process +unexpectedly terminated). Thus the server can easily associate all +\mdline{730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{730} messages received from the same client, because they are +processed within the context of the same function call.%mdk + +%mdk-data-line={733} +\mdline{733}A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{738}, \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{738}, and \mdline{738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{738} in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods\mdline{740}~[\mdcite{grpcauth}{8}]\mdline{740} that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server.%mdk + +%mdk-data-line={744} +\subsection{\mdline{744}5.1.\hspace*{0.5em}\mdline{744}Default Role}\label{sec-default-role}%mdk%mdk + +%mdk-data-line={746} +\noindent\mdline{746}A controller can omit the role message in \mdline{746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{746}. This +implies the \mdline{747}\textquotedblleft{}default role\textquotedblright{}\mdline{747}, which corresponds to \mdline{747}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{747}. This +also implies that a default role has a \mdline{748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{748} of 0 (default). If using a +default role, all RPCs from the controller (\mdline{749}e.g.\mdline{749} \mdline{749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{749}) must set the \mdline{749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{749} +to 0.%mdk + +%mdk-data-line={752} +\subsection{\mdline{752}5.2.\hspace*{0.5em}\mdline{752}Role Config}\label{sec-arbitration-role-config}%mdk%mdk + +%mdk-data-line={754} +\noindent\mdline{754}The \mdline{754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{754} field in the \mdline{754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{754} message sent by the +controller describes the role configuration, \mdline{755}i.e.\mdline{755} which operations are in the +scope of a given role. In particular, the definition of a role may include the +following:%mdk + +%mdk-data-line={759} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={759} +\item\mdline{759}A list of P4 entities for which the controller may issue \mdline{759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{759} updates and +receive notification messages (\mdline{760}e.g.\mdline{760} \mdline{760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{760} and +\mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{761}).%mdk + +%mdk-data-line={762} +\item\mdline{762}Whether the controller is able to receive \mdline{762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{762} messages, along with a +filtering mechanism based on the values of the \mdline{763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{763} fields to +select which \mdline{764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{764} messages should be sent to the controller.%mdk + +%mdk-data-line={765} +\item\mdline{765}Whether the controller is able to send \mdline{765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{765} messages, along with a +filtering mechanism based on the values of the \mdline{766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{766} fields to +select which \mdline{767}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{767} messages are allowed to be sent by the controller.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={769} +\noindent\mdline{769}An unset \mdline{769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{769} implies \mdline{769}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{769} (similar to the default +role explained above). In order to support different role definition schemes, +\mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{771} is defined as an \mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{771} Protobuf message\mdline{771}~[\mdcite{protoany}{31}]\mdline{771}. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion.%mdk + +%mdk-data-line={776} +\mdline{776}It is the job of the P4Runtime server to remember the \mdline{776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{776} for every +\mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{777} and \mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{777} pair.%mdk + +%mdk-data-line={779} +\subsection{\mdline{779}5.3.\hspace*{0.5em}\mdline{779}Rules for Handling \mdline{779}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{779} Messages Received from Controllers}\label{sec-mastership-updates}%mdk%mdk + +%mdk-data-line={781} +\begin{enumerate}%mdk + +%mdk-data-line={781} +\item{} +%mdk-data-line={781} +\mdline{781}If the \mdline{781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{781} message is received for the first time on +this particular channel (\mdline{782}i.e.\mdline{782} for a newly connected controller):%mdk + +%mdk-data-line={784} +\begin{enumerate}%mdk + +%mdk-data-line={784} +\item{} +%mdk-data-line={784} +\mdline{784}If \mdline{784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{784} does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +\mdline{786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{786} error.%mdk%mdk + +%mdk-data-line={788} +\item{} +%mdk-data-line={788} +\mdline{788}If the \mdline{788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{788} is set and is already used by another controller for +the same (\mdline{789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{789}, \mdline{789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{789}), the P4Runtime server shall terminate +the stream by returning an \mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{790} error.%mdk%mdk + +%mdk-data-line={792} +\item{} +%mdk-data-line={792} +\mdline{792}If \mdline{792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{792} does not match the \mdline{792}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{792} scheme previously +agreed upon, the server must return an \mdline{793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{793} error.%mdk%mdk + +%mdk-data-line={795} +\item{} +%mdk-data-line={795} +\mdline{795}If the number of open streams for the given (\mdline{795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{795}, \mdline{795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{795}) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a \mdline{797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{797} error.%mdk%mdk + +%mdk-data-line={799} +\item{} +%mdk-data-line={799} +\mdline{799}Otherwise, the controller is added to a list of connected controllers for +the given (\mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{800}, \mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{800}) and the server remembers the +controllers \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{801}, \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{801} and \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{801} for this gRPC +channel. See below for the rules to determine if this controller becomes +a master or slave, and what notifications are sent as a consequence.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={805} +\item{} +%mdk-data-line={805} +\mdline{805}Otherwise, if the \mdline{805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{805} message is received from an +already connected controller:%mdk + +%mdk-data-line={808} +\begin{enumerate}%mdk + +%mdk-data-line={808} +\item{} +%mdk-data-line={808} +\mdline{808}If the \mdline{808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{808} does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{810} error.%mdk%mdk + +%mdk-data-line={812} +\item{} +%mdk-data-line={812} +\mdline{812}If the \mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{812} does not match the current \mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{812} assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{814} error. If the controller wishes to change its role, +it must close the current stream channel and open a new one.%mdk%mdk + +%mdk-data-line={817} +\item{} +%mdk-data-line={817} +\mdline{817}If \mdline{817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{817} does not match the \mdline{817}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{817} scheme previously +agreed upon, the server must return an \mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{818} error.%mdk%mdk + +%mdk-data-line={820} +\item{} +%mdk-data-line={820} +\mdline{820}If the \mdline{820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{820} is set and is already used by another controller +(excluding the controller making the request) for the same +(\mdline{822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{822}, \mdline{822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{822}), the P4Runtime server shall terminate the stream +by returning an \mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{823} error.%mdk%mdk + +%mdk-data-line={825} +\item{} +%mdk-data-line={825} +\mdline{825}If the \mdline{825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{825} matches the one assigned to this stream:%mdk + +%mdk-data-line={827} +\begin{enumerate}%mdk + +%mdk-data-line={827} +\item{} +%mdk-data-line={827} +\mdline{827}If the controller for this channel is the master, then the server +updates the \mdline{828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{828} to the one specified in the +\mdline{829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{829}. An advisory mastership message is sent to +all controllers for this \mdline{830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{830} and \mdline{830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{830} informing +them of the new \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{831}. Since the format of \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{831} is +out of scope for the P4Runtime specification, the server will send +the advisory message for every update, even if the master sets the +same \mdline{834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{834} as it has before. See the +\mdline{835}\mdref{sec-mastership-notification}{following section}\mdline{835} for the format of +the advisory message.%mdk%mdk + +%mdk-data-line={838} +\item{} +%mdk-data-line={838} +\mdline{838}If the controller is a slave, this is a no-op and the \mdline{838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{838} +is ignored. No response is sent to any controller.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={841} +\item{} +%mdk-data-line={841} +\mdline{841}Otherwise, the server updates the \mdline{841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{841} it has stored for this +controller. This change might cause a change in mastership (this +controller might become master, or the controller might have downgraded +itself to a slave, see below), as well as notifications being sent to one +or more controllers.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={847} +\noindent\mdline{847}If the \mdline{847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{847} is accepted by either of the two steps above +(cases 1.5. and 2.6. above), then the server determines if there are changes in +mastership. Let \mdline{849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{849} be the highest election ID the server has +ever seen for the given \mdline{850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{850} and \mdline{850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{850} (including the one of the +current master if there is one).%mdk + +%mdk-data-line={853} +\begin{enumerate}%mdk + +%mdk-data-line={853} +\item{} +%mdk-data-line={853} +\mdline{853}If \mdline{853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{853} is greater than or equal to \mdline{853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{853}, then the +controller becomes master. The server updates the role configuration to +\mdline{855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{855} for the given \mdline{855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{855}. Furthermore:%mdk + +%mdk-data-line={857} +\begin{enumerate}%mdk + +%mdk-data-line={857} +\item{} +%mdk-data-line={857} +\mdline{857}If there was no master for this \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{857} and \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{857} before and +there are no \mdline{858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{858} requests still processing from a previous master, +then the server immediately sends an advisory notification to all +controllers for this \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{860} and \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{860}. See the +\mdline{861}\mdref{sec-mastership-notification}{following section}\mdline{861} for the format of the +advisory message.%mdk%mdk + +%mdk-data-line={864} +\item{} +%mdk-data-line={864} +\mdline{864}If there was a previous master or \mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{864} requests in flight, then the +server carries out the following steps (in this order):%mdk + +%mdk-data-line={867} +\begin{enumerate}%mdk + +%mdk-data-line={867} +\item{} +%mdk-data-line={867} +\mdline{867}The server stops accepting \mdline{867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{867} requests from the previous master +(if there is one). At this point, the server will reject all \mdline{868}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{868} +requests with \mdline{869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{869}.%mdk%mdk + +%mdk-data-line={871} +\item{} +%mdk-data-line={871} +\mdline{871}The server notifies all controllers other than the new master of the +mastership change by sending the advisory notification described in +the\mdline{873}~\mdref{sec-mastership-notification}{following section}\mdline{873}.%mdk%mdk + +%mdk-data-line={875} +\item{} +%mdk-data-line={875} +\mdline{875}The server will finish processing any \mdline{875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{875} requests that have +already started. If there are errors, they are reported as usual to +the previous master. If the previous master has already disconnected, +any possible errors are dropped and not reported.%mdk%mdk + +%mdk-data-line={880} +\item{} +%mdk-data-line={880} +\mdline{880}The server now accepts the current controller as the new master, thus +accepting \mdline{881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{881} requests from this controller. The server updates +the highest election ID (\mdline{882}i.e.\mdline{882} \mdline{882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{882}) it has seen for +this \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{883} and \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{883} to \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{883}.%mdk%mdk + +%mdk-data-line={885} +\item{} +%mdk-data-line={885} +\mdline{885}The server notifies the new master by sending the advisory message +described in the\mdline{886}~\mdref{sec-mastership-notification}{following section}\mdline{886}.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={888} +\item{} +%mdk-data-line={888} +\mdline{888}Otherwise, the controller becomes a slave. If the controller was previously a +master (and downgraded itself), then an advisory message is sent to all +controllers for this \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{890} and \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{890}. Otherwise, the advisory +message is only sent to the controller that sent the initial +\mdline{892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{892}. See the +\mdline{893}\mdref{sec-mastership-notification}{following section}\mdline{893} for the format of the +advisory message.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={896} +\subsection{\mdline{896}5.4.\hspace*{0.5em}\mdline{896}Mastership Notifications}\label{sec-mastership-notification}%mdk%mdk + +%mdk-data-line={898} +\noindent\mdline{898}For any given \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{898} and \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{898}, any time a new master is chosen, a +master downgrades its status to a slave, a master disconnects, or the +\mdline{900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{900} is updated by the master, all controllers for that +(\mdline{901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{901}, \mdline{901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{901}) are informed of this by sending a +\mdline{902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{902}. The \mdline{902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{902} is populated as follows:%mdk + +%mdk-data-line={904} +\begin{itemize}%mdk + +%mdk-data-line={904} +\item{} +%mdk-data-line={904} +\mdline{904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{904} and \mdline{904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{904} as given.%mdk%mdk + +%mdk-data-line={906} +\item{} +%mdk-data-line={906} +\mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{906} is set to the role configuration the server received most +recently in a \mdline{907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{907} from a master.%mdk%mdk + +%mdk-data-line={909} +\item{} +%mdk-data-line={909} +\mdline{909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{909} is populated as follows:%mdk + +%mdk-data-line={911} +\begin{itemize}%mdk + +%mdk-data-line={911} +\item{} +%mdk-data-line={911} +\mdline{911}If there has not been any master at all, the election\mdline{911}\_\mdline{911}id is left unset.%mdk%mdk + +%mdk-data-line={913} +\item{} +%mdk-data-line={913} +\mdline{913}Otherwise, \mdline{913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{913} is set to the highest election ID that the server +has seen for this \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{914} and \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{914} (which is the \mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{914} of +the current master if there is any).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={917} +\item{} +%mdk-data-line={917} +\mdline{917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{917} is set differently based on whether the notification is sent to the +master or a slave controller:%mdk + +%mdk-data-line={920} +\begin{itemize}%mdk + +%mdk-data-line={920} +\item{} +%mdk-data-line={920} +\mdline{920}If there is a master:%mdk + +%mdk-data-line={922} +\begin{itemize}%mdk + +%mdk-data-line={922} +\item{} +%mdk-data-line={922} +\mdline{922}For the master, \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{922} is OK (with \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{922} set to +\mdline{923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.OK}}}\mdline{923}).%mdk%mdk + +%mdk-data-line={925} +\item{} +%mdk-data-line={925} +\mdline{925}For all slave controllers, \mdline{925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{925} is set to non-OK (with +\mdline{926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{926} set to \mdline{926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.ALREADY\_EXISTS}}}\mdline{926}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={928} +\item{} +%mdk-data-line={928} +\mdline{928}Otherwise, if there is no master currently, for all slave controllers, +\mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{929} is set to non-OK (with \mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{929} set to +\mdline{930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.NOT\_FOUND}}}\mdline{930}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={932} +\noindent\mdline{932}Note that on mastership changes with outstanding \mdline{932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{932} request, some +notifications might be delayed, see the +\mdline{934}\mdref{sec-mastership-updates}{previous section}\mdline{934} for details.%mdk + +%mdk-data-line={936} +\section{\mdline{936}6.\hspace*{0.5em}\mdline{936}The P4Info Message}\label{sec-the-p4info-message}%mdk%mdk + +%mdk-data-line={938} +\noindent\mdline{938}The purpose of P4Info was described under +\mdline{939}\mdref{sec-reference-architecture}{Reference Architecture}\mdline{939}. +Here we describe the various +components.%mdk + +%mdk-data-line={943} +\subsection{\mdline{943}6.1.\hspace*{0.5em}\mdline{943}Common Messages}\label{sec-common-messages}%mdk%mdk + +%mdk-data-line={945} +\noindent\mdline{945}These messages appear nested within many other messages.%mdk + +%mdk-data-line={947} +\subsubsection{\mdline{947}6.1.1.\hspace*{0.5em}\mdline{947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{947} Message}\label{sec-documentation-message}%mdk%mdk + +%mdk-data-line={949} +\noindent\mdline{949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{949} is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers.%mdk + +%mdk-data-line={953} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={954} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Documentation~\{\\ +~~{\mdcolor{darkgreen}//~A~brief~description~of~something,~e.g.~one~sentence}\\ +~~{\bfseries{\mdcolor{navy}string}}~brief~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~A~more~verbose~description~of~something.}\\ +~~{\mdcolor{darkgreen}//~Multiline~is~accepted.~Markup~format~(if~any)~is~TBD.}\\ +~~{\bfseries{\mdcolor{navy}string}}~description~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={963} +\subsubsection{\mdline{963}6.1.2.\hspace*{0.5em}\mdline{963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{963} Message}\label{sec-preamble-message}%mdk%mdk + +%mdk-data-line={965} +\noindent\mdline{965}The preamble serves as the \mdline{965}\textquotedblleft{}descriptor\textquotedblright{}\mdline{965} for each entity and contains the unique +instance ID, name, alias, annotations and documentation.%mdk + +%mdk-data-line={968} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={969} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Preamble~\{\\ +~~{\mdcolor{darkgreen}//~ids~share~the~same~number-space;~e.g.~table~ids~cannot~overlap~with~counter}\\ +~~{\mdcolor{darkgreen}//~ids.~Even~though~this~is~irrelevant~to~this~proto~definition,~the~ids~are}\\ +~~{\mdcolor{darkgreen}//~allocated~in~such~a~way~that~it~is~possible~based~on~an~id~to~deduce~the}\\ +~~{\mdcolor{darkgreen}//~resource~type~(e.g.~table,~action,~counter,~...).~This~means~that~code}\\ +~~{\mdcolor{darkgreen}//~using~these~ids~can~detect~if~the~wrong~resource~type~is~used}\\ +~~{\mdcolor{darkgreen}//~somewhere.~This~also~means~that~ids~of~different~types~can~be~mixed}\\ +~~{\mdcolor{darkgreen}//~(e.g.~direct~resource~list~for~a~table)~without~ambiguity.~Note~that~id~0}\\ +~~{\mdcolor{darkgreen}//~is~reserved~and~means~"invalid~id".}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name~of~the~P4~object,~e.g.~c1.c2.ipv4\_lpm}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~an~alias~(alternative~name)~for~the~P4~object,~probably~shorter~than~its}\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name.~The~only~constraint~is~for~it~to~be~unique~with}\\ +~~{\mdcolor{darkgreen}//~respect~to~other~P4~objects~of~the~same~type.~By~default,~the~compiler~uses}\\ +~~{\mdcolor{darkgreen}//~the~shortest~suffix~of~the~name~that~uniquely~identifies~the~object.~For}\\ +~~{\mdcolor{darkgreen}//~example~if~the~P4~program~contains~two~tables~with~names~s.c1.t~and~s.c2.t,}\\ +~~{\mdcolor{darkgreen}//~the~default~aliases~will~respectively~be~c1.t~and~c2.t.~In~the~future,~the}\\ +~~{\mdcolor{darkgreen}//~P4~programmer~may~also~be~able~to~override~the~default~alias~for~any~P4}\\ +~~{\mdcolor{darkgreen}//~object~(TBD).}\\ +~~{\bfseries{\mdcolor{navy}string}}~alias~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~The~location~of~`annotations{}[i]`~is~given~by~`annotation\_locations{}[i]`.}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~SourceLocation~annotation\_locations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~Documentation~of~the~entity}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={999} +\subsubsection{\mdline{999}6.1.3.\hspace*{0.5em}\mdline{999}Annotating P4 Entities with \mdline{999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}\label{sec-annotating-p4-entities-with-documentation}%mdk%mdk + +%mdk-data-line={1001} +\noindent\mdline{1001}P4 entities may be annotated using the following annotations:%mdk + +%mdk-data-line={1003} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1004} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}(string...)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}(string...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1008} +\noindent\mdline{1008}Attaching either or both of these annotations to an entity will generate a +P4Info\mdline{1009}~\mdref{sec-documentation-message}{Documentation Message}\mdline{1009}, which in turn will +appear in the\mdline{1010}~\mdref{sec-preamble-message}{Preamble Message}\mdline{1010} for the entity.%mdk + +%mdk-data-line={1012} +\mdline{1012}The P4 compiler should not emit \mdline{1012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation}}}\mdline{1012} messages in the P4Info for these +specific cases; instead, it should generate the \mdline{1013}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1013} messages as +described.%mdk + +%mdk-data-line={1016} +\mdline{1016}The following example shows documentation annotations for a \mdline{1016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table}}}\mdline{1016} entity:%mdk + +%mdk-data-line={1018} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1019} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port.~\textbackslash{}}\\ +Uses~LPM~match~{\bfseries{\mdcolor{navy}type}}.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}table~my\_ipv4\_lkup~\{}\\ +{\mdcolor{maroon}~~...}\\ +{\mdcolor{maroon}\}}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1027} +\subsubsection{\mdline{1027}6.1.4.\hspace*{0.5em}\mdline{1027}Structured Annotations}\label{sec-structured-annotations}%mdk%mdk + +%mdk-data-line={1029} +\noindent\mdline{1029}P4 supports both unstructured and structured annotations\mdline{1029}~[\mdcite{p4annotations}{13}]\mdline{1029}. +Unstructured annotations of the form \mdline{1030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno1}}}\mdline{1030} or \mdline{1030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno2(body-content)}}}\mdline{1030} can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +\mdline{1033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno3{}[]}}}\mdline{1033} or \mdline{1033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno4{}[kvList\textbar{}expressionList]}}}\mdline{1033} have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this.%mdk + +%mdk-data-line={1038} +\mdline{1038}The annotations described up to this point, \mdline{1038}e.g.\mdline{1038} \mdline{1038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief()}}}\mdline{1038}, have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as \mdline{1040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1040} fields in the various \mdline{1040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{1040}s. +Similarly, structured annotations are represented in \mdline{1041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated\\ +StructuredAnnotation~structured\_annotations}}}\mdline{1042} fields which are siblings to the +unstructured \mdline{1043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1043}. The \mdline{1043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations}}}\mdline{1043} contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations.%mdk + +%mdk-data-line={1048} +\mdline{1048}The structured annotation messages are defined in p4types.proto.%mdk + +%mdk-data-line={1050} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1051} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~KeyValuePair~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~key~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Expression~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~KeyValuePairList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~KeyValuePair~kv\_pairs~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Expression~\{\\ +~~{\bfseries{\mdcolor{navy}oneof}}~value~\{\\ +~~~~{\bfseries{\mdcolor{navy}string}}~string\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~{\bfseries{\mdcolor{navy}int64}}~int64\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~{\bfseries{\mdcolor{navy}bool}}~bool\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~ExpressionList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Expression~expressions~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~StructuredAnnotation~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}oneof}}~body~\{\\ +~~~~ExpressionList~expression\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~KeyValuePairList~kv\_pair\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~Location~of~the~'@'~symbol~of~this~annotation~in~the~source~code.}\\ +~~SourceLocation~source\_location~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1083} +\noindent\mdline{1083}The \mdline{1083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1083} message can represent either a \mdline{1083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1083} +or an \mdline{1084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExpressionList}}}\mdline{1084}.%mdk + +%mdk-data-line={1086} +\mdline{1086}The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The \mdline{1087}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{1087} +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don\mdline{1089}'\mdline{1089}t match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler \mdline{1091}\emph{may}\mdline{1091} print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions.%mdk + +%mdk-data-line={1095} +\mdline{1095}The following invariants hold:%mdk + +%mdk-data-line={1097} +\begin{enumerate}%mdk + +%mdk-data-line={1097} +\item{} +%mdk-data-line={1097} +\mdline{1097}For any P4 entity, there are no two \mdline{1097}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1097}s that have the +same name.%mdk%mdk + +%mdk-data-line={1100} +\item{} +%mdk-data-line={1100} +\mdline{1100}Within a \mdline{1100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1100}, there are no two \mdline{1100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePair}}}\mdline{1100}s that have the +same \mdline{1101}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key.}}}\mdline{1101}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1103} +\paragraph{\mdline{1103}6.1.4.1.\hspace*{0.5em}\mdline{1103}Structured Annotation Examples}\label{sec-structured-annotation-examples}%mdk%mdk + +%mdk-data-line={1105} +\noindent\mdline{1105}We omit the \mdline{1105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}source\_location}}}\mdline{1105} field in the following examples.%mdk + +%mdk-data-line={1107} +\mdline{1107}\textbf{Empty Expression List}\mdline{1107}%mdk + +%mdk-data-line={1109} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1110} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}Empty}{\mdcolor{maroon}{}[]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1116} +\noindent\mdline{1116}The generated P4Info will contain the following.%mdk + +%mdk-data-line={1118} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1119} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}Empty}{\mdcolor{maroon}"}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1124} +\noindent\mdline{1124}\textbf{Mixed Expression List}\mdline{1124}%mdk + +%mdk-data-line={1126} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1127} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~TEXT\_CONST~"hello"}\\ +{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~NUM\_CONST~6}\\ +{\mdcolor{gray}@}{\mdcolor{gray}MixedExprList}{\mdcolor{maroon}{}[1,TEXT\_CONST,true,1==2,5+NUM\_CONST]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1135} +\noindent\mdline{1135}The generated P4Info will contain:%mdk + +%mdk-data-line={1137} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1138} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedExprList}{\mdcolor{maroon}"}\\ +~~expression\_list~\{\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}1}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}hello}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~true\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~false\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}11}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1160} +\noindent\mdline{1160}\textbf{kvList of Mixed Expressions}\mdline{1160}%mdk + +%mdk-data-line={1162} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1163} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}MixedKV}{\mdcolor{maroon}{}[label="text",~my\_bool=true,~int\_val=2*3]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1169} +\noindent\mdline{1169}The generated P4Info will contain:%mdk + +%mdk-data-line={1171} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1172} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedKV}{\mdcolor{maroon}"}\\ +~~kv\_pair\_list~\{\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}label}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}text}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}my\_bool}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~bool\_value:~true\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}int\_val}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~int64\_value:~{\mdcolor{purple}6}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1197} +\subsubsection{\mdline{1197}6.1.5.\hspace*{0.5em}\mdline{1197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1197} Message}\label{sec-sourcelocation-message}%mdk%mdk + +%mdk-data-line={1199} +\noindent\mdline{1199}A source location describes a location within a \mdline{1199}\emph{.p4}\mdline{1199}-source file. The +\mdline{1200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1200} message is defined in p4types.proto as follows:%mdk + +%mdk-data-line={1202} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1203} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Location~of~code~relative~to~a~given~source~file.}\\ +{\bfseries{\mdcolor{navy}message}}~SourceLocation~\{\\ +~~{\mdcolor{darkgreen}//~Path~to~the~source~file~(absolute~or~relative~to~the~working~directory).}\\ +~~{\bfseries{\mdcolor{navy}string}}~file~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Line~and~column~numbers~within~the~source~file,~1-based.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~line~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}int32}}~column~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1213} +\noindent\mdline{1213}We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations.%mdk + +%mdk-data-line={1218} +\mdline{1218}The \mdline{1218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1218} message associated with an annotation holds the location of +the \mdline{1219}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@}}}\mdline{1219} symbol introducing the annotation in the P4 source code; the message can +be found in the following place:%mdk + +%mdk-data-line={1222} +\begin{itemize}%mdk + +%mdk-data-line={1222} +\item{} +%mdk-data-line={1222} +\mdline{1222}For \mdline{1222}\textbf{unstructured annotations}\mdline{1222}, every message containing a field +\mdline{1223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1223} also contains a field +\mdline{1224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~SourceLocation~annotation\_locations}}}\mdline{1224}. The i-th member of +\mdline{1225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation\_locations}}}\mdline{1225} is the source location of the i-th member of +\mdline{1226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1226}.%mdk%mdk + +%mdk-data-line={1228} +\item{} +%mdk-data-line={1228} +\mdline{1228}For \mdline{1228}\textbf{structured annotations}\mdline{1228}, every \mdline{1228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1228} message contains +a field \mdline{1229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation~source\_location}}}\mdline{1229} holding its source location.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1232} +\subsection{\mdline{1232}6.2.\hspace*{0.5em}\mdline{1232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1232} Message}\label{sec-pkginfo-message}%mdk%mdk + +%mdk-data-line={1234} +\noindent\mdline{1234}The \mdline{1234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1234} message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. \mdline{1235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1235} can be extracted +and used to facilitate \mdline{1236}\textquotedblleft{}browsing\textquotedblright{}\mdline{1236} of available P4 programs from a +library. Although all fields are technically \mdline{1237}\textquotedblleft{}optional,\textquotedblright{}\mdline{1237} every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included.%mdk + +%mdk-data-line={1241} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1242} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Can~be~used~to~manage~multiple~P4~packages.}\\ +{\bfseries{\mdcolor{navy}message}}~PkgInfo~\{\\ +~~{\mdcolor{darkgreen}//~a~definitive~name~for~this~configuration,~e.g.~switch.p4\_v1.0}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~configuration~version,~free-format~string}\\ +~~{\bfseries{\mdcolor{navy}string}}~version~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~brief~and~detailed~descriptions}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~free-form;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~the~target~architecture,~e.g.~"psa"}\\ +~~{\bfseries{\mdcolor{navy}string}}~arch~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\mdcolor{darkgreen}//~organization~which~produced~the~configuration,~e.g.~"p4.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~organization~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~{\mdcolor{darkgreen}//~contact~info~for~support,e.g.~"tech-support@acme.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~contact~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~url~for~more~information,~e.g.~"http://support.p4.org/ref/p4/switch.p4\_v1.0"}\\ +~~{\bfseries{\mdcolor{navy}string}}~url~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}8};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~structured;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}9};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1265} +\subsubsection{\mdline{1265}6.2.1.\hspace*{0.5em}\mdline{1265}Annotating P4 code with PkgInfo}\label{sec-annotating-p4-code-with-pkginfo}%mdk%mdk + +%mdk-data-line={1267} +\noindent\mdline{1267}A P4 progam\mdline{1267}'\mdline{1267}s \mdline{1267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1267} may be declared using one or more of the following +annotations, attached to the \mdline{1268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1268} block only:%mdk + +%mdk-data-line={1270} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1271} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value{}[,key=value,...])}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("A~brief~description")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("A~longer\textbackslash{}}\\ +description{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@custom\_annotation(...)}\\ +{\mdcolor{maroon}@another\_custom\_annotation(...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1280} +\noindent\mdline{1280}Above we see several different types of annotations:%mdk + +%mdk-data-line={1282} +\begin{itemize}%mdk + +%mdk-data-line={1282} +\item{} +%mdk-data-line={1282} +\mdline{1282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1282} \mdline{1282}- This is used to populate a specific field within the \mdline{1282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1282} +message. Multiple \mdline{1283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1283} annotations are allowed. For compactness, +multiple key-value pairs can appear in a single \mdline{1284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1284} annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The \mdline{1286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{1286}s must be from +among the message fields inside \mdline{1287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1287}, for example, \mdline{1287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1287}, \mdline{1287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}version}}}\mdline{1287}, +etc. Each key-value pair assigns a value to the corresponding field inside the +single \mdline{1289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1289} message for the program\mdline{1289}'\mdline{1289}s P4Info. One exception is that the +\mdline{1290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1290} field of \mdline{1290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1290} must be expressed as individual +\mdline{1291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1291} and \mdline{1291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1291} annotations, see next bullets. The key \mdline{1291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}arch}}}\mdline{1291} will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself.%mdk%mdk + +%mdk-data-line={1295} +\item{} +%mdk-data-line={1295} +\mdline{1295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1295} \mdline{1295}- This will populate the \mdline{1295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.brief}}}\mdline{1295} message field.%mdk%mdk + +%mdk-data-line={1297} +\item{} +%mdk-data-line={1297} +\mdline{1297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1297} \mdline{1297}- This will populate the \mdline{1297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.description}}}\mdline{1297} message +field%mdk%mdk + +%mdk-data-line={1300} +\item{} +%mdk-data-line={1300} +\mdline{1300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@\textless{}anything~else\textgreater{}}}}\mdline{1300} \mdline{1300}- This will create a \mdline{1300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotation}}}\mdline{1300} entry%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1302} +\noindent\mdline{1302}Declaring one or more of these annotations on \mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1302} will +generate a single corresponding \mdline{1303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1303} message in the P4Info as described in +\mdline{1304}\mdref{sec-pkginfo-message}{PkgInfo Message}\mdline{1304}.%mdk + +%mdk-data-line={1306} +\mdline{1306}The following example shows \mdline{1306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1306} annotations using a mixture of single and +multiple key-value pairs. It also shows \mdline{1307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1307} and \mdline{1307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1307} annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the \mdline{1309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1309} message. The custom annotations will +be appended to the \mdline{1310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotations}}}\mdline{1310} list.%mdk + +%mdk-data-line={1312} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1313} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(name="switch.p4",version="2")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(organization="p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(contact="info@p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(url="www.p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("L2/L3~switch")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("L2/L3~switch.\textbackslash{}}\\ +Built~for~data-center~profile.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@my\_annotation1(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}@my\_annotation2(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}PSA\_Switch(IgPipeline,~PacketReplicationEngine(),~EgPipeline,}\\ +{\mdcolor{maroon}~~~~~~~~~~~BufferingQueueingEngine())~main;}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1326} +\subsection{\mdline{1326}6.3.\hspace*{0.5em}\mdline{1326}ID Allocation for P4Info Objects}\label{sec-id-allocation}%mdk%mdk + +%mdk-data-line={1328} +\noindent\mdline{1328}P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(\mdline{1332}e.g.\mdline{1332} table, action, counter, \mdline{1332}\dots{}\mdline{1332}). The most significant 8 bits of the ID +encodes the object type (as per Table\mdline{1333}~\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}}\mdline{1333}). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (\mdline{1335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.P4Ids.Prefix}}}\mdline{1335}). These values must +be used (\mdline{1336}e.g.\mdline{1336} by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table\mdline{1338}~\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}}\mdline{1338} shows the ID +layout.%mdk + +%mdk-data-line={1341} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1343} 8-bit prefix value}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1343} P4 object type}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{1345} 0x00}&\multicolumn{1}{|l|}{\mdline{1345} Reserved (unspecified)}\\ +\multicolumn{1}{|l}{\mdline{1346} 0x01}&\multicolumn{1}{|l|}{\mdline{1346} Action}\\ +\multicolumn{1}{|l}{\mdline{1347} 0x02}&\multicolumn{1}{|l|}{\mdline{1347} Table}\\ +\multicolumn{1}{|l}{\mdline{1348} 0x03}&\multicolumn{1}{|l|}{\mdline{1348} Value-set}\\ +\multicolumn{1}{|l}{\mdline{1349} 0x04}&\multicolumn{1}{|l|}{\mdline{1349} Controller header (header type with \mdline{1349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1349} annotation)}\\ +\multicolumn{1}{|l}{\mdline{1350} 0x05\mdline{1350}\dots{}\mdline{1350}0x0f}&\multicolumn{1}{|l|}{\mdline{1350} Reserved (for future P4 built-in objects)}\\ +\multicolumn{1}{|l}{\mdline{1351} 0x10}&\multicolumn{1}{|l|}{\mdline{1351} Reserved (start of PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1352} 0x11}&\multicolumn{1}{|l|}{\mdline{1352} PSA Action profiles / selectors}\\ +\multicolumn{1}{|l}{\mdline{1353} 0x12}&\multicolumn{1}{|l|}{\mdline{1353} PSA Counter}\\ +\multicolumn{1}{|l}{\mdline{1354} 0x13}&\multicolumn{1}{|l|}{\mdline{1354} PSA Direct counter}\\ +\multicolumn{1}{|l}{\mdline{1355} 0x14}&\multicolumn{1}{|l|}{\mdline{1355} PSA Meter}\\ +\multicolumn{1}{|l}{\mdline{1356} 0x15}&\multicolumn{1}{|l|}{\mdline{1356} PSA Direct meter}\\ +\multicolumn{1}{|l}{\mdline{1357} 0x16}&\multicolumn{1}{|l|}{\mdline{1357} PSA Register}\\ +\multicolumn{1}{|l}{\mdline{1358} 0x17}&\multicolumn{1}{|l|}{\mdline{1358} PSA Digest}\\ +\multicolumn{1}{|l}{\mdline{1359} 0x18\mdline{1359}\dots{}\mdline{1359}0x7f}&\multicolumn{1}{|l|}{\mdline{1359} Reserved (for future PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1360} 0x80}&\multicolumn{1}{|l|}{\mdline{1360} Reserved (start of vendor-specific extern types)}\\ +\multicolumn{1}{|l}{\mdline{1361} 0x81\mdline{1361}\dots{}\mdline{1361}0xfe}&\multicolumn{1}{|l|}{\mdline{1361} Vendor-specific extern types}\\ +\multicolumn{1}{|l}{\mdline{1362} 0xff}&\multicolumn{1}{|l|}{\mdline{1362} Reserved (max prefix value)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1364} +\mdhr{}%mdk + +%mdk-data-line={1365} +\noindent\mdline{1365}\mdcaption{\textbf{Table~\mdcaptionlabel{1}.}~\mdcaptiontext{Mapping of P4Info object type to 8-bit ID prefix value}}%mdk +%mdk +\end{mdcenter}\label{tab-mapping-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1368} +\begin{table}[h!]%mdk +\begin{mdblock}{text-align=center,breakable=true}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{cc}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1370} MSB bit 31 \mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}.. bit 24}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1370} bit 23 \mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}\dots{}\mdline{1370}.. bit 0 LSB}}\\ + +\midrule +\multicolumn{1}{|c}{\mdline{1372} Object type prefix}&\multicolumn{1}{|c|}{\mdline{1372} Generated suffix (\mdline{1372}e.g.\mdline{1372} by the compiler)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1374} +\mdhr{}%mdk + +%mdk-data-line={1375} +\noindent\mdline{1375}\mdcaption{\textbf{Table~\mdcaptionlabel{2}.}~\mdcaptiontext{Format of P4Info object IDs}}%mdk%mdk +\end{mdblock}\label{tab-format-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1379} +\mdline{1379}It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with \mdline{1380}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1380} (see Table +\mdline{1381}\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}}\mdline{1381}). The compiler must honor the \mdline{1381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1381} annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (\mdline{1383}i.e.\mdline{1383} if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same \mdline{1385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1385} value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct.%mdk + +%mdk-data-line={1394} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth-7cm)/1}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{\mdinline{width=7cm}{{\bfseries\mdline{1396} P4 declaration(s)}}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1396} Compiler-allocated ID(s)}}\\ + +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1398} \mdline{1398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1398}}}&\multicolumn{1}{|l|}{\mdline{1398} 0x0212ab34}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1400} \mdline{1400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1400}}}&\multicolumn{1}{|l|}{\mdline{1400} \mdline{1400}\textbf{Error}\mdline{1400}(same ID suffixes for 2 objects of the same type)}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1401} \mdline{1401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tB...}}}\mdline{1401}}}&\multicolumn{1}{|l|}{\mdline{1401}}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1403} \mdline{1403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1403}}}&\multicolumn{1}{|l|}{\mdline{1403} 0x0212ab34}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1404} \mdline{1404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~action~act1...}}}\mdline{1404}}}&\multicolumn{1}{|l|}{\mdline{1404} 0x0112ab34}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1406} +\mdhr{}%mdk + +%mdk-data-line={1407} +\noindent\mdline{1407}\mdcaption{\textbf{Table~\mdcaptionlabel{3}.}~\mdcaptiontext{Example of statically-assigned P4Info object IDs}}%mdk +%mdk +\end{mdcenter}\label{tab-exmpl-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1410} +\mdline{1410}The \mdline{1410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1410} annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively).%mdk + +%mdk-data-line={1416} +\subsection{\mdline{1416}6.4.\hspace*{0.5em}\mdline{1416}P4Info Objects}\label{sec-p4info-objects}%mdk%mdk + +%mdk-data-line={1418} +\subsubsection{\mdline{1418}6.4.1.\hspace*{0.5em}\mdline{1418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}\label{sec-table}%mdk%mdk + +%mdk-data-line={1420} +\noindent\mdline{1420}Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields:%mdk + +%mdk-data-line={1423} +\begin{itemize}%mdk + +%mdk-data-line={1423} +\item{} +%mdk-data-line={1423} +\mdline{1423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1423}, a \mdline{1423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1423} message with the ID, name, and alias of this table.%mdk%mdk + +%mdk-data-line={1425} +\item{} +%mdk-data-line={1425} +\mdline{1425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1425}, a repeated field of type \mdline{1425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1425} representing the data to +be used to construct the lookup key matched in this table. Each \mdline{1426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1426} +message is defined with the following fields:%mdk + +%mdk-data-line={1429} +\begin{itemize}%mdk + +%mdk-data-line={1429} +\item{} +%mdk-data-line={1429} +\mdline{1429}id, the \mdline{1429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1429} identifier of this \mdline{1429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1429}, unique in the scope of +this table. No rules are prescribed on the way \mdline{1430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1430} IDs should be +allocated, as long as two \mdline{1431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1431} of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the \mdline{1435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1435} annotation, or let the compiler +choose them.%mdk%mdk + +%mdk-data-line={1438} +\item{} +%mdk-data-line={1438} +\mdline{1438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1438}, the string representing the name of this \mdline{1438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1438}.%mdk%mdk + +%mdk-data-line={1440} +\item{} +%mdk-data-line={1440} +\mdline{1440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1440}, a repeated field of strings, each one representing a P4 +annotation associated to this match field.%mdk%mdk + +%mdk-data-line={1443} +\item{} +%mdk-data-line={1443} +\mdline{1443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1443}, an \mdline{1443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1443} value set to the size in bits of this match field.%mdk%mdk + +%mdk-data-line={1445} +\item{} +%mdk-data-line={1445} +\mdline{1445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1445}, a \mdline{1445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{1445} describing the match behavior for this field; it can be +either:%mdk + +%mdk-data-line={1447} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1447} +\item\mdline{1447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1447}, an enum field of type \mdline{1447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchType}}}\mdline{1447}, which includes all +possible PSA match kinds.%mdk + +%mdk-data-line={1449} +\item\mdline{1449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_match\_type}}}\mdline{1449}, a string field which can be used to encode any +architecture-specific match type.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1452} +\item{} +%mdk-data-line={1452} +\mdline{1452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1452}, a \mdline{1452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1452} message describing this match field.%mdk%mdk + +%mdk-data-line={1454} +\item{} +%mdk-data-line={1454} +\mdline{1454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1454}, which indicates whether the match field has a\mdline{1454}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1455}; this is useful for +\mdline{1456}\mdref{sec-psa-metadata-translation}{translation}\mdline{1456}.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1458} +\item{} +%mdk-data-line={1458} +\mdline{1458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_refs}}}\mdline{1458}, a repeated \mdline{1458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1458} field representing the set of possible +actions for this table. The \mdline{1459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1459} message is used to reference an action +specified in the same P4Info message and it includes the following fields:%mdk + +%mdk-data-line={1461} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1461} +\item\mdline{1461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1461}, the \mdline{1461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1461} identifier of the action.%mdk + +%mdk-data-line={1462} +\item\mdline{1462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1462}, an enum value which can take one of three values: + \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1463}, \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1463} and \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1463}. The \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1463} of the + action is determined by the use of the P4 standard annotations + \mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1465} and \mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1465}~[\mdcite{p4actionannotations}{18}]\mdline{1465}. \mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1465} + (\mdline{1466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1466} annotation) means that the action can only appear within + the table, and never as the default action. \mdline{1467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1467} + (\mdline{1468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1468} annotation) means that the action can only be used as the + default action. \mdline{1469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1469} is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action.%mdk + +%mdk-data-line={1472} +\item\mdline{1472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1472}, a repeated string field, each one representing a P4 +annotation associated to the action \mdline{1473}\emph{reference}\mdline{1473} in this table.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1475} +\item{} +%mdk-data-line={1475} +\mdline{1475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\_default\_action\_id}}}\mdline{1475}, if this table has a constant default action, this +field will carry the \mdline{1476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1476} identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action\mdline{1479}'\mdline{1479}s +arguments.%mdk%mdk + +%mdk-data-line={1482} +\item{} +%mdk-data-line={1482} +\mdline{1482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation\_id}}}\mdline{1482}, the \mdline{1482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1482} identifier of the \mdline{1482}\textquotedblleft{}implementation\textquotedblright{}\mdline{1482} of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (\mdline{1485}e.g.\mdline{1485} a PSA \mdline{1485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1485} or \mdline{1485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{1485} +instance). The table is then referred to as an indirect match table.%mdk%mdk + +%mdk-data-line={1488} +\item{} +%mdk-data-line={1488} +\mdline{1488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_resource\_ids}}}\mdline{1488}, repeated \mdline{1488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1488} identifiers for all the direct +resources attached to this table, such as \mdline{1489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1489} and \mdline{1489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1489} +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2.%mdk%mdk + +%mdk-data-line={1495} +\item{} +%mdk-data-line={1495} +\mdline{1495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1495}, an \mdline{1495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1495} describing the desired number of table entries that the +target should support for the table. See the \mdline{1496}\textquotedblleft{}Size\textquotedblright{}\mdline{1496} subsection within the +\mdline{1497}\textquotedblleft{}Table Properties\textquotedblright{}\mdline{1497} section of the P4\mdline{1497}\mdsub{16}\mdline{1497} language specification for details +\mdline{1498}[\mdcite{p4tableproperties}{30}]\mdline{1498}.%mdk%mdk + +%mdk-data-line={1500} +\item{} +%mdk-data-line={1500} +\mdline{1500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_behavior}}}\mdline{1500}, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +\mdline{1502}\mdref{sec-idle-timeout}{Idle-Timeout}\mdline{1502} section). Value can be any of the +\mdline{1503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutBehavior}}}\mdline{1503} enum:%mdk + +%mdk-data-line={1504} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1504} +\item\mdline{1504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NO\_TIMEOUT}}}\mdline{1504} (default value), which means that idle timeout is not +supported for this table.%mdk + +%mdk-data-line={1506} +\item\mdline{1506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOTIFY\_CONTROL}}}\mdline{1506}, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +\mdline{1508}\mdref{sec-table-idle-timeout-notification}{Table Idle Timeout Notifications}\mdline{1508}).%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1510} +\item{} +%mdk-data-line={1510} +\mdline{1510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{1510}, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime.%mdk%mdk + +%mdk-data-line={1513} +\item{} +%mdk-data-line={1513} +\mdline{1513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{1513}, an \mdline{1513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1513} Protobuf message\mdline{1513}~[\mdcite{protoany}{31}]\mdline{1513} to embed +architecture-specific table properties\mdline{1514}~[\mdcite{p4tableproperties}{30}]\mdline{1514} which are not part +of the core P4 language or of the PSA architecture.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1517} +\subsubsection{\mdline{1517}6.4.2.\hspace*{0.5em}\mdline{1517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}\label{sec-action}%mdk%mdk + +%mdk-data-line={1519} +\noindent\mdline{1519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1519} messages are used to specify all possible actions of all match-action +tables.%mdk + +%mdk-data-line={1522} +\mdline{1522}The \mdline{1522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1522} message defines the following fields:%mdk + +%mdk-data-line={1524} +\begin{itemize}%mdk + +%mdk-data-line={1524} +\item{} +%mdk-data-line={1524} +\mdline{1524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1524}, a \mdline{1524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1524} message with the ID, name, and alias of this action%mdk%mdk + +%mdk-data-line={1526} +\item{} +%mdk-data-line={1526} +\mdline{1526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{1526}, a repeated field of \mdline{1526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1526} messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each \mdline{1528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1528} message contains the +following fields:%mdk + +%mdk-data-line={1530} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1530} +\item\mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1530}, the \mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1530} identifier of this parameter. No rules are prescribed +on the way \mdline{1531}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1531} IDs should be allocated, as long as two \mdline{1531}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1531} of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the \mdline{1535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1535} +annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1537} +\item\mdline{1537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1537}, the string representing the name of this parameter.%mdk + +%mdk-data-line={1538} +\item\mdline{1538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1538}, a repeated field of strings, each one representing a P4 +annotation associated to this parameter.%mdk + +%mdk-data-line={1540} +\item\mdline{1540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1540}, an \mdline{1540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1540} value set to the size in bits of this parameter.%mdk + +%mdk-data-line={1541} +\item\mdline{1541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1541}, which describes this parameter using a \mdline{1541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1541} message.%mdk + +%mdk-data-line={1542} +\item\mdline{1542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1542}, which indicates whether the action parameter has a +\mdline{1543}\mdref{sec-user-defined-types}{user-defined type}\mdline{1543}; this is useful for +\mdline{1544}\mdref{sec-psa-metadata-translation}{translation}\mdline{1544}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1546} +\subsubsection{\mdline{1546}6.4.3.\hspace*{0.5em}\mdline{1546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}\label{sec-p4info-action-profile}%mdk%mdk + +%mdk-data-line={1548} +\noindent\mdline{1548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1548} messages are used to specify all available instances of Action +Profile and Action Selector PSA externs.%mdk + +%mdk-data-line={1551} +\mdline{1551}PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile \mdline{1555}\emph{member}\mdline{1555}, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime.%mdk + +%mdk-data-line={1559} +\mdline{1559}PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into \mdline{1560}\emph{groups}\mdline{1560}. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime.%mdk + +%mdk-data-line={1569} +\mdline{1569}While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same \mdline{1570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1570} message to describe both.%mdk + +%mdk-data-line={1572} +\mdline{1572}The \mdline{1572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1572} message includes the following fields:%mdk + +%mdk-data-line={1574} +\begin{itemize}%mdk + +%mdk-data-line={1574} +\item{} +%mdk-data-line={1574} +\mdline{1574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1574}, a \mdline{1574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1574} message with the ID, name, and alias of this Action +Profile or Selector.%mdk%mdk + +%mdk-data-line={1577} +\item{} +%mdk-data-line={1577} +\mdline{1577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_ids}}}\mdline{1577}, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector.%mdk%mdk + +%mdk-data-line={1580} +\item{} +%mdk-data-line={1580} +\mdline{1580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}with\_selector}}}\mdline{1580}, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern.%mdk%mdk + +%mdk-data-line={1583} +\item{} +%mdk-data-line={1583} +\mdline{1583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1583}, an \mdline{1583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1583} representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups.%mdk%mdk + +%mdk-data-line={1587} +\item{} +%mdk-data-line={1587} +\mdline{1587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1587}, an \mdline{1587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1587} representing the maximum sum of all member +weights within any given selector group, in the case of an Action Selector, or +0 for an Action Profile. PSA programs can use the \mdline{1589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{1589} annotation +to provide this value for Action Selectors. If the annotation is omitted, the +P4Info field will default to 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1593} +\subsubsection{\mdline{1593}6.4.4.\hspace*{0.5em}\mdline{1593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1593} \mdline{1593}\&\mdline{1593} \mdline{1593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}\label{sec-counter-directcounter}%mdk%mdk + +%mdk-data-line={1595} +\noindent\mdline{1595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1595} and \mdline{1595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1595} messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is:%mdk + +%mdk-data-line={1601} +\begin{itemize}%mdk + +%mdk-data-line={1601} +\item{} +%mdk-data-line={1601} +\mdline{1601}Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index.%mdk%mdk + +%mdk-data-line={1605} +\item{} +%mdk-data-line={1605} +\mdline{1605}Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1608} +\noindent\mdline{1608}Both \mdline{1608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1608} and \mdline{1608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1608} messages share the following fields:%mdk + +%mdk-data-line={1610} +\begin{itemize}%mdk + +%mdk-data-line={1610} +\item{} +%mdk-data-line={1610} +\mdline{1610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1610}, a \mdline{1610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1610} message with the ID, name, and alias of this counter +extern instance.%mdk%mdk + +%mdk-data-line={1613} +\item{} +%mdk-data-line={1613} +\mdline{1613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1613}, a message of of type \mdline{1613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1613} used to describe the compile-time +configuration of this counter. Currently, the \mdline{1614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1614} message is used to +carry only the counter unit, which can be any of the \mdline{1615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec.Unit}}}\mdline{1615} enum +values:%mdk + +%mdk-data-line={1617} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1617} +\item\mdline{1617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1617}: reserved value.%mdk + +%mdk-data-line={1618} +\item\mdline{1618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1618}: byte counter.%mdk + +%mdk-data-line={1619} +\item\mdline{1619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1619}: packet counter.%mdk + +%mdk-data-line={1620} +\item\mdline{1620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BOTH}}}\mdline{1620}: combination of both byte and packet counter.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1622} +\noindent\mdline{1622}For indexed counters, the \mdline{1622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1622} message contains also a \mdline{1622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1622} field, an +\mdline{1623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1623} representing the maximum number of independent values that can be held +by this counter array. Conversely, the \mdline{1624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1624} message contains a +\mdline{1625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1625} field that carries the \mdline{1625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}unit32}}}\mdline{1625} identifier of the table to +which this direct counter is attached.%mdk + +%mdk-data-line={1628} +\mdline{1628}For indexed counters, the \mdline{1628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1628} message contains also an \mdline{1628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1628} +field, which indicates whether the index has a\mdline{1629}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1630}. This is useful for +\mdline{1631}\mdref{sec-psa-metadata-translation}{translation}\mdline{1631}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1632}).%mdk + +%mdk-data-line={1634} +\subsubsection{\mdline{1634}6.4.5.\hspace*{0.5em}\mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1634} \mdline{1634}\&\mdline{1634} \mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}\label{sec-meter-directmeter}%mdk%mdk + +%mdk-data-line={1636} +\noindent\mdline{1636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1636} and \mdline{1636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1636} messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is:%mdk + +%mdk-data-line={1642} +\begin{itemize}%mdk + +%mdk-data-line={1642} +\item{} +%mdk-data-line={1642} +\mdline{1642}Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +\mdline{1644}e.g.\mdline{1644} to set the rate threshold.%mdk%mdk + +%mdk-data-line={1646} +\item{} +%mdk-data-line={1646} +\mdline{1646}Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1649} +\noindent\mdline{1649}Both \mdline{1649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1649} and \mdline{1649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1649} messages share the following fields:%mdk + +%mdk-data-line={1651} +\begin{itemize}%mdk + +%mdk-data-line={1651} +\item{} +%mdk-data-line={1651} +\mdline{1651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1651}, a \mdline{1651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1651} message with the ID, name, and alias of this meter +extern instance.%mdk%mdk + +%mdk-data-line={1654} +\item{} +%mdk-data-line={1654} +\mdline{1654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1654}, a message of type \mdline{1654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1654} used to describe the capabilities of +this meter extern instance. Currently, the \mdline{1655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1655} message is used to +carry only the meter unit, which can be any of the \mdline{1656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Unit}}}\mdline{1656} enum +values:%mdk + +%mdk-data-line={1658} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1658} +\item\mdline{1658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1658}: reserved value.%mdk + +%mdk-data-line={1659} +\item\mdline{1659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1659}, which signifies that this meter can be configured with rates +expressed in bytes/second.%mdk + +%mdk-data-line={1661} +\item\mdline{1661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1661}, for rates expressed in packets/second.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1663} +\noindent\mdline{1663}For indexed meters, the \mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1663} message contains also a \mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1663} field, an \mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1663} +representing the maximum number of independent cells that can be held by this +meter. Conversely, the \mdline{1665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1665} message contains a \mdline{1665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1665} field +that carries the \mdline{1666}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1666} identifier of the table to which this direct meter is +attached.%mdk + +%mdk-data-line={1669} +\mdline{1669}For indexed meters, the \mdline{1669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1669} message contains also an \mdline{1669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1669} +field, which indicates whether the index has a\mdline{1670}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1671}. This is useful for +\mdline{1672}\mdref{sec-psa-metadata-translation}{translation}\mdline{1672}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1673}).%mdk + +%mdk-data-line={1675} +\subsubsection{\mdline{1675}6.4.6.\hspace*{0.5em}\mdline{1675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\label{sec-controller-packet-meta}%mdk%mdk + +%mdk-data-line={1677} +\noindent\mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1677} messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server.%mdk + +%mdk-data-line={1683} +\mdline{1683}When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet.%mdk + +%mdk-data-line={1689} +\mdline{1689}Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +\mdline{1691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_in")}}}\mdline{1691} and \mdline{1691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_out")}}}\mdline{1691}, +respectively. \mdline{1692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1692} messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages).%mdk + +%mdk-data-line={1697} +\mdline{1697}A P4Info message can contain at most two \mdline{1697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata~messages}}}\mdline{1697}, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields:%mdk + +%mdk-data-line={1701} +\begin{itemize}%mdk + +%mdk-data-line={1701} +\item{} +%mdk-data-line={1701} +\mdline{1701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1701}, a \mdline{1701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1701} message where \mdline{1701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble.name}}}\mdline{1701} is set to \mdline{1701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_in"}}}\mdline{1701} +and \mdline{1702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_out"}}}\mdline{1702} for packet-in and packet-out metadata, respectively.%mdk%mdk + +%mdk-data-line={1704} +\item{} +%mdk-data-line={1704} +\mdline{1704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{1704}, a repeated field of type \mdline{1704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1704}, where each \mdline{1704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1704} message +includes the following fields:%mdk + +%mdk-data-line={1706} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1706} +\item\mdline{1706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1706}, a \mdline{1706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1706} identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two \mdline{1707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1707} of the +same \mdline{1708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1708} message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the \mdline{1712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1712} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1713} +\item\mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1713}, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below).%mdk + +%mdk-data-line={1717} +\item\mdline{1717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1717}, a repeated field of strings, each one representing a P4 +annotation associated to this metadata.%mdk + +%mdk-data-line={1719} +\item\mdline{1719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1719}, an \mdline{1719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1719} representing the size in bits of this metadata.%mdk + +%mdk-data-line={1720} +\item\mdline{1720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1720}, which indicates whether the metadata field has a +\mdline{1721}\mdref{sec-user-defined-types}{user-defined type}\mdline{1721}; this is useful for +\mdline{1722}\mdref{sec-psa-metadata-translation}{translation}\mdline{1722}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1724} +\noindent\mdline{1724}As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding \mdline{1725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1725} +messages.%mdk + +%mdk-data-line={1728} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1729} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~egress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~port~where~the~packet}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~should~be~sent~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~queue\_id;~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~queue~ID~}{\mdcolor{darkgreen}*/}\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~ingress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~data~plane~port~ID~where}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~the~original~packet~was~received~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}1}\textgreater{}~is\_clone;~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~1~if~this~is~a~clone~of~the}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~original~packet~}{\mdcolor{darkgreen}*/}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1744} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1745} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868916615}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_out}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_out}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}egress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}queue\_id}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~\}\\ +\}\\ +\\ +controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868941301}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_in}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_in}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ingress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}is\_clone}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}1}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1782} +\noindent\mdline{1782}Note that the use of \mdline{1782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1782} is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages.%mdk + +%mdk-data-line={1788} +\subsubsection{\mdline{1788}6.4.7.\hspace*{0.5em}\mdline{1788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}\label{sec-valueset}%mdk%mdk + +%mdk-data-line={1790} +\noindent\mdline{1790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1790} messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P4\mdline{1793}\mdsub{16}\mdline{1793} +specification\mdline{1794}~[\mdcite{p4valuesets}{39}]\mdline{1794}.%mdk + +%mdk-data-line={1796} +\mdline{1796}The \mdline{1796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1796} message defines the following fields:%mdk + +%mdk-data-line={1798} +\begin{itemize}%mdk + +%mdk-data-line={1798} +\item{} +%mdk-data-line={1798} +\mdline{1798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1798}, a \mdline{1798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1798} message with the ID, name, and alias of this Value +Set.%mdk%mdk + +%mdk-data-line={1801} +\item{} +%mdk-data-line={1801} +\mdline{1801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1801}, a repeated field of \mdline{1801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1801} messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the \mdline{1804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1804} repeated field in the +\mdline{1805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{1805} message.%mdk%mdk + +%mdk-data-line={1807} +\item{} +%mdk-data-line={1807} +\mdline{1807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1807}, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +\mdline{1809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set}}}\mdline{1809} constructor call.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1811} +\noindent\mdline{1811}According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of \mdline{1814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1814}, +\mdline{1815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1815}, or \mdline{1815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1815}~[\mdcite{p4selectexpr}{26}]\mdline{1815}. The rest of this section looks at all 3 of +these cases and gives an example \mdline{1816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1816} message when appropriate.%mdk + +%mdk-data-line={1818} +\begin{enumerate}%mdk + +%mdk-data-line={1818} +\item{} +%mdk-data-line={1818} +\mdline{1818}If the type parameter is \mdline{1818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1818}, \mdline{1818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1818} will include exactly one +\mdline{1819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1819} message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used):%mdk + +%mdk-data-line={1822} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1822} +\item\mdline{1822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1822}: set to 1%mdk + +%mdk-data-line={1823} +\item\mdline{1823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1823}: set to the value of \mdline{1823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1823}%mdk + +%mdk-data-line={1824} +\item\mdline{1824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1824}: set to \mdline{1824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1824}%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1826} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1827} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}bit\textless{}8\textgreater{}~\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(hdr.f8)~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1830} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1831} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1845} +\begin{enumerate}[,start=2]%mdk + +%mdk-data-line={1845} +\item{} +%mdk-data-line={1845} +\mdline{1845}If the type parameter is a \mdline{1845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1845}, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program.%mdk%mdk + +%mdk-data-line={1850} +\item{} +%mdk-data-line={1850} +\mdline{1850}If the type parameter is a \mdline{1850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1850}, this version of P4Runtime requires that +all the fields of the struct be of type \mdline{1851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1851} (where \mdline{1851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1851} can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +\mdline{1854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1854} field will include one \mdline{1854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1854} message for each field in the +struct, with the following fields:%mdk + +%mdk-data-line={1857} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1857} +\item\mdline{1857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1857}: must be unique with respect to the other \mdline{1857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1857} entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +\mdline{1861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1861} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1862} +\item\mdline{1862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1862}: set to the name of the corresponding struct field.%mdk + +%mdk-data-line={1863} +\item\mdline{1863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1863}: set to the list of P4 annotations associated with the struct +field, except for the \mdline{1864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1864} annotation, if present (see the \mdline{1864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1864} field +below).%mdk + +%mdk-data-line={1866} +\item\mdline{1866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1866}: set to the value of \mdline{1866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1866} for the corresponding struct field.%mdk + +%mdk-data-line={1867} +\item\mdline{1867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1867}, which indicates whether the struct field has a\mdline{1867}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1868}; this is useful for +\mdline{1869}\mdref{sec-psa-metadata-translation}{translation}\mdline{1869}.%mdk + +%mdk-data-line={1870} +\item\mdline{1870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1870}: by default \mdline{1870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1870} is set to \mdline{1870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1870}; the P4 programmer can +specify a different match type by using the \mdline{1871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1871} annotation +\mdline{1872}[\mdcite{p4selectexpr}{26}]\mdline{1872}.%mdk + +%mdk-data-line={1873} +\item\mdline{1873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1873}: documentation associated with the struct field.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1875} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1876} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~bit\textless{}8\textgreater{}~f8;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(2)~@match(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(3)~@match(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1884} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1885} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1912} +\noindent\mdline{1912}In the above example, the \mdline{1912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1912} annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs.%mdk + +%mdk-data-line={1915} +\mdline{1915}Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a\mdline{1916}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1917} that resolves to a \mdline{1917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1917}, or a \mdline{1917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1917} where +one or more fields is a\mdline{1918}~\mdref{sec-user-defined-types}{user-defined type}\mdline{1918} that +resolves to a \mdline{1919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1919}. For each \mdline{1919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1919} that corresponds to a user-defined +type, the \mdline{1920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1920} field must be set to the appropriate value (\mdline{1920}i.e.\mdline{1920} the name +of the type).%mdk + +%mdk-data-line={1923} +\subsubsection{\mdline{1923}6.4.8.\hspace*{0.5em}\mdline{1923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}\label{sec-register}%mdk%mdk + +%mdk-data-line={1925} +\noindent\mdline{1925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1925} messages are used to specify all possible instances of Register PSA +externs.%mdk + +%mdk-data-line={1928} +\mdline{1928}Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime.%mdk + +%mdk-data-line={1932} +\mdline{1932}The \mdline{1932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1932} message defines the following fields:%mdk + +%mdk-data-line={1934} +\begin{itemize}%mdk + +%mdk-data-line={1934} +\item{} +%mdk-data-line={1934} +\mdline{1934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1934}, a \mdline{1934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1934} message with the ID, name, and alias of this register +instance.%mdk%mdk + +%mdk-data-line={1937} +\item{} +%mdk-data-line={1937} +\mdline{1937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1937}, which specifies the data type stored by this register, expressed +using a \mdline{1938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1938} message (see section on\mdline{1938}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary +P4 Types}\mdline{1939}).%mdk%mdk + +%mdk-data-line={1941} +\item{} +%mdk-data-line={1941} +\mdline{1941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1941}, an \mdline{1941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1941} value representing the total number of independent register +cells available.%mdk%mdk + +%mdk-data-line={1944} +\item{} +%mdk-data-line={1944} +\mdline{1944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1944}, which indicates whether the register index has a +\mdline{1945}\mdref{sec-user-defined-types}{user-defined type}\mdline{1945}. This is useful for +\mdline{1946}\mdref{sec-psa-metadata-translation}{translation}\mdline{1946}. The underlying built-in type +must be a fixed-width unsigned bitstring (\mdline{1947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1947}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1949} +\subsubsection{\mdline{1949}6.4.9.\hspace*{0.5em}\mdline{1949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}\label{sec-digest}%mdk%mdk + +%mdk-data-line={1951} +\noindent\mdline{1951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1951} messages are used to specify all possible instances of Packet Digest +PSA externs.%mdk + +%mdk-data-line={1954} +\mdline{1954}A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages.%mdk + +%mdk-data-line={1963} +\mdline{1963}The \mdline{1963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1963} message defines the following fields:%mdk + +%mdk-data-line={1965} +\begin{itemize}%mdk + +%mdk-data-line={1965} +\item{} +%mdk-data-line={1965} +\mdline{1965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1965}, a \mdline{1965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1965} message with the ID, name, and alias of this digest +instance.%mdk%mdk + +%mdk-data-line={1968} +\item{} +%mdk-data-line={1968} +\mdline{1968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1968}, which specifies the data type of an individual digest +notification using a \mdline{1969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1969} message (see section on\mdline{1969}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation +of Arbitrary P4 Types}\mdline{1970}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1972} +\subsubsection{\mdline{1972}6.4.10.\hspace*{0.5em}\mdline{1972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}\label{sec-p4info-extern}%mdk%mdk + +%mdk-data-line={1974} +\noindent\mdline{1974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1974} messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one \mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1977} message instance in P4Info. The \mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1977} message defines +the following fields:%mdk + +%mdk-data-line={1980} +\begin{itemize}%mdk + +%mdk-data-line={1980} +\item{} +%mdk-data-line={1980} +\mdline{1980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{1980}, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the\mdline{1981}~\mdref{sec-id-allocation}{reserved +range}\mdline{1982} \mdline{1982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{}[0x81,~0xfe]}}}\mdline{1982}. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture.%mdk%mdk + +%mdk-data-line={1987} +\item{} +%mdk-data-line={1987} +\mdline{1987}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_name}}}\mdline{1987}, which specifies the fully-qualified P4 name of the extern +type.%mdk%mdk + +%mdk-data-line={1990} +\item{} +%mdk-data-line={1990} +\mdline{1990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instances}}}\mdline{1990}, a repeated field of \mdline{1990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{1990} Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +\mdline{1992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{1992} in turn defines the following fields:%mdk + +%mdk-data-line={1994} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1994} +\item\mdline{1994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1994}, a \mdline{1994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1994} message with the ID, name, and alias of this digest +instance.%mdk + +%mdk-data-line={1996} +\item\mdline{1996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{1996}, an \mdline{1996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1996} Protobuf message\mdline{1996}~[\mdcite{protoany}{31}]\mdline{1996} which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for \mdline{1998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{1998} should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on\mdline{2000}~\mdref{sec-extending-p4runtime}{Extending +P4Runtime for non-PSA Architectures}\mdline{2001} for more +information.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2004} +\noindent\mdline{2004}If the P4 program does not include any instance of a given extern type, the +\mdline{2005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2005} message instance for that type should be omitted from the P4Info.%mdk + +%mdk-data-line={2007} +\subsection{\mdline{2007}6.5.\hspace*{0.5em}\mdline{2007}Support for Arbitrary P4 Types with P4TypeInfo}\label{sec-support-for-arbitrary-p4-types-with-p4typeinfo}%mdk%mdk + +%mdk-data-line={2009} +\noindent\mdline{2009}See section on\mdline{2009}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary P4 +Types}\mdline{2010}.%mdk + +%mdk-data-line={2012} +\section{\mdline{2012}7.\hspace*{0.5em}\mdline{2012}P4 Forwarding-Pipeline Configuration}\label{sec-p4-fwd-pipe-config}%mdk%mdk + +%mdk-data-line={2014} +\noindent\mdline{2014}The \mdline{2014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2014} captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the \mdline{2016}\textquotedblleft{}Device Configuration\textquotedblright{}\mdline{2016} and sometimes also referred to as +the \mdline{2017}\textquotedblleft{}P4 Blob\textquotedblright{}\mdline{2017}. It is defined as:%mdk + +%mdk-data-line={2019} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2020} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ForwardingPipelineConfig~\{\\ +~~config.P{\mdcolor{purple}4}Info~p4info~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~p4\_device\_config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}message}}~Cookie~\{\\ +~~~~{\bfseries{\mdcolor{navy}uint64}}~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~\}\\ +~~Cookie~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2030} +\noindent\mdline{2030}The \mdline{2030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{2030} field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic.%mdk + +%mdk-data-line={2033} +\mdline{2033}The \mdline{2033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{2033} is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new \mdline{2035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2035} on that target.%mdk + +%mdk-data-line={2037} +\mdline{2037}The \mdline{2037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{2037} field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a \mdline{2042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{2042} RPC. +When writing the config via a \mdline{2043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{2043} RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present.%mdk + +%mdk-data-line={2047} +\section{\mdline{2047}8.\hspace*{0.5em}\mdline{2047}General Principles for Message Formatting}\label{sec-general-principles-for-message-formatting}%mdk%mdk + +%mdk-data-line={2049} +\subsection{\mdline{2049}8.1.\hspace*{0.5em}\mdline{2049}Set / Unset Protobuf Field}\label{sec-set-unset-protobuf-field}%mdk%mdk + +%mdk-data-line={2051} +\noindent\mdline{2051}In Protobuf version 3 (\mdline{2051}\emph{proto3}\mdline{2051}), the default value for a message field is +\mdline{2052}\textquotedblleft{}unset\textquotedblright{}\mdline{2052}~[\mdcite{protodefaults}{4}]\mdline{2052}. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +\mdline{2057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2057} message, an \mdline{2057}\textquotedblleft{}unset\textquotedblright{}\mdline{2057} \mdline{2057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2057} field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the \mdline{2059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2059} message field is +set, a single entry will be read.%mdk + +%mdk-data-line={2062} +\mdline{2062}Let\mdline{2062}'\mdline{2062}s look at the counter example in more details. Based on this specification +document, the C++ server code which processes \mdline{2063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2063} messages may look +like this:%mdk + +%mdk-data-line={2065} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2066} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}auto}}~*counter\_entry~=~...\\ +{\bfseries{\mdcolor{navy}if}}~(counter\_entry-\textgreater{}has\_index())~\{\\ +~~{\bfseries{\mdcolor{navy}auto}}~index~=~counter\_entry-\textgreater{}index().index();\\ +~~read\_one\_entry(counter\_entry-\textgreater{}id(),~index);\\ +\}~{\bfseries{\mdcolor{navy}else}}~\{\\ +~~read\_all\_entries(counter\_entry-\textgreater{}id());\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2075} +\begin{enumerate}%mdk + +%mdk-data-line={2075} +\item{} +%mdk-data-line={2075} +\mdline{2075}Reading a single counter entry at index 0 in the counter array with id +\mdline{2076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textless{}id\textgreater{}}}}\mdline{2076}:%mdk + +%mdk-data-line={2077} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2077} +\item\mdline{2077}Here is the C++ client code: + +%mdk-data-line={2078} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2079} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});\\ +entry.mutable\_index();\\ +{\mdcolor{darkgreen}//~The~above~line~sets~the~index~field;~it~is~equivalent~to:}\\ +{\mdcolor{darkgreen}//~auto~*index~=~entry.mutable\_index();}\\ +{\mdcolor{darkgreen}//~index-\textgreater{}set\_index(0);}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2086} +\item\mdline{2086}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2087} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2088} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}\\ +index~\{\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2091} +\item\mdline{2091}\textbf{Expected behavior}\mdline{2091}: Counter entry at index 0 is read. Notice that the +\mdline{2092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2092} subfield is missing under the \mdline{2092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2092} field message of +\mdline{2093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2093} in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2098} +\item{} +%mdk-data-line={2098} +\mdline{2098}Reading all counter entries by leaving the \mdline{2098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2098} field unset%mdk + +%mdk-data-line={2099} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2099} +\item\mdline{2099}Here is the C++ client code: + +%mdk-data-line={2100} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2101} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2104} +\item\mdline{2104}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2105} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2106} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2108} +\item\mdline{2108}\textbf{Expected behavior}\mdline{2108}: All counter entries for the provided counter +instance are read. Notice that the \mdline{2109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2109} message field is unset (default +value) and is therefore omitted from the textual representation of the +message.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={2113} +\subsection{\mdline{2113}8.2.\hspace*{0.5em}\mdline{2113}Read-Write Symmetry}\label{sec-read-write-symmetry}%mdk%mdk + +%mdk-data-line={2115} +\noindent\mdline{2115}The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example:%mdk + +%mdk-data-line={2121} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2122} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}intended\_value~=~value\\ +\\ +status~=~server.write(intended\_value,~p4\_entity)\\ +observed\_value~=~server.read(p4\_entity)\\ +\\ +assert(intended\_value~==~observed\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2130} +\noindent\mdline{2130}To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If \mdline{2134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{2134} RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol\mdline{2137}'\mdline{2137}s complexities to the client implementations.%mdk + +%mdk-data-line={2139} +\mdline{2139}In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the \mdline{2142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2142} fields in a \mdline{2142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2142} message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +\mdline{2145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MessageDifferencer}}}\mdline{2145} class\mdline{2145}~[\mdcite{protomessagedifferencer}{36}]\mdline{2145} included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance.%mdk + +%mdk-data-line={2150} +\subsection{\mdline{2150}8.3.\hspace*{0.5em}\mdline{2150}Zero as Reserved Value}\label{sec-zero-as-reserved-value}%mdk%mdk + +%mdk-data-line={2152} +\noindent\mdline{2152}p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a \mdline{2153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{2153}. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a \mdline{2156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{2156} or a \mdline{2156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfigRequest}}}\mdline{2156}.%mdk + +%mdk-data-line={2158} +\subsection{\mdline{2158}8.4.\hspace*{0.5em}\mdline{2158}Bytestrings}\label{sec-bytestrings}%mdk%mdk + +%mdk-data-line={2160} +\noindent\mdline{2160}P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (\mdline{2162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2162}) or signed (\mdline{2162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2162}), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +\mdline{2165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2165} Protobuf type. The correct bitwidth\mdline{2165} \mdline{2165}\textemdash{}\mdline{2165} as per the P4 program\mdline{2165} \mdline{2165}\textemdash{}\mdline{2165} of +each integer variable exposed through P4Runtime is specified in the P4Info +message.%mdk + +%mdk-data-line={2169} +\mdline{2169}The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals:%mdk + +%mdk-data-line={2172} +\begin{itemize}%mdk + +%mdk-data-line={2172} +\item{} +%mdk-data-line={2172} +\mdline{2172}It ensures that a properly encoded binary string\mdline{2172}'\mdline{2172}s integer value conforms +to the P4Info-specified bitwidth.%mdk%mdk + +%mdk-data-line={2175} +\item{} +%mdk-data-line={2175} +\mdline{2175}It supports\mdline{2175}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2175}.%mdk%mdk + +%mdk-data-line={2177} +\item{} +%mdk-data-line={2177} +\mdline{2177}It helps facilitate non-disruptive P4 program updates.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2179} +\noindent\mdline{2179}In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type \mdline{2184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2184} and/or \mdline{2184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2184}.%mdk + +%mdk-data-line={2186} +\mdline{2186}Note that this representation does \mdline{2186}\emph{not}\mdline{2186} make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range.%mdk + +%mdk-data-line={2195} +\mdline{2195}In the P4Runtime API version 1.0, values of table key fields, action parameters, +and fields in packet-in and packet-out headers between a device and the +controller (see\mdline{2197}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{2197}), may not be of type \mdline{2197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2197}. +The rules for encoding signed values thus only apply to messages of type +\mdline{2199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2199} (see\mdline{2199}~\mdref{sec-p4data-in-p4runtime-proto}{8.5.3}\mdline{2199}).%mdk + +%mdk-data-line={2201} +\mdline{2201}For a value of type \mdline{2201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2201}, the fewest number of bits required to represent +the integer value \mdline{2202}$V > 0$\mdline{2202} is the smallest integer \mdline{2202}$A$\mdline{2202} such that \mdline{2202}$V \leq 2^A -1$\mdline{2203}.%mdk + +%mdk-data-line={2205} +\mdline{2205}For a value of type \mdline{2205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2205}, the fewest number of bits required to represent +the integer value \mdline{2206}$V \neq 0$\mdline{2206} in 2\mdline{2206}'\mdline{2206}s complement form is the smallest integer \mdline{2206}$A$\mdline{2206} +such that \mdline{2207}$-2^{A-1} \leq V \leq 2^{A-1} - 1$\mdline{2207}.%mdk + +%mdk-data-line={2209} +\mdline{2209}As a special case, define that the value \mdline{2209}$V=0$\mdline{2209} requires at least \mdline{2209}$A=1$\mdline{2209} bit to +represent, regardless of whether it is signed or unsigned.%mdk + +%mdk-data-line={2212} +\mdline{2212}The shortest possible binary string for an integer \mdline{2212}$V$\mdline{2212} that needs \mdline{2212}$A$\mdline{2212} bits to +represent it is computed as:%mdk + +%mdk-data-line={2214} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2215} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size~=~floor(({\mdcolor{teal}A}~+~{\mdcolor{purple}7})~/~{\mdcolor{purple}8})}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2218} +\noindent\mdline{2218}Binary strings with the byte length computed as \mdline{2218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2218} promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies.%mdk + +%mdk-data-line={2222} +\mdline{2222}Any additional bits in the bytes sent for an unsigned integer value (type +\mdline{2223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2223}) must be 0. If additional bytes are transmitted above the +\mdline{2224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2224} minimum required, they must be filled with 0.%mdk + +%mdk-data-line={2226} +\mdline{2226}Any additional bits in the bytes sent for a signed integer value (type \mdline{2226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2226}) +must be copies of the sign bit, \mdline{2227}i.e.\mdline{2227} 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +\mdline{2229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2229} minimum required, they must be filled with copies of the +sign bit, \mdline{2230}i.e.\mdline{2230} 0 for non-negative values, or 0xff for negative values. In 2\mdline{2230}'\mdline{2230}s +complement representation, this is called \mdline{2231}\textquotedblleft{}sign extension\textquotedblright{}\mdline{2231}, and leaves the +numeric value represented unchanged.%mdk + +%mdk-data-line={2234} +\mdline{2234}Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value.%mdk + +%mdk-data-line={2240} +\mdline{2240}For a received bitstring expected to fit within a \mdline{2240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2240} type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring\mdline{2242}'\mdline{2242}s width is \mdline{2242}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2242} bits or less.%mdk + +%mdk-data-line={2244} +\mdline{2244}For a received bitstring expected to fit within an \mdline{2244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2244} type, the value it +represents is in range if, after \mdline{2245}\textquotedblleft{}undoing sign extension\textquotedblright{}\mdline{2245}, the remaining bit +string\mdline{2246}'\mdline{2246}s width is \mdline{2246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2246} bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other.%mdk + +%mdk-data-line={2252} +\mdline{2252}If the string\mdline{2252}'\mdline{2252}s byte length is zero, the server always rejects the string.%mdk + +%mdk-data-line={2254} +\mdline{2254}When the server rejects a binary string due to any of the previous criteria, +it returns an \mdline{2255}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2255} error.%mdk + +%mdk-data-line={2257} +\mdline{2257}For all binary strings, P4Runtime uses big-endian (\mdline{2257}i.e.\mdline{2257} network) byte-order. +For signed integer values (\mdline{2258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2258} P4 type), P4Runtime uses the same two\mdline{2258}'\mdline{2258}s +complement bitwise representation as P4. Table\mdline{2259}~\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}}\mdline{2259} +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above.%mdk + +%mdk-data-line={2263} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2265} P4 type}}&\multicolumn{1}{|c}{{\bfseries\mdline{2265} Integer value}}&\multicolumn{1}{|c}{{\bfseries\mdline{2265} P4Runtime binary string}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2265} Read-write symmetry}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2267} \mdline{2267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2267}}&\multicolumn{1}{|l}{\mdline{2267} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2267} \mdline{2267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2267}}&\multicolumn{1}{|l|}{\mdline{2267} yes}\\ +\multicolumn{1}{|l}{\mdline{2268} \mdline{2268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2268}}&\multicolumn{1}{|l}{\mdline{2268} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2268} \mdline{2268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2268}}&\multicolumn{1}{|l|}{\mdline{2268} no}\\ +\multicolumn{1}{|l}{\mdline{2269} \mdline{2269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2269}}&\multicolumn{1}{|l}{\mdline{2269} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2269} \mdline{2269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2269}}&\multicolumn{1}{|l|}{\mdline{2269} yes}\\ +\multicolumn{1}{|l}{\mdline{2270} \mdline{2270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2270}}&\multicolumn{1}{|l}{\mdline{2270} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2270} \mdline{2270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x30\textbackslash{}x64}}}\mdline{2270}}&\multicolumn{1}{|l|}{\mdline{2270} yes}\\ +\multicolumn{1}{|l}{\mdline{2271} \mdline{2271}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2271}}&\multicolumn{1}{|l}{\mdline{2271} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2271} \mdline{2271}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x30\textbackslash{}x64}}}\mdline{2271}}&\multicolumn{1}{|l|}{\mdline{2271} no}\\ +\multicolumn{1}{|l}{\mdline{2272} \mdline{2272}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2272}}&\multicolumn{1}{|l}{\mdline{2272} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2272} \mdline{2272}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2272}}&\multicolumn{1}{|l|}{\mdline{2272} no}\\ +\multicolumn{1}{|l}{\mdline{2273} \mdline{2273}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2273}}&\multicolumn{1}{|l}{\mdline{2273} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2273} \mdline{2273}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2273}}&\multicolumn{1}{|l|}{\mdline{2273} yes}\\ +\multicolumn{1}{|l}{\mdline{2274} \mdline{2274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2274}}&\multicolumn{1}{|l}{\mdline{2274} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2274} \mdline{2274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00\textbackslash{}x63}}}\mdline{2274}}&\multicolumn{1}{|l|}{\mdline{2274} no}\\ +\multicolumn{1}{|l}{\mdline{2275} \mdline{2275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2275}}&\multicolumn{1}{|l}{\mdline{2275} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2275} \mdline{2275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2275}}&\multicolumn{1}{|l|}{\mdline{2275} yes}\\ +\multicolumn{1}{|l}{\mdline{2276} \mdline{2276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2276}}&\multicolumn{1}{|l}{\mdline{2276} \mdline{2276}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2276} \mdline{2276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x9d}}}\mdline{2276}}&\multicolumn{1}{|l|}{\mdline{2276} yes}\\ +\multicolumn{1}{|l}{\mdline{2277} \mdline{2277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2277}}&\multicolumn{1}{|l}{\mdline{2277} \mdline{2277}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2277} \mdline{2277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xff\textbackslash{}x9d}}}\mdline{2277}}&\multicolumn{1}{|l|}{\mdline{2277} no}\\ +\multicolumn{1}{|l}{\mdline{2278} \mdline{2278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2278}}&\multicolumn{1}{|l}{\mdline{2278} \mdline{2278}-739 (-0x2e3)}&\multicolumn{1}{|l}{\mdline{2278} \mdline{2278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xfd\textbackslash{}x1d}}}\mdline{2278}}&\multicolumn{1}{|l|}{\mdline{2278} yes}\\ +\multicolumn{1}{|l}{\mdline{2279} \mdline{2279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2279}}&\multicolumn{1}{|l}{\mdline{2279} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2279} \mdline{2279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00}}}\mdline{2279}}&\multicolumn{1}{|l|}{\mdline{2279} no}\\ +\multicolumn{1}{|l}{\mdline{2280} \mdline{2280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2280}}&\multicolumn{1}{|l}{\mdline{2280} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2280} \mdline{2280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00}}}\mdline{2280}}&\multicolumn{1}{|l|}{\mdline{2280} yes}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2282} +\mdhr{}%mdk + +%mdk-data-line={2283} +\noindent\mdline{2283}\mdcaption{\textbf{Table~\mdcaptionlabel{4}.}~\mdcaptiontext{Examples of Valid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-valid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2285} +\mdline{2285}Table\mdline{2285}~\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}}\mdline{2285} shows some examples of invalid +P4Runtime binary strings:%mdk + +%mdk-data-line={2288} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2290} P4 type}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2290} P4Runtime binary string}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2292} \mdline{2292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2292}}&\multicolumn{1}{|l|}{\mdline{2292} \mdline{2292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x63}}}\mdline{2292}}\\ +\multicolumn{1}{|l}{\mdline{2293} \mdline{2293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2293}}&\multicolumn{1}{|l|}{\mdline{2293} \mdline{2293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2293}}\\ +\multicolumn{1}{|l}{\mdline{2294} \mdline{2294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2294}}&\multicolumn{1}{|l|}{\mdline{2294} \mdline{2294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2294}}\\ +\multicolumn{1}{|l}{\mdline{2295} \mdline{2295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2295}}&\multicolumn{1}{|l|}{\mdline{2295} \mdline{2295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x10\textbackslash{}x63}}}\mdline{2295}}\\ +\multicolumn{1}{|l}{\mdline{2296} \mdline{2296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2296}}&\multicolumn{1}{|l|}{\mdline{2296} \mdline{2296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2296}}\\ +\multicolumn{1}{|l}{\mdline{2297} \mdline{2297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2297}}&\multicolumn{1}{|l|}{\mdline{2297} \mdline{2297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x40\textbackslash{}x63}}}\mdline{2297}}\\ +\multicolumn{1}{|l}{\mdline{2298} \mdline{2298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2298}}&\multicolumn{1}{|l|}{\mdline{2298} \mdline{2298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x9d}}}\mdline{2298}}\\ +\multicolumn{1}{|l}{\mdline{2299} \mdline{2299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2299}}&\multicolumn{1}{|l|}{\mdline{2299} \mdline{2299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x8d\textbackslash{}x1d}}}\mdline{2299}}\\ +\multicolumn{1}{|l}{\mdline{2300} \mdline{2300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2300}}&\multicolumn{1}{|l|}{\mdline{2300} \mdline{2300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2300}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2302} +\mdhr{}%mdk + +%mdk-data-line={2303} +\noindent\mdline{2303}\mdcaption{\textbf{Table~\mdcaptionlabel{5}.}~\mdcaptiontext{Examples of Invalid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-invalid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2305} +\mdline{2305}As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from \mdline{2310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2310} to \mdline{2310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2310}, a server +running the \mdline{2311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2311} version of the P4 program will accept requests from +clients that remain on the \mdline{2312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2312} P4Runtime version.%mdk + +%mdk-data-line={2314} +\mdline{2314}Despite the server\mdline{2314}'\mdline{2314}s binary string flexibility for P4 program update support, +the client and server must both remain aware of the +\mdline{2316}\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2316} +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values.%mdk + +%mdk-data-line={2321} +\mdline{2321}Representation of variable-length integer values (\mdline{2321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2321} P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the \mdline{2323}\emph{dynamic-length}\mdline{2323} of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an \mdline{2326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2326} error code otherwise.%mdk + +%mdk-data-line={2328} +\subsection{\mdline{2328}8.5.\hspace*{0.5em}\mdline{2328}Representation of Arbitrary P4 Types}\label{sec-representation-of-arbitrary-p4-types}%mdk%mdk + +%mdk-data-line={2330} +\subsubsection{\mdline{2330}8.5.1.\hspace*{0.5em}\mdline{2330}Problem Statement}\label{sec-problem-statement}%mdk%mdk + +%mdk-data-line={2332} +\noindent\mdline{2332}The P4\mdline{2332}\mdsub{16}\mdline{2332} language includes more complex types than just binary strings +\mdline{2333}[\mdcite{p4complextypes}{3}]\mdline{2333}. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table\mdline{2336}~\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}}\mdline{2336} shows the different +P4\mdline{2337}\mdsub{16}\mdline{2337} types and how they are allowed to be used, as per the P4\mdline{2337}\mdsub{16}\mdline{2337} +specification.%mdk + +%mdk-data-line={2340} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|l}{{\bfseries\mdline{2342}}}&\multicolumn{3}{|c|}{{\bfseries\mdline{2342} Container type}}\\ +\cmidrule{2-2}\cmidrule{3-3}\cmidrule{4-4} +\multicolumn{1}{|l}{{\bfseries\mdline{2344} Element type}}&\multicolumn{1}{|l}{{\bfseries\mdline{2344} header}}&\multicolumn{1}{|l}{{\bfseries\mdline{2344} header\mdline{2344}\_\mdline{2344}union}}&\multicolumn{1}{|l|}{{\bfseries\mdline{2344} struct or tuple}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2346} \mdline{2346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2346}}&\multicolumn{1}{|l}{\mdline{2346} allowed}&\multicolumn{1}{|l}{\mdline{2346} error}&\multicolumn{1}{|l|}{\mdline{2346} allowed}\\ +\multicolumn{1}{|l}{\mdline{2347} \mdline{2347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2347}}&\multicolumn{1}{|l}{\mdline{2347} allowed}&\multicolumn{1}{|l}{\mdline{2347} error}&\multicolumn{1}{|l|}{\mdline{2347} allowed}\\ +\multicolumn{1}{|l}{\mdline{2348} \mdline{2348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2348}}&\multicolumn{1}{|l}{\mdline{2348} allowed}&\multicolumn{1}{|l}{\mdline{2348} error}&\multicolumn{1}{|l|}{\mdline{2348} allowed}\\ +\multicolumn{1}{|l}{\mdline{2349} \mdline{2349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int}}}\mdline{2349}}&\multicolumn{1}{|l}{\mdline{2349} error}&\multicolumn{1}{|l}{\mdline{2349} error}&\multicolumn{1}{|l|}{\mdline{2349} error}\\ +\multicolumn{1}{|l}{\mdline{2350} \mdline{2350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}void}}}\mdline{2350}}&\multicolumn{1}{|l}{\mdline{2350} error}&\multicolumn{1}{|l}{\mdline{2350} error}&\multicolumn{1}{|l|}{\mdline{2350} error}\\ +\multicolumn{1}{|l}{\mdline{2351} \mdline{2351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2351}}&\multicolumn{1}{|l}{\mdline{2351} error}&\multicolumn{1}{|l}{\mdline{2351} error}&\multicolumn{1}{|l|}{\mdline{2351} allowed}\\ +\multicolumn{1}{|l}{\mdline{2352} \mdline{2352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_kind}}}\mdline{2352}}&\multicolumn{1}{|l}{\mdline{2352} error}&\multicolumn{1}{|l}{\mdline{2352} error}&\multicolumn{1}{|l|}{\mdline{2352} error}\\ +\multicolumn{1}{|l}{\mdline{2353} \mdline{2353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2353}}&\multicolumn{1}{|l}{\mdline{2353} error}&\multicolumn{1}{|l}{\mdline{2353} error}&\multicolumn{1}{|l|}{\mdline{2353} allowed}\\ +\multicolumn{1}{|l}{\mdline{2354} \mdline{2354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2354}}&\multicolumn{1}{|l}{\mdline{2354} allowed\mdline{2354}\mdfootnote{1}{%mdk-data-line={2364} +%mdk-data-line={2364} +\noindent\mdline{2364}an \mdline{2364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2364} type used as a field in a \mdline{2364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2364} must specify a +underlying type and representation for \mdline{2365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2365} elements.%mdk +\label{fn-enum_header}%mdk%mdk +}\mdline{2354}}&\multicolumn{1}{|l}{\mdline{2354} error}&\multicolumn{1}{|l|}{\mdline{2354} allowed}\\ +\multicolumn{1}{|l}{\mdline{2355} \mdline{2355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2355}}&\multicolumn{1}{|l}{\mdline{2355} error}&\multicolumn{1}{|l}{\mdline{2355} allowed}&\multicolumn{1}{|l|}{\mdline{2355} allowed}\\ +\multicolumn{1}{|l}{\mdline{2356} header stack}&\multicolumn{1}{|l}{\mdline{2356} error}&\multicolumn{1}{|l}{\mdline{2356} error}&\multicolumn{1}{|l|}{\mdline{2356} allowed}\\ +\multicolumn{1}{|l}{\mdline{2357} \mdline{2357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2357}}&\multicolumn{1}{|l}{\mdline{2357} error}&\multicolumn{1}{|l}{\mdline{2357} error}&\multicolumn{1}{|l|}{\mdline{2357} allowed}\\ +\multicolumn{1}{|l}{\mdline{2358} \mdline{2358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2358}}&\multicolumn{1}{|l}{\mdline{2358} error}&\multicolumn{1}{|l}{\mdline{2358} error}&\multicolumn{1}{|l|}{\mdline{2358} allowed}\\ +\multicolumn{1}{|l}{\mdline{2359} \mdline{2359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2359}}&\multicolumn{1}{|l}{\mdline{2359} error}&\multicolumn{1}{|l}{\mdline{2359} error}&\multicolumn{1}{|l|}{\mdline{2359} allowed}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2361} +\mdhr{}%mdk + +%mdk-data-line={2362} +\noindent\mdline{2362}\mdcaption{\textbf{Table~\mdcaptionlabel{6}.}~\mdcaptiontext{P4 Type Usage}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-type-usage}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2367} +\mdline{2367}For example, the following P4\mdline{2367}\mdsub{16}\mdline{2367} objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects.%mdk + +%mdk-data-line={2370} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2371} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}{\bfseries{\mdcolor{navy}tuple}}\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}4}\textgreater{},~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~\textgreater{}~\textgreater{}()~digest\_complex;\\ +digest\_complex.pack(\{~hdr.ipv4.version,~hdr.ipv4.protocol~\});\\ +{\mdcolor{darkgreen}//~...}\\ +{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2381} +\noindent\mdline{2381}One solution would be to use only binary string (\mdline{2381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2381} type) in +p4runtime.proto and to define a custom serialization format for complex P4\mdline{2382}\mdsub{16}\mdline{2382} +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P4\mdline{2389}\mdsub{16}\mdline{2389} types.%mdk + +%mdk-data-line={2391} +\subsubsection{\mdline{2391}8.5.2.\hspace*{0.5em}\mdline{2391}P4 Type Specifications in p4info.proto}\label{sec-p4-type-specifications-in-p4infoproto}%mdk%mdk + +%mdk-data-line={2393} +\noindent\mdline{2393}In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type \mdline{2397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip\_t}}}\mdline{2397}, which is a header union with 2 possible headers: +\mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4}}}\mdline{2398} with type \mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4\_t}}}\mdline{2398} and \mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6}}}\mdline{2398} with type \mdline{2398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6\_t}}}\mdline{2398}. Similarly, they need to +know the field layout for both of these header types.%mdk + +%mdk-data-line={2401} +\mdline{2401}To achieve this we introduce 2 main Protobuf messages: \mdline{2401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2401} and +\mdline{2402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2402}.%mdk + +%mdk-data-line={2404} +\mdline{2404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2404} is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P4\mdline{2405}\mdsub{16}\mdline{2405} program. These +named types are \mdline{2406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2406}, \mdline{2406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2406}, \mdline{2406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2406}, \mdline{2406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2406} and +\mdline{2407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2407}; for each of these we have a type specification message, +respectively \mdline{2408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructTypeSpec}}}\mdline{2408}, \mdline{2408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderTypeSpec}}}\mdline{2408}, \mdline{2408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionTypeSpec}}}\mdline{2408}, +\mdline{2409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4EnumTypeSpec}}}\mdline{2409} and \mdline{2409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4SerializableEnumTypeSpec}}}\mdline{2409}. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. \mdline{2411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2411} also includes the list of parser errors for the program, as +a \mdline{2412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4ErrorTypeSpec}}}\mdline{2412} message.%mdk + +%mdk-data-line={2414} +\mdline{2414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2414} is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each \mdline{2416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2416} message corresponds to a compile-time type in the +original P4\mdline{2417}\mdsub{16}\mdline{2417} program (\mdline{2417}e.g.\mdline{2417} the type parameter of an extern). This +compile-time type is represented as a Protobuf \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2418}, which can be:%mdk + +%mdk-data-line={2420} +\begin{itemize}%mdk + +%mdk-data-line={2420} +\item{} +%mdk-data-line={2420} +\mdline{2420}a string representing the name of the type in case of a named type (\mdline{2420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2420}, +\mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2421}, \mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2421}, \mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2421}, \mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2421} or user-defined \mdline{2421}\textquotedblleft{}new\textquotedblright{}\mdline{2421} +\mdline{2422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2422}),%mdk%mdk + +%mdk-data-line={2424} +\item{} +%mdk-data-line={2424} +\mdline{2424}an empty Protobuf message for \mdline{2424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2424} and \mdline{2424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2424}, or%mdk%mdk + +%mdk-data-line={2426} +\item{} +%mdk-data-line={2426} +\mdline{2426}a Protobuf message for other anonymous types (\mdline{2426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2426}, \mdline{2426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2426}, \mdline{2426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2426}, +\mdline{2427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2427} or stack). The \mdline{2427}\textquotedblleft{}binary string\textquotedblright{}\mdline{2427} types (\mdline{2427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2427}, \mdline{2427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2427}, and +\mdline{2428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2428}) are grouped together in the \mdline{2428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4BitstringLikeTypeSpec}}}\mdline{2428} message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf \mdline{2430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2430} +type).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2433} +\noindent\mdline{2433}For all P4\mdline{2433}\mdsub{16}\mdline{2433} compound types (\mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2433}, and \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2433}), +the order of \mdline{2434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2434} in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P4\mdline{2436}\mdsub{16}\mdline{2436} declaration. The same goes for the order of members of an \mdline{2436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2436} +(serializable or not) or members of \mdline{2437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2437}.%mdk + +%mdk-data-line={2439} +\subsubsection{\mdline{2439}8.5.3.\hspace*{0.5em}\mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2439} in p4runtime.proto}\label{sec-p4data-in-p4runtime-proto}%mdk%mdk + +%mdk-data-line={2441} +\noindent\mdline{2441}P4Runtime uses the \mdline{2441}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2441} message to represent values of arbitrary types. The +P4Runtime client must generate correct \mdline{2442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2442} messages based on the type +specification information included in P4Info. The \mdline{2443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2443} message was designed +to introduce little overhead compared to using binary strings in the most common +case (P4\mdline{2445}\mdsub{16}\mdline{2445} \mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2445} type).%mdk + +%mdk-data-line={2447} +\mdline{2447}Just like its P4Info counterpart\mdline{2447} \mdline{2447}- \mdline{2447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2447} \mdline{2447}-, \mdline{2447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2447} uses a Protobuf +\mdline{2448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2448} to represent all possible values.%mdk + +%mdk-data-line={2450} +\mdline{2450}We define a canonical representation for \mdline{2450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2450} messages\mdline{2450} \mdline{2450}\textemdash{}\mdline{2450} therefore +guaranteeing read-write symmetry\mdline{2451} \mdline{2451}\textemdash{}\mdline{2451} by introducing the following requirements:%mdk + +%mdk-data-line={2453} +\begin{itemize}%mdk + +%mdk-data-line={2453} +\item{} +%mdk-data-line={2453} +\mdline{2453}The order of \mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2453} in \mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructLike}}}\mdline{2453} and the order of \mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2453} in +\mdline{2454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2454} must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P4\mdline{2455}\mdsub{16}\mdline{2455} type +declaration.%mdk%mdk + +%mdk-data-line={2458} +\item{} +%mdk-data-line={2458} +\mdline{2458}An invalid header is represented by a \mdline{2458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2458} message where the \mdline{2458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_valid}}}\mdline{2458} +field is false and the \mdline{2459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2459} repeated field is empty.%mdk%mdk + +%mdk-data-line={2461} +\item{} +%mdk-data-line={2461} +\mdline{2461}An invalid header union (\mdline{2461}i.e.\mdline{2461} all headers in the union are invalid) is +represented by a \mdline{2462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnion}}}\mdline{2462} message where the \mdline{2462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header\_name}}}\mdline{2462} is the +empty string (default value for the field) and the \mdline{2463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header}}}\mdline{2463} is unset.%mdk%mdk + +%mdk-data-line={2465} +\item{} +%mdk-data-line={2465} +\mdline{2465}The order of \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2465} in \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStack}}}\mdline{2465} and \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStack}}}\mdline{2465} is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the \mdline{2467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2467} field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding \mdline{2469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStackTypeSpec}}}\mdline{2469} or +\mdline{2470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStackTypeSpec}}}\mdline{2470} message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2472} +\subsubsection{\mdline{2472}8.5.4.\hspace*{0.5em}\mdline{2472}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={2474} +\noindent\mdline{2474}Let\mdline{2474}'\mdline{2474}s look at the Register example again:%mdk + +%mdk-data-line={2476} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2477} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2484} +\noindent\mdline{2484}Here\mdline{2484}'\mdline{2484}s the corresponding entry in the P4Info message:%mdk + +%mdk-data-line={2486} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2487} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}registers~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}369119267}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~\}\\ +~~type\_spec~\{\\ +~~~~header\_union~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~size:~{\mdcolor{purple}128}\\ +\}\\ +type\_info~\{\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~header\_unions~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2543} +\noindent\mdline{2543}Here\mdline{2543}'\mdline{2543}s a \mdline{2543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.WriteRequest}}}\mdline{2543} to set the value of \mdline{2543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_ip{}[12]}}}\mdline{2543}:%mdk + +%mdk-data-line={2545} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2546} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}update~\{\\ +~~type:~INSERT\\ +~~entity~\{\\ +~~~~register\_entry~\{\\ +~~~~~~register\_id:~{\mdcolor{purple}369119267}\\ +~~~~~~index~\{\\ +~~~~~~~~index:~{\mdcolor{purple}12}\\ +~~~~~~\}\\ +~~~~~~data~\{\\ +~~~~~~~~header\_union~\{\\ +~~~~~~~~~~valid\_header\_name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~~~valid\_header~\{\\ +~~~~~~~~~~~~is\_valid:~true\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x04}{\mdcolor{maroon}"}\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{darkgreen}\#~...}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2569} +\subsubsection{\mdline{2569}8.5.5.\hspace*{0.5em}\mdline{2569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2569}, serializable \mdline{2569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2569} and \mdline{2569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}\label{sec-enum-serializable-enum-and-error}%mdk%mdk + +%mdk-data-line={2571} +\noindent\mdline{2571}P4\mdline{2571}\mdsub{16}\mdline{2571} supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or \mdline{2572}\textquotedblleft{}unsafe\textquotedblright{}\mdline{2572} enum) +\mdline{2573}[\mdcite{p4enums}{5}]\mdline{2573}. For \mdline{2573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2573} types with no underlying type\mdline{2573} \mdline{2573}\textemdash{}\mdline{2573} as well as \mdline{2573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2573} \mdline{2573}\textemdash{}\mdline{2573} +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in \mdline{2576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2576} to represent \mdline{2576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2576} and +\mdline{2577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2577} values.%mdk + +%mdk-data-line={2579} +\mdline{2579}Serializable \mdline{2579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2579} types have an underlying fixed-width unsigned integer +representation (\mdline{2580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2580}). All named enum members must be assigned an integer +value by the P4 programmer, but \mdline{2581}\emph{not all}\mdline{2581} valid numeric values for the +underlying type need to have a corresponding name. \mdline{2582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2582} includes the +mapping between entry name and entry value. When providing serializable enum +values through \mdline{2584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2584}, one must use the assigned integer value (\mdline{2584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum\_value}}}\mdline{2584} +bytestring field). P4Runtime does not provide a way for the client to use the +name\mdline{2586} \mdline{2586}\textemdash{}\mdline{2586} even when the enum member has one\mdline{2586} \mdline{2586}\textemdash{}\mdline{2586} instead of the value, as it makes +it easier for the server to respect the\mdline{2587}~\mdref{sec-read-write-symmetry}{read-write +symmetry}\mdline{2588} principle.%mdk + +%mdk-data-line={2590} +\subsubsection{\mdline{2590}8.5.6.\hspace*{0.5em}\mdline{2590}User-defined types}\label{sec-user-defined-types}%mdk%mdk + +%mdk-data-line={2592} +\noindent\mdline{2592}P4\mdline{2592}\mdsub{16}\mdline{2592} enables programmers to introduce new types\mdline{2592}~[\mdcite{p4newtypes}{11}]\mdline{2592}. While similar +to \mdline{2593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{2593}, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +\mdline{2596}\mdref{sec-psa-metadata-translation}{translation}\mdline{2596}. When introducing a new type, the +declaration can be annotated with \mdline{2597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2597} to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for\mdline{2599}~\mdref{sec-translation-of-port-numbers}{port numbers}\mdline{2599}, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. \mdline{2602}\textbf{The \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}} annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}})}\mdline{2604}. The type exposed to the control plane (referred to as the +\mdline{2605}\emph{controller\_type}\mdline{2605}) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a \mdline{2607}\emph{URI}\mdline{2607} (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the \mdline{2609}\emph{controller\_type}\mdline{2609} of the values exposed to the control plane. The +\mdline{2610}\emph{controller\_type}\mdline{2610} can be either \mdline{2610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2610} where \mdline{2610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2610} is any positive integer, or +\mdline{2611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{2611}, or a positive integer \mdline{2611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2611} which has the same meaning as \mdline{2611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2611}. +Specifying just an integer is deprecated.%mdk + +%mdk-data-line={2614} +\mdline{2614}It is recommended that the URI includes at least the P4 architecture name and +the type name.%mdk + +%mdk-data-line={2617} +\mdline{2617}A \mdline{2617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2617} annotation need not have any effect if it is used to +annotate anything in a P4 program other than a \mdline{2618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2618} declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect.%mdk + +%mdk-data-line={2622} +\mdline{2622}User-defined types are specified using the \mdline{2622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{2622} message, which has +the following fields:%mdk + +%mdk-data-line={2625} +\begin{itemize}%mdk + +%mdk-data-line={2625} +\item{} +%mdk-data-line={2625} +\mdline{2625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}representation}}}\mdline{2625}, a Protobuf \mdline{2625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2625} specifying how values of this type are +exchanged between client and server; it can be either:%mdk + +%mdk-data-line={2628} +\begin{itemize}%mdk + +%mdk-data-line={2628} +\item{} +%mdk-data-line={2628} +\mdline{2628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2628}, if and only if no \mdline{2628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2628} annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 \mdline{2630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2630} declaration is itself a +user-defined type, \mdline{2631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2631} is obtained by \mdline{2631}\textquotedblleft{}walking\textquotedblright{}\mdline{2631} the chain of +\mdline{2632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2632} declarations recursively until a built-in type (\mdline{2632}e.g.\mdline{2632} \mdline{2632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2632}) is +found.%mdk%mdk + +%mdk-data-line={2635} +\item{} +%mdk-data-line={2635} +\mdline{2635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}translated\_type}}}\mdline{2635}, if and only if the P4 \mdline{2635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2635} declaration was annotated +with \mdline{2636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2636}. It is of type \mdline{2636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeTranslation}}}\mdline{2636}, +which itself has two fields\mdline{2637} \mdline{2637}\textemdash{}\mdline{2637} \mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uri}}}\mdline{2637} and either \mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_string}}}\mdline{2637} or +\mdline{2638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_bitwidth}}}\mdline{2638} \mdline{2638}\textemdash{}\mdline{2638}, which map to the two input parameters to the +annotation.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2641} +\item{} +%mdk-data-line={2641} +\mdline{2641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{2641}, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2644} +\noindent\mdline{2644}For example, an architecture\mdline{2644} \mdline{2644}\textemdash{}\mdline{2644} in this case PSA\mdline{2644} \mdline{2644}\textemdash{}\mdline{2644} may introduce a new type +for port numbers:%mdk + +%mdk-data-line={2646} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2647} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~string,~e.g.~"eth0".}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~32-bit~integer,~e.g.~0xffffffff.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{darkgreen}//~Same~as~above.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_32\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_32\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2660} +\noindent\mdline{2660}In this case, the P4Info message would include the following \mdline{2660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2660} +messages:%mdk + +%mdk-data-line={2663} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2664} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_string:~\{\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2701} +\noindent\mdline{2701}Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (\mdline{2702}e.g.\mdline{2702} through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over \mdline{2704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2704} to enable users +to overwrite annotations included as part of the P4 architecture definition.%mdk + +%mdk-data-line={2707} +\subsubsection{\mdline{2707}8.5.7.\hspace*{0.5em}\mdline{2707}Trade-off for v1.x Releases}\label{sec-trade-off-for-v1x-releases}%mdk%mdk + +%mdk-data-line={2709} +\noindent\mdline{2709}For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +\mdline{2710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2710} with \mdline{2710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2710} in the \mdline{2710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{2710} message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +\mdline{2713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2713} to provide action parameter values and controller metadata +values. However \mdline{2714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2714} is used whenever appropriate for PSA externs and we +encourage the use of \mdline{2715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2715} in architecture-specific extensions.%mdk + +%mdk-data-line={2717} +\mdline{2717}In order to support\mdline{2717}~\mdref{sec-psa-metadata-translation}{translation}\mdline{2717} for action +parameters and match fields, we include a \mdline{2718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2718} field in +\mdline{2719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{2719}, \mdline{2719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Action.Param}}}\mdline{2719} and +\mdline{2720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ControllerPacketMetadata.Metadata}}}\mdline{2720}. In addition, the \mdline{2720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2720} +field for all of these message types must abide by the following rule when +\mdline{2722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2722} names a translated user-defined type:%mdk + +%mdk-data-line={2724} +\begin{itemize}%mdk + +%mdk-data-line={2724} +\item{} +%mdk-data-line={2724} +\mdline{2724}If the \mdline{2724}\emph{controller\_type}\mdline{2724} is a fixed-width unsigned bitstring, the \mdline{2724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2724} +field must be set to the bitwidth of the \mdline{2725}\emph{controller\_type}\mdline{2725}. This information +is redundant with the one included in the \mdline{2726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2726} entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent.%mdk%mdk + +%mdk-data-line={2732} +\item{} +%mdk-data-line={2732} +\mdline{2732}Otherwise (\mdline{2732}i.e.\mdline{2732}, if the \mdline{2732}\emph{controller\_type}\mdline{2732} is a string), the \mdline{2732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2732} must +be \mdline{2733}\textquotedblleft{}unset\textquotedblright{}\mdline{2733}, which, in Protobuf version 3, is the same as setting the field to +0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2736} +\noindent\mdline{2736}For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types:%mdk + +%mdk-data-line={2738} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2739} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{navy}@}{\mdcolor{navy}name}{\mdcolor{maroon}(".t")}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~meta.port1:~exact;~~{\mdcolor{darkgreen}//~meta.port1~has~type~PortId\_String\_t}\\ +~~~~meta.port2:~exact;~~{\mdcolor{darkgreen}//~meta.port2~has~type~PortId\_Bit32\_t}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2757} +\noindent\mdline{2757}This table would have the following representation in the generated P4Info +message:%mdk + +%mdk-data-line={2759} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2760} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tables~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}34728461}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port1}{\mdcolor{maroon}"}\\ +~~~~{\mdcolor{darkgreen}\#~notice~that~bitwidth~is~unset}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port2}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~{\mdcolor{darkgreen}\#~...}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2788} +\section{\mdline{2788}9.\hspace*{0.5em}\mdline{2788}P4 Entity Messages}\label{sec-p4-entity-msgs}%mdk%mdk + +%mdk-data-line={2790} +\noindent\mdline{2790}P4Runtime covers P4 entities that are either part of the P4\mdline{2790}\mdsub{16}\mdline{2790} language, or +defined as PSA externs. The sections below describe the messages for each +supported entity.%mdk + +%mdk-data-line={2794} +\subsection{\mdline{2794}9.1.\hspace*{0.5em}\mdline{2794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}\label{sec-table-entry}%mdk%mdk + +%mdk-data-line={2796} +\noindent\mdline{2796}The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action\mdline{2798}'\mdline{2798}s +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification.%mdk + +%mdk-data-line={2804} +\mdline{2804}P4Runtime supports inserting, modifying, deleting and reading table entries with +the \mdline{2805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2805} entity, which has the following fields:%mdk + +%mdk-data-line={2807} +\begin{itemize}%mdk + +%mdk-data-line={2807} +\item{} +%mdk-data-line={2807} +\mdline{2807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2807}, which identifies the table instance; the \mdline{2807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2807} is determined +by the P4Info message.%mdk%mdk + +%mdk-data-line={2810} +\item{} +%mdk-data-line={2810} +\mdline{2810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2810}, a repeated field of \mdline{2810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2810} messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration.%mdk%mdk + +%mdk-data-line={2814} +\item{} +%mdk-data-line={2814} +\mdline{2814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2814}, which indicates which of the table\mdline{2814}'\mdline{2814}s actions to execute in case of +match and with which argument values.%mdk%mdk + +%mdk-data-line={2817} +\item{} +%mdk-data-line={2817} +\mdline{2817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2817}, a 32-bit integer used to order entries when the table\mdline{2817}'\mdline{2817}s match key +includes an optional, ternary or range match.%mdk%mdk + +%mdk-data-line={2820} +\item{} +%mdk-data-line={2820} +\mdline{2820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2820}, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +\mdline{2824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{2824} field.%mdk%mdk + +%mdk-data-line={2826} +\item{} +%mdk-data-line={2826} +\mdline{2826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{2826}, an arbitrary \mdline{2826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2826} value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry.%mdk%mdk + +%mdk-data-line={2831} +\item{} +%mdk-data-line={2831} +\mdline{2831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2831}, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See\mdline{2832}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2833} section for more information.%mdk%mdk + +%mdk-data-line={2835} +\item{} +%mdk-data-line={2835} +\mdline{2835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2835}, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See\mdline{2836}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2837} section for more information.%mdk%mdk + +%mdk-data-line={2839} +\item{} +%mdk-data-line={2839} +\mdline{2839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2839}, a boolean flag which indicates whether the table entry is +the default entry for the table. See\mdline{2840}~\mdref{sec-default-entry}{Default entry}\mdline{2840} +section for more information.%mdk%mdk + +%mdk-data-line={2843} +\item{} +%mdk-data-line={2843} +\mdline{2843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2843} and \mdline{2843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2843}, which are two fields used to +implement idle-timeout support for the table, if applicable. See +\mdline{2845}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{2845} section for more information.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2847} +\noindent\mdline{2847}The \mdline{2847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2847} field must be set to a non-zero value if the match key includes a +ternary match (\mdline{2848}i.e.\mdline{2848} in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an \mdline{2849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{2849}, \mdline{2849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2849} or +\mdline{2850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2850} match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches.%mdk + +%mdk-data-line={2859} +\mdline{2859}The \mdline{2859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2859} and \mdline{2859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2859} fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for \mdline{2861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2861} and \mdline{2861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{2861} updates. When deleting +an entry, these key fields (along with \mdline{2862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2862}) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a \mdline{2864}\emph{keyless}\mdline{2864} +table (the table has an empty match key), the server must reject all attempts to +\mdline{2866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2866} a match entry and return an \mdline{2866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2866} error.%mdk + +%mdk-data-line={2868} +\mdline{2868}The number of match entries that a table \mdline{2868}\emph{should}\mdline{2868} support is indicated in P4Info +(\mdline{2869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2869} field of \mdline{2869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{2869} message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P4\mdline{2870}\mdsub{16}\mdline{2870} specification for the +\mdline{2871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2871} property\mdline{2871}~[\mdcite{p4tableproperties}{30}]\mdline{2871}. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +\mdline{2875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{2875} when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached.%mdk + +%mdk-data-line={2880} +\subsubsection{\mdline{2880}9.1.1.\hspace*{0.5em}\mdline{2880}Match Format}\label{sec-match-format}%mdk%mdk + +%mdk-data-line={2882} +\noindent\mdline{2882}The bytes fields in the \mdline{2882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2882} message follow the format described in +\mdline{2883}\mdref{sec-bytestrings}{Bytestrings}\mdline{2883}.%mdk + +%mdk-data-line={2885} +\mdline{2885}For \mdline{2885}\textquotedblleft{}don't care\textquotedblright{}\mdline{2885} matches, the P4Runtime client must omit the field\mdline{2885}'\mdline{2885}s entire +\mdline{2886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2886} entry when building the \mdline{2886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2886} repeated field of the \mdline{2886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2886} +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for \mdline{2888}\textquotedblleft{}don't care\textquotedblright{}\mdline{2888} matches, which is needed +to ensure\mdline{2889}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2889}. For PSA match types, +a \mdline{2890}\textquotedblleft{}don't care\textquotedblright{}\mdline{2890} match for a specific match key field is defined as follows:%mdk + +%mdk-data-line={2892} +\begin{itemize}%mdk + +%mdk-data-line={2892} +\item{} +%mdk-data-line={2892} +\mdline{2892}For a \mdline{2892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2892} match, it is logically equivalent to a mask of zeros.%mdk%mdk + +%mdk-data-line={2894} +\item{} +%mdk-data-line={2894} +\mdline{2894}For a \mdline{2894}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{2894} match, it is logically equivalent to a wildcard match.%mdk%mdk + +%mdk-data-line={2896} +\item{} +%mdk-data-line={2896} +\mdline{2896}For an \mdline{2896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2896} match, it is logically equivalent to a prefix\mdline{2896}\_\mdline{2896}len of zero.%mdk%mdk + +%mdk-data-line={2898} +\item{} +%mdk-data-line={2898} +\mdline{2898}For a \mdline{2898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2898} match, it is logically equivalent to a range which includes all +possible values for the field.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2901} +\noindent\mdline{2901}Note that there is no \mdline{2901}\textquotedblleft{}don't care\textquotedblright{}\mdline{2901} value for \mdline{2901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2901} matches and therefore exact +match fields can never be omitted from the \mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2902} message.%mdk + +%mdk-data-line={2904} +\mdline{2904}The following example shows a P4Runtime message that treats a \mdline{2904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2904} field +as a \mdline{2905}\textquotedblleft{}don't care\textquotedblright{}\mdline{2905} match. The P4 program defines table \mdline{2905}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{2905} with \mdline{2905}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2905} +and \mdline{2906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2906} fields in its match key:%mdk + +%mdk-data-line={2908} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2909} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~ternary;\\ +~~~~istd.ingress\_port:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2920} +\noindent\mdline{2920}In this P4Runtime request, the client omits the table\mdline{2920}'\mdline{2920}s \mdline{2920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2920} field +from the repeated \mdline{2921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2921} field to indicate a \mdline{2921}\textquotedblleft{}don't care\textquotedblright{}\mdline{2921} match. As shown +below, the \mdline{2922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2922} specifies only the \mdline{2922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2922} field given by \mdline{2922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id:~2}}}\mdline{2922}.%mdk + +%mdk-data-line={2924} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2925} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}33554439}~~{\mdcolor{darkgreen}\#~Table~t's~ID.}\\ +~~~~match~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~field\_id~1~is~not~present~to~use~the~don't~care~ternary~value.}\\ +~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~exact~\{\\ +~~~~~~~~value:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x20}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~action~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~Action~selection~goes~here.}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2943} +\noindent\mdline{2943}For every member of the \mdline{2943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2943} repeated \mdline{2943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2943} field, \mdline{2943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id}}}\mdline{2943} must be +a valid id for the table, as per the P4Info, and one of the fields in +\mdline{2945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{2945} must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an \mdline{2947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2947} error code.%mdk + +%mdk-data-line={2949} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2949} +\item\mdline{2949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2949} match + +%mdk-data-line={2950} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2950} +\item\mdline{2950}The binary string encoding of the value must conform to the +\mdline{2951}\mdref{sec-bytestrings}{Bytestrings}\mdline{2951} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2953} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2954} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.exact().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2957} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2957} +\item\mdline{2957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2957} match + +%mdk-data-line={2958} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2958} +\item\mdline{2958}The binary string encoding of the value (when present) must conform to the +\mdline{2959}\mdref{sec-bytestrings}{Bytestrings}\mdline{2959} requirements.%mdk + +%mdk-data-line={2960} +\item\mdline{2960}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2960} match must be omitted.%mdk + +%mdk-data-line={2961} +\item\mdline{2961}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2961} bits must be 0 in value.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2963} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2964} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.lpm().value()))\\ +\\ +pLen~=~match.lpm().prefix\_len()\\ +assert(pLen~\textgreater{}~0)\\ +\\ +trailing\_zeros~=~countTrailingZeros(match.lpm().value())\\ +assert(trailing\_zeros~\textgreater{}=~field\_bits~-~pLen)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2973} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2973} +\item\mdline{2973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2973} match + +%mdk-data-line={2974} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2974} +\item\mdline{2974}The binary string encoding of the value (when present) and mask (when +present) must conform to the\mdline{2975}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2975} requirements.%mdk + +%mdk-data-line={2976} +\item\mdline{2976}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2976} match must be omitted.%mdk + +%mdk-data-line={2977} +\item\mdline{2977}Masked bits must be 0 in value. This constraint taken together +with the\mdline{2978}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2978} requirements means that the +value\mdline{2979}'\mdline{2979}s binary string is never longer than the mask\mdline{2979}'\mdline{2979}s binary string. +When the value\mdline{2980}'\mdline{2980}s string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2984} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2985} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.ternary().value()))\\ +assert(BytestringValid(match.ternary().mask()))\\ +assert(match.ternary().value().size()~\textless{}=~match.ternary().mask().size());\\ +\\ +value~=~parseInteger(match.ternary().value())\\ +mask~=~parseInteger(match.ternary().mask())\\ +\\ +assert(mask~!=~0)\\ +\\ +assert(value~\&~mask~==~value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2997} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2997} +\item\mdline{2997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2997} match + +%mdk-data-line={2998} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2998} +\item\mdline{2998}The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the\mdline{2999}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2999} +requirements.%mdk + +%mdk-data-line={3001} +\item\mdline{3001}Low bound must be less than or equal to the high bound.%mdk + +%mdk-data-line={3002} +\item\mdline{3002}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3002} match must be omitted.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3004} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3005} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.range().low()))\\ +assert(BytestringValid(match.range().high()))\\ +\\ +low~=~parseInteger(match.range().low())\\ +high~=~parseInteger(match.range().high())\\ +\\ +assert(low~\textless{}=~high)\\ +\\ +assert(low~!=~min\_field\_value~\textbar{}\textbar{}~high~!=~max\_field\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3016} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3016} +\item\mdline{3016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3016} match + +%mdk-data-line={3017} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3017} +\item\mdline{3017}The binary string encoding of the value must conform to the +\mdline{3018}\mdref{sec-bytestrings}{Bytestrings}\mdline{3018} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3020} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3021} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.optional().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3024} +\subsubsection{\mdline{3024}9.1.2.\hspace*{0.5em}\mdline{3024}Action Specification}\label{sec-action-specification}%mdk%mdk + +%mdk-data-line={3026} +\noindent\mdline{3026}The \mdline{3026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3026} \mdline{3026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3026} field must be set for every \mdline{3026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3026} update but may be +left unset for \mdline{3027}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3027} updates, in which case the action specification for the +table entry will not be modified (if a \mdline{3028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3028} update has an unset action field +and does not modify any direct resource attached to the table then the \mdline{3029}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3029} +update is a no-op). Based on the implementation property value of the P4 table, +the \mdline{3031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3031} in the \mdline{3031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3031} message will either be:%mdk + +%mdk-data-line={3033} +\begin{itemize}%mdk + +%mdk-data-line={3033} +\item{} +%mdk-data-line={3033} +\mdline{3033}an \mdline{3033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3033} specification for direct tables (with no P4 \mdline{3033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3033} +property)%mdk%mdk + +%mdk-data-line={3036} +\item{} +%mdk-data-line={3036} +\mdline{3036}an action profile member id for indirect tables for which the \mdline{3036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3036} +property is an action profile with no selector.%mdk%mdk + +%mdk-data-line={3039} +\item{} +%mdk-data-line={3039} +\mdline{3039}an action profile member id or group id for indirect tables for which the +\mdline{3040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3040} property is an action profile with selector.%mdk%mdk + +%mdk-data-line={3042} +\item{} +%mdk-data-line={3042} +\mdline{3042}an \mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3042} specification for indirect tables for +which the \mdline{3043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3043} property is an action profile with +selector. This usage is described in\mdline{3044}~\mdref{sec-oneshot}{One Shot Action Selector +Programming}\mdline{3045}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3047} +\noindent\mdline{3047}If the \mdline{3047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3047} does not match the table description in the P4Info (\mdline{3047}e.g.\mdline{3047} the +\mdline{3048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3048} is \mdline{3048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member\_id}}}\mdline{3048} for a direct table), the server must +return an \mdline{3049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3049} error code.%mdk + +%mdk-data-line={3051} +\mdline{3051}The \mdline{3051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3051} Protobuf message has the following fields:%mdk + +%mdk-data-line={3053} +\begin{itemize}%mdk + +%mdk-data-line={3053} +\item{} +%mdk-data-line={3053} +\mdline{3053}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3053}, which identifies the action instance; the \mdline{3053}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3053} is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an \mdline{3055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3055} error +code. If the client uses a valid \mdline{3056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3056} for the table but does not +respect the action scope specified in P4Info (\mdline{3057}e.g.\mdline{3057} tries to set a \mdline{3057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{3057} +action as the default action), the server must return a \mdline{3058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3058} +error code.%mdk%mdk + +%mdk-data-line={3061} +\item{} +%mdk-data-line={3061} +\mdline{3061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{3061}: a repeated Protobuf field of action parameter values, each encoded +as a \mdline{3062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{3062} message. For each parameter, \mdline{3062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}param\_id}}}\mdline{3062} must be valid for the +action (as per the P4Info) and value must follow the format described in +\mdline{3064}\mdref{sec-bytestrings}{Bytestrings}\mdline{3064}. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an \mdline{3066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3066} error code +if a parameter id is missing, if an extra parameter\mdline{3067} \mdline{3067}\textemdash{}\mdline{3067} id not found in the +P4Info\mdline{3068} \mdline{3068}\textemdash{}\mdline{3068} was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +\mdline{3070}\mdref{sec-bytestrings}{Bytestrings}\mdline{3070} format.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3072} +\noindent\mdline{3072}For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a \mdline{3074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3074} error code.%mdk + +%mdk-data-line={3076} +\subsubsection{\mdline{3076}9.1.3.\hspace*{0.5em}\mdline{3076}Default Entry}\label{sec-default-entry}%mdk%mdk + +%mdk-data-line={3078} +\noindent\mdline{3078}According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer\mdline{3079} \mdline{3079}\textemdash{}\mdline{3079} or defaults to \mdline{3079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3079} +(which is a no-op) otherwise\mdline{3080} \mdline{3080}\textemdash{}\mdline{3080} and assuming it is not declared as \mdline{3080}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3080}, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3082} and \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3082} updates on the default entry and the +P4Runtime server must return an \mdline{3083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3083} error code if the client +attempts one.%mdk + +%mdk-data-line={3086} +\mdline{3086}The default entry is identified by setting the \mdline{3086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3086} boolean field +to true. When this flag is set to true, the repeated \mdline{3087}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3087} field must be empty +and the \mdline{3088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3088} field must be set to zero, otherwise the P4Runtime server +must return an \mdline{3089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3089} error code. When performing a \mdline{3089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3089} update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its \mdline{3093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3093} and \mdline{3093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3093} value as well as the +configurations for its\mdline{3094}~\mdref{sec-direct-resources}{direct resources}\mdline{3094} will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a \mdline{3096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3096} +error code if the client attempts to modify it.%mdk + +%mdk-data-line={3099} +\mdline{3099}Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to\mdline{3100}~\mdref{sec-direct-resources}{direct resources}\mdline{3100}.%mdk + +%mdk-data-line={3102} +\mdline{3102}In this P4Runtime release, we have decided to restrict the default entry for +indirect tables\mdline{3103} \mdline{3103}\textemdash{}\mdline{3103} tables with an ActionProfile or ActionSelector +\mdline{3104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3104} property\mdline{3104} \mdline{3104}\textemdash{}\mdline{3104} to a constant \mdline{3104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3104} action entry, with the +hope that it would simplify the implementation of the P4Runtime service.%mdk + +%mdk-data-line={3107} +\subsubsection{\mdline{3107}9.1.4.\hspace*{0.5em}\mdline{3107}Constant Tables}\label{sec-constant-tables}%mdk%mdk + +%mdk-data-line={3109} +\noindent\mdline{3109}Constant tables are defined as tables whose match entries are immutable. They +are identified by the \mdline{3110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3110} flag in P4Info.%mdk + +%mdk-data-line={3112} +\mdline{3112}The only write updates which are allowed for constant tables are \mdline{3112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3112} +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +\mdline{3116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3116} error. Just like any table entry \mdline{3116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3116} request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a \mdline{3120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3120} error.%mdk + +%mdk-data-line={3122} +\mdline{3122}The contents of const tables can be queried by the client through a +\mdline{3123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3123}. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: \mdline{3124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3124}, \mdline{3124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3124}, \mdline{3124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3124}, +\mdline{3125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3125}, and \mdline{3125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3125} (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the \mdline{3128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3128} field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P4\mdline{3130}\mdsub{16}\mdline{3130} does not support assigning explicit priorities to static +entries. When a priority value is required (\mdline{3131}e.g.\mdline{3131} for tables including \mdline{3131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3131}, +\mdline{3132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3132} or \mdline{3132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3132} matches), it is inferred based on the order in which +entries appear in the table declaration.%mdk + +%mdk-data-line={3135} +\subsubsection{\mdline{3135}9.1.5.\hspace*{0.5em}\mdline{3135}Wildcard Reads}\label{sec-table-wildcard-reads}%mdk%mdk + +%mdk-data-line={3137} +\noindent\mdline{3137}When performing a \mdline{3137}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3137}, the P4Runtime client can select all entries +from one or all tables on the target and use several of the \mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3138} fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as \mdline{3142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3142} and \mdline{3142}\textquotedblleft{}unset\textquotedblright{}\mdline{3142} for message fields such as \mdline{3142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3142}. The following +fields may be used to select and filter results:%mdk + +%mdk-data-line={3145} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3145} +\item\mdline{3145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3145}: If default (0), entries from all tables\mdline{3145} \mdline{3145}\textemdash{}\mdline{3145} including constant +tables\mdline{3146} \mdline{3146}\textemdash{}\mdline{3146} will be selected and no other filter can be used. Otherwise only +the specified table will be considered.%mdk + +%mdk-data-line={3148} +\item\mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3148}: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned.%mdk + +%mdk-data-line={3152} +\item\mdline{3152}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3152}: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an \mdline{3153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3153} (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id.%mdk + +%mdk-data-line={3159} +\item\mdline{3159}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3159}: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value.%mdk + +%mdk-data-line={3162} +\item\mdline{3162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3162}: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +\mdline{3164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3164} value.%mdk + +%mdk-data-line={3165} +\item\mdline{3165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3165}: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided \mdline{3167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3167} value.%mdk + +%mdk-data-line={3168} +\item\mdline{3168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3168}: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3172} +\noindent\mdline{3172}For example, in order to read all entries from all tables from device 3, the +client can use the following \mdline{3173}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3173} message.%mdk + +%mdk-data-line={3175} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3176} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0}\\ +~~~~priority:~{\mdcolor{purple}0}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3187} +\noindent\mdline{3187}In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following \mdline{3188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3188} +message:%mdk + +%mdk-data-line={3191} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3192} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~priority:~{\mdcolor{purple}11}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3203} +\noindent\mdline{3203}The canonical representation of \mdline{3203}\textquotedblleft{}don't care\textquotedblright{}\mdline{3203} matches, combined with the ability +to do a wildcard read on all table entries by leaving the \mdline{3204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3204} field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single \mdline{3206}\textquotedblleft{}don't care\textquotedblright{}\mdline{3206} entry or to do a wildcard +read. If a table has no fields with match kind \mdline{3207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3207}, it is possible via +P4Runtime to add an entry that is \mdline{3208}\textquotedblleft{}don't care\textquotedblright{}\mdline{3208} for all fields (\mdline{3208}i.e.\mdline{3208} has an empty +\mdline{3209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3209} field) but is not the default entry (\mdline{3209}i.e.\mdline{3209} \mdline{3209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3209} is +false). When reading this entry from the table, there is no way to read \mdline{3210}\emph{only}\mdline{3210} +that entry from the table, because it would require providing an unset \mdline{3211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3211} +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single \mdline{3214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{3214} match:%mdk + +%mdk-data-line={3216} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3217} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;~fwd;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3227} +\noindent\mdline{3227}The following \mdline{3227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3227} message can be used to add 2 entries:%mdk + +%mdk-data-line={3228} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3229} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{~{\mdcolor{darkgreen}\#~don't~care~entry}\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +~~table~entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~match~\{\\ +~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~lpm~\{\\ +~~~~~~~~value:~{\mdcolor{purple}0x0a000000}\\ +~~~~~~~~prefix\_len:~{\mdcolor{purple}8}\\ +~~~~~~\}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3248} +\noindent\mdline{3248}The first entry is a \mdline{3248}\textquotedblleft{}don't care\textquotedblright{}\mdline{3248} entry, while the second one matches all +\mdline{3249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}10.0.0.0/8}}}\mdline{3249} addresses. The second entry has higher priority than the first one.%mdk + +%mdk-data-line={3251} +\mdline{3251}The following \mdline{3251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3251} message will return \mdline{3251}\emph{all}\mdline{3251} entries in the table, not +just the \mdline{3252}\textquotedblleft{}don't care\textquotedblright{}\mdline{3252} entry.%mdk + +%mdk-data-line={3253} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3254} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3262} +\noindent\mdline{3262}This issue also exists for tables with \mdline{3262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3262}, \mdline{3262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3262}, and \mdline{3262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3262} +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the \mdline{3265}\textquotedblleft{}don't care\textquotedblright{}\mdline{3265} entry will be returned to the +client. If the client uses distinct priority values for all entries\mdline{3266} \mdline{3266}\textemdash{}\mdline{3266} which is +strongly recommended to achieve\mdline{3267}~\mdref{sec-table-entry}{deterministic behavior}\mdline{3267} \mdline{3267}\textemdash{}\mdline{3267}, +then there is no ambiguity because the wildcard read will actually return a +single entry (the \mdline{3269}\textquotedblleft{}don't care\textquotedblright{}\mdline{3269} entry) as long as the \mdline{3269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3269} field is set to +the correct value.%mdk + +%mdk-data-line={3272} +\subsubsection{\mdline{3272}9.1.6.\hspace*{0.5em}\mdline{3272}Direct Resources}\label{sec-direct-resources}%mdk%mdk + +%mdk-data-line={3274} +\noindent\mdline{3274}In addition to the \mdline{3274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3274} and \mdline{3274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3274} entities, +P4Runtime support reading and writing direct resources as part of the +\mdline{3276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3276} message. This is convenient for two reasons:%mdk + +%mdk-data-line={3278} +\begin{itemize}%mdk + +%mdk-data-line={3278} +\item{} +%mdk-data-line={3278} +\mdline{3278}A table entry and its direct resources can be read with a single entity when +doing a \mdline{3279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{3279} RPC call%mdk%mdk + +%mdk-data-line={3281} +\item{} +%mdk-data-line={3281} +\mdline{3281}The initial configuration for an entry\mdline{3281}'\mdline{3281}s direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can \mdline{3286}\textquotedblleft{}hit\textquotedblright{}\mdline{3286} the table entry without +executing the appropriate meter entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3289} +\noindent\mdline{3289}Once the table entry has been inserted, the P4Runtime client is free to use the +\mdline{3290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3290} and \mdline{3290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3290} messages for read and write +operations on \mdline{3291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3291} and \mdline{3291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3291} instances. For example, it is +usually more convenient as well as more efficient to use \mdline{3292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3292} to +query a counter entry value rather than use \mdline{3293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3293}, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry.%mdk + +%mdk-data-line={3297} +\mdline{3297}The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does \mdline{3298}\emph{not}\mdline{3298} need to be \mdline{3298}\textquotedblleft{}executed\textquotedblright{}\mdline{3298} in +every action bound to the table. It is an error to provide a direct resource +configuration in a \mdline{3300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3300} message when programming an action that does not +execute the direct resource, and the server must return an \mdline{3301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3301} +error code.%mdk + +%mdk-data-line={3304} +\mdline{3304}We leverage Protobuf\mdline{3304}'\mdline{3304}s ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the \mdline{3306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3306} message. The list below describes how +the server must handle the \mdline{3307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3307} and \mdline{3307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3307} fields for read and +write requests, based on whether the fields are set or not. We do not cover +error cases in the list, \mdline{3309}i.e.\mdline{3309} we assume that we are dealing with a table which +is assigned a direct counter / a direct meter, and that the action being used +for the table entry \mdline{3311}\textquotedblleft{}executes\textquotedblright{}\mdline{3311} the direct resource appropriately.%mdk + +%mdk-data-line={3313} +\begin{itemize}%mdk + +%mdk-data-line={3313} +\item{} +%mdk-data-line={3313} +\mdline{3313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3313} field%mdk + +%mdk-data-line={3314} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3314} +\item\mdline{3314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3314} + +%mdk-data-line={3315} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3315} +\item\mdline{3315}if \mdline{3315}\textbf{unset}\mdline{3315}: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets).%mdk + +%mdk-data-line={3317} +\item\mdline{3317}if \mdline{3317}\textbf{set}\mdline{3317}: The initial configuration for the meter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3319} +\item\mdline{3319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3319} + +%mdk-data-line={3320} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3320} +\item\mdline{3320}if \mdline{3320}\textbf{unset}\mdline{3320}: The meter entry\mdline{3320}'\mdline{3320}s configuration is reset to the default +(meter returns GREEN for all packets).%mdk + +%mdk-data-line={3322} +\item\mdline{3322}if \mdline{3322}\textbf{set}\mdline{3322}: The value provided by the client is used to re-configure +the meter entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3324} +\item\mdline{3324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3324} + +%mdk-data-line={3325} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3325} +\item\mdline{3325}if \mdline{3325}\textbf{unset}\mdline{3325}: The response does not include the meter entry\mdline{3325}'\mdline{3325}s +configuration (\mdline{3326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3326} is unset in the response).%mdk + +%mdk-data-line={3327} +\item\mdline{3327}if \mdline{3327}\textbf{set}\mdline{3327}: If the meter entry\mdline{3327}'\mdline{3327}s configuration is the default +configuration, \mdline{3328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3328} is unset in the response. Otherwise, the +response includes the meter entry\mdline{3329}'\mdline{3329}s configuration that was written by +the client earlier. This respects the \mdline{3330}\textquotedblleft{}read-write symmetry\textquotedblright{}\mdline{3330} principle.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3332} +\item{} +%mdk-data-line={3332} +\mdline{3332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3332} field%mdk + +%mdk-data-line={3333} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3333} +\item\mdline{3333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3333} + +%mdk-data-line={3334} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3334} +\item\mdline{3334}if \mdline{3334}\textbf{unset}\mdline{3334}: The initial value for the counter entry is the default +(0).%mdk + +%mdk-data-line={3336} +\item\mdline{3336}if \mdline{3336}\textbf{set}\mdline{3336}: The initial value for the counter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3338} +\item\mdline{3338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3338} + +%mdk-data-line={3339} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3339} +\item\mdline{3339}if \mdline{3339}\textbf{unset}\mdline{3339}: The counter entry\mdline{3339}'\mdline{3339}s value is not changed.%mdk + +%mdk-data-line={3340} +\item\mdline{3340}if \mdline{3340}\textbf{set}\mdline{3340}: The value provided by the client is written to the counter +entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3342} +\item\mdline{3342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3342} + +%mdk-data-line={3343} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3343} +\item\mdline{3343}if \mdline{3343}\textbf{unset}\mdline{3343}: The response does not include the counter entry\mdline{3343}'\mdline{3343}s value +(\mdline{3344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3344} is unset in the response).%mdk + +%mdk-data-line={3345} +\item\mdline{3345}if \mdline{3345}\textbf{set}\mdline{3345}: The response includes the counter entry\mdline{3345}'\mdline{3345}s value read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3348} +\noindent\mdline{3348}In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +\mdline{3350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3350} field unset when inserting \mdline{3350}\textbf{or modifying}\mdline{3350} a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the \mdline{3352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3352} message +(\mdline{3353}i.e.\mdline{3353} the \mdline{3353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3353} field must be set to match the existing configuration).%mdk + +%mdk-data-line={3355} +\subsubsection{\mdline{3355}9.1.7.\hspace*{0.5em}\mdline{3355}Idle-timeout}\label{sec-idle-timeout}%mdk%mdk + +%mdk-data-line={3357} +\noindent\mdline{3357}P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not \mdline{3359}\textquotedblleft{}hit\textquotedblright{}\mdline{3359} (\mdline{3359}i.e.\mdline{3359} not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification\mdline{3361} \mdline{3361}\textemdash{}\mdline{3361} using the +\mdline{3362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3362} message\mdline{3362} \mdline{3362}\textemdash{}\mdline{3362} to the master client, which can then take +action, such as remove the idle table entry.%mdk + +%mdk-data-line={3365} +\mdline{3365}Two fields of the \mdline{3365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3365} Protobuf message are used to implement idle +timeout:%mdk + +%mdk-data-line={3368} +\begin{itemize}%mdk + +%mdk-data-line={3368} +\item{} +%mdk-data-line={3368} +\mdline{3368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3368}: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, \mdline{3369}i.e.\mdline{3369} no +\mdline{3370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3370} message will ever be generated for this entry. When +a client reads a \mdline{3371}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3371}, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry.%mdk%mdk + +%mdk-data-line={3375} +\item{} +%mdk-data-line={3375} +\mdline{3375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3375}: a Protobuf message with a single field (\mdline{3375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{3375}) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The \mdline{3377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3377} field must be unset for a +\mdline{3378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3378} write. When reading a table entry, \mdline{3378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3378} must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3383} +\noindent\mdline{3383}These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an \mdline{3385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3385} error code if at least one of these +conditions is met:%mdk + +%mdk-data-line={3388} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3388} +\item\mdline{3388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3388} is set to a non-zero value, or%mdk + +%mdk-data-line={3389} +\item\mdline{3389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3389} is set%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3391} +\noindent\mdline{3391}The target should do its best to approximate the \mdline{3391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3391} value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the \mdline{3394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3394} write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for \mdline{3396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3396}.%mdk + +%mdk-data-line={3398} +\mdline{3398}P4Runtime does not support idle timeout for default entries. When the +\mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3399} flag is set in a \mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3399} message, \mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3399} +must be set to 0 (default) and \mdline{3400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3400} must be unset. If the +server receives a \mdline{3401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3401} message which violates this, it must return an +\mdline{3402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3402} error.%mdk + +%mdk-data-line={3404} +\mdline{3404}For more information about idle timeout, in particular regarding +\mdline{3405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3405}, please refer to the\mdline{3405}~\mdref{sec-table-idle-timeout-notification}{Table idle timeout +notifications}\mdline{3406} section.%mdk + +%mdk-data-line={3408} +\subsection{\mdline{3408}9.2.\hspace*{0.5em}\mdline{3408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3408} \mdline{3408}\&\mdline{3408} \mdline{3408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}\label{sec-action-profile-member-and-group}%mdk%mdk + +%mdk-data-line={3410} +\noindent\mdline{3410}P4Runtime defines an API for programming a PSA ActionProfile extern using +\mdline{3411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3411} messages. A PSA ActionSelector extern can be programmed +using both \mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3412} and \mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3412} messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table \mdline{3416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3416} for L3 routing, implemented with an action +selector \mdline{3417}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3417}.%mdk + +%mdk-data-line={3419} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3420} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector(HashAlgorithm.crc32,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}size~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w1024,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}output\_width~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w10)~as;\\ +\\ +{\bfseries{\mdcolor{navy}action}}~set\_nhop(PortId\_t~p,~EthAddr~smac,~EthAddr~dmac)~\{\\ +~~istd.egress\_port~=~p;\\ +~~hdr.ethernet.smac~=~smac;\\ +~~hdr.ethernet.dmac~=~dmac;\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;~~{\mdcolor{darkgreen}//~LPM~on~destination~IP~address}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~set\_nhop;\\ +~~\}\\ +~~implementation~=~as;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3441} +\noindent\mdline{3441}When programming table \mdline{3441}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3441} in the example above, a P4Runtime client should +specify the \mdline{3442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3442} in the \mdline{3442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3442} to be a reference to either an +action profile member or group. The reference is a non-zero \mdline{3443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3443} identifier +that uniquely identifies a member or group programmed in the action selector +\mdline{3445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3445}.%mdk + +%mdk-data-line={3447} +\mdline{3447}If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata.%mdk + +%mdk-data-line={3452} +\mdline{3452}If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata.%mdk + +%mdk-data-line={3463} +\subsubsection{\mdline{3463}9.2.1.\hspace*{0.5em}\mdline{3463}Action Profile Member Programming}\label{sec-action-profile-member-programming}%mdk%mdk + +%mdk-data-line={3465} +\noindent\mdline{3465}Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a \mdline{3466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3466} identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the \mdline{3468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3468} +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the \mdline{3470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3470} attributes of the +tables \mdline{3471}\emph{must have an identical list of P4 actions}\mdline{3471}. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector.%mdk + +%mdk-data-line={3475} +\mdline{3475}An \mdline{3475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3475} entity update message has the following fields:%mdk + +%mdk-data-line={3477} +\begin{itemize}%mdk + +%mdk-data-line={3477} +\item{} +%mdk-data-line={3477} +\mdline{3477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3477} is the \mdline{3477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3477} identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3480} +\item{} +%mdk-data-line={3480} +\mdline{3480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3480} is the non-zero \mdline{3480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3480} identifier of the action profile member +entry being updated.%mdk%mdk + +%mdk-data-line={3483} +\item{} +%mdk-data-line={3483} +\mdline{3483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3483} is the specification of the P4 action instance bound to the action +profile member entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3486} +\noindent\mdline{3486}An action profile member may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3489} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3489} +\item\mdline{3489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3489}: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an \mdline{3491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3491} error +code. The action specification must be provided, or the server must return +\mdline{3493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3493}. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return \mdline{3495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3495}.%mdk + +%mdk-data-line={3496} +\item\mdline{3496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3496}: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return \mdline{3497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3497}, +and the action specification must be provided, or the server must return +\mdline{3499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3499}.%mdk + +%mdk-data-line={3500} +\item\mdline{3500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3500}: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a \mdline{3501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3501} error code. The member +must not be part of an action profile group, or the server must return +\mdline{3503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3503}. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return \mdline{3506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3506}. \mdline{3506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3506} and \mdline{3506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3506} are the only +fields that are considered when performing a \mdline{3507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3507} and every other field +will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3510} +\noindent\mdline{3510}When reading, an \mdline{3510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3510} message with \mdline{3510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3510} and +\mdline{3511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3511} equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with \mdline{3512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3512} equal to the id of +an existing ActionProfile or ActionSelector object, and a \mdline{3513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3513} equal to +0, will read all members of that specified object.%mdk + +%mdk-data-line={3516} +\subsubsection{\mdline{3516}9.2.2.\hspace*{0.5em}\mdline{3516}Action Profile Group Programming}\label{sec-action-profile-group-programming}%mdk%mdk + +%mdk-data-line={3518} +\noindent\mdline{3518}Action profile groups are entries in an ActionSelector and are referenced by a +\mdline{3519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3519} identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type.%mdk + +%mdk-data-line={3523} +\mdline{3523}Within a single ActionSelector object, the \mdline{3523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3523} values used to identify its +members are in a separate \mdline{3524}\textquoteleft{}scope\textquoteright{}\mdline{3524} from the \mdline{3524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3524} values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5.%mdk + +%mdk-data-line={3528} +\mdline{3528}There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it.%mdk + +%mdk-data-line={3534} +\mdline{3534}An \mdline{3534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3534} entity update message has the following fields:%mdk + +%mdk-data-line={3536} +\begin{itemize}%mdk + +%mdk-data-line={3536} +\item{} +%mdk-data-line={3536} +\mdline{3536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3536} is the \mdline{3536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3536} identifier of the PSA ActionSelector +extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3539} +\item{} +%mdk-data-line={3539} +\mdline{3539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3539} is the non-zero \mdline{3539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3539} identifier of the action profile group +entry being updated.%mdk%mdk + +%mdk-data-line={3542} +\item{} +%mdk-data-line={3542} +\mdline{3542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3542} is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields:%mdk + +%mdk-data-line={3545} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3545} +\item\mdline{3545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3545} for looking up the member table in the selector.%mdk + +%mdk-data-line={3546} +\item\mdline{3546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3546} specifying the probability of the member\mdline{3546}'\mdline{3546}s selection at +runtime. 0 is not a valid \mdline{3547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3547} value and the server must return +\mdline{3548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3548} if the client attempts to use it.%mdk + +%mdk-data-line={3549} +\item\mdline{3549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3549} is the controller-defined 32-bit port number that the member\mdline{3549}'\mdline{3549}s +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +\mdline{3552}\mdref{action-selector-constraints}{9.2.4}\mdline{3552} for notes on the behavior if all members in +a group are excluded for this reason. If \mdline{3553}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3553} is 0, then the member is +always included in the selection, regardless of the status of any port of +the device. The value must be 0 or the SDN port number of an existing +port on the device, otherwise the server must return \mdline{3556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3556}.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3558} +\item{} +%mdk-data-line={3558} +\mdline{3558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3558} is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +\mdline{3560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3560} update. See the subsection below for the\mdline{3560}~\mdref{sec-max-size-rules}{rules on setting +\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\mdline{3561}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3563} +\noindent\mdline{3563}An action profile group may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3566} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3566} +\item\mdline{3566}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3566}: Add a new group entry bound to a set of existing action profile +members. \mdline{3567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}The~group\_id}}}\mdline{3567} must be different from ids of already programmed +groups for that selector, or the server must return an \mdline{3568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3568} error +code. All members specified in the group must exist in the selector, or the +server must return \mdline{3570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3570}. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target.%mdk + +%mdk-data-line={3572} +\item\mdline{3572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3572}: Modify the member set specification of an existing group entry. An +entry with the \mdline{3573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3573} must exist, or the server must return +\mdline{3574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3574}. All members specified in the group entry must exist in the +selector, or the server must return \mdline{3575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3575}. The value of \mdline{3575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3575} must +be identical to the value used when inserting the group, otherwise an +\mdline{3577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3577} error is returned.%mdk + +%mdk-data-line={3578} +\item\mdline{3578}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3578}: Delete the group entry and deallocate the \mdline{3578}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3578}. The group must +not be referenced in the table action of any table entry, or the server must +return a \mdline{3580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3580} error code. If the \mdline{3580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3580} is invalid, the +server must return \mdline{3581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3581}. \mdline{3581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3581} and \mdline{3581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3581} are the +only fields that are considered when performing a \mdline{3582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3582} and every other +field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3585} +\noindent\mdline{3585}When setting the group membership with \mdline{3585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3585} or \mdline{3585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3585}, the \mdline{3585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3585} +repeated field must not include duplicates, \mdline{3586}i.e.\mdline{3586} members with the same +\mdline{3587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3587}. The \mdline{3587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3587} field is used instead to logically \mdline{3587}\textquotedblleft{}repeat\textquotedblright{}\mdline{3587} the member +inside the group.%mdk + +%mdk-data-line={3590} +\mdline{3590}It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation \mdline{3591}\textquotedblleft{}stores\textquotedblright{}\mdline{3591} the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made.%mdk + +%mdk-data-line={3595} +\mdline{3595}When reading, an \mdline{3595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3595} message with \mdline{3595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3595} and +\mdline{3596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3596} equal to 0 will read all groups of all ActionSelector objects. A +message with \mdline{3597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3597} equal to the id of an existing ActionSelector +object, and a \mdline{3598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3598} equal to 0, will read all groups of that one specified +object.%mdk + +%mdk-data-line={3601} +\paragraph{\mdline{3601}9.2.2.1.\hspace*{0.5em}\mdline{3601}Rules on Setting \mdline{3601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\label{sec-max-size-rules}%mdk%mdk + +%mdk-data-line={3603} +\noindent\mdline{3603}The valid values for \mdline{3603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3603} depend on the static \mdline{3603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3603} included +in the P4Info message:%mdk + +%mdk-data-line={3606} +\begin{itemize}%mdk + +%mdk-data-line={3606} +\item{} +%mdk-data-line={3606} +\mdline{3606}If \mdline{3606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3606} is greater than 0, then \mdline{3606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3606} must be greater than 0, +and less than or equal to \mdline{3607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3607}. We assume that the target can +support selector groups for which the sum of all member weights is up to +\mdline{3609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3609}, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If \mdline{3610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3610} is greater than \mdline{3610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3610}, the server +must return \mdline{3611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3611}.%mdk%mdk + +%mdk-data-line={3613} +\item{} +%mdk-data-line={3613} +\mdline{3613}Otherwise (\mdline{3613}i.e.\mdline{3613} if \mdline{3613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3613} is 0), the P4Runtime client can set +\mdline{3614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3614} to any value greater than or equal to 0.%mdk + +%mdk-data-line={3616} +\begin{itemize}%mdk + +%mdk-data-line={3616} +\item{} +%mdk-data-line={3616} +\mdline{3616}A \mdline{3616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3616} of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (\mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3619} or \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3619}), the target must return a +\mdline{3620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3620} error.%mdk%mdk + +%mdk-data-line={3622} +\item{} +%mdk-data-line={3622} +\mdline{3622}If \mdline{3622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3622} is greater than 0 and the value is not supported by the +target, the server must return a \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3623} error at +group-creation time.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3626} +\subsubsection{\mdline{3626}9.2.3.\hspace*{0.5em}\mdline{3626}One Shot Action Selector Programming}\label{sec-oneshot}%mdk%mdk + +%mdk-data-line={3628} +\noindent\mdline{3628}P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids.%mdk + +%mdk-data-line={3634} +\mdline{3634}One shots are programmed by choosing the \mdline{3634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3634} message as the +\mdline{3635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3635}. The \mdline{3635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3635} message consists of a set of +\mdline{3636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3636} messages, which in turn have the following fields:%mdk + +%mdk-data-line={3638} +\begin{itemize}%mdk + +%mdk-data-line={3638} +\item{} +%mdk-data-line={3638} +\mdline{3638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3638} is one of the actions specified by the table that is being +programmed.%mdk%mdk + +%mdk-data-line={3641} +\item{} +%mdk-data-line={3641} +\mdline{3641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3641} specifying the probability of the action\mdline{3641}'\mdline{3641}s selection at runtime. 0 is +not a valid \mdline{3642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3642} value and the server must return \mdline{3642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3642} if +the client attempts to use it. The sum of all weights across all +\mdline{3644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3644} messages for that \mdline{3644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3644} message must +not exceed the \mdline{3645}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3645} specificed in the P4Info (if greater than 0), +or the server must return \mdline{3646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3646}.%mdk%mdk + +%mdk-data-line={3648} +\item{} +%mdk-data-line={3648} +\mdline{3648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3648} is the controller-defined 32-bit port number that the action\mdline{3648}'\mdline{3648}s +liveness depends on. At runtime, the action must be excluded from selection if +the watch port is down. See Section +\mdline{3651}\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{3651} for more details on the \mdline{3651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{3651} field, +which also apply for one shot action selector programming.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3655} +\noindent\mdline{3655}Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics.%mdk + +%mdk-data-line={3660} +\mdline{3660}To preserve read-write symmetry, an implementation must answer \mdline{3660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3660}s +with the original one shot messages. It may not return a desugared version of +the one shot message.%mdk + +%mdk-data-line={3664} +\mdline{3664}For example, consider the action selector table defined +\mdline{3665}\mdref{sec-action-profile-member-and-group}{here}\mdline{3665}. This table could be programmed +with the following one shot update:%mdk + +%mdk-data-line={3668} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3669} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{\\ +~~~~action\_profile\_action\_set~\{\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}1}\\ +~~~~~~~~watch:~{\mdcolor{purple}1}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}2}\\ +~~~~~~~~watch:~{\mdcolor{purple}2}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}3}\\ +~~~~~~~~watch:~{\mdcolor{purple}3}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3694} +\noindent\mdline{3694}Which would be equivalent to the following updates, where \mdline{3694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GROUP\_ID}}}\mdline{3694}, +\mdline{3695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_1}}}\mdline{3695}, \mdline{3695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_2}}}\mdline{3695}, and \mdline{3695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_3}}}\mdline{3695} are unused ids:%mdk + +%mdk-data-line={3697} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3698} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_1\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_2\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_3\\ +~~action~\{~~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +\}\\ +action\_profile\_group~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~group\_id:~GROUP\_ID\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_1\\ +~~~~weight:~{\mdcolor{purple}1}\\ +~~~~watch:~{\mdcolor{purple}1}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_2\\ +~~~~weight:~{\mdcolor{purple}2}\\ +~~~~watch:~{\mdcolor{purple}2}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_3\\ +~~~~weight:~{\mdcolor{purple}3}\\ +~~~~watch:~{\mdcolor{purple}3}\\ +~~\}\\ +\}\\ +table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{~action\_profile\_group\_id:~GROUP\_ID~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3739} +\noindent\mdline{3739}Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure\mdline{3740}~\mdref{sec-batching-and-ordering-of-updates}{correct ordering between the dependent +updates}\mdline{3741}. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct \mdline{3743}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3743} batches are required.%mdk + +%mdk-data-line={3745} +\mdline{3745}It is possible to include several \mdline{3745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3745} messages with the same +exact \mdline{3746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3746} specification in one \mdline{3746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3746} message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the \mdline{3748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3748} field. Note that to preserve read-write symmetry, the server +must not coalesce multiple \mdline{3749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3749} messages with the same \mdline{3749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3749} +specification into one.%mdk + +%mdk-data-line={3752} +\mdline{3752}All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with \mdline{3753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3753} and +\mdline{3754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3754} messages. Programming some entries with one shots, and +other entries with \mdline{3755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3755} and \mdline{3755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3755} messages is +not allowed, and the server must return the error code \mdline{3756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3756} in +that case.%mdk + +%mdk-data-line={3759} +\mdline{3759}A P4Runtime server \mdline{3759}\emph{must}\mdline{3759} support the one shot style of programming tables with +an action selector implementation. Support for the \mdline{3760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3760} and +\mdline{3761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3761} style is \mdline{3761}\emph{optional}\mdline{3761}. If \mdline{3761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3761} and +\mdline{3762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3762} are not supported by a server, it must return an +\mdline{3763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3763} error for every \mdline{3763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3763} or \mdline{3763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3763} +message that it receives.%mdk + +%mdk-data-line={3766} +\subsubsection{\mdline{3766}9.2.4.\hspace*{0.5em}\mdline{3766}Constraints on action selector programming}\label{action-selector-constraints}%mdk%mdk + +%mdk-data-line={3768} +\noindent\mdline{3768}The PSA specification states that the following features are \mdline{3768}\emph{optional}\mdline{3768} in +action selector implementations\mdline{3769}~[\mdcite{psaactionselector}{22}]\mdline{3769}:%mdk + +%mdk-data-line={3771} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3771} +\item\mdline{3771}Support for non-empty groups where in the same group, different members are +bound to different actions.%mdk + +%mdk-data-line={3773} +\item\mdline{3773}Predictable data plane behavior when a matched table entry points to an empty +group.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={3776} +\noindent\mdline{3776}For 1., if a client tries to \mdline{3776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3776} or \mdline{3776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3776} a group with members bound to +different actions, the server should return \mdline{3777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3777} if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return \mdline{3783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3783} (modifying the action parameter values must be +supported, however).%mdk + +%mdk-data-line={3786} +\mdline{3786}PSA 1.1 introduces the \mdline{3786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3786} table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. \mdline{3790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3790} is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of \mdline{3793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3793} at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +\mdline{3795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3795}. Even when \mdline{3795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3795} is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of \mdline{3799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3799} mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming.%mdk + +%mdk-data-line={3804} +\mdline{3804}The PSA specification includes a discussion on how to implement +\mdline{3805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3805} in software in the P4Runtime server +\mdline{3806}[\mdcite{psaemptygroupactionappendix}{25}]\mdline{3806}.%mdk + +%mdk-data-line={3808} +\mdline{3808}If a P4Runtime implementation does support \mdline{3808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3808}, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down.%mdk + +%mdk-data-line={3812} +\mdline{3812}If a P4Runtime implementation does not support \mdline{3812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3812}, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down.%mdk + +%mdk-data-line={3818} +\subsection{\mdline{3818}9.3.\hspace*{0.5em}\mdline{3818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3818} \mdline{3818}\&\mdline{3818} \mdline{3818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-counterentry-directcounterentry}%mdk%mdk + +%mdk-data-line={3820} +\noindent\mdline{3820}PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The \mdline{3822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3822} +P4Runtime message can be used for all three types of PSA counters\mdline{3823} \mdline{3823}\textemdash{}\mdline{3823} \mdline{3823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{3823}, +\mdline{3824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{3824} and \mdline{3824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3824} \mdline{3824}\textemdash{}\mdline{3824} and consists of the following fields:%mdk + +%mdk-data-line={3826} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3826} +\item\mdline{3826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3826} is an \mdline{3826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3826}, corresponding to the number of octets.%mdk + +%mdk-data-line={3827} +\item\mdline{3827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3827} is an \mdline{3827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3827}, corresponding to the number of packets.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3829} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3830} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterData~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~byte\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}int64}}~packet\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3836} +\noindent\mdline{3836}P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of \mdline{3837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3837} and \mdline{3837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3837} fields, which +is equivalent to specifying the counter type \mdline{3838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3838}. Counters may +be defined as direct or indirect (indexed) instances.%mdk + +%mdk-data-line={3841} +\subsubsection{\mdline{3841}9.3.1.\hspace*{0.5em}\mdline{3841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-directcounterentry}%mdk%mdk + +%mdk-data-line={3843} +\noindent\mdline{3843}A direct counter is a direct resource associated with a \mdline{3843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3843} (see +\mdline{3844}\mdref{sec-direct-resources}{Direct Resources}\mdline{3844}). The \mdline{3844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3844} field of the +\mdline{3845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3845} message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +\mdline{3848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3848} message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed.%mdk + +%mdk-data-line={3851} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3852} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectCounterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3858} +\noindent\mdline{3858}A \mdline{3858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3858} may only include an \mdline{3858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3858} message of type \mdline{3858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3858} with a +\mdline{3859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3859}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3861} +\begin{itemize}%mdk + +%mdk-data-line={3861} +\item{} +%mdk-data-line={3861} +\mdline{3861}the \mdline{3861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3861} field must match \mdline{3861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry.match}}}\mdline{3861} of the table entry +to which this direct counter entry is associated. If a matching \mdline{3862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3862} +is not found, the server returns the error code \mdline{3863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3863}.%mdk%mdk + +%mdk-data-line={3865} +\item{} +%mdk-data-line={3865} +\mdline{3865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3865} is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3869} +\noindent\mdline{3869}Specifying \mdline{3869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3869} in an \mdline{3869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3869} message of type \mdline{3869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3869} or +\mdline{3870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3870} is not allowed, and the server must return the error code +\mdline{3871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3871} in that case.%mdk + +%mdk-data-line={3873} +\mdline{3873}A client may use \mdline{3873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3873} in two ways to read the contents of a +\mdline{3874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3874}:%mdk + +%mdk-data-line={3876} +\begin{itemize}%mdk + +%mdk-data-line={3876} +\item{} +%mdk-data-line={3876} +\mdline{3876}As a direct resource associated with a table entry, request the server to +return the counter value in the \mdline{3877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3877} field of the \mdline{3877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3877} message +(see\mdline{3878}~\mdref{sec-direct-resources}{Direct resources}\mdline{3878}).%mdk%mdk + +%mdk-data-line={3880} +\item{} +%mdk-data-line={3880} +\mdline{3880}Explicitly request the counter value by including the \mdline{3880}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3880} in +the \mdline{3881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3881}. The \mdline{3881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3881} field must match the \mdline{3881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3881} +whose counter is being read. If no such entry is found, the server returns the +error code \mdline{3883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3883}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3885} +\subsubsection{\mdline{3885}9.3.2.\hspace*{0.5em}\mdline{3885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}\label{sec-counterentry}%mdk%mdk + +%mdk-data-line={3887} +\noindent\mdline{3887}An indirect or indexed counter is not associated with a specific \mdline{3887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3887} +and may be updated independently of any action. It may be read or written using +the P4Runtime \mdline{3889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3889} message whose fields are defined as follows:%mdk + +%mdk-data-line={3891} +\begin{itemize}%mdk + +%mdk-data-line={3891} +\item{} +%mdk-data-line={3891} +\mdline{3891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3891} is a \mdline{3891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3891}, the unique identifier for the counter.%mdk%mdk + +%mdk-data-line={3893} +\item{} +%mdk-data-line={3893} +\mdline{3893}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3893} is a Protobuf message that encapsulates an \mdline{3893}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3893}, used to index into +the counter array.%mdk%mdk + +%mdk-data-line={3896} +\item{} +%mdk-data-line={3896} +\mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3896} is a Protobuf message of type \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3896}, which represents the +counter value.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3899} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3900} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~counter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3907} +\noindent\mdline{3907}The \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3907} can only be used in a \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3907} with the \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3907} update +type. The P4Runtime server must return an \mdline{3908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3908} error code for +update types \mdline{3909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3909} and \mdline{3909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3909}. By default all the counter entries in the +array have default value 0.%mdk + +%mdk-data-line={3912} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3912} +\item\mdline{3912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3912}: Server returns the error code \mdline{3912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3912}.%mdk + +%mdk-data-line={3913} +\item\mdline{3913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3913}: Modify an indirect counter instance whose unique id is \mdline{3913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3913} +and array index is specified by \mdline{3914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3914}. The counter value is set to the value +specified by the client in the \mdline{3915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3915} field. Note that the counter value is +not modified if this Protobuf field is not set. If \mdline{3916}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3916} is omitted all +counter values in the array will be set to the value provided by the +client. The server must return \mdline{3918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3918} for a negative index value +and \mdline{3919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3919} if the index value exceeds the size of the counter array.%mdk + +%mdk-data-line={3920} +\item\mdline{3920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3920}: Server returns the error code \mdline{3920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3920}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3922} +\noindent\mdline{3922}A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a \mdline{3923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3923} by including a \mdline{3923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3923} +entity for each of the instances, specifying the \mdline{3924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3924} and +\mdline{3925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3925}. Wildcard reads are also supported as follows.%mdk + +%mdk-data-line={3927} +\begin{itemize}%mdk + +%mdk-data-line={3927} +\item{} +%mdk-data-line={3927} +\mdline{3927}If the \mdline{3927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3927} field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the \mdline{3928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3928}.%mdk%mdk + +%mdk-data-line={3930} +\item{} +%mdk-data-line={3930} +\mdline{3930}If the \mdline{3930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3930} field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id \mdline{3931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3931}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3933} +\subsection{\mdline{3933}9.4.\hspace*{0.5em}\mdline{3933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3933} \mdline{3933}\&\mdline{3933} \mdline{3933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-meterentry-directmeterentry}%mdk%mdk + +%mdk-data-line={3935} +\noindent\mdline{3935}Meters are an advanced mechanism for keeping statistics, involving stateful +\mdline{3936}\textquotedblleft{}marking\textquotedblright{}\mdline{3936} and usually \mdline{3936}\textquotedblleft{}throttling\textquotedblright{}\mdline{3936} of packets based on configured rates of +traffic. The PSA metering function is based on the \mdline{3937}\emph{Two Rate Three Color Marker}\mdline{3937} +(trTCM) defined in RFC 2698\mdline{3938}~[\mdcite{rfc2698}{2}]\mdline{3938}. The trTCM meters an arbitrary packet +stream using two configured rates\mdline{3939} \mdline{3939}\textemdash{}\mdline{3939} the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes\mdline{3940} \mdline{3940}\textemdash{}\mdline{3940} and +\mdline{3941}\textquotedblleft{}marks\textquotedblright{}\mdline{3941} its packets as GREEN, YELLOW or RED based on the observed rate.%mdk + +%mdk-data-line={3943} +\mdline{3943}A meter may be configured as a direct or indirect instance, similar to a +counter. The \mdline{3944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{3944} P4Runtime message represents meter configuration.%mdk + +%mdk-data-line={3946} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3947} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterConfig~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~cir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~Committed~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~cburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};~~{\mdcolor{darkgreen}//~Committed~Burst~Size}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};~~{\mdcolor{darkgreen}//~Peak~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};~~{\mdcolor{darkgreen}//~Peak~Burst~Size}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3955} +\subsubsection{\mdline{3955}9.4.1.\hspace*{0.5em}\mdline{3955}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-directmeterentry}%mdk%mdk + +%mdk-data-line={3957} +\noindent\mdline{3957}A direct meter is a direct resource associated with a \mdline{3957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3957} (see\mdline{3957}~\mdref{sec-direct-resources}{Direct +resources}\mdline{3958}). The \mdline{3958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3958} field of the \mdline{3958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3958} +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +\mdline{3962}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3962} message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed.%mdk + +%mdk-data-line={3965} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3966} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectMeterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3972} +\noindent\mdline{3972}A \mdline{3972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3972} may only include an \mdline{3972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3972} message of type \mdline{3972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3972} with a +\mdline{3973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3973}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3975} +\begin{itemize}%mdk + +%mdk-data-line={3975} +\item{} +%mdk-data-line={3975} +\mdline{3975}the \mdline{3975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3975} field must match the match key of the \mdline{3975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3975} +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching \mdline{3977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3977} is not found, +the server returns the error code \mdline{3978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3978}.%mdk%mdk + +%mdk-data-line={3980} +\item{} +%mdk-data-line={3980} +\mdline{3980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{3980} is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3984} +\noindent\mdline{3984}Specifying \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3984} in an \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3984} message of type \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3984} or +\mdline{3985}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3985} is not allowed, and the server must return the error code +\mdline{3986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3986} in that case.%mdk + +%mdk-data-line={3988} +\mdline{3988}A client may use \mdline{3988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3988} in two ways to read a \mdline{3988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3988} config.%mdk + +%mdk-data-line={3990} +\begin{itemize}%mdk + +%mdk-data-line={3990} +\item{} +%mdk-data-line={3990} +\mdline{3990}As a direct resource associated with a table entry, request the server to +return the meter config in the \mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3991} field of the \mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3991} +message (see\mdline{3992}~\mdref{sec-direct-resources}{Direct resources}\mdline{3992}).%mdk%mdk + +%mdk-data-line={3994} +\item{} +%mdk-data-line={3994} +\mdline{3994}Explicitly request the meter configuration by including the \mdline{3994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3994} +in the \mdline{3995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3995}. The \mdline{3995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3995} field must match the +\mdline{3996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3996} whose meter config is being read. If no such entry is found, the +server returns the error code \mdline{3997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3997}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3999} +\subsubsection{\mdline{3999}9.4.2.\hspace*{0.5em}\mdline{3999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}\label{sec-meterentry}%mdk%mdk + +%mdk-data-line={4001} +\noindent\mdline{4001}An indirect or indexed meter is not associated with a specific \mdline{4001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4001} and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime \mdline{4003}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4003} message whose fields are defined as +follows:%mdk + +%mdk-data-line={4006} +\begin{itemize}%mdk + +%mdk-data-line={4006} +\item{} +%mdk-data-line={4006} +\mdline{4006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4006} is a \mdline{4006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4006}, the unique identifier for the meter.%mdk%mdk + +%mdk-data-line={4008} +\item{} +%mdk-data-line={4008} +\mdline{4008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4008} is a Protobuf message that encapsulates an \mdline{4008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4008}, used to index into +a meter array.%mdk%mdk + +%mdk-data-line={4011} +\item{} +%mdk-data-line={4011} +\mdline{4011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4011} is a Protobuf message of type \mdline{4011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{4011}, which represents the +meter configuration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4014} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4015} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~meter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4022} +\noindent\mdline{4022}The \mdline{4022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4022} can only be used in a \mdline{4022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4022} with the \mdline{4022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4022} update +type. The P4Runtime server must return an \mdline{4023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4023} error code for +update types \mdline{4024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4024} and \mdline{4024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4024}. By default all the meter entries in the +array have a default configuration (GREEN for all packets).%mdk + +%mdk-data-line={4027} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4027} +\item\mdline{4027}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4027}: Server returns the error code \mdline{4027}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4027}.%mdk + +%mdk-data-line={4028} +\item\mdline{4028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4028}: Modify an indirect meter instance whose unique id is \mdline{4028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4028} and +array index is specified by \mdline{4029}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4029}. The meter is reconfigured using the +\mdline{4030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4030} field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the \mdline{4032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4032} field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if \mdline{4034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4034} is unset). The server must return \mdline{4034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4034} for a +negative index value and \mdline{4035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4035} if the index value exceeds the size of +the meter array.%mdk + +%mdk-data-line={4037} +\item\mdline{4037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4037}: Server returns the error code \mdline{4037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4037}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4039} +\noindent\mdline{4039}A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a \mdline{4040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4040} by including a \mdline{4040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4040} entity for each +of the instances, specifying the \mdline{4041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4041} and \mdline{4041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4041}. Wildcard reads are also +supported as follows:%mdk + +%mdk-data-line={4044} +\begin{itemize}%mdk + +%mdk-data-line={4044} +\item{} +%mdk-data-line={4044} +\mdline{4044}If the \mdline{4044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4044} field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the \mdline{4045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4045}.%mdk%mdk + +%mdk-data-line={4047} +\item{} +%mdk-data-line={4047} +\mdline{4047}If the \mdline{4047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4047} field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id \mdline{4048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4048}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4050} +\subsection{\mdline{4050}9.5.\hspace*{0.5em}\mdline{4050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}\label{sec-packetreplicationengineentry}%mdk%mdk + +%mdk-data-line={4052} +\noindent\mdline{4052}The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets.%mdk + +%mdk-data-line={4058} +\subsubsection{\mdline{4058}9.5.1.\hspace*{0.5em}\mdline{4058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}\label{sec-multicastgroupentry}%mdk%mdk + +%mdk-data-line={4060} +\noindent\mdline{4060}Multicasting is achieved in PSA programs by setting the \mdline{4060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4060} +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the \mdline{4063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4063} API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example.%mdk + +%mdk-data-line={4068} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4069} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~arp\_multicast({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ethernet.isValid()~\&\&\\ +~~~~~~~~hdr.ethernet.eth\_type~==~ETH\_TYPE\_ARP)~\{\\ +~~~~~~smeta.multicast\_group~=~(MulticastGroup\_t)~{\mdcolor{purple}1};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4079} +\noindent\mdline{4079}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4082} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4083} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~multicast\_group\_entry~\{\\ +~~~~~~multicast\_group\_id:~{\mdcolor{purple}1}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}5}~instance:~{\mdcolor{purple}1}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}12}~instance:~{\mdcolor{purple}2}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}18}~instance:~{\mdcolor{purple}3}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}24}~instance:~{\mdcolor{purple}4}~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4097} +\noindent\mdline{4097}As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +\mdline{4102}\mdref{sec-translation-of-port-numbers}{PSA Metadata Translation}\mdline{4102} section.%mdk + +%mdk-data-line={4104} +\mdline{4104}The egress packets may be distinguished for further processing in the egress +using the \mdline{4105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4105} metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 \mdline{4107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4107} metadata is set to a value that is not +programmed in the PRE, then the packet is dropped.%mdk + +%mdk-data-line={4110} +\mdline{4110}A multicast group may be inserted, modified or deleted as per the following +semantics.%mdk + +%mdk-data-line={4113} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4113} +\item\mdline{4113}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4113}: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The \mdline{4114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4114} field is a \mdline{4114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4114} and must be greater +than 0 (see explanation\mdline{4115}~\mdref{sec-valid-values-for-mg-id}{below}\mdline{4115}), or the +P4Runtime server must return an \mdline{4116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4116} error. The replica +\mdline{4117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4117} ID is also a \mdline{4117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4117}, and its value may not exceed the maximum +allowed by the target for the \mdline{4118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4118} type (0 is allowed), or the +server must return an \mdline{4119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4119} error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of \mdline{4121}\emph{both}\mdline{4121} \mdline{4121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{4121} and \mdline{4121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4121}, or the server +must return \mdline{4122}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4122}.%mdk + +%mdk-data-line={4123} +\item\mdline{4123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4123}: Modify the set of replicas for a given multicast group entry, +indexed by the given \mdline{4124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4124}. Same restrictions as \mdline{4124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4124} apply +here.%mdk + +%mdk-data-line={4126} +\item\mdline{4126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4126}: Delete the multicast group indexed by the given +\mdline{4127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4127}. The replicas need not be provided for this +operation. Any packets with their \mdline{4128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4128} metadata in the data plane +set to the deleted \mdline{4129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4129} will be dropped.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4131} +\noindent\mdline{4131}When reading a multicast group, only \mdline{4131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4131} is considered. All +other fields in \mdline{4132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4132} are ignored. To perform a \mdline{4132}\emph{wildcard}\mdline{4132} +\mdline{4133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4133} on all configured multicast group entries, the \mdline{4133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4133} field +must be set to 0, its default value.%mdk + +%mdk-data-line={4136} +\paragraph{\mdline{4136}9.5.1.1.\hspace*{0.5em}\mdline{4136}Valid Values for \mdline{4136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}}\label{sec-valid-values-for-mg-id}%mdk%mdk + +%mdk-data-line={4138} +\noindent\mdline{4138}The PSA specification states that the valid \mdline{4138}\emph{data plane}\mdline{4138} values for multicast +group ids (\mdline{4139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroup\_t}}}\mdline{4139}) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target\mdline{4141}~[\mdcite{psatranslation}{24}]\mdline{4141}. This means that, in the absence of +translation, the client must set the \mdline{4142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4142} field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special \mdline{4144}\emph{wildcard}\mdline{4144} value which is used to read all the multicast groups +configured in the target, the \mdline{4145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4145} field must never be set to 0 +when performing a \mdline{4146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4146} RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value.%mdk + +%mdk-data-line={4151} +\subsubsection{\mdline{4151}9.5.2.\hspace*{0.5em}\mdline{4151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}\label{sec-clonesessionentry}%mdk%mdk + +%mdk-data-line={4153} +\noindent\mdline{4153}PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +\mdline{4157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4157} identifier and a boolean flag \mdline{4157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone}}}\mdline{4157} in the packet +metadata. The \mdline{4158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4158} serves as a handle to the clone attributes, +namely a set \mdline{4159}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}replicas}}}\mdline{4159} of \mdline{4159}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(egress~port,~instance)}}}\mdline{4159} pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +\mdline{4162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4162} API.%mdk + +%mdk-data-line={4164} +\mdline{4164}The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the \mdline{4167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_low\_ttl}}}\mdline{4167} control block is applied in the ingress +pipeline to create an ingress-to-egress clone.%mdk + +%mdk-data-line={4170} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4171} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~clone\_low\_ttl({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ipv4.isValid()~\&\&\\ +~~~~~~~~hdr.ipv4.ttl~\textless{}=~LOW\_TTL\_THRESHOLD)~\{\\ +~~~~~~smeta.clone\_session\_id~=~{\mdcolor{purple}10}w100;\\ +~~~~~~smeta.clone~=~{\bfseries{\mdcolor{navy}true}};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4183} +\noindent\mdline{4183}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4186} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4187} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~clone\_session\_entry~\{\\ +~~~~~~session\_id:~{\mdcolor{purple}100}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}0xfffffffd}~instance:~{\mdcolor{purple}1}~\}~{\mdcolor{darkgreen}\#~to~CPU}\\ +~~~~~~class\_of\_service:~{\mdcolor{purple}2}\\ +~~~~~~packet\_length\_bytes:~{\mdcolor{purple}4096}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4200} +\noindent\mdline{4200}As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type \mdline{4204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4204}~[\mdcite{psatranslation}{24}]\mdline{4204}). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes.%mdk + +%mdk-data-line={4209} +\mdline{4209}The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port \mdline{4210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfffffffd}}}\mdline{4210}; see +\mdline{4211}\mdref{sec-translation-of-port-numbers}{Translation of Port Numbers}\mdline{4211}). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port.%mdk + +%mdk-data-line={4214} +\mdline{4214}If the \mdline{4214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4214} data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created.%mdk + +%mdk-data-line={4217} +\mdline{4217}A clone session may be inserted, modified or deleted as per the following +semantics:%mdk + +%mdk-data-line={4220} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4220} +\item\mdline{4220}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4220}: Add a new clone session entry bound to a set of egress ports and +replica IDs. The \mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4221} is a \mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4221} and must be greater than 0 (see +explanation\mdline{4222}~\mdref{sec-valid-values-for-session-id}{below}\mdline{4222}), or the P4Runtime +server must return an \mdline{4223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4223} error. The replica \mdline{4223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4223} ID is +also a \mdline{4224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4224}, and its value may not exceed the maximum allowed by the +target for the \mdline{4225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4225} type (0 is allowed), or the server must also +return an \mdline{4226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4226} error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (\mdline{4229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}class\_of\_service}}}\mdline{4229} field). This value must be a valid +value for the PSA \mdline{4230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ClassOfService\_t}}}\mdline{4230} type, which supports runtime translation +by default\mdline{4231}~[\mdcite{psatranslation}{24}]\mdline{4231}, or the server must return +\mdline{4232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4232}. See\mdline{4232}~\mdref{sec-translation-of-port-numbers}{PSA Metadata +Translation}\mdline{4233} for more information. The +\mdline{4234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4234} field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +\mdline{4236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4236} field is 0 (default), no truncation on the clone will be +performed.%mdk + +%mdk-data-line={4238} +\item\mdline{4238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4238}: Modify the attributes of a given clone session entry, indexed by the +given \mdline{4239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4239}. Same restrictions as \mdline{4239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4239} apply here.%mdk + +%mdk-data-line={4240} +\item\mdline{4240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4240}: Delete the clone session indexed by the given +\mdline{4241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4241}. Other fields need not be provided for this operation. Any +packet with their \mdline{4242}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4242} metadata in the data plane set to the +deleted \mdline{4243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4243} will no longer be cloned.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4245} +\noindent\mdline{4245}When reading a clone session, only \mdline{4245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4245} is considered. All other fields +in \mdline{4246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4246} are ignored. To perform a \mdline{4246}\emph{wildcard}\mdline{4246} \mdline{4246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4246} on all +configured clone session entries, the \mdline{4247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4247} field must be set to 0, its +default value. The \mdline{4248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4248} field can never be equal to 0 in a \mdline{4248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4248} +RPC. If it does, the server must return an \mdline{4249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4249} error.%mdk + +%mdk-data-line={4251} +\paragraph{\mdline{4251}9.5.2.1.\hspace*{0.5em}\mdline{4251}Valid Values for \mdline{4251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}}\label{sec-valid-values-for-session-id}%mdk%mdk + +%mdk-data-line={4253} +\noindent\mdline{4253}The PSA specification states that the valid \mdline{4253}\emph{data plane}\mdline{4253} values for clone +session ids (\mdline{4254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4254}) range from 0 to the maximum value supported by +the target\mdline{4255}~[\mdcite{psatranslation}{24}]\mdline{4255}. Note that unlike for\mdline{4255}~\mdref{sec-valid-values-for-mg-id}{multicast group +ids}\mdline{4256}, 0 is a valid \mdline{4256}\emph{data plane}\mdline{4256} value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special \mdline{4258}\emph{wildcard}\mdline{4258} value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a \mdline{4259}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4259} +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is \mdline{4261}\emph{not}\mdline{4261} enabled, we effectively +\mdline{4262}\textquotedblleft{}lose\textquotedblright{}\mdline{4262} one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (\mdline{4263}e.g.\mdline{4263} because the target supports a very +limited number of clone sessions), one can enable translation on +\mdline{4265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4265} and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id.%mdk + +%mdk-data-line={4268} +\subsection{\mdline{4268}9.6.\hspace*{0.5em}\mdline{4268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}\label{sec-valuesetentry}%mdk%mdk + +%mdk-data-line={4270} +\noindent\mdline{4270}Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the \mdline{4274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4274} state.%mdk + +%mdk-data-line={4276} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4277} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}state}}~parse\_l2~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}(MAX\_TRILL\_TYPES)~trill\_types;}\\ +~~extract(hdr.ethernet);\\ +~~{\bfseries{\mdcolor{navy}select}}~(hdr.ethernet.eth\_type)~\{\\ +~~~~ETH\_TYPE\_IPV4:~parse\_ipv4;\\ +~~~~ETH\_TYPE\_IPV6:~parse\_ipv6;\\ +~~~~trill\_types:~~~parse\_trill\_types;\\ +~~~~\_:~~~~~~~~~~~~~reject;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4289} +\noindent\mdline{4289}The corresponding entry in the P4Info for this Value Set is:%mdk + +%mdk-data-line={4291} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4292} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}trill\_types}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~\textless{}MAX\_TRILL\_TYPES\textgreater{}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4306} +\noindent\mdline{4306}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4309} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4310} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x22f3}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x893b}~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4328} +\noindent\mdline{4328}As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the \mdline{4330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4330} state.%mdk + +%mdk-data-line={4332} +\mdline{4332}A \mdline{4332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4332} entity update message has the following fields:%mdk + +%mdk-data-line={4334} +\begin{itemize}%mdk + +%mdk-data-line={4334} +\item{} +%mdk-data-line={4334} +\mdline{4334}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4334} is the \mdline{4334}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4334} identifier of the Value Set instance, as +defined in P4Info.%mdk%mdk + +%mdk-data-line={4337} +\item{} +%mdk-data-line={4337} +\mdline{4337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4337} is a repeated field of type \mdline{4337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4337}. When \mdline{4337}\textquotedblleft{}selecting\textquotedblright{}\mdline{4337} +against a Value Set, every member will be considered and if at least one +\mdline{4339}\textquotedblleft{}matches\textquotedblright{}\mdline{4339}, the corresponding parser transition will be taken. Each +\mdline{4340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4340} contains a repeated field of \mdline{4340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4340} messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a \mdline{4342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4342} if and only if +it matches all its \mdline{4343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4343} messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. \mdline{4345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4345} messages in a \mdline{4345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4345} follow +the\mdline{4346}~\mdref{sec-match-format}{same rules}\mdline{4346} as in a \mdline{4346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4346}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4348} +\noindent\mdline{4348}A \mdline{4348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4348} may only be modified. If the update type is \mdline{4348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4348} or +\mdline{4349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4349}, the server must return an \mdline{4349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4349} error. If the update type +is \mdline{4350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4350}, the server writes the members given in the repeated field to the +Value Set entry indexed by the given \mdline{4351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4351}. The maximum number of +matches must not exceed the maximum size given by the \mdline{4352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{4352} field in P4Info of +the Value Set, otherwise the server must return a \mdline{4353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4353} error. To +empty a Value Set (\mdline{4354}i.e.\mdline{4354} restore it to its initial state), the P4Runtime client +can perform a \mdline{4355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4355} update with an empty \mdline{4355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4355} repeated field.%mdk + +%mdk-data-line={4357} +\mdline{4357}To facilitate\mdline{4357}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{4357}, the server must +return an \mdline{4358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4358} error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set.%mdk + +%mdk-data-line={4364} +\mdline{4364}See Appendix\mdline{4364}~\mdref{sec-value-set-example}{A.3}\mdline{4364} for a more complex Value Set example.%mdk + +%mdk-data-line={4366} +\subsection{\mdline{4366}9.7.\hspace*{0.5em}\mdline{4366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}\label{sec-registerentry}%mdk%mdk + +%mdk-data-line={4368} +\noindent\mdline{4368}The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The \mdline{4369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4369} P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations.%mdk + +%mdk-data-line={4373} +\mdline{4373}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4373} has the following fields:%mdk + +%mdk-data-line={4375} +\begin{itemize}%mdk + +%mdk-data-line={4375} +\item{} +%mdk-data-line={4375} +\mdline{4375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4375}, which identifies the PSA Register extern instance which is +being accessed by the client; the \mdline{4376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4376} is specified by the P4Info +message.%mdk%mdk + +%mdk-data-line={4379} +\item{} +%mdk-data-line={4379} +\mdline{4379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4379}, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the \mdline{4381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4381} message +used for the request. When an \mdline{4382}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4382} is provided , the server must validate +its value, and return \mdline{4383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4383} for a negative index or +\mdline{4384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4384} if the index exceeds the size of the register array.%mdk%mdk + +%mdk-data-line={4386} +\item{} +%mdk-data-line={4386} +\mdline{4386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4386}: the data to be written to the array (if \mdline{4386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4386} is part of a +\mdline{4387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4387} message) or the data read from the array (if \mdline{4387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4387} is +part of a \mdline{4388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4388} message). The \mdline{4388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4388} field is a \mdline{4388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{4388} message and +must match the format described by the \mdline{4389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{4389} field of the corresponding +Register entry in the P4Info, or the server must return an \mdline{4390}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4390} +error.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4393} +\subsection{\mdline{4393}9.8.\hspace*{0.5em}\mdline{4393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}\label{sec-digestentry}%mdk%mdk + +%mdk-data-line={4395} +\noindent\mdline{4395}A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly.%mdk + +%mdk-data-line={4400} +\mdline{4400}The \mdline{4400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4400} P4Runtime entity is used to \mdline{4400}\textbf{configure}\mdline{4400} how the device must +generate digest messages. The \mdline{4401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4401} Protobuf message is not used to +carry digest data, which is done on the \mdline{4402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4402} bidirectional stream +using the \mdline{4403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4403} (digest data sent by the target to the client) and +\mdline{4404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4404} (digest data acknowledgments sent by the client to the target) +Protobuf messages.%mdk + +%mdk-data-line={4407} +\mdline{4407}In this section, we refer to the data learned by a single data plane call to +\mdline{4408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}T\textgreater{}::pack}}}\mdline{4408} as a \mdline{4408}\textquotedblleft{}digest message\textquotedblright{}\mdline{4408} and we use \mdline{4408}\textquotedblleft{}digest list\textquotedblright{}\mdline{4408} to designate +the list of digest messages bundled by the P4Runtime service in a single +\mdline{4410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4410} stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are \mdline{4412}\textquotedblleft{}duplicate\textquotedblright{}\mdline{4412} if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are \mdline{4413}\textquotedblleft{}distinct\textquotedblright{}\mdline{4413} +if they are not duplicate.%mdk + +%mdk-data-line={4416} +\mdline{4416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4416} has the following fields:%mdk + +%mdk-data-line={4418} +\begin{itemize}%mdk + +%mdk-data-line={4418} +\item{} +%mdk-data-line={4418} +\mdline{4418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4418}, which identifies the PSA Digest extern instance which emitted the +data; the \mdline{4419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4419} is determined by the P4Info message.%mdk%mdk + +%mdk-data-line={4421} +\item{} +%mdk-data-line={4421} +\mdline{4421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4421}, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +\mdline{4423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4423}; these parameters are:%mdk + +%mdk-data-line={4425} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4425} +\item\mdline{4425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4425}: the maximum server buffering delay in nanoseconds for an +outstanding digest message.%mdk + +%mdk-data-line={4427} +\item\mdline{4427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4427}: the maximum digest list size\mdline{4427} \mdline{4427}\textemdash{}\mdline{4427} in number of digest +messages\mdline{4428} \mdline{4428}\textemdash{}\mdline{4428} sent by the server to the client as a single \mdline{4428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4428} +Protobuf message.%mdk + +%mdk-data-line={4430} +\item\mdline{4430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4430}: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4434} +\noindent\mdline{4434}Here is the significance of the different \mdline{4434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4434} types for \mdline{4434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4434}:%mdk + +%mdk-data-line={4436} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4436} +\item\mdline{4436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4436}: Enable server generation of \mdline{4436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4436} messages for given digest +instance and use provided configuration parameters.%mdk + +%mdk-data-line={4438} +\item\mdline{4438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4438}: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance.%mdk + +%mdk-data-line={4440} +\item\mdline{4440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4440}: Disable server generation of \mdline{4440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4440} messages for given digest +instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4443} +\noindent\mdline{4443}A server should buffer digest messages until either:%mdk + +%mdk-data-line={4445} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4445} +\item\mdline{4445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4445} time has passed since the first digest message was added to +the empty buffer, or%mdk + +%mdk-data-line={4447} +\item\mdline{4447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4447} \mdline{4447}\emph{distinct}\mdline{4447} digest messages have been received from the +data plane and added to the buffer%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4450} +\noindent\mdline{4450}At which point the server should, with best effort, generate a \mdline{4450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4450} +stream message with the buffer contents and send it to the master client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software.%mdk + +%mdk-data-line={4456} +\mdline{4456}To avoid sending duplicate digest messages across different \mdline{4456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4456} +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the master client indicates that it has received the +digest list and acted on it. The server must keep a \mdline{4459}\textquotedblleft{}cache\textquotedblright{}\mdline{4459} containing the set +of all digest messages that have been sent, but not acknowledged yet by the +master client, up-to \mdline{4461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4461} in the past. The server must delete all +cache entries for a given digest list when they are at least \mdline{4462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4462} +old or when a matching \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4463} message (\mdline{4463}i.e.\mdline{4463} with the same \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4463} +and \mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}list\_id}}}\mdline{4464} fields as the \mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4464} message) is received.%mdk + +%mdk-data-line={4466} +\mdline{4466}The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged \mdline{4471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4471} messages.%mdk + +%mdk-data-line={4473} +\mdline{4473}When \mdline{4473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4473} is set to 0 and / or \mdline{4473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4473} is set to 1, the +server should, with best effort, generate a \mdline{4474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4474} message for every +digest message generated by the data plane which is not already in the cache. If +\mdline{4476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4476} is set to 0, the cache must always be an empty set. If +\mdline{4477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4477} is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +\mdline{4479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4479} configuration parameter.%mdk + +%mdk-data-line={4481} +\mdline{4481}The P4Runtime server may empty the digest message cache in case of a client +mastership change.%mdk + +%mdk-data-line={4484} +\mdline{4484}Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server:%mdk + +%mdk-data-line={4487} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4488} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestStream~stream;\\ +DigestCache~cache;\\ +DigestBuffer~buffers;\\ +\\ +{\mdcolor{darkgreen}//~sends~digest~list~when~it~is~ready}\\ +send\_buffer(Id~digest\_id)~\{\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~stream.write(DigestList(buffer));\\ +~~cache.merge(buffer);~~{\mdcolor{darkgreen}//~updates~cache~with~new~digest~list}\\ +~~buffer.clear();\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~data~plane~digest~messages~from~device}\\ +handle\_dataplane\_digest(Digest~msg)~\{\\ +~~digest\_id~=~msg.digest\_id();\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~{\bfseries{\mdcolor{navy}if}}~(msg~in~cache~{\mdcolor{teal}OR}~msg~in~buffer)~{\bfseries{\mdcolor{navy}return}};\\ +~~buffer.enqueue(msg);\\ +~~{\bfseries{\mdcolor{navy}if}}~(buffer.length()~\textless{}~max\_list\_size(digest\_id))~{\bfseries{\mdcolor{navy}return}};\\ +~~send\_buffer(digest\_id);\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~ack~messages~received~on~the~stream}\\ +handle\_stream\_ack(DigestListAck~ack)~\{\\ +~~{\mdcolor{darkgreen}//~clear~all~cache~entries~matching~the~tuple~(digest\_id,~list\_id)}\\ +~~cache.erase(~(ack.digest\_id(),~ack.list\_id()~)\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~loop~to~enforce~timeouts}\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~now~=~now();\\ +~~{\mdcolor{darkgreen}//~check~for~buffers~that~need~to~be~sent}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~buffer)~in~buffers)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~buffer.first\_enq\_time()~\textgreater{}=~max\_timeout\_ns(digest\_id))\\ +~~~~~~send\_buffer(buffer\_id);\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~check~for~expired~entries~in~cache}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~list\_id,~sent\_time)~in~cache)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~sent\_time~\textgreater{}=~ack\_timeout\_ns(digest\_id))\\ +~~~~~~cache.erase(~(digest\_id,~list\_id)~);\\ +~~\}\\ +~~sleep({\mdcolor{teal}X});\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4533} +\subsection{\mdline{4533}9.9.\hspace*{0.5em}\mdline{4533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\label{sec-extern-entry}%mdk%mdk + +%mdk-data-line={4535} +\noindent\mdline{4535}This is used to support a P4 extern entity that is not part of PSA. It is +defined as:%mdk + +%mdk-data-line={4538} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4539} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ExternEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_type\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~google.protobuf.Any~entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4546} +\noindent\mdline{4546}Each \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4546} entity maps to an \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{4546} message in the +\mdline{4547}\mdref{sec-p4info-extern}{P4Info}\mdline{4547} and an \mdline{4547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4547} message within that +message. The \mdline{4548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{4548} field must be equal to the one in +\mdline{4549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4549}. The \mdline{4549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_id}}}\mdline{4549} field must be equal to the ID included in the +\mdline{4550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{4550} of the corresponding \mdline{4550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4550} message.%mdk + +%mdk-data-line={4552} +\mdline{4552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entry}}}\mdline{4552} itself is embedded as an \mdline{4552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{4552} Protobuf message\mdline{4552}~[\mdcite{protoany}{31}]\mdline{4552} to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on\mdline{4556}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{4557} for more information.%mdk + +%mdk-data-line={4559} +\section{\mdline{4559}10.\hspace*{0.5em}\mdline{4559}Error Reporting Messages}\label{sec-error-reporting-messages}%mdk%mdk + +%mdk-data-line={4561} +\noindent\mdline{4561}P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case.%mdk + +%mdk-data-line={4565} +\mdline{4565}gRPC uses \mdline{4565}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4565}~[\mdcite{grpcstatus}{32}]\mdline{4565} to represent the status returned by an +RPC. It has 3 attributes:%mdk + +%mdk-data-line={4568} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4569} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StatusCode~code\_;\\ +{\mdcolor{navy}grpc::}string~error\_message\_;\\ +{\mdcolor{navy}grpc::}string~binary\_error\_details\_;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4574} +\noindent\mdline{4574}The \mdline{4574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4574} represents a canonical error\mdline{4574}~[\mdcite{grpcstatuscodes}{34}]\mdline{4574} and describes the +overall RPC status. The \mdline{4575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4575} is a developer-facing error message, +which should be in English. The \mdline{4576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}binary\_error\_details\_}}}\mdline{4576} carries a serialized +\mdline{4577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4577} message\mdline{4577}~[\mdcite{protostatus}{28}]\mdline{4577} message, which has 3 fields:%mdk + +%mdk-data-line={4579} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4580} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}int32}}~code~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~see~code.proto}\\ +{\bfseries{\mdcolor{navy}string}}~{\bfseries{\mdcolor{navy}message}}~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +{\bfseries{\mdcolor{navy}repeated}}~google.protobuf.Any~details~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4585} +\noindent\mdline{4585}The code and message fields must be the same as \mdline{4585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4585} and \mdline{4585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4585} +fields from \mdline{4586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4586} above. The \mdline{4586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{4586} field is a list that consists of +\mdline{4587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4587} messages that carry error details for individual elements inside +batch-request RPCs (\mdline{4588}e.g.\mdline{4588} \mdline{4588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4588} and \mdline{4588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4588}). \mdline{4588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4588} includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices\mdline{4592}~[\mdcite{grpcstatuscodes}{34}]\mdline{4592}.%mdk + +%mdk-data-line={4594} +\mdline{4594}Figure\mdline{4594}~\mdref{fig-error-report}{\mdcaptionlabel{7}}\mdline{4594} illustrates how these messages fit together.%mdk + +%mdk-data-line={4596} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={4597} +\noindent\mdline{4597}\includegraphics[keepaspectratio=true,width=\dimwidth{0.70}]{build/error-report}{}\mdline{4597}%mdk + +%mdk-data-line={4598} +\mdhr{}%mdk + +%mdk-data-line={4599} +\noindent\mdline{4599}\mdcaption{\textbf{Figure~\mdcaptionlabel{7}.}~\mdcaptiontext{P4Runtime Error Report Message Format}}%mdk +%mdk +\end{mdcenter}\label{fig-error-report}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={4601} +\noindent\mdline{4601}gRPC provides utility functions \mdline{4601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExtractErrorDetails()}}}\mdline{4601} and \mdline{4601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetErrorDetails()}}}\mdline{4601} +\mdline{4602}[\mdcite{grpcerrordetails}{33}]\mdline{4602} to easily convert between \mdline{4602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4602} and +\mdline{4603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4603}.%mdk + +%mdk-data-line={4605} +\mdline{4605}Please see sections on individual P4Runtime RPCs for details on how +\mdline{4606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4606} is populated for reporting errors.%mdk + +%mdk-data-line={4608} +\mdline{4608}Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on\mdline{4611}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{4612} for more information.%mdk + +%mdk-data-line={4614} +\section{\mdline{4614}11.\hspace*{0.5em}\mdline{4614}Atomicity of Individual \mdline{4614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4614} and \mdline{4614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4614} Operations}\label{sec-atomicity-of-individual-write-and-read-operations}%mdk%mdk + +%mdk-data-line={4616} +\noindent\mdline{4616}Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane \mdline{4617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4617} +operation, and every single \mdline{4618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4618} operation on a table that inserts, deletes, +or modifies one table entry, the \mdline{4619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4619} operation should behave as if that +\mdline{4620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4620} operation has not yet occurred, or as if the \mdline{4620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4620} operation is +complete. The P4 program should never behave as if the \mdline{4621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4621} operation is +partially complete. These guarantees also apply to extern instances: \mdline{4622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4622} and +\mdline{4623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4623} operations on extern entities must execute atomically relative to extern +data plane methods.%mdk + +%mdk-data-line={4626} +\mdline{4626}The atomicity guarantees provided by P4Runtime for individual \mdline{4626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4626} and \mdline{4626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4626} +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification\mdline{4628}~[\mdcite{psaatomicityofcontrolplaneops}{23}]\mdline{4628}.%mdk + +%mdk-data-line={4630} +\mdline{4630}The P4\mdline{4630}\mdsub{16}\mdline{4630} language introduces an \mdline{4630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4630} annotation\mdline{4630}~[\mdcite{p4concurrency}{14}]\mdline{4630}, to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the \mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4632} annotation for \mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4632} +operations, as well as\mdline{4633}~\mdref{wildcard-reads}{non-wildcard \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} operations}\mdline{4633}, +relative to data plane execution. Consider the following P4 example written for +PSA:%mdk + +%mdk-data-line={4637} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4638} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024)~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\mdcolor{darkgreen}//~...}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~Value\_t~v~=~r1.read((Index\_t){\mdcolor{purple}1});\\ +~~~~~~~~v~=~v~+~{\mdcolor{purple}1};\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~v);\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4654} +\noindent\mdline{4654}If a P4Runtime server is processing messages which write to Register \mdline{4654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4654} at +index \mdline{4655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}1}}}\mdline{4655}, these writes must not happen between the data plane \mdline{4655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}read}}}\mdline{4655} and +\mdline{4656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}write}}}\mdline{4656}.%mdk + +%mdk-data-line={4658} +\mdline{4658}Now let\mdline{4658}'\mdline{4658}s consider the following example:%mdk + +%mdk-data-line={4660} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4661} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024,~(Value\_t){\mdcolor{purple}0}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~initial~value~}{\mdcolor{darkgreen}*/})~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}100});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}100});\\ +~~~~\}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}200});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}200});\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4679} +\noindent\mdline{4679}If a P4Runtime client issues a \mdline{4679}\emph{wildcard}\mdline{4679} \mdline{4679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4679} on Register \mdline{4679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4679}, there is no +guarantee that \mdline{4680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]~==~r1{}[2]}}}\mdline{4680} in the response, as the read for \mdline{4680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4680} may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for \mdline{4682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4682} may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read \mdline{4684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4684} and \mdline{4684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4684} separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +\mdline{4687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4687} message) of individual read requests. Similar to a batch +\mdline{4688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4688}, a wildcard read of a register can execute the reads of the +register array elements (\mdline{4689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4689}, \mdline{4689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4689}, \mdline{4689}\dots{}\mdline{4689}) in an arbitrary order relative +to each other.%mdk + +%mdk-data-line={4692} +\mdline{4692}If the \mdline{4692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4692} annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program.%mdk + +%mdk-data-line={4696} +\section{\mdline{4696}12.\hspace*{0.5em}\mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4696} RPC}\label{sec-write-rpc}%mdk%mdk + +%mdk-data-line={4698} +\noindent\mdline{4698}The \mdline{4698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4698} RPC updates one or more P4 entities on the target. The request is +defined as follows:%mdk + +%mdk-data-line={4701} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4702} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~WriteRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint64}}~role\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Update~updates~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\bfseries{\mdcolor{navy}enum}}~Atomicity~\{\\ +~~~~CONTINUE\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~ROLLBACK\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~DATAPLANE\_ATOMIC~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~\}\\ +~~Atomicity~atomicity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4716} +\noindent\mdline{4716}The \mdline{4716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4716} uniquely identifies the target P4 device. The \mdline{4716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4716} and +\mdline{4717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4717} define the client role and election-id as described in the +\mdline{4718}\mdref{sec-master-slave-arbitration-and-controller-replication}{Master-Slave Arbitration and Controller +Replication}\mdline{4719} +section. The server is expected to perform the following checks (in this order) +before processing the \mdline{4721}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}updates}}}\mdline{4721} list:%mdk + +%mdk-data-line={4723} +\begin{enumerate}%mdk + +%mdk-data-line={4723} +\item{} +%mdk-data-line={4723} +\mdline{4723}If \mdline{4723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4723} does not match any of the devices known to the P4Runtime +server or if \mdline{4724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4724} does not match any of the roles for the device, the +server must return a \mdline{4725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4725} error.%mdk%mdk + +%mdk-data-line={4727} +\item{} +%mdk-data-line={4727} +\mdline{4727}If the client is not the master for (\mdline{4727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4727}, \mdline{4727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4727}) according to the +\mdline{4728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4728} value, the server must return a \mdline{4728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4728} error.%mdk%mdk + +%mdk-data-line={4730} +\item{} +%mdk-data-line={4730} +\mdline{4730}If the \mdline{4730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4730} is attempted before a \mdline{4730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4730} has been set, +the server must return a \mdline{4731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{4731} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4733} +\noindent\mdline{4733}The updates field is a list of P4 entity updates to be applied. Each update is +defined as:%mdk + +%mdk-data-line={4736} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4737} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Update~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Type~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~INSERT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~MODIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DELETE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~Type~type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Entity~entity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4749} +\noindent\mdline{4749}This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a \mdline{4750}\emph{logical}\mdline{4750} table (\mdline{4750}e.g.\mdline{4750} +\mdline{4751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4751}) or an actual table (\mdline{4751}e.g.\mdline{4751} \mdline{4751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4751}) in the P4 data +plane. Each entity in the container is uniquely identified by its \mdline{4752}\emph{key}\mdline{4752}. Please +refer to the\mdline{4753}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4753} section for details on +what parts of the entity specification make up the \mdline{4754}\emph{key}\mdline{4754} for each P4 entity.%mdk + +%mdk-data-line={4756} +\mdline{4756}An update can be one of the following types:%mdk + +%mdk-data-line={4758} +\begin{itemize}%mdk + +%mdk-data-line={4758} +\item{} +%mdk-data-line={4758} +\mdline{4758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4758}: Inserts the given P4 entity in the entity container. +The \mdline{4759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{4759} field always specifies the full state of the P4 entity. +If the entity already exists, an \mdline{4760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4760} error is returned, and +the existing entity remains unchanged. +If the entity is malformed, an \mdline{4762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4762} error is returned. +If the entity cannot be inserted because the container is already full, +a \mdline{4764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4764} error is returned.%mdk%mdk + +%mdk-data-line={4766} +\item{} +%mdk-data-line={4766} +\mdline{4766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4766}: Modifies the P4 entity to its new specified state. This uses +\mdline{4767}\emph{assign}\mdline{4767} or \mdline{4767}\emph{full-snapshot}\mdline{4767} semantics, \mdline{4767}i.e.\mdline{4767} the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an \mdline{4769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4769} error is usually returned (unless a +more specific error code applies\mdline{4770}~[\mdcite{grpcstatuscodes}{34}]\mdline{4770}). If the entity does not +exist, a \mdline{4771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4771} error is returned.%mdk%mdk + +%mdk-data-line={4773} +\item{} +%mdk-data-line={4773} +\mdline{4773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4773}: Deletes the specified P4 entity. If the entity does not exist, a +\mdline{4774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4774} error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4777} +\noindent\mdline{4777}If an update is not allowed under the given controller role, the server must +return a \mdline{4778}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4778} error for this update.%mdk + +%mdk-data-line={4780} +\subsection{\mdline{4780}12.1.\hspace*{0.5em}\mdline{4780}Batching and Ordering of Updates}\label{sec-batching-and-ordering-of-updates}%mdk%mdk + +%mdk-data-line={4782} +\noindent\mdline{4782}P4Runtime supports batching of \mdline{4782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4782} operations. The list of updates in a +\mdline{4783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4783} is referred to as a \mdline{4783}\emph{batch}\mdline{4783}. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of \mdline{4785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4785} entities).%mdk + +%mdk-data-line={4787} +\mdline{4787}The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +\mdline{4789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4789}s can also be processed interleaved and/or in parallel. +However, \mdline{4790}\textbf{the processing of requests must be strictly serializable}\mdline{4790}. That +is, given a history \mdline{4791}$S$\mdline{4791} of \mdline{4791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4791}s including the responses to those +requests, there must exist an order \mdline{4792}$L$\mdline{4792} for all updates in \mdline{4792}$S$\mdline{4792}, such that:%mdk + +%mdk-data-line={4794} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4794} +\item\mdline{4794}All updates from the same write request must appear as a contiguous +subsequence in \mdline{4795}$L$\mdline{4795}, but the order within that subsequence can be arbitrary.%mdk + +%mdk-data-line={4796} +\item\mdline{4796}For two updates \mdline{4796}$u_1$\mdline{4796} and \mdline{4796}$u_2$\mdline{4796}, if the write request containing \mdline{4796}$u_1$\mdline{4796} +completed before the write request of \mdline{4797}$u_2$\mdline{4797} was sent, then \mdline{4797}$u_1$\mdline{4797} must appear +before \mdline{4798}$u_2$\mdline{4798} in \mdline{4798}$L$\mdline{4798}.%mdk + +%mdk-data-line={4799} +\item\mdline{4799}Executing all updates in \mdline{4799}$L$\mdline{4799} sequentially must yield the same response for +every update as in \mdline{4800}$S$\mdline{4800}.%mdk + +%mdk-data-line={4801} +\item\mdline{4801}The observable state of the switch after \mdline{4801}$S$\mdline{4801} (\mdline{4801}e.g.\mdline{4801}, through the \mdline{4801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4801} RPC) +is identical to the one obtained by sequentially executing \mdline{4802}$L$\mdline{4802}.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4804} +\noindent\mdline{4804}The \mdline{4804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4804} RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the \mdline{4805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4805} RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (\mdline{4808}e.g.\mdline{4808} inserting an \mdline{4808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4808} +followed by pointing a \mdline{4809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4809} to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding \mdline{4811}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4811} RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate \mdline{4815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4815} calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each \mdline{4816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4816} call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one.%mdk + +%mdk-data-line={4821} +\subsection{\mdline{4821}12.2.\hspace*{0.5em}\mdline{4821}Batch Atomicity}\label{sec-batch-atomicity}%mdk%mdk + +%mdk-data-line={4823} +\noindent\mdline{4823}A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the \mdline{4824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4824} +enum. A P4Runtime server is required to support only the modes marked as +\mdline{4826}\emph{Required}\mdline{4826} below:%mdk + +%mdk-data-line={4828} +\begin{itemize}%mdk + +%mdk-data-line={4828} +\item{} +%mdk-data-line={4828} +\mdline{4828}\emph{Required}\mdline{4828}: \mdline{4828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4828}: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that \mdline{4832}\emph{see}\mdline{4832} each of +these intermediate stages.%mdk%mdk + +%mdk-data-line={4835} +\item{} +%mdk-data-line={4835} +\mdline{4835}\emph{Optional}\mdline{4835}: \mdline{4835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ROLLBACK\_ON\_ERROR}}}\mdline{4835}: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is \mdline{4839}\emph{all-or-none}\mdline{4839}, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that \mdline{4843}\emph{see}\mdline{4843} each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure.%mdk + +%mdk-data-line={4848} +\mdline{4848}If a P4Runtime server does not support this option at all, an +\mdline{4849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4849} error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (\mdline{4850}e.g.\mdline{4850} it is +more straightforward to implement batches that contain only \mdline{4851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4851} +operations, vs. those that contain \mdline{4852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4852} operations), an +\mdline{4853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4853} error is returned when the batch cannot be executed +in a data plane-atomic way.%mdk%mdk + +%mdk-data-line={4856} +\item{} +%mdk-data-line={4856} +\mdline{4856}\emph{Optional}\mdline{4856}: \mdline{4856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4856}: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +\mdline{4860}\emph{transaction}\mdline{4860}. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane\mdline{4862}'\mdline{4862}s table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table.%mdk + +%mdk-data-line={4869} +\mdline{4869}If a P4Runtime server does not support this option at all, an \mdline{4869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4869} +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an \mdline{4871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4871} error is returned when the batch +cannot be executed in a data plane-atomic way.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4874} +\noindent\mdline{4874}There is no expectation that a given client must always use the same \mdline{4874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4874} +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use \mdline{4877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4877} at one time and default behavior +(\mdline{4878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4878}) at other times.%mdk + +%mdk-data-line={4880} +\subsection{\mdline{4880}12.3.\hspace*{0.5em}\mdline{4880}Error Reporting}\label{sec-error-reporting}%mdk%mdk + +%mdk-data-line={4882} +\noindent\mdline{4882}Please see section\mdline{4882}~\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{4882} for +information on error reporting messages and guidelines. P4Runtime server will +populate \mdline{4884}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4884} as follows:%mdk + +%mdk-data-line={4886} +\begin{enumerate}%mdk + +%mdk-data-line={4886} +\item{} +%mdk-data-line={4886} +\mdline{4886}If all batch updates succeeded, set \mdline{4886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4886} to \mdline{4886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4886} and do not +populate any other field.%mdk%mdk + +%mdk-data-line={4889} +\item{} +%mdk-data-line={4889} +\mdline{4889}If an error is encountered before even trying to attempt individual batch +updates, set \mdline{4890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4890} that best describes that RPC-wide +error. For example, use \mdline{4891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNAVAILABLE}}}\mdline{4891} if the P4Runtime service is not yet +ready to handle requests. Set \mdline{4892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4892} to describe the issue. Do not +set \mdline{4893}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_details}}}\mdline{4893} in this case.%mdk%mdk + +%mdk-data-line={4895} +\item{} +%mdk-data-line={4895} +\mdline{4895}Otherwise, if one or more updates in the batch (\mdline{4895}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest.updates}}}\mdline{4895}) +failed, set \mdline{4896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4896} to \mdline{4896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{4896}. For example, one update in +the batch may fail with \mdline{4897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4897} and another with +\mdline{4898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4898}. A \mdline{4898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4898} message is used to capture the status of +each and every update in the batch. The number of \mdline{4899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4899} messages packed +into \mdline{4900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{4900} field should therefore always match the +number of updates in the \mdline{4901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4901}, and the order of +\mdline{4902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4902} messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +\mdline{4904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4904} should set the code to \mdline{4904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4904} and omit other fields.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4906} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4907} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}\#~Example~of~a~grpc::Status~returned~for~a~Write~RPC~with~a~batch~of~3~updates.}\\ +{\mdcolor{darkgreen}\#~The~first~and~third~updates~encountered~an~error,~while~the~second~update}\\ +{\mdcolor{darkgreen}\#~succeeded.}\\ +code\_~=~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +error\_message\_~=~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +binary\_error\_details~\{\\ +~~code:~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}8}~~{\mdcolor{darkgreen}\#~RESOURCE\_EXHAUSTED}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Table~is~full.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}500}~~{\mdcolor{darkgreen}\#~ERR\_TABLE\_FULL}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}0}~~{\mdcolor{darkgreen}\#~OK}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}6}~~{\mdcolor{darkgreen}\#~ALREADY\_EXISTS}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Entity~already~exists.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}600}~~{\mdcolor{darkgreen}\#~ERR\_ENTITY\_ALREADY\_EXISTS}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4933} +\section{\mdline{4933}13.\hspace*{0.5em}\mdline{4933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4933} RPC}\label{sec-read-rpc}%mdk%mdk + +%mdk-data-line={4935} +\noindent\mdline{4935}The \mdline{4935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4935} RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as:%mdk + +%mdk-data-line={4938} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4939} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4945} +\noindent\mdline{4945}The \mdline{4945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4945} uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +\mdline{4947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4947} error. The \mdline{4947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{4947} repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server.%mdk + +%mdk-data-line={4950} +\mdline{4950}Since \mdline{4950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4950}s do not mutate any state on the switch, they do not +require an \mdline{4951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4951}, and they do not require the presence of an open +\mdline{4952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4952} between the server and client.%mdk + +%mdk-data-line={4954} +\mdline{4954}The \mdline{4954}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read~}}}\mdline{4954}response consists of a sequence of messages (a gRPC \mdline{4954}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}stream}}}\mdline{4954}) with +each message defined as:%mdk + +%mdk-data-line={4957} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4958} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadResponse~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4963} +\noindent\mdline{4963}The \mdline{4963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{4963} repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the \mdline{4967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Finish()}}}\mdline{4967} method on the stream object +\mdline{4968}[\mdcite{grpcstreamc}{10}]\mdline{4968}).%mdk + +%mdk-data-line={4970} +\subsection{\mdline{4970}13.1.\hspace*{0.5em}\mdline{4970}Nomenclature}\label{sec-nomenclature}%mdk%mdk + +%mdk-data-line={4972} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries request}}%mdk + +%mdk-data-line={4972} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{4972}An element of the \mdline{4972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{4972} repeated field. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries batch}}%mdk + +%mdk-data-line={4974} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{4974}Refers to the \mdline{4974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{4974} repeated field.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={4977} +\noindent\mdline{4977}Each \mdline{4977}\emph{request}\mdline{4977} acts as a query filter for that entity type. If a \mdline{4977}\emph{request}\mdline{4977} fully +specifies the entity key, the \mdline{4978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4978} operation should retrieve a single P4 +entity. Please refer to the\mdline{4979}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4979} section +for details on what parts of the entity specification make up the entity \mdline{4980}\emph{key}\mdline{4980}.%mdk + +%mdk-data-line={4982} +\subsection{\mdline{4982}13.2.\hspace*{0.5em}\mdline{4982}Wildcard Reads}\label{sec-wildcard-reads}%mdk%mdk + +%mdk-data-line={4984} +\noindent\mdline{4984}P4Runtime allows wildcard read of P4 entities. A \mdline{4984}\emph{request}\mdline{4984} may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the\mdline{4986}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4986} section for details on +what parts of the entity can be wildcarded in a given \mdline{4987}\emph{request}\mdline{4987}.%mdk + +%mdk-data-line={4989} +\mdline{4989}For example, in a \mdline{4989}\emph{request}\mdline{4989} of type \mdline{4989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4989}:%mdk + +%mdk-data-line={4991} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4991} +\item\mdline{4991}A default \mdline{4991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4991} (0) implies a request to read all counter-entries for +all indirect counters.%mdk + +%mdk-data-line={4993} +\item\mdline{4993}A particular (non-default) \mdline{4993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4993} in conjunction with \mdline{4993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4993} unset +implies a request to read all counter-entries for the given indirect counter +ID.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4997} +\noindent\mdline{4997}To read the entire forwarding state for a given device, the P4Runtime client can +generate the following \mdline{4998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4998}:%mdk + +%mdk-data-line={5000} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5001} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~\textless{}ID\textgreater{}\\ +entities~\{\\ +~~extern\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~extern~instances~for~all~supported~extern~types}\\ +~~table\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~table~entries~for~all~tables}\\ +~~action\_profile\_member~\{~\}~~{\mdcolor{darkgreen}\#~read~all~members~for~all~action~profiles}\\ +~~action\_profile\_group~\{~\}~~{\mdcolor{darkgreen}\#~read~all~groups~for~all~action~profiles}\\ +~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5011} +\noindent\mdline{5011}The \mdline{5011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5011} oneof field in the \mdline{5011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5011} message must always be set, or the +server must return an \mdline{5012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5012} error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty \mdline{5014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5014} message in the \mdline{5014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5014}. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the \mdline{5016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5016} oneof\mdline{5016}~[\mdcite{protooneofbackwardscompatibility}{20}]\mdline{5016}.%mdk + +%mdk-data-line={5018} +\subsection{\mdline{5018}13.3.\hspace*{0.5em}\mdline{5018}Batch Processing}\label{sec-batch-processing}%mdk%mdk + +%mdk-data-line={5020} +\noindent\mdline{5020}A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type \mdline{5021}\emph{request}\mdline{5021} +appears only once in the batch.%mdk + +%mdk-data-line={5024} +\mdline{5024}A P4Runtime server will process the batch as follows:%mdk + +%mdk-data-line={5026} +\begin{enumerate}%mdk + +%mdk-data-line={5026} +\item{} +%mdk-data-line={5026} +\mdline{5026}Lock state (preventing new writes) and validate each \mdline{5026}\emph{request}\mdline{5026} in the batch:%mdk + +%mdk-data-line={5028} +\begin{enumerate}%mdk + +%mdk-data-line={5028} +\item{} +%mdk-data-line={5028} +\mdline{5028}If it is a valid \mdline{5028}\emph{request}\mdline{5028}, perform the read;%mdk + +%mdk-data-line={5030} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5030} +\item\mdline{5030}If the read was successful, return the entities read in +\mdline{5031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5031} stream.%mdk + +%mdk-data-line={5032} +\item\mdline{5032}If the read failed (exception / critical-error), prepare a \mdline{5032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5032} +with code set to \mdline{5033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INTERNAL}}}\mdline{5033}.%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5035} +\item{} +%mdk-data-line={5035} +\mdline{5035}If the \mdline{5035}\emph{request}\mdline{5035} is invalid (invalid-argument, not-supported, etc.), +prepare a \mdline{5036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5036} with relevant canonical code to capture the error.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5038} +\item{} +%mdk-data-line={5038} +\mdline{5038}Unlock the state (allowing new writes);%mdk%mdk + +%mdk-data-line={5040} +\item{} +%mdk-data-line={5040} +\mdline{5040}Close the \mdline{5040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5040} stream and return a \mdline{5040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5040} as follows:%mdk + +%mdk-data-line={5042} +\begin{enumerate}%mdk + +%mdk-data-line={5042} +\item{} +%mdk-data-line={5042} +\mdline{5042}If no errors were encountered, set code to \mdline{5042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{5042} and do not populate any +other field.%mdk%mdk + +%mdk-data-line={5045} +\item{} +%mdk-data-line={5045} +\mdline{5045}Otherwise, the overall code should be set to \mdline{5045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{5045}. See section +\mdline{5046}\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{5046} for information +on error reporting messages and guidelines. Assemble a list of \mdline{5047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5047} +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +\mdline{5051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{5051} field. This behavior also matches \mdline{5051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5051} +RPC.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5054} +\subsubsection{\mdline{5054}13.3.1.\hspace*{0.5em}\mdline{5054}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={5056} +\noindent\mdline{5056}If a client asked to read \mdline{5056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{a,b,c,d\}}}}\mdline{5056} and \mdline{5056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}b}}}\mdline{5056} and \mdline{5056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}d}}}\mdline{5056} \mdline{5056}\emph{requests}\mdline{5056} didn\mdline{5056}'\mdline{5056}t +validate, the server will return entities corresponding to \mdline{5057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5057} and \mdline{5057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}c}}}\mdline{5057}, followed +by a status \mdline{5058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{p4.Error(OK),~p4.Error(xxx),~p4.Error(yyy),~p4.Error(OK)\}}}}\mdline{5058} in the +\mdline{5059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5059} field.%mdk + +%mdk-data-line={5061} +\mdline{5061}The P4Runtime server is not required to perform any optimization (\mdline{5061}e.g.\mdline{5061} merge two +\mdline{5062}\emph{requests}\mdline{5062} in the \mdline{5062}\emph{batch}\mdline{5062} if one is a subset of other). As a result of this, it +is possible for the \mdline{5063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5063} to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging.%mdk + +%mdk-data-line={5066} +\mdline{5066}There is no requirement that each request in the batch will correspond to one +\mdline{5067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5067} message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit.%mdk + +%mdk-data-line={5072} +\mdline{5072}A P4Runtime server must be prepared to handle multiple concurrent \mdline{5072}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5072} RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (\mdline{5077}e.g.\mdline{5077} in a single-threaded architecture), it may choose to serialize +\mdline{5078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5078} RPC processing.%mdk + +%mdk-data-line={5080} +\subsection{\mdline{5080}13.4.\hspace*{0.5em}\mdline{5080}Parallelism of Read and Write Requests}\label{sec-parallelism-of-read-and-write-requests}%mdk%mdk + +%mdk-data-line={5082} +\noindent\mdline{5082}A P4Runtime server may be implemented to serve at most one +\mdline{5083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5083} or \mdline{5083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5083} message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so.%mdk + +%mdk-data-line={5088} +\mdline{5088}For example, imagine a client that wanted to use \mdline{5088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5088} +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +\mdline{5092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5092} messages with only a few updates to an \mdline{5092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{5092} +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +\mdline{5095}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5095} batch currently being processed, but it will not +complete for a significant amount of time.%mdk + +%mdk-data-line={5098} +\mdline{5098}The restrictions on which a client may rely are:%mdk + +%mdk-data-line={5100} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5100} +\item\mdline{5100}The processing of any two \mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5100} messages \mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W1}}}\mdline{5100} and \mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W2}}}\mdline{5100} must +result in the same state as if one of them was completed before the +other began.%mdk + +%mdk-data-line={5103} +\item\mdline{5103}For any \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5103} \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5103} and any \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5103} \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5103}, \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5103} must +return results consistent with a state where \mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5104} has completed +processing, or \mdline{5105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5105} has not yet begun processing.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5107} +\noindent\mdline{5107}For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a \mdline{5110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5110} message it acquired a write lock for each stateful +object affected by the \mdline{5111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5111}, and before starting the +processing of a \mdline{5112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5112} message it acquired a read lock for each +stateful object accessed by the \mdline{5113}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5113}, such an implementation +meets all of the requirements above.%mdk + +%mdk-data-line={5116} +\mdline{5116}It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, \mdline{5118}e.g.\mdline{5118} if the server somehow determined that two +\mdline{5119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5119} messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly.%mdk + +%mdk-data-line={5125} +\section{\mdline{5125}14.\hspace*{0.5em}\mdline{5125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5125} RPC}\label{sec-setforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5127} +\noindent\mdline{5127}A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the \mdline{5128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig~RPC}}}\mdline{5128}. The request is defined as:%mdk + +%mdk-data-line={5130} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5131} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~SetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Action~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~VERIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~VERIFY\_AND\_SAVE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~VERIFY\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~~~COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~~~RECONCILE\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint64}}~role\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~Action~action~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5148} +\noindent\mdline{5148}The server is expected to perform the following checks (in this order) +before performing the required \mdline{5149}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{5149}:%mdk + +%mdk-data-line={5151} +\begin{enumerate}%mdk + +%mdk-data-line={5151} +\item{} +%mdk-data-line={5151} +\mdline{5151}If \mdline{5151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5151} does not match any of the devices known to the P4Runtime +server or if \mdline{5152}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{5152} does not match any of the roles for the device, the +server must return a \mdline{5153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5153} error.%mdk%mdk + +%mdk-data-line={5155} +\item{} +%mdk-data-line={5155} +\mdline{5155}If the client is not the master for (\mdline{5155}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5155}, \mdline{5155}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{5155}) according to the +\mdline{5156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5156} value, the server must return a \mdline{5156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5156} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5158} +\noindent\mdline{5158}The action is the type of configuration action requested, it can be one of:%mdk + +%mdk-data-line={5160} +\begin{itemize}%mdk + +%mdk-data-line={5160} +\item{} +%mdk-data-line={5160} +\mdline{5160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY}}}\mdline{5160}: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an \mdline{5161}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5161} +error if config is not provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5164} +\item{} +%mdk-data-line={5164} +\mdline{5164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5164}: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent \mdline{5166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5166} / \mdline{5166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5166} requests must refer to fields in the new +config. Returns an \mdline{5167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5167} error if the forwarding config is not +provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5170} +\item{} +%mdk-data-line={5170} +\mdline{5170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_COMMIT}}}\mdline{5170}: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an \mdline{5172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5172} error if the forwarding config is not provided or if the +provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5175} +\item{} +%mdk-data-line={5175} +\mdline{5175}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COMMIT}}}\mdline{5175}: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a \mdline{5178}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5178} error if no saved config +is found, \mdline{5179}i.e.\mdline{5179} if no \mdline{5179}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5179} action preceded this one. Returns an +\mdline{5180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5180} error if a config is provided with this message.%mdk%mdk + +%mdk-data-line={5182} +\item{} +%mdk-data-line={5182} +\mdline{5182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RECONCILE\_AND\_COMMIT}}}\mdline{5182}: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5188} error. For targets that support this option, an +\mdline{5189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5189} error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5193} +\noindent\mdline{5193}The \mdline{5193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5193} field is a message of type \mdline{5193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5193} that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(\mdline{5195}e.g.\mdline{5195} generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the\mdline{5196}~\mdref{sec-p4-fwd-pipe-config}{Forwarding-Pipeline +Configuration}\mdline{5197} section for details.%mdk + +%mdk-data-line={5199} +\mdline{5199}A P4Runtime server running on a non-programmable device may not +support \mdline{5200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5200} (\mdline{5200}e.g.\mdline{5200} the forwarding-pipeline +config is part of the device\mdline{5201}'\mdline{5201}s software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +\mdline{5203}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5203} error.%mdk + +%mdk-data-line={5205} +\section{\mdline{5205}15.\hspace*{0.5em}\mdline{5205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5205} RPC}\label{sec-getforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5207} +\noindent\mdline{5207}The forwarding-pipeline configuration of the target can be retrieved by invoking +the \mdline{5208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig~RPC}}}\mdline{5208}. The request is defined as:%mdk + +%mdk-data-line={5210} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5211} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~ResponseType~\{\\ +~~~~ALL~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~COOKIE\_ONLY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~P{\mdcolor{purple}4}INFO\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DEVICE\_CONFIG\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~ResponseType~response\_type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5223} +\noindent\mdline{5223}The \mdline{5223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5223} uniquely identifies the target P4 device. A \mdline{5223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5223} error is +returned if the \mdline{5224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5224} is not recognized by the P4Runtime server.%mdk + +%mdk-data-line={5226} +\mdline{5226}The \mdline{5226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5226} is used to specify which fields to populate in the response, +its value can be one of:%mdk + +%mdk-data-line={5229} +\begin{itemize}%mdk + +%mdk-data-line={5229} +\item{} +%mdk-data-line={5229} +\mdline{5229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5229}: returns a \mdline{5229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5229} with all fields +set as stored by the target. This is the default behaviour if the +\mdline{5231}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5231} field is not set.%mdk%mdk + +%mdk-data-line={5233} +\item{} +%mdk-data-line={5233} +\mdline{5233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COOKIE\_ONLY}}}\mdline{5233}: reply by setting only the \mdline{5233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5233} field in the +\mdline{5234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5234}, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message.%mdk%mdk + +%mdk-data-line={5238} +\item{} +%mdk-data-line={5238} +\mdline{5238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4INFO\_AND\_COOKIE}}}\mdline{5238}: reply by setting the \mdline{5238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{5238} and \mdline{5238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5238} fields.%mdk%mdk + +%mdk-data-line={5240} +\item{} +%mdk-data-line={5240} +\mdline{5240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEVICE\_CONFIG\_AND\_COOKIE}}}\mdline{5240}: reply by setting the \mdline{5240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5240} and +\mdline{5241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5241} fields.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5243} +\noindent\mdline{5243}The response contains the \mdline{5243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5243} for the specified device:%mdk + +%mdk-data-line={5245} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5246} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigResponse~\{\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5251} +\noindent\mdline{5251}If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level \mdline{5252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5252} field will be unset in the response. Examples are +(i) a server that only allows configuration via \mdline{5253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5253} +but this RPC hasn\mdline{5254}'\mdline{5254}t been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn\mdline{5255}'\mdline{5255}t yet occurred.%mdk + +%mdk-data-line={5257} +\mdline{5257}Once a forwarding-pipeline config is installed on the device (either via +\mdline{5258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5258} or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +\mdline{5260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.p4\_device\_config}}}\mdline{5260} will be empty / unset in the response, even if +\mdline{5261}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5261} in the request was set to \mdline{5261}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5261}. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the \mdline{5263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5263} RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +\mdline{5265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5265}, the value of \mdline{5265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.cookie}}}\mdline{5265} will be unset.%mdk + +%mdk-data-line={5267} +\mdline{5267}If a P4Runtime server supports both \mdline{5267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5267} as well as +returning the \mdline{5268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5268}, there should be read-write symmetry between +\mdline{5269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5269} and \mdline{5269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5269} RPCs.%mdk + +%mdk-data-line={5271} +\section{\mdline{5271}16.\hspace*{0.5em}\mdline{5271}P4Runtime Stream Messages}\label{sec-p4runtime-stream-messages}%mdk%mdk + +%mdk-data-line={5273} +\subsection{\mdline{5273}16.1.\hspace*{0.5em}\mdline{5273}Packet I/O}\label{sec-packet-i_o}%mdk%mdk + +%mdk-data-line={5275} +\noindent\mdline{5275}P4Runtime supports controller packet-in and packet-out by means of \mdline{5275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5275} +and \mdline{5276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5276} stream messages, respectively.%mdk + +%mdk-data-line={5278} +\mdline{5278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5278} messages are sent by the P4Runtime server to the client. Conversely, +\mdline{5279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5279} messages are sent by the client to the server. Any \mdline{5279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5279} +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a \mdline{5282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5282} message with the \mdline{5282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5282} field set to +report the error to the client. See the section on\mdline{5283}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{5284} for more information on \mdline{5284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5284}.%mdk + +%mdk-data-line={5286} +\mdline{5286}As introduced in the\mdline{5286}~\mdref{sec-controller-packet-meta}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\mdline{5286} +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with \mdline{5288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5288}. The expected metadata is described +in the P4Info using the \mdline{5289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5289} messages.%mdk + +%mdk-data-line={5291} +\mdline{5291}Both \mdline{5291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5291} and \mdline{5291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5291} stream messages share the same fields and are +defined as follows:%mdk + +%mdk-data-line={5294} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5295} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Packet~sent~from~the~controller~to~the~switch.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketOut~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~Packet~sent~from~the~switch~to~the~controller.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketIn~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~PacketMetadata~\{\\ +~~{\mdcolor{darkgreen}//~This~refers~to~Metadata.id~coming~from~P4Info~ControllerPacketMetadata.}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~metadata\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5314} +\begin{itemize}%mdk + +%mdk-data-line={5314} +\item{} +%mdk-data-line={5314} +\mdline{5314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}payload}}}\mdline{5314} is used to carry the full packet content, including the headers.%mdk%mdk + +%mdk-data-line={5316} +\item{} +%mdk-data-line={5316} +\mdline{5316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5316} is a repeated field of \mdline{5316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{5316} messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +\mdline{5319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5319}. Indeed, when a P4Runtime client (or server) +generates a \mdline{5320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5320} (or \mdline{5320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5320}) message, it needs to populate the +\mdline{5321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5321} field with as many values as in \mdline{5321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{5321} +for the packet-out (or packet-in) case. Each \mdline{5322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata.value}}}\mdline{5322} is a +binary string and must conform to the\mdline{5323}~\mdref{sec-bytestrings}{Bytestrings}\mdline{5323} +requirements based on the corresponding P4Info +\mdline{5325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{5325} specification. If the \mdline{5325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5325} field +does not match the P4Info specification, the server must drop the \mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5326} +message and may generate a \mdline{5327}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5327} message with the \mdline{5327}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5327} +field set to report the error to the client which issued the \mdline{5328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5328}. See +the section on\mdline{5329}~\mdref{sec-stream-error-reporting}{Stream Error Reporting}\mdline{5329} for more +information on \mdline{5330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5330}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5332} +\subsection{\mdline{5332}16.2.\hspace*{0.5em}\mdline{5332}Master Arbitration Update}\label{sec-master-arbitration-update}%mdk%mdk + +%mdk-data-line={5334} +\noindent\mdline{5334}P4Runtime\mdline{5334}'\mdline{5334}s master arbitration mechanism ensures that only the current master +can modify state on the switch, and that the \mdline{5335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5335} is monotonically +increasing. For example, the switch must finish all previous write operations +before changing masters, and must only accept write requests from the current +master.%mdk + +%mdk-data-line={5340} +\mdline{5340}As explained earlier in this document, the controller uses the \mdline{5340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5340} +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via \mdline{5342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5342} RPC), +it needs to start a controller session and become a \mdline{5343}\textquotedblleft{}master\textquotedblright{}\mdline{5343}. To do so, the +controller first opens a bidirectional stream channel to the server via +\mdline{5345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5345} for each device and sends a \mdline{5345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5345} message. The +controller populates the \mdline{5346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5346} field in this message using +its \mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{5347} and \mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5347} and the \mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5347} of the device, as explained +in detail in the\mdline{5348}~\mdref{sec-master-slave-arbitration-and-controller-replication}{Master-Slave Arbitration and Controller +Replication}\mdline{5349} +section. For any given \mdline{5350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role\_id)}}}\mdline{5350}, the P4Runtime server keeps track +of the highest \mdline{5351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5351} that it has ever received. If a controller\mdline{5351}'\mdline{5351}s +\mdline{5352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5352} is equal to the highest \mdline{5352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5352} that the server has ever +received, that controller is the master. All other controllers are slaves. Note +that it is possible that all controllers are slaves, and that there is no +master. There can be at most one master, because for any given +\mdline{5356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role\_id)}}}\mdline{5356}, each connected controller has a unique \mdline{5356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5356}.%mdk + +%mdk-data-line={5358} +\mdline{5358}This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest \mdline{5359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5359} after such a restart. +However, across a\mdline{5360}~\mdref{sec-restarts}{full restart}\mdline{5360}, the \mdline{5360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5360} must be +reset. In fact, a full restart is the only way to reset the \mdline{5361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5361}.%mdk + +%mdk-data-line={5363} +\mdline{5363}The \mdline{5363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5363} message is defined as follows:%mdk + +%mdk-data-line={5365} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5366} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Role~\{\\ +~~{\mdcolor{darkgreen}//~role\_id~for~this~role.~Defined~offline~in~agreement~across~the}\\ +~~{\mdcolor{darkgreen}//~entire~control~plane.}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Describes~the~role~configuration.}\\ +~~google.protobuf.Any~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~MasterArbitrationUpdate~\{\\ +~~{\mdcolor{darkgreen}//~Identifies~the~device~(aka~target~or~node~or~switching~chip).}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~The~role~for~which~the~mastership~is~being~arbitrated.}\\ +~~Role~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~The~election\_id~(unique~per~role).}\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Switch~populates~this~with~OK~for~the~client~that~is~the~master,}\\ +~~{\mdcolor{darkgreen}//~and~with~an~error~status~for~all~other~connected~clients~(at}\\ +~~{\mdcolor{darkgreen}//~every~mastership~change).~The~controller~does~not~populate~this}\\ +~~{\mdcolor{darkgreen}//~field.}\\ +~~google.{\bfseries{\mdcolor{navy}rpc}}.Status~status~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5389} +\noindent\mdline{5389}Note that the \mdline{5389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5389} field in the \mdline{5389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5389} message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a \mdline{5391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5391} message back to the controller, in which +it populates the \mdline{5392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5392} message using the \mdline{5392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5392}, +\mdline{5393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5393}, and \mdline{5393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5393} it previously received from the controller. The server +also populates the \mdline{5394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5394} field in the \mdline{5394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5394} according to +the rules in an\mdline{5395}~\mdref{sec-mastership-updates}{earlier section}\mdline{5395}.%mdk + +%mdk-data-line={5397} +\mdline{5397}The sender need not specify an \mdline{5397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5397}. If the \mdline{5397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5397} is not +specified, the sender\mdline{5398}'\mdline{5398}s \mdline{5398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5398} is considered lower than any +\mdline{5399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5399}, and the sender will thus never become master. This way, a +controller can choose to be a standby controller, in order to avoid master +\mdline{5401}\textquotedblleft{}flapping\textquotedblright{}\mdline{5401} (if a standby controller connects to the switch shortly before the +actual master controller, therefore becoming master temporarily).%mdk + +%mdk-data-line={5405} +\subsection{\mdline{5405}16.3.\hspace*{0.5em}\mdline{5405}Digest Messages}\label{sec-digest-messages}%mdk%mdk + +%mdk-data-line={5407} +\noindent\mdline{5407}See the\mdline{5407}~\mdref{sec-digestentry}{DigestEntry}\mdline{5407} section.%mdk + +%mdk-data-line={5409} +\subsection{\mdline{5409}16.4.\hspace*{0.5em}\mdline{5409}Table Idle Timeout Notification}\label{sec-table-idle-timeout-notification}%mdk%mdk + +%mdk-data-line={5411} +\noindent\mdline{5411}When a table supports idle timeout (as per the P4Info message), the master +client can specify a TTL value for each entry in the table (see +\mdline{5413}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{5413} section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an \mdline{5415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5415} message on the +\mdline{5416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5416} bidirectional stream to the master client. The master client can +then take the action of its choice, most likely remove the idle entry.%mdk + +%mdk-data-line={5419} +\mdline{5419}The \mdline{5419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5419} Protobuf message has the following fields:%mdk + +%mdk-data-line={5421} +\begin{itemize}%mdk + +%mdk-data-line={5421} +\item{} +%mdk-data-line={5421} +\mdline{5421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}timestamp}}}\mdline{5421}: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server\mdline{5422}'\mdline{5422}s local clock.%mdk%mdk + +%mdk-data-line={5424} +\item{} +%mdk-data-line={5424} +\mdline{5424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5424}: a repeated field of entries which have expired. Each individual +entry is identified by a single \mdline{5425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5425} message. For each \mdline{5425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5425}, +the \mdline{5426}\emph{key}\mdline{5426} fields (\mdline{5426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{5426}, \mdline{5426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{5426} and \mdline{5426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{5426}) must be set, along with +the \mdline{5427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{5427} field, the \mdline{5427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5427} field, and the +\mdline{5428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{5428} field. Other fields may be set by the server but should be +ignored by the client.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5431} +\noindent\mdline{5431}Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +\mdline{5433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5433} message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an \mdline{5438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5438} +message with an empty \mdline{5439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5439} repeated field.%mdk + +%mdk-data-line={5441} +\mdline{5441}After generating an idle notification, the P4Runtime server must \mdline{5441}\textquotedblleft{}reset\textquotedblright{}\mdline{5441} the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the master client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle.%mdk + +%mdk-data-line={5448} +\mdline{5448}Here is a reasonable pseudo-code implementation for idle timeout for table +entries:%mdk + +%mdk-data-line={5451} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5452} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutStream~stream;\\ +\\ +scanning\_interval~=~{\mdcolor{purple}10}ms;\\ +\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~{\mdcolor{darkgreen}//~iterate~over~all~tables~which~support~idle~timeout}\\ +~~{\bfseries{\mdcolor{navy}for}}~(table~in~tables)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(!table.idle\_timeout\_supported)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~{\mdcolor{darkgreen}//~we~coalesce~all~idle~notifications~for~the~same~table~in~one}\\ +~~~~{\mdcolor{darkgreen}//~message}\\ +~~~~IdleTimeoutNotification~msg;\\ +~~~~{\mdcolor{darkgreen}//~read~time\_since\_last\_hit~from~device}\\ +~~~~entries~=~device.load\_table\_entries\_from\_hw(table);\\ +~~~~{\bfseries{\mdcolor{navy}for}}~(entry~in~entries)~\{\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.idle\_timeout~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~TTL}\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.time\_since\_last\_hit~\textless{}~entry.idle\_timeout)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~~~msg.table\_entry\_add(entry);\\ +~~~~~~entry.reset\_time\_since\_last\_hit();\\ +~~~~\}\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(msg.table\_entry\_size()~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~notifications}\\ +~~~~msg.set\_timestamp(now());\\ +~~~~stream.write(msg);\\ +~~\}\\ +~~sleep(scanning\_interval);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5479} +\subsection{\mdline{5479}16.5.\hspace*{0.5em}\mdline{5479}Architecture-Specific Notifications}\label{sec-architecture-specific-notifications}%mdk%mdk + +%mdk-data-line={5481} +\noindent\mdline{5481}P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on \mdline{5482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5482}, by including an \mdline{5482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5482} Protobuf field\mdline{5482}~[\mdcite{protoany}{31}]\mdline{5482} +named \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5483} in both \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5483} and \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5483}. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the\mdline{5485}~\mdref{sec-digestentry}{PSA \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}} +extern}\mdline{5486}. See section on\mdline{5486}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{5487} for more information.%mdk + +%mdk-data-line={5489} +\subsection{\mdline{5489}16.6.\hspace*{0.5em}\mdline{5489}Stream Error Reporting}\label{sec-stream-error-reporting}%mdk%mdk + +%mdk-data-line={5491} +\noindent\mdline{5491}The P4Runtime server can asynchronously report errors which occur when +processing \mdline{5492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5492} messages, using the \mdline{5492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5492} message field (of +type \mdline{5493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5493}) in \mdline{5493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5493}. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature.%mdk + +%mdk-data-line={5497} +\mdline{5497}The \mdline{5497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5497} message has the following fields:%mdk + +%mdk-data-line={5499} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5499} +\item\mdline{5499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5499}, which must be set to the appropriate canonical error code +\mdline{5500}[\mdcite{grpcstatuscodes}{34}]\mdline{5500}.%mdk + +%mdk-data-line={5501} +\item\mdline{5501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{5501}, an optional developer-facing error message describing the error.%mdk + +%mdk-data-line={5502} +\item\mdline{5502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5502} and \mdline{5502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5502}, which are optional and can be used by vendors to provide +additional details on the error. \mdline{5503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5503} is a numeric error code drawn from a +vendor\mdline{5504}'\mdline{5504}s chosen error \mdline{5504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5504}.%mdk + +%mdk-data-line={5505} +\item\mdline{5505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5505}, which is a Protobuf \mdline{5505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5505} used to help the client identify which +\mdline{5506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5506} triggered the error. The server is required to set the +appropriate field in the \mdline{5507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5507} so that the client can identify which type +of stream message is responsible for the error (\mdline{5508}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5508}, +\mdline{5509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_list\_ack}}}\mdline{5509} or \mdline{5509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5509}), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid \mdline{5511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5511} message from the +client, the \mdline{5512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5512} field (of type \mdline{5512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError)}}}\mdline{5512} should be set in +the \mdline{5513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5513} \mdline{5513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5513}, and the server may additionally set the \mdline{5513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5513} +field in the \mdline{5514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError}}}\mdline{5514} sub-message (by copying it from the invalid +\mdline{5515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5515} message received on the stream channel) so that the client can +know exactly what packet-out triggered the error.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5518} +\noindent\mdline{5518}The appropriate canonical error code\mdline{5518}~[\mdcite{grpcstatuscodes}{34}]\mdline{5518} should be used when +populating the \mdline{5519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5519} field. For example:%mdk + +%mdk-data-line={5521} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5521} +\item\mdline{5521}if a controller is not allowed to send a \mdline{5521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5521} message under its +current role definition, the code should be set to \mdline{5522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5522}.%mdk + +%mdk-data-line={5523} +\item\mdline{5523}if the \mdline{5523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5523} repeated field in \mdline{5523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5523} does not match the P4Info +definition, the code should be set to \mdline{5524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5524}. It may be useful +for the server to set the \mdline{5525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5525} field in this case, so that the client +can find out which set of metadata fields triggered the error.%mdk + +%mdk-data-line={5527} +\item\mdline{5527}if the \mdline{5527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{5527} field in \mdline{5527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{5527} does not match any \mdline{5527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{5527} entry +in P4Info, the code should be set to \mdline{5528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5528}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5530} +\noindent\mdline{5530}The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, \mdline{5531}e.g.\mdline{5531} because of a +burst of \mdline{5532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5532} messages.%mdk + +%mdk-data-line={5534} +\mdline{5534}Note that master-arbitration errors are never reported using the \mdline{5534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5534} +message. Invalid \mdline{5535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5535} messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section\mdline{5537}~\mdref{sec-mastership-updates}{5.3}\mdline{5537}.%mdk + +%mdk-data-line={5539} +\subsubsection{\mdline{5539}16.6.1.\hspace*{0.5em}\mdline{5539}Examples of \mdline{5539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5539} Messages}\label{sec-examples-of-streamerror-messages}%mdk%mdk + +%mdk-data-line={5541} +\begin{itemize}%mdk + +%mdk-data-line={5541} +\item{} +%mdk-data-line={5541} +\mdline{5541}\textbf{Malformed packet-out metadata.}\mdline{5541} If the server receives a \mdline{5541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5541} +message with a \mdline{5542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5542} field with id 7 which is not included in the P4Info +\mdline{5543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5543} message for \mdline{5543}\textquotedblleft{}packet\_out\textquotedblright{}\mdline{5543}, the server may send the +following \mdline{5544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5544} back to the client:%mdk + +%mdk-data-line={5545} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5546} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Unknown~metadata~field~id~7.}{\mdcolor{maroon}"}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~copied~from~the~PacketOut~message~received~from~the~client}\\ +~~~packet\_out~\{\\ +~~~~~payload:~...\\ +~~~~~metadata~\{\\ +~~~~~~~id:~{\mdcolor{purple}7}\\ +~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}I\_should\_not\_be\_here}{\mdcolor{maroon}"}\\ +~~~~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~~\}\\ +~~~~~{\mdcolor{darkgreen}\#~more~metadata}\\ +~~~\}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={5564} +\item{} +%mdk-data-line={5564} +\mdline{5564}\textbf{Packet-out which exceeds the MTU.}\mdline{5564} If the server receives a \mdline{5564}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5564} +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following \mdline{5567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5567}:%mdk + +%mdk-data-line={5568} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5569} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Packet~exceeds~the~MTU~for~port.}{\mdcolor{maroon}"}\\ +~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendor1}{\mdcolor{maroon}"}\\ +~code:~{\mdcolor{purple}123}~~{\mdcolor{darkgreen}\#~MTU\_EXCEEDED}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~we~do~not~set~the~packet\_out~field~as~it~does~not~provide~any}\\ +~~~{\mdcolor{darkgreen}\#~extra~information~to~the~client}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5581} +\section{\mdline{5581}17.\hspace*{0.5em}\mdline{5581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5581} RPC}\label{sec-capabilities-rpc}%mdk%mdk + +%mdk-data-line={5583} +\noindent\mdline{5583}The \mdline{5583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5583} RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the \mdline{5585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesRequest}}}\mdline{5585} message is empty and the \mdline{5585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5585} +message only includes the \mdline{5586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_api\_version}}}\mdline{5586} string field. This field must +be set to the full semantic version string\mdline{5587}~[\mdcite{semver}{27}]\mdline{5587} corresponding to the +version of the P4Runtime API implemented by the server, \mdline{5588}e.g.\mdline{5588} \mdline{5588}\textquotedblleft{}1.1.0-rc.1\textquotedblright{}\mdline{5588}.%mdk + +%mdk-data-line={5590} +\mdline{5590}Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three\mdline{5591}~\mdref{sec-batch-atomicity}{atomicity +modes}\mdline{5592} for \mdline{5592}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5592} batches, two of them being +optional. In the future we may decide to leverage the \mdline{5593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5593} +message to enable the server to report to the client which subset of these +atomicity modes is supported.%mdk + +%mdk-data-line={5597} +\mdline{5597}The semantic version string included in \mdline{5597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5597} can be used by +the client to determine which exact feature set is implemented by the server, +since\mdline{5599}~\mdref{sec-p4runtime-versioning}{minor releases}\mdline{5599} may introduce new +functionality. However, because the \mdline{5600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5600} RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (\mdline{5602}i.e.\mdline{5602} an \mdline{5602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5602} error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0).%mdk + +%mdk-data-line={5606} +\section{\mdline{5606}18.\hspace*{0.5em}\mdline{5606}Portability Considerations}\label{sec-portability-considerations}%mdk%mdk + +%mdk-data-line={5608} +\subsection{\mdline{5608}18.1.\hspace*{0.5em}\mdline{5608}PSA Metadata Translation}\label{sec-psa-metadata-translation}%mdk%mdk + +%mdk-data-line={5610} +\noindent\mdline{5610}The \mdline{5610}\emph{Portable Switch Architecture}\mdline{5610} (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +\mdline{5614}[\mdcite{psatranslation}{24}]\mdline{5614}. For such metadata, a translation between the controller\mdline{5614}'\mdline{5614}s +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the \mdline{5618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5618} annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture.%mdk + +%mdk-data-line={5622} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={5623} +\noindent\mdline{5623}\includegraphics[keepaspectratio=true,height=7cm]{build/psa-metadata-translation}{}\mdline{5623}%mdk + +%mdk-data-line={5624} +\mdhr{}%mdk + +%mdk-data-line={5625} +\noindent\mdline{5625}\mdcaption{\textbf{Figure~\mdcaptionlabel{8}.}~\mdcaptiontext{P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdcenter}\label{fig-psa-metadata-translation}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={5629} +\noindent\mdline{5629}Figure\mdline{5629}~\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}}\mdline{5629} illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller\mdline{5635}'\mdline{5635}s 32 bit port +numbers to a target\mdline{5636}'\mdline{5636}s 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch.%mdk + +%mdk-data-line={5640} +\subsubsection{\mdline{5640}18.1.1.\hspace*{0.5em}\mdline{5640}Translation of Port Numbers}\label{sec-translation-of-port-numbers}%mdk%mdk + +%mdk-data-line={5642} +\noindent\mdline{5642}In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller\mdline{5643}'\mdline{5643}s space and the PSA device\mdline{5643}'\mdline{5643}s space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +\mdline{5647}\mdref{sec-user-defined-types}{user-defined P4 types}\mdline{5647}, namely \mdline{5647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5647} and +\mdline{5648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5648}, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in \mdline{5651}\emph{psa.p4}\mdline{5651} for +the PSA device in Switch 1.%mdk + +%mdk-data-line={5654} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5655} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_t;\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortIdInHeader\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~PortIdInHeader\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5661} +\noindent\mdline{5661}The first argument to the \mdline{5661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5661} annotation is a URI that +indicates to the P4Runtime server which numerical mapping\mdline{5662} \mdline{5662}\textemdash{}\mdline{5662} provided by the +out-of-band switch configuration mechanism\mdline{5663} \mdline{5663}\textemdash{}\mdline{5663} to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports).%mdk + +%mdk-data-line={5667} +\mdline{5667}An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows:%mdk + +%mdk-data-line={5673} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5674} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}enum}}~SdnPort~\{\\ +~~SDN\_PORT\_UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +\\ +~~{\mdcolor{darkgreen}//~SDN~ports~are~numbered~starting~from~1.}\\ +~~SDN\_PORT\_MIN~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\\ +~~{\mdcolor{darkgreen}//~The~maximum~value~of~an~SDN~port~(physical~or~logical).}\\ +~~SDN\_PORT\_MAX~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffeff};\\ +\\ +~~{\mdcolor{darkgreen}//~Reserved~SDN~port~numbers~(0xfffffff0~-~0xffffffff)}\\ +\\ +~~SDN\_PORT\_RECIRCULATE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffa};\\ +~~SDN\_PORT\_CPU~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffd};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5690} +\noindent\mdline{5690}The switch config will map \mdline{5690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_RECIRCULATE}}}\mdline{5690} and \mdline{5690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_CPU}}}\mdline{5690} \mdline{5690}\textemdash{}\mdline{5690} as well +as any SDN port number corresponding to a \mdline{5691}\textquotedblleft{}regular\textquotedblright{}\mdline{5691} front-panel port\mdline{5691} \mdline{5691}\textemdash{}\mdline{5691} to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation.%mdk + +%mdk-data-line={5695} +\mdline{5695}The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs.%mdk + +%mdk-data-line={5698} +\subsubsection{\mdline{5698}18.1.2.\hspace*{0.5em}\mdline{5698}Translation of Packet-IO Header Fields}\label{sec-translation-of-packet-io-header-fields}%mdk%mdk + +%mdk-data-line={5700} +\noindent\mdline{5700}Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:.%mdk + +%mdk-data-line={5703} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5704} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~PortIdInHeader\_t~egress\_port;\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~PortIdInHeader\_t~ingress\_port;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5715} +\noindent\mdline{5715}The header-level annotation \mdline{5715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5715} is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (\mdline{5719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5719}) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI\mdline{5723} \mdline{5723}\textemdash{}\mdline{5723} first argument to the \mdline{5723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5723} +annotation). Any subsequent reference to the \mdline{5724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5724} field in the +data plane will use the translated value. \mdline{5725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5725} is used in the +header definition instead of \mdline{5726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5726} to guarantee byte-aligned headers in +case this is required by the target.%mdk + +%mdk-data-line={5729} +\mdline{5729}A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target\mdline{5731}'\mdline{5731}s PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the \mdline{5733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ingress\_port}}}\mdline{5733} field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller.%mdk + +%mdk-data-line={5739} +\subsubsection{\mdline{5739}18.1.3.\hspace*{0.5em}\mdline{5739}Translation of Match Fields}\label{sec-translation-of-match-fields}%mdk%mdk + +%mdk-data-line={5741} +\noindent\mdline{5741}Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table\mdline{5742}'\mdline{5742}s match key as shown in the example below:%mdk + +%mdk-data-line={5744} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5745} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~istd.ingress\_port:~exact;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~ingress~port}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5755} +\noindent\mdline{5755}Table \mdline{5755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5755} has an exact match on PSA standard metadata ingress port +(\mdline{5756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}istd.ingress\_port}}}\mdline{5756}). Since the field is of type \mdline{5756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5756}, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in \mdline{5759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5759} from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table \mdline{5764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5764} is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values.%mdk + +%mdk-data-line={5768} +\mdline{5768}Note that it may be infeasible to translate the value-mask pair for ternary +matches: \mdline{5769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5769}, \mdline{5769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5769} or \mdline{5769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5769} match kinds. The P4Runtime server may +require that for these match kinds the port match be either \mdline{5770}\emph{de facto}\mdline{5770} \mdline{5770}\textquotedblleft{}exact\textquotedblright{}\mdline{5770} +(0xffffffff mask for \mdline{5771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5771}, prefix-length of 32 for \mdline{5771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5771}, or same low and +high bounds for \mdline{5772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5772}) or \mdline{5772}\textquotedblleft{}don't care\textquotedblright{}\mdline{5772}.%mdk + +%mdk-data-line={5774} +\subsubsection{\mdline{5774}18.1.4.\hspace*{0.5em}\mdline{5774}Translation of Action Parameters}\label{sec-translation-of-action-parameters}%mdk%mdk + +%mdk-data-line={5776} +\noindent\mdline{5776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5776} type parameters can be part of a P4 action definition as shown in the +example below:%mdk + +%mdk-data-line={5779} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5780} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.h.f:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~a;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5794} +\noindent\mdline{5794}The controller may write entries in table \mdline{5794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5794} with action \mdline{5794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5794} to set the egress +port as shown in the P4 code above. The action parameter \mdline{5795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5795} is of type +\mdline{5796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5796}, which leads to a 32-bit bitwidth for \mdline{5796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5796} being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device.%mdk + +%mdk-data-line={5802} +\subsubsection{\mdline{5802}18.1.5.\hspace*{0.5em}\mdline{5802}Port Translation for PSA Extern APIs}\label{sec-port-translation-for-psa-extern-apis}%mdk%mdk + +%mdk-data-line={5804} +\noindent\mdline{5804}The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch field is +of type \mdline{5810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5810} to carry the 32-bit SDN representation of the port being +watched. The P4Runtime server will translate the given watch port number into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device.%mdk + +%mdk-data-line={5815} +\mdline{5815}The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type \mdline{5817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5817} to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane.%mdk + +%mdk-data-line={5821} +\subsubsection{\mdline{5821}18.1.6.\hspace*{0.5em}\mdline{5821}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}\label{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}%mdk%mdk + +%mdk-data-line={5823} +\noindent\mdline{5823}P4Runtime supports using a translated value (\mdline{5823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5823} or any other translated +type for which the underlying built-in type is \mdline{5824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5824}) as an index to a +register, indirect counter, or indirect meter.%mdk + +%mdk-data-line={5827} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5828} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~counter~entry~type~}{\mdcolor{darkgreen}*/},~PortId\_t~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~index~type~}{\mdcolor{darkgreen}*/}\textgreater{}(\\ +~~{\mdcolor{purple}32}w1024,~PSA\_CounterType\_t.PACKETS)~counter;\\ +{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +~~counter.count(p);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5836} +\noindent\mdline{5836}This P4 Counter declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={5839} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5840} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counters~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x12000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}counter}{\mdcolor{maroon}"}\\ +~~\}\\ +~~spec~\{\\ +~~~~unit:~PACKETS\\ +~~\}\\ +~~index\_type\_name~\{\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5854} +\noindent\mdline{5854}The controller may read and write counter values from indexed counter \mdline{5854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter}}}\mdline{5854} +using SDN port numbers as indices, and not device-specific port numbers. The +\mdline{5856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{5856} field in the P4Info message is a signal to the P4Runtime +server that translation is required.%mdk + +%mdk-data-line={5859} +\section{\mdline{5859}19.\hspace*{0.5em}\mdline{5859}P4Runtime Versioning}\label{sec-p4runtime-versioning}%mdk%mdk + +%mdk-data-line={5861} +\noindent\mdline{5861}P4Runtime follows the Google guidelines for versioning cloud APIs +\mdline{5862}[\mdcite{apiversioning}{6}]\mdline{5862}. We use a \mdline{5862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR.MINOR.PATCH}}}\mdline{5862} style version number scheme and +we increment the:%mdk + +%mdk-data-line={5865} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5865} +\item\mdline{5865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5865} version when we make incompatible API changes,%mdk + +%mdk-data-line={5866} +\item\mdline{5866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MINOR}}}\mdline{5866} version when we add functionality in a backwards-compatible manner,%mdk + +%mdk-data-line={5867} +\item\mdline{5867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PATCH}}}\mdline{5867} version when we make backwards-compatible bug fixes.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5869} +\noindent\mdline{5869}The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is \mdline{5871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1}}}\mdline{5871} and the package +name for P4Info is \mdline{5872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1}}}\mdline{5872}. Even though \mdline{5872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5872} and \mdline{5872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5872} are two +different Protobuf packages, \mdline{5873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5873} depends on \mdline{5873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5873} and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence.%mdk + +%mdk-data-line={5877} +\mdline{5877}As recommended in\mdline{5877}~[\mdcite{apiversioning}{6}]\mdline{5877}, we may consider using pre-GA release +suffixes (such as \mdline{5878}\emph{alpha}\mdline{5878} or \mdline{5878}\emph{beta}\mdline{5878}) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1).%mdk + +%mdk-data-line={5882} +\mdline{5882}Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner.\mdline{5883}~[\mdcite{apiversioningbackwardscompatibility}{7}]\mdline{5883} describes +what constitute a backwards-compatible change. We expect \mdline{5884}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5884} version bumps +to be a \mdline{5885}\textbf{rare}\mdline{5885} event.%mdk + +%mdk-data-line={5887} +\mdline{5887}Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor\mdline{5892} \mdline{5892}+ patch version numbers in future releases.%mdk + +%mdk-data-line={5894} +\mdline{5894}All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository\mdline{5895}~[\mdcite{p4runtimerepo}{15}]\mdline{5895} and the version label follows +semantic versioning rules\mdline{5896}~[\mdcite{semver}{27}]\mdline{5896}.%mdk + +%mdk-data-line={5898} +\section{\mdline{5898}20.\hspace*{0.5em}\mdline{5898}Extending P4Runtime for non-PSA Architectures}\label{sec-extending-p4runtime}%mdk%mdk + +%mdk-data-line={5900} +\noindent\mdline{5900}P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place.%mdk + +%mdk-data-line={5908} +\mdline{5908}When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names:%mdk + +%mdk-data-line={5912} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5912} +\item\mdline{5912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/config/\textless{}major~version\textgreater{}/p4info.proto}}}\mdline{5912}%mdk + +%mdk-data-line={5913} +\item\mdline{5913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/\textless{}major~version\textgreater{}/p4runtime.proto}}}\mdline{5913}%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5915} +\noindent\mdline{5915}We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they \mdline{5916}\textquotedblleft{}extend\textquotedblright{}\mdline{5916}.%mdk + +%mdk-data-line={5918} +\mdline{5918}For the remainder of this section, we will refer to these two files as +\mdline{5919}\emph{p4info-ext}\mdline{5919} and \mdline{5919}\emph{p4runtime-ext}\mdline{5919} respectively.%mdk + +%mdk-data-line={5921} +\subsection{\mdline{5921}20.1.\hspace*{0.5em}\mdline{5921}Extending P4Runtime for Architecture-Specific Externs}\label{sec-extending-p4runtime-for-architecture-specific-externs}%mdk%mdk + +%mdk-data-line={5923} +\noindent\mdline{5923}Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both \mdline{5924}\emph{p4info-ext}\mdline{5924} and +\mdline{5925}\emph{p4runtime-ext}\mdline{5925}. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example:%mdk + +%mdk-data-line={5929} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5930} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~T~must~be~a~bit\textless{}W\textgreater{}~type,~it~indicates~the~width~of~each~counter~cell}\\ +{\bfseries{\mdcolor{navy}extern}}~MyNewPacketCounter\textless{}T\textgreater{}~\{\\ +~~counter({\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~size);\\ +~~increment({\bfseries{\mdcolor{navy}in}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~index);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5937} +\subsubsection{\mdline{5937}20.1.1.\hspace*{0.5em}\mdline{5937}Extending the P4Info message}\label{sec-extending-the-p4info-message}%mdk%mdk + +%mdk-data-line={5939} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5939} +\item\mdline{5939}Id prefixes \mdline{5939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0x81}}}\mdline{5939} through \mdline{5939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfe}}}\mdline{5939} are reserved for architecture-specific +externs. It is recommended that \mdline{5940}\emph{p4info-ext}\mdline{5940} include a \mdline{5940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Ids}}}\mdline{5940} message based +on the one in p4info.proto that the P4 compiler can refer to when\mdline{5941}~\mdref{sec-id-allocation}{assigning +IDs}\mdline{5942} to each extern instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5944} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5945} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~P{\mdcolor{purple}4}Ids~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Prefix~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~MY\_NEW\_PACKET\_COUNTER~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0x81};\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5953} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5953} +\item\mdline{5953}\emph{p4info-ext}\mdline{5953} should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +\mdline{5957}\mdref{sec-p4info-extern}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ExternInstance}}}}\mdline{5957} message as the \mdline{5957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{5957} +field, which is of type \mdline{5958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5958}~[\mdcite{protoany}{31}]\mdline{5958}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5960} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5961} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\mdcolor{darkgreen}//~corresponds~to~the~T~type~parameter~in~the~P4~extern~definition}\\ +~~p4.config.v1.P{\mdcolor{purple}4}DataTypeSpec~type\_spec~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~constructor~argument}\\ +~~{\bfseries{\mdcolor{navy}int64}}~size~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5969} +\subsubsection{\mdline{5969}20.1.2.\hspace*{0.5em}\mdline{5969}Extending the P4Runtime Service}\label{sec-extending-the-p4runtime-service}%mdk%mdk + +%mdk-data-line={5971} +\noindent\mdline{5971}Just like \mdline{5971}\emph{p4info-ext}\mdline{5971}, \mdline{5971}\emph{p4runtime-ext}\mdline{5971} should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an\mdline{5976}~\mdref{sec-extern-entry}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\mdline{5976} message generated by the +P4Runtime client.%mdk + +%mdk-data-line={5979} +\mdline{5979}Here is a possible Protobuf message for our \mdline{5979}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyNewPacketCounter}}}\mdline{5979} P4 extern:%mdk + +%mdk-data-line={5980} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5981} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~This~message~enables~reading~/~writing~data~to~the~counter~at~the~provided}\\ +{\mdcolor{darkgreen}//~index}\\ +{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~p4.v1.P{\mdcolor{purple}4}Data~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5989} +\noindent\mdline{5989}P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an \mdline{5990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5990} Protobuf field\mdline{5990}~[\mdcite{protoany}{31}]\mdline{5990} named \mdline{5990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5990} +in both \mdline{5991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{5991} and +\mdline{5992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{5992}. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in \mdline{5994}\emph{p4runtime-ext}\mdline{5994} and embed instances of these messages in +\mdline{5995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{5995} and \mdline{5995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{5995} as appropriate.%mdk + +%mdk-data-line={5997} +\subsection{\mdline{5997}20.2.\hspace*{0.5em}\mdline{5997}Architecture-Specific Table Extensions}\label{sec-architecture-specific-table-extensions}%mdk%mdk + +%mdk-data-line={5999} +\subsubsection{\mdline{5999}20.2.1.\hspace*{0.5em}\mdline{5999}New Match Types}\label{sec-new-match-types}%mdk%mdk + +%mdk-data-line={6001} +\noindent\mdline{6001}An architecture may introduce new table match types\mdline{6001}~[\mdcite{p4matchtypes}{12}]\mdline{6001}. P4Runtime +accounts for this by providing the following hooks:%mdk + +%mdk-data-line={6004} +\begin{itemize}%mdk + +%mdk-data-line={6004} +\item{} +%mdk-data-line={6004} +\mdline{6004}The \mdline{6004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{6004} field in \mdline{6004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{6004} (p4info.proto) is a \mdline{6004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6004} +which can be either one of the default match types (\mdline{6005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{6005}, \mdline{6005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{6005}, \mdline{6005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{6005}, +\mdline{6006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{6006}, or \mdline{6006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6006}) or an architecture-specific match type encoded as a +string.%mdk%mdk + +%mdk-data-line={6009} +\item{} +%mdk-data-line={6009} +\mdline{6009}The \mdline{6009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{6009} field in \mdline{6009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6009} (p4runtime.proto) is a +\mdline{6010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6010} which includes an \mdline{6010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6010} Protobuf message\mdline{6010}~[\mdcite{protoany}{31}]\mdline{6010} field +(\mdline{6011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6011}). \mdline{6011}\emph{p4info-ext}\mdline{6011} should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in \mdline{6014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6014} as the +\mdline{6015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6015} field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6018} +\subsubsection{\mdline{6018}20.2.2.\hspace*{0.5em}\mdline{6018}New Table Properties}\label{sec-new-table-properties}%mdk%mdk + +%mdk-data-line={6020} +\noindent\mdline{6020}An architecture may introduce additional table properties +\mdline{6021}[\mdcite{p4tableproperties}{30}]\mdline{6021}. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +\mdline{6023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Table}}}\mdline{6023} message includes the \mdline{6023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{6023} \mdline{6023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6023} Protobuf +field\mdline{6024}~[\mdcite{protoany}{31}]\mdline{6024}. At the moment, there is not any mechanism to extend the +\mdline{6025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.TableEntry}}}\mdline{6025} message based on the value of architecture-specific table +properties, but we may include on in future versions of the API.%mdk + +%mdk-data-line={6028} +\section{\mdline{6028}21.\hspace*{0.5em}\mdline{6028}Known Limitations of Current P4Runtime Version}\label{sec-known-limitations-of-current-p4runtime-version}%mdk%mdk + +%mdk-data-line={6030} +\begin{itemize}%mdk + +%mdk-data-line={6030} +\item{} +%mdk-data-line={6030} +\mdline{6030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6030}, action \mdline{6030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6030}, and controller packet metadata fields only +support unsigned bitstrings, \mdline{6031}i.e.\mdline{6031} values of one of the following types (not +the more general \mdline{6032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{6032}):%mdk + +%mdk-data-line={6033} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6033} +\item\mdline{6033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6033}%mdk + +%mdk-data-line={6034} +\item\mdline{6034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6034}. Note that as far as the \mdline{6034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Info}}}\mdline{6034} message contents and +thus controller software is concerned, such fields of type \mdline{6035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6035} +will be indistinguishable from those that have been declared with +type \mdline{6037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6037}. P4Runtime server software will automatically +perform any conversion needed between the type \mdline{6038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6038} values in +P4Runtime messages and the data plane representation.%mdk + +%mdk-data-line={6040} +\item\mdline{6040}an \mdline{6040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{6040} with underlying type \mdline{6040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6040}%mdk + +%mdk-data-line={6041} +\item\mdline{6041}a \mdline{6041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6041} or \mdline{6041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6041} with an underlying type that is one of the above (or +in general a \mdline{6042}\textquotedblleft{}chain\textquotedblright{}\mdline{6042} of \mdline{6042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6042} and/or \mdline{6042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6042} that eventually ends with +one of the types above)%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6045} +\item{} +%mdk-data-line={6045} +\mdline{6045}Support for PSA Random \mdline{6045}\&\mdline{6045} Timestamp externs is postponed to a future minor +version update.%mdk%mdk + +%mdk-data-line={6048} +\item{} +%mdk-data-line={6048} +\mdline{6048}P4Info does not include information about which of a table\mdline{6048}'\mdline{6048}s actions execute +which direct resource(s).%mdk%mdk + +%mdk-data-line={6051} +\item{} +%mdk-data-line={6051} +\mdline{6051}The default action for indirect match tables is restricted to a \mdline{6051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\\ +NoAction}}}\mdline{6052} known at compile-time.%mdk%mdk + +%mdk-data-line={6054} +\item{} +%mdk-data-line={6054} +\mdline{6054}There is no mechanism for changing the value of the \mdline{6054}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{6054} +table property at runtime.%mdk%mdk + +%mdk-data-line={6057} +\item{} +%mdk-data-line={6057} +\mdline{6057}There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor\mdline{6058} \mdline{6058}+ +patch version numbers.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6061} +\section{\mdline{6061}22.\hspace*{0.5em}\mdline{6061}Security concerns for P4Runtime}\label{sec-security-concerns-for-p4runtime}%mdk%mdk + +%mdk-data-line={6063} +\noindent\mdline{6063}Appropriate measures and security best practices need to be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client.%mdk + +%mdk-data-line={6070} +\section{\mdline{6070}A.\hspace*{0.5em}\mdline{6070}Appendix}\label{sec-appendix}%mdk%mdk + +%mdk-data-line={6072} +\subsection{\mdline{6072}A.1.\hspace*{0.5em}\mdline{6072}Revision History}\label{sec-revision-history}%mdk%mdk + +%mdk-data-line={6074} +\subsubsection{\mdline{6074}A.1.1.\hspace*{0.5em}\mdline{6074}Changes in v1.2.0}\label{sec-changes-in-v120}%mdk%mdk + +%mdk-data-line={6076} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6076} +\item\mdline{6076}Add new \mdline{6076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6076} match kind. At the moment, \mdline{6076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6076} is only supported by +the v1model architecture\mdline{6077}~[\mdcite{v1model}{38}]\mdline{6077}, and not by PSA. It will eventually be +included in the core P4 language.%mdk + +%mdk-data-line={6079} +\item\mdline{6079}Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists.%mdk + +%mdk-data-line={6081} +\item\mdline{6081}Add a new \mdline{6081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6081} field of type \mdline{6081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{6081} to \mdline{6081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{6081}. This is more +flexible than the now deprecated \mdline{6082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{6082} field.%mdk + +%mdk-data-line={6083} +\item\mdline{6083}Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +\mdline{6085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6085} annotation.%mdk + +%mdk-data-line={6086} +\item\mdline{6086}Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature.%mdk + +%mdk-data-line={6088} +\item\mdline{6088}Support using \mdline{6088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{6088} as the controller type in the \mdline{6088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6088} +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type.%mdk + +%mdk-data-line={6091} +\item\mdline{6091}Add optional P4 source locations to both structured and unstructured +annotations.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6094} +\subsubsection{\mdline{6094}A.1.2.\hspace*{0.5em}\mdline{6094}Changes in v1.1.0}\label{sec-changes-in-v110}%mdk%mdk + +%mdk-data-line={6096} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6096} +\item\mdline{6096}Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously.%mdk + +%mdk-data-line={6102} +\item\mdline{6102}Add \mdline{6102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{6102} field to stream messages sent by the server.%mdk + +%mdk-data-line={6103} +\item\mdline{6103}Add \mdline{6103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6103} RPC to query the P4Runtime API version implemented by the +server.%mdk + +%mdk-data-line={6105} +\item\mdline{6105}Support wildcard reads for multicast groups and clone sessions.%mdk + +%mdk-data-line={6106} +\item\mdline{6106}Support for modifying direct resources of const tables.%mdk + +%mdk-data-line={6107} +\item\mdline{6107}Support P4 user-defined types for Packet IO metadata fields.%mdk + +%mdk-data-line={6108} +\item\mdline{6108}Clarify consistency requirements for \mdline{6108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6108} and \mdline{6108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{6108} RPCs.%mdk + +%mdk-data-line={6109} +\item\mdline{6109}Add Appendix providing implementation advice for avoiding common pitfalls: + +%mdk-data-line={6110} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6110} +\item\mdline{6110}advice on setting gRPC Metadata Maximum Size%mdk + +%mdk-data-line={6111} +\item\mdline{6111}advice on setting gRPC Server Maximum Receive Message Size%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6112} +\item\mdline{6112}Clarify limitations on supported types for \mdline{6112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6112}, action \mdline{6112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6112}, and +Packet IO metadata fields.%mdk + +%mdk-data-line={6114} +\item\mdline{6114}Clarify that reading entire forwarding state with empty \mdline{6114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{6114} is not +supported.%mdk + +%mdk-data-line={6116} +\item\mdline{6116}Document that \mdline{6116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6116} need only be supported when applied to +type declarations in P4.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6119} +\subsection{\mdline{6119}A.2.\hspace*{0.5em}\mdline{6119}P4 Annotations}\label{sec-p4-annotations}%mdk%mdk + +%mdk-data-line={6121} +\noindent\mdline{6121}Table\mdline{6121}~\mdref{tab-p4-annotations}{\mdcaptionlabel{7}}\mdline{6121} lists P4\mdline{6121}\mdsub{16}\mdline{6121} annotations introduced primarily for +the purpose of adding features for the P4Runtime API.%mdk + +%mdk-data-line={6124} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{6126} Annotation}}&\multicolumn{1}{|c|}{{\bfseries\mdline{6126} Description}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{6128} \mdline{6128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{6128}}&\multicolumn{1}{|l|}{\mdline{6128} See section\mdline{6128}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6128}}\\ +\multicolumn{1}{|l}{\mdline{6129} \mdline{6129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{6129}}&\multicolumn{1}{|l|}{\mdline{6129} See section\mdline{6129}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{6129}}\\ +\multicolumn{1}{|l}{\mdline{6130} \mdline{6130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{6130}}&\multicolumn{1}{|l|}{\mdline{6130} See section\mdline{6130}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6130}}\\ +\multicolumn{1}{|l}{\mdline{6131} \mdline{6131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6131}}&\multicolumn{1}{|l|}{\mdline{6131} See section\mdline{6131}~\mdref{sec-id-allocation}{6.3}\mdline{6131}}\\ +\multicolumn{1}{|l}{\mdline{6132} \mdline{6132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{6132}}&\multicolumn{1}{|l|}{\mdline{6132} See sections\mdline{6132}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{6132},\mdline{6132}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{6132}}\\ +\multicolumn{1}{|l}{\mdline{6133} \mdline{6133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{6133}}&\multicolumn{1}{|l|}{\mdline{6133} See section\mdline{6133}~\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1}\mdline{6133}}\\ +\multicolumn{1}{|l}{\mdline{6134} \mdline{6134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6134}}&\multicolumn{1}{|l|}{\mdline{6134} See sections\mdline{6134}~\mdref{sec-user-defined-types}{8.5.6}\mdline{6134},\mdline{6134}~\mdref{sec-translation-of-port-numbers}{18.1.1}\mdline{6134}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={6136} +\mdhr{}%mdk + +%mdk-data-line={6137} +\noindent\mdline{6137}\mdcaption{\textbf{Table~\mdcaptionlabel{7}.}~\mdcaptiontext{P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-annotations}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={6140} +\subsection{\mdline{6140}A.3.\hspace*{0.5em}\mdline{6140}A More Complex Value Set Example}\label{sec-value-set-example}%mdk%mdk + +%mdk-data-line={6142} +\noindent\mdline{6142}This section includes a more complex Value Set example, with multiple matches of +different kinds.%mdk + +%mdk-data-line={6145} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6146} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6155} +\noindent\mdline{6155}This P4 Value Set declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={6158} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6159} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6186} +\noindent\mdline{6186}A P4Runtime client can set the membership for this Value Set with \mdline{6186}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6186} +messages similar to this one:%mdk + +%mdk-data-line={6189} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6190} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xac}~\}\\ +~~~~~~\}\\ +~~~~~~{\mdcolor{darkgreen}\#~match~for~field\_id~2~is~missing~=\textgreater{}~don't~care~match}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xdc}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~~~ternary~\{~value:~{\mdcolor{purple}0x88}~mask:~{\mdcolor{purple}8}f~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6224} +\subsection{\mdline{6224}A.4.\hspace*{0.5em}\mdline{6224}Guidelines for Implementations}\label{sec-guidelines-for-implementations}%mdk%mdk + +%mdk-data-line={6226} +\noindent\mdline{6226}This section contains practical advice for implementing P4Runtime clients and +servers.%mdk + +%mdk-data-line={6229} +\subsubsection{\mdline{6229}A.4.1.\hspace*{0.5em}\mdline{6229}gRPC Metadata Maximum Size}\label{sec-grpc-metadata-maximum-size}%mdk%mdk + +%mdk-data-line={6231} +\noindent\mdline{6231}In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the \mdline{6232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6232} gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the \mdline{6233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6233} P4Runtime RPC. The \mdline{6233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6233} RPC +returns an individual error for every item in a batch (see Section +\mdline{6235}\mdref{sec-write-rpc}{12}\mdline{6235}), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +\mdline{6237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{6237} error, without any of the individual errors.%mdk + +%mdk-data-line={6239} +\mdline{6239}To fix this problem, one can set the \mdline{6239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6239} option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it\mdline{6241}'\mdline{6241}s +limit, as only the receiving side\mdline{6242}'\mdline{6242}s limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every \mdline{6244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{6244}, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +\mdline{6246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}8192~+~MAX\_UPDATES\_PER\_WRITE~*~100}}}\mdline{6246} bytes of metadata.%mdk + +%mdk-data-line={6248} +\mdline{6248}For example, in C++, one can create a client channel as follows:%mdk + +%mdk-data-line={6249} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6250} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}~=~{\mdcolor{purple}100};\\ +::{\mdcolor{navy}grpc::}ChannelArguments~arguments;\\ +arguments{\bfseries{\mdcolor{navy}.}}SetInt({\mdcolor{teal}GRPC\_ARG\_MAX\_METADATA\_SIZE},~{\mdcolor{purple}8192}~+~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}*{\mdcolor{purple}100});\\ +{\bfseries{\mdcolor{navy}return}}~{\mdcolor{navy}grpc::}CreateCustomChannel(address,~credentials,~arguments);}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6256} +\subsubsection{\mdline{6256}A.4.2.\hspace*{0.5em}\mdline{6256}gRPC Server Maximum Receive Message Size}\label{sec-grpc-server-maximum-receive-message-size}%mdk%mdk + +%mdk-data-line={6258} +\noindent\mdline{6258}At the time of writing, the default maximum receive message size in gRPC is 4MB +\mdline{6259}\textemdash{}\mdline{6259} while the default maximum send message size is unlimited. This can be a +problem for the \mdline{6260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{6260} RPC, since for some targets the +binary \mdline{6261}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6261} can exceed 4MB, in which case by default the P4Runtime +server would return an \mdline{6262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6262} error. To a lesser extent, this may +affect the \mdline{6263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6263} RPC as well, in case of extremely large batches.%mdk + +%mdk-data-line={6265} +\mdline{6265}To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of \mdline{6267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6267} for their target(s). This can be done by +setting the \mdline{6268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_receive\_message\_length}}}\mdline{6268} when building the gRPC server.%mdk + +%mdk-data-line={6270} +\mdline{6270}For example, in C++, one can set the maximum receive message size as follows:%mdk + +%mdk-data-line={6271} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6272} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE}~=~{\mdcolor{purple}128}~*~{\mdcolor{purple}1024}~*~{\mdcolor{purple}1024};~~{\mdcolor{darkgreen}//~128MB}\\ +::{\mdcolor{navy}grpc::}ServerBuilder~server\_builder;\\ +builder{\bfseries{\mdcolor{navy}.}}AddListeningPort({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});\\ +builder{\bfseries{\mdcolor{navy}.}}RegisterService({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});~~{\mdcolor{darkgreen}//~register~P4Runtime~service}\\ +builder{\bfseries{\mdcolor{navy}.}}SetMaxReceiveMessageSize({\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE});\\ +builder{\bfseries{\mdcolor{navy}.}}BuildAndStart();}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6280} +\noindent\mdline{6280}On the client side, we recommend that P4Runtime clients do not use \mdline{6280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6280} +batches larger than the default maximum receive message size (4MB)\mdline{6281} \mdline{6281}\textemdash{}\mdline{6281} in case +the server did not deem necessary to increase the default value\mdline{6282} \mdline{6282}\textemdash{}\mdline{6282}, unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB).%mdk + +%mdk-data-line={6288;build/P4Runtime-Spec-bib.bbl.mdk:1} +%mdk-data-line={6288;build/P4Runtime-Spec-bib.bbl.mdk:2} +\mdsetrefname{References}%mdk +{\mdbibindent{0}%mdk +\begin{thebibliography}{39}%mdk +\label{sec-bibliography}%mdk + +%mdk-data-line={references.bib:68} +\bibitem{p4spec}\mdbibitemlabel{{}[1]}\textquotedblleft{}$P4_{16}$ 1.2.1 Specification.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html}}.\label{p4spec}%mdk%mdk + +%mdk-data-line={references.bib:134} +\bibitem{rfc2698}\mdbibitemlabel{{}[2]}\textquotedblleft{}A Two Rate Three Color Marker.\textquotedblright{} \href{https://tools.ietf.org/html/rfc2698}{{\ttfamily https://\hspace{0pt}tools.\hspace{0pt}ietf.\hspace{0pt}org/\hspace{0pt}html/\hspace{0pt}rfc2698}}.\label{rfc2698}%mdk%mdk + +%mdk-data-line={references.bib:32} +\bibitem{p4complextypes}\mdbibitemlabel{{}[3]}\textquotedblleft{}Complex Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-p4-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}p4-\hspace{0pt}type}}.\label{p4complextypes}%mdk%mdk + +%mdk-data-line={references.bib:37} +\bibitem{protodefaults}\mdbibitemlabel{{}[4]}\textquotedblleft{}Default Values for Protobuf 3 ($proto3$) Fields.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23default}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}default}}.\label{protodefaults}%mdk%mdk + +%mdk-data-line={references.bib:78} +\bibitem{p4enums}\mdbibitemlabel{{}[5]}\textquotedblleft{}Enums in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-enum-types}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}enum-\hspace{0pt}types}}.\label{p4enums}%mdk%mdk + +%mdk-data-line={references.bib:119} +\bibitem{apiversioning}\mdbibitemlabel{{}[6]}\textquotedblleft{}Google Cloud APIs Versioning.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning}}.\label{apiversioning}%mdk%mdk + +%mdk-data-line={references.bib:124} +\bibitem{apiversioningbackwardscompatibility}\mdbibitemlabel{{}[7]}\textquotedblleft{}Google Cloud APIs Versioning - Backwards-Compatibility.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning\%23backwards_compatibility}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning\#\hspace{0pt}backwards\_\hspace{0pt}compatibility}}.\label{apiversioningbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:149} +\bibitem{grpcauth}\mdbibitemlabel{{}[8]}\textquotedblleft{}gRPC Authentication.\textquotedblright{} \href{https://grpc.io/docs/guides/auth.html}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}guides/\hspace{0pt}auth.\hspace{0pt}html}}.\label{grpcauth}%mdk%mdk + +%mdk-data-line={references.bib:7} +\bibitem{grpc}\mdbibitemlabel{{}[9]}\textquotedblleft{}gRPC Main Site.\textquotedblright{} \href{https://grpc.io}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io}}.\label{grpc}%mdk%mdk + +%mdk-data-line={references.bib:144} +\bibitem{grpcstreamc}\mdbibitemlabel{{}[10]}\textquotedblleft{}gRPC Streaming RPCs in C++.\textquotedblright{} \href{https://grpc.io/docs/tutorials/basic/c.html\%23streaming-rpcs}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}tutorials/\hspace{0pt}basic/\hspace{0pt}c.\hspace{0pt}html\#\hspace{0pt}streaming-\hspace{0pt}rpcs}}.\label{grpcstreamc}%mdk%mdk + +%mdk-data-line={references.bib:114} +\bibitem{p4newtypes}\mdbibitemlabel{{}[11]}\textquotedblleft{}Introducing New Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-newtype}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}newtype}}.\label{p4newtypes}%mdk%mdk + +%mdk-data-line={references.bib:139} +\bibitem{p4matchtypes}\mdbibitemlabel{{}[12]}\textquotedblleft{}Match Types in P4.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-match-kind-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}match-\hspace{0pt}kind-\hspace{0pt}type}}.\label{p4matchtypes}%mdk%mdk + +%mdk-data-line={references.bib:194} +\bibitem{p4annotations}\mdbibitemlabel{{}[13]}\textquotedblleft{}P4 Annotations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-annotations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}annotations}}.\label{p4annotations}%mdk%mdk + +%mdk-data-line={references.bib:174} +\bibitem{p4concurrency}\mdbibitemlabel{{}[14]}\textquotedblleft{}P4 Concurrency Model.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-concurrency}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}concurrency}}.\label{p4concurrency}%mdk%mdk + +%mdk-data-line={references.bib:1} +\bibitem{p4runtimerepo}\mdbibitemlabel{{}[15]}\textquotedblleft{}p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.\textquotedblright{} \href{https://github.com/p4lang/p4runtime}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4runtime}}.\label{p4runtimerepo}%mdk%mdk + +%mdk-data-line={references.bib:42} +\bibitem{pirepo}\mdbibitemlabel{{}[16]}\textquotedblleft{}p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.\textquotedblright{} \href{https://github.com/p4lang/PI}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}PI}}.\label{pirepo}%mdk%mdk + +%mdk-data-line={references.bib:109} +\bibitem{p4apiwgcharter}\mdbibitemlabel{{}[17]}\textquotedblleft{}P4.org API Working Group Charter.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4_API_WG_charter.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4\_\hspace{0pt}API\_\hspace{0pt}WG\_\hspace{0pt}charter.\hspace{0pt}html}}.\label{p4apiwgcharter}%mdk%mdk + +%mdk-data-line={references.bib:154} +\bibitem{p4actionannotations}\mdbibitemlabel{{}[18]}\textquotedblleft{}P4 Standard Annotations on Table Actions.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-action-anno}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}action-\hspace{0pt}anno}}.\label{p4actionannotations}%mdk%mdk + +%mdk-data-line={references.bib:73} +\bibitem{psa}\mdbibitemlabel{{}[19]}\textquotedblleft{}Portable Switch Architecture Specification (v1.1.0).\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html}}.\label{psa}%mdk%mdk + +%mdk-data-line={references.bib:189} +\bibitem{protooneofbackwardscompatibility}\mdbibitemlabel{{}[20]}\textquotedblleft{}Protobuf OneOf Backwards-Compatibility Issues.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23backwards-compatibility-issues}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}backwards-\hspace{0pt}compatibility-\hspace{0pt}issues}}.\label{protooneofbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:12} +\bibitem{proto}\mdbibitemlabel{{}[21]}\textquotedblleft{}Protocol Buffers Main Site.\textquotedblright{} \href{https://developers.google.com/protocol-buffers}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers}}.\label{proto}%mdk%mdk + +%mdk-data-line={references.bib:159} +\bibitem{psaactionselector}\mdbibitemlabel{{}[22]}\textquotedblleft{}PSA Action Selector.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-action-selector}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}action-\hspace{0pt}selector}}.\label{psaactionselector}%mdk%mdk + +%mdk-data-line={references.bib:169} +\bibitem{psaatomicityofcontrolplaneops}\mdbibitemlabel{{}[23]}\textquotedblleft{}PSA Atomicity of Control Plane Operations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-atomicity-of-control-plane-api-operations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}atomicity-\hspace{0pt}of-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}api-\hspace{0pt}operations}}.\label{psaatomicityofcontrolplaneops}%mdk%mdk + +%mdk-data-line={references.bib:179} +\bibitem{psatranslation}\mdbibitemlabel{{}[24]}\textquotedblleft{}PSA Data Plane vs Control Plane Types.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-data-plane-vs-control-plane-values}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}data-\hspace{0pt}plane-\hspace{0pt}vs-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}values}}.\label{psatranslation}%mdk%mdk + +%mdk-data-line={references.bib:164} +\bibitem{psaemptygroupactionappendix}\mdbibitemlabel{{}[25]}\textquotedblleft{}PSA Empty Group Action Appendix.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23appendix-empty-action-selector-groups}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}appendix-\hspace{0pt}empty-\hspace{0pt}action-\hspace{0pt}selector-\hspace{0pt}groups}}.\label{psaemptygroupactionappendix}%mdk%mdk + +%mdk-data-line={references.bib:58} +\bibitem{p4selectexpr}\mdbibitemlabel{{}[26]}\textquotedblleft{}Select Expressions in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-select}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}select}}.\label{p4selectexpr}%mdk%mdk + +%mdk-data-line={references.bib:129} +\bibitem{semver}\mdbibitemlabel{{}[27]}\textquotedblleft{}Semantic Versioning.\textquotedblright{} \href{https://semver.org/}{{\ttfamily https://\hspace{0pt}semver.\hspace{0pt}org/\hspace{0pt}}}.\label{semver}%mdk%mdk + +%mdk-data-line={references.bib:98} +\bibitem{protostatus}\mdbibitemlabel{{}[28]}\textquotedblleft{}Status.proto:the Protobuf Status Message.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}src/\hspace{0pt}proto/\hspace{0pt}grpc/\hspace{0pt}status/\hspace{0pt}status.\hspace{0pt}proto}}.\label{protostatus}%mdk%mdk + +%mdk-data-line={references.bib:63} +\bibitem{p4revisions110}\mdbibitemlabel{{}[29]}\textquotedblleft{}Summary of Changes Made in $P4_{16}$ Version 1.1.0.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-summary-of-changes-made-in-version-110}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}summary-\hspace{0pt}of-\hspace{0pt}changes-\hspace{0pt}made-\hspace{0pt}in-\hspace{0pt}version-\hspace{0pt}110}}.\label{p4revisions110}%mdk%mdk + +%mdk-data-line={references.bib:48} +\bibitem{p4tableproperties}\mdbibitemlabel{{}[30]}\textquotedblleft{}Table Properties in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-props}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}props}}.\label{p4tableproperties}%mdk%mdk + +%mdk-data-line={references.bib:83} +\bibitem{protoany}\mdbibitemlabel{{}[31]}\textquotedblleft{}The Any Protobuf Message.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23any}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}any}}.\label{protoany}%mdk%mdk + +%mdk-data-line={references.bib:88} +\bibitem{grpcstatus}\mdbibitemlabel{{}[32]}\textquotedblleft{}The gRPC $Status$ Class.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/status.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}impl/\hspace{0pt}codegen/\hspace{0pt}status.\hspace{0pt}h}}.\label{grpcstatus}%mdk%mdk + +%mdk-data-line={references.bib:104} +\bibitem{grpcerrordetails}\mdbibitemlabel{{}[33]}\textquotedblleft{}The gRPC C++ Error Details Library.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/support/error_details.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}support/\hspace{0pt}error\_\hspace{0pt}details.\hspace{0pt}h}}.\label{grpcerrordetails}%mdk%mdk + +%mdk-data-line={references.bib:93} +\bibitem{grpcstatuscodes}\mdbibitemlabel{{}[34]}\textquotedblleft{}The gRPC Canonical Status Codes.\textquotedblright{} \href{https://developers.google.com/maps-booking/reference/grpc-api/status_codes}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}maps-\hspace{0pt}booking/\hspace{0pt}reference/\hspace{0pt}grpc-\hspace{0pt}api/\hspace{0pt}status\_\hspace{0pt}codes}}.\label{grpcstatuscodes}%mdk%mdk + +%mdk-data-line={references.bib:22} +\bibitem{openconfig}\mdbibitemlabel{{}[35]}\textquotedblleft{}The OpenConfig Project.\textquotedblright{} \href{http://openconfig.net}{{\ttfamily http://\hspace{0pt}openconfig.\hspace{0pt}net}}.\label{openconfig}%mdk%mdk + +%mdk-data-line={references.bib:184} +\bibitem{protomessagedifferencer}\mdbibitemlabel{{}[36]}\textquotedblleft{}The Protobuf MessageDifferencer in the C++ API.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.util.message_differencer}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}reference/\hspace{0pt}cpp/\hspace{0pt}google.\hspace{0pt}protobuf.\hspace{0pt}util.\hspace{0pt}message\_\hspace{0pt}differencer}}.\label{protomessagedifferencer}%mdk%mdk + +%mdk-data-line={references.bib:27} +\bibitem{stratum}\mdbibitemlabel{{}[37]}\textquotedblleft{}The Stratum Project.\textquotedblright{} \href{https://stratumproject.org/}{{\ttfamily https://\hspace{0pt}stratumproject.\hspace{0pt}org/\hspace{0pt}}}.\label{stratum}%mdk%mdk + +%mdk-data-line={references.bib:199} +\bibitem{v1model}\mdbibitemlabel{{}[38]}\textquotedblleft{}v1model Architecture Definition.\textquotedblright{} \href{https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4c/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}p4include/\hspace{0pt}v1model.\hspace{0pt}p4}}.\label{v1model}%mdk%mdk + +%mdk-data-line={references.bib:53} +\bibitem{p4valuesets}\mdbibitemlabel{{}[39]}\textquotedblleft{}Value Sets in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-value-set}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}value-\hspace{0pt}set}}.\label{p4valuesets}%mdk%mdk +\par%mdk +\end{thebibliography}}%mdk%mdk +}%mdk + + +\end{document} diff --git a/spec/v1.2.0/ellipse.sty b/spec/v1.2.0/ellipse.sty new file mode 100644 index 00000000..7c0ecb3e --- /dev/null +++ b/spec/v1.2.0/ellipse.sty @@ -0,0 +1,318 @@ +%% +%% This is file `ellipse.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ellipse.dtx (with options: `package') +%% +%% Copyright (C) 2015 +%% Daan Leijen +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". +%% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{ellipse} + [2004/11/05 v1.0 .dtx ellipse file] +\RequirePackage{pict2e} + +\providecommand*\pIIe@csedef[1]{\expandafter\edef\csname #1\endcsname} +\newcommand*\pIIe@ellip@csqrt[3]{% + \@ovxx=#1\relax + \ifdim\@ovxx<\z@\@ovxx-\@ovxx\fi + \@ovyy=#2\relax + \ifdim\@ovyy<\z@\@ovyy-\@ovyy\fi + \edef\pIIe@csname{@csqrt(\number\@ovxx,\number\@ovyy)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@ellip@csqrt@% + \pIIe@csedef{\pIIe@csname}{\the\dimen@}% + #3\dimen@ + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} +\newcommand*\pIIe@ellip@csqrt@{% + \@ovdx\@ovxx + \advance\@ovdx by \@ovyy + \dimen@0.7071067\@ovdx + \ifdim\dimen@<\@ovyy\dimen@\@ovyy\fi + \ifdim\dimen@<\@ovxx\dimen@\@ovxx\fi + \ifdim\@ovdx<128\p@ + \edef\@tempa{\strip@pt\@ovxx}% + \@ovxx\@tempa\@ovxx + \edef\@tempa{\strip@pt\@ovyy}% + \@ovyy\@tempa\@ovyy + \advance\@ovxx by \@ovyy + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \fi +} + +\newcommand*\pIIe@atan@{% + \@tempdima\dimen@ + \@tempdimb\@tempdima + \ifdim\@tempdimb<\z@\@tempdimb-\@tempdimb\fi + \dimen@0.0663\@tempdimb + \advance\dimen@ 0.2447pt\relax + \advance\@tempdimb -1pt\relax + \edef\@tempa{\strip@pt\@tempdimb}% + \dimen@\@tempa\dimen@ + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \dimen@-\dimen@ + \advance\dimen@ 0.7853\@tempdima +} + +\newcommand*\pIIe@atantwo[3]{% + \edef\pIIe@csname{@atan2(\number\dimexpr#1\relax,\number\dimexpr#2\relax)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@atantwo@{#1}{#2}{#3}% + \pIIe@csedef{\pIIe@csname}{\the\dimexpr#3\relax}% + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} + +\newcommand*\pIIe@atantwo@[3]{% + \@tempdima\dimexpr#2\relax + \@tempdimb\dimexpr#1\relax + \ifdim\@tempdima=\z@\relax + \ifdim\@tempdimb>\z@\relax\dimen@90\p@ + \else\ifdim\@tempdimb<\z@\relax\dimen@-90\p@ + \else\dimen@0\p@ + \fi\fi + \else + \@tempdimd\z@ + \ifdim\@tempdima<\z@\relax + \ifdim\@tempdimb<\z@\relax\@tempdimd-180\p@ + \else\@tempdimd180\p@ + \fi + \fi + \dimen@\dimexpr1pt * \@tempdimb/\@tempdima\relax + \@tempdimc\dimen@ + \ifdim\@tempdimc<\z@\relax\@tempdimc-\@tempdimc\fi + \ifdim\@tempdimc>\p@\relax + \dimen@\dimexpr1pt * \@tempdima/\@tempdimb\relax + \ifdim\dimen@<\z@\relax\def\@tempsign{-}\else\def\@tempsign{}\fi + \pIIe@atan@ + \dimen@-\dimen@ + \advance\dimen@ by \@tempsign1.5707pt\relax + \else + \pIIe@atan@ + \fi + \dimen@57.29578\dimen@ + \advance\dimen@ by \@tempdimd + \fi + #3\dimen@% +} + +\newcommand*\pIIe@noneto[2]{} +\newcommand*\pIIe@ellip@sincost@[2]{% + \CalculateSin{#1}% + \CalculateCos{#1}% + \@tempdima\UseSin{#1}\p@ + \@tempdimb\UseCos{#1}\p@ + \ifdim\@tempdima=\p@\relax + \pIIe@csedef{@ellipsin#2}{1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else\ifdim\@tempdima=-\p@\relax + \pIIe@csedef{@ellipsin#2}{-1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else + \@tempdimc\@ellipratio\dimexpr1pt * \@tempdima/\@tempdimb\relax + %\typeout{ i#2=\the\@tempdimc, sin(#1)=\the\@tempdima}% + \pIIe@ellip@csqrt{\p@}{\@tempdimc}\@tempdimd + \ifdim\@tempdimb<\z@\relax\@tempdimd-\@tempdimd\fi + \pIIe@csedef{@ellipsin#2}{\strip@pt\dimexpr1pt * \@tempdimc/\@tempdimd\relax}% + \pIIe@csedef{@ellipcos#2}{\strip@pt\dimexpr1pt * \p@/\@tempdimd\relax}% + \fi\fi +} + +\newcommand*\pIIe@ellip@sincost[2]{% + %\typeout{ calc sin cos: angles (#1,#2), radii: (\the\@ovro,\the\@ovri)}% + \edef\@ellipratio{\strip@pt\dimexpr1pt * \@ovro/\@ovri\relax}% + \pIIe@ellip@sincost@{#1}{one}% + \pIIe@ellip@sincost@{#2}{two}% + %\typeout{ sincos(a=#1)=(\@ellipsinone,\@ellipcosone), sincos(a=#2)=(\@ellipsintwo,\@ellipcostwo), }% +} +\newcommand*\pIIe@omega[3]{% + \@tempdima\csname @ellipcos#3\endcsname\@ovro + \advance\@tempdima by #1\relax + \@tempdimb\csname @ellipsin#3\endcsname\@ovri + \advance\@tempdimb by #2\relax +} + +\newcommand*\pIIe@omegai[1]{% + \@tempdimc\csname @ellipsin#1\endcsname\@ovro + \@tempdimc-\@tempdimc + \@tempdimd\csname @ellipcos#1\endcsname\@ovri +} + +\newcommand*\pIIe@ellip@kappa{% + \@ovyy\@ellipsinone\p@ + \@ovxx\@ellipcosone\p@ + \@tempdima\@ellipcostwo\@ovyy + \@tempdima-\@tempdima + \advance\@tempdima by \@ellipsintwo\@ovxx + \@tempdimb\@ellipcostwo\@ovxx + \advance\@tempdimb by \@ellipsintwo\@ovyy + \ifdim\@tempdima=\z@\relax + \edef\@ellipkappa{0}% + \else + \dimen@\dimexpr1pt - \@tempdimb\relax + \dimen@\dimexpr1pt * \dimen@/\@tempdima\relax + \pIIe@ellip@csqrt{2\p@}{1.73205\dimen@}{\dimen@}% + \advance\dimen@ by -\p@ + \divide\dimen@ by 3% + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \edef\@ellipkappa{\strip@pt\dimen@}% + \fi + %\typeout{ calculated kappa: \@ellipkappa}% +} + +\newcommand*\pIIe@elliparc@[5]{% + %\typeout{elliparc: #1, center: (#2, #3), radius (\the\@ovro, \the\@ovri),angle (#4, #5)}% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \pIIe@ellip@sincost{#4}{#5}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@t[5]{% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \CalculateSin{#4}\CalculateCos{#4}% + \edef\@ellipsinone{\UseSin{#4}}% + \edef\@ellipcosone{\UseCos{#4}}% + \CalculateSin{#5}\CalculateCos{#5}% + \edef\@ellipsintwo{\UseSin{#5}}% + \edef\@ellipcostwo{\UseCos{#5}}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@draw[2]{% + \pIIe@ellip@kappa% + \pIIe@omega{#1}{#2}{one}% + %\typeout{ point one: (\the\@tempdima,\the\@tempdimb)}% + \@ellip@startto\@tempdima\@tempdimb + \pIIe@omegai{one}% + \advance\@tempdima by \@ellipkappa\@tempdimc + \advance\@tempdimb by \@ellipkappa\@tempdimd + \pIIe@add@nums\@tempdima\@tempdimb + %\typeout{ control one: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@omega{#1}{#2}{two}% + \pIIe@omegai{two}% + \@tempdimc\@ellipkappa\@tempdimc + \@tempdimd\@ellipkappa\@tempdimd + \@tempdimc-\@tempdimc + \@tempdimd-\@tempdimd + \advance\@tempdimc by \@tempdima + \advance\@tempdimd by \@tempdimb + \pIIe@add@nums\@tempdimc\@tempdimd + %\typeout{ control two: (\the\@tempdimc,\the\@tempdimd)}% + \pIIe@add@CP\@tempdima\@tempdimb + %\typeout{ point two: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@addtoGraph\pIIe@curveto@op +} +\newcommand*\pIIe@elliparc[7][0]{% + \@ovro #4\relax + \@ovri #5\relax + \iffalse%dim\@ovro=\@ovri + \pIIe@arc[#1]{#2}{#3}{#4}{#6}{#7} + \else + \ifdim \@ovro<\z@ \pIIe@badcircarg\else + \ifdim \@ovri<\z@ \pIIe@badcircarg\else + \@arclen #7\p@ \advance\@arclen -#6\p@ + \ifdim \@arclen<\z@ \def\@tempsign{-}\else\def\@tempsign{}\fi + \ifdim \@tempsign\@arclen>720\p@ + \PackageWarning {ellipse}{The arc angle is reduced to -720..720}% + \@whiledim \@tempsign\@arclen>720\p@ \do {\advance\@arclen-\@tempsign360\p@}% + \@tempdima #6\p@ \advance\@tempdima \@arclen + \edef\@angleend{\strip@pt\@tempdima}% + \pIIe@@elliparc{#1}{#2}{#3}{#6}{\@angleend}% + \else + \pIIe@@elliparc{#1}{#2}{#3}{#6}{#7}% + \fi + \fi + \fi + \fi +} +\newcommand*\pIIe@@elliparc[5]{% + \begingroup + \ifdim \@tempsign\@arclen>90\p@ + \divide\@arclen 2% + \@tempdima #4\p@\advance\@tempdima by \@arclen + \edef\@anglemid{\strip@pt\@tempdima}% + \def\@tempa{\pIIe@@elliparc{#1}{#2}{#3}{#4}}% + \expandafter\@tempa\expandafter{\@anglemid}% + \def\@tempa{\pIIe@@elliparc{2}{#2}{#3}}% + \expandafter\@tempa\expandafter{\@anglemid}{#5}% + \else + \pIIe@elliparc@{#1}{#2}{#3}{#4}{#5}% + \fi + \endgroup +}% + +\newcommand*\pIIeelliparc[7][0]{% + \@killglue + \pIIe@elliparc[#1]{#2\unitlength}{#3\unitlength}{#4\unitlength}{#5\unitlength}{#6}{#7}% + \ignorespaces% +} +\ifx\undefined\elliparc\else + \PackageWarning{ellipse}{\protect\elliparc\space is redefined}% +\fi +\let\elliparc\pIIeelliparc + +\newcommand*\pIIeearc + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\newcommand*\pIIe@earc@[3][0,360]{\pIIe@earc@@(#1){#2}{#3}} +\def\pIIe@earc@@(#1,#2)#3#4{% + \if@tempswa + \pIIe@moveto\z@\z@ + \pIIe@elliparc{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@closepath\pIIe@fillGraph + \else + \pIIe@elliparc[1]{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@strokeGraph + \fi} +\ifx\undefined\earc\else + \PackageWarning{ellipse}{\protect\earc\space is redefined}% +\fi +\let\earc\pIIeearc + +\newcommand*\pIIeellipse + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\let\ellipse\pIIeellipse + +\endinput +%% +%% End of file `ellipse.sty'. diff --git a/spec/v1.2.0/embedded-plus-single-remote-controller.png b/spec/v1.2.0/embedded-plus-single-remote-controller.png new file mode 100644 index 00000000..2e0f1803 Binary files /dev/null and b/spec/v1.2.0/embedded-plus-single-remote-controller.png differ diff --git a/spec/v1.2.0/embedded-plus-single-remote-controller.svg b/spec/v1.2.0/embedded-plus-single-remote-controller.svg new file mode 100644 index 00000000..9fe2ce9c --- /dev/null +++ b/spec/v1.2.0/embedded-plus-single-remote-controller.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spec/v1.2.0/embedded-plus-two-remote-controllers.png b/spec/v1.2.0/embedded-plus-two-remote-controllers.png new file mode 100644 index 00000000..b6dc04fc Binary files /dev/null and b/spec/v1.2.0/embedded-plus-two-remote-controllers.png differ diff --git a/spec/v1.2.0/embedded-plus-two-remote-controllers.svg b/spec/v1.2.0/embedded-plus-two-remote-controllers.svg new file mode 100644 index 00000000..0f97ba38 --- /dev/null +++ b/spec/v1.2.0/embedded-plus-two-remote-controllers.svg @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + + + Entities + + + + + + + \ No newline at end of file diff --git a/spec/v1.2.0/embedded-plus-two-remote-ha-controllers.png b/spec/v1.2.0/embedded-plus-two-remote-ha-controllers.png new file mode 100644 index 00000000..f663e9bf Binary files /dev/null and b/spec/v1.2.0/embedded-plus-two-remote-ha-controllers.png differ diff --git a/spec/v1.2.0/embedded-plus-two-remote-ha-controllers.svg b/spec/v1.2.0/embedded-plus-two-remote-ha-controllers.svg new file mode 100644 index 00000000..710111fa --- /dev/null +++ b/spec/v1.2.0/embedded-plus-two-remote-ha-controllers.svg @@ -0,0 +1,510 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + Master (Active) + + + + + + Slave (Standby) + + + + + + + \ No newline at end of file diff --git a/spec/v1.2.0/error-report.png b/spec/v1.2.0/error-report.png new file mode 100644 index 00000000..766cb77f Binary files /dev/null and b/spec/v1.2.0/error-report.png differ diff --git a/spec/v1.2.0/error-report.svg b/spec/v1.2.0/error-report.svg new file mode 100644 index 00000000..a2709a72 --- /dev/null +++ b/spec/v1.2.0/error-report.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StatusCode error_code_; // canonical error codestring error_message_;string binary_error_details_; // serialized google.rpc.Status + + + + + + + + + + + + + google.rpc.Status + + + + + + int32 error_code; // canonical error codestring message;repeated Any details; // P4Error + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + + + p4.Error + + + + + + p4.Error + + + + + + + + + + + + + + + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + grpc::Status + + + + + + + \ No newline at end of file diff --git a/spec/v1.2.0/longbox.sty b/spec/v1.2.0/longbox.sty new file mode 100644 index 00000000..cab48934 --- /dev/null +++ b/spec/v1.2.0/longbox.sty @@ -0,0 +1,853 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longbox}[2015/12/01, Daan Leijen, Provides basic longbox that can break over pages] +\RequirePackage{options} + +\@ifclassloaded{beamer}{% + \newcommand\lb@savefootnotes{}% + \newcommand\lb@restorefootnotes{}% +}% +{\RequirePackage{footnote}% + \newcommand\lb@savefootnotes{\savenotes}% + \newcommand\lb@restorefootnotes{\spewnotes}% +} + + +% -------------------------------------------------------- +% Debugging +% -------------------------------------------------------- + +\newcommand*\lb@debug[1]{% + \ontoggle{lb@debug}{\typeout{longbox debug: #1}}% +} +\newcommand*\lb@typeout[1]{% + \ontoggle{lb@verbose}{\typeout{longbox: #1}}% +} +\newcommand*\lb@warncannotsplit{% + \PackageWarning{longbox}{Cannot split box; it seems you are using a non-splittable contents}% +} +\newcommand*\lb@warnbadsplit[1]{% + \PackageWarning{longbox}{Bad split (underful vbox by \the#1)}% +} + + +% -------------------------------------------------------- +% Utilities for LaTeX internals +% -------------------------------------------------------- + +% Suppress the indentation on the following paragraph +\providecommand\nofirstindent{\@afterindentfalse\@afterheading} + +% Suppress the paragraph skip on the following paragraph +\providecommand\nofirstparskip{\addvskip{-\parskip}} + +% In contrast to addvspace, addvskip is not suppressed in a minipage +\providecommand\addvskip[1]{% + \ifvmode + \ifdim\lastskip=\z@ + \vskip #1\relax + \else + \@tempskipb#1\relax\@xaddvskip + \fi + \else\@noitemerr\fi +} + + +% Skip to 0.3\baselineskip multiple taking prevdepth into account. +\newskip\lb@prevdepth +\newcommand\lb@skiptobaseline{% + \global\lb@prevdepth=-\@m\p@\relax + \ifvmode + \ifdim\lastskip=\z@\relax + \ifdim\prevdepth=-\@m\p@\else + \dimen@\prevdepth + % Calculate the modulus of the previous depth with 0.3|\baselineskip| in |\dimen@|. + \@tempcnta\prevdepth + \@tempskipa=0.3\baselineskip\relax + \@tempcntb=\@tempskipa\relax + \divide \@tempcnta by \@tempcntb + \dimen@\prevdepth + \advance\dimen@ -\@tempcnta\@tempskipa + % Skip back by that amount, and then skip by 0.3|\baselineskip|. + \vskip -\dimen@ + \vskip \@tempskipa\relax + \global\lb@prevdepth=\@tempskipa\relax + \fi + \fi + \fi +} + +% unvbox a box, and return a vbox with a given background color +% \unvcolorbox{}{} +\newcommand\unvcolorbox[2]{% + \ifoptionblank{#1}{\vbox{\unvbox#2}}{% + \lb@debug{vcolorbox: #1}% + \vbox{\offinterlineskip + \hbox to \z@{\vbox to \z@{\optioncolor{#1}\hrule\@width\wd#2\@height\ht#2\@depth\dp#2\vss}\hss}% + \unvbox#2% + }% + }% +} + +% create a vbox with a given background color +\newcommand\vcolorbox[2]{% + \eifblank{#1}{\vbox{#2}}{% + \setbox\z@=\vbox{#2}\relax + \unvcolorbox{#1}{\z@}% + }% +}% + +% -------------------------------------------------------- +% The following macros come from mdframed +% -------------------------------------------------------- + +% Determine the amount of free space left on the current page +\newlength\lb@freevspace +\newcommand*\lb@setfreevspace@page{% + \lb@debug{ determine free space}% + \bgroup\@nobreakfalse\addpenalty\z@\egroup% + \penalty\@M\relax\vskip 2\baselineskip\relax% + \penalty9999\relax\vskip -2\baselineskip\relax% + \penalty9999% + \ifdim\pagegoal=\maxdimen\relax% + \lb@freevspace=\vsize% + \else + \lb@freevspace=\dimexpr\pagegoal-\pagetotal-\parskip\relax% + \fi + \lb@debug{free space: \the\lb@freevspace, in page: \the\textheight, vsize=\the\vsize}% +} + +\newcommand*\lb@shiftdim[2]{% + %\letoption{#1}\lb@list + \expandafter\lb@setheadtail@#1,\relax + \eifblank{\lb@head}{}{\option@invoke{/longbox/@breakat-previous}{\lb@head}}% + #2\option{/longbox/@breakat-previous}% + \eifblank{\lb@tail}{}{\let#1\lb@tail}% push back tail +} +\def\lb@comma{,}% +\def\lb@setheadtail@#1,#2\relax{% + \def\lb@head{#1}% + \def\lb@tail{#2}% adds commas! +} + +\newcommand*\lb@setfreevspace{% + \eifblank{\lb@breakat}{\lb@setfreevspace@page}{% + \def\lb@eject{\par}%no eject + \lb@extrasplit=\z@\relax% + \lb@shiftdim{\lb@breakat}\lb@freevspace + \ifdim\lb@freevspace>\z@\else\lb@setfreevspace@page\fi + }% +} + + +% Suppress overfull-underfull vbox messages +\newcommand*\lb@ignorevbadness{% + \edef\lb@currentvbadness{\the\vbadness}% + \edef\lb@currentvfuzz{\the\vfuzz}% + \vbadness=\@M\relax% + \vfuzz=\maxdimen\relax% + \afterassignment\lb@restorevbadness +} +\newcommand*\lb@restorevbadness{% + \vbadness=\lb@currentvbadness\relax + \vfuzz=\lb@currentvfuzz\relax +} + + +% -------------------------------------------------------- +% The 'long vbox' (lvbox) environment collects long material +% into a long \vbox, instead of a \hbox like a lrbox in latex. +% The collected box can contain any box, minipage, lrbox, fbox etc, +% but not outer-par material like a figure. Footnotes can be +% dealt with useing lb@savefootnotes. +% +% The material is typeset in a \vbox according to a given width. +% inside the environment, the boolean 'inlvbox' is true. +% +% \begin{lvbox}{}{} +% -------------------------------------------------------- + +\newif\ifinlvbox +\newcommand\lvbox[4]{% + \setbox#1\vbox\bgroup + \begingroup + \inlvboxtrue + % reset defaults + \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\par\@@par + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + % set margin and linewidth + \leftmargin=#2\relax\rightmargin=#4\relax + \@totalleftmargin=\leftmargin% + %\leftskip=#2\relax\rightskip=#4\relax\@rightskip=#4\relax + \linewidth=#3\relax + % set primitive tex margins + \leftskip=\@totalleftmargin% + \rightskip=\rightmargin% + \@rightskip=\rightmargin% + \hsize=\dimexpr\@totalleftmargin+\linewidth+\rightmargin\relax + \columnwidth\hsize + \textwidth\hsize + \nofirstindent + %\nofirstparskip +} +\def\endlvbox{\endgroup\egroup} + + + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + + +\newsavebox\lb@headbox +\newsavebox\lb@savebox +\newsavebox\lb@mainbox + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@setbaseline[1]{% + %\typeout{ set baseline, \the\dp#1,\the\ht#1}% + \ifcase\lb@baseline% + \relax%bottom + \or%middle + \setbox#1=\vbox{\hbox{\lower \dimexpr(\dp#1 + \ht#1)/2 - \dp#1\relax\vbox{\unvbox#1}}}% + \or%top + \setbox#1=\vtop{\unvbox#1}% + \fi + %\typeout{ .new dim: \the\dp#1, \the\ht#1}% +} + + +\@ifundefined{define@key}{}% + {\define@key{longbox}{options}{\options{#1}\option{/longbox/adjust-options}}}% + +\newcommand*\lb@render@breakbox{% + %\typeout{render breakbox entry (in output routine), height=\the\bb@height}% + \bb@restorekeys{longbox}% + \lb@skiptop=\ifbb@isfirst\option{/longbox/skip-top}\else\option{/longbox/skip-break-top}\fi\relax + \lb@skipbottom=\ifbb@islast\option{/longbox/skip-bottom}\else\option{/longbox/skip-break-bottom}\fi\relax + \lb@skipbreaktop=\ifbb@isfirst 0pt\else\option{/longbox/skip-break-top}\fi + \lb@skipbreakbottom=\ifbb@islast 0pt\else\option{/longbox/skip-break-bottom}\fi + %\typeout{ render: skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom, break-top=\the\dimexpr\option{/longbox/skip-bottom}}% + \options{% + /longbox/@part-height=\bb@height + \lb@skipbreaktop + \lb@skipbreakbottom, + /longbox/@part-width=\option{/longbox/width} + \option{/longbox/skip-left} + \option{/longbox/skip-right},%\bb@width, + /longbox/@part-depth=0pt, + /longbox/@part-needtop=\ifbb@isfirst true\else false\fi, + /longbox/@part-needbottom=\ifbb@islast true\else false\fi, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-depth=\option{/longbox/@part-depth}, + }% + %\typeout{breakbox: width=\expandafter\the\option{/longbox/width}, \the\bb@width, \the\dimexpr\option{/longbox/@part-width}}% + \vbox{% + \kern -\lb@skipbreaktop% todo: move to breakbox? + \option{/longbox/render}% + \kern -\lb@skipbreakbottom + }% +} + +\newcommand*\lb@render@vbox[1]{% + \lb@debug{render vbox entry}% + \lb@restoreoptions + \lb@skiptop=\dimexpr\iftoggle{/longbox/@part-needtop}{\option{/longbox/skip-top}}{\option{/longbox/skip-break-top}}\relax + \lb@skipbottom=\dimexpr\iftoggle{/longbox/@part-needbottom}{\option{/longbox/skip-bottom}}{\option{/longbox/skip-break-bottom}}\relax + %\typeout{ skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom}% + % add top skip while maintaining the baseline. + \ifdim\lb@skiptop=\z@\relax\else + \setbox\z@=\vtop{\unvcopy#1}% + \dimen@=\ht\z@ + \setbox#1=\vbox{\offinterlineskip + \hrule width \z@ height \dimexpr\dimen@ + \lb@skiptop\relax depth -\dimen@ + \unvbox#1% + }% + \fi + % add bottom skip while maintaining the baseline. + \ifdim\lb@skipbottom=\z@\relax\else + \dimen@=\dp#1% + \setbox#1=\vbox{\offinterlineskip\unvbox#1\hrule width \z@ height -\dimen@ depth \dimexpr\dimen@ + \lb@skipbottom\relax}% + \fi + \lb@setbaseline{#1}% + \options{% + /longbox/@part-height=\dimexpr\ht#1 + \dp#1\relax, + /longbox/@part-width=\dimexpr\wd#1 + \option{/longbox/skip-left} + \option{/longbox/skip-right}\relax, + /longbox/@part-depth=\dp#1, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-depth=\option{/longbox/@part-depth} - \lb@skipbottom, + }% + %\typeout{ longbox: height=\the\dimexpr\option{/longbox/@content-box-height}, outer height=\the\dimexpr\option{/longbox/@part-height}\relax}% + % lower the box depending on vertical alignment + \ifcase\option{/longbox/vertical-align/@ord}\relax + \@tempdima\z@ + \or + %bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%middle + \@tempdima\dimexpr0.5\option{/longbox/@part-height} - \option{/longbox/@part-depth}\relax + \or%top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%text-bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%text-top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%super + \@tempdima=-0.9ex% + \or%sub + \@tempdima=0.7ex% + \else + \@tempdima\z@ + \fi + \advance\@tempdima by -\option{/longbox/raise}% + \option@invoke{/longbox/@lower}{\@tempdima}% + \noindent\hbox{\lower \@tempdima\vbox{\offinterlineskip + \hbox to \z@{% + \vbox to \z@{% + \hbox{\lower \option{/longbox/@part-height}\vbox{\offinterlineskip{\option{/longbox/render}}}}% + \vss}% + \hss + }% + \hbox{% + \ifdim\option{/longbox/skip-left}=\z@\else\hskip\option{/longbox/skip-left}\fi + \box#1% + \ifdim\option{/longbox/skip-right}=\z@\else\hskip\option{/longbox/skip-right}\fi + %$\box#1% + }% + }}% +} + +\newcommand*\lb@single@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} +\newcommand*\lb@first@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@middle@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@last@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand*\lb@env@start{% + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore +} + +\newcount\lb@usevbox +\newlength\lb@width +\newlength\lb@height +\newlength\lb@skiptop +\newlength\lb@skipright +\newlength\lb@skipbottom +\newlength\lb@skipleft +\newlength\lb@skipbreaktop +\newlength\lb@skipbreakbottom +\newlength\lb@outerwidth +\newlength\lb@extrasplit +\newcount\lb@textalign +\newcount\lb@baseline +\newtoggle{lb@baselineskip}% +\newtoggle{lb@breakable}% +\newtoggle{lb@debug}% +\newtoggle{lb@verbose}% +\def\lb@breakat{}% +\def\lb@halign{}% +\def\lb@eject{}% +\def\lb@insertafter{} +\def\lb@insertbefore{} + +\newcommand*\lb@peekoptions[1]{% + % process options inside a group and just set necessary parameters + % this way, nested boxes don't influence each other's parameters + \begingroup + \options{#1}% + \option{/longbox/adjust-options}% + \protected@edef\lb@temp{\endgroup + \lb@width=\the\dimexpr\option{/longbox/width}\relax + \lb@height=\the\dimexpr\option{/longbox/height}\relax + \lb@textalign=\the\numexpr\option{/longbox/text-align/@ord}\relax + \lb@baseline=\the\numexpr\option{/longbox/baseline/@ord}\relax + \lb@skiptop=\the\dimexpr\option{/longbox/skip-top}\relax + \lb@skipright=\the\dimexpr\option{/longbox/skip-right}\relax + \lb@skipbottom=\the\dimexpr\option{/longbox/skip-bottom}\relax + \lb@skipleft=\the\dimexpr\option{/longbox/skip-left}\relax + \lb@skipbreaktop=\the\dimexpr\option{/longbox/skip-break-top}\relax + \lb@skipbreakbottom=\the\dimexpr\option{/longbox/skip-break-bottom}\relax + \lb@usevbox=\iftoggle{/longbox/use-vbox}{1}{0}\relax + \lb@outerwidth=\the\dimexpr\option{/longbox/outer-width}\relax + \lb@extrasplit=\the\dimexpr\option{/longbox/split-minimum}\relax + \def\noexpand\lb@insertafter{\option{/longbox/insert-after}}% + \def\noexpand\lb@insertbefore{\option{/longbox/insert-before}}% + \def\noexpand\lb@breakat{\option{/longbox/breakat}}% + \def\noexpand\lb@halign{\option{/longbox/height-align}}% + \def\noexpand\lb@eject{\option{/longbox/eject}}% + \noexpand\csname toggle\iftoggle{/longbox/baseline-skip}{true}{false}\endcsname{lb@baselineskip}% + \noexpand\csname toggle\iftoggle{/longbox/breakable}{true}{false}\endcsname{lb@breakable}% + \noexpand\csname toggle\iftoggle{/longbox/debug}{true}{false}\endcsname{lb@debug}% + \noexpand\csname toggle\iftoggle{/longbox/verbose}{true}{false}\endcsname{lb@verbose}% + }% + \lb@temp +} + +\newenvironment{longbox@env}[2]{% + % save options + \lb@peekoptions{#1,#2}% + % + \ifnum\lb@usevbox=0\relax + \lb@debug{start breakbox}% + \let\bb@render\lb@render@breakbox + \bb@savekeys{longbox}{options={#1,#2,outer-width=\the\lb@outerwidth}}% + \iftoggle{lb@baselineskip}{\typeout{**insert bskip}}{\typeout{**suppress bskip}\vskip 1pt}% + \begin{breakbox}% + \ifdim\lb@skiptop=\z@\relax\else\vspace{\lb@skiptop}\fi% + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \begin{bb@margins}{\lb@skipleft}{\dimen@}% + \else + \lb@debug{start vbox}% + \def\lb@restoreoptions{\options{#1,#2}\option{/longbox/adjust-options}}% + \lb@savefootnotes + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \lb@debug{ width=\the\lb@width, linewidth=\the\linewidth, skipleft=\the\lb@skipleft, right=\the\lb@skipright, total right=\the\dimen@}% + \iftoggle{lb@baselineskip}{\lb@skiptobaseline}{\lb@prevdepth=-\@m pt}% + \lvbox{\lb@mainbox}{0pt}{\lb@width}{0pt}%{\lb@skipleft}{\lb@width}{\lb@skipright}% + \prevdepth=\lb@prevdepth + \fi + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore + \begingroup +}{% + \par\unskip + \endgroup + \lb@insertafter + %\ifdim\lb@skipbottom=\z@\relax\else\vskip\lb@skipbottom\fi% + \ifnum\lb@usevbox=0\relax + \end{bb@margins}% + \ifdim\lb@skipbottom=\z@\relax\else\hrule width \z@ height \lb@skipbottom\fi%\vspace{\lb@skipbottom}\fi% + \iftoggle{lb@baselineskip}{}{\vskip 1sp}% + \end{breakbox}% + \lb@debug{end breakbox}% + \else + \ontoggle{lb@baselineskip}{\lb@skiptobaseline}% + \endlvbox% + \lb@debug{initial lvbox: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@processbox + %\setbox\lb@mainbox=\hbox{\lower \lb@skipbottom\vbox{\offinterlineskip\unvbox\lb@mainbox}}% + \lb@restorefootnotes + \lb@debug{end vbox}% + \fi +} + +\newcommand\longbox@cmd[3]{% + \begingroup + %\options{/options/collectunknown,/longbox/scoped,#2}% set scoped options first + %\option{/longbox/scoped/@adjust-options}% + \lb@peekoptions{#1,#2}% + \leavevmode + %\setbox\lb@mainbox=\hbox{% + % \begingroup + % #3% + % \endgroup + %}% + \setbox\lb@mainbox=\hbox{% + \begingroup + \ifcase\lb@textalign\relax + %default=left + \or%left + \or\hss%center + \or\hss%right + \else%justify + \fi + \lb@insertbefore + #3% + \lb@insertafter + \ifnum\lb@textalign<3\relax\hss\fi% default,left,center + \endgroup + }% + \options{#1,#2}% + \ifdim\option{/longbox/width}=-1sp\relax + \options{/longbox/width=\wd\lb@mainbox}%set to natural width + \fi + \option{/longbox/adjust-options}% + % make it a vbox + \setbox\lb@mainbox=\vbox{\offinterlineskip% + \hbox to \option{/longbox/width}{% + \unhbox\lb@mainbox + }% + }% + \def\lb@restoreoptions{}% + \letoption{/longbox/height-align}\lb@halign + \lb@height=\option{/longbox/height}\relax + \lb@baseline=\option{/longbox/baseline/@ord}\relax + \lb@processbox + \endgroup +} + +\newcommand\lb@processbox{% + \ifdim\lb@height<0pt\relax + \lb@setbaseline{\lb@mainbox}% + \else + \lb@restrictheight + \fi + \lb@typesetbox +} + +\newcommand\lb@typesetbox{% + \ifinlvbox + \iftoggle{lb@breakable}{% + %\lb@debug{disable breakable due to nesting of long-boxes}% + \togglefalse{lb@breakable}% + }{}% + \fi + \ifhmode\lb@single@{\lb@mainbox}\else\lb@typeset\fi +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@restrictheight{% + \lb@typeout{restrict height to \the\lb@height}% + \lb@splitheight=\lb@height% + %lb@debug{before height split: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + %split failed.. do nothing + \lb@debug{could not restrict height}% + \else + % store splitted off content in the mainbox (and discard the rest) + \setbox\lb@mainbox\vbox{\unvbox\lb@headbox}% + \lb@debug{restricted height to \the\ht\lb@mainbox}% + \fi + % set baseline + \lb@setbaseline{\lb@mainbox}% + % height align + %\letoption{/longbox/height-align}\lb@halign + \eifstrequal{\lb@halign}{bottom}% + {\setbox\lb@mainbox=\vbox{\hbox{\vbox to \lb@splitheight{\vss\unvbox\lb@mainbox}}}}% + {\eifstrequal{\lb@halign}{middle}% + {\dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\hbox{% + \lower \dimexpr0.5\dimen@ + \dp\lb@mainbox\relax% + \vbox to \lb@splitheight{\vss\unvbox\lb@mainbox\vss}}}}% + {% default is top + \dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\vtop to \lb@splitheight{\box\lb@mainbox\vss}}% + }% + }% +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newlength\lb@neededvspace +\newcommand\lb@typeset[1][0pt]{% + \iftoggle{lb@breakable}{% + \lb@setfreevspace + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skiptop+\lb@skipbottom\relax}% + \lb@debug{needed: \the\lb@neededvspace, available: \the\lb@freevspace}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@single@{\lb@mainbox}% + \else + \lb@typeout{longbox needs splitting}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skiptop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \ifdim\dimexpr\lb@freevspace + #1\relax<\textheight\relax % test if we were at a fresh page.. (and prevent infinite recursion) + \lb@debug{failed to split the box, inserting a page break}% + \hrule \@height\z@ \@width\hsize + \lb@eject% + \lb@typeset[\textheight]% try again, but pass \textheight to guard against infinite recursion + \else + % on a fresh page we should not fail anymore.. just output as is.. + % lb@warncannotsplit + \lb@single@{\lb@mainbox}% + \fi + \else + % first part success + \lb@typeout{first part splitted}% + \lb@first@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest + \fi + \fi + }{%\else + \lb@debug{unbreakable box}% + \lb@single@{\lb@mainbox}% always directly output an unbreakable box + }% +} + +\newcommand\lb@typesetrest{% + \lb@setfreevspace% + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skipbottom+\lb@skipbreaktop\relax}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@typeout{output last part of box}% + \lb@last@{\lb@mainbox}% + \else + \lb@debug{split box further}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skipbreaktop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \lb@typeout{failed to split box!}% + \lb@last@{\lb@mainbox}% + \else + % middle part success + \lb@typeout{output middle part of box}% + \lb@middle@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest% continue the iteration... + \fi + \fi +} + +% -------------------------------------------------------- +% Split a long vbox over multiple pages. +% This code is based on similar code in the mdframed package +% -------------------------------------------------------- + +\newlength\lb@splitheight +\newlength\lb@insurance % tiny extra space to ensure our box will really fit +\setlength\lb@insurance{1pt} + +% expects split target height in lb@splitheight, and splits off the start of lb@mainbox to lb@headbox +\newcommand\lb@splitbox{% + \ifdim\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax>\lb@splitheight\relax + % the main box is larger than our target split height.. + \ifdim\lb@extrasplit>\lb@splitheight\relax + % not enough space to bother + \lb@typeout{not enough space on page for a split}% + \setbox\lb@headbox=\vbox{}% empty head + \else + % try a split; lower the split height a bit so we are sure to fit + \advance\lb@splitheight -\lb@insurance\relax + \lb@debug{split: \the\lb@splitheight, from \the\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax}% + \setbox\lb@savebox=\vbox{\unvcopy\lb@mainbox}% save original + \lb@trysplit{\lb@splitheight}% + \ifdim\dimexpr\ht\lb@headbox + \dp\lb@headbox>\lb@splitheight\relax + % too big, bad split. Try other splits.. iterate N times with 1 or 5pt less before giving up + \dimen@=\lb@splitheight\relax + \@tempcnta=\z@\relax + \loop + \ifdim\dimexpr\ht\lb@headbox+\dp\lb@headbox\relax>\lb@splitheight\relax + \ifnum\@tempcnta<50% + \advance\dimen@ by -\p@\relax% try a slightly smaller height.. + \else + \advance\dimen@ by -5\p@\relax% try larger increase after 50pt.. + \fi + \advance\@tempcnta by \@ne\relax + \lb@ignorevbadness + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \lb@trysplit{\dimen@}% + \ifdim\lb@extrasplit<\dimen@\relax\else\lb@splitstop\fi % don't try to split too small + \ifnum\@tempcnta<100\relax\else\lb@splitstop\fi % and not more than N attempts + \repeat% + \ifnum\@tempcnta<100\relax + \dimen@=\dimexpr\lb@splitheight - \ht\lb@headbox - \dp\lb@headbox\relax + \ifdim\dimen@>\option{/longbox/split-badness}\relax + \lb@warnbadsplit{\dimen@}% + \fi + \fi + \fi + \fi + \else + % mainbox fits in our target lb@splitheight + \setbox\lb@headbox=\vbox{\unvbox\lb@mainbox}% + \setbox\lb@mainbox=\vbox{}% + \fi +} + +\newcommand\lb@splitstop{% + \lb@typeout{cannot find a good split}% + \let\iterate\relax + \lb@warncannotsplit + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \setbox\lb@headbox=\vbox{}% empty head + \@tempcnta=\@M\relax +} + +\newcommand\lb@trysplit[1]{% try to split at given height + \lb@typeout{try to split at: \the\dimexpr #1\relax}% + \lb@ignorevbadness + \setbox\lb@headbox=\vsplit\lb@mainbox to #1\relax% + \setbox\lb@headbox=\vbox{\unvbox\lb@headbox}% + \setbox\lb@mainbox=\vbox{\unvbox\lb@mainbox}% +} + +% -------------------------------------------------------- +% The longbox environment uses options to set its options +% -------------------------------------------------------- + + +% keys and styles that can be set once globally +\options{% + /longbox/.new family, +}% + +\options{/longbox,% + % computed + @part-needtop/.new toggle, + @part-needbottom/.new toggle, + @part-height/.new length, + @part-width/.new length, + @part-depth/.new length, + @content-box-height/.new length, + @content-box-width/.new length, + @content-box-depth/.new length, + @breakat-previous/.new length, + @lower/.new length, + % + debug/.new toggle, + verbose/.new toggle, + render/.new value =\lb@render@fbox, + adjust-options/.new value = {\longbox@adjustoptions}, + eject/.new value = {\protect\vfill\protect\eject}, + use-vbox/.new toggle = true, + split-minimum/.new length = {1.5\baselineskip}, + split-badness/.new length = \baselineskip, + % + height-align/.new choice= {top,middle,bottom}, + baseline/.new choice = {bottom,middle,top}, + text-align/.new choice = {default,left,center,right,justify}, + vertical-align/.new choice = {baseline,bottom,middle,top,text-bottom,text-top,super,sub}, + raise/.new length = {0pt}, + baseline-skip/.new toggle =true, + % + height/.new length = -1sp, + width/.new length = -1sp, + outer-height/.new length= -1sp, + outer-width/.new length = -1sp, + insert-before/.new value= {}, + insert-after/.new value = {}, + breakat/.new value = {}, + breakable/.new toggle = false, + skip/.new style = {skip-top=#1,skip-right=#1,skip-bottom=#1,skip-left=#1}, + skip-top/.new length, + skip-right/.new length, + skip-bottom/.new length, + skip-left/.new length, + skip-break-bottom/.new length, + skip-break-top/.new length, +} + +\newcommand\longbox@adjustoptions{% + %\typeout{ standard longbox adjustoptions}% + \lb@debug{ current width=\the\dimexpr\option{/longbox/width}, outer=\the\dimexpr\option{/longbox/outer-width}, linewidth=\the\linewidth}% + \ontoggle{/longbox/debug}{\option@invoke{/longbox/verbose}{true}}% + % adjust height + \ifdim\option{/longbox/height}=-1sp\relax + \ifdim\option{/longbox/outer-height}=-1sp\else + \option@invoke{/longbox/height}% + {\option{/longbox/outer-height}-\option{/longbox/skip-top}-\option{/longbox/skip-bottom}}% + \fi + \fi + % set width + \ifdim\option{/longbox/width}=-1sp\relax + \ifdim\option{/longbox/outer-width}=-1sp\relax + \option@invoke{/longbox/outer-width}{\linewidth}% + \fi + \dimen@=\dimexpr\option{/longbox/outer-width}-\option{/longbox/skip-left}-\option{/longbox/skip-right}\relax + \ifdim\dimen@<\z@\relax\dimen@=\z@\fi + \option@invoke{/longbox/width}{\dimen@}% + \fi + % use a breakbox whenever we are in external vertical mode and not width or height restricted. + \iftoggle{/longbox/use-vbox}{}{% + \ifinner\toggletrue{/longbox/use-vbox}\else + \ifhmode\toggletrue{/longbox/use-vbox}\else + \ifdim\option{/longbox/height}>-1sp\toggletrue{/longbox/use-vbox}\else + \iftoggle{/longbox/breakable}{}{\toggletrue{/longbox/use-vbox}}% + \ifoptionblank{/longbox/breakat}{}{\toggletrue{/longbox/use-vbox}}% + \fi\fi\fi + }% +} + +\newenvironment{longbox}[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \begin{longbox@env}{/longbox}{#1}% +}{\end{longbox@env}} + +\newcommand\lbox[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \longbox@cmd{/longbox}{#1}% +} + +\newcommand*\lb@render@fbox{% + %\typeout{render defaultbox: bgcolor=\bb@bgcolor, needtop=\iftoggle{/longbox/@part-needtop}{true}{false}}% + \@ovdx=\dimexpr\option{/longbox/@part-width} - 2\fboxrule\relax% + \@ovdy=\dimexpr\option{/longbox/@part-height}\relax% + \iftoggle{/longbox/@part-needbottom}% + {\@tempdima=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdima=\dimexpr\fboxrule + \bb@stickout\relax + \advance\bb@height by \@tempdima + \advance\@ovdy by \@tempdima}% + \iftoggle{/longbox/@part-needtop}% + {\@tempdimb=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdimb=\dimexpr\bb@stickout\relax + \advance\bb@height by \@tempdimb + \advance\@ovdy by \@tempdimb}% + % + \hbox{\lower \@tempdima\vbox{% + \vskip -\@tempdimb + \ontoggle{/longbox/@part-needtop}{\lb@debug{toprule wd=\expandafter\the\option{/longbox/width}}\hrule width \option{/longbox/@part-width} height \fboxrule}% + \hbox{% + \vrule width \fboxrule height \@ovdy% + \ifx\bb@bgcolor\@empty + \vrule width \@ovdx height \z@\relax + \else + {\color{\bb@bgcolor}\vrule width \@ovdx height \@ovdy}% + \fi + \vrule width \fboxrule height \@ovdy% + }% + \ontoggle{/longbox/@part-needbottom}{\hrule width \option{/longbox/@part-width} height \fboxrule}% + }}% +} \ No newline at end of file diff --git a/spec/v1.2.0/longfbox.sty b/spec/v1.2.0/longfbox.sty new file mode 100644 index 00000000..0df01331 --- /dev/null +++ b/spec/v1.2.0/longfbox.sty @@ -0,0 +1,1344 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longfbox}[2015/12/01, Daan Leijen, Provides long fbox that can break over pages] + +\RequirePackage{options} +\RequirePackage{longbox} +\RequirePackage{pict2e} +\RequirePackage{ellipse} + +% -------------------------------------------------------- +% Dimension calulations +% -------------------------------------------------------- + +% dimmin/dimmax return minimum or maximum dimension +\providecommand\dim@min[2]{\ifdim#1>#2#2\else #1\fi} +\providecommand\dim@max[2]{\ifdim#1>#2#1\else #2\fi} + +\newcommand*\option@dimmin[2]{\dim@min{\option{#1}}{\option{#2}}} +\newcommand*\option@dimmax[2]{\dim@max{\option{#1}}{\option{#2}}} + + +% -------------------------------------------------------- +% Add a new 'sides' option type +% -------------------------------------------------------- + +\options{ + /handlers/new sides/.new handler = []{ + \ifblank{#2}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#1-top={##1}, #1-right={##2}, #1-bottom={##3}, #1-left={##4}}}}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#2}}}% + \optionsalso{ + #1/.new cmdx = {##1,##2,##3,##4,##5\relax}{,,,,\relax}{% + \ifblank{##2##3##4}{\option{#1/@cmd@sides}{##1}{##1}{##1}{##1}}% + {\ifblank{##3##4}{\option{#1/@cmd@sides}{##1}{##2}{##1}{##2}}% + {\ifblank{##4}{\option{#1/@cmd@sides}{##1}{##2}{##3}{##2}}% + {\option{#1/@cmd@sides}{##1}{##2}{##3}{##4}}% + }% + }% + }, + #1/.type = sides, + }% + },% +} + +\newcommand*\optionlengthlimit[3]{% len, min, max + \letoption{#1}\opt@temp + \ifdim\opt@temp<\dimexpr#2\relax + \option@invoke{#1}{#2}% + \else\ifdim\opt@temp>\dimexpr#3\relax + \option@invoke{#1}{#3}% + \fi\fi +} + +\newcommand*\optionradiuslimit[4]{% r1, r2, min, max + \letoption{#1}\opt@tempa + \letoption{#2}\opt@tempb + \ifdim\opt@tempa<\dimexpr#3\relax\option@invoke{#1}{#3}\fi + \ifdim\opt@tempb<\dimexpr#3\relax\option@invoke{#2}{#3}\fi + \ifdim\dimexpr\opt@tempa + \opt@tempb\relax=\z@\relax\else + \ifdim\dimexpr\opt@tempa+\opt@tempb\relax>\dimexpr#4\relax + \edef\opt@perc{\the\numexpr(\number\dimexpr#4\relax)/% + (\number\dimexpr(\opt@tempa+\opt@tempb)/100\relax)}% + %\typeout{scale:\the\opt@tempa,\the\opt@tempb, by \opt@perc percent to make \the\dimexpr#4\relax}% + \edef\opt@temp{\dimexpr\opt@perc\dimexpr\the\opt@tempa\relax / 100\relax}% + \option@einvoke{#1}{\opt@temp}% + \option@einvoke{#2}{\dimexpr#4 - \opt@temp\relax}% + %\typeout{ scaled to: \the\opt@temp,\the\dimexpr#4 - \opt@temp\relax}% + \fi + \fi +} + + +% \begin{macro}{\trig@atantan} +% \marg{a}\marg{b}\marg{$\alpha$}{dimen$_\mathit{reg}$}\\ +% Assigns $\atan_2(\frac{\sin(\alpha)}{b},\frac{\cos(\alpha)}{a})$ to dimension register \textit{dimen$_\mathit{reg}$}, +% where $a$ and $b$ are dimensions. +% Returns $\alpha$ when $a = b$, or when $a=0$ or $b=0$. +% \begin{macrocode} +\newcommand*\trig@atantan[4]{% + %\typeout{ atantan:(\the#1,\the#2,\the#3, #4)}% + \@tempdima\dimexpr#1\relax + \@tempdimb\dimexpr#2\relax +% \end{macrocode} +% If $a = b$, we have a circle and the result is $\alpha$. +% \begin{macrocode} + \ifdim\@tempdima=\@tempdimb + #4\dimexpr#3\relax + \else\ifdim\@tempdima=\z@ + #4\dimexpr#3\relax + \else\ifdim\@tempdimb=\z@ + #4\dimexpr#3\relax + \else + \edef\trig@temp{\strip@pt\dimexpr#3\relax}% + \CalculateSin{\trig@temp}\CalculateCos{\trig@temp}% + \@tempdimc\dimexpr1\p@ * \dimexpr\UseSin{\trig@temp}\p@\relax/\@tempdimb\relax + \@tempdimd\dimexpr1\p@ * \dimexpr\UseCos{\trig@temp}\p@\relax/\@tempdima\relax + \pIIe@atantwo{\@tempdimc}{\@tempdimd}\dimen@ + \ifdim\dimen@<\z@ + \ifdim\dimexpr#3\relax<\z@\else\advance\dimen@360\p@\fi + \fi + \@tempdima\dimexpr#3 - \dimen@\relax + \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi + \ifdim\@tempdima<360\p@\else\advance\dimen@360\p@\fi + %\typeout{atan: \the\dimexpr#3\relax versus. \the\dimen@ }% + #4\dimen@ + \fi\fi\fi +} +% \end{macrocode} +% \end{macro} + +% rough approximation of the perimeter; +% if |radius-x == radius-y| = 0 (a circle), the approximation is precise. +% otherwise, works best when |angle2-angle1| <= 45 and gets worse from there on. +\newcommand*\ellip@letarcperimeter[5]{% 'radius-x', 'radius-y', 'angle-1', 'angle-2', '\result' + \@tempdima\dimexpr#3\relax + \@tempdimb\dimexpr#4\relax + \@tempdimc\dimexpr\@tempdima - \@tempdimb\relax + \ifdim\@tempdimc<\z@\@tempdimc-\@tempdimc\fi + \ifdim#1=#2\relax% circle? + \edef\@tempa{\strip@pt\@tempdimc}% angle difference delta as factor + \dimen@\@tempa\dimexpr#1\relax% r*delta + \dimen@0.017453\dimen@% (2*pi/360) * r * delta = 2*pi*r * (delta/360) + \else% ellipse: take the distance between the points on the ellipse, works pretty good if delta <= 45, and ok'ish for delta <= 90 + \@ovro\dimexpr#1\relax + \@ovri\dimexpr#2\relax + \edef\fbox@tempa{\strip@pt\@tempdima}% + \edef\fbox@tempb{\strip@pt\@tempdimb}% + \pIIe@ellip@sincost{\fbox@tempa}{\fbox@tempb}% + \@tempdima\@ellipcosone\@ovro + \@tempdimb\@ellipsinone\@ovri + \@tempdimc\@ellipcostwo\@ovro + \@tempdimd\@ellipsintwo\@ovri + \advance\@tempdimc by -\@tempdima% + \advance\@tempdimd by -\@tempdimb% + \pIIe@ellip@csqrt{\@tempdimc}{\@tempdimd}{\dimen@}% + %\typeout{ distance: \the\dimen@, from (x,y)=(\the\@tempdimc,\the\@tempdimd), radii=(\the#1,\the#2), angles=(\the#3,\the#4)}% + \fi + \edef#5{\the\dimen@}% +} + + +% ------------------------------------------------------------------------------ +% Borders using the picture environment +% ------------------------------------------------------------------------------ + +\newcommand*\fbox@border@pict{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \begingroup + \hbox{% + \unitlength\p@ + \begin{picture}(0,0)(0,\optionunit{/fbox/@border-box-height})% bottom-left is origin + % markers + \ontoggle{/fbox/show-markers}{% + \linethickness{\option{/fbox/marker-width}}% + \optioncolor{/fbox/marker-color}% + \fbox@rect{0pt}{0pt}{\option{/fbox/@border-box-width}}{\option{/fbox/@border-box-height}}% + \fbox@rect{\option{/fbox/border-left-width}}{\option{/fbox/border-\fbox@bottom-width}}% + {\option{/fbox/@border-box-width}-\option{/fbox/border-right-width}}% + {\option{/fbox/@border-box-height}-\option{/fbox/border-\fbox@top-width}}%S + }% + %compute corner coordinates + \fbox@border@calccorners + %put down the background color + \fbox@border@colorbackground + \option{/fbox/picture-insert-before}% + %put down the sides + \fbox@border@side{3}{-2}{0}%top + \fbox@border@side{5}{-4}{3}%left + \fbox@border@side{-6}{7}{2}%bottom + \fbox@border@side{-8}{1}{1}%right + \end{picture}% + }% + \endgroup + \fi +} + +\newcommand*\fbox@border@pict@after{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \letoption{/fbox/picture-insert-after}\fbox@insertafter + \eifblank{\fbox@insertafter}{}{% + \begingroup + \hbox{% + \begin{picture}(0,0)(0,0)% bottom-left is origin + \fbox@insertafter + \end{picture}% + }% + \endgroup + }% + \fi +} + +\newcommand*\fbox@border@side[3]{% + \fbox@setoct@angles{#1}% + \edef\fbox@style{\option{/fbox/border-\fbox@side-style}}% + \optioncolor{/fbox/border-\fbox@side-color}% + \option{/fbox/picture-side-insert-before}% + \ifcsdef{fbox@border@pict@\fbox@style}% + {\csuse{fbox@border@pict@\fbox@style}{#1}{#2}{#3}}% + {\PackageWarning{longfbox}{Unknown style "\fbox@style". Using "solid" instead.}% + \fbox@border@pict@solid{#1}{#2}{#3}}% + \option{/fbox/picture-side-insert-after}% +} + +% ------------------------------------------------------------------------------ +% Define standard border styles for the picture environment +% +% a style has the form \fbox@border@pict@ + + + + + + +
+
+
+
P4Runtime Specification
+
version 1.3.0
+
+
+
The P4.org API Working Group
+
2020-12-01
+
+

Abstract. P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.

+ + +

1. Introduction and Scope

+

This document is published by the P4.org API Working Group, which was +chartered [17] to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called P4Runtime. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +https://github.com/p4lang/p4runtime/tree/v1.3.0/proto. +

1.1. P4 Language Version Applicability

+

P4Runtime is designed to be implemented in conjunction with the P416 language +version or later. P414 programs should be translated into P416 to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P416 1.0, but were introduced in P416 1.1.0 [29]. For +this version of P4Runtime, we recommend using P416 1.2.1 [1]. +

1.2. In Scope

+

This specification document defines the semantics of P4Runtime messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime: +

+
    +
  • Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA) [19] externs (e.g. Counters, Meters, Action +Profiles, ). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0. +
  • +
  • Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism. +
  • +
  • Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy. +
  • +
  • Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities. +
  • +
  • Packet I/O to enable streaming packets to & from the control plane. +
  • +
  • Batching support, with different atomicity guarantees. +
  • +
  • In-the-field device-reconfiguration with a new P4 data plane. +
+ +

The following are in the scope of this specification document: +

+
    +
  • Rationale for the P4Runtime design. +
  • +
  • Reference architecture and use-cases for deploying a P4Runtime service. +
  • +
  • Detailed description of the API semantics. +
  • +
  • Requirements for conformant implementations of the API. +
+

1.3. Not In Scope

+

The following are not in scope of P4Runtime: +

+
    +
  • Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +[35]. An open source implementation of these APIs is also in progress +as part of the Stratum project [37]. +
  • +
  • Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures. +
+ +

The following are not in scope of this specification document: +

+
    +
  • Description of the P4 programming language; it is assumed that the reader is +already familiar with P416 [1]. +
  • +
  • Descriptions of gRPC and Protobuf files in general. +
  • +
  • Controller role definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme. +
+

2. Terms and Definitions

+
+
arbitration
+
Refers to the process through which P4Runtime ensures that at any given +time, there is a single primary controller (i.e. a client with write access) +for a given role. Also referred to as “client arbitration”. +
+
client
+
The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +
+
COS
+
Class of Service. +
+
device
+
Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +
+
entity
+
An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +
+
gRPC
+
gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +[9]. +
+
HA
+
High-Availability. Refers to a redundancy architecture. +
+
Instrumentation
+
The part of the P4Runtime server which implements the calls to the device or +target native “SDK” or backend. +
+
IPC
+
Inter-Process Communication. +
+
P4 Blob
+
A more colloquial term for P4 Device Config (Blob = Binary Large Object). +
+
P4 Device Config
+
The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its “program.” +
+
P4Info
+
Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +
+
P4RT
+
Abbreviation for P4Runtime. +
+
Protobuf (Protocol Buffers)
+
The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See [21]. +
+
PSA
+
Portable Switch Architecture [19]; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +
+
RPC
+
Remote Procedure Call. +
+
RTT
+
Round-trip time. +
+
SDN
+
Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network controller. +
+
SDN port
+
A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +
+
server
+
The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +
+
stream
+
Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (StreamChannel), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and client arbitration, among other things. +
+
switch config
+
Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +
+
target
+
The hardware or software entity which “executes” the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with “device”. +
+
URI
+
Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.

3. Reference Architecture

+

Figure 1 represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. P4Runtime only grants write access to a +single primary controller for each read/write entity. A role defines a grouping +of P4 entities. P4Runtime allows for a primary controller for each role, and a +role-based client arbitration scheme ensures only one controller has +write access to each read/write entity, or the pipeline config itself. Any +controller may perform read access to any entity or the pipeline config. Later +sections describe this in detail. For the sake of brevity, the term controller +may refer to one or more controllers. +

+

The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +[15]. It may be compiled via protoc the Protobuf compiler +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server. +

+

Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository [16]. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, e.g. via callbacks, thus reducing the burden of implementing +P4Runtime. +

+

The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard. +

+

The controller can also set the ForwardingPipelineConfig, which amounts to +installing and running the compiled P4 program output, which is included in the +p4_device_config Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +ForwardingPipelineConfig to retrieve the device config and the P4Info. +

+
+

reference-architecture +

+
+ +
Figure 1. P4Runtime Reference Architecture.

3.1. P4Runtime Service Implementation

+

The P4Runtime API is implemented by a program that runs a gRPC server which +binds an implementation of auto-generated P4Runtime Service interface. This +program is called the “P4Runtime server.” The server must listen on TCP port +9559 by default, which is the port that has been allocated by IANA for the +P4Runtime service. Servers should allow users to override the default port +using a configuration file or flag when starting the server. Uses of other +port numbers as the default should be discontinued. +

3.1.1. Security concerns

+

Appropriate measures and security best practices must be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. Mutual TLS (mTLS) may +be used to facilitate the authentication of the client by the server and +vice-versa. +

3.2. Idealized Workflow

+

In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the ForwardingPipelineConfig +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a SetForwardingPipelineConfig +RPC. Metadata in the P4Info describes both the overall program itself +(PkgInfo) as well as all entity instances derived from the P4 program +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise “handle” used in API +calls. +

+

In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible. +

+

In some use cases, it is expected that a controller will store a +collection of multiple P4 “packages”, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the ForwardingPipelineConfig from the target via the +GetForwardingPipelineRequest RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state. +

3.3. P4 as a Behavioral Description Language

+

P4 can be considered a behavioral description of a switching device which may or +may not execute “P4” natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a SetForwardingPipelineRequest to +change its pipeline “program”, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device. +

+

While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API. +

+

In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the PkgInfo +message as well as the embedded doc fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections. +

3.4. Alternative Workflows

+

Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary. +

3.4.1. P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config

+

In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +p4_device_config. The device's configuration might be derived via some other +means to implement the P4 source code's intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane. +

3.4.2. No P4 Source Available, P4Info Available

+

In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are: +

+
    +
  1. +

    The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security. +

  2. +
  3. +

    The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info. +

+ +

As discussed in Section 3.3, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, e.g. documentation. +

3.4.3. Partial P4Info and P4 Source are Available

+

In this situation, a subset of the target's pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code. +

3.4.4. P4Info Role-Based Subsets

+

In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more. +

3.5. P4Runtime State Across Restarts

+

All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade. +

4. Controller Use-cases

+

P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +section. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime's flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex. +

4.1. Single Embedded Controller

+

Figure 2 shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases. +

+

P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC. +

+
+

single-embedded-controller +

+
+ +
Figure 2. Use-Case: Single Embedded Controller

4.2. Single Remote Controller

+

Figure 3 shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections. +

+
+

single-remote-controller +

+
+ +
Figure 3. Use-Case: Single Remote Controller

4.3. Embedded + Single Remote Controller

+

Figure 4 illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller. +

+

For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables. +

+
+

embedded-plus-single-remote-controller +

+
+ +
Figure 4. Use-Case: Embedded Plus Single Remote Controller

4.4. Embedded + Two Remote Controllers

+

Figure 5 illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +e.g. routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership. +

+
+

embedded-plus-two-remote-controllers +

+
+ +
Figure 5. Use-Case: Embedded Plus Two Remote Controllers

4.5. Embedded Controller + Two High-Availability Remote Controllers

+

Figure 6 illustrates a single +embedded controller plus two remote controllers in an active-standby (i.e. +primary-backup) HA (High-Availability) configuration. Controller #1 is the +active controller and is in charge of some entities. If it fails, Controller #2 +takes over and manages the tables formerly owned by Controller #1. The mechanics +of HA architectures are beyond the scope of this document, but the P4Runtime +role-based client arbitration scheme supports it. +

+
+

embedded-plus-two-remote-ha-controllers +

+
+ +
Figure 6. Use-Case: Embedded Plus Two Remote High-Availability Controllers

5. Client Arbitration and Controller Replication

+

The P4Runtime interface allows multiple clients (i.e. controllers) to be +connected to the P4Runtime server running on the device at the same time for the +following reasons: +

+
    +
  1. +

    Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, “roles” (or “realms”) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +primary and the rest are backups. Role definition, i.e. how P4 entities get +assigned to each role, is out-of-scope of this document. +

  2. +
  3. +

    Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby backup controllers. These can already have a connection +open, which can help them become primary more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved. +

+ +

To support multiple controllers, P4Runtime uses the streaming channel (available +via StreamChannel RPC) for session management. The workflow is described as +follows: +

+
    +
  • +

    Each controller instance (e.g. a controller process) can participate in one or +more roles. For each (device_id, role_id), the controller receives an +election_id. This election_id can be the same for different roles and/or +devices, as long as the tuple (device_id, role_id, election_id) is +unique. For each (device_id, role_id) that the controller wishes to +control, it establishes a StreamChannel with the P4Runtime server +responsible for that device, and sends a MasterArbitrationUpdate message +containing that tuple of (device_id, role_id, election_id) values. The +P4Runtime server selects a primary independently for each (device_id, +role_id) pair. The primary is the client that has the highest election_id +that the device has ever received for the same (device_id, +role_id) values. A connection between a controller instance and a device id + which involves a persistent StreamChannel can be referred to as a +P4Runtime client. +

    +

    Note that the P4Runtime server does not assign a role_id or election_id to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the election_id values used for each +StreamChannel. The P4Runtime server only keeps track of the (device_id, +role_id, election_id) of each StreamChannel that has sent a successful +MasterArbitrationUpdate message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +WriteRequest message to identify which client is making the WriteRequest, +not only the election_id. This enables controllers to re-use the same +numeric election_id values across different (device_id, role_id) +pairs. P4Runtime does not require election_id values be reused across such +different (device_id, role_id) pairs; it allows it. +

  • +
  • +

    To start a controller session, a controller first opens a bidirectional stream +channel to the server via the StreamChannel RPC for each device. This stream +will be used for two purposes: +

    +
      +
    • +

      Session management: As soon as the controller opens the stream +channel, it sends a StreamMessageRequest message to the switch. The +controller populates the MasterArbitrationUpdate field in this message +using its role_id and election_id, as well as the device_id of the +device. Note that the status field in the MasterArbitrationUpdate is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below. +

    • +
    • +

      Streaming of notifications (e.g. digests) and packet I/O: The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the primary controller can participate in +packet I/O. This feature is explained in more details in the Packet +I/O section. +

    + +

    Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state. +

  • +
  • +

    Note that the stream is opened per device. In case a switching platform has +multiple devices (e.g. multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different primary clients for +different devices. In this case, it is the responsibility of the P4Runtime +server to keep track of the primary for each device (and role). More +specifically, the P4Runtime server will know which stream corresponds to the +primary controller for each pair of (device_id, role_id) at any point of +time. +

  • +
  • +

    The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered “offline” or +“dead” as soon as its stream channel to the switch is broken. When a primary +channel gets broken: (i) an advisory message is sent to all other controllers +for that device_id and role_id, as described in the +following section (ii) the P4Runtime server +will be without a primary controller, until a client sends a successful +MasterArbitrationUpdate (as per the rules in a +later section). +

  • +
  • +

    The mechanism via which the controller receives the P4Runtime server details +which includes the device_id, ip and port, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +device_id) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks. +

+ +

gRPC enables the server to identify which client originated each message in the +StreamChannel stream. For example, the C++ gRPC library [10] in +synchronous mode enables a server process to cause a function to be called when +a new client creates a StreamChannel stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +StreamChannel is closed normally (or broken, e.g. because a client process +unexpectedly terminated). Thus the server can easily associate all +StreamChannel messages received from the same client, because they are +processed within the context of the same function call. +

+

A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values device_id, role_id, and election_id in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods [8] that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server. +

5.1. Default Role

+

A controller can omit the role message in MasterArbitrationUpdate. This +implies the “default role”, which corresponds to “full pipeline access”. This +also implies that a default role has a role.id of 0 (default). If using a +default role, all RPCs from the controller (e.g. Write) must set the role_id +to 0. +

5.2. Role Config

+

The role.config field in the MasterArbitrationUpdate message sent by the +controller describes the role configuration, i.e. which operations are in the +scope of a given role. In particular, the definition of a role may include the +following: +

+
    +
  • A list of P4 entities for which the controller may issue Write updates and +receive notification messages (e.g. DigestList and +IdleTimeoutNotification). +
  • +
  • Whether the controller is able to receive PacketIn messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketIn messages should be sent to the controller. +
  • +
  • Whether the controller is able to send PacketOut messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketOut messages are allowed to be sent by the controller. +
+ +

An unset role.config implies “full pipeline access” (similar to the default +role explained above). In order to support different role definition schemes, +role.config is defined as an Any Protobuf message [31]. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion. +

+

It is the job of the P4Runtime server to remember the role.config for every +device_id and role_id pair. +

5.3. Rules for Handling MasterArbitrationUpdate Messages Received from Controllers

+
    +
  1. +

    If the MasterArbitrationUpdate message is received for the first time on +this particular channel (i.e. for a newly connected controller): +

    +
      +
    1. +

      If device_id does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +NOT_FOUND error. +

    2. +
    3. +

      If the election_id is set and is already used by another controller for +the same (device_id, role_id), the P4Runtime server shall terminate +the stream by returning an INVALID_ARGUMENT error. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the number of open streams for the given (device_id, role_id) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a RESOURCE_EXHAUSTED error. +

    8. +
    9. +

      Otherwise, the controller is added to a list of connected controllers for +the given (device_id, role_id) and the server remembers the +controllers device_id, role_id and election_id for this gRPC +channel. See below for the rules to determine if this controller becomes +a primary or backup, and what notifications are sent as a consequence. +

    +
  2. +
  3. +

    Otherwise, if the MasterArbitrationUpdate message is received from an +already connected controller: +

    +
      +
    1. +

      If the device_id does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. +

    2. +
    3. +

      If the role.id does not match the current role_id assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. If the controller wishes to change its role, +it must close the current stream channel and open a new one. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the election_id is set and is already used by another controller +(excluding the controller making the request) for the same +(device_id, role_id), the P4Runtime server shall terminate the stream +by returning an INVALID_ARGUMENT error. +

    8. +
    9. +

      If the election_id matches the one assigned to this stream: +

      +
        +
      1. +

        If the controller for this channel is the primary, then the server +updates the role.config to the one specified in the +MasterArbitrationUpdate. An advisory client arbitration message is +sent to all controllers for this device_id and role_id informing +them of the new role.config. Since the format of role.config is +out of scope for the P4Runtime specification, the server will send +the advisory message for every update, even if the primary sets the +same role.config as it has before. See the following +section for the format of the +advisory message. +

      2. +
      3. +

        If the controller is a backup, this is a no-op and the role.config +is ignored. No response is sent to any controller. +

      +
    10. +
    11. +

      Otherwise, the server updates the election_id it has stored for this +controller. This change might cause a change in the primary client (this +controller might become primary, or the controller might have downgraded +itself to a backup, see below), as well as notifications being sent to +one or more controllers. +

    +
+ +

If the MasterArbitrationUpdate is accepted by either of the two steps above +(cases 1.5. and 2.6. above), then the server determines if there are changes in +the primary client. Let election_id_past be the highest election ID the server +has ever seen for the given device_id and role_id (including the one of the +current primary if there is one). +

+
    +
  1. +

    If election_id is greater than or equal to election_id_past, then the +controller becomes primary. The server updates the role configuration to +role.config for the given role.id. Furthermore: +

    +
      +
    1. +

      If there was no primary for this device_id and role_id before and +there are no Write requests still processing from a previous primary, +then the server immediately sends an advisory notification to all +controllers for this device_id and role_id. See the +following section for the format of the +advisory message. +

    2. +
    3. +

      If there was a previous primary or Write requests in flight, then the +server carries out the following steps (in this order): +

      +
        +
      1. +

        The server stops accepting Write requests from the previous primary +(if there is one). At this point, the server will reject all Write +requests with PERMISSION_DENIED. +

      2. +
      3. +

        The server notifies all controllers other than the new primary client +of the change by sending the advisory notification described in +the following section. +

      4. +
      5. +

        The server will finish processing any Write requests that have +already started. If there are errors, they are reported as usual to +the previous primary. If the previous primary has already +disconnected, any possible errors are dropped and not reported. +

      6. +
      7. +

        The server now accepts the current controller as the new primary, +thus accepting Write requests from this controller. The server +updates the highest election ID (i.e. election_id_past) it has seen +for this device_id and role_id to election_id. +

      8. +
      9. +

        The server notifies the new primary by sending the advisory message +described in the following section. +

      +
    +
  2. +
  3. +

    Otherwise, the controller becomes a backup. If the controller was previously +a primary (and downgraded itself), then an advisory message is sent to all +controllers for this device_id and role_id. Otherwise, the advisory +message is only sent to the controller that sent the initial +MasterArbitrationUpdate. See the +following section for the format of the +advisory message. +

+

5.4. Client Arbitration Notifications

+

For any given device_id and role_id, any time a new primary is chosen, a +primary downgrades its status to a backup, a primary disconnects, or the +role.config is updated by the primary, all controllers for that +(device_id, role_id) are informed of this by sending a +StreamMessageResponse. The MasterArbitrationUpdate is populated as follows: +

+
    +
  • +

    device_id and role.id as given. +

  • +
  • +

    role.config is set to the role configuration the server received most +recently in a MasterArbitrationUpdate from a primary. +

  • +
  • +

    election_id is populated as follows: +

    +
      +
    • +

      If there has not been any primary at all, the election_id is left unset. +

    • +
    • +

      Otherwise, election_id is set to the highest election ID that the server +has seen for this device_id and role_id (which is the election_id of +the current primary if there is any). +

    +
  • +
  • +

    status is set differently based on whether the notification is sent to the +primary or a backup controller: +

    +
      +
    • +

      If there is a primary: +

      +
        +
      • +

        For the primary, status is OK (with status.code set to +google.rpc.OK). +

      • +
      • +

        For all backup controllers, status is set to non-OK (with +status.code set to google.rpc.ALREADY_EXISTS). +

      +
    • +
    • +

      Otherwise, if there is no primary currently, for all backup controllers, +status is set to non-OK (with status.code set to +google.rpc.NOT_FOUND). +

    +
+ +

Note that on primary client changes with outstanding Write request, some +notifications might be delayed, see the +previous section for details. +

6. The P4Info Message

+

The purpose of P4Info was described under +Reference Architecture. +Here we describe the various +components. +

6.1. Common Messages

+

These messages appear nested within many other messages. +

6.1.1. Documentation Message

+

Documentation is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers. +

+
+
+
message Documentation {
+  // A brief description of something, e.g. one sentence
+  string brief = 1;
+  // A more verbose description of something.
+  // Multiline is accepted. Markup format (if any) is TBD.
+  string description = 2;
+}

6.1.2. Preamble Message

+

The preamble serves as the “descriptor” for each entity and contains the unique +instance ID, name, alias, annotations and documentation. +

+
+
+
message Preamble {
+  // ids share the same number-space; e.g. table ids cannot overlap with counter
+  // ids. Even though this is irrelevant to this proto definition, the ids are
+  // allocated in such a way that it is possible based on an id to deduce the
+  // resource type (e.g. table, action, counter, ...). This means that code
+  // using these ids can detect if the wrong resource type is used
+  // somewhere. This also means that ids of different types can be mixed
+  // (e.g. direct resource list for a table) without ambiguity. Note that id 0
+  // is reserved and means "invalid id".
+  uint32 id = 1;
+  // fully qualified name of the P4 object, e.g. c1.c2.ipv4_lpm
+  string name = 2;
+  // an alias (alternative name) for the P4 object, probably shorter than its
+  // fully qualified name. The only constraint is for it to be unique with
+  // respect to other P4 objects of the same type. By default, the compiler uses
+  // the shortest suffix of the name that uniquely identifies the object. For
+  // example if the P4 program contains two tables with names s.c1.t and s.c2.t,
+  // the default aliases will respectively be c1.t and c2.t. In the future, the
+  // P4 programmer may also be able to override the default alias for any P4
+  // object (TBD).
+  string alias = 3;
+  repeated string annotations = 4;
+  // Optional. If present, the location of `annotations[i]` is given by
+ // `annotation_locations[i]`.
+  repeated SourceLocation annotation_locations = 7;
+  // Documentation of the entity
+  Documentation doc = 5;
+  repeated StructuredAnnotation structured_annotations = 6;
+}

6.1.3. Annotating P4 Entities with Documentation

+

P4 entities may be annotated using the following annotations: +

+
+
+
@brief(string...)
+@description(string...)
+

Attaching either or both of these annotations to an entity will generate a +P4Info Documentation Message, which in turn will +appear in the Preamble Message for the entity. +

+

The P4 compiler should not emit annotation messages in the P4Info for these +specific cases; instead, it should generate the Documentation messages as +described. +

+

The following example shows documentation annotations for a table entity: +

+
+
+
@brief("Match IPv4 addresses to next-hop MAC and port")
+@description("Match IPv4 addresses to next-hop MAC and port. \
+Uses LPM match type.")
+table my_ipv4_lkup {
+  ...
+}

6.1.4. Structured Annotations

+

P4 supports both unstructured and structured annotations [13]. +Unstructured annotations of the form MyAnno1 or MyAnno2(body-content) can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +MyAnno3[] or MyAnno4[kvList|expressionList] have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this. +

+

The annotations described up to this point, e.g. @brief(), have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as repeated string annotations fields in the various messages. +Similarly, structured annotations are represented in repeated +StructuredAnnotation structured_annotations fields which are siblings to the +unstructured annotations. The structured_annotations contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations. +

+

The structured annotation messages are defined in p4types.proto. +

+
+
+
message KeyValuePair {
+  string key = 1;
+  Expression value = 2;
+}
+
+message KeyValuePairList {
+  repeated KeyValuePair kv_pairs = 1;
+}
+
+message Expression {
+  oneof value {
+    string string_value = 1;
+    int64 int64_value = 2;
+    bool bool_value = 3;
+  }
+}
+
+message ExpressionList {
+  repeated Expression expressions = 1;
+}
+
+message StructuredAnnotation {
+  string name = 1;
+  oneof body {
+    ExpressionList expression_list = 2;
+    KeyValuePairList kv_pair_list = 3;
+  }
+  // Optional. Location of the '@' symbol of this annotation in the source code.
+  SourceLocation source_location = 4;
+}
+

The StructuredAnnotation message can represent either a KeyValuePairList +or an ExpressionList. +

+

The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The p4c +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don't match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler may print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions. +

+

The following invariants hold: +

+
    +
  1. +

    For any P4 entity, there are no two StructuredAnnotations that have the +same name. +

  2. +
  3. +

    Within a KeyValuePairList, there are no two KeyValuePairs that have the +same key. +

+
6.1.4.1. Structured Annotation Examples
+

We omit the source_location field in the following examples. +

+

Empty Expression List +

+
+
+
@Empty[]
+table t {
+    ...
+}
+

The generated P4Info will contain the following. +

+
+
+
structured_annotations {
+  name: "Empty"
+}
+

Mixed Expression List +

+
+
+
#define TEXT_CONST "hello"
+#define NUM_CONST 6
+@MixedExprList[1,TEXT_CONST,true,1==2,5+NUM_CONST]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedExprList"
+  expression_list {
+    expressions {
+      int64_value: 1
+    }
+    expressions {
+      string_value: "hello"
+    }
+    expressions {
+      bool_value: true
+    }
+    expressions {
+      bool_value: false
+    }
+    expressions {
+      int64_value: 11
+    }
+  }
+}
+

kvList of Mixed Expressions +

+
+
+
@MixedKV[label="text", my_bool=true, int_val=2*3]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedKV"
+  kv_pair_list {
+    kv_pairs {
+      key: "label"
+      value {
+        string_value: "text"
+      }
+    }
+    kv_pairs {
+      key: "my_bool"
+      value {
+        bool_value: true
+      }
+    }
+    kv_pairs {
+      key: "int_val"
+      value {
+        int64_value: 6
+      }
+    }
+  }
+}

6.1.5. SourceLocation Message

+

A source location describes a location within a .p4-source file. The +SourceLocation message is defined in p4types.proto as follows: +

+
+
+
// Location of code relative to a given source file.
+message SourceLocation {
+  // Path to the source file (absolute or relative to the working directory).
+  string file = 1;
+  // Line and column numbers within the source file, 1-based.
+  int32 line = 2;
+  int32 column = 3;
+}
+

We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations. +

+

The SourceLocation message associated with an annotation holds the location of +the @ symbol introducing the annotation in the P4 source code; the message can +be found in the following place: +

+
    +
  • +

    For unstructured annotations, every message containing a field +repeated string annotations also contains a field +repeated SourceLocation annotation_locations. The field must either be empty + or match the size of annotations. In the latter case, the i-th member of +annotation_locations is the source location of the i-th member of +annotations. +

  • +
  • +

    For structured annotations, every StructuredAnnotation message contains +an optional field SourceLocation source_location holding its source +location, if present. +

+

6.2. PkgInfo Message

+

The PkgInfo message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. PkgInfo can be extracted +and used to facilitate “browsing” of available P4 programs from a +library. Although all fields are technically “optional,” every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included. +

+
+
+
// Can be used to manage multiple P4 packages.
+message PkgInfo {
+  // a definitive name for this configuration, e.g. switch.p4_v1.0
+  string name = 1;
+  // configuration version, free-format string
+  string version = 2;
+  // brief and detailed descriptions
+  Documentation doc = 3;
+  // Miscellaneous metadata, free-form; a way to extend PkgInfo
+  repeated string annotations = 4;
+  // the target architecture, e.g. "psa"
+  string arch = 5;
+  // organization which produced the configuration, e.g. "p4.org"
+  string organization = 6;
+  // contact info for support,e.g. "tech-support@acme.org"
+  string contact = 7;
+  // url for more information, e.g. "http://support.p4.org/ref/p4/switch.p4_v1.0"
+  string url = 8;
+  // Miscellaneous metadata, structured; a way to extend PkgInfo
+  repeated StructuredAnnotation structured_annotations = 9;
+}

6.2.1. Annotating P4 code with PkgInfo

+

A P4 progam's PkgInfo may be declared using one or more of the following +annotations, attached to the main block only: +

+
+
+
@pkginfo(key=value)
+@pkginfo(key=value[,key=value,...])
+@brief("A brief description")
+@description("A longer\
+description")
+@custom_annotation(...)
+@another_custom_annotation(...)
+

Above we see several different types of annotations: +

+
    +
  • +

    @pkginfo - This is used to populate a specific field within the PkgInfo +message. Multiple @pkginfo annotations are allowed. For compactness, +multiple key-value pairs can appear in a single @pkginfo annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The keys must be from +among the message fields inside PkgInfo, for example, name, version, +etc. Each key-value pair assigns a value to the corresponding field inside the +single PkgInfo message for the program's P4Info. One exception is that the +Documentation field of PkgInfo must be expressed as individual +@description and @brief annotations, see next bullets. The key arch will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself. +

  • +
  • +

    @brief - This will populate the PkgInfo.doc.brief message field. +

  • +
  • +

    @description - This will populate the PkgInfo.doc.description message +field +

  • +
  • +

    @<anything else> - This will create a PkgInfo.annotation entry +

+ +

Declaring one or more of these annotations on main will +generate a single corresponding PkgInfo message in the P4Info as described in +PkgInfo Message. +

+

The following example shows @pkginfo annotations using a mixture of single and +multiple key-value pairs. It also shows @brief and @description annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the PkgInfo message. The custom annotations will +be appended to the PkgInfo.annotations list. +

+
+
+
@pkginfo(name="switch.p4",version="2")
+@pkginfo(organization="p4.org")
+@pkginfo(contact="info@p4.org")
+@pkginfo(url="www.p4.org")
+@brief("L2/L3 switch")
+@description("L2/L3 switch.\
+Built for data-center profile.")
+@my_annotation1(...) // Not well-known, this will appear in PkgInfo annotations
+@my_annotation2(...) // Not well-known, this will appear in PkgInfo annotations
+PSA_Switch(IgPipeline, PacketReplicationEngine(), EgPipeline,
+           BufferingQueueingEngine()) main;

6.3. ID Allocation for P4Info Objects

+

P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(e.g. table, action, counter, ). The most significant 8 bits of the ID +encodes the object type (as per Table 1). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (p4.config.v1.P4Ids.Prefix). These values must +be used (e.g. by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table 2 shows the ID +layout. +

+
+ + + + + + + + + + + + + + + + + + + + + +
8-bit prefix value P4 object type
0x00 Reserved (unspecified)
0x01 Action
0x02 Table
0x03 Value-set
0x04 Controller header (header type with @controller_header annotation)
0x050x0f Reserved (for future P4 built-in objects)
0x10 Reserved (start of PSA extern types)
0x11 PSA Action profiles / selectors
0x12 PSA Counter
0x13 PSA Direct counter
0x14 PSA Meter
0x15 PSA Direct meter
0x16 PSA Register
0x17 PSA Digest
0x180x7f Reserved (for future PSA extern types)
0x80 Reserved (start of vendor-specific extern types)
0x810xfe Vendor-specific extern types
0xff Reserved (max prefix value)
+
+ +
Table 1. Mapping of P4Info object type to 8-bit ID prefix value
+
+ + + + +
MSB bit 31 .. bit 24 bit 23 .. bit 0 LSB
Object type prefix Generated suffix (e.g. by the compiler)
+
+ +
Table 2. Format of P4Info object IDs
+

It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with @id (see Table +3). The compiler must honor the @id annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (i.e. if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same @id value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct. +

+
+ + + + + + + + + + +
P4 declaration(s) Compiler-allocated ID(s)
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) table tA... Error(same ID suffixes for 2 objects of the same type)
@id(0x12ab34) table tB...
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) action act1... 0x0112ab34
+
+ +
Table 3. Example of statically-assigned P4Info object IDs
+

The @id annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively). +

6.4. P4Info Objects

6.4.1. Table

+

Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this table. +

  • +
  • +

    match_fields, a repeated field of type MatchField representing the data to +be used to construct the lookup key matched in this table. Each MatchField +message is defined with the following fields: +

    +
      +
    • +

      id, the uint32 identifier of this MatchField, unique in the scope of +this table. No rules are prescribed on the way MatchField IDs should be +allocated, as long as two MatchField of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the @id annotation, or let the compiler +choose them. +

    • +
    • +

      name, the string representing the name of this MatchField. +

    • +
    • +

      annotations, a repeated field of strings, each one representing a P4 +annotation associated to this match field. +

    • +
    • +

      bitwidth, an int32 value set to the size in bits of this match field. +

    • +
    • +

      match, a oneof describing the match behavior for this field; it can be +either: +

      +
        +
      • match_type, an enum field of type MatchType, which includes all +possible PSA match kinds. +
      • +
      • other_match_type, a string field which can be used to encode any +architecture-specific match type. +
      +
    • +
    • +

      doc, a Documentation message describing this match field. +

    • +
    • +

      type_name, which indicates whether the match field has a user-defined +type; this is useful for +translation. +

    +
  • +
  • +

    action_refs, a repeated ActionRef field representing the set of possible +actions for this table. The ActionRef message is used to reference an action +specified in the same P4Info message and it includes the following fields: +

    +
      +
    • id, the uint32 identifier of the action. +
    • +
    • scope, an enum value which can take one of three values: + TABLE_AND_DEFAULT, TABLE_ONLY and DEFAULT_ONLY. The scope of the + action is determined by the use of the P4 standard annotations + @tableonly and @defaultonly [18]. TABLE_ONLY + (@tableonly annotation) means that the action can only appear within + the table, and never as the default action. DEFAULT_ONLY + (@defaultonly annotation) means that the action can only be used as the + default action. TABLE_AND_DEFAULT is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action. +
    • +
    • annotations, a repeated string field, each one representing a P4 +annotation associated to the action reference in this table. +
    +
  • +
  • +

    const_default_action_id, if this table has a constant default action, this +field will carry the uint32 identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action's +arguments. +

  • +
  • +

    implementation_id, the uint32 identifier of the “implementation” of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (e.g. a PSA ActionProfile or ActionSelector +instance). The table is then referred to as an indirect match table. +

  • +
  • +

    direct_resource_ids, repeated uint32 identifiers for all the direct +resources attached to this table, such as DirectMeter and DirectCounter +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2. +

  • +
  • +

    size, an int64 describing the desired number of table entries that the +target should support for the table. See the “Size” subsection within the +“Table Properties” section of the P416 language specification for details +[30]. +

  • +
  • +

    idle_timeout_behavior, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +Idle-Timeout section). Value can be any of the +IdleTimeoutBehavior enum: +

    +
      +
    • NO_TIMEOUT (default value), which means that idle timeout is not +supported for this table. +
    • +
    • NOTIFY_CONTROL, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +Table Idle Timeout Notifications). +
    +
  • +
  • +

    is_const_table, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime. +

  • +
  • +

    other_properties, an Any Protobuf message [31] to embed +architecture-specific table properties [30] which are not part +of the core P4 language or of the PSA architecture. +

+

6.4.2. Action

+

Action messages are used to specify all possible actions of all match-action +tables. +

+

The Action message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this action +

  • +
  • +

    params, a repeated field of Param messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each Param message contains the +following fields: +

    +
      +
    • id, the uint32 identifier of this parameter. No rules are prescribed +on the way Param IDs should be allocated, as long as two Param of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the @id +annotation, or let the compiler choose them. +
    • +
    • name, the string representing the name of this parameter. +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this parameter. +
    • +
    • bitwidth, an int32 value set to the size in bits of this parameter. +
    • +
    • doc, which describes this parameter using a Documentation message. +
    • +
    • type_name, which indicates whether the action parameter has a +user-defined type; this is useful for +translation. +
    +
+

6.4.3. ActionProfile

+

ActionProfile messages are used to specify all available instances of Action +Profile and Action Selector PSA externs. +

+

PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile member, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime. +

+

PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into groups. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime. +

+

While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same ActionProfile message to describe both. +

+

The ActionProfile message includes the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Action +Profile or Selector. +

  • +
  • +

    table_ids, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector. +

  • +
  • +

    with_selector, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern. +

  • +
  • +

    size, an int64 representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups. +

  • +
  • +

    max_group_size, an int32 representing the maximum sum of all member +weights within any given selector group, in the case of an Action Selector, or +0 for an Action Profile. PSA programs can use the @max_group_size annotation +to provide this value for Action Selectors. If the annotation is omitted, the +P4Info field will default to 0. +

+

6.4.4. Counter & DirectCounter

+

Counter and DirectCounter messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is: +

+
    +
  • +

    Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index. +

  • +
  • +

    Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table. +

+ +

Both Counter and DirectCounter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this counter +extern instance. +

  • +
  • +

    spec, a message of of type CounterSpec used to describe the compile-time +configuration of this counter. Currently, the CounterSpec message is used to +carry only the counter unit, which can be any of the CounterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES: byte counter. +
    • +
    • PACKETS: packet counter. +
    • +
    • BOTH: combination of both byte and packet counter. +
    +
+ +

For indexed counters, the Counter message contains also a size field, an +int64 representing the maximum number of independent values that can be held +by this counter array. Conversely, the DirectCounter message contains a +direct_table_id field that carries the unit32 identifier of the table to +which this direct counter is attached. +

+

For indexed counters, the Counter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.5. Meter & DirectMeter

+

Meter and DirectMeter messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is: +

+
    +
  • +

    Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +e.g. to set the rate threshold. +

  • +
  • +

    Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table. +

+ +

Both Meter and DirectMeter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this meter +extern instance. +

  • +
  • +

    spec, a message of type MeterSpec used to describe the capabilities of +this meter extern instance. Currently, the MeterSpec message is used to +carry only the meter unit, which can be any of the MeterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES, which signifies that this meter can be configured with rates +expressed in bytes/second. +
    • +
    • PACKETS, for rates expressed in packets/second. +
    +
+ +

For indexed meters, the Meter message contains also a size field, an int64 +representing the maximum number of independent cells that can be held by this +meter. Conversely, the DirectMeter message contains a direct_table_id field +that carries the uint32 identifier of the table to which this direct meter is +attached. +

+

For indexed meters, the Meter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.6. ControllerPacketMetadata

+

ControllerPacketMetadata messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server. +

+

When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet. +

+

Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +@controller_header("packet_in") and @controller_header("packet_out"), +respectively. ControllerPacketMetadata messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages). +

+

A P4Info message can contain at most two ControllerPacketMetadata messages, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message where preamble.name is set to "packet_in" +and "packet_out" for packet-in and packet-out metadata, respectively. +

  • +
  • +

    metadata, a repeated field of type Metadata, where each Metadata message +includes the following fields: +

    +
      +
    • id, a uint32 identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two Metadata of the +same ControllerPacketMetadata message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the @id annotation, or let the compiler choose them. +
    • +
    • name, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below). +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this metadata. +
    • +
    • bitwidth, an int32 representing the size in bits of this metadata. +
    • +
    • type_name, which indicates whether the metadata field has a +user-defined type; this is useful for +translation. +
    +
+ +

As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding ControllerPacketMetadata +messages. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  bit<9> egress_port; /* suggested port where the packet
+                         should be sent */
+  bit<8> queue_id;    /* suggested queue ID */
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  bit<9> ingress_port; /* data plane port ID where
+                          the original packet was received */
+  bit<1> is_clone;     /* 1 if this is a clone of the
+                          original packet */
+}
+
+
+
controller_packet_metadata {
+  preamble {
+    id: 2868916615
+    name: "packet_out"
+    annotations: "@controller_header(\"packet_out\")"
+  }
+  metadata {
+    id: 1
+    name: "egress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "queue_id"
+    bitwidth: 8
+  }
+}
+
+controller_packet_metadata {
+  preamble {
+    id: 2868941301
+    name: "packet_in"
+    annotations: "@controller_header(\"packet_in\")"
+  }
+  metadata {
+    id: 1
+    name: "ingress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "is_clone"
+    bitwidth: 1
+  }
+}
+

Note that the use of @controller_header is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages. +

6.4.7. ValueSet

+

ValueSet messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P416 +specification [39]. +

+

The ValueSet message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Value +Set. +

  • +
  • +

    match, a repeated field of MatchField messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the match_fields repeated field in the +Table message. +

  • +
  • +

    size, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +value_set constructor call. +

+ +

According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of bit<W>, +tuple, or struct [26]. The rest of this section looks at all 3 of +these cases and gives an example ValueSet message when appropriate. +

+
    +
  1. +

    If the type parameter is bit<W>, match will include exactly one +MatchField message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used): +

    +
      +
    • id: set to 1 +
    • +
    • bitwidth: set to the value of W +
    • +
    • match_type: set to EXACT +
    +
+ +
+
+
@id(1) value_set<bit<8> >(4) pvs;
+select (hdr.f8) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    bitwidth: 8
+    match_type: EXACT
+  }
+  size: 4
+}
+
    +
  1. +

    If the type parameter is a tuple, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program. +

  2. +
  3. +

    If the type parameter is a struct, this version of P4Runtime requires that +all the fields of the struct be of type bit<W> (where W can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +match field will include one MatchField message for each field in the +struct, with the following fields: +

    +
      +
    • id: must be unique with respect to the other match entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +@id annotation, or let the compiler choose them. +
    • +
    • name: set to the name of the corresponding struct field. +
    • +
    • annotations: set to the list of P4 annotations associated with the struct +field, except for the @match annotation, if present (see the match field +below). +
    • +
    • bitwidth: set to the value of W for the corresponding struct field. +
    • +
    • type_name, which indicates whether the struct field has a user-defined +type; this is useful for +translation. +
    • +
    • match: by default match_type is set to EXACT; the P4 programmer can +specify a different match type by using the @match annotation +[26]. +
    • +
    • doc: documentation associated with the struct field. +
    +
+ +
+
+
struct match_t {
+  @id(1) bit<8> f8;
+  @id(2) @match(ternary) bit<16> f16;
+  @id(3) @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

In the above example, the @id annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs. +

+

Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a user-defined +type that resolves to a bit<W>, or a struct where +one or more fields is a user-defined type that +resolves to a bit<W>. For each MatchField that corresponds to a user-defined +type, the type_name field must be set to the appropriate value (i.e. the name +of the type). +

6.4.8. Register

+

Register messages are used to specify all possible instances of Register PSA +externs. +

+

Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime. +

+

The Register message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this register +instance. +

  • +
  • +

    type_spec, which specifies the data type stored by this register, expressed +using a P4DataTypeSpec message (see section on Representation of Arbitrary +P4 Types). +

  • +
  • +

    size, an int32 value representing the total number of independent register +cells available. +

  • +
  • +

    index_type_name, which indicates whether the register index has a +user-defined type. This is useful for +translation. The underlying built-in type +must be a fixed-width unsigned bitstring (bit<W>). +

+

6.4.9. Digest

+

Digest messages are used to specify all possible instances of Packet Digest +PSA externs. +

+

A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages. +

+

The Digest message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this digest +instance. +

  • +
  • +

    type_spec, which specifies the data type of an individual digest +notification using a P4DataTypeSpec message (see section on Representation +of Arbitrary P4 Types). +

+

6.4.10. Extern

+

Extern messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one Extern message instance in P4Info. The Extern message defines +the following fields: +

+
    +
  • +

    extern_type_id, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the reserved +range [0x81, 0xfe]. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture. +

  • +
  • +

    extern_type_name, which specifies the fully-qualified P4 name of the extern +type. +

  • +
  • +

    instances, a repeated field of ExternInstance Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +ExternInstance in turn defines the following fields: +

    +
      +
    • preamble, a Preamble message with the ID, name, and alias of this digest +instance. +
    • +
    • info, an Any Protobuf message [31] which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for info should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on Extending +P4Runtime for non-PSA Architectures for more +information. +
    +
+ +

If the P4 program does not include any instance of a given extern type, the +Extern message instance for that type should be omitted from the P4Info. +

6.5. Support for Arbitrary P4 Types with P4TypeInfo

+

See section on Representation of Arbitrary P4 +Types. +

7. P4 Forwarding-Pipeline Configuration

+

The ForwardingPipelineConfig captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the “Device Configuration” and sometimes also referred to as +the “P4 Blob”. It is defined as: +

+
+
+
message ForwardingPipelineConfig {
+  config.P4Info p4info = 1;
+  bytes p4_device_config = 2;
+  message Cookie {
+    uint64 cookie = 1;
+  }
+  Cookie cookie = 3;
+}
+

The p4info field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic. +

+

The p4_device_config is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new ForwardingPipelineConfig on that target. +

+

The cookie field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a GetForwardingPipelineConfig RPC. +When writing the config via a SetForwardingPipelineConfig RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present. +

8. General Principles for Message Formatting

8.1. Set / Unset Protobuf Field

+

In Protobuf version 3 (proto3), the default value for a message field is +“unset” [4]. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +CounterEntry message, an “unset” index field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the index message field is +set, a single entry will be read. +

+

Let's look at the counter example in more details. Based on this specification +document, the C++ server code which processes CounterEntry messages may look +like this: +

+
+
+
auto *counter_entry = ...
+if (counter_entry->has_index()) {
+  auto index = counter_entry->index().index();
+  read_one_entry(counter_entry->id(), index);
+} else {
+  read_all_entries(counter_entry->id());
+}
+
    +
  1. +

    Reading a single counter entry at index 0 in the counter array with id +<id>: +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
      +entry.mutable_index();
      +// The above line sets the index field; it is equivalent to:
      +// auto *index = entry.mutable_index();
      +// index->set_index(0);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
      +index {}
    • +
    • Expected behavior: Counter entry at index 0 is read. Notice that the +index subfield is missing under the index field message of +CounterEntry in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages. +
    +
  2. +
  3. +

    Reading all counter entries by leaving the index field unset +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
    • +
    • Expected behavior: All counter entries for the provided counter +instance are read. Notice that the index message field is unset (default +value) and is therefore omitted from the textual representation of the +message. +
    +
+

8.2. Read-Write Symmetry

+

The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example: +

+
+
+
intended_value = value
+
+status = server.write(intended_value, p4_entity)
+observed_value = server.read(p4_entity)
+
+assert(intended_value == observed_value)
+

To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If Read RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol's complexities to the client implementations. +

+

In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the match fields in a TableEntry message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +MessageDifferencer class [36] included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance. +

8.3. Zero as Reserved Value

+

p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a uint32. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a WriteRequest or a SetForwardingPipelineConfigRequest. +

8.4. Bytestrings

+

P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (bit<W>) or signed (int<W>), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +bytes Protobuf type. The correct bitwidth as per the P4 program of +each integer variable exposed through P4Runtime is specified in the P4Info +message. +

+

The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals: +

+
    +
  • +

    It ensures that a properly encoded binary string's integer value conforms +to the P4Info-specified bitwidth. +

  • +
  • +

    It supports read-write symmetry. +

  • +
  • +

    It helps facilitate non-disruptive P4 program updates. +

+ +

In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type bit<W> and/or int<W>. +

+

Note that this representation does not make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range. +

+

In the P4Runtime API version 1.0, values of table key fields, action parameters, +and fields in packet-in and packet-out headers between a device and the +controller (see 6.4.6), may not be of type int<W>. +The rules for encoding signed values thus only apply to messages of type +P4Data (see 8.5.3). +

+

For a value of type bit<W>, the fewest number of bits required to represent +the integer value $V > 0$ is the smallest integer $A$ such that $V \leq 2^A -1$. +

+

For a value of type int<W>, the fewest number of bits required to represent +the integer value $V \neq 0$ in 2's complement form is the smallest integer $A$ +such that $-2^{A-1} \leq V \leq 2^{A-1} - 1$. +

+

As a special case, define that the value $V=0$ requires at least $A=1$ bit to +represent, regardless of whether it is signed or unsigned. +

+

The shortest possible binary string for an integer $V$ that needs $A$ bits to +represent it is computed as: +

+
+
+
minimum_string_size = floor((A + 7) / 8)
+

Binary strings with the byte length computed as minimum_string_size promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies. +

+

Any additional bits in the bytes sent for an unsigned integer value (type +bit<W>) must be 0. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with 0. +

+

Any additional bits in the bytes sent for a signed integer value (type int<W>) +must be copies of the sign bit, i.e. 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with copies of the +sign bit, i.e. 0 for non-negative values, or 0xff for negative values. In 2's +complement representation, this is called “sign extension”, and leaves the +numeric value represented unchanged. +

+

Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value. +

+

For a received bitstring expected to fit within a bit<W> type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring's width is W bits or less. +

+

For a received bitstring expected to fit within an int<W> type, the value it +represents is in range if, after “undoing sign extension”, the remaining bit +string's width is W bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other. +

+

If the string's byte length is zero, the server always rejects the string. +

+

When the server rejects a binary string due to any of the previous criteria, +it returns an OUT_OF_RANGE error. +

+

For all binary strings, P4Runtime uses big-endian (i.e. network) byte-order. +For signed integer values (int<W> P4 type), P4Runtime uses the same two's +complement bitwise representation as P4. Table 4 +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above. +

+
+ + + + + + + + + + + + + + + + + +
P4 type Integer value P4Runtime binary string Read-write symmetry
bit<8> 99 (0x63) \x63 yes
bit<16> 99 (0x63) \x00\x63 no
bit<16> 99 (0x63) \x63 yes
bit<16> 12388 (0x3064) \x30\x64 yes
bit<16> 12388 (0x3064) \x00\x30\x64 no
bit<12> 99 (0x63) \x00\x63 no
bit<12> 99 (0x63) \x63 yes
bit<12> 99 (0x63) \x00\x00\x63 no
int<8> 99 (0x63) \x63 yes
int<8> -99 (-0x63) \x9d yes
int<8> -99 (-0x63) \xff\x9d no
int<12> -739 (-0x2e3) \xfd\x1d yes
int<16> 0 (0x0) \x00\x00 no
int<16> 0 (0x0) \x00 yes
+
+ +
Table 4. Examples of Valid Bytestring Encoding
+

Table 5 shows some examples of invalid +P4Runtime binary strings: +

+
+ + + + + + + + + + + + +
P4 type P4Runtime binary string
bit<8> \x01\x63
bit<8> empty string
bit<16> \x01\x00\x63
bit<12> \x10\x63
bit<12> \x01\x00\x63
bit<12> \x00\x40\x63
int<8> \x00\x9d
int<12> \x8d\x1d
int<16> empty string
+
+ +
Table 5. Examples of Invalid Bytestring Encoding
+

As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from bit<8> to bit<9>, a server +running the bit<9> version of the P4 program will accept requests from +clients that remain on the bit<8> P4Runtime version. +

+

Despite the server's binary string flexibility for P4 program update support, +the client and server must both remain aware of the +read-write symmetry +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values. +

+

Representation of variable-length integer values (varbit<W> P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the dynamic-length of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an OUT_OF_RANGE error code otherwise. +

8.5. Representation of Arbitrary P4 Types

8.5.1. Problem Statement

+

The P416 language includes more complex types than just binary strings +[3]. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table 6 shows the different +P416 types and how they are allowed to be used, as per the P416 +specification. +

+
+ + + + + + + + + + + + + + + + + + + +
Container type
Element type header header_union struct or tuple
bit<W> allowed error allowed
int<W> allowed error allowed
varbit<W> allowed error allowed
int error error error
void error error error
error error error allowed
match_kind error error error
bool error error allowed
enum allowed1 error allowed
header error allowed allowed
header stack error error allowed
header_union error error allowed
struct error error allowed
tuple error error allowed
+
+ +
Table 6. P4 Type Usage
+

For example, the following P416 objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects. +

+
+
+
Digest<tuple<bit<4>, bit<8> > >() digest_complex;
+digest_complex.pack({ hdr.ipv4.version, hdr.ipv4.protocol });
+// ...
+header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

One solution would be to use only binary string (bytes type) in +p4runtime.proto and to define a custom serialization format for complex P416 +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P416 types. +

8.5.2. P4 Type Specifications in p4info.proto

+

In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type ip_t, which is a header union with 2 possible headers: +ipv4 with type ipv4_t and ipv6 with type ipv6_t. Similarly, they need to +know the field layout for both of these header types. +

+

To achieve this we introduce 2 main Protobuf messages: P4TypeInfo and +P4DataTypeSpec. +

+

P4TypeInfo is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P416 program. These +named types are struct, header, header_union, enum and +serializable_enum; for each of these we have a type specification message, +respectively P4StructTypeSpec, P4HeaderTypeSpec, P4HeaderUnionTypeSpec, +P4EnumTypeSpec and P4SerializableEnumTypeSpec. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. P4TypeInfo also includes the list of parser errors for the program, as +a P4ErrorTypeSpec message. +

+

P4DataTypeSpec is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each P4DataTypeSpec message corresponds to a compile-time type in the +original P416 program (e.g. the type parameter of an extern). This +compile-time type is represented as a Protobuf oneof, which can be: +

+
    +
  • +

    a string representing the name of the type in case of a named type (struct, +header, header_union, enum, serializable_enum or user-defined “new” +type), +

  • +
  • +

    an empty Protobuf message for bool and error, or +

  • +
  • +

    a Protobuf message for other anonymous types (bit<W>, int<W>, varbit<W>, +tuple or stack). The “binary string” types (bit<W>, int<W>, and +varbit<W>) are grouped together in the P4BitstringLikeTypeSpec message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf bytes +type). +

+ +

For all P416 compound types (tuple, struct, header, and header_union), +the order of members in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P416 declaration. The same goes for the order of members of an enum +(serializable or not) or members of error. +

8.5.3. P4Data in p4runtime.proto

+

P4Runtime uses the P4Data message to represent values of arbitrary types. The +P4Runtime client must generate correct P4Data messages based on the type +specification information included in P4Info. The P4Data message was designed +to introduce little overhead compared to using binary strings in the most common +case (P416 bit<W> type). +

+

Just like its P4Info counterpart - P4DataTypeSpec -, P4Data uses a Protobuf +oneof to represent all possible values. +

+

We define a canonical representation for P4Data messages therefore +guaranteeing read-write symmetry by introducing the following requirements: +

+
    +
  • +

    The order of members in P4StructLike and the order of bitstrings in +P4Header must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P416 type +declaration. +

  • +
  • +

    An invalid header is represented by a P4Header message where the is_valid +field is false and the bitstrings repeated field is empty. +

  • +
  • +

    An invalid header union (i.e. all headers in the union are invalid) is +represented by a P4HeaderUnion message where the valid_header_name is the +empty string (default value for the field) and the valid_header is unset. +

  • +
  • +

    The order of entries in P4HeaderStack and P4HeaderUnionStack is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the entries field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding P4HeaderStackTypeSpec or +P4HeaderUnionStackTypeSpec message. +

+

8.5.4. Example

+

Let's look at the Register example again: +

+
+
+
header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

Here's the corresponding entry in the P4Info message: +

+
+
+
registers {
+  preamble {
+    id: 369119267
+    name: "register_ip"
+    alias: "register_ip"
+  }
+  type_spec {
+    header_union {
+      name: "ip_t"
+    }
+  }
+  size: 128
+}
+type_info {
+  headers {
+    key: "ipv4_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  headers {
+    key: "ipv6_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  header_unions {
+    key: "ip_t"
+    value {
+      members {
+        name: "ipv4"
+        header {
+          name: "ipv4_t"
+        }
+      }
+      members {
+        name: "ipv6"
+        header {
+          name: "ipv6_t"
+        }
+      }
+    }
+  }
+}
+

Here's a p4.WriteRequest to set the value of register_ip[12]: +

+
+
+
update {
+  type: INSERT
+  entity {
+    register_entry {
+      register_id: 369119267
+      index {
+        index: 12
+      }
+      data {
+        header_union {
+          valid_header_name: "ipv4"
+          valid_header {
+            is_valid: true
+            bitstrings: "\x04"
+            bitstrings: # ...
+          }
+        }
+      }
+    }
+  }
+}

8.5.5. enum, serializable enum and error

+

P416 supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or “unsafe” enum) +[5]. For enum types with no underlying type as well as error +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in P4Data to represent enum and +error values. +

+

Serializable enum types have an underlying fixed-width unsigned integer +representation (bit<W>). All named enum members must be assigned an integer +value by the P4 programmer, but not all valid numeric values for the +underlying type need to have a corresponding name. P4TypeInfo includes the +mapping between entry name and entry value. When providing serializable enum +values through P4Data, one must use the assigned integer value (enum_value +bytestring field). P4Runtime does not provide a way for the client to use the +name even when the enum member has one instead of the value, as it makes +it easier for the server to respect the read-write +symmetry principle. +

8.5.6. User-defined types

+

P416 enables programmers to introduce new types [11]. While similar +to typedef, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +translation. When introducing a new type, the +declaration can be annotated with @p4runtime_translation to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for port numbers, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. The @p4runtime_translation annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (bit<W>). The type exposed to the control plane (referred to as the +controller_type) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a URI (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the controller_type of the values exposed to the control plane. The +controller_type can be either bit<W> where W is any positive integer, or +string, or a positive integer W which has the same meaning as bit<W>. +Specifying just an integer is deprecated. +

+

It is recommended that the URI includes at least the P4 architecture name and +the type name. +

+

A @p4runtime_translation annotation need not have any effect if it is used to +annotate anything in a P4 program other than a type declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect. +

+

User-defined types are specified using the P4NewTypeSpec message, which has +the following fields: +

+
    +
  • +

    representation, a Protobuf oneof specifying how values of this type are +exchanged between client and server; it can be either: +

    +
      +
    • +

      original_type, if and only if no @p4runtime_translation annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 type declaration is itself a +user-defined type, original_type is obtained by “walking” the chain of +type declarations recursively until a built-in type (e.g. bit<W>) is +found. +

    • +
    • +

      translated_type, if and only if the P4 type declaration was annotated +with @p4runtime_translation. It is of type P4NewTypeTranslation, +which itself has two fields uri and either sdn_string or +sdn_bitwidth , which map to the two input parameters to the +annotation. +

    +
  • +
  • +

    annotations, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration. +

+ +

For example, an architecture in this case PSA may introduce a new type +for port numbers: +

+
+
+
// Controller refers to ports as a string, e.g. "eth0".
+@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+// Controller refers to ports as a 32-bit integer, e.g. 0xffffffff.
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+// Same as above.
+@p4runtime_translation("p4.org/psa/v1/PortId_32_t", 32)
+type bit<9> PortId_32_t;
+

In this case, the P4Info message would include the following P4TypeInfo +messages: +

+
+
+
type_info {
+  new_types {
+    key: "PortId_String_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_String_t"
+        sdn_string: {}
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_Bit32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_Bit32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+

Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (e.g. through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over @p4runtime_translation to enable users +to overwrite annotations included as part of the P4 architecture definition. +

8.5.7. Trade-off for v1.x Releases

+

For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +bytes with P4Data in the p4.v1.FieldMatch message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +bytes to provide action parameter values and controller metadata +values. However P4Data is used whenever appropriate for PSA externs and we +encourage the use of P4Data in architecture-specific extensions. +

+

In order to support translation for action +parameters and match fields, we include a type_name field in +p4.config.v1.MatchField, p4.config.v1.Action.Param and +p4.config.v1.ControllerPacketMetadata.Metadata. In addition, the bitwidth +field for all of these message types must abide by the following rule when +type_name names a translated user-defined type: +

+
    +
  • +

    If the controller_type is a fixed-width unsigned bitstring, the bitwidth +field must be set to the bitwidth of the controller_type. This information +is redundant with the one included in the P4TypeInfo entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent. +

  • +
  • +

    Otherwise (i.e., if the controller_type is a string), the bitwidth must +be “unset”, which, in Protobuf version 3, is the same as setting the field to +0. +

+ +

For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types: +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+@name(".t")
+table t {
+  key = {
+    meta.port1: exact;  // meta.port1 has type PortId_String_t
+    meta.port2: exact;  // meta.port2 has type PortId_Bit32_t
+  }
+  actions = {
+    drop;
+  }
+}
+

This table would have the following representation in the generated P4Info +message: +

+
+
+
tables {
+  preamble {
+    id: 34728461
+    name: "t"
+    alias: "t"
+  }
+  match_fields {
+    id: 1
+    name: "meta.port1"
+    # notice that bitwidth is unset
+    match_type: EXACT
+    type_name {
+      name: "PortId_String_t"
+    }
+  }
+  match_fields {
+    id: 2
+    name: "meta.port2"
+    bitwidth: 32
+    match_type: EXACT
+    type_name {
+      name: "PortId_Bit32_t"
+    }
+  }
+  # ...
+}

9. P4 Entity Messages

+

P4Runtime covers P4 entities that are either part of the P416 language, or +defined as PSA externs. The sections below describe the messages for each +supported entity. +

9.1. TableEntry

+

The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action's +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification. +

+

P4Runtime supports inserting, modifying, deleting and reading table entries with +the TableEntry entity, which has the following fields: +

+
    +
  • +

    table_id, which identifies the table instance; the table_id is determined +by the P4Info message. +

  • +
  • +

    match, a repeated field of FieldMatch messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration. +

  • +
  • +

    action, which indicates which of the table's actions to execute in case of +match and with which argument values. +

  • +
  • +

    priority, a 32-bit integer used to order entries when the table's match key +includes an optional, ternary or range match. +

  • +
  • +

    controller_metadata, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +metadata field. +

  • +
  • +

    metadata, an arbitrary bytes value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. +

  • +
  • +

    meter_config, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    counter_data, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    is_default_action, a boolean flag which indicates whether the table entry is +the default entry for the table. See Default entry +section for more information. +

  • +
  • +

    idle_timeout_ns and time_since_last_hit, which are two fields used to +implement idle-timeout support for the table, if applicable. See +Idle-timeout section for more information. +

+ +

The priority field must be set to a non-zero value if the match key includes a +ternary match (i.e. in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an OPTIONAL, TERNARY or +RANGE match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches. +

+

The match and priority fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for MODIFY and DELETE updates. When deleting +an entry, these key fields (along with is_default_action) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a keyless +table (the table has an empty match key), the server must reject all attempts to +INSERT a match entry and return an INVALID_ARGUMENT error. +

+

The number of match entries that a table should support is indicated in P4Info +(size field of Table message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P416 specification for the +size property [30]. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +RESOURCE_EXHAUSTED when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached. +

9.1.1. Match Format

+

The bytes fields in the FieldMatch message follow the format described in +Bytestrings. +

+

For “don't care” matches, the P4Runtime client must omit the field's entire +FieldMatch entry when building the match repeated field of the TableEntry +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for “don't care” matches, which is needed +to ensure read-write symmetry. For PSA match types, +a “don't care” match for a specific match key field is defined as follows: +

+
    +
  • +

    For a TERNARY match, it is logically equivalent to a mask of zeros. +

  • +
  • +

    For a OPTIONAL match, it is logically equivalent to a wildcard match. +

  • +
  • +

    For an LPM match, it is logically equivalent to a prefix_len of zero. +

  • +
  • +

    For a RANGE match, it is logically equivalent to a range which includes all +possible values for the field. +

+ +

Note that there is no “don't care” value for EXACT matches and therefore exact +match fields can never be omitted from the TableEntry message. +

+

The following example shows a P4Runtime message that treats a TERNARY field +as a “don't care” match. The P4 program defines table t with TERNARY +and EXACT fields in its match key: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: ternary;
+    istd.ingress_port: exact;
+  }
+  actions = {
+    drop;
+  }
+}
+

In this P4Runtime request, the client omits the table's TERNARY field +from the repeated match field to indicate a “don't care” match. As shown +below, the match specifies only the EXACT field given by field_id: 2. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 33554439  # Table t's ID.
+    match {
+      # field_id 1 is not present to use the don't care ternary value.
+      field_id: 2
+      exact {
+        value: "\x20"
+      }
+    }
+    action {
+      # Action selection goes here.
+    }
+  }
+}
+

For every member of the TableEntry repeated match field, field_id must be +a valid id for the table, as per the P4Info, and one of the fields in +field_match_type must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an INVALID_ARGUMENT error code. +

+
    +
  • EXACT match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.exact().value()))
+
    +
  • LPM match + +
      +
    • The binary string encoding of the value (when present) must conform to the +Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • “Don't care” bits must be 0 in value. +
+ +
+
+
assert(BytestringValid(match.lpm().value()))
+
+pLen = match.lpm().prefix_len()
+assert(pLen > 0)
+
+trailing_zeros = countTrailingZeros(match.lpm().value())
+assert(trailing_zeros >= field_bits - pLen)
+
    +
  • TERNARY match + +
      +
    • The binary string encoding of the value (when present) and mask (when +present) must conform to the Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • Masked bits must be 0 in value. This constraint taken together +with the Bytestrings requirements means that the +value's binary string is never longer than the mask's binary string. +When the value's string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask. +
+ +
+
+
assert(BytestringValid(match.ternary().value()))
+assert(BytestringValid(match.ternary().mask()))
+assert(match.ternary().value().size() <= match.ternary().mask().size());
+
+value = parseInteger(match.ternary().value())
+mask = parseInteger(match.ternary().mask())
+
+assert(mask != 0)
+
+assert(value & mask == value)
+
    +
  • RANGE match + +
      +
    • The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the Bytestrings +requirements. +
    • +
    • Low bound must be less than or equal to the high bound. +
    • +
    • “Don't care” match must be omitted. +
+ +
+
+
assert(BytestringValid(match.range().low()))
+assert(BytestringValid(match.range().high()))
+
+low = parseInteger(match.range().low())
+high = parseInteger(match.range().high())
+
+assert(low <= high)
+
+assert(low != min_field_value || high != max_field_value)
+
    +
  • OPTIONAL match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.optional().value()))

9.1.2. Action Specification

+

The TableEntry action field must be set for every INSERT update but may be +left unset for MODIFY updates, in which case the action specification for the +table entry will not be modified (if a MODIFY update has an unset action field +and does not modify any direct resource attached to the table then the MODIFY +update is a no-op). Based on the implementation property value of the P4 table, +the oneof in the TableAction message will either be: +

+
    +
  • +

    an Action specification for direct tables (with no P4 implementation +property) +

  • +
  • +

    an action profile member id for indirect tables for which the implementation +property is an action profile with no selector. +

  • +
  • +

    an action profile member id or group id for indirect tables for which the +implementation property is an action profile with selector. +

  • +
  • +

    an ActionProfileActionSet specification for indirect tables for +which the implementation property is an action profile with +selector. This usage is described in One Shot Action Selector +Programming +

+ +

If the oneof does not match the table description in the P4Info (e.g. the +oneof is action_profile_member_id for a direct table), the server must +return an INVALID_ARGUMENT error code. +

+

The Action Protobuf message has the following fields: +

+
    +
  • +

    action_id, which identifies the action instance; the action_id is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an INVALID_ARGUMENT error +code. If the client uses a valid action_id for the table but does not +respect the action scope specified in P4Info (e.g. tries to set a TABLE_ONLY +action as the default action), the server must return a PERMISSION_DENIED +error code. +

  • +
  • +

    params: a repeated Protobuf field of action parameter values, each encoded +as a Param message. For each parameter, param_id must be valid for the +action (as per the P4Info) and value must follow the format described in +Bytestrings. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an INVALID_ARGUMENT error code +if a parameter id is missing, if an extra parameter id not found in the +P4Info was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +Bytestrings format. +

+ +

For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a NOT_FOUND error code. +

9.1.3. Default Entry

+

According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer or defaults to NoAction +(which is a no-op) otherwise and assuming it is not declared as const, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow INSERT and DELETE updates on the default entry and the +P4Runtime server must return an INVALID_ARGUMENT error code if the client +attempts one. +

+

The default entry is identified by setting the is_default_action boolean field +to true. When this flag is set to true, the repeated match field must be empty +and the priority field must be set to zero, otherwise the P4Runtime server +must return an INVALID_ARGUMENT error code. When performing a MODIFY update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its controller_metadata and metadata value as well as the +configurations for its direct resources will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a PERMISSION_DENIED +error code if the client attempts to modify it. +

+

Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to direct resources. +

+

In this P4Runtime release, we have decided to restrict the default entry for +indirect tables tables with an ActionProfile or ActionSelector +implementation property to a constant NoAction action entry, with the +hope that it would simplify the implementation of the P4Runtime service. +

9.1.4. Constant Tables

+

Constant tables are defined as tables whose match entries are immutable. They +are identified by the is_const_table flag in P4Info. +

+

The only write updates which are allowed for constant tables are MODIFY +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +PERMISSION_DENIED error. Just like any table entry MODIFY request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a PERMISSION_DENIED error. +

+

The contents of const tables can be queried by the client through a +ReadRequest. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: table_id, match, action, +is_default_action, and priority (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the priority field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P416 does not support assigning explicit priorities to static +entries. When a priority value is required (e.g. for tables including RANGE, +TERNARY or OPTIONAL matches), it is inferred based on the order in which +entries appear in the table declaration. +

9.1.5. Wildcard Reads

+

When performing a ReadRequest, the P4Runtime client can select all entries +from one or all tables on the target and use several of the TableEntry fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as priority and “unset” for message fields such as match. The following +fields may be used to select and filter results: +

+
    +
  • table_id: If default (0), entries from all tables including constant +tables will be selected and no other filter can be used. Otherwise only +the specified table will be considered. +
  • +
  • match: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned. +
  • +
  • action: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an action_id (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id. +
  • +
  • priority: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value. +
  • +
  • controller_metadata: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +controller_metadata value. +
  • +
  • metadata: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided metadata value. +
  • +
  • is_default_action: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered. +
+ +

For example, in order to read all entries from all tables from device 3, the +client can use the following ReadRequest message. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0
+    priority: 0
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following ReadRequest +message: +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+    priority: 11
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

The canonical representation of “don't care” matches, combined with the ability +to do a wildcard read on all table entries by leaving the match field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single “don't care” entry or to do a wildcard +read. If a table has no fields with match kind EXACT, it is possible via +P4Runtime to add an entry that is “don't care” for all fields (i.e. has an empty +match field) but is not the default entry (i.e. is_default_action is +false). When reading this entry from the table, there is no way to read only +that entry from the table, because it would require providing an unset match +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single LPM match: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: lpm;
+  }
+  actions = {
+    drop; fwd;
+  }
+}
+

The following WriteRequest message can be used to add 2 entries: +

+
+
+
device_id: 3
+entities {
+  table_entry { # don't care entry
+    table_id: 0x0212ab34
+    # ...
+  }
+  table entry {
+    table_id: 0x0212ab34
+    match {
+      field_id: 1
+      lpm {
+        value: 0x0a000000
+        prefix_len: 8
+      }
+    # ...
+  }
+}
+

The first entry is a “don't care” entry, while the second one matches all +10.0.0.0/8 addresses. The second entry has higher priority than the first one. +

+

The following ReadRequest message will return all entries in the table, not +just the “don't care” entry. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+  }
+}
+

This issue also exists for tables with TERNARY, RANGE, and OPTIONAL +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the “don't care” entry will be returned to the +client. If the client uses distinct priority values for all entries which is +strongly recommended to achieve deterministic behavior , +then there is no ambiguity because the wildcard read will actually return a +single entry (the “don't care” entry) as long as the priority field is set to +the correct value. +

9.1.6. Direct Resources

+

In addition to the DirectCounterEntry and DirectMeterEntry entities, +P4Runtime support reading and writing direct resources as part of the +TableEntry message. This is convenient for two reasons: +

+
    +
  • +

    A table entry and its direct resources can be read with a single entity when +doing a Read RPC call +

  • +
  • +

    The initial configuration for an entry's direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can “hit” the table entry without +executing the appropriate meter entry. +

+ +

Once the table entry has been inserted, the P4Runtime client is free to use the +DirectCounterEntry and DirectMeterEntry messages for read and write +operations on DirectCounter and DirectMeter instances. For example, it is +usually more convenient as well as more efficient to use DirectCounterEntry to +query a counter entry value rather than use TableEntry, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry. +

+

The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does not need to be “executed” in +every action bound to the table. It is an error to provide a direct resource +configuration in a TableEntry message when programming an action that does not +execute the direct resource, and the server must return an INVALID_ARGUMENT +error code. +

+

We leverage Protobuf's ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the TableEntry message. The list below describes how +the server must handle the meter_config and counter_data fields for read and +write requests, based on whether the fields are set or not. We do not cover +error cases in the list, i.e. we assume that we are dealing with a table which +is assigned a direct counter / a direct meter, and that the action being used +for the table entry “executes” the direct resource appropriately. +

+
    +
  • +

    meter_config field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets). +
      • +
      • if set: The initial configuration for the meter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The meter entry's configuration is reset to the default +(meter returns GREEN for all packets). +
      • +
      • if set: The value provided by the client is used to re-configure +the meter entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the meter entry's +configuration (meter_config is unset in the response). +
      • +
      • if set: If the meter entry's configuration is the default +configuration, meter_config is unset in the response. Otherwise, the +response includes the meter entry's configuration that was written by +the client earlier. This respects the “read-write symmetry” principle. +
    +
  • +
  • +

    counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for the counter entry is the default +(0). +
      • +
      • if set: The initial value for the counter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The counter entry's value is not changed. +
      • +
      • if set: The value provided by the client is written to the counter +entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the counter entry's value +(counter_data is unset in the response). +
      • +
      • if set: The response includes the counter entry's value read from +the target. +
    +
+ +

In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +meter_config field unset when inserting or modifying a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the TableEntry message +(i.e. the meter_config field must be set to match the existing configuration). +

9.1.7. Idle-timeout

+

P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not “hit” (i.e. not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification using the +IdleTimeoutNotification message to the primary client, which can then take +action, such as remove the idle table entry. +

+

Two fields of the TableEntry Protobuf message are used to implement idle +timeout: +

+
    +
  • +

    idle_timeout_ns: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, i.e. no +IdleTimeoutNotification message will ever be generated for this entry. When +a client reads a TableEntry, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry. +

  • +
  • +

    time_since_last_hit: a Protobuf message with a single field (elapsed_ns) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The time_since_last_hit field must be unset for a +TableEntry write. When reading a table entry, time_since_last_hit must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0. +

+ +

These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an INVALID_ARGUMENT error code if at least one of these +conditions is met: +

+
    +
  • idle_timeout_ns is set to a non-zero value, or +
  • +
  • time_since_last_hit is set +
+ +

The target should do its best to approximate the idle_timeout_ns value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the TableEntry write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for time_since_last_hit. +

+

P4Runtime does not support idle timeout for default entries. When the +is_default_action flag is set in a TableEntry message, idle_timeout_ns +must be set to 0 (default) and time_since_last_hit must be unset. If the +server receives a TableEntry message which violates this, it must return an +INVALID_ARGUMENT error. +

+

For more information about idle timeout, in particular regarding +IdleTimeoutNotification, please refer to the Table idle timeout +notifications section. +

9.2. ActionProfileMember & ActionProfileGroup

+

P4Runtime defines an API for programming a PSA ActionProfile extern using +ActionProfileMember messages. A PSA ActionSelector extern can be programmed +using both ActionProfileMember and ActionProfileGroup messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table t for L3 routing, implemented with an action +selector as. +

+
+
+
ActionSelector(HashAlgorithm.crc32,
+               /*size = */ 32w1024,
+               /*output_width = */ 32w10) as;
+
+action set_nhop(PortId_t p, EthAddr smac, EthAddr dmac) {
+  istd.egress_port = p;
+  hdr.ethernet.smac = smac;
+  hdr.ethernet.dmac = dmac;
+}
+
+table t {
+  key = {
+    hdr.ipv4.dip: lpm;  // LPM on destination IP address
+  }
+  actions = {
+    set_nhop;
+  }
+  implementation = as;
+}
+

When programming table t in the example above, a P4Runtime client should +specify the TableAction in the TableEntry to be a reference to either an +action profile member or group. The reference is a non-zero uint32 identifier +that uniquely identifies a member or group programmed in the action selector +as. +

+

If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata. +

+

If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata. +

9.2.1. Action Profile Member Programming

+

Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a uint32 identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the actions +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the actions attributes of the +tables must have an identical list of P4 actions. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector. +

+

An ActionProfileMember entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info. +

  • +
  • +

    member_id is the non-zero uint32 identifier of the action profile member +entry being updated. +

  • +
  • +

    action is the specification of the P4 action instance bound to the action +profile member entry. +

+ +

An action profile member may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an ALREADY_EXISTS error +code. The action specification must be provided, or the server must return +INVALID_ARGUMENT. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return RESOURCE_EXHAUSTED. +
  • +
  • MODIFY: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return NOT_FOUND, +and the action specification must be provided, or the server must return +INVALID_ARGUMENT. +
  • +
  • DELETE: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a NOT_FOUND error code. The member +must not be part of an action profile group, or the server must return +FAILED_PRECONDITION. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return FAILED_PRECONDITION. action_profile_id and member_id are the only +fields that are considered when performing a DELETE and every other field +will be ignored. +
+ +

When reading, an ActionProfileMember message with action_profile_id and +member_id equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with action_profile_id equal to the id of +an existing ActionProfile or ActionSelector object, and a member_id equal to +0, will read all members of that specified object. +

9.2.2. Action Profile Group Programming

+

Action profile groups are entries in an ActionSelector and are referenced by a +uint32 identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type. +

+

Within a single ActionSelector object, the uint32 values used to identify its +members are in a separate ‘scope’ from the uint32 values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5. +

+

There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it. +

+

An ActionProfileGroup entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionSelector +extern instance, as defined in P4Info. +

  • +
  • +

    group_id is the non-zero uint32 identifier of the action profile group +entry being updated. +

  • +
  • +

    members is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields: +

    +
      +
    • member_id for looking up the member table in the selector. +
    • +
    • weight specifying the probability of the member's selection at +runtime. 0 is not a valid weight value and the server must return +INVALID_ARGUMENT if the client attempts to use it. +
    • +
    • watch_port is the controller-defined port that the member's +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +9.2.4 for notes on the behavior if all members in +a group are excluded for this reason. If watch_port is empty, then the +member is always included in the selection, regardless of the status of +any port of the device. The value must be empty or the SDN port of an +existing port on the device, otherwise the server must return +INVALID_ARGUMENT. +
    +
  • +
  • +

    max_size is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +MODIFY update. See the subsection below for the rules on setting +max_size. +

+ +

An action profile group may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new group entry bound to a set of existing action profile +members. The group_id must be different from ids of already programmed +groups for that selector, or the server must return an ALREADY_EXISTS error +code. All members specified in the group must exist in the selector, or the +server must return NOT_FOUND. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target. +
  • +
  • MODIFY: Modify the member set specification of an existing group entry. An +entry with the group_id must exist, or the server must return +NOT_FOUND. All members specified in the group entry must exist in the +selector, or the server must return NOT_FOUND. The value of max_size must +be identical to the value used when inserting the group, otherwise an +INVALID_ARGUMENT error is returned. +
  • +
  • DELETE: Delete the group entry and deallocate the group_id. The group must +not be referenced in the table action of any table entry, or the server must +return a FAILED_PRECONDITION error code. If the group_id is invalid, the +server must return NOT_FOUND. action_profile_id and group_id are the +only fields that are considered when performing a DELETE and every other +field will be ignored. +
+ +

When setting the group membership with INSERT or MODIFY, the members +repeated field must not include duplicates, i.e. members with the same +member_id. The weight field is used instead to logically “repeat” the member +inside the group. +

+

It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation “stores” the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made. +

+

When reading, an ActionProfileGroup message with action_profile_id and +group_id equal to 0 will read all groups of all ActionSelector objects. A +message with action_profile_id equal to the id of an existing ActionSelector +object, and a group_id equal to 0, will read all groups of that one specified +object. +

9.2.2.1. Rules on Setting max_size
+

The valid values for max_size depend on the static max_group_size included +in the P4Info message: +

+
    +
  • +

    If max_group_size is greater than 0, then max_size must be greater than 0, +and less than or equal to max_group_size. We assume that the target can +support selector groups for which the sum of all member weights is up to +max_group_size, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If max_size is greater than max_group_size, the server +must return INVALID_ARGUMENT. +

  • +
  • +

    Otherwise (i.e. if max_group_size is 0), the P4Runtime client can set +max_size to any value greater than or equal to 0. +

    +
      +
    • +

      A max_size of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (INSERT or MODIFY), the target must return a +RESOURCE_EXHAUSTED error. +

    • +
    • +

      If max_size is greater than 0 and the value is not supported by the +target, the server must return a RESOURCE_EXHAUSTED error at +group-creation time. +

    +
+

9.2.3. One Shot Action Selector Programming

+

P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids. +

+

One shots are programmed by choosing the ActionProfileActionSet message as the +TableAction. The ActionProfileActionSet message consists of a set of +ActionProfileAction messages, which in turn have the following fields: +

+
    +
  • +

    action is one of the actions specified by the table that is being +programmed. +

  • +
  • +

    weight specifying the probability of the action's selection at runtime. 0 is +not a valid weight value and the server must return INVALID_ARGUMENT if +the client attempts to use it. The sum of all weights across all +ActionProfileAction messages for that ActionProfileActionSet message must +not exceed the max_group_size specificed in the P4Info (if greater than 0), +or the server must return INVALID_ARGUMENT. +

  • +
  • +

    watch_port is the controller-defined port that the action's liveness depends +on. At runtime, the action must be excluded from selection if the watch port +is down. See Section 9.2.2 for more details +on the watch_port field, which also apply for one shot action selector +programming. +

+ +

Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics. +

+

To preserve read-write symmetry, an implementation must answer ReadRequests +with the original one shot messages. It may not return a desugared version of +the one shot message. +

+

For example, consider the action selector table defined +here. This table could be programmed +with the following one shot update: +

+
+
+
table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action {
+    action_profile_action_set {
+      action_profile_actions {
+        action { /* set nexthop 1 */ }
+        weight: 1
+        watch_port: "\x01"
+      }
+      action_profile_actions {
+        action { /* set nexthop 2 */ }
+        weight: 2
+        watch_port: "\x02"
+      }
+      action_profile_actions {
+        action { /* set nexthop 3 */ }
+        weight: 3
+        watch_port: "\x03"
+      }
+    }
+  }
+}
+

Which would be equivalent to the following updates, where GROUP_ID, +MEMBER_ID_1, MEMBER_ID_2, and MEMBER_ID_3 are unused ids: +

+
+
+
action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_1
+  action { /* set nexthop 1 */ }
+}
+action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_2
+  action { /* set nexthop 2 */ }
+}
+action_profile_member {
+  action_profile_id: 1
+  member_id: MEMBER_ID_3
+  action {  /* set nexthop 3 */ }
+}
+action_profile_group {
+  action_profile_id: 0x11ab12cd
+  group_id: GROUP_ID
+  members {
+    member_id: MEMBER_ID_1
+    weight: 1
+    watch_port: "\x01"
+  }
+  members {
+    member_id: MEMBER_ID_2
+    weight: 2
+    watch_port: "\x02"
+  }
+  members {
+    member_id: MEMBER_ID_3
+    weight: 3
+    watch_port: "\x03"
+  }
+}
+table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action { action_profile_group_id: GROUP_ID }
+}
+

Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure correct ordering between the dependent +updates. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct WriteRequest batches are required. +

+

It is possible to include several ActionProfileAction messages with the same +exact action specification in one ActionProfileActionSet message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the weight field. Note that to preserve read-write symmetry, the server +must not coalesce multiple ActionProfileAction messages with the same action +specification into one. +

+

All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with ActionProfileMember and +ActionProfileGroup messages. Programming some entries with one shots, and +other entries with ActionProfileMember and ActionProfileGroup messages is +not allowed, and the server must return the error code INVALID_ARGUMENT in +that case. +

+

A P4Runtime server must support the one shot style of programming tables with +an action selector implementation. Support for the ActionProfileMember and +ActionProfileGroup style is optional. If ActionProfileMember and +ActionProfileGroup are not supported by a server, it must return an +UNIMPLEMENTED error for every ActionProfileMember or ActionProfileGroup +message that it receives. +

9.2.4. Constraints on action selector programming

+

The PSA specification states that the following features are optional in +action selector implementations [22]: +

+
    +
  1. Support for non-empty groups where in the same group, different members are +bound to different actions. +
  2. +
  3. Predictable data plane behavior when a matched table entry points to an empty +group. +
+ +

For 1., if a client tries to INSERT or MODIFY a group with members bound to +different actions, the server should return UNIMPLEMENTED if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return UNIMPLEMENTED (modifying the action parameter values must be +supported, however). +

+

PSA 1.1 introduces the psa_empty_group_action table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. psa_empty_group_action is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of psa_empty_group_action at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +NoAction. Even when psa_empty_group_action is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of psa_empty_group_action mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming. +

+

The PSA specification includes a discussion on how to implement +psa_empty_group_action in software in the P4Runtime server +[25]. +

+

If a P4Runtime implementation does support psa_empty_group_action, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down. +

+

If a P4Runtime implementation does not support psa_empty_group_action, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down. +

9.3. CounterEntry & DirectCounterEntry

+

PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The CounterData +P4Runtime message can be used for all three types of PSA counters PACKETS, +BYTES and PACKETS_AND_BYTES and consists of the following fields: +

+
    +
  • byte_count is an int64, corresponding to the number of octets. +
  • +
  • packet_count is an int64, corresponding to the number of packets. +
+ +
+
+
message CounterData {
+  int64 byte_count = 1;
+  int64 packet_count = 2;
+}
+

P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of byte_count and packet_count fields, which +is equivalent to specifying the counter type PACKETS_AND_BYTES. Counters may +be defined as direct or indirect (indexed) instances. +

9.3.1. DirectCounterEntry

+

A direct counter is a direct resource associated with a TableEntry (see +Direct Resources). The counter_data field of the +TableEntry message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +DirectCounterEntry message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed. +

+
+
+
message DirectCounterEntry {
+  TableEntry table_entry = 1;
+  CounterData data = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectCounterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match TableEntry.match of the table entry +to which this direct counter entry is associated. If a matching TableEntry +is not found, the server returns the error code NOT_FOUND. +

  • +
  • +

    data is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified. +

+ +

Specifying DirectCounterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read the contents of a +DirectCounter: +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the counter value in the counter_data field of the TableEntry message +(see Direct resources). +

  • +
  • +

    Explicitly request the counter value by including the DirectCounterEntry in +the ReadRequest. The table_entry.match field must match the TableEntry +whose counter is being read. If no such entry is found, the server returns the +error code NOT_FOUND. +

+

9.3.2. CounterEntry

+

An indirect or indexed counter is not associated with a specific TableEntry +and may be updated independently of any action. It may be read or written using +the P4Runtime CounterEntry message whose fields are defined as follows: +

+
    +
  • +

    counter_id is a uint32, the unique identifier for the counter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +the counter array. +

  • +
  • +

    data is a Protobuf message of type CounterData, which represents the +counter value. +

+ +
+
+
message CounterEntry {
+  uint32 counter_id = 1;
+  Index index = 2;
+  CounterData data = 3;
+}
+

The CounterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the counter entries in the +array have default value 0. +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect counter instance whose unique id is counter_id +and array index is specified by index. The counter value is set to the value +specified by the client in the data field. Note that the counter value is +not modified if this Protobuf field is not set. If index is omitted all +counter values in the array will be set to the value provided by the +client. The server must return INVALID_ARGUMENT for a negative index value +and OUT_OF_RANGE if the index value exceeds the size of the counter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a ReadRequest by including a CounterEntry +entity for each of the instances, specifying the counter_id and +index. Wildcard reads are also supported as follows. +

+
    +
  • +

    If the counter_id field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id counter_id. +

+

9.4. MeterEntry & DirectMeterEntry

+

Meters are an advanced mechanism for keeping statistics, involving stateful +“marking” and usually “throttling” of packets based on configured rates of +traffic. The PSA metering function is based on the Two Rate Three Color Marker +(trTCM) defined in RFC 2698 [2]. The trTCM meters an arbitrary packet +stream using two configured rates the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes and +“marks” its packets as GREEN, YELLOW or RED based on the observed rate. +

+

A meter may be configured as a direct or indirect instance, similar to a +counter. The MeterConfig P4Runtime message represents meter configuration. +

+
+
+
message MeterConfig {
+  int64 cir = 1;  // Committed Information Rate
+  int64 cburst = 2;  // Committed Burst Size
+  int64 pir = 3;  // Peak Information Rate
+  int64 pburst = 4;  // Peak Burst Size
+}

9.4.1. DirectMeterEntry

+

A direct meter is a direct resource associated with a TableEntry (see Direct +resources). The meter_config field of the TableEntry +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +DirectMeterEntry message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed. +

+
+
+
message DirectMeterEntry {
+  TableEntry table_entry = 1;
+  MeterConfig config = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectMeterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match the match key of the TableEntry +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching TableEntry is not found, +the server returns the error code NOT_FOUND. +

  • +
  • +

    config is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets). +

+ +

Specifying DirectMeterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read a DirectMeter config. +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the meter config in the meter_config field of the TableEntry +message (see Direct resources). +

  • +
  • +

    Explicitly request the meter configuration by including the DirectMeterEntry +in the ReadRequest. The table_entry.match field must match the +TableEntry whose meter config is being read. If no such entry is found, the +server returns the error code NOT_FOUND. +

+

9.4.2. MeterEntry

+

An indirect or indexed meter is not associated with a specific TableEntry and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime MeterEntry message whose fields are defined as +follows: +

+
    +
  • +

    meter_id is a uint32, the unique identifier for the meter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +a meter array. +

  • +
  • +

    config is a Protobuf message of type MeterConfig, which represents the +meter configuration. +

+ +
+
+
message MeterEntry {
+  uint32 meter_id = 1;
+  Index index = 2;
+  MeterConfig config = 3;
+}
+

The MeterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the meter entries in the +array have a default configuration (GREEN for all packets). +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect meter instance whose unique id is meter_id and +array index is specified by index. The meter is reconfigured using the +config field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the index field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if config is unset). The server must return INVALID_ARGUMENT for a +negative index value and OUT_OF_RANGE if the index value exceeds the size of +the meter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a ReadRequest by including a MeterEntry entity for each +of the instances, specifying the meter_id and index. Wildcard reads are also +supported as follows: +

+
    +
  • +

    If the meter_id field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id meter_id. +

+

9.5. PacketReplicationEngineEntry

+

The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets. +

9.5.1. MulticastGroupEntry

+

Multicasting is achieved in PSA programs by setting the multicast_group +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the MulticastGroupEntry API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example. +

+
+
+
control arp_multicast(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ethernet.isValid() &&
+        hdr.ethernet.eth_type == ETH_TYPE_ARP) {
+      smeta.multicast_group = (MulticastGroup_t) 1;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    multicast_group_entry {
+      multicast_group_id: 1
+      replicas { egress_port: 5 instance: 1 }
+      replicas { egress_port: 12 instance: 2 }
+      replicas { egress_port: 18 instance: 3 }
+      replicas { egress_port: 24 instance: 4 }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +PSA Metadata Translation section. +

+

The egress packets may be distinguished for further processing in the egress +using the instance metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 multicast_group metadata is set to a value that is not +programmed in the PRE, then the packet is dropped. +

+

A multicast group may be inserted, modified or deleted as per the following +semantics. +

+
    +
  • INSERT: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The multicast_group_id field is a uint32 and must be greater +than 0 (see explanation below), or the +P4Runtime server must return an INVALID_ARGUMENT error. The replica +instance ID is also a uint32, and its value may not exceed the maximum +allowed by the target for the EgressInstance_t type (0 is allowed), or the +server must return an INVALID_ARGUMENT error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of both egress_port and instance, or the server +must return INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify the set of replicas for a given multicast group entry, +indexed by the given multicast_group_id. Same restrictions as INSERT apply +here. +
  • +
  • DELETE: Delete the multicast group indexed by the given +multicast_group_id. The replicas need not be provided for this +operation. Any packets with their multicast_group metadata in the data plane +set to the deleted multicast_group_id will be dropped. +
+ +

When reading a multicast group, only multicast_group_id is considered. All +other fields in MulticastGroupEntry are ignored. To perform a wildcard +Read on all configured multicast group entries, the multicast_group_id field +must be set to 0, its default value. +

9.5.1.1. Valid Values for multicast_group_id
+

The PSA specification states that the valid data plane values for multicast +group ids (MulticastGroup_t) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target [24]. This means that, in the absence of +translation, the client must set the multicast_group_id field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special wildcard value which is used to read all the multicast groups +configured in the target, the multicast_group_id field must never be set to 0 +when performing a Write RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value. +

9.5.2. CloneSessionEntry

+

PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +clone_session_id identifier and a boolean flag clone in the packet +metadata. The clone_session_id serves as a handle to the clone attributes, +namely a set replicas of (egress port, instance) pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +CloneSessionEntry API. +

+

The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the clone_low_ttl control block is applied in the ingress +pipeline to create an ingress-to-egress clone. +

+
+
+
control clone_low_ttl(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ipv4.isValid() &&
+        hdr.ipv4.ttl <= LOW_TTL_THRESHOLD) {
+      smeta.clone_session_id = 10w100;
+      smeta.clone = true;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    clone_session_entry {
+      session_id: 100
+      replicas { egress_port: 0xfffffffd instance: 1 } # to CPU
+      class_of_service: 2
+      packet_length_bytes: 4096
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type CloneSessionId_t [24]). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes. +

+

The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port 0xfffffffd; see +Translation of Port Numbers). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port. +

+

If the clone_session_id data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created. +

+

A clone session may be inserted, modified or deleted as per the following +semantics: +

+
    +
  • INSERT: Add a new clone session entry bound to a set of egress ports and +replica IDs. The session_id is a uint32 and must be greater than 0 (see +explanation below), or the P4Runtime +server must return an INVALID_ARGUMENT error. The replica instance ID is +also a uint32, and its value may not exceed the maximum allowed by the +target for the EgressInstance_t type (0 is allowed), or the server must also +return an INVALID_ARGUMENT error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (class_of_service field). This value must be a valid +value for the PSA ClassOfService_t type, which supports runtime translation +by default [24], or the server must return +INVALID_ARGUMENT. See PSA Metadata +Translation for more information. The +packet_length_bytes field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +packet_length_bytes field is 0 (default), no truncation on the clone will be +performed. +
  • +
  • MODIFY: Modify the attributes of a given clone session entry, indexed by the +given clone_session_id. Same restrictions as INSERT apply here. +
  • +
  • DELETE: Delete the clone session indexed by the given +clone_session_id. Other fields need not be provided for this operation. Any +packet with their clone_session_id metadata in the data plane set to the +deleted session_id will no longer be cloned. +
+ +

When reading a clone session, only session_id is considered. All other fields +in CloneSessionEntry are ignored. To perform a wildcard Read on all +configured clone session entries, the session_id field must be set to 0, its +default value. The session_id field can never be equal to 0 in a Write +RPC. If it does, the server must return an INVALID_ARGUMENT error. +

9.5.2.1. Valid Values for session_id
+

The PSA specification states that the valid data plane values for clone +session ids (CloneSessionId_t) range from 0 to the maximum value supported by +the target [24]. Note that unlike for multicast group +ids, 0 is a valid data plane value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special wildcard value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a session_id +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is not enabled, we effectively +“lose” one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (e.g. because the target supports a very +limited number of clone sessions), one can enable translation on +CloneSessionId_t and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id. +

9.6. ValueSetEntry

+

Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the parse_trill_types state. +

+
+
+
state parse_l2 {
+  @id(1) value_set<ETH_TYPE_BITWIDTH>(MAX_TRILL_TYPES) trill_types;
+  extract(hdr.ethernet);
+  select (hdr.ethernet.eth_type) {
+    ETH_TYPE_IPV4: parse_ipv4;
+    ETH_TYPE_IPV6: parse_ipv6;
+    trill_types:   parse_trill_types;
+    _:             reject;
+  }
+}
+

The corresponding entry in the P4Info for this Value Set is: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "trill_types"
+  }
+  match {
+    id: 1
+    bitwidth: <ETH_TYPE_BITWIDTH>
+    match_type: EXACT
+  }
+  size: <MAX_TRILL_TYPES>
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0x22f3 }
+      }
+      match {
+        field_id: 1
+        exact { value: 0x893b }
+      }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the parse_trill_types state. +

+

A ValueSetEntry entity update message has the following fields: +

+
    +
  • +

    value_set_id is the uint32 identifier of the Value Set instance, as +defined in P4Info. +

  • +
  • +

    members is a repeated field of type ValueSetMember. When “selecting” +against a Value Set, every member will be considered and if at least one +“matches”, the corresponding parser transition will be taken. Each +ValueSetMember contains a repeated field of FieldMatch messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a ValueSetMember if and only if +it matches all its FieldMatch messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. FieldMatch messages in a ValueSetEntry follow +the same rules as in a TableEntry. +

+ +

A ValueSetEntry may only be modified. If the update type is INSERT or +DELETE, the server must return an INVALID_ARGUMENT error. If the update type +is MODIFY, the server writes the members given in the repeated field to the +Value Set entry indexed by the given value_set_id. The maximum number of +matches must not exceed the maximum size given by the size field in P4Info of +the Value Set, otherwise the server must return a RESOURCE_EXHAUSTED error. To +empty a Value Set (i.e. restore it to its initial state), the P4Runtime client +can perform a MODIFY update with an empty members repeated field. +

+

To facilitate read-write symmetry, the server must +return an ALREADY_EXISTS error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set. +

+

See Appendix A.3 for a more complex Value Set example. +

9.7. RegisterEntry

+

The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The RegisterEntry P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations. +

+

RegisterEntry has the following fields: +

+
    +
  • +

    register_id, which identifies the PSA Register extern instance which is +being accessed by the client; the register_id is specified by the P4Info +message. +

  • +
  • +

    index, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the RegisterEntry message +used for the request. When an index is provided , the server must validate +its value, and return INVALID_ARGUMENT for a negative index or +OUT_OF_RANGE if the index exceeds the size of the register array. +

  • +
  • +

    data: the data to be written to the array (if RegisterEntry is part of a +WriteRequest message) or the data read from the array (if RegisterEntry is +part of a ReadResponse message). The data field is a P4Data message and +must match the format described by the type_spec field of the corresponding +Register entry in the P4Info, or the server must return an INVALID_ARGUMENT +error. +

+

9.8. DigestEntry

+

A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly. +

+

The DigestEntry P4Runtime entity is used to configure how the device must +generate digest messages. The DigestEntry Protobuf message is not used to +carry digest data, which is done on the StreamChannel bidirectional stream +using the DigestList (digest data sent by the target to the client) and +DigestListAck (digest data acknowledgments sent by the client to the target) +Protobuf messages. +

+

In this section, we refer to the data learned by a single data plane call to +Digest<T>::pack as a “digest message” and we use “digest list” to designate +the list of digest messages bundled by the P4Runtime service in a single +DigestList stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are “duplicate” if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are “distinct” +if they are not duplicate. +

+

DigestEntry has the following fields: +

+
    +
  • +

    digest_id, which identifies the PSA Digest extern instance which emitted the +data; the digest_id is determined by the P4Info message. +

  • +
  • +

    config, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +digest_id; these parameters are: +

    +
      +
    • max_timeout_ns: the maximum server buffering delay in nanoseconds for an +outstanding digest message. +
    • +
    • max_list_size: the maximum digest list size in number of digest +messages sent by the server to the client as a single DigestList +Protobuf message. +
    • +
    • ack_timeout_ns: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data. +
    +
+ +

Here is the significance of the different Update types for DigestEntry: +

+
    +
  • INSERT: Enable server generation of DigestList messages for given digest +instance and use provided configuration parameters. +
  • +
  • MODIFY: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance. +
  • +
  • DELETE: Disable server generation of DigestList messages for given digest +instance. +
+ +

A server should buffer digest messages until either: +

+
    +
  • max_timeout_ns time has passed since the first digest message was added to +the empty buffer, or +
  • +
  • max_list_size distinct digest messages have been received from the +data plane and added to the buffer +
+ +

At which point the server should, with best effort, generate a DigestList +stream message with the buffer contents and send it to the primary client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software. +

+

To avoid sending duplicate digest messages across different DigestList +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the primary client indicates that it has received the +digest list and acted on it. The server must keep a “cache” containing the set +of all digest messages that have been sent, but not acknowledged yet by the +primary client, up-to ack_timeout_ns in the past. The server must delete all +cache entries for a given digest list when they are at least ack_timeout_ns +old or when a matching DigestListAck message (i.e. with the same digest_id +and list_id fields as the DigestList message) is received. +

+

The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged DigestList messages. +

+

When max_timeout_ns is set to 0 and / or max_list_size is set to 1, the +server should, with best effort, generate a DigestList message for every +digest message generated by the data plane which is not already in the cache. If +ack_timeout_ns is set to 0, the cache must always be an empty set. If +max_list_size is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +max_timeout_ns configuration parameter. +

+

The P4Runtime server may empty the digest message cache in case of a client +status change. +

+

Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server: +

+
+
+
DigestStream stream;
+DigestCache cache;
+DigestBuffer buffers;
+
+// sends digest list when it is ready
+send_buffer(Id digest_id) {
+  buffer = buffers[digest_id];
+  stream.write(DigestList(buffer));
+  cache.merge(buffer);  // updates cache with new digest list
+  buffer.clear();
+}
+
+// callback which handles data plane digest messages from device
+handle_dataplane_digest(Digest msg) {
+  digest_id = msg.digest_id();
+  buffer = buffers[digest_id];
+  if (msg in cache OR msg in buffer) return;
+  buffer.enqueue(msg);
+  if (buffer.length() < max_list_size(digest_id)) return;
+  send_buffer(digest_id);
+}
+
+// callback which handles ack messages received on the stream
+handle_stream_ack(DigestListAck ack) {
+  // clear all cache entries matching the tuple (digest_id, list_id)
+  cache.erase( (ack.digest_id(), ack.list_id() )
+}
+
+// loop to enforce timeouts
+while (true) {
+  now = now();
+  // check for buffers that need to be sent
+  for ((digest_id, buffer) in buffers) {
+    if (now - buffer.first_enq_time() >= max_timeout_ns(digest_id))
+      send_buffer(buffer_id);
+  }
+  // check for expired entries in cache
+  for ((digest_id, list_id, sent_time) in cache) {
+    if (now - sent_time >= ack_timeout_ns(digest_id))
+      cache.erase( (digest_id, list_id) );
+  }
+  sleep(X);
+}

9.9. ExternEntry

+

This is used to support a P4 extern entity that is not part of PSA. It is +defined as: +

+
+
+
message ExternEntry {
+  uint32 extern_type_id = 1;
+  uint32 extern_id = 2;
+  google.protobuf.Any entry = 3;
+}
+

Each ExternEntry entity maps to an Extern message in the +P4Info and an ExternInstance message within that +message. The extern_type_id field must be equal to the one in +ExternEntry. The extern_id field must be equal to the ID included in the +preamble of the corresponding ExternInstance message. +

+

entry itself is embedded as an Any Protobuf message [31] to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on Extending P4Runtime for non-PSA +Architectures for more information. +

10. Error Reporting Messages

+

P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case. +

+

gRPC uses grpc::Status [32] to represent the status returned by an +RPC. It has 3 attributes: +

+
+
+
StatusCode code_;
+grpc::string error_message_;
+grpc::string binary_error_details_;
+

The code_ represents a canonical error [34] and describes the +overall RPC status. The error_message_ is a developer-facing error message, +which should be in English. The binary_error_details_ carries a serialized +google.rpc.Status message [28] message, which has 3 fields: +

+
+
+
int32 code = 1;  // see code.proto
+string message = 2;
+repeated google.protobuf.Any details = 3;
+

The code and message fields must be the same as code_ and error_message_ +fields from grpc::Status above. The details field is a list that consists of +p4.Error messages that carry error details for individual elements inside +batch-request RPCs (e.g. Write and Read). p4.Error includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices [34]. +

+

Figure 7 illustrates how these messages fit together. +

+
+

error-report +

+
+ +
Figure 7. P4Runtime Error Report Message Format
+

gRPC provides utility functions ExtractErrorDetails() and SetErrorDetails() +[33] to easily convert between grpc::Status and +google.rpc.Status. +

+

Please see sections on individual P4Runtime RPCs for details on how +grpc::Status is populated for reporting errors. +

+

Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on Stream Error +Reporting for more information. +

11. Atomicity of Individual Write and Read Operations

+

Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane apply +operation, and every single Write operation on a table that inserts, deletes, +or modifies one table entry, the apply operation should behave as if that +Write operation has not yet occurred, or as if the Write operation is +complete. The P4 program should never behave as if the Write operation is +partially complete. These guarantees also apply to extern instances: Read and +Write operations on extern entities must execute atomically relative to extern +data plane methods. +

+

The atomicity guarantees provided by P4Runtime for individual Read and Write +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification [23]. +

+

The P416 language introduces an @atomic annotation [14], to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the @atomic annotation for Write +operations, as well as non-wildcard Read operations, +relative to data plane execution. Consider the following P4 example written for +PSA: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024) r1;
+
+  apply {
+    // ...
+    @atomic {
+        Value_t v = r1.read((Index_t)1);
+        v = v + 1;
+        r1.write((Index_t)1, v);
+    }
+  }
+}
+

If a P4Runtime server is processing messages which write to Register r1 at +index 1, these writes must not happen between the data plane read and +write. +

+

Now let's consider the following example: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024, (Value_t)0 /* initial value */) r1;
+
+  apply {
+    @atomic {
+        r1.write((Index_t)1, (Value_t)100);
+        r1.write((Index_t)2, (Value_t)100);
+    }
+    @atomic {
+        r1.write((Index_t)1, (Value_t)200);
+        r1.write((Index_t)2, (Value_t)200);
+    }
+  }
+}
+

If a P4Runtime client issues a wildcard Read on Register r1, there is no +guarantee that r1[1] == r1[2] in the response, as the read for r1[1] may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for r1[2] may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read r1[1] and r1[2] separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +ReadRequest message) of individual read requests. Similar to a batch +ReadRequest, a wildcard read of a register can execute the reads of the +register array elements (r1[1], r1[2], ) in an arbitrary order relative +to each other. +

+

If the @atomic annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program. +

12. Write RPC

+

The Write RPC updates one or more P4 entities on the target. The request is +defined as follows: +

+
+
+
message WriteRequest {
+  uint64 device_id = 1;
+  uint64 role_id = 2;
+  Uint128 election_id = 3;
+  repeated Update updates = 4;
+  enum Atomicity {
+    CONTINUE_ON_ERROR = 0;
+    ROLLBACK_ON_ERROR = 1;
+    DATAPLANE_ATOMIC = 2;
+  }
+  Atomicity atomicity = 5;
+}
+

The device_id uniquely identifies the target P4 device. The role_id and +election_id define the client role and election-id as described in the +Primary-Backup Arbitration and Controller +Replication +section. The server is expected to perform the following checks (in this order) +before processing the updates list: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role_id does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the primary for (device_id, role_id) according to +the election_id value, the server must return a PERMISSION_DENIED error. +

  4. +
  5. +

    If the Write is attempted before a ForwardingPipelineConfig has been set, +the server must return a FAILED_PRECONDITION error. +

+ +

The updates field is a list of P4 entity updates to be applied. Each update is +defined as: +

+
+
+
message Update {
+  enum Type {
+    UNSPECIFIED = 0;
+    INSERT = 1;
+    MODIFY = 2;
+    DELETE = 3;
+  }
+  Type type = 1;
+  Entity entity = 2;
+}
+

This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a logical table (e.g. +CounterEntry) or an actual table (e.g. TableEntry) in the P4 data +plane. Each entity in the container is uniquely identified by its key. Please +refer to the P4 Entity Messages section for details on +what parts of the entity specification make up the key for each P4 entity. +

+

An update can be one of the following types: +

+
    +
  • +

    INSERT: Inserts the given P4 entity in the entity container. +The entity field always specifies the full state of the P4 entity. +If the entity already exists, an ALREADY_EXISTS error is returned, and +the existing entity remains unchanged. +If the entity is malformed, an INVALID_ARGUMENT error is returned. +If the entity cannot be inserted because the container is already full, +a RESOURCE_EXHAUSTED error is returned. +

  • +
  • +

    MODIFY: Modifies the P4 entity to its new specified state. This uses +assign or full-snapshot semantics, i.e. the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an INVALID_ARGUMENT error is usually returned (unless a +more specific error code applies [34]). If the entity does not +exist, a NOT_FOUND error is returned. +

  • +
  • +

    DELETE: Deletes the specified P4 entity. If the entity does not exist, a +NOT_FOUND error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored. +

+ +

If an update is not allowed under the given controller role, the server must +return a PERMISSION_DENIED error for this update. +

12.1. Batching and Ordering of Updates

+

P4Runtime supports batching of Write operations. The list of updates in a +WriteRequest is referred to as a batch. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of TableEntry entities). +

+

The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +WriteRequests can also be processed interleaved and/or in parallel. +However, the processing of requests must be strictly serializable. That +is, given a history $S$ of WriteRequests including the responses to those +requests, there must exist an order $L$ for all updates in $S$, such that: +

+
    +
  1. All updates from the same write request must appear as a contiguous +subsequence in $L$, but the order within that subsequence can be arbitrary. +
  2. +
  3. For two updates $u_1$ and $u_2$, if the write request containing $u_1$ +completed before the write request of $u_2$ was sent, then $u_1$ must appear +before $u_2$ in $L$. +
  4. +
  5. Executing all updates in $L$ sequentially must yield the same response for +every update as in $S$. +
  6. +
  7. The observable state of the switch after $S$ (e.g., through the Read RPC) +is identical to the one obtained by sequentially executing $L$. +
+ +

The Write RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the Write RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (e.g. inserting an ActionProfileMember +followed by pointing a TableEntry to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding Write RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate Write calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each Write call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one. +

12.2. Batch Atomicity

+

A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the Atomicity +enum. A P4Runtime server is required to support only the modes marked as +Required below: +

+
    +
  • +

    Required: CONTINUE_ON_ERROR: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that see each of +these intermediate stages. +

  • +
  • +

    Optional: ROLLBACK_ON_ERROR: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is all-or-none, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that see each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure. +

    +

    If a P4Runtime server does not support this option at all, an +UNIMPLEMENTED error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (e.g. it is +more straightforward to implement batches that contain only INSERT +operations, vs. those that contain DELETE operations), an +UNIMPLEMENTED error is returned when the batch cannot be executed +in a data plane-atomic way. +

  • +
  • +

    Optional: DATAPLANE_ATOMIC: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +transaction. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane's table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table. +

    +

    If a P4Runtime server does not support this option at all, an UNIMPLEMENTED +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an UNIMPLEMENTED error is returned when the batch +cannot be executed in a data plane-atomic way. +

+ +

There is no expectation that a given client must always use the same Atomicity +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use DATAPLANE_ATOMIC at one time and default behavior +(CONTINUE_ON_ERROR) at other times. +

12.3. Error Reporting

+

Please see section Error Reporting Messages for +information on error reporting messages and guidelines. P4Runtime server will +populate grpc::Status as follows: +

+
    +
  1. +

    If all batch updates succeeded, set grpc::Status::code_ to OK and do not +populate any other field. +

  2. +
  3. +

    If an error is encountered before even trying to attempt individual batch +updates, set grpc::Status::code_ that best describes that RPC-wide +error. For example, use UNAVAILABLE if the P4Runtime service is not yet +ready to handle requests. Set error_message_ to describe the issue. Do not +set error_details in this case. +

  4. +
  5. +

    Otherwise, if one or more updates in the batch (WriteRequest.updates) +failed, set grpc::Status::code_ to UNKNOWN. For example, one update in +the batch may fail with RESOURCE_EXHAUSTED and another with +INVALID_ARGUMENT. A p4.Error message is used to capture the status of +each and every update in the batch. The number of p4.Error messages packed +into google.rpc.Status.details field should therefore always match the +number of updates in the WriteRequest, and the order of +p4.Error messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +p4.Error should set the code to OK and omit other fields. +

+ +
+
+
# Example of a grpc::Status returned for a Write RPC with a batch of 3 updates.
+# The first and third updates encountered an error, while the second update
+# succeeded.
+code_ = 2  # UNKNOWN
+error_message_ = "Write failure."
+binary_error_details {
+  code: 2  # UNKNOWN
+  message: "Write failure."
+  details {
+    canonical_code: 8  # RESOURCE_EXHAUSTED
+    message: "Table is full."
+    space: "targetX-psa-vendorY"
+    code: 500  # ERR_TABLE_FULL
+  }
+  details {
+    canonical_code: 0  # OK
+  }
+  details {
+    canonical_code: 6  # ALREADY_EXISTS
+    message: "Entity already exists."
+    space: "targetX-psa-vendorY"
+    code: 600  # ERR_ENTITY_ALREADY_EXISTS
+  }
+}

13. Read RPC

+

The Read RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as: +

+
+
+
message ReadRequest {
+  uint64 device_id = 1;
+  repeated Entity entities = 2;
+}
+

The device_id uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +NOT_FOUND error. The entities repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server. +

+

Since ReadRequests do not mutate any state on the switch, they do not +require an election_id, and they do not require the presence of an open +StreamChannel between the server and client. +

+

The Read response consists of a sequence of messages (a gRPC stream) with +each message defined as: +

+
+
+
message ReadResponse {
+  repeated Entity entities = 1;
+}
+

The entities repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the Finish() method on the stream object +[10]). +

13.1. Nomenclature

+
+
request
+
An element of the p4.ReadRequest.entities repeated field. +
+
batch
+
Refers to the p4.ReadRequest.entities repeated field.
+

Each request acts as a query filter for that entity type. If a request fully +specifies the entity key, the Read operation should retrieve a single P4 +entity. Please refer to the P4 Entity Messages section +for details on what parts of the entity specification make up the entity key. +

13.2. Wildcard Reads

+

P4Runtime allows wildcard read of P4 entities. A request may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the P4 Entity Messages section for details on +what parts of the entity can be wildcarded in a given request. +

+

For example, in a request of type CounterEntry: +

+
    +
  • A default counter_id (0) implies a request to read all counter-entries for +all indirect counters. +
  • +
  • A particular (non-default) counter_id in conjunction with index unset +implies a request to read all counter-entries for the given indirect counter +ID. +
+ +

To read the entire forwarding state for a given device, the P4Runtime client can +generate the following ReadRequest: +

+
+
+
device_id: <ID>
+entities {
+  extern_entry { }  # read all extern instances for all supported extern types
+  table_entry { }  # read all table entries for all tables
+  action_profile_member { }  # read all members for all action profiles
+  action_profile_group { }  # read all groups for all action profiles
+  ...
+}
+

The entity oneof field in the Entity message must always be set, or the +server must return an INVALID_ARGUMENT error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty Entity message in the ReadRequest. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the entity oneof [20]. +

13.3. Batch Processing

+

A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type request +appears only once in the batch. +

+

A P4Runtime server will process the batch as follows: +

+
    +
  1. +

    Lock state (preventing new writes) and validate each request in the batch: +

    +
      +
    1. +

      If it is a valid request, perform the read; +

      +
        +
      1. If the read was successful, return the entities read in +ReadResponse stream. +
      2. +
      3. If the read failed (exception / critical-error), prepare a p4.Error +with code set to INTERNAL. +
      +
    2. +
    3. +

      If the request is invalid (invalid-argument, not-supported, etc.), +prepare a p4.Error with relevant canonical code to capture the error. +

    +
  2. +
  3. +

    Unlock the state (allowing new writes); +

  4. +
  5. +

    Close the ReadResponse stream and return a grpc::Status as follows: +

    +
      +
    1. +

      If no errors were encountered, set code to OK and do not populate any +other field. +

    2. +
    3. +

      Otherwise, the overall code should be set to UNKNOWN. See section +Error Reporting Messages for information +on error reporting messages and guidelines. Assemble a list of p4.Error +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +google.rpc.Status.details field. This behavior also matches Write +RPC. +

    +
+

13.3.1. Example

+

If a client asked to read {a,b,c,d} and b and d requests didn't +validate, the server will return entities corresponding to a and c, followed +by a status {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} in the +details field. +

+

The P4Runtime server is not required to perform any optimization (e.g. merge two +requests in the batch if one is a subset of other). As a result of this, it +is possible for the ReadResponse to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging. +

+

There is no requirement that each request in the batch will correspond to one +ReadResponse message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit. +

+

A P4Runtime server must be prepared to handle multiple concurrent Read RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (e.g. in a single-threaded architecture), it may choose to serialize +Read RPC processing. +

13.4. Parallelism of Read and Write Requests

+

A P4Runtime server may be implemented to serve at most one +ReadRequest or WriteRequest message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so. +

+

For example, imagine a client that wanted to use WriteRequest +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +WriteRequest messages with only a few updates to an ActionSelector +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +WriteRequest batch currently being processed, but it will not +complete for a significant amount of time. +

+

The restrictions on which a client may rely are: +

+
    +
  • The processing of any two WriteRequest messages W1 and W2 must +result in the same state as if one of them was completed before the +other began. +
  • +
  • For any WriteRequest W and any ReadRequest R, R must +return results consistent with a state where W has completed +processing, or W has not yet begun processing. +
+ +

For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a WriteRequest message it acquired a write lock for each stateful +object affected by the WriteRequest, and before starting the +processing of a ReadRequest message it acquired a read lock for each +stateful object accessed by the ReadRequest, such an implementation +meets all of the requirements above. +

+

It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, e.g. if the server somehow determined that two +WriteRequest messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly. +

14. SetForwardingPipelineConfig RPC

+

A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the SetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message SetForwardingPipelineConfigRequest {
+  enum Action {
+    UNSPECIFIED = 0;
+    VERIFY = 1;
+    VERIFY_AND_SAVE = 2;
+    VERIFY_AND_COMMIT = 3;
+    COMMIT = 4;
+    RECONCILE_AND_COMMIT = 5;
+  }
+  uint64 device_id = 1;
+  uint64 role_id = 2;
+  Uint128 election_id = 3;
+  Action action = 4;
+  ForwardingPipelineConfig config = 5;
+}
+

The server is expected to perform the following checks (in this order) +before performing the required action: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role_id does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the primary for (device_id, role_id) according to +the election_id value, the server must return a PERMISSION_DENIED error. +

+ +

The action is the type of configuration action requested, it can be one of: +

+
    +
  • +

    VERIFY: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an INVALID_ARGUMENT +error if config is not provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_SAVE: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent Read / Write requests must refer to fields in the new +config. Returns an INVALID_ARGUMENT error if the forwarding config is not +provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_COMMIT: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an INVALID_ARGUMENT error if the forwarding config is not provided or if the +provided config cannot be realized. +

  • +
  • +

    COMMIT: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a NOT_FOUND error if no saved config +is found, i.e. if no VERIFY_AND_SAVE action preceded this one. Returns an +INVALID_ARGUMENT error if a config is provided with this message. +

  • +
  • +

    RECONCILE_AND_COMMIT: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an UNIMPLEMENTED error. For targets that support this option, an +INVALID_ARGUMENT error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target. +

+ +

The config field is a message of type ForwardingPipelineConfig that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(e.g. generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the Forwarding-Pipeline +Configuration section for details. +

+

A P4Runtime server running on a non-programmable device may not +support SetForwardingPipelineConfig (e.g. the forwarding-pipeline +config is part of the device's software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +UNIMPLEMENTED error. +

15. GetForwardingPipelineConfig RPC

+

The forwarding-pipeline configuration of the target can be retrieved by invoking +the GetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message GetForwardingPipelineConfigRequest {
+  enum ResponseType {
+    ALL = 0;
+    COOKIE_ONLY = 1;
+    P4INFO_AND_COOKIE = 2;
+    DEVICE_CONFIG_AND_COOKIE = 3;
+  }
+  uint64 device_id = 1;
+  ResponseType response_type = 2;
+}
+

The device_id uniquely identifies the target P4 device. A NOT_FOUND error is +returned if the device_id is not recognized by the P4Runtime server. +

+

The response_type is used to specify which fields to populate in the response, +its value can be one of: +

+
    +
  • +

    ALL: returns a ForwardingPipelineConfig with all fields +set as stored by the target. This is the default behaviour if the +response_type field is not set. +

  • +
  • +

    COOKIE_ONLY: reply by setting only the cookie field in the +ForwardingPipelineConfig, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message. +

  • +
  • +

    P4INFO_AND_COOKIE: reply by setting the p4info and cookie fields. +

  • +
  • +

    DEVICE_CONFIG_AND_COOKIE: reply by setting the p4_device_config and +cookie fields. +

+ +

The response contains the ForwardingPipelineConfig for the specified device: +

+
+
+
message GetForwardingPipelineConfigResponse {
+  ForwardingPipelineConfig config = 1;
+}
+

If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level config field will be unset in the response. Examples are +(i) a server that only allows configuration via SetForwardingPipelineConfig +but this RPC hasn't been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn't yet occurred. +

+

Once a forwarding-pipeline config is installed on the device (either via +SetForwardingPipelineConfig or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +config.p4_device_config will be empty / unset in the response, even if +response_type in the request was set to ALL. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the SetForwardingPipelineConfig RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +SetForwardingPipelineConfig, the value of config.cookie will be unset. +

+

If a P4Runtime server supports both SetForwardingPipelineConfig as well as +returning the p4_device_config, there should be read-write symmetry between +SetForwardingPipelineConfig and GetForwardingPipelineConfig RPCs. +

16. P4Runtime Stream Messages

16.1. Packet I/O

+

P4Runtime supports controller packet-in and packet-out by means of PacketIn +and PacketOut stream messages, respectively. +

+

PacketIn messages are sent by the P4Runtime server to the client. Conversely, +PacketOut messages are sent by the client to the server. Any PacketOut +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a StreamMessageResponse message with the error field set to +report the error to the client. See the section on Stream Error +Reporting for more information on error. +

+

As introduced in the ControllerPacketMetadata +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with @controller_header. The expected metadata is described +in the P4Info using the ControllerPacketMetadata messages. +

+

Both PacketIn and PacketOut stream messages share the same fields and are +defined as follows: +

+
+
+
// Packet sent from the controller to the switch.
+message PacketOut {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+// Packet sent from the switch to the controller.
+message PacketIn {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+message PacketMetadata {
+  // This refers to Metadata.id coming from P4Info ControllerPacketMetadata.
+  uint32 metadata_id = 1;
+  bytes value = 2;
+}
+
    +
  • +

    payload is used to carry the full packet content, including the headers. +

  • +
  • +

    metadata is a repeated field of PacketMetadata messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +ControllerPacketMetadata. Indeed, when a P4Runtime client (or server) +generates a PacketOut (or PacketIn) message, it needs to populate the +metadata field with as many values as in ControllerPacketMetadata.metadata +for the packet-out (or packet-in) case. Each PacketMetadata.value is a +binary string and must conform to the Bytestrings +requirements based on the corresponding P4Info +ControllerPacketMetadata.metadata specification. If the metadata field +does not match the P4Info specification, the server must drop the PacketOut +message and may generate a StreamMessageResponse message with the error +field set to report the error to the client which issued the PacketOut. See +the section on Stream Error Reporting for more +information on error. +

+

16.2. Client Arbitration Update

+

P4Runtime's client arbitration mechanism ensures that only the current primary +can modify state on the switch, and that the election_id is monotonically +increasing. For example, the switch must finish all previous write operations +before before selecting a different primary, and must only accept write requests +from the current primary. +

+

As explained earlier in this document, the controller uses the StreamChannel +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via Write RPC), +it needs to start a controller session and become a “primary”. To do so, the +controller first opens a bidirectional stream channel to the server via +StreamChannel for each device and sends a StreamMessageRequest message. The +controller populates the MasterArbitrationUpdate field in this message using +its role_id and election_id and the device_id of the device, as explained +in detail in the Client Arbitration and Controller +Replication +section. For any given (device_id, role_id), the P4Runtime server keeps track +of the highest election_id that it has ever received. If a controller's +election_id is equal to the highest election_id that the server has ever +received, that controller is the primary. All other controllers are backups. +Note that it is possible that all controllers are backups, and that there is no +primary. There can be at most one primary, because for any given +(device_id, role_id), each connected controller has a unique election_id. +

+

This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest election_id after such a restart. +However, across a full restart, the election_id must be +reset. In fact, a full restart is the only way to reset the election_id. +

+

The MasterArbitrationUpdate message is defined as follows: +

+
+
+
message MasterArbitrationUpdate {
+  uint64 device_id = 1;
+  // The role for which the primary client is being arbitrated. For use-cases
+  // where multiple roles are not needed, the controller can leave this unset,
+  // implying default role and full pipeline access.
+  Role role = 2;
+  // The stream RPC with the highest election_id is the primary. The 'primary'
+  // controller instance populates this with its latest election_id. Switch
+  // populates with the highest election ID it has received from all connected
+  // controllers.
+  Uint128 election_id = 3;
+  // Switch populates this with OK for the client that is the primary, and
+  // with an error status for all other connected clients (at every primary
+  // client change). The controller does not populate this field.
+  .google.rpc.Status status = 4;
+}
+
+message Role {
+  // Uniquely identifies this role.
+  uint64 id = 1;
+  // Describes the role configuration, i.e. what operations, P4 entities,
+  // behaviors, etc. are in the scope of a given role. If config is not set
+  // (default case), it implies all P4 objects and control behaviors are in
+  // scope, i.e. full pipeline access. The format of this message is
+  // out-of-scope of P4Runtime.
+  .google.protobuf.Any config = 2;
+}
+

Note that the status field in the MasterArbitrationUpdate message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a StreamMessageResponse message back to the controller, in which +it populates the MasterArbitrationUpdate message using the device_id, +role, and election_id it previously received from the controller. The server +also populates the status field in the MasterArbitrationUpdate according to +the rules in an earlier section. +

+

The sender need not specify an election_id. If the election_id is not +specified, the sender's election_id is considered lower than any +election_id, and the sender will thus never become primary. This way, a +controller can choose to be a backup controller, in order to avoid +“flapping” (if a backup controller connects to the switch shortly before the +actual primary controller, therefore becoming primary temporarily). +

16.3. Digest Messages

+

See the DigestEntry section. +

16.4. Table Idle Timeout Notification

+

When a table supports idle timeout (as per the P4Info message), the primary +client can specify a TTL value for each entry in the table (see +Idle-timeout section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an IdleTimeoutNotification message on the +StreamChannel bidirectional stream to the primary client. The primary client +can then take the action of its choice, most likely remove the idle entry. +

+

The IdleTimeoutNotification Protobuf message has the following fields: +

+
    +
  • +

    timestamp: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server's local clock. +

  • +
  • +

    table_entry: a repeated field of entries which have expired. Each individual +entry is identified by a single TableEntry message. For each TableEntry, +the key fields (table_id, match and priority) must be set, along with +the controller_metadata field, the metadata field, and the +idle_timeout_ns field. Other fields may be set by the server but should be +ignored by the client. +

+ +

Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +IdleTimeoutNotification message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an IdleTimeoutNotification +message with an empty table_entry repeated field. +

+

After generating an idle notification, the P4Runtime server must “reset” the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the primary client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle. +

+

Here is a reasonable pseudo-code implementation for idle timeout for table +entries: +

+
+
+
IdleTimeoutStream stream;
+
+scanning_interval = 10ms;
+
+while (true) {
+  // iterate over all tables which support idle timeout
+  for (table in tables) {
+    if (!table.idle_timeout_supported) continue;
+    // we coalesce all idle notifications for the same table in one
+    // message
+    IdleTimeoutNotification msg;
+    // read time_since_last_hit from device
+    entries = device.load_table_entries_from_hw(table);
+    for (entry in entries) {
+      if (entry.idle_timeout == 0) continue;  // no TTL
+      if (entry.time_since_last_hit < entry.idle_timeout) continue;
+      msg.table_entry_add(entry);
+      entry.reset_time_since_last_hit();
+    }
+    if (msg.table_entry_size() == 0) continue;  // no notifications
+    msg.set_timestamp(now());
+    stream.write(msg);
+  }
+  sleep(scanning_interval);
+}

16.5. Architecture-Specific Notifications

+

P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on StreamChannel, by including an Any Protobuf field [31] +named other in both StreamMessageRequest and StreamMessageResponse. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the PSA Digest +extern. See section on Extending P4Runtime for non-PSA +Architectures for more information. +

16.6. Stream Error Reporting

+

The P4Runtime server can asynchronously report errors which occur when +processing StreamMessageRequest messages, using the error message field (of +type StreamError) in StreamMessageResponse. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature. +

+

The StreamError message has the following fields: +

+
    +
  • canonical_code, which must be set to the appropriate canonical error code +[34]. +
  • +
  • message, an optional developer-facing error message describing the error. +
  • +
  • space and code, which are optional and can be used by vendors to provide +additional details on the error. code is a numeric error code drawn from a +vendor's chosen error space. +
  • +
  • details, which is a Protobuf oneof used to help the client identify which +StreamMessageRequest triggered the error. The server is required to set the +appropriate field in the oneof so that the client can identify which type +of stream message is responsible for the error (packet_out, +digest_list_ack or other), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid PacketOut message from the +client, the packet_out field (of type PacketOutError) should be set in +the details oneof, and the server may additionally set the packet_out +field in the PacketOutError sub-message (by copying it from the invalid +PacketOut message received on the stream channel) so that the client can +know exactly what packet-out triggered the error. +
+ +

The appropriate canonical error code [34] should be used when +populating the canonical_code field. For example: +

+
    +
  • if a controller is not allowed to send a PacketOut message under its +current role definition, the code should be set to PERMISSION_DENIED. +
  • +
  • if the metadata repeated field in PacketOut does not match the P4Info +definition, the code should be set to INVALID_ARGUMENT. It may be useful +for the server to set the packet_out field in this case, so that the client +can find out which set of metadata fields triggered the error. +
  • +
  • if the digest_id field in DigestListAck does not match any Digest entry +in P4Info, the code should be set to INVALID_ARGUMENT. +
+ +

The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, e.g. because of a +burst of PacketIn messages. +

+

Note that client arbitration errors are never reported using the StreamError +message. Invalid MasterArbitrationUpdate messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section 5.3. +

16.6.1. Examples of StreamError Messages

+
    +
  • +

    Malformed packet-out metadata. If the server receives a PacketOut +message with a metadata field with id 7 which is not included in the P4Info +ControllerPacketMetadata message for “packet_out”, the server may send the +following StreamMessageResponse back to the client: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Unknown metadata field id 7."
    + packet_out {
    +   # copied from the PacketOut message received from the client
    +   packet_out {
    +     payload: ...
    +     metadata {
    +       id: 7
    +       name: "I_should_not_be_here"
    +       bitwidth: 32
    +     }
    +     # more metadata
    +   }
    + }
    +}
  • +
  • +

    Packet-out which exceeds the MTU. If the server receives a PacketOut +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following StreamMessageResponse: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Packet exceeds the MTU for port."
    + space: "targetX-psa-vendor1"
    + code: 123  # MTU_EXCEEDED
    + packet_out {
    +   # we do not set the packet_out field as it does not provide any
    +   # extra information to the client
    + }
    +}
+

17. Capabilities RPC

+

The Capabilities RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the CapabilitiesRequest message is empty and the CapabilitiesResponse +message only includes the p4runtime_api_version string field. This field must +be set to the full semantic version string [27] corresponding to the +version of the P4Runtime API implemented by the server, e.g. “1.1.0-rc.1”. +

+

Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three atomicity +modes for WriteRequest batches, two of them being +optional. In the future we may decide to leverage the CapabilitiesResponse +message to enable the server to report to the client which subset of these +atomicity modes is supported. +

+

The semantic version string included in CapabilitiesResponse can be used by +the client to determine which exact feature set is implemented by the server, +since minor releases may introduce new +functionality. However, because the Capabilities RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (i.e. an UNIMPLEMENTED error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0). +

18. Portability Considerations

18.1. PSA Metadata Translation

+

The Portable Switch Architecture (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +[24]. For such metadata, a translation between the controller's +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the @p4runtime_translation annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture. +

+
+

psa-metadata-translation +

+
+ +
Figure 8. P4Runtime Metadata Translation for the Portable Switch Architecture
+

Figure 8 illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller's 32 bit port +numbers to a target's 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch. +

18.1.1. Translation of Port Numbers

+

In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller's space and the PSA device's space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +user-defined P4 types, namely PortId_t and +PortIdInHeader_t, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in psa.p4 for +the PSA device in Switch 1. +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type bit<9> PortId_t;
+@p4runtime_translation("p4.org/psa/v1/PortIdInHeader_t", 32)
+type bit<32> PortIdInHeader_t;
+

The first argument to the @p4runtime_translation annotation is a URI that +indicates to the P4Runtime server which numerical mapping provided by the +out-of-band switch configuration mechanism to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports). +

+

An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows: +

+
+
+
enum SdnPort {
+  SDN_PORT_UNSPECIFIED = 0;
+
+  // SDN ports are numbered starting from 1.
+  SDN_PORT_MIN = 1;
+
+  // The maximum value of an SDN port (physical or logical).
+  SDN_PORT_MAX = 0xfffffeff;
+
+  // Reserved SDN port numbers (0xfffffff0 - 0xffffffff)
+
+  SDN_PORT_RECIRCULATE = 0xfffffffa;
+  SDN_PORT_CPU = 0xfffffffd;
+}
+

The switch config will map SDN_PORT_RECIRCULATE and SDN_PORT_CPU as well +as any SDN port number corresponding to a “regular” front-panel port to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation. +

+

The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs. +

18.1.2. Translation of Packet-IO Header Fields

+

Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  PortIdInHeader_t egress_port;
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  PortIdInHeader_t ingress_port;
+}
+

The header-level annotation @controller_header is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (egress_port) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI first argument to the @p4runtime_translation +annotation). Any subsequent reference to the egress_port field in the +data plane will use the translated value. PortIdInHeader_t is used in the +header definition instead of PortId_t to guarantee byte-aligned headers in +case this is required by the target. +

+

A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target's PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the ingress_port field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller. +

18.1.3. Translation of Match Fields

+

Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table's match key as shown in the example below: +

+
+
+
table t {
+  key = {
+    istd.ingress_port: exact;  // PSA standard metadata ingress port
+  }
+  actions = {
+    drop;
+  }
+}
+

Table t has an exact match on PSA standard metadata ingress port +(istd.ingress_port). Since the field is of type PortId_t, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in t from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table t is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values. +

+

Note that it may be infeasible to translate the value-mask pair for ternary +matches: LPM, TERNARY or RANGE match kinds. The P4Runtime server may +require that for these match kinds the port match be either de facto “exact” +(0xffffffff mask for TERNARY, prefix-length of 32 for LPM, or same low and +high bounds for RANGE) or “don't care”. +

18.1.4. Translation of Action Parameters

+

PortId_t type parameters can be part of a P4 action definition as shown in the +example below: +

+
+
+
action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+}
+
+table t {
+  key = {
+    hdr.h.f: exact;
+  }
+  actions = {
+    a;
+  }
+}
+

The controller may write entries in table t with action a to set the egress +port as shown in the P4 code above. The action parameter p is of type +PortId_t, which leads to a 32-bit bitwidth for p being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device. +

18.1.5. Port Translation for PSA Extern APIs

+

The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch_port +field is of type bytes to carry the SDN representation of the port being +watched. The P4Runtime server will translate the given watch port into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device. +

+

The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type uint32 to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane. +

18.1.6. Using Port as an Index to a Register, Indirect Counter or Indirect Meter

+

P4Runtime supports using a translated value (PortId_t or any other translated +type for which the underlying built-in type is bit<W>) as an index to a +register, indirect counter, or indirect meter. +

+
+
+
Counter<bit<32> /* counter entry type */, PortId_t /* index type */>(
+  32w1024, PSA_CounterType_t.PACKETS) counter;
+action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+  counter.count(p);
+}
+

This P4 Counter declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
counters {
+  preamble {
+    id: 0x12000001
+    name: "counter"
+  }
+  spec {
+    unit: PACKETS
+  }
+  index_type_name {
+    name: "PortId_t"
+  }
+}
+

The controller may read and write counter values from indexed counter counter +using SDN port numbers as indices, and not device-specific port numbers. The +index_type_name field in the P4Info message is a signal to the P4Runtime +server that translation is required. +

19. P4Runtime Versioning

+

P4Runtime follows the Google guidelines for versioning cloud APIs +[6]. We use a MAJOR.MINOR.PATCH style version number scheme and +we increment the: +

+
    +
  • MAJOR version when we make incompatible API changes, +
  • +
  • MINOR version when we add functionality in a backwards-compatible manner, +
  • +
  • PATCH version when we make backwards-compatible bug fixes. +
+ +

The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is p4.v1 and the package +name for P4Info is p4.config.v1. Even though p4 and p4.config are two +different Protobuf packages, p4 depends on p4.config and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence. +

+

As recommended in [6], we may consider using pre-GA release +suffixes (such as alpha or beta) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1). +

+

Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner. [7] describes +what constitute a backwards-compatible change. We expect MAJOR version bumps +to be a rare event. +

+

Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor + patch version numbers in future releases. +

+

All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository [15] and the version label follows +semantic versioning rules [27]. +

20. Extending P4Runtime for non-PSA Architectures

+

P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place. +

+

When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names: +

+
    +
  • p4/[organization]/arch/config/<major version>/p4info.proto +
  • +
  • p4/[organization]/arch/<major version>/p4runtime.proto +
+ +

We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they “extend”. +

+

For the remainder of this section, we will refer to these two files as +p4info-ext and p4runtime-ext respectively. +

20.1. Extending P4Runtime for Architecture-Specific Externs

+

Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both p4info-ext and +p4runtime-ext. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example: +

+
+
+
// T must be a bit<W> type, it indicates the width of each counter cell
+extern MyNewPacketCounter<T> {
+  counter(bit<32> size);
+  increment(in bit<32> index);
+}

20.1.1. Extending the P4Info message

+
    +
  • Id prefixes 0x81 through 0xfe are reserved for architecture-specific +externs. It is recommended that p4info-ext include a P4Ids message based +on the one in p4info.proto that the P4 compiler can refer to when assigning +IDs to each extern instance. +
+ +
+
+
message P4Ids {
+  enum Prefix {
+    UNSPECIFIED = 0;
+    MY_NEW_PACKET_COUNTER = 0x81;
+  }
+}
+
    +
  • p4info-ext should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +p4.config.v1.ExternInstance message as the info +field, which is of type Any [31]. +
+ +
+
+
message MyNewPacketCounter {
+  // corresponds to the T type parameter in the P4 extern definition
+  p4.config.v1.P4DataTypeSpec type_spec = 1;
+  // constructor argument
+  int64 size = 2;
+}

20.1.2. Extending the P4Runtime Service

+

Just like p4info-ext, p4runtime-ext should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an ExternEntry message generated by the +P4Runtime client. +

+

Here is a possible Protobuf message for our MyNewPacketCounter P4 extern: +

+
+
+
// This message enables reading / writing data to the counter at the provided
+// index
+message MyNewPacketCounter {
+  int64 index = 1;
+  p4.v1.P4Data data = 2;
+}
+

P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an Any Protobuf field [31] named other +in both p4.v1.StreamMessageRequest and +p4.v1.StreamMessageResponse. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in p4runtime-ext and embed instances of these messages in +p4.v1.StreamMessageRequest and p4.v1.StreamMessageResponse as appropriate. +

20.2. Architecture-Specific Table Extensions

20.2.1. New Match Types

+

An architecture may introduce new table match types [12]. P4Runtime +accounts for this by providing the following hooks: +

+
    +
  • +

    The match field in p4.config.v1.MatchField (p4info.proto) is a oneof +which can be either one of the default match types (EXACT, LPM, TERNARY, +RANGE, or OPTIONAL) or an architecture-specific match type encoded as a +string. +

  • +
  • +

    The field_match_type field in p4.v1.FieldMatch (p4runtime.proto) is a +oneof which includes an Any Protobuf message [31] field +(other). p4info-ext should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in p4.v1.FieldMatch as the +other field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info. +

+

20.2.2. New Table Properties

+

An architecture may introduce additional table properties +[30]. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +p4.config.v1.Table message includes the other_properties Any Protobuf +field [31]. At the moment, there is not any mechanism to extend the +p4.v1.TableEntry message based on the value of architecture-specific table +properties, but we may include on in future versions of the API. +

21. Known Limitations of Current P4Runtime Version

+
    +
  • +

    FieldMatch, action Param, and controller packet metadata fields only +support unsigned bitstrings, i.e. values of one of the following types (not +the more general P4Data): +

    +
      +
    • bit<W> +
    • +
    • bool. Note that as far as the P4Info message contents and +thus controller software is concerned, such fields of type bool +will be indistinguishable from those that have been declared with +type bit<1>. P4Runtime server software will automatically +perform any conversion needed between the type bit<1> values in +P4Runtime messages and the data plane representation. +
    • +
    • an enum with underlying type bit<W> +
    • +
    • a type or typedef with an underlying type that is one of the above (or +in general a “chain” of type and/or typedef that eventually ends with +one of the types above) +
    +
  • +
  • +

    Support for PSA Random & Timestamp externs is postponed to a future minor +version update. +

  • +
  • +

    P4Info does not include information about which of a table's actions execute +which direct resource(s). +

  • +
  • +

    The default action for indirect match tables is restricted to a const +NoAction known at compile-time. +

  • +
  • +

    There is no mechanism for changing the value of the psa_empty_group_action +table property at runtime. +

  • +
  • +

    There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor + +patch version numbers. +

+

A. Appendix

A.1. Revision History

A.1.1. Changes in v1.3.0

+
    +
  • Add IANA assigned TCP port, 9559, to P4Runtime server discussion. +
  • +
  • Move “Security considerations” section to P4Runtime server discussion. +
  • +
  • Deprecate watch field (int32) in favor of watch_port (bytes). This allows +using the watch port feature with the p4runtime_translation feature. +
  • +
  • Replace master, slave, master arbitration with more inclusive language: +primary, backup, and client arbitration +
  • +
  • Clarify that source locations for annotations are optional in the P4Info +message. +
+

A.1.2. Changes in v1.2.0

+
    +
  • Add new OPTIONAL match kind. At the moment, OPTIONAL is only supported by +the v1model architecture [38], and not by PSA. It will eventually be +included in the core P4 language. +
  • +
  • Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists. +
  • +
  • Add a new metadata field of type bytes to TableEntry. This is more +flexible than the now deprecated controller_metadata field. +
  • +
  • Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +@id annotation. +
  • +
  • Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature. +
  • +
  • Support using string as the controller type in the @p4runtime_translation +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type. +
  • +
  • Add optional P4 source locations to both structured and unstructured +annotations. +
+

A.1.3. Changes in v1.1.0

+
    +
  • Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously. +
  • +
  • Add error field to stream messages sent by the server. +
  • +
  • Add Capabilities RPC to query the P4Runtime API version implemented by the +server. +
  • +
  • Support wildcard reads for multicast groups and clone sessions. +
  • +
  • Support for modifying direct resources of const tables. +
  • +
  • Support P4 user-defined types for Packet IO metadata fields. +
  • +
  • Clarify consistency requirements for Write and Read RPCs. +
  • +
  • Add Appendix providing implementation advice for avoiding common pitfalls: + +
      +
    • advice on setting gRPC Metadata Maximum Size +
    • +
    • advice on setting gRPC Server Maximum Receive Message Size +
  • +
  • Clarify limitations on supported types for FieldMatch, action Param, and +Packet IO metadata fields. +
  • +
  • Clarify that reading entire forwarding state with empty entity is not +supported. +
  • +
  • Document that @p4runtime_translation need only be supported when applied to +type declarations in P4. +
+

A.2. P4 Annotations

+

Table 7 lists P416 annotations introduced primarily for +the purpose of adding features for the P4Runtime API. +

+
+ + + + + + + + + + +
Annotation Description
@brief See section 6.1.3
@controller_header See section 6.4.6
@description See section 6.1.3
@id See section 6.3
@max_group_size See sections 6.4.3, 9.2.2
@pkginfo See section 6.2.1
@p4runtime_translation See sections 8.5.6, 18.1.1
+
+ +
Table 7. P4 annotations introduced by P4Runtime

A.3. A More Complex Value Set Example

+

This section includes a more complex Value Set example, with multiple matches of +different kinds. +

+
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+

This P4 Value Set declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

A P4Runtime client can set the membership for this Value Set with WriteRequest +messages similar to this one: +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xac }
+      }
+      # match for field_id 2 is missing => don't care match
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xdc }
+      }
+      match {
+        field_id: 2
+        ternary { value: 0x88 mask: 8f }
+      }
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+  }
+}

A.4. Guidelines for Implementations

+

This section contains practical advice for implementing P4Runtime clients and +servers. +

A.4.1. gRPC Metadata Maximum Size

+

In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the grpc.max_metadata_size gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the Write P4Runtime RPC. The Write RPC +returns an individual error for every item in a batch (see Section +12), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +RESOURCE_EXHAUSTED error, without any of the individual errors. +

+

To fix this problem, one can set the grpc.max_metadata_size option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it's +limit, as only the receiving side's limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every p4.Error, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +8192 + MAX_UPDATES_PER_WRITE * 100 bytes of metadata. +

+

For example, in C++, one can create a client channel as follows: +

+
+
+
const int MAX_UPDATES_PER_WRITE = 100;
+::grpc::ChannelArguments arguments;
+arguments.SetInt(GRPC_ARG_MAX_METADATA_SIZE, 8192 + MAX_UPDATES_PER_WRITE*100);
+return grpc::CreateCustomChannel(address, credentials, arguments);

A.4.2. gRPC Server Maximum Receive Message Size

+

At the time of writing, the default maximum receive message size in gRPC is 4MB + while the default maximum send message size is unlimited. This can be a +problem for the SetForwardingPipelineConfig RPC, since for some targets the +binary p4_device_config can exceed 4MB, in which case by default the P4Runtime +server would return an INVALID_ARGUMENT error. To a lesser extent, this may +affect the Write RPC as well, in case of extremely large batches. +

+

To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of p4_device_config for their target(s). This can be done by +setting the grpc.max_receive_message_length when building the gRPC server. +

+

For example, in C++, one can set the maximum receive message size as follows: +

+
+
+
const int MAX_RECEIVE_MESSAGE_SIZE = 128 * 1024 * 1024;  // 128MB
+::grpc::ServerBuilder server_builder;
+builder.AddListeningPort(/*...*/);
+builder.RegisterService(/*...*/);  // register P4Runtime service
+builder.SetMaxReceiveMessageSize(MAX_RECEIVE_MESSAGE_SIZE);
+builder.BuildAndStart();
+

On the client side, we recommend that P4Runtime clients do not use Write +batches larger than the default maximum receive message size (4MB) in case +the server did not deem necessary to increase the default value , unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB). +

+

References

+
+ +
[2]“A Two Rate Three Color Marker.” https://​tools.​ietf.​org/​html/​rfc2698.
+ + + + +
[7]“Google Cloud APIs Versioning - Backwards-Compatibility.” https://​cloud.​google.​com/​apis/​design/​versioning#​backwards_​compatibility.
+ +
[9]“gRPC Main Site.” https://​grpc.​io.
+ + + + + +
[15]“p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” https://​github.​com/​p4lang/​p4runtime.
+
[16]“p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.” https://​github.​com/​p4lang/​PI.
+ + +
[19]“Portable Switch Architecture Specification (v1.1.0).” https://​p4.​org/​p4-​spec/​docs/​PSA-​v1.​1.​0.​html.
+ + + + + + + +
[27]“Semantic Versioning.” https://​semver.​org/​.
+ + + + + + + +
[35]“The OpenConfig Project.” http://​openconfig.​net.
+ +
[37]“The Stratum Project.” https://​stratumproject.​org/​.
+ +
+
+
+ +
+

1.an enum type used as a field in a header must specify a +underlying type and representation for enum elements. +

+ + + diff --git a/spec/v1.3.0/P4Runtime-Spec.log b/spec/v1.3.0/P4Runtime-Spec.log new file mode 100644 index 00000000..30ffb088 --- /dev/null +++ b/spec/v1.3.0/P4Runtime-Spec.log @@ -0,0 +1,14585 @@ +This is XeTeX, Version 3.14159265-2.6-0.99992 (TeX Live 2015/Debian) (preloaded format=xelatex 2018.8.17) 1 DEC 2020 02:59 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**build/P4Runtime-Spec.tex +(./build/P4Runtime-Spec.tex +LaTeX2e <2016/02/01> +Babel <3.9q> and hyphenation patterns for 81 language(s) loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2014/09/29 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo +File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@section=\count80 +\c@subsection=\count81 +\c@subsubsection=\count82 +\c@paragraph=\count83 +\c@subparagraph=\count84 +\c@figure=\count85 +\c@table=\count86 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) (build/madoko2.sty (/usr/share/texlive/texmf-dist/tex/latex/colortbl/colortbl.sty +Package: colortbl 2012/02/13 v1.0a Color table columns (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty +Package: array 2014/10/28 v2.4c Tabular extension package (FMi) +\col@sep=\dimen103 +\extrarowheight=\dimen104 +\NC@list=\toks14 +\extratabsurround=\skip43 +\backup@length=\skip44 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty +Package: color 2016/01/03 v1.1b Standard LaTeX Color (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package color Info: Driver file: xetex.def on input line 143. +(/usr/share/texlive/texmf-dist/tex/xelatex/xetex-def/xetex.def +File: xetex.def 2015/09/11 v4.06 LaTeX color/graphics driver for XeTeX (TeX Live/RRM/JK) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +))) +\everycr=\toks15 +\minrowclearance=\skip45 +) (/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: xetex.def on input line 225. +LaTeX Info: Redefining \color on input line 702. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) (build/options.sty +Package: options 2015/03/01, Daan Leijen, Provides convenient path-value (or key-value) options +(/usr/share/texlive/texmf-dist/tex/latex/etoolbox/etoolbox.sty +Package: etoolbox 2015/08/02 v2.2a e-TeX tools for LaTeX (JAW) +\etb@tempcnta=\count87 +) +\opt@nesting=\count88 +\opt@idx=\count89 +\opt@choiceord=\count90 +) (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty +Package: iftex 2013/04/04 v0.2 Provides if(tex) conditional for PDFTeX, XeTeX, and LuaTeX +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2014/10/28 v1.0g Enhanced LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks16 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2016/01/03 v1.0q Standard LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2016/01/03 v1.10 sin cos tan (DPC) +) (/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg +File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live +) +Package graphics Info: Driver file: xetex.def on input line 95. +) +\Gin@req@height=\dimen105 +\Gin@req@width=\dimen106 +) (build/longfbox.sty +Package: longfbox 2015/12/01, Daan Leijen, Provides long fbox that can break over pages +(build/longbox.sty +Package: longbox 2015/12/01, Daan Leijen, Provides basic longbox that can break over pages +(/usr/share/texlive/texmf-dist/tex/latex/mdwtools/footnote.sty +Package: footnote 1997/01/28 1.13 Save footnotes around boxes +\fn@notes=\box26 +\fn@width=\dimen107 +) +\lb@prevdepth=\skip46 +\lb@freevspace=\skip47 +\lb@headbox=\box27 +\lb@savebox=\box28 +\lb@mainbox=\box29 +\lb@usevbox=\count91 +\lb@width=\skip48 +\lb@height=\skip49 +\lb@skiptop=\skip50 +\lb@skipright=\skip51 +\lb@skipbottom=\skip52 +\lb@skipleft=\skip53 +\lb@skipbreaktop=\skip54 +\lb@skipbreakbottom=\skip55 +\lb@outerwidth=\skip56 +\lb@extrasplit=\skip57 +\lb@textalign=\count92 +\lb@baseline=\count93 +\lb@neededvspace=\skip58 +\lb@splitheight=\skip59 +\lb@insurance=\skip60 +\/longbox/@part-height=\skip61 +\/longbox/@part-width=\skip62 +\/longbox/@part-depth=\skip63 +\/longbox/@content-box-height=\skip64 +\/longbox/@content-box-width=\skip65 +\/longbox/@content-box-depth=\skip66 +\/longbox/@breakat-previous=\skip67 +\/longbox/@lower=\skip68 +\/longbox/split-minimum=\skip69 +\/longbox/split-badness=\skip70 +\/longbox/raise=\skip71 +\/longbox/height=\skip72 +\/longbox/width=\skip73 +\/longbox/outer-height=\skip74 +\/longbox/outer-width=\skip75 +\/longbox/skip-top=\skip76 +\/longbox/skip-right=\skip77 +\/longbox/skip-bottom=\skip78 +\/longbox/skip-left=\skip79 +\/longbox/skip-break-bottom=\skip80 +\/longbox/skip-break-top=\skip81 +) (/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.sty +Package: pict2e 2016/02/05 v0.3b Improved picture commands (HjG,RN,JT) +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.cfg +File: pict2e.cfg 2016/02/05 v0.1u pict2e configuration for teTeX/TeXLive +) +Package pict2e Info: Driver file: xetex.def on input line 119. +Package pict2e Info: Driver file for pict2e: p2e-xetex.def on input line 121. +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/p2e-xetex.def +File: p2e-xetex.def 2016/02/05 v0.1u Driver-dependant file (RN,HjG,JT) +) +\pIIe@GRAPH=\toks17 +\@arclen=\dimen108 +\@arcrad=\dimen109 +\@tempdimd=\dimen110 +) (build/ellipse.sty +Package: ellipse 2004/11/05 v1.0 .dtx ellipse file +) +\fbox@oct=\count94 +\fbox@quad=\count95 +\fbox@diaq=\count96 +\fbox@sign=\count97 +\fbox@anglestart=\skip82 +\fbox@angleend=\skip83 +\fbox@dash=\skip84 +\fbox@dashskip=\skip85 +\fbox@anglecur=\skip86 +\fbox@dashangle=\skip87 +\fbox@dashskipangle=\skip88 +\fbox@delta=\skip89 +\fbox@from=\skip90 +\fbox@to=\skip91 +\/fbox/padding-top=\skip92 +\/fbox/padding-right=\skip93 +\/fbox/padding-bottom=\skip94 +\/fbox/padding-left=\skip95 +\/fbox/padding-break-top=\skip96 +\/fbox/padding-break-bottom=\skip97 +\/fbox/margin-top=\skip98 +\/fbox/margin-right=\skip99 +\/fbox/margin-bottom=\skip100 +\/fbox/margin-left=\skip101 +\/fbox/margin-break-top=\skip102 +\/fbox/margin-break-bottom=\skip103 +\/fbox/border-top-width=\skip104 +\/fbox/border-right-width=\skip105 +\/fbox/border-bottom-width=\skip106 +\/fbox/border-left-width=\skip107 +\/fbox/border-break-top-width=\skip108 +\/fbox/border-break-bottom-width=\skip109 +\/fbox/@lower=\skip110 +\/fbox/@padding-box-height=\skip111 +\/fbox/@padding-box-depth=\skip112 +\/fbox/@padding-box-width=\skip113 +\/fbox/@border-box-width=\skip114 +\/fbox/@border-box-height=\skip115 +\/fbox/@border-box-depth=\skip116 +\/fbox/@border-top-left-radius-x=\skip117 +\/fbox/@border-top-right-radius-x=\skip118 +\/fbox/@border-bottom-left-radius-x=\skip119 +\/fbox/@border-bottom-right-radius-x=\skip120 +\/fbox/@border-top-left-radius-y=\skip121 +\/fbox/@border-top-right-radius-y=\skip122 +\/fbox/@border-bottom-left-radius-y=\skip123 +\/fbox/@border-bottom-right-radius-y=\skip124 +\/fbox/@border-top-left-ix=\skip125 +\/fbox/@border-top-left-iy=\skip126 +\/fbox/@border-top-right-ix=\skip127 +\/fbox/@border-top-right-iy=\skip128 +\/fbox/@border-bottom-left-ix=\skip129 +\/fbox/@border-bottom-left-iy=\skip130 +\/fbox/@border-bottom-right-ix=\skip131 +\/fbox/@border-bottom-right-iy=\skip132 +\/fbox/@border-top-left-phi=\skip133 +\/fbox/@border-top-right-phi=\skip134 +\/fbox/@border-bottom-left-phi=\skip135 +\/fbox/@border-bottom-right-phi=\skip136 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2016/03/03 v2.15a AMS math features +\@mathmargin=\skip137 +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2000/06/29 v2.01 AMS text +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen111 +)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen112 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 1999/12/14 v2.01 operator names +) +\inf@bad=\count98 +LaTeX Info: Redefining \frac on input line 199. +\uproot@=\count99 +\leftroot@=\count100 +LaTeX Info: Redefining \overline on input line 297. +\classnum@=\count101 +\DOTSCASE@=\count102 +LaTeX Info: Redefining \ldots on input line 394. +LaTeX Info: Redefining \dots on input line 397. +LaTeX Info: Redefining \cdots on input line 518. +\Mathstrutbox@=\box30 +\strutbox@=\box31 +\big@size=\dimen113 +LaTeX Font Info: Redeclaring font encoding OML on input line 630. +LaTeX Font Info: Redeclaring font encoding OMS on input line 631. +\macc@depth=\count103 +\c@MaxMatrixCols=\count104 +\dotsspace@=\muskip10 +\c@parentequation=\count105 +\dspbrk@lvl=\count106 +\tag@help=\toks19 +\row@=\count107 +\column@=\count108 +\maxfields@=\count109 +\andhelp@=\toks20 +\eqnshift@=\dimen114 +\alignsep@=\dimen115 +\tagshift@=\dimen116 +\tagwidth@=\dimen117 +\totwidth@=\dimen118 +\lineht@=\dimen119 +\@envbody=\toks21 +\multlinegap=\skip138 +\multlinetaggap=\skip139 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2735. +LaTeX Info: Redefining \] on input line 2736. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +) (/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/stmaryrd.sty +Package: stmaryrd 1994/03/03 St Mary's Road symbol package +\symstmry=\mathgroup6 +LaTeX Font Info: Overwriting symbol font `stmry' in version `bold' +(Font) U/stmry/m/n --> U/stmry/b/n on input line 89. +) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty +Package: textcomp 2005/09/27 v1.99g Standard LaTeX package +Package textcomp Info: Sub-encoding information: +(textcomp) 5 = only ISO-Adobe without \textcurrency +(textcomp) 4 = 5 + \texteuro +(textcomp) 3 = 4 + \textohm +(textcomp) 2 = 3 + \textestimated + \textcurrency +(textcomp) 1 = TS1 - \textcircled - \t +(textcomp) 0 = TS1 (full) +(textcomp) Font families with sub-encoding setting implement +(textcomp) only a restricted character set as indicated. +(textcomp) Family '?' is the default used for unknown fonts. +(textcomp) See the documentation for details. +Package textcomp Info: Setting ? sub-encoding to TS1/1 on input line 79. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +) +LaTeX Info: Redefining \oldstylenums on input line 334. +Package textcomp Info: Setting cmr sub-encoding to TS1/0 on input line 349. +Package textcomp Info: Setting cmss sub-encoding to TS1/0 on input line 350. +Package textcomp Info: Setting cmtt sub-encoding to TS1/0 on input line 351. +Package textcomp Info: Setting cmvtt sub-encoding to TS1/0 on input line 352. +Package textcomp Info: Setting cmbr sub-encoding to TS1/0 on input line 353. +Package textcomp Info: Setting cmtl sub-encoding to TS1/0 on input line 354. +Package textcomp Info: Setting ccr sub-encoding to TS1/0 on input line 355. +Package textcomp Info: Setting ptm sub-encoding to TS1/4 on input line 356. +Package textcomp Info: Setting pcr sub-encoding to TS1/4 on input line 357. +Package textcomp Info: Setting phv sub-encoding to TS1/4 on input line 358. +Package textcomp Info: Setting ppl sub-encoding to TS1/3 on input line 359. +Package textcomp Info: Setting pag sub-encoding to TS1/4 on input line 360. +Package textcomp Info: Setting pbk sub-encoding to TS1/4 on input line 361. +Package textcomp Info: Setting pnc sub-encoding to TS1/4 on input line 362. +Package textcomp Info: Setting pzc sub-encoding to TS1/4 on input line 363. +Package textcomp Info: Setting bch sub-encoding to TS1/4 on input line 364. +Package textcomp Info: Setting put sub-encoding to TS1/5 on input line 365. +Package textcomp Info: Setting uag sub-encoding to TS1/5 on input line 366. +Package textcomp Info: Setting ugq sub-encoding to TS1/5 on input line 367. +Package textcomp Info: Setting ul8 sub-encoding to TS1/4 on input line 368. +Package textcomp Info: Setting ul9 sub-encoding to TS1/4 on input line 369. +Package textcomp Info: Setting augie sub-encoding to TS1/5 on input line 370. +Package textcomp Info: Setting dayrom sub-encoding to TS1/3 on input line 371. +Package textcomp Info: Setting dayroms sub-encoding to TS1/3 on input line 372. +Package textcomp Info: Setting pxr sub-encoding to TS1/0 on input line 373. +Package textcomp Info: Setting pxss sub-encoding to TS1/0 on input line 374. +Package textcomp Info: Setting pxtt sub-encoding to TS1/0 on input line 375. +Package textcomp Info: Setting txr sub-encoding to TS1/0 on input line 376. +Package textcomp Info: Setting txss sub-encoding to TS1/0 on input line 377. +Package textcomp Info: Setting txtt sub-encoding to TS1/0 on input line 378. +Package textcomp Info: Setting lmr sub-encoding to TS1/0 on input line 379. +Package textcomp Info: Setting lmdh sub-encoding to TS1/0 on input line 380. +Package textcomp Info: Setting lmss sub-encoding to TS1/0 on input line 381. +Package textcomp Info: Setting lmssq sub-encoding to TS1/0 on input line 382. +Package textcomp Info: Setting lmvtt sub-encoding to TS1/0 on input line 383. +Package textcomp Info: Setting lmtt sub-encoding to TS1/0 on input line 384. +Package textcomp Info: Setting qhv sub-encoding to TS1/0 on input line 385. +Package textcomp Info: Setting qag sub-encoding to TS1/0 on input line 386. +Package textcomp Info: Setting qbk sub-encoding to TS1/0 on input line 387. +Package textcomp Info: Setting qcr sub-encoding to TS1/0 on input line 388. +Package textcomp Info: Setting qcs sub-encoding to TS1/0 on input line 389. +Package textcomp Info: Setting qpl sub-encoding to TS1/0 on input line 390. +Package textcomp Info: Setting qtm sub-encoding to TS1/0 on input line 391. +Package textcomp Info: Setting qzc sub-encoding to TS1/0 on input line 392. +Package textcomp Info: Setting qhvc sub-encoding to TS1/0 on input line 393. +Package textcomp Info: Setting futs sub-encoding to TS1/4 on input line 394. +Package textcomp Info: Setting futx sub-encoding to TS1/4 on input line 395. +Package textcomp Info: Setting futj sub-encoding to TS1/4 on input line 396. +Package textcomp Info: Setting hlh sub-encoding to TS1/3 on input line 397. +Package textcomp Info: Setting hls sub-encoding to TS1/3 on input line 398. +Package textcomp Info: Setting hlst sub-encoding to TS1/3 on input line 399. +Package textcomp Info: Setting hlct sub-encoding to TS1/5 on input line 400. +Package textcomp Info: Setting hlx sub-encoding to TS1/5 on input line 401. +Package textcomp Info: Setting hlce sub-encoding to TS1/5 on input line 402. +Package textcomp Info: Setting hlcn sub-encoding to TS1/5 on input line 403. +Package textcomp Info: Setting hlcw sub-encoding to TS1/5 on input line 404. +Package textcomp Info: Setting hlcf sub-encoding to TS1/5 on input line 405. +Package textcomp Info: Setting pplx sub-encoding to TS1/3 on input line 406. +Package textcomp Info: Setting pplj sub-encoding to TS1/3 on input line 407. +Package textcomp Info: Setting ptmx sub-encoding to TS1/4 on input line 408. +Package textcomp Info: Setting ptmj sub-encoding to TS1/4 on input line 409. +) (/usr/share/texlive/texmf-dist/tex/latex/psnfss/pifont.sty +Package: pifont 2005/04/12 PSNFSS-v9.2a Pi font support (SPQR) +LaTeX Font Info: Try loading font information for U+pzd on input line 63. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upzd.fd +File: upzd.fd 2001/06/04 font definitions for U/pzd. +) +LaTeX Font Info: Try loading font information for U+psy on input line 64. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upsy.fd +File: upsy.fd 2001/06/04 font definitions for U/psy. +)) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2012/11/06 v6.83m Hypertext links for LaTeX +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO) +Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO) +Package hobsub Info: Skipping package `infwarerr' (already loaded). +Package hobsub Info: Skipping package `ltxcmds' (already loaded). +Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO) +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is not detected. +Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) +Package etexcmds Info: Could not find \expanded. +(etexcmds) That can mean that you are not using pdfTeX 1.50 or +(etexcmds) that some package has redefined \expanded. +(etexcmds) In the latter case, load this package earlier. +Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) +Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO) +Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: pdfTeX >= 1.30 not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode not found. +Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO) +Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO) +Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO) +Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO) +Package: xcolor-patch 2011/01/30 xcolor patch +Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO) +Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO) +Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO) +Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2011/03/04 v1.3 Hooks for auxiliary files (HO) +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) +) +\@linkdim=\dimen120 +\Hy@linkcounter=\count110 +\Hy@pagecounter=\count111 +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count112 +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Hyper figures OFF on input line 4443. +Package hyperref Info: Link nesting OFF on input line 4448. +Package hyperref Info: Hyper index ON on input line 4451. +Package hyperref Info: Plain pages OFF on input line 4458. +Package hyperref Info: Backreferencing OFF on input line 4463. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4688. +\c@Hy@tempcnt=\count113 +(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip11 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 5041. +\XeTeXLinkMargin=\dimen121 +\Fld@menulength=\count114 +\Field@Width=\dimen122 +\Fld@charsize=\dimen123 +Package hyperref Info: Hyper figures OFF on input line 6295. +Package hyperref Info: Link nesting OFF on input line 6300. +Package hyperref Info: Hyper index ON on input line 6303. +Package hyperref Info: backreferencing OFF on input line 6310. +Package hyperref Info: Link coloring OFF on input line 6315. +Package hyperref Info: Link coloring with OCG OFF on input line 6320. +Package hyperref Info: PDF/A mode OFF on input line 6325. +LaTeX Info: Redefining \ref on input line 6365. +LaTeX Info: Redefining \pageref on input line 6369. +\Hy@abspage=\count115 +\c@Item=\count116 +\c@Hfootnote=\count117 +) + +Package hyperref Message: Driver (autodetected): hxetex. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hxetex.def +File: hxetex.def 2012/11/06 v6.83m Hyperref driver for XeTeX +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def +File: puenc.def 2012/11/06 v6.83m Hyperref: PDF Unicode definition (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/stringenc.sty +Package: stringenc 2011/12/02 v1.10 Convert strings between diff. encodings (HO) +) +\pdfm@box=\box32 +\c@Hy@AnnotLevel=\count118 +\HyField@AnnotCount=\count119 +\Fld@listcount=\count120 +\c@bookmark@seq@number=\count121 +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO) +Package rerunfilecheck Info: Feature \pdfmdfivesum is not available +(rerunfilecheck) (e.g. pdfTeX or LuaTeX with package `pdftexcmds'). +(rerunfilecheck) Therefore file contents cannot be checked efficiently +(rerunfilecheck) and the loading of the package is aborted. +) +\Hy@SectionHShift=\skip140 +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bookmark.sty +Package: bookmark 2011/12/02 v1.24 PDF bookmarks (HO) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bkm-dvipdfm.def +File: bkm-dvipdfm.def 2011/12/02 v1.24 bookmark driver for dvipdfm (HO) +\BKM@id=\count122 +)) (/usr/share/texlive/texmf-dist/tex/latex/booktabs/booktabs.sty +Package: booktabs 2005/04/14 v1.61803 publication quality tables +\heavyrulewidth=\dimen124 +\lightrulewidth=\dimen125 +\cmidrulewidth=\dimen126 +\belowrulesep=\dimen127 +\belowbottomsep=\dimen128 +\aboverulesep=\dimen129 +\abovetopsep=\dimen130 +\cmidrulesep=\dimen131 +\cmidrulekern=\dimen132 +\defaultaddspace=\dimen133 +\@cmidla=\count123 +\@cmidlb=\count124 +\@aboverulesep=\dimen134 +\@belowrulesep=\dimen135 +\@thisruleclass=\count125 +\@lastruleclass=\count126 +\@thisrulewidth=\dimen136 +) (/usr/share/texlive/texmf-dist/tex/latex/tools/longtable.sty +Package: longtable 2014/10/28 v4.11 Multi-page Table package (DPC) +\LTleft=\skip141 +\LTright=\skip142 +\LTpre=\skip143 +\LTpost=\skip144 +\LTchunksize=\count127 +\LTcapwidth=\dimen137 +\LT@head=\box33 +\LT@firsthead=\box34 +\LT@foot=\box35 +\LT@lastfoot=\box36 +\LT@cols=\count128 +\LT@rows=\count129 +\c@LT@tables=\count130 +\c@LT@chunks=\count131 +\LT@p@ftn=\toks23 +) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Package: anyfontsize 2007/11/22 anyfontsize.sty by pts +) (/usr/share/texlive/texmf-dist/tex/latex/enumitem/enumitem.sty +Package: enumitem 2011/09/28 v3.5.2 Customized lists +\labelindent=\skip145 +\enit@outerparindent=\dimen138 +\enit@toks=\toks24 +\enit@inbox=\box37 +\enitdp@description=\count132 +) (/usr/share/texlive/texmf-dist/tex/latex/wrapfig/wrapfig.sty +\wrapoverhang=\dimen139 +\WF@size=\dimen140 +\c@WF@wrappedlines=\count133 +\WF@box=\box38 +\WF@everypar=\toks25 +Package: wrapfig 2003/01/31 v 3.6 +) (/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.sty (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty +Package: expl3 2016/01/19 v6377 L3 programming layer (loader) +(/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3-code.tex +Package: expl3 2016/01/19 v6377 L3 programming layer (code) +L3 Module: l3bootstrap 2016/01/01 v6339 L3 Bootstrap code +L3 Module: l3names 2015/12/21 v6328 L3 Namespace for primitives +L3 Module: l3basics 2015/11/22 v6315 L3 Basic definitions +L3 Module: l3expan 2015/09/10 v5983 L3 Argument expansion +L3 Module: l3tl 2015/09/29 v6121 L3 Token lists +L3 Module: l3str 2016/01/03 v6357 L3 Strings +L3 Module: l3seq 2015/08/05 v5777 L3 Sequences and stacks +L3 Module: l3int 2016/01/05 v6366 L3 Integers +\c_max_int=\count134 +\l_tmpa_int=\count135 +\l_tmpb_int=\count136 +\g_tmpa_int=\count137 +\g_tmpb_int=\count138 +L3 Module: l3quark 2015/08/17 v5855 L3 Quarks +L3 Module: l3prg 2015/11/01 v6216 L3 Control structures +\g__prg_map_int=\count139 +L3 Module: l3clist 2015/09/02 v5901 L3 Comma separated lists +L3 Module: l3token 2015/11/11 v6249 L3 Experimental token manipulation +L3 Module: l3prop 2016/01/05 v6366 L3 Property lists +L3 Module: l3msg 2015/09/28 v6113 L3 Messages +L3 Module: l3file 2015/12/03 v6317 L3 File and I/O operations +\l_iow_line_count_int=\count140 +\l__iow_target_count_int=\count141 +\l__iow_current_line_int=\count142 +\l__iow_current_word_int=\count143 +\l__iow_current_indentation_int=\count144 +L3 Module: l3skip 2016/01/05 v6366 L3 Dimensions and skips +\c_zero_dim=\dimen141 +\c_max_dim=\dimen142 +\l_tmpa_dim=\dimen143 +\l_tmpb_dim=\dimen144 +\g_tmpa_dim=\dimen145 +\g_tmpb_dim=\dimen146 +\c_zero_skip=\skip146 +\c_max_skip=\skip147 +\l_tmpa_skip=\skip148 +\l_tmpb_skip=\skip149 +\g_tmpa_skip=\skip150 +\g_tmpb_skip=\skip151 +\c_zero_muskip=\muskip12 +\c_max_muskip=\muskip13 +\l_tmpa_muskip=\muskip14 +\l_tmpb_muskip=\muskip15 +\g_tmpa_muskip=\muskip16 +\g_tmpb_muskip=\muskip17 +L3 Module: l3keys 2015/11/17 v6284 L3 Key-value interfaces +\g__keyval_level_int=\count145 +\l_keys_choice_int=\count146 +L3 Module: l3fp 2015/08/25 v5890 L3 Floating points +\c__fp_leading_shift_int=\count147 +\c__fp_middle_shift_int=\count148 +\c__fp_trailing_shift_int=\count149 +\c__fp_big_leading_shift_int=\count150 +\c__fp_big_middle_shift_int=\count151 +\c__fp_big_trailing_shift_int=\count152 +\c__fp_Bigg_leading_shift_int=\count153 +\c__fp_Bigg_middle_shift_int=\count154 +\c__fp_Bigg_trailing_shift_int=\count155 +L3 Module: l3box 2015/08/09 v5822 L3 Experimental boxes +\c_empty_box=\box39 +\l_tmpa_box=\box40 +\l_tmpb_box=\box41 +\g_tmpa_box=\box42 +\g_tmpb_box=\box43 +L3 Module: l3coffins 2015/08/06 v5789 L3 Coffin code layer +\l__coffin_internal_box=\box44 +\l__coffin_internal_dim=\dimen147 +\l__coffin_offset_x_dim=\dimen148 +\l__coffin_offset_y_dim=\dimen149 +\l__coffin_x_dim=\dimen150 +\l__coffin_y_dim=\dimen151 +\l__coffin_x_prime_dim=\dimen152 +\l__coffin_y_prime_dim=\dimen153 +\c_empty_coffin=\box45 +\l__coffin_aligned_coffin=\box46 +\l__coffin_aligned_internal_coffin=\box47 +\l_tmpa_coffin=\box48 +\l_tmpb_coffin=\box49 +\l__coffin_display_coffin=\box50 +\l__coffin_display_coord_coffin=\box51 +\l__coffin_display_pole_coffin=\box52 +\l__coffin_display_offset_dim=\dimen154 +\l__coffin_display_x_dim=\dimen155 +\l__coffin_display_y_dim=\dimen156 +L3 Module: l3color 2014/08/23 v5354 L3 Experimental color support +L3 Module: l3sys 2015/09/25 v6087 L3 Experimental system/runtime functions +L3 Module: l3candidates 2016/01/14 v6376 L3 Experimental additions to l3kernel +\l__box_top_dim=\dimen157 +\l__box_bottom_dim=\dimen158 +\l__box_left_dim=\dimen159 +\l__box_right_dim=\dimen160 +\l__box_top_new_dim=\dimen161 +\l__box_bottom_new_dim=\dimen162 +\l__box_left_new_dim=\dimen163 +\l__box_right_new_dim=\dimen164 +\l__box_internal_box=\box53 +\l__coffin_bounding_shift_dim=\dimen165 +\l__coffin_left_corner_dim=\dimen166 +\l__coffin_right_corner_dim=\dimen167 +\l__coffin_bottom_corner_dim=\dimen168 +\l__coffin_top_corner_dim=\dimen169 +\l__coffin_scaled_total_height_dim=\dimen170 +\l__coffin_scaled_width_dim=\dimen171 +L3 Module: l3luatex 2015/11/11 v6250 L3 Experimental LuaTeX-specific functions +) (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def +File: l3xdvidpfmx.def 2015/11/11 v6250 L3 Experimental driver: xdvipdfmx +)) (/usr/share/texlive/texmf-dist/tex/latex/l3packages/xparse/xparse.sty +Package: xparse 2016/01/19 v6377 L3 Experimental document command parser +\l__xparse_current_arg_int=\count156 +\l__xparse_m_args_int=\count157 +\l__xparse_mandatory_args_int=\count158 +\l__xparse_processor_int=\count159 +\l__xparse_v_nesting_int=\count160 +) +Package: fontspec 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec-xetex.sty +Package: fontspec-xetex 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +\l_fontspec_script_int=\count161 +\l_fontspec_language_int=\count162 +\l_fontspec_strnum_int=\count163 +\l__fontspec_tmpa_dim=\dimen172 +\l__fontspec_tmpb_dim=\dimen173 +\l__fontspec_tmpc_dim=\dimen174 +\g__file_internal_ior=\read1 +(/usr/share/texlive/texmf-dist/tex/latex/base/fontenc.sty +Package: fontenc 2005/09/27 v1.99g Standard LaTeX package +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1enc.def +File: eu1enc.def 2010/05/27 v0.1h Experimental Unicode font encodings +) +LaTeX Font Info: Try loading font information for EU1+lmr on input line 105. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmr.fd +File: eu1lmr.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) (/usr/share/texlive/texmf-dist/tex/xelatex/xunicode/xunicode.sty +File: xunicode.sty 2011/09/09 v0.981 provides access to latin accents and many other characters in Unicode lower plane +(/usr/share/texmf/tex/latex/tipa/t3enc.def +File: t3enc.def 2001/12/31 T3 encoding +LaTeX Font Info: Try loading font information for EU1+lmss on input line 357. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmss.fd +File: eu1lmss.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) +\tipaTiiicode=\count164 +\tipasavetokens=\toks26 +\tipachecktokens=\toks27 +) +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \__fontspec_post_arg:w with sig. 'mmO{}' on line 353. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \fontspec with sig. 'om' on line 355. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmainfont with sig. 'om' on line 365. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setsansfont with sig. 'om' on line 375. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmonofont with sig. 'om' on line 385. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathrm with sig. 'om' on line 399. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setboldmathrm with sig. 'om' on line 407. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathsf with sig. 'om' on line 415. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathtt with sig. 'om' on line 423. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfamily with sig. 'mom' on line 437. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontface with sig. 'mom' on line 453. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \defaultfontfeatures with sig. 't+om' on line 467. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \addfontfeatures with sig. 'm' on line 529. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfeature with sig. 'mm' on line 540. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newAATfeature with sig. 'mmmm' on line 548. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newopentypefeature with sig. 'mmm' on line 556. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeature with sig. 'mm' on line 577. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeatureoption with sig. 'mmm' on line 586. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontscript with sig. 'mm' on line 590. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontlanguage with sig. 'mm' on line 594. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \DeclareFontsExtensions with sig. 'm' on line 599. +................................................. +\l__fontspec_tmp_int=\count165 +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.cfg) +LaTeX Info: Redefining \itshape on input line 2705. +LaTeX Info: Redefining \slshape on input line 2710. +LaTeX Info: Redefining \scshape on input line 2715. +LaTeX Info: Redefining \upshape on input line 2720. +\l__fontspec_em_int=\count166 +\l__fontspec_emdef_int=\count167 +LaTeX Info: Redefining \em on input line 2736. +LaTeX Info: Redefining \emph on input line 2742. +LaTeX Info: Redefining \- on input line 2746. +................................................. +. LaTeX info: "xparse/redefine-command" +. +. Redefining command \oldstylenums with sig. 'm' on line 2841. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \liningnums with sig. 'm' on line 2845. +................................................. +)) +Package hyperref Info: Option `colorlinks' set `true' on input line 87. +\px=\skip152 +\c@md@targetcount=\count168 +\mdcompactskip=\skip153 +\mdcompacttopsep=\skip154 +\dim@rem=\skip155 +\dim@ch=\skip156 +\md@height=\skip157 +\dim@marginbottom=\skip158 +\dim@paddingbottom=\skip159 +\md@interaction=\count169 +\mddefinitionsskip=\skip160 +\md@captionlen=\skip161 +\mdtoclevel=\count170 +\c@mdtoclevelbold=\count171 +\c@mdtocleveldots=\count172 +\mdtocskip=\skip162 +\mdpreskip=\skip163 +\presp=\skip164 +LaTeX Font Info: Try loading font information for EU1+lmtt on input line 801. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmtt.fd +File: eu1lmtt.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +\md@postskip=\skip165 +\ppresp=\skip166 +\md@thmcaption=\box54 +\md@defaultcolwidth=\skip167 +\mdtabularskip=\skip168 +\mdbibindentunit=\skip169 +\c@md@authorcount=\count173 +\c@mdx@authorcount=\count174 +\c@@mdTargetCount=\count175 +\@snippetBox=\box55 +\@snippetWidth=\skip170 +\@snippetHeight=\skip171 +\@snippetDepth=\skip172 +\c@snippets=\count176 +) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty +Package: geometry 2010/09/12 v5.6 Page Geometry +\Gm@cnth=\count177 +\Gm@cntv=\count178 +\c@Gm@tempcnt=\count179 +\Gm@bindingoffset=\dimen175 +\Gm@wd@mp=\dimen176 +\Gm@odd@mp=\dimen177 +\Gm@even@mp=\dimen178 +\Gm@layoutwidth=\dimen179 +\Gm@layoutheight=\dimen180 +\Gm@layouthoffset=\dimen181 +\Gm@layoutvoffset=\dimen182 +\Gm@dimlist=\toks28 +) (/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +\fancy@headwidth=\skip173 +\f@ncyO@elh=\skip174 +\f@ncyO@erh=\skip175 +\f@ncyO@olh=\skip176 +\f@ncyO@orh=\skip177 +\f@ncyO@elf=\skip178 +\f@ncyO@erf=\skip179 +\f@ncyO@olf=\skip180 +\f@ncyO@orf=\skip181 +) (build/P4Runtime-Spec.aux + +LaTeX Warning: Label `sec-example' multiply defined. + +) +\openout1 = `P4Runtime-Spec.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for TS1+cmr on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1cmr.fd +File: ts1cmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions +) +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for EU1/lmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T3/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for T3+cmr on input line 14. +(/usr/share/texmf/tex/latex/tipa/t3cmr.fd +File: t3cmr.fd 2001/12/31 TIPA font definitions +) +LaTeX Font Info: ... okay on input line 14. +\AtBeginShipoutBox=\box56 +Package hyperref Info: Link coloring ON on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2012/10/27 v2.43 Cross-referencing by name of section +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO) +) +\c@section@level=\count180 +) +LaTeX Info: Redefining \ref on input line 14. +LaTeX Info: Redefining \pageref on input line 14. +LaTeX Info: Redefining \nameref on input line 14. +................................................. +. fontspec info: "setup-math" +. +. Adjusting the maths setup (use [no-math] to avoid this). +................................................. +\symlegacymaths=\mathgroup7 +LaTeX Font Info: Overwriting symbol font `legacymaths' in version `bold' +(Font) OT1/cmr/m/n --> OT1/cmr/bx/n on input line 14. +LaTeX Font Info: Redeclaring math accent \acute on input line 14. +LaTeX Font Info: Redeclaring math accent \grave on input line 14. +LaTeX Font Info: Redeclaring math accent \ddot on input line 14. +LaTeX Font Info: Redeclaring math accent \tilde on input line 14. +LaTeX Font Info: Redeclaring math accent \bar on input line 14. +LaTeX Font Info: Redeclaring math accent \breve on input line 14. +LaTeX Font Info: Redeclaring math accent \check on input line 14. +LaTeX Font Info: Redeclaring math accent \hat on input line 14. +LaTeX Font Info: Redeclaring math accent \dot on input line 14. +LaTeX Font Info: Redeclaring math accent \mathring on input line 14. +LaTeX Font Info: Redeclaring math symbol \Gamma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Delta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Theta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Lambda on input line 14. +LaTeX Font Info: Redeclaring math symbol \Xi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Pi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Sigma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Upsilon on input line 14. +LaTeX Font Info: Redeclaring math symbol \Phi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Psi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Omega on input line 14. +LaTeX Font Info: Redeclaring math symbol \mathdollar on input line 14. +LaTeX Font Info: Redeclaring symbol font `operators' on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `normal' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/cmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `bold' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/cmr/bx/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) EU1/lmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/cmr/m/it --> EU1/lmr/m/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/cmr/bx/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/cmss/m/n --> EU1/lmss/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/cmtt/m/n --> EU1/lmtt/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) EU1/lmr/m/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' +(Font) OT1/cmr/bx/it --> EU1/lmr/bx/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/cmss/bx/n --> EU1/lmss/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/cmtt/m/n --> EU1/lmtt/bx/n on input line 14. +*geometry* driver: auto-detecting +*geometry* detected driver: xetex +*geometry* verbose mode - [ preamble ] result: +* driver: xetex +* paper: +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: +* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt) +* v-part:(T,H,B)=(72.26999pt, 632.3625pt, 90.3375pt) +* \paperwidth=614.295pt +* \paperheight=794.96999pt +* \textwidth=469.75502pt +* \textheight=632.3625pt +* \oddsidemargin=0.0pt +* \evensidemargin=0.0pt +* \topmargin=-37.0pt +* \headheight=30.0pt +* \headsep=25.0pt +* \topskip=11.0pt +* \footskip=30.0pt +* \marginparwidth=59.0pt +* \marginparsep=10.0pt +* \columnsep=10.0pt +* \skip\footins=10.0pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +resolve font stack: UtopiaStd-Regular + +\g__fontspec_family_UtopiaStd-Regular_int=\count181 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'UtopiaStd-Regular(0)' created for font 'UtopiaStd-Regular' with +. options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;" +. - 'small caps' (m/sc) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;+smcp;" +................................................. + +resolved font stack 'UtopiaStd-Regular' to: UtopiaStd-Regular +LaTeX Font Info: Try loading font information for U+msa on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Try loading font information for U+msb on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Try loading font information for U+stmry on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/Ustmry.fd) + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/bx/n' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 35. + +resolve font stack: LuxiMono + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +\g__fontspec_family_LuxiMono_int=\count182 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'LuxiMono(0)' created for font 'LuxiMono' with options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: <->"LuxiMono/OT:" +. - 'small caps' (m/sc) with NFSS spec.: +................................................. + +resolved font stack 'LuxiMono' to: LuxiMono +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/se-ascii-print.def +File: se-ascii-print.def 2011/12/02 v1.10 stringenc: Printable ASCII characters +) [1 + +] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[2] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <10.95> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 307. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Font Warning: Font shape `EU1/LuxiMono(0)/bx/n' undefined +(Font) using `EU1/LuxiMono(0)/m/n' instead on input line 307. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[3] + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/m/it' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 517. + +[4] [5] [6] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[7] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/reference-architecture.png Graphic file (type QTm) + [8] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[9] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[10] +File: build/single-embedded-controller.png Graphic file (type QTm) + +File: build/single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-single-remote-controller.png Graphic file (type QTm) + [11] [12] +File: build/embedded-plus-two-remote-controllers.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-ha-controllers.png Graphic file (type QTm) + [13] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[14] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[15] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <12> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 1528. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1528. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1528. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1528. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1528. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1528. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1528. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1528. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1528. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1528. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1528. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1528. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1528. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1528. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[16] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[17] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (65.03293pt too wide) in paragraph at lines 1825--1828 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For all backup controllers, \EU1/LuxiMono(0)/bx/n/8.2125 status \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set to non-OK (with \EU1/LuxiMono(0)/bx/n/8.2125 status.code \EU1/UtopiaStd-Regular(0)/m/it/10.95 set to \EU1/LuxiMono(0)/bx/n/8.2125 google.rpc.ALREADY_EXISTS\EU1/UtopiaStd-Regular(0)/m/it/10.95 ). + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[18] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1862. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1886. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1886. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[19] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1931. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[20] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[21] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[22] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2214. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2214. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2214. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2214. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2214. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2214. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2214. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2214. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2214. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2214. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2214. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2214. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2214. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[23] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1057) in paragraph at lines 2264--2268 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For structured annotations, every \EU1/LuxiMono(0)/bx/n/8.2125 StructuredAnnotation \EU1/UtopiaStd-Regular(0)/m/it/10.95 message contains an optional field + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2271. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2271. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2271. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2271. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2271. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2271. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2271. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2271. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2271. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2271. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2271. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2271. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2271. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[24] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[25] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[26] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (12.45624pt too wide) in paragraph at lines 2502--2515 + [] + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2538. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2538. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[27] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[28] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2729. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2729. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2729. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2729. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2729. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2729. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2729. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2729. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2729. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2729. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2729. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2729. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2729. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2789. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2789. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2789. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2789. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2789. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2789. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2789. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2789. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2789. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2789. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2789. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2789. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2789. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[29] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2862. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2862. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[30] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2943. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2943. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.59204pt too wide) in paragraph at lines 2997--2999 +[]\EU1/LuxiMono(0)/bx/n/8.2125 BYTES\EU1/UtopiaStd-Regular(0)/m/it/10.95 , which signifies that this meter can be configured with rates expressed in bytes/second. + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3022. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3022. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3022. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3022. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3022. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3022. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3022. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3022. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3022. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3022. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3022. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3022. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3022. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[31] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (18.74199pt too wide) in paragraph at lines 3039--3046 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 carrying P4 standard annotations \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_in") \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_out")\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[32] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3181. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3181. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3181. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3181. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3181. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3181. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3181. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3181. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3181. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3181. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3181. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3181. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3181. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[33] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[34] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[35] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3409. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3409. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3409. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3409. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3409. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3409. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3409. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3409. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3409. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3409. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3409. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3409. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3409. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3456. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3456. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[36] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3494. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3494. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3494. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3494. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3494. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3494. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3494. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3494. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3494. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3494. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3494. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3494. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3494. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[37] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[38] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[39] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[40] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[41] [42] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1629) in paragraph at lines 4098--4100 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For example, the following P4$[]$ objects involve complex types that need to be exposed in + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[43] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1454) in paragraph at lines 4146--4155 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 ification for all the named types in the P4$[]$ program. These named types are \EU1/LuxiMono(0)/bx/n/8.2125 struct\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 header\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + + +Underfull \hbox (badness 1831) in paragraph at lines 4146--4155 +\EU1/LuxiMono(0)/bx/n/8.2125 header_union\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 enum \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 serializable_enum\EU1/UtopiaStd-Regular(0)/m/it/10.95 ; for each of these we have a type specification mes- + [] + + +Underfull \hbox (badness 1845) in paragraph at lines 4146--4155 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 sage, respectively \EU1/LuxiMono(0)/bx/n/8.2125 P4StructTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnionTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4EnumTypeSpec \EU1/UtopiaStd-Regular(0)/m/it/10.95 and + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (33.06564pt too wide) in paragraph at lines 4181--4188 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 “binary string” types (\EU1/LuxiMono(0)/bx/n/8.2125 bit\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 int\EU1/UtopiaStd-Regular(0)/m/it/10.95 , and \EU1/LuxiMono(0)/bx/n/8.2125 varbit\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) are grouped together in the \EU1/LuxiMono(0)/bx/n/8.2125 P4BitstringLikeTypeSpec + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4198. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4198. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4198. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4198. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4198. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4198. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4198. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4198. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4198. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4198. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4198. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4198. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4198. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[44] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.46094pt too wide) in paragraph at lines 4235--4238 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 An invalid header union (i.e. all headers in the union are invalid) is represented by a \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnion + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[45] [46] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4372. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4372. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[47] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (24.68944pt too wide) in paragraph at lines 4460--4466 +[]\EU1/LuxiMono(0)/bx/n/8.2125 translated_type\EU1/UtopiaStd-Regular(0)/m/it/10.95 , if and only if the P4 \EU1/LuxiMono(0)/bx/n/8.2125 type \EU1/UtopiaStd-Regular(0)/m/it/10.95 declaration was annotated with \EU1/LuxiMono(0)/bx/n/8.2125 @p4runtime_translation\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[48] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[49] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (32.59732pt too wide) in paragraph at lines 4568--4574 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 in \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.MatchField\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.Action.Param \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.ControllerPacketMetadata.Metadata\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[50] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4675. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4675. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4675. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4675. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4675. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4675. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4675. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4675. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4675. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4675. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4675. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4675. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4675. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[51] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[52] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[53] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[54] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.53593pt too wide) in paragraph at lines 5131--5134 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 If the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 does not match the table description in the P4Info (e.g. the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 is \EU1/LuxiMono(0)/bx/n/8.2125 action_profile_member_id + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[55] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[56] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[57] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[58] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[59] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[60] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5704. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[61] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[62] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[63] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (9.29865pt too wide) in paragraph at lines 5988--5990 + []\EU1/lmr/bx/n/10.95 9.2.2.1.| Rules on Setting \EU1/LuxiMono(0)/bx/n/8.2125 max_size[] \EU1/UtopiaStd-Regular(0)/m/it/10.95 The valid values for \EU1/LuxiMono(0)/bx/n/8.2125 max_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 depend on the static \EU1/LuxiMono(0)/bx/n/8.2125 max_group_size + [] + +[64] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[65] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[66] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[67] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6276. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6276. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6316. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1331) in paragraph at lines 6319--6326 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 A direct counter is a direct resource associated with a \EU1/LuxiMono(0)/bx/n/8.2125 TableEntry \EU1/UtopiaStd-Regular(0)/m/it/10.95 (see [][]Direct Resources[][]). The + [] + +[68] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6393. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6393. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6393. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6393. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6393. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6393. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6393. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6393. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6393. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6393. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6393. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6393. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6393. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[69] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6486. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6486. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6517. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6517. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6517. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6517. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6517. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6517. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6517. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6517. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6517. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6517. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6517. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6517. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6517. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[70] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6594. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6594. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6594. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6594. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6594. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6594. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6594. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6594. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6594. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6594. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6594. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6594. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6594. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 6635. + + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 6635. + +[71] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6690. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6690. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6690. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6690. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6690. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6690. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6690. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6690. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6690. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6690. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6690. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6690. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6690. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6700. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6700. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6700. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6700. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6700. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6700. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6700. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6700. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6700. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6700. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6700. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6700. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6700. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[72] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[73] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6824. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6824. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[74] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.93839pt too wide) in paragraph at lines 6935--6937 +[]\EU1/LuxiMono(0)/bx/n/8.2125 MODIFY\EU1/UtopiaStd-Regular(0)/m/it/10.95 : Modify the attributes of a given clone session entry, indexed by the given \EU1/LuxiMono(0)/bx/n/8.2125 clone_session_id\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[75] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6973. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6973. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6973. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6973. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6973. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6973. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6973. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6973. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6973. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6973. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6973. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6973. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6973. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[76] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7109. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7109. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7109. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7109. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7109. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7109. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7109. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7109. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7109. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7109. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7109. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7109. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7109. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[77] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7153. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7153. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7153. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7153. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7153. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7153. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7153. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7153. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7153. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7153. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7153. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7153. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7153. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[78] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[79] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7351. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7351. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7351. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7351. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7351. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7351. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7351. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7351. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7351. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7351. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7351. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7351. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7351. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[80] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/error-report.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[81] +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <14.4> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 7475. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7475. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7475. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: Hyper reference `wildcard-reads' on page 82 undefined on input line 7497. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[82] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7577. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7577. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7577. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7577. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7577. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7577. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7577. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7577. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7577. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7577. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7577. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7577. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7577. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[83] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[84] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[85] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (34.34796pt too wide) in paragraph at lines 7861--7866 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If an error is encountered before even trying to attempt individual batch updates, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.66206pt too wide) in paragraph at lines 7870--7881 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 Otherwise, if one or more updates in the batch (\EU1/LuxiMono(0)/bx/n/8.2125 WriteRequest.updates\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) failed, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[86] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7917. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[87] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[88] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.4752pt too wide) in paragraph at lines 8146--8150 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 responding to \EU1/LuxiMono(0)/bx/n/8.2125 a \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 c\EU1/UtopiaStd-Regular(0)/m/it/10.95 , followed by a status \EU1/LuxiMono(0)/bx/n/8.2125 {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[89] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8232. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8232. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8232. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8232. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8232. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8232. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8232. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8232. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8232. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8232. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8232. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8232. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8232. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[90] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8355. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8355. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8355. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8355. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8355. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8355. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8355. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8355. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8355. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8355. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8355. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8355. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8355. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[91] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 8453--8456 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If a P4Runtime server supports both \EU1/LuxiMono(0)/bx/n/8.2125 SetForwardingPipelineConfig \EU1/UtopiaStd-Regular(0)/m/it/10.95 as well as returning the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[92] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[93] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[94] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[95] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[96] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8822. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8822. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8822. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8822. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8822. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8822. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8822. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8822. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8822. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8822. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8822. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8822. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8822. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[97] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8890. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8890. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8890. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8890. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8890. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8890. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8890. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8890. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8890. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8890. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8890. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8890. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8890. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[98] +File: build/psa-metadata-translation.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[99] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[100] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[101] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[102] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[103] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[104] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 9400--9407 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 p4info-ext should include a Protobuf message definition for every extern type that can + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 4036) in paragraph at lines 9455--9462 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 P4Runtime also supports streaming arbitrary Protobuf messages between the server and the + [] + + +Underfull \hbox (badness 1629) in paragraph at lines 9455--9462 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 client, by including an \EU1/LuxiMono(0)/bx/n/8.2125 Any \EU1/UtopiaStd-Regular(0)/m/it/10.95 Protobuf field [[][]31[][]] named \EU1/LuxiMono(0)/bx/n/8.2125 other \EU1/UtopiaStd-Regular(0)/m/it/10.95 in both \EU1/LuxiMono(0)/bx/n/8.2125 p4.v1.StreamMessageRequest + [] + +[105] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[106] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[107] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1997) in paragraph at lines 9716--9718 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 Table [][]7[][] lists P4$[]$ annotations introduced primarily for the purpose of adding features for the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[108] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[109] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.61781pt too wide) in paragraph at lines 9863--9870 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 In gRPC, the status of a RPC request is sent as metadata, whose size is limited by the \EU1/LuxiMono(0)/bx/n/8.2125 grpc.max_metadata_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[110] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 10000) in paragraph at lines 9954--9955 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Complex Types in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- p4- + [] + + +Underfull \hbox (badness 4001) in paragraph at lines 9966--9967 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Google Cloud APIs Versioning - Backwards-Compatibility.” [][]\EU1/lmtt/m/n/10.95 https:// cloud. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9975--9976 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “gRPC Streaming RPCs in C++.” [][]\EU1/lmtt/m/n/10.95 https:// grpc. io/ docs/ tutorials/ basic/ c. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9987--9988 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “P4 Concurrency Model.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 9990--9991 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” + [] + +[111] +Underfull \hbox (badness 10000) in paragraph at lines 10005--10006 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Protobuf OneOf Backwards-Compatibility Issues.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10011--10012 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Action Selector.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# sec- action- + [] + + +Underfull \hbox (badness 2409) in paragraph at lines 10020--10021 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Empty Group Action Appendix.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10023--10024 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Select Expressions in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 1668) in paragraph at lines 10038--10039 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Any Protobuf Message.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ protocol- buffers/ docs/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10044--10045 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC C++ Error Details Library.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ grpc/ grpc/ blob/ master/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10047--10048 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC Canonical Status Codes.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ maps- booking/ + [] + +[112] +Underfull \hbox (badness 10000) in paragraph at lines 10053--10054 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Protobuf MessageDifferencer in the C++ API.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10059--10060 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “v1model Architecture Definition.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ p4lang/ p4c/ blob/ master/ + [] + +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 10068. +[113] +Package atveryend Info: Empty hook `AfterLastShipout' on input line 10068. +(build/P4Runtime-Spec.aux) +Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 10068. +Package atveryend Info: Empty hook `AtEndAfterFileList' on input line 10068. + +LaTeX Font Warning: Some font shapes were not available, defaults substituted. + + +LaTeX Warning: There were undefined references. + + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 27551 strings out of 493638 + 517911 string characters out of 6146796 + 565952 words of memory out of 5000000 + 30653 multiletter control sequences out of 15000+600000 + 14633 words of font info for 98 fonts, out of 8000000 for 9000 + 1328 hyphenation exceptions out of 8191 + 48i,19n,81p,10429b,902s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on build/P4Runtime-Spec.pdf (113 pages). diff --git a/spec/v1.3.0/P4Runtime-Spec.pdf b/spec/v1.3.0/P4Runtime-Spec.pdf new file mode 100644 index 00000000..da8ac46a Binary files /dev/null and b/spec/v1.3.0/P4Runtime-Spec.pdf differ diff --git a/spec/v1.3.0/P4Runtime-Spec.tex b/spec/v1.3.0/P4Runtime-Spec.tex new file mode 100644 index 00000000..c3fbe450 --- /dev/null +++ b/spec/v1.3.0/P4Runtime-Spec.tex @@ -0,0 +1,10068 @@ +\documentclass[11pt]{article} +% generated by Madoko, version 1.1.4 +%mdk-data-line={1} + + +\usepackage[heading-base={2},section-num={False},bib-label={hide},fontspec={True}]{madoko2} +\usepackage[top=1in, bottom=1.25in, left=1in, right=1in]{geometry} +\usepackage{fancyhdr} +%mdk-data-line={11} + + \setlength{\headheight}{30pt} + \setlength{\emergencystretch}{2em} + +\begin{document} + + + +{\mdfontfamily{UtopiaStd-Regular} +%mdk-data-line={203} +\mdxtitleblockstart{} +%mdk-data-line={203} +\mdxtitle{{\sffamily{\bfseries\mdline{203}P4Runtime Specification}}}%mdk + +%mdk-data-line={206} +\mdxtitlenote{{\sffamily{\bfseries\mdline{206}version 1.3.0}}}%mdk +\mdxauthorstart{} +%mdk-data-line={211} +\mdxauthorname{\mdline{211}The P4.org API Working Group}%mdk +\mdxauthorend +%mdk-data-line={220} +\mdxtitlefooter{{\sffamily{\bfseries\mdline{220}2020-12-01}}}%mdk +\mdtitleauthorrunning{}{}\mdxtitleblockend%mdk + +%mdk-data-line={205} +\begin{abstract}%mdk + +%mdk-data-line={206} +\noindent\mdline{206}P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.%mdk +%mdk +\end{abstract}%mdk +\mdline{214} +\begin{mdtoc}%mdk + +\section*{Contents}\label{sec-contents}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-introduction-and-scope}{\mdref{sec-introduction-and-scope}{1.\hspace*{0.5em}Introduction and Scope}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-language-version-applicability}{\mdref{sec-p4-language-version-applicability}{1.1.\hspace*{0.5em}P4 Language Version Applicability}}%mdk + +\mdtocitemx{sec-in-scope}{\mdref{sec-in-scope}{1.2.\hspace*{0.5em}In Scope}}%mdk + +\mdtocitemx{sec-not-in-scope}{\mdref{sec-not-in-scope}{1.3.\hspace*{0.5em}Not In Scope}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-terms-and-definitions}{\mdref{sec-terms-and-definitions}{2.\hspace*{0.5em}Terms and Definitions}}%mdk + +\mdtocitemx{sec-reference-architecture}{\mdref{sec-reference-architecture}{3.\hspace*{0.5em}Reference Architecture}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-service-implementation}{\mdref{sec-p4runtime-service-implementation}{3.1.\hspace*{0.5em}P4Runtime Service Implementation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-security-concerns}{\mdref{sec-security-concerns}{3.1.1.\hspace*{0.5em}Security concerns}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-idealized-workflow}{\mdref{sec-idealized-workflow}{3.2.\hspace*{0.5em}Idealized Workflow}}%mdk + +\mdtocitemx{sec-p4-as-behavioral-description-language}{\mdref{sec-p4-as-behavioral-description-language}{3.3.\hspace*{0.5em}P4 as a Behavioral Description Language}}%mdk + +\mdtocitemx{sec-alternative-workflows}{\mdref{sec-alternative-workflows}{3.4.\hspace*{0.5em}Alternative Workflows}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{\mdref{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{3.4.1.\hspace*{0.5em}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}}%mdk + +\mdtocitemx{sec-no-p4-source-available-p4info-available}{\mdref{sec-no-p4-source-available-p4info-available}{3.4.2.\hspace*{0.5em}No P4 Source Available, P4Info Available}}%mdk + +\mdtocitemx{sec-partial-p4info-and-p4-source-are-available}{\mdref{sec-partial-p4info-and-p4-source-are-available}{3.4.3.\hspace*{0.5em}Partial P4Info and P4 Source are Available}}%mdk + +\mdtocitemx{sec-p4info-role-based-subsets}{\mdref{sec-p4info-role-based-subsets}{3.4.4.\hspace*{0.5em}P4Info Role-Based Subsets}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-restarts}{\mdref{sec-restarts}{3.5.\hspace*{0.5em}P4Runtime State Across Restarts}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-controller-use-cases}{\mdref{sec-controller-use-cases}{4.\hspace*{0.5em}Controller Use-cases}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-single-embedded-controller}{\mdref{sec-single-embedded-controller}{4.1.\hspace*{0.5em}Single Embedded Controller}}%mdk + +\mdtocitemx{sec-single-remote-controller}{\mdref{sec-single-remote-controller}{4.2.\hspace*{0.5em}Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-single-remote-controller}{\mdref{sec-embedded-single-remote-controller}{4.3.\hspace*{0.5em}Embedded + Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-two-remote-controllers}{\mdref{sec-embedded-two-remote-controllers}{4.4.\hspace*{0.5em}Embedded + Two Remote Controllers}}%mdk + +\mdtocitemx{sec-embedded-controller-two-high-availability-remote-controllers}{\mdref{sec-embedded-controller-two-high-availability-remote-controllers}{4.5.\hspace*{0.5em}Embedded Controller + Two High-Availability Remote Controllers}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-client-arbitration-and-controller-replication}{\mdref{sec-client-arbitration-and-controller-replication}{5.\hspace*{0.5em}Client Arbitration and Controller Replication}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-default-role}{\mdref{sec-default-role}{5.1.\hspace*{0.5em}Default Role}}%mdk + +\mdtocitemx{sec-arbitration-role-config}{\mdref{sec-arbitration-role-config}{5.2.\hspace*{0.5em}Role Config}}%mdk + +\mdtocitemx{sec-arbitration-updates}{\mdref{sec-arbitration-updates}{5.3.\hspace*{0.5em}Rules for Handling \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}} Messages Received from Controllers}}%mdk + +\mdtocitemx{sec-arbitration-notification}{\mdref{sec-arbitration-notification}{5.4.\hspace*{0.5em}Client Arbitration Notifications}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-the-p4info-message}{\mdref{sec-the-p4info-message}{6.\hspace*{0.5em}The P4Info Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-common-messages}{\mdref{sec-common-messages}{6.1.\hspace*{0.5em}Common Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-documentation-message}{\mdref{sec-documentation-message}{6.1.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}} Message}}%mdk + +\mdtocitemx{sec-preamble-message}{\mdref{sec-preamble-message}{6.1.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}} Message}}%mdk + +\mdtocitemx{sec-annotating-p4-entities-with-documentation}{\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3.\hspace*{0.5em}Annotating P4 Entities with \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}}%mdk + +\mdtocitemx{sec-structured-annotations}{\mdref{sec-structured-annotations}{6.1.4.\hspace*{0.5em}Structured Annotations}}%mdk + +\mdtocitemx{sec-sourcelocation-message}{\mdref{sec-sourcelocation-message}{6.1.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}} Message}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-pkginfo-message}{\mdref{sec-pkginfo-message}{6.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}} Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-annotating-p4-code-with-pkginfo}{\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1.\hspace*{0.5em}Annotating P4 code with PkgInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-id-allocation}{\mdref{sec-id-allocation}{6.3.\hspace*{0.5em}ID Allocation for P4Info Objects}}%mdk + +\mdtocitemx{sec-p4info-objects}{\mdref{sec-p4info-objects}{6.4.\hspace*{0.5em}P4Info Objects}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table}{\mdref{sec-table}{6.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}}%mdk + +\mdtocitemx{sec-action}{\mdref{sec-action}{6.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}}%mdk + +\mdtocitemx{sec-p4info-action-profile}{\mdref{sec-p4info-action-profile}{6.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}}%mdk + +\mdtocitemx{sec-counter-directcounter}{\mdref{sec-counter-directcounter}{6.4.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}}%mdk + +\mdtocitemx{sec-meter-directmeter}{\mdref{sec-meter-directmeter}{6.4.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}}%mdk + +\mdtocitemx{sec-controller-packet-meta}{\mdref{sec-controller-packet-meta}{6.4.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}}%mdk + +\mdtocitemx{sec-valueset}{\mdref{sec-valueset}{6.4.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}}%mdk + +\mdtocitemx{sec-register}{\mdref{sec-register}{6.4.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}}%mdk + +\mdtocitemx{sec-digest}{\mdref{sec-digest}{6.4.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}}%mdk + +\mdtocitemx{sec-p4info-extern}{\mdref{sec-p4info-extern}{6.4.10.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{\mdref{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{6.5.\hspace*{0.5em}Support for Arbitrary P4 Types with P4TypeInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-fwd-pipe-config}{\mdref{sec-p4-fwd-pipe-config}{7.\hspace*{0.5em}P4 Forwarding-Pipeline Configuration}}%mdk + +\mdtocitemx{sec-general-principles-for-message-formatting}{\mdref{sec-general-principles-for-message-formatting}{8.\hspace*{0.5em}General Principles for Message Formatting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-set-unset-protobuf-field}{\mdref{sec-set-unset-protobuf-field}{8.1.\hspace*{0.5em}Set / Unset Protobuf Field}}%mdk + +\mdtocitemx{sec-read-write-symmetry}{\mdref{sec-read-write-symmetry}{8.2.\hspace*{0.5em}Read-Write Symmetry}}%mdk + +\mdtocitemx{sec-zero-as-reserved-value}{\mdref{sec-zero-as-reserved-value}{8.3.\hspace*{0.5em}Zero as Reserved Value}}%mdk + +\mdtocitemx{sec-bytestrings}{\mdref{sec-bytestrings}{8.4.\hspace*{0.5em}Bytestrings}}%mdk + +\mdtocitemx{sec-representation-of-arbitrary-p4-types}{\mdref{sec-representation-of-arbitrary-p4-types}{8.5.\hspace*{0.5em}Representation of Arbitrary P4 Types}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-problem-statement}{\mdref{sec-problem-statement}{8.5.1.\hspace*{0.5em}Problem Statement}}%mdk + +\mdtocitemx{sec-p4-type-specifications-in-p4infoproto}{\mdref{sec-p4-type-specifications-in-p4infoproto}{8.5.2.\hspace*{0.5em}P4 Type Specifications in p4info.proto}}%mdk + +\mdtocitemx{sec-p4data-in-p4runtime-proto}{\mdref{sec-p4data-in-p4runtime-proto}{8.5.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}} in p4runtime.proto}}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{8.5.4.\hspace*{0.5em}Example}}%mdk + +\mdtocitemx{sec-enum-serializable-enum-and-error}{\mdref{sec-enum-serializable-enum-and-error}{8.5.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}, serializable \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}}%mdk + +\mdtocitemx{sec-user-defined-types}{\mdref{sec-user-defined-types}{8.5.6.\hspace*{0.5em}User-defined types}}%mdk + +\mdtocitemx{sec-trade-off-for-v1x-releases}{\mdref{sec-trade-off-for-v1x-releases}{8.5.7.\hspace*{0.5em}Trade-off for v1.x Releases}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-entity-msgs}{\mdref{sec-p4-entity-msgs}{9.\hspace*{0.5em}P4 Entity Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table-entry}{\mdref{sec-table-entry}{9.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-match-format}{\mdref{sec-match-format}{9.1.1.\hspace*{0.5em}Match Format}}%mdk + +\mdtocitemx{sec-action-specification}{\mdref{sec-action-specification}{9.1.2.\hspace*{0.5em}Action Specification}}%mdk + +\mdtocitemx{sec-default-entry}{\mdref{sec-default-entry}{9.1.3.\hspace*{0.5em}Default Entry}}%mdk + +\mdtocitemx{sec-constant-tables}{\mdref{sec-constant-tables}{9.1.4.\hspace*{0.5em}Constant Tables}}%mdk + +\mdtocitemx{sec-table-wildcard-reads}{\mdref{sec-table-wildcard-reads}{9.1.5.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-direct-resources}{\mdref{sec-direct-resources}{9.1.6.\hspace*{0.5em}Direct Resources}}%mdk + +\mdtocitemx{sec-idle-timeout}{\mdref{sec-idle-timeout}{9.1.7.\hspace*{0.5em}Idle-timeout}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-and-group}{\mdref{sec-action-profile-member-and-group}{9.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-programming}{\mdref{sec-action-profile-member-programming}{9.2.1.\hspace*{0.5em}Action Profile Member Programming}}%mdk + +\mdtocitemx{sec-action-profile-group-programming}{\mdref{sec-action-profile-group-programming}{9.2.2.\hspace*{0.5em}Action Profile Group Programming}}%mdk + +\mdtocitemx{sec-oneshot}{\mdref{sec-oneshot}{9.2.3.\hspace*{0.5em}One Shot Action Selector Programming}}%mdk + +\mdtocitemx{action-selector-constraints}{\mdref{action-selector-constraints}{9.2.4.\hspace*{0.5em}Constraints on action selector programming}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-counterentry-directcounterentry}{\mdref{sec-counterentry-directcounterentry}{9.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directcounterentry}{\mdref{sec-directcounterentry}{9.3.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\mdtocitemx{sec-counterentry}{\mdref{sec-counterentry}{9.3.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-meterentry-directmeterentry}{\mdref{sec-meterentry-directmeterentry}{9.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directmeterentry}{\mdref{sec-directmeterentry}{9.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\mdtocitemx{sec-meterentry}{\mdref{sec-meterentry}{9.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-packetreplicationengineentry}{\mdref{sec-packetreplicationengineentry}{9.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-multicastgroupentry}{\mdref{sec-multicastgroupentry}{9.5.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}}%mdk + +\mdtocitemx{sec-clonesessionentry}{\mdref{sec-clonesessionentry}{9.5.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-valuesetentry}{\mdref{sec-valuesetentry}{9.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}}%mdk + +\mdtocitemx{sec-registerentry}{\mdref{sec-registerentry}{9.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}}%mdk + +\mdtocitemx{sec-digestentry}{\mdref{sec-digestentry}{9.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}}%mdk + +\mdtocitemx{sec-extern-entry}{\mdref{sec-extern-entry}{9.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-error-reporting-messages}{\mdref{sec-error-reporting-messages}{10.\hspace*{0.5em}Error Reporting Messages}}%mdk + +\mdtocitemx{sec-atomicity-of-individual-write-and-read-operations}{\mdref{sec-atomicity-of-individual-write-and-read-operations}{11.\hspace*{0.5em}Atomicity of Individual \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} Operations}}%mdk + +\mdtocitemx{sec-write-rpc}{\mdref{sec-write-rpc}{12.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-batching-and-ordering-of-updates}{\mdref{sec-batching-and-ordering-of-updates}{12.1.\hspace*{0.5em}Batching and Ordering of Updates}}%mdk + +\mdtocitemx{sec-batch-atomicity}{\mdref{sec-batch-atomicity}{12.2.\hspace*{0.5em}Batch Atomicity}}%mdk + +\mdtocitemx{sec-error-reporting}{\mdref{sec-error-reporting}{12.3.\hspace*{0.5em}Error Reporting}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-read-rpc}{\mdref{sec-read-rpc}{13.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-nomenclature}{\mdref{sec-nomenclature}{13.1.\hspace*{0.5em}Nomenclature}}%mdk + +\mdtocitemx{sec-wildcard-reads}{\mdref{sec-wildcard-reads}{13.2.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-batch-processing}{\mdref{sec-batch-processing}{13.3.\hspace*{0.5em}Batch Processing}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{13.3.1.\hspace*{0.5em}Example}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-parallelism-of-read-and-write-requests}{\mdref{sec-parallelism-of-read-and-write-requests}{13.4.\hspace*{0.5em}Parallelism of Read and Write Requests}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-setforwardingpipelineconfig-rpc}{\mdref{sec-setforwardingpipelineconfig-rpc}{14.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-getforwardingpipelineconfig-rpc}{\mdref{sec-getforwardingpipelineconfig-rpc}{15.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-p4runtime-stream-messages}{\mdref{sec-p4runtime-stream-messages}{16.\hspace*{0.5em}P4Runtime Stream Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-packet-i_o}{\mdref{sec-packet-i_o}{16.1.\hspace*{0.5em}Packet I/O}}%mdk + +\mdtocitemx{sec-client-arbitration-update}{\mdref{sec-client-arbitration-update}{16.2.\hspace*{0.5em}Client Arbitration Update}}%mdk + +\mdtocitemx{sec-digest-messages}{\mdref{sec-digest-messages}{16.3.\hspace*{0.5em}Digest Messages}}%mdk + +\mdtocitemx{sec-table-idle-timeout-notification}{\mdref{sec-table-idle-timeout-notification}{16.4.\hspace*{0.5em}Table Idle Timeout Notification}}%mdk + +\mdtocitemx{sec-architecture-specific-notifications}{\mdref{sec-architecture-specific-notifications}{16.5.\hspace*{0.5em}Architecture-Specific Notifications}}%mdk + +\mdtocitemx{sec-stream-error-reporting}{\mdref{sec-stream-error-reporting}{16.6.\hspace*{0.5em}Stream Error Reporting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-examples-of-streamerror-messages}{\mdref{sec-examples-of-streamerror-messages}{16.6.1.\hspace*{0.5em}Examples of \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}} Messages}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-capabilities-rpc}{\mdref{sec-capabilities-rpc}{17.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}} RPC}}%mdk + +\mdtocitemx{sec-portability-considerations}{\mdref{sec-portability-considerations}{18.\hspace*{0.5em}Portability Considerations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-psa-metadata-translation}{\mdref{sec-psa-metadata-translation}{18.1.\hspace*{0.5em}PSA Metadata Translation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-translation-of-port-numbers}{\mdref{sec-translation-of-port-numbers}{18.1.1.\hspace*{0.5em}Translation of Port Numbers}}%mdk + +\mdtocitemx{sec-translation-of-packet-io-header-fields}{\mdref{sec-translation-of-packet-io-header-fields}{18.1.2.\hspace*{0.5em}Translation of Packet-IO Header Fields}}%mdk + +\mdtocitemx{sec-translation-of-match-fields}{\mdref{sec-translation-of-match-fields}{18.1.3.\hspace*{0.5em}Translation of Match Fields}}%mdk + +\mdtocitemx{sec-translation-of-action-parameters}{\mdref{sec-translation-of-action-parameters}{18.1.4.\hspace*{0.5em}Translation of Action Parameters}}%mdk + +\mdtocitemx{sec-port-translation-for-psa-extern-apis}{\mdref{sec-port-translation-for-psa-extern-apis}{18.1.5.\hspace*{0.5em}Port Translation for PSA Extern APIs}}%mdk + +\mdtocitemx{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{\mdref{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{18.1.6.\hspace*{0.5em}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-versioning}{\mdref{sec-p4runtime-versioning}{19.\hspace*{0.5em}P4Runtime Versioning}}%mdk + +\mdtocitemx{sec-extending-p4runtime}{\mdref{sec-extending-p4runtime}{20.\hspace*{0.5em}Extending P4Runtime for non-PSA Architectures}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-p4runtime-for-architecture-specific-externs}{\mdref{sec-extending-p4runtime-for-architecture-specific-externs}{20.1.\hspace*{0.5em}Extending P4Runtime for Architecture-Specific Externs}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-the-p4info-message}{\mdref{sec-extending-the-p4info-message}{20.1.1.\hspace*{0.5em}Extending the P4Info message}}%mdk + +\mdtocitemx{sec-extending-the-p4runtime-service}{\mdref{sec-extending-the-p4runtime-service}{20.1.2.\hspace*{0.5em}Extending the P4Runtime Service}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-architecture-specific-table-extensions}{\mdref{sec-architecture-specific-table-extensions}{20.2.\hspace*{0.5em}Architecture-Specific Table Extensions}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-new-match-types}{\mdref{sec-new-match-types}{20.2.1.\hspace*{0.5em}New Match Types}}%mdk + +\mdtocitemx{sec-new-table-properties}{\mdref{sec-new-table-properties}{20.2.2.\hspace*{0.5em}New Table Properties}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-known-limitations-of-current-p4runtime-version}{\mdref{sec-known-limitations-of-current-p4runtime-version}{21.\hspace*{0.5em}Known Limitations of Current P4Runtime Version}}%mdk + +\mdtocitemx{sec-appendix}{\mdref{sec-appendix}{A.\hspace*{0.5em}Appendix}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-revision-history}{\mdref{sec-revision-history}{A.1.\hspace*{0.5em}Revision History}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-changes-in-v130}{\mdref{sec-changes-in-v130}{A.1.1.\hspace*{0.5em}Changes in v1.3.0}}%mdk + +\mdtocitemx{sec-changes-in-v120}{\mdref{sec-changes-in-v120}{A.1.2.\hspace*{0.5em}Changes in v1.2.0}}%mdk + +\mdtocitemx{sec-changes-in-v110}{\mdref{sec-changes-in-v110}{A.1.3.\hspace*{0.5em}Changes in v1.1.0}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-annotations}{\mdref{sec-p4-annotations}{A.2.\hspace*{0.5em}P4 Annotations}}%mdk + +\mdtocitemx{sec-value-set-example}{\mdref{sec-value-set-example}{A.3.\hspace*{0.5em}A More Complex Value Set Example}}%mdk + +\mdtocitemx{sec-guidelines-for-implementations}{\mdref{sec-guidelines-for-implementations}{A.4.\hspace*{0.5em}Guidelines for Implementations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-grpc-metadata-maximum-size}{\mdref{sec-grpc-metadata-maximum-size}{A.4.1.\hspace*{0.5em}gRPC Metadata Maximum Size}}%mdk + +\mdtocitemx{sec-grpc-server-maximum-receive-message-size}{\mdref{sec-grpc-server-maximum-receive-message-size}{A.4.2.\hspace*{0.5em}gRPC Server Maximum Receive Message Size}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-bibliography}{\mdref{sec-bibliography}{References}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{215} +\begin{mdtoc}%mdk + +\section*{Figures}\label{sec-figures}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{fig-reference-architecture}{\mdref{fig-reference-architecture}{\mdcaptionlabel{1}. P4Runtime Reference Architecture.}}%mdk + +\mdtocitemx{fig-single-embedded-controller}{\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}. Use-Case: Single Embedded Controller}}%mdk + +\mdtocitemx{fig-single-remote-controller}{\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}. Use-Case: Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-single-remote-controller}{\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}. Use-Case: Embedded Plus Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-controllers}{\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}. Use-Case: Embedded Plus Two Remote Controllers}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-ha-controllers}{\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}. Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk + +\mdtocitemx{fig-error-report}{\mdref{fig-error-report}{\mdcaptionlabel{7}. P4Runtime Error Report Message Format}}%mdk + +\mdtocitemx{fig-psa-metadata-translation}{\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}. P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{216} +\begin{mdtoc}%mdk + +\section*{Tables}\label{sec-tables}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{tab-mapping-p4-obj-ids}{\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}. Mapping of P4Info object type to 8-bit ID prefix value}}%mdk + +\mdtocitemx{tab-format-p4-obj-ids}{\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}. Format of P4Info object IDs}}%mdk + +\mdtocitemx{tab-exmpl-p4-obj-ids}{\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}. Example of statically-assigned P4Info object IDs}}%mdk + +\mdtocitemx{tab-valid-bytestring-encoding}{\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}. Examples of Valid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-invalid-bytestring-encoding}{\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}. Examples of Invalid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-p4-type-usage}{\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}. P4 Type Usage}}%mdk + +\mdtocitemx{tab-p4-annotations}{\mdref{tab-p4-annotations}{\mdcaptionlabel{7}. P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk + +%mdk-data-line={218} +\section{\mdline{218}1.\hspace*{0.5em}\mdline{218}Introduction and Scope}\label{sec-introduction-and-scope}%mdk%mdk + +%mdk-data-line={220} +\noindent\mdline{220}This document is published by the \mdline{220}\emph{P4.org API Working Group}\mdline{220}, which was +chartered\mdline{221}~[\mdcite{p4apiwgcharter}{17}]\mdline{221} to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called \mdline{223}\emph{P4Runtime}\mdline{223}. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +\mdline{226}\href{https://github.com/p4lang/p4runtime/tree/v1.3.0/proto}{https://github.com/p4lang/p4runtime/tree/v1.3.0/proto}\mdline{226}.%mdk + +%mdk-data-line={228} +\subsection{\mdline{228}1.1.\hspace*{0.5em}\mdline{228}P4 Language Version Applicability}\label{sec-p4-language-version-applicability}%mdk%mdk + +%mdk-data-line={230} +\noindent\mdline{230}P4Runtime is designed to be implemented in conjunction with the P4\mdline{230}\mdsub{16}\mdline{230} language +version or later. P4\mdline{231}\mdsub{14}\mdline{231} programs should be translated into P4\mdline{231}\mdsub{16}\mdline{231} to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P4\mdline{233}\mdsub{16}\mdline{233} 1.0, but were introduced in P4\mdline{233}\mdsub{16}\mdline{233} 1.1.0\mdline{233}~[\mdcite{p4revisions110}{29}]\mdline{233}. For +this version of P4Runtime, we recommend using P4\mdline{234}\mdsub{16}\mdline{234} 1.2.1\mdline{234}~[\mdcite{p4spec}{1}]\mdline{234}.%mdk + +%mdk-data-line={236} +\subsection{\mdline{236}1.2.\hspace*{0.5em}\mdline{236}In Scope}\label{sec-in-scope}%mdk%mdk + +%mdk-data-line={238} +\noindent\mdline{238}This specification document defines the \mdline{238}\emph{semantics}\mdline{238} of \mdline{238}\emph{P4Runtime}\mdline{238} messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime:%mdk + +%mdk-data-line={242} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={242} +\item\mdline{242}Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA)\mdline{243}~[\mdcite{psa}{19}]\mdline{243} externs (\mdline{243}e.g.\mdline{243} Counters, Meters, Action +Profiles, \mdline{244}\dots{}\mdline{244}). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0.%mdk + +%mdk-data-line={246} +\item\mdline{246}Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism.%mdk + +%mdk-data-line={248} +\item\mdline{248}Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy.%mdk + +%mdk-data-line={251} +\item\mdline{251}Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities.%mdk + +%mdk-data-line={253} +\item\mdline{253}Packet I/O to enable streaming packets to \mdline{253}\&\mdline{253} from the control plane.%mdk + +%mdk-data-line={254} +\item\mdline{254}Batching support, with different atomicity guarantees.%mdk + +%mdk-data-line={255} +\item\mdline{255}In-the-field device-reconfiguration with a new P4 data plane.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={257} +\noindent\mdline{257}The following are in the scope of this specification document:%mdk + +%mdk-data-line={259} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={259} +\item\mdline{259}Rationale for the P4Runtime design.%mdk + +%mdk-data-line={260} +\item\mdline{260}Reference architecture and use-cases for deploying a P4Runtime service.%mdk + +%mdk-data-line={261} +\item\mdline{261}Detailed description of the API semantics.%mdk + +%mdk-data-line={262} +\item\mdline{262}Requirements for conformant implementations of the API.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={264} +\subsection{\mdline{264}1.3.\hspace*{0.5em}\mdline{264}Not In Scope}\label{sec-not-in-scope}%mdk%mdk + +%mdk-data-line={266} +\noindent\mdline{266}The following are not in scope of P4Runtime:%mdk + +%mdk-data-line={268} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={268} +\item\mdline{268}Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +\mdline{273}[\mdcite{openconfig}{35}]\mdline{273}. An open source implementation of these APIs is also in progress +as part of the Stratum project\mdline{274}~[\mdcite{stratum}{37}]\mdline{274}.%mdk + +%mdk-data-line={275} +\item\mdline{275}Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={280} +\noindent\mdline{280}The following are not in scope of this specification document:%mdk + +%mdk-data-line={282} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={282} +\item\mdline{282}Description of the P4 programming language; it is assumed that the reader is +already familiar with P4\mdline{283}\mdsub{16}\mdline{283}~[\mdcite{p4spec}{1}]\mdline{283}.%mdk + +%mdk-data-line={284} +\item\mdline{284}Descriptions of gRPC and Protobuf files in general.%mdk + +%mdk-data-line={285} +\item\mdline{285}Controller\mdline{285}~\mdref{sec-arbitration-role-config}{role}\mdline{285} definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={289} +\section{\mdline{289}2.\hspace*{0.5em}\mdline{289}Terms and Definitions}\label{sec-terms-and-definitions}%mdk%mdk + +%mdk-data-line={291} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries arbitration}}%mdk + +%mdk-data-line={291} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{291}Refers to the process through which P4Runtime ensures that at any given +time, there is a single primary controller (\mdline{292}i.e.\mdline{292} a client with write access) +for a given role. Also referred to as \mdline{293}\textquotedblleft{}client arbitration\textquotedblright{}\mdline{293}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries client}}%mdk + +%mdk-data-line={295} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{295}The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries COS}}%mdk + +%mdk-data-line={299} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{299}Class of Service. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries device}}%mdk + +%mdk-data-line={301} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{301}Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries entity}}%mdk + +%mdk-data-line={305} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{305}An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries gRPC}}%mdk + +%mdk-data-line={308} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{308}gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +\mdline{309}[\mdcite{grpc}{9}]\mdline{309}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries HA}}%mdk + +%mdk-data-line={311} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{311}High-Availability. Refers to a redundancy architecture. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Instrumentation}}%mdk + +%mdk-data-line={313} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{313}The part of the P4Runtime server which implements the calls to the device or +target native \mdline{314}\textquotedblleft{}SDK\textquotedblright{}\mdline{314} or backend. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries IPC}}%mdk + +%mdk-data-line={316} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{316}Inter-Process Communication. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Blob}}%mdk + +%mdk-data-line={318} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{318}A more colloquial term for P4 Device Config (Blob = Binary Large Object). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Device Config}}%mdk + +%mdk-data-line={320} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{320}The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its \mdline{322}\textquotedblleft{}program.\textquotedblright{}\mdline{322} +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4Info}}%mdk + +%mdk-data-line={324} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{324}Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4RT}}%mdk + +%mdk-data-line={328} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{328}Abbreviation for P4Runtime. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Protobuf (Protocol Buffers)}}%mdk + +%mdk-data-line={330} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{330}The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See\mdline{331}~[\mdcite{proto}{21}]\mdline{331}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries PSA}}%mdk + +%mdk-data-line={333} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{333}Portable Switch Architecture\mdline{333}~[\mdcite{psa}{19}]\mdline{333}; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RPC}}%mdk + +%mdk-data-line={337} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{337}Remote Procedure Call. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RTT}}%mdk + +%mdk-data-line={339} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{339}Round-trip time. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN}}%mdk + +%mdk-data-line={341} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{341}Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network \mdline{346}\emph{controller}\mdline{346}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN port}}%mdk + +%mdk-data-line={348} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{348}A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries server}}%mdk + +%mdk-data-line={352} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{352}The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries stream}}%mdk + +%mdk-data-line={356} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{356}Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (\mdline{357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{357}), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and client arbitration, among other things. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries switch config}}%mdk + +%mdk-data-line={361} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{361}Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries target}}%mdk + +%mdk-data-line={366} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{366}The hardware or software entity which \mdline{366}\textquotedblleft{}executes\textquotedblright{}\mdline{366} the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with \mdline{367}\textquotedblleft{}device\textquotedblright{}\mdline{367}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries URI}}%mdk + +%mdk-data-line={369} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{369}Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={373} +\section{\mdline{373}3.\hspace*{0.5em}\mdline{373}Reference Architecture}\label{sec-reference-architecture}%mdk%mdk + +%mdk-data-line={375} +\noindent\mdline{375}Figure\mdline{375}~\mdref{fig-reference-architecture}{\mdcaptionlabel{1}}\mdline{375} represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. P4Runtime only grants write access to a +single primary controller for each read/write entity. A role defines a grouping +of P4 entities. P4Runtime allows for a primary controller for each role, and a +role-based client arbitration scheme ensures only one controller has +write access to each read/write entity, or the pipeline config itself. Any +controller may perform read access to any entity or the pipeline config. Later +sections describe this in detail. For the sake of brevity, the term controller +may refer to one or more controllers.%mdk + +%mdk-data-line={386} +\mdline{386}The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +\mdline{389}[\mdcite{p4runtimerepo}{15}]\mdline{389}. It may be compiled via protoc\mdline{389} \mdline{389}\textemdash{}\mdline{389} the Protobuf compiler\mdline{389} \mdline{389}\textemdash{}\mdline{389} +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server.%mdk + +%mdk-data-line={394} +\mdline{394}Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository\mdline{395}~[\mdcite{pirepo}{16}]\mdline{395}. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, \mdline{397}e.g.\mdline{397} via callbacks, thus reducing the burden of implementing +P4Runtime.%mdk + +%mdk-data-line={400} +\mdline{400}The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard.%mdk + +%mdk-data-line={404} +\mdline{404}The controller can also set the \mdline{404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{404}, which amounts to +installing and running the compiled P4 program output, which is included in the +\mdline{406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{406} Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +\mdline{408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{408} to retrieve the device config and the P4Info.%mdk + +%mdk-data-line={411} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={412} +\noindent\mdline{412}\includegraphics[keepaspectratio=true,height=7cm]{build/reference-architecture}{}\mdline{412}%mdk + +%mdk-data-line={413} +\mdhr{}%mdk + +%mdk-data-line={414} +\noindent\mdline{414}\mdcaption{\textbf{Figure~\mdcaptionlabel{1}.}~\mdcaptiontext{P4Runtime Reference Architecture.}}%mdk +%mdk +\end{mdcenter}\label{fig-reference-architecture}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={418} +\subsection{\mdline{418}3.1.\hspace*{0.5em}\mdline{418}P4Runtime Service Implementation}\label{sec-p4runtime-service-implementation}%mdk%mdk + +%mdk-data-line={420} +\noindent\mdline{420}The P4Runtime API is implemented by a program that runs a gRPC server which +binds an implementation of auto-generated P4Runtime Service interface. This +program is called the \mdline{422}\textquotedblleft{}P4Runtime server.\textquotedblright{}\mdline{422} The server must listen on TCP port +9559 by default, which is the port that has been allocated by IANA for the +P4Runtime service. Servers should allow users to override the default port +using a configuration file or flag when starting the server. Uses of other +port numbers as the default should be discontinued.%mdk + +%mdk-data-line={428} +\subsubsection{\mdline{428}3.1.1.\hspace*{0.5em}\mdline{428}Security concerns}\label{sec-security-concerns}%mdk%mdk + +%mdk-data-line={430} +\noindent\mdline{430}Appropriate measures and security best practices must be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. Mutual TLS (mTLS) may +be used to facilitate the authentication of the client by the server and +vice-versa.%mdk + +%mdk-data-line={439} +\subsection{\mdline{439}3.2.\hspace*{0.5em}\mdline{439}Idealized Workflow}\label{sec-idealized-workflow}%mdk%mdk + +%mdk-data-line={441} +\noindent\mdline{441}In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the \mdline{442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{442} +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a \mdline{444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{444} +RPC. Metadata in the P4Info describes both the overall program itself +(\mdline{446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{446}) as well as all entity instances derived from the P4 program\mdline{446} \mdline{446}\textemdash{}\mdline{446} +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise \mdline{448}\textquotedblleft{}handle\textquotedblright{}\mdline{448} used in API +calls.%mdk + +%mdk-data-line={451} +\mdline{451}In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible.%mdk + +%mdk-data-line={457} +\mdline{457}In some use cases, it is expected that a controller will store a +collection of multiple P4 \mdline{458}\textquotedblleft{}packages\textquotedblright{}\mdline{458}, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the \mdline{460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{460} from the target via the +\mdline{461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineRequest}}}\mdline{461} RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state.%mdk + +%mdk-data-line={465} +\subsection{\mdline{465}3.3.\hspace*{0.5em}\mdline{465}P4 as a Behavioral Description Language}\label{sec-p4-as-behavioral-description-language}%mdk%mdk + +%mdk-data-line={467} +\noindent\mdline{467}P4 can be considered a behavioral description of a switching device which may or +may not execute \mdline{468}\textquotedblleft{}P4\textquotedblright{}\mdline{468} natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a \mdline{470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineRequest}}}\mdline{470} to +change its pipeline \mdline{471}\textquotedblleft{}program\textquotedblright{}\mdline{471}, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device.%mdk + +%mdk-data-line={477} +\mdline{477}While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API.%mdk + +%mdk-data-line={486} +\mdline{486}In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the \mdline{487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{487} +message as well as the embedded \mdline{488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{488} fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections.%mdk + +%mdk-data-line={492} +\subsection{\mdline{492}3.4.\hspace*{0.5em}\mdline{492}Alternative Workflows}\label{sec-alternative-workflows}%mdk%mdk + +%mdk-data-line={494} +\noindent\mdline{494}Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary.%mdk + +%mdk-data-line={498} +\subsubsection{\mdline{498}3.4.1.\hspace*{0.5em}\mdline{498}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}\label{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}%mdk%mdk + +%mdk-data-line={500} +\noindent\mdline{500}In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +\mdline{502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{502}. The device\mdline{502}'\mdline{502}s configuration might be derived via some other +means to implement the P4 source code\mdline{503}'\mdline{503}s intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane.%mdk + +%mdk-data-line={507} +\subsubsection{\mdline{507}3.4.2.\hspace*{0.5em}\mdline{507}No P4 Source Available, P4Info Available}\label{sec-no-p4-source-available-p4info-available}%mdk%mdk + +%mdk-data-line={509} +\noindent\mdline{509}In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are:%mdk + +%mdk-data-line={512} +\begin{enumerate}%mdk + +%mdk-data-line={512} +\item{} +%mdk-data-line={512} +\mdline{512}The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security.%mdk%mdk + +%mdk-data-line={515} +\item{} +%mdk-data-line={515} +\mdline{515}The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={518} +\noindent\mdline{518}As discussed in Section\mdline{518}~\mdref{sec-p4-as-behavioral-description-language}{3.3}\mdline{518}, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, \mdline{521}e.g.\mdline{521} documentation.%mdk + +%mdk-data-line={523} +\subsubsection{\mdline{523}3.4.3.\hspace*{0.5em}\mdline{523}Partial P4Info and P4 Source are Available}\label{sec-partial-p4info-and-p4-source-are-available}%mdk%mdk + +%mdk-data-line={525} +\noindent\mdline{525}In this situation, a subset of the target\mdline{525}'\mdline{525}s pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code.%mdk + +%mdk-data-line={532} +\subsubsection{\mdline{532}3.4.4.\hspace*{0.5em}\mdline{532}P4Info Role-Based Subsets}\label{sec-p4info-role-based-subsets}%mdk%mdk + +%mdk-data-line={534} +\noindent\mdline{534}In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more.%mdk + +%mdk-data-line={538} +\subsection{\mdline{538}3.5.\hspace*{0.5em}\mdline{538}P4Runtime State Across Restarts}\label{sec-restarts}%mdk%mdk + +%mdk-data-line={540} +\noindent\mdline{540}All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade.%mdk + +%mdk-data-line={546} +\section{\mdline{546}4.\hspace*{0.5em}\mdline{546}Controller Use-cases}\label{sec-controller-use-cases}%mdk%mdk + +%mdk-data-line={548} +\noindent\mdline{548}P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +\mdline{550}\mdref{sec-client-arbitration-and-controller-replication}{section}\mdline{550}. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime\mdline{552}'\mdline{552}s flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex.%mdk + +%mdk-data-line={555} +\subsection{\mdline{555}4.1.\hspace*{0.5em}\mdline{555}Single Embedded Controller}\label{sec-single-embedded-controller}%mdk%mdk + +%mdk-data-line={557} +\noindent\mdline{557}Figure\mdline{557}~\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}}\mdline{557} shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases.%mdk + +%mdk-data-line={562} +\mdline{562}P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC.%mdk + +%mdk-data-line={567} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={568} +\noindent\mdline{568}\includegraphics[keepaspectratio=true,height=6cm]{build/single-embedded-controller}{}\mdline{568}%mdk + +%mdk-data-line={569} +\mdhr{}%mdk + +%mdk-data-line={570} +\noindent\mdline{570}\mdcaption{\textbf{Figure~\mdcaptionlabel{2}.}~\mdcaptiontext{Use-Case: Single Embedded Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-embedded-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={574} +\subsection{\mdline{574}4.2.\hspace*{0.5em}\mdline{574}Single Remote Controller}\label{sec-single-remote-controller}%mdk%mdk + +%mdk-data-line={576} +\noindent\mdline{576}Figure\mdline{576}~\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}}\mdline{576} shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections.%mdk + +%mdk-data-line={581} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={582} +\noindent\mdline{582}\includegraphics[keepaspectratio=true,height=7cm]{build/single-remote-controller}{}\mdline{582}%mdk + +%mdk-data-line={583} +\mdhr{}%mdk + +%mdk-data-line={584} +\noindent\mdline{584}\mdcaption{\textbf{Figure~\mdcaptionlabel{3}.}~\mdcaptiontext{Use-Case: Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={588} +\subsection{\mdline{588}4.3.\hspace*{0.5em}\mdline{588}Embedded\mdline{588} \mdline{588}+ Single Remote Controller}\label{sec-embedded-single-remote-controller}%mdk%mdk + +%mdk-data-line={590} +\noindent\mdline{590}Figure\mdline{590}~\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}}\mdline{590} illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller.%mdk + +%mdk-data-line={597} +\mdline{597}For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables.%mdk + +%mdk-data-line={601} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={602} +\noindent\mdline{602}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-single-remote-controller}{}\mdline{602}%mdk + +%mdk-data-line={603} +\mdhr{}%mdk + +%mdk-data-line={604} +\noindent\mdline{604}\mdcaption{\textbf{Figure~\mdcaptionlabel{4}.}~\mdcaptiontext{Use-Case: Embedded Plus Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={609} +\subsection{\mdline{609}4.4.\hspace*{0.5em}\mdline{609}Embedded\mdline{609} \mdline{609}+ Two Remote Controllers}\label{sec-embedded-two-remote-controllers}%mdk%mdk + +%mdk-data-line={611} +\noindent\mdline{611}Figure\mdline{611}~\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}}\mdline{611} illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +\mdline{614}e.g.\mdline{614} routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership.%mdk + +%mdk-data-line={617} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={618} +\noindent\mdline{618}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-controllers}{}\mdline{618}%mdk + +%mdk-data-line={619} +\mdhr{}%mdk + +%mdk-data-line={620} +\noindent\mdline{620}\mdcaption{\textbf{Figure~\mdcaptionlabel{5}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={625} +\subsection{\mdline{625}4.5.\hspace*{0.5em}\mdline{625}Embedded Controller\mdline{625} \mdline{625}+ Two High-Availability Remote Controllers}\label{sec-embedded-controller-two-high-availability-remote-controllers}%mdk%mdk + +%mdk-data-line={627} +\noindent\mdline{627}Figure\mdline{627}~\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}}\mdline{627} illustrates a single +embedded controller plus two remote controllers in an active-standby (\mdline{628}i.e.\mdline{628} +primary-backup) HA (High-Availability) configuration. Controller \mdline{629}\#\mdline{629}1 is the +active controller and is in charge of some entities. If it fails, Controller \mdline{630}\#\mdline{630}2 +takes over and manages the tables formerly owned by Controller \mdline{631}\#\mdline{631}1. The mechanics +of HA architectures are beyond the scope of this document, but the P4Runtime +role-based client arbitration scheme supports it.%mdk + +%mdk-data-line={635} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={636} +\noindent\mdline{636}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-ha-controllers}{}\mdline{636}%mdk + +%mdk-data-line={637} +\mdhr{}%mdk + +%mdk-data-line={638} +\noindent\mdline{638}\mdcaption{\textbf{Figure~\mdcaptionlabel{6}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-ha-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={643} +\section{\mdline{643}5.\hspace*{0.5em}\mdline{643}Client Arbitration and Controller Replication}\label{sec-client-arbitration-and-controller-replication}%mdk%mdk + +%mdk-data-line={646} +\noindent\mdline{646}The P4Runtime interface allows multiple clients (\mdline{646}i.e.\mdline{646} controllers) to be +connected to the P4Runtime server running on the device at the same time for the +following reasons:%mdk + +%mdk-data-line={650} +\begin{enumerate}%mdk + +%mdk-data-line={650} +\item{} +%mdk-data-line={650} +\mdline{650}Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, \mdline{651}\textquotedblleft{}roles\textquotedblright{}\mdline{651} (or \mdline{651}\textquotedblleft{}realms\textquotedblright{}\mdline{651}) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +primary and the rest are backups. Role definition, \mdline{654}i.e.\mdline{654} how P4 entities get +assigned to each role, is \mdline{655}\textbf{out-of-scope}\mdline{655} of this document.%mdk%mdk + +%mdk-data-line={657} +\item{} +%mdk-data-line={657} +\mdline{657}Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby backup controllers. These can already have a connection +open, which can help them become primary more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={663} +\noindent\mdline{663}To support multiple controllers, P4Runtime uses the streaming channel (available +via \mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{664} RPC) for session management. The workflow is described as +follows:%mdk + +%mdk-data-line={667} +\begin{itemize}%mdk + +%mdk-data-line={667} +\item{} +%mdk-data-line={667} +\mdline{667}Each controller instance (\mdline{667}e.g.\mdline{667} a controller process) can participate in one or +more roles. For each (\mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{668}, \mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{668}), the controller receives an +\mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{669}. This \mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{669} can be the same for different roles and/or +devices, as long as the tuple (\mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{670}, \mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{670}, \mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{670}) is +unique. For each (\mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{671}, \mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{671}) that the controller wishes to +control, it establishes a \mdline{672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{672} with the P4Runtime server +responsible for that device, and sends a \mdline{673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{673} message +containing that tuple of (\mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{674}, \mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{674}, \mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{674}) values. The +P4Runtime server selects a primary independently for each (\mdline{675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{675}, +\mdline{676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{676}) pair. The primary is the client that has the highest \mdline{676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{676} +that the device has ever received for the same (\mdline{677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{677}, +\mdline{678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{678}) values. A connection between a controller instance and a device id +\mdline{679}\textemdash{}\mdline{679} which involves a persistent \mdline{679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{679} \mdline{679}\textemdash{}\mdline{679} can be referred to as a +P4Runtime client.%mdk + +%mdk-data-line={682} +\mdline{682}Note that the P4Runtime server does not assign a \mdline{682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{682} or \mdline{682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{682} to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the \mdline{684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{684} values used for each +\mdline{685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{685}. The P4Runtime server only keeps track of the (\mdline{685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{685}, +\mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{686}, \mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{686}) of each \mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{686} that has sent a successful +\mdline{687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{687} message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +\mdline{689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{689} message to identify which client is making the \mdline{689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{689}, +not only the \mdline{690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{690}. This enables controllers to re-use the same +numeric \mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{691} values across different (\mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{691}, \mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{691}) +pairs. P4Runtime does not require \mdline{692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{692} values be reused across such +different (\mdline{693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{693}, \mdline{693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{693}) pairs; it allows it.%mdk%mdk + +%mdk-data-line={695} +\item{} +%mdk-data-line={695} +\mdline{695}To start a controller session, a controller first opens a bidirectional stream +channel to the server via the \mdline{696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{696} RPC for each device. This stream +will be used for two purposes:%mdk + +%mdk-data-line={699} +\begin{itemize}%mdk + +%mdk-data-line={699} +\item{} +%mdk-data-line={699} +\mdline{699}\textbf{Session management:}\mdline{699} As soon as the controller opens the stream +channel, it sends a \mdline{700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{700} message to the switch. The +controller populates the \mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{701} field in this message +using its \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{702} and \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{702}, as well as the \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{702} of the +device. Note that the \mdline{703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{703} field in the \mdline{703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{703} is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below.%mdk%mdk + +%mdk-data-line={707} +\item{} +%mdk-data-line={707} +\mdline{707}\textbf{Streaming of notifications (e.g. digests) and packet I/O:}\mdline{707} The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the primary controller can participate in +packet I/O. This feature is explained in more details in the\mdline{711}~\mdref{sec-packet-i_o}{Packet +I/O}\mdline{712} section.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={714} +\mdline{714}Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state.%mdk%mdk + +%mdk-data-line={717} +\item{} +%mdk-data-line={717} +\mdline{717}Note that the stream is opened per device. In case a switching platform has +multiple devices (\mdline{718}e.g.\mdline{718} multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different primary clients for +different devices. In this case, it is the responsibility of the P4Runtime +server to keep track of the primary for each device (and role). More +specifically, the P4Runtime server will know which stream corresponds to the +primary controller for each pair of (\mdline{723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{723}, \mdline{723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{723}) at any point of +time.%mdk%mdk + +%mdk-data-line={726} +\item{} +%mdk-data-line={726} +\mdline{726}The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered \mdline{727}\textquotedblleft{}offline\textquotedblright{}\mdline{727} or +\mdline{728}\textquotedblleft{}dead\textquotedblright{}\mdline{728} as soon as its stream channel to the switch is broken. When a primary +channel gets broken: (i) an advisory message is sent to all other controllers +for that \mdline{730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{730} and \mdline{730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{730}, as described in the +\mdline{731}\mdref{sec-arbitration-notification}{following section}\mdline{731} (ii) the P4Runtime server +will be without a primary controller, until a client sends a successful +\mdline{733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{733} (as per the rules in a +\mdline{734}\mdref{sec-arbitration-updates}{later section}\mdline{734}).%mdk%mdk + +%mdk-data-line={736} +\item{} +%mdk-data-line={736} +\mdline{736}The mechanism via which the controller receives the P4Runtime server details +which includes the \mdline{737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{737}, \mdline{737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip}}}\mdline{737} and \mdline{737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{737}, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +\mdline{741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{741}) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={746} +\noindent\mdline{746}gRPC enables the server to identify which client originated each message in the +\mdline{747}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{747} stream. For example, the C++ gRPC library\mdline{747}~[\mdcite{grpcstreamc}{10}]\mdline{747} in +synchronous mode enables a server process to cause a function to be called when +a new client creates a \mdline{749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{749} stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +\mdline{751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{751} is closed normally (or broken, \mdline{751}e.g.\mdline{751} because a client process +unexpectedly terminated). Thus the server can easily associate all +\mdline{753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{753} messages received from the same client, because they are +processed within the context of the same function call.%mdk + +%mdk-data-line={756} +\mdline{756}A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values \mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{761}, \mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{761}, and \mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{761} in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods\mdline{763}~[\mdcite{grpcauth}{8}]\mdline{763} that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server.%mdk + +%mdk-data-line={767} +\subsection{\mdline{767}5.1.\hspace*{0.5em}\mdline{767}Default Role}\label{sec-default-role}%mdk%mdk + +%mdk-data-line={769} +\noindent\mdline{769}A controller can omit the role message in \mdline{769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{769}. This +implies the \mdline{770}\textquotedblleft{}default role\textquotedblright{}\mdline{770}, which corresponds to \mdline{770}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{770}. This +also implies that a default role has a \mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{771} of 0 (default). If using a +default role, all RPCs from the controller (\mdline{772}e.g.\mdline{772} \mdline{772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{772}) must set the \mdline{772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{772} +to 0.%mdk + +%mdk-data-line={775} +\subsection{\mdline{775}5.2.\hspace*{0.5em}\mdline{775}Role Config}\label{sec-arbitration-role-config}%mdk%mdk + +%mdk-data-line={777} +\noindent\mdline{777}The \mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{777} field in the \mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{777} message sent by the +controller describes the role configuration, \mdline{778}i.e.\mdline{778} which operations are in the +scope of a given role. In particular, the definition of a role may include the +following:%mdk + +%mdk-data-line={782} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={782} +\item\mdline{782}A list of P4 entities for which the controller may issue \mdline{782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{782} updates and +receive notification messages (\mdline{783}e.g.\mdline{783} \mdline{783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{783} and +\mdline{784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{784}).%mdk + +%mdk-data-line={785} +\item\mdline{785}Whether the controller is able to receive \mdline{785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{785} messages, along with a +filtering mechanism based on the values of the \mdline{786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{786} fields to +select which \mdline{787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{787} messages should be sent to the controller.%mdk + +%mdk-data-line={788} +\item\mdline{788}Whether the controller is able to send \mdline{788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{788} messages, along with a +filtering mechanism based on the values of the \mdline{789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{789} fields to +select which \mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{790} messages are allowed to be sent by the controller.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={792} +\noindent\mdline{792}An unset \mdline{792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{792} implies \mdline{792}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{792} (similar to the default +role explained above). In order to support different role definition schemes, +\mdline{794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{794} is defined as an \mdline{794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{794} Protobuf message\mdline{794}~[\mdcite{protoany}{31}]\mdline{794}. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion.%mdk + +%mdk-data-line={799} +\mdline{799}It is the job of the P4Runtime server to remember the \mdline{799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{799} for every +\mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{800} and \mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{800} pair.%mdk + +%mdk-data-line={802} +\subsection{\mdline{802}5.3.\hspace*{0.5em}\mdline{802}Rules for Handling \mdline{802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{802} Messages Received from Controllers}\label{sec-arbitration-updates}%mdk%mdk + +%mdk-data-line={804} +\begin{enumerate}%mdk + +%mdk-data-line={804} +\item{} +%mdk-data-line={804} +\mdline{804}If the \mdline{804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{804} message is received for the first time on +this particular channel (\mdline{805}i.e.\mdline{805} for a newly connected controller):%mdk + +%mdk-data-line={807} +\begin{enumerate}%mdk + +%mdk-data-line={807} +\item{} +%mdk-data-line={807} +\mdline{807}If \mdline{807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{807} does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +\mdline{809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{809} error.%mdk%mdk + +%mdk-data-line={811} +\item{} +%mdk-data-line={811} +\mdline{811}If the \mdline{811}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{811} is set and is already used by another controller for +the same (\mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{812}, \mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{812}), the P4Runtime server shall terminate +the stream by returning an \mdline{813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{813} error.%mdk%mdk + +%mdk-data-line={815} +\item{} +%mdk-data-line={815} +\mdline{815}If \mdline{815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{815} does not match the \mdline{815}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{815} scheme previously +agreed upon, the server must return an \mdline{816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{816} error.%mdk%mdk + +%mdk-data-line={818} +\item{} +%mdk-data-line={818} +\mdline{818}If the number of open streams for the given (\mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{818}, \mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{818}) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a \mdline{820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{820} error.%mdk%mdk + +%mdk-data-line={822} +\item{} +%mdk-data-line={822} +\mdline{822}Otherwise, the controller is added to a list of connected controllers for +the given (\mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{823}, \mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{823}) and the server remembers the +controllers \mdline{824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{824}, \mdline{824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{824} and \mdline{824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{824} for this gRPC +channel. See below for the rules to determine if this controller becomes +a primary or backup, and what notifications are sent as a consequence.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={828} +\item{} +%mdk-data-line={828} +\mdline{828}Otherwise, if the \mdline{828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{828} message is received from an +already connected controller:%mdk + +%mdk-data-line={831} +\begin{enumerate}%mdk + +%mdk-data-line={831} +\item{} +%mdk-data-line={831} +\mdline{831}If the \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{831} does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{833} error.%mdk%mdk + +%mdk-data-line={835} +\item{} +%mdk-data-line={835} +\mdline{835}If the \mdline{835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{835} does not match the current \mdline{835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{835} assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{837} error. If the controller wishes to change its role, +it must close the current stream channel and open a new one.%mdk%mdk + +%mdk-data-line={840} +\item{} +%mdk-data-line={840} +\mdline{840}If \mdline{840}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{840} does not match the \mdline{840}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{840} scheme previously +agreed upon, the server must return an \mdline{841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{841} error.%mdk%mdk + +%mdk-data-line={843} +\item{} +%mdk-data-line={843} +\mdline{843}If the \mdline{843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{843} is set and is already used by another controller +(excluding the controller making the request) for the same +(\mdline{845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{845}, \mdline{845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{845}), the P4Runtime server shall terminate the stream +by returning an \mdline{846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{846} error.%mdk%mdk + +%mdk-data-line={848} +\item{} +%mdk-data-line={848} +\mdline{848}If the \mdline{848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{848} matches the one assigned to this stream:%mdk + +%mdk-data-line={850} +\begin{enumerate}%mdk + +%mdk-data-line={850} +\item{} +%mdk-data-line={850} +\mdline{850}If the controller for this channel is the primary, then the server +updates the \mdline{851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{851} to the one specified in the +\mdline{852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{852}. An advisory client arbitration message is +sent to all controllers for this \mdline{853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{853} and \mdline{853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{853} informing +them of the new \mdline{854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{854}. Since the format of \mdline{854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{854} is +out of scope for the P4Runtime specification, the server will send +the advisory message for every update, even if the primary sets the +same \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{857} as it has before. See the\mdline{857}~\mdref{sec-arbitration-notification}{following +section}\mdline{858} for the format of the +advisory message.%mdk%mdk + +%mdk-data-line={861} +\item{} +%mdk-data-line={861} +\mdline{861}If the controller is a backup, this is a no-op and the \mdline{861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{861} +is ignored. No response is sent to any controller.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={864} +\item{} +%mdk-data-line={864} +\mdline{864}Otherwise, the server updates the \mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{864} it has stored for this +controller. This change might cause a change in the primary client (this +controller might become primary, or the controller might have downgraded +itself to a backup, see below), as well as notifications being sent to +one or more controllers.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={870} +\noindent\mdline{870}If the \mdline{870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{870} is accepted by either of the two steps above +(cases 1.5. and 2.6. above), then the server determines if there are changes in +the primary client. Let \mdline{872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{872} be the highest election ID the server +has ever seen for the given \mdline{873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{873} and \mdline{873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{873} (including the one of the +current primary if there is one).%mdk + +%mdk-data-line={876} +\begin{enumerate}%mdk + +%mdk-data-line={876} +\item{} +%mdk-data-line={876} +\mdline{876}If \mdline{876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{876} is greater than or equal to \mdline{876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{876}, then the +controller becomes primary. The server updates the role configuration to +\mdline{878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{878} for the given \mdline{878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{878}. Furthermore:%mdk + +%mdk-data-line={880} +\begin{enumerate}%mdk + +%mdk-data-line={880} +\item{} +%mdk-data-line={880} +\mdline{880}If there was no primary for this \mdline{880}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{880} and \mdline{880}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{880} before and +there are no \mdline{881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{881} requests still processing from a previous primary, +then the server immediately sends an advisory notification to all +controllers for this \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{883} and \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{883}. See the +\mdline{884}\mdref{sec-arbitration-notification}{following section}\mdline{884} for the format of the +advisory message.%mdk%mdk + +%mdk-data-line={887} +\item{} +%mdk-data-line={887} +\mdline{887}If there was a previous primary or \mdline{887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{887} requests in flight, then the +server carries out the following steps (in this order):%mdk + +%mdk-data-line={890} +\begin{enumerate}%mdk + +%mdk-data-line={890} +\item{} +%mdk-data-line={890} +\mdline{890}The server stops accepting \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{890} requests from the previous primary +(if there is one). At this point, the server will reject all \mdline{891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{891} +requests with \mdline{892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{892}.%mdk%mdk + +%mdk-data-line={894} +\item{} +%mdk-data-line={894} +\mdline{894}The server notifies all controllers other than the new primary client +of the change by sending the advisory notification described in +the\mdline{896}~\mdref{sec-arbitration-notification}{following section}\mdline{896}.%mdk%mdk + +%mdk-data-line={898} +\item{} +%mdk-data-line={898} +\mdline{898}The server will finish processing any \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{898} requests that have +already started. If there are errors, they are reported as usual to +the previous primary. If the previous primary has already +disconnected, any possible errors are dropped and not reported.%mdk%mdk + +%mdk-data-line={903} +\item{} +%mdk-data-line={903} +\mdline{903}The server now accepts the current controller as the new primary, +thus accepting \mdline{904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{904} requests from this controller. The server +updates the highest election ID (\mdline{905}i.e.\mdline{905} \mdline{905}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{905}) it has seen +for this \mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{906} and \mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{906} to \mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{906}.%mdk%mdk + +%mdk-data-line={908} +\item{} +%mdk-data-line={908} +\mdline{908}The server notifies the new primary by sending the advisory message +described in the\mdline{909}~\mdref{sec-arbitration-notification}{following section}\mdline{909}.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={911} +\item{} +%mdk-data-line={911} +\mdline{911}Otherwise, the controller becomes a backup. If the controller was previously +a primary (and downgraded itself), then an advisory message is sent to all +controllers for this \mdline{913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{913} and \mdline{913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{913}. Otherwise, the advisory +message is only sent to the controller that sent the initial +\mdline{915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{915}. See the +\mdline{916}\mdref{sec-arbitration-notification}{following section}\mdline{916} for the format of the +advisory message.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={919} +\subsection{\mdline{919}5.4.\hspace*{0.5em}\mdline{919}Client Arbitration Notifications}\label{sec-arbitration-notification}%mdk%mdk + +%mdk-data-line={921} +\noindent\mdline{921}For any given \mdline{921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{921} and \mdline{921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{921}, any time a new primary is chosen, a +primary downgrades its status to a backup, a primary disconnects, or the +\mdline{923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{923} is updated by the primary, all controllers for that +(\mdline{924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{924}, \mdline{924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{924}) are informed of this by sending a +\mdline{925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{925}. The \mdline{925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{925} is populated as follows:%mdk + +%mdk-data-line={927} +\begin{itemize}%mdk + +%mdk-data-line={927} +\item{} +%mdk-data-line={927} +\mdline{927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{927} and \mdline{927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.id}}}\mdline{927} as given.%mdk%mdk + +%mdk-data-line={929} +\item{} +%mdk-data-line={929} +\mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{929} is set to the role configuration the server received most +recently in a \mdline{930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{930} from a primary.%mdk%mdk + +%mdk-data-line={932} +\item{} +%mdk-data-line={932} +\mdline{932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{932} is populated as follows:%mdk + +%mdk-data-line={934} +\begin{itemize}%mdk + +%mdk-data-line={934} +\item{} +%mdk-data-line={934} +\mdline{934}If there has not been any primary at all, the election\mdline{934}\_\mdline{934}id is left unset.%mdk%mdk + +%mdk-data-line={936} +\item{} +%mdk-data-line={936} +\mdline{936}Otherwise, \mdline{936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{936} is set to the highest election ID that the server +has seen for this \mdline{937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{937} and \mdline{937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{937} (which is the \mdline{937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{937} of +the current primary if there is any).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={940} +\item{} +%mdk-data-line={940} +\mdline{940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{940} is set differently based on whether the notification is sent to the +primary or a backup controller:%mdk + +%mdk-data-line={943} +\begin{itemize}%mdk + +%mdk-data-line={943} +\item{} +%mdk-data-line={943} +\mdline{943}If there is a primary:%mdk + +%mdk-data-line={945} +\begin{itemize}%mdk + +%mdk-data-line={945} +\item{} +%mdk-data-line={945} +\mdline{945}For the primary, \mdline{945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{945} is OK (with \mdline{945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{945} set to +\mdline{946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.OK}}}\mdline{946}).%mdk%mdk + +%mdk-data-line={948} +\item{} +%mdk-data-line={948} +\mdline{948}For all backup controllers, \mdline{948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{948} is set to non-OK (with +\mdline{949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{949} set to \mdline{949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.ALREADY\_EXISTS}}}\mdline{949}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={951} +\item{} +%mdk-data-line={951} +\mdline{951}Otherwise, if there is no primary currently, for all backup controllers, +\mdline{952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{952} is set to non-OK (with \mdline{952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{952} set to +\mdline{953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.NOT\_FOUND}}}\mdline{953}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={955} +\noindent\mdline{955}Note that on primary client changes with outstanding \mdline{955}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{955} request, some +notifications might be delayed, see the +\mdline{957}\mdref{sec-arbitration-updates}{previous section}\mdline{957} for details.%mdk + +%mdk-data-line={959} +\section{\mdline{959}6.\hspace*{0.5em}\mdline{959}The P4Info Message}\label{sec-the-p4info-message}%mdk%mdk + +%mdk-data-line={961} +\noindent\mdline{961}The purpose of P4Info was described under +\mdline{962}\mdref{sec-reference-architecture}{Reference Architecture}\mdline{962}. +Here we describe the various +components.%mdk + +%mdk-data-line={966} +\subsection{\mdline{966}6.1.\hspace*{0.5em}\mdline{966}Common Messages}\label{sec-common-messages}%mdk%mdk + +%mdk-data-line={968} +\noindent\mdline{968}These messages appear nested within many other messages.%mdk + +%mdk-data-line={970} +\subsubsection{\mdline{970}6.1.1.\hspace*{0.5em}\mdline{970}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{970} Message}\label{sec-documentation-message}%mdk%mdk + +%mdk-data-line={972} +\noindent\mdline{972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{972} is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers.%mdk + +%mdk-data-line={976} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={977} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Documentation~\{\\ +~~{\mdcolor{darkgreen}//~A~brief~description~of~something,~e.g.~one~sentence}\\ +~~{\bfseries{\mdcolor{navy}string}}~brief~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~A~more~verbose~description~of~something.}\\ +~~{\mdcolor{darkgreen}//~Multiline~is~accepted.~Markup~format~(if~any)~is~TBD.}\\ +~~{\bfseries{\mdcolor{navy}string}}~description~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={986} +\subsubsection{\mdline{986}6.1.2.\hspace*{0.5em}\mdline{986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{986} Message}\label{sec-preamble-message}%mdk%mdk + +%mdk-data-line={988} +\noindent\mdline{988}The preamble serves as the \mdline{988}\textquotedblleft{}descriptor\textquotedblright{}\mdline{988} for each entity and contains the unique +instance ID, name, alias, annotations and documentation.%mdk + +%mdk-data-line={991} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={992} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Preamble~\{\\ +~~{\mdcolor{darkgreen}//~ids~share~the~same~number-space;~e.g.~table~ids~cannot~overlap~with~counter}\\ +~~{\mdcolor{darkgreen}//~ids.~Even~though~this~is~irrelevant~to~this~proto~definition,~the~ids~are}\\ +~~{\mdcolor{darkgreen}//~allocated~in~such~a~way~that~it~is~possible~based~on~an~id~to~deduce~the}\\ +~~{\mdcolor{darkgreen}//~resource~type~(e.g.~table,~action,~counter,~...).~This~means~that~code}\\ +~~{\mdcolor{darkgreen}//~using~these~ids~can~detect~if~the~wrong~resource~type~is~used}\\ +~~{\mdcolor{darkgreen}//~somewhere.~This~also~means~that~ids~of~different~types~can~be~mixed}\\ +~~{\mdcolor{darkgreen}//~(e.g.~direct~resource~list~for~a~table)~without~ambiguity.~Note~that~id~0}\\ +~~{\mdcolor{darkgreen}//~is~reserved~and~means~"invalid~id".}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name~of~the~P4~object,~e.g.~c1.c2.ipv4\_lpm}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~an~alias~(alternative~name)~for~the~P4~object,~probably~shorter~than~its}\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name.~The~only~constraint~is~for~it~to~be~unique~with}\\ +~~{\mdcolor{darkgreen}//~respect~to~other~P4~objects~of~the~same~type.~By~default,~the~compiler~uses}\\ +~~{\mdcolor{darkgreen}//~the~shortest~suffix~of~the~name~that~uniquely~identifies~the~object.~For}\\ +~~{\mdcolor{darkgreen}//~example~if~the~P4~program~contains~two~tables~with~names~s.c1.t~and~s.c2.t,}\\ +~~{\mdcolor{darkgreen}//~the~default~aliases~will~respectively~be~c1.t~and~c2.t.~In~the~future,~the}\\ +~~{\mdcolor{darkgreen}//~P4~programmer~may~also~be~able~to~override~the~default~alias~for~any~P4}\\ +~~{\mdcolor{darkgreen}//~object~(TBD).}\\ +~~{\bfseries{\mdcolor{navy}string}}~alias~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~Optional.~If~present,~the~location~of~`annotations{}[i]`~is~given~by}\\ +~{\mdcolor{darkgreen}//~`annotation\_locations{}[i]`.}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~SourceLocation~annotation\_locations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~Documentation~of~the~entity}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1023} +\subsubsection{\mdline{1023}6.1.3.\hspace*{0.5em}\mdline{1023}Annotating P4 Entities with \mdline{1023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}\label{sec-annotating-p4-entities-with-documentation}%mdk%mdk + +%mdk-data-line={1025} +\noindent\mdline{1025}P4 entities may be annotated using the following annotations:%mdk + +%mdk-data-line={1027} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1028} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}(string...)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}(string...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1032} +\noindent\mdline{1032}Attaching either or both of these annotations to an entity will generate a +P4Info\mdline{1033}~\mdref{sec-documentation-message}{Documentation Message}\mdline{1033}, which in turn will +appear in the\mdline{1034}~\mdref{sec-preamble-message}{Preamble Message}\mdline{1034} for the entity.%mdk + +%mdk-data-line={1036} +\mdline{1036}The P4 compiler should not emit \mdline{1036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation}}}\mdline{1036} messages in the P4Info for these +specific cases; instead, it should generate the \mdline{1037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1037} messages as +described.%mdk + +%mdk-data-line={1040} +\mdline{1040}The following example shows documentation annotations for a \mdline{1040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table}}}\mdline{1040} entity:%mdk + +%mdk-data-line={1042} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1043} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port.~\textbackslash{}}\\ +Uses~LPM~match~{\bfseries{\mdcolor{navy}type}}.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}table~my\_ipv4\_lkup~\{}\\ +{\mdcolor{maroon}~~...}\\ +{\mdcolor{maroon}\}}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1051} +\subsubsection{\mdline{1051}6.1.4.\hspace*{0.5em}\mdline{1051}Structured Annotations}\label{sec-structured-annotations}%mdk%mdk + +%mdk-data-line={1053} +\noindent\mdline{1053}P4 supports both unstructured and structured annotations\mdline{1053}~[\mdcite{p4annotations}{13}]\mdline{1053}. +Unstructured annotations of the form \mdline{1054}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno1}}}\mdline{1054} or \mdline{1054}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno2(body-content)}}}\mdline{1054} can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +\mdline{1057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno3{}[]}}}\mdline{1057} or \mdline{1057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno4{}[kvList\textbar{}expressionList]}}}\mdline{1057} have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this.%mdk + +%mdk-data-line={1062} +\mdline{1062}The annotations described up to this point, \mdline{1062}e.g.\mdline{1062} \mdline{1062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief()}}}\mdline{1062}, have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as \mdline{1064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1064} fields in the various \mdline{1064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{1064}s. +Similarly, structured annotations are represented in \mdline{1065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated\\ +StructuredAnnotation~structured\_annotations}}}\mdline{1066} fields which are siblings to the +unstructured \mdline{1067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1067}. The \mdline{1067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations}}}\mdline{1067} contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations.%mdk + +%mdk-data-line={1072} +\mdline{1072}The structured annotation messages are defined in p4types.proto.%mdk + +%mdk-data-line={1074} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1075} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~KeyValuePair~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~key~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Expression~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~KeyValuePairList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~KeyValuePair~kv\_pairs~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Expression~\{\\ +~~{\bfseries{\mdcolor{navy}oneof}}~value~\{\\ +~~~~{\bfseries{\mdcolor{navy}string}}~string\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~{\bfseries{\mdcolor{navy}int64}}~int64\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~{\bfseries{\mdcolor{navy}bool}}~bool\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~ExpressionList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Expression~expressions~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~StructuredAnnotation~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}oneof}}~body~\{\\ +~~~~ExpressionList~expression\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~KeyValuePairList~kv\_pair\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~Optional.~Location~of~the~'@'~symbol~of~this~annotation~in~the~source~code.}\\ +~~SourceLocation~source\_location~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1107} +\noindent\mdline{1107}The \mdline{1107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1107} message can represent either a \mdline{1107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1107} +or an \mdline{1108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExpressionList}}}\mdline{1108}.%mdk + +%mdk-data-line={1110} +\mdline{1110}The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The \mdline{1111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{1111} +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don\mdline{1113}'\mdline{1113}t match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler \mdline{1115}\emph{may}\mdline{1115} print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions.%mdk + +%mdk-data-line={1119} +\mdline{1119}The following invariants hold:%mdk + +%mdk-data-line={1121} +\begin{enumerate}%mdk + +%mdk-data-line={1121} +\item{} +%mdk-data-line={1121} +\mdline{1121}For any P4 entity, there are no two \mdline{1121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1121}s that have the +same name.%mdk%mdk + +%mdk-data-line={1124} +\item{} +%mdk-data-line={1124} +\mdline{1124}Within a \mdline{1124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1124}, there are no two \mdline{1124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePair}}}\mdline{1124}s that have the +same \mdline{1125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key.}}}\mdline{1125}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1127} +\paragraph{\mdline{1127}6.1.4.1.\hspace*{0.5em}\mdline{1127}Structured Annotation Examples}\label{sec-structured-annotation-examples}%mdk%mdk + +%mdk-data-line={1129} +\noindent\mdline{1129}We omit the \mdline{1129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}source\_location}}}\mdline{1129} field in the following examples.%mdk + +%mdk-data-line={1131} +\mdline{1131}\textbf{Empty Expression List}\mdline{1131}%mdk + +%mdk-data-line={1133} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1134} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}Empty}{\mdcolor{maroon}{}[]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1140} +\noindent\mdline{1140}The generated P4Info will contain the following.%mdk + +%mdk-data-line={1142} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1143} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}Empty}{\mdcolor{maroon}"}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1148} +\noindent\mdline{1148}\textbf{Mixed Expression List}\mdline{1148}%mdk + +%mdk-data-line={1150} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1151} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~TEXT\_CONST~"hello"}\\ +{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~NUM\_CONST~6}\\ +{\mdcolor{gray}@}{\mdcolor{gray}MixedExprList}{\mdcolor{maroon}{}[1,TEXT\_CONST,true,1==2,5+NUM\_CONST]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1159} +\noindent\mdline{1159}The generated P4Info will contain:%mdk + +%mdk-data-line={1161} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1162} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedExprList}{\mdcolor{maroon}"}\\ +~~expression\_list~\{\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}1}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}hello}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~true\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~false\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}11}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1184} +\noindent\mdline{1184}\textbf{kvList of Mixed Expressions}\mdline{1184}%mdk + +%mdk-data-line={1186} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1187} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}MixedKV}{\mdcolor{maroon}{}[label="text",~my\_bool=true,~int\_val=2*3]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1193} +\noindent\mdline{1193}The generated P4Info will contain:%mdk + +%mdk-data-line={1195} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1196} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedKV}{\mdcolor{maroon}"}\\ +~~kv\_pair\_list~\{\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}label}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}text}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}my\_bool}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~bool\_value:~true\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}int\_val}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~int64\_value:~{\mdcolor{purple}6}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1221} +\subsubsection{\mdline{1221}6.1.5.\hspace*{0.5em}\mdline{1221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1221} Message}\label{sec-sourcelocation-message}%mdk%mdk + +%mdk-data-line={1223} +\noindent\mdline{1223}A source location describes a location within a \mdline{1223}\emph{.p4}\mdline{1223}-source file. The +\mdline{1224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1224} message is defined in p4types.proto as follows:%mdk + +%mdk-data-line={1226} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1227} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Location~of~code~relative~to~a~given~source~file.}\\ +{\bfseries{\mdcolor{navy}message}}~SourceLocation~\{\\ +~~{\mdcolor{darkgreen}//~Path~to~the~source~file~(absolute~or~relative~to~the~working~directory).}\\ +~~{\bfseries{\mdcolor{navy}string}}~file~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Line~and~column~numbers~within~the~source~file,~1-based.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~line~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}int32}}~column~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1237} +\noindent\mdline{1237}We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations.%mdk + +%mdk-data-line={1242} +\mdline{1242}The \mdline{1242}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1242} message associated with an annotation holds the location of +the \mdline{1243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@}}}\mdline{1243} symbol introducing the annotation in the P4 source code; the message can +be found in the following place:%mdk + +%mdk-data-line={1246} +\begin{itemize}%mdk + +%mdk-data-line={1246} +\item{} +%mdk-data-line={1246} +\mdline{1246}For \mdline{1246}\textbf{unstructured annotations}\mdline{1246}, every message containing a field +\mdline{1247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1247} also contains a field +\mdline{1248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~SourceLocation~annotation\_locations}}}\mdline{1248}. The field must either be empty + or match the size of \mdline{1249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1249}. In the latter case, the i-th member of +\mdline{1250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation\_locations}}}\mdline{1250} is the source location of the i-th member of +\mdline{1251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1251}.%mdk%mdk + +%mdk-data-line={1253} +\item{} +%mdk-data-line={1253} +\mdline{1253}For \mdline{1253}\textbf{structured annotations}\mdline{1253}, every \mdline{1253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1253} message contains +an optional field \mdline{1254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation~source\_location}}}\mdline{1254} holding its source +location, if present.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1258} +\subsection{\mdline{1258}6.2.\hspace*{0.5em}\mdline{1258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1258} Message}\label{sec-pkginfo-message}%mdk%mdk + +%mdk-data-line={1260} +\noindent\mdline{1260}The \mdline{1260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1260} message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. \mdline{1261}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1261} can be extracted +and used to facilitate \mdline{1262}\textquotedblleft{}browsing\textquotedblright{}\mdline{1262} of available P4 programs from a +library. Although all fields are technically \mdline{1263}\textquotedblleft{}optional,\textquotedblright{}\mdline{1263} every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included.%mdk + +%mdk-data-line={1267} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1268} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Can~be~used~to~manage~multiple~P4~packages.}\\ +{\bfseries{\mdcolor{navy}message}}~PkgInfo~\{\\ +~~{\mdcolor{darkgreen}//~a~definitive~name~for~this~configuration,~e.g.~switch.p4\_v1.0}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~configuration~version,~free-format~string}\\ +~~{\bfseries{\mdcolor{navy}string}}~version~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~brief~and~detailed~descriptions}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~free-form;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~the~target~architecture,~e.g.~"psa"}\\ +~~{\bfseries{\mdcolor{navy}string}}~arch~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\mdcolor{darkgreen}//~organization~which~produced~the~configuration,~e.g.~"p4.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~organization~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~{\mdcolor{darkgreen}//~contact~info~for~support,e.g.~"tech-support@acme.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~contact~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~url~for~more~information,~e.g.~"http://support.p4.org/ref/p4/switch.p4\_v1.0"}\\ +~~{\bfseries{\mdcolor{navy}string}}~url~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}8};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~structured;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}9};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1291} +\subsubsection{\mdline{1291}6.2.1.\hspace*{0.5em}\mdline{1291}Annotating P4 code with PkgInfo}\label{sec-annotating-p4-code-with-pkginfo}%mdk%mdk + +%mdk-data-line={1293} +\noindent\mdline{1293}A P4 progam\mdline{1293}'\mdline{1293}s \mdline{1293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1293} may be declared using one or more of the following +annotations, attached to the \mdline{1294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1294} block only:%mdk + +%mdk-data-line={1296} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1297} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value{}[,key=value,...])}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("A~brief~description")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("A~longer\textbackslash{}}\\ +description{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@custom\_annotation(...)}\\ +{\mdcolor{maroon}@another\_custom\_annotation(...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1306} +\noindent\mdline{1306}Above we see several different types of annotations:%mdk + +%mdk-data-line={1308} +\begin{itemize}%mdk + +%mdk-data-line={1308} +\item{} +%mdk-data-line={1308} +\mdline{1308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1308} \mdline{1308}- This is used to populate a specific field within the \mdline{1308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1308} +message. Multiple \mdline{1309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1309} annotations are allowed. For compactness, +multiple key-value pairs can appear in a single \mdline{1310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1310} annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The \mdline{1312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{1312}s must be from +among the message fields inside \mdline{1313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1313}, for example, \mdline{1313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1313}, \mdline{1313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}version}}}\mdline{1313}, +etc. Each key-value pair assigns a value to the corresponding field inside the +single \mdline{1315}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1315} message for the program\mdline{1315}'\mdline{1315}s P4Info. One exception is that the +\mdline{1316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1316} field of \mdline{1316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1316} must be expressed as individual +\mdline{1317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1317} and \mdline{1317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1317} annotations, see next bullets. The key \mdline{1317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}arch}}}\mdline{1317} will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself.%mdk%mdk + +%mdk-data-line={1321} +\item{} +%mdk-data-line={1321} +\mdline{1321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1321} \mdline{1321}- This will populate the \mdline{1321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.brief}}}\mdline{1321} message field.%mdk%mdk + +%mdk-data-line={1323} +\item{} +%mdk-data-line={1323} +\mdline{1323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1323} \mdline{1323}- This will populate the \mdline{1323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.description}}}\mdline{1323} message +field%mdk%mdk + +%mdk-data-line={1326} +\item{} +%mdk-data-line={1326} +\mdline{1326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@\textless{}anything~else\textgreater{}}}}\mdline{1326} \mdline{1326}- This will create a \mdline{1326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotation}}}\mdline{1326} entry%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1328} +\noindent\mdline{1328}Declaring one or more of these annotations on \mdline{1328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1328} will +generate a single corresponding \mdline{1329}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1329} message in the P4Info as described in +\mdline{1330}\mdref{sec-pkginfo-message}{PkgInfo Message}\mdline{1330}.%mdk + +%mdk-data-line={1332} +\mdline{1332}The following example shows \mdline{1332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1332} annotations using a mixture of single and +multiple key-value pairs. It also shows \mdline{1333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1333} and \mdline{1333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1333} annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the \mdline{1335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1335} message. The custom annotations will +be appended to the \mdline{1336}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotations}}}\mdline{1336} list.%mdk + +%mdk-data-line={1338} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1339} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(name="switch.p4",version="2")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(organization="p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(contact="info@p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(url="www.p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("L2/L3~switch")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("L2/L3~switch.\textbackslash{}}\\ +Built~for~data-center~profile.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@my\_annotation1(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}@my\_annotation2(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}PSA\_Switch(IgPipeline,~PacketReplicationEngine(),~EgPipeline,}\\ +{\mdcolor{maroon}~~~~~~~~~~~BufferingQueueingEngine())~main;}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1352} +\subsection{\mdline{1352}6.3.\hspace*{0.5em}\mdline{1352}ID Allocation for P4Info Objects}\label{sec-id-allocation}%mdk%mdk + +%mdk-data-line={1354} +\noindent\mdline{1354}P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(\mdline{1358}e.g.\mdline{1358} table, action, counter, \mdline{1358}\dots{}\mdline{1358}). The most significant 8 bits of the ID +encodes the object type (as per Table\mdline{1359}~\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}}\mdline{1359}). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (\mdline{1361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.P4Ids.Prefix}}}\mdline{1361}). These values must +be used (\mdline{1362}e.g.\mdline{1362} by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table\mdline{1364}~\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}}\mdline{1364} shows the ID +layout.%mdk + +%mdk-data-line={1367} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1369} 8-bit prefix value}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1369} P4 object type}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{1371} 0x00}&\multicolumn{1}{|l|}{\mdline{1371} Reserved (unspecified)}\\ +\multicolumn{1}{|l}{\mdline{1372} 0x01}&\multicolumn{1}{|l|}{\mdline{1372} Action}\\ +\multicolumn{1}{|l}{\mdline{1373} 0x02}&\multicolumn{1}{|l|}{\mdline{1373} Table}\\ +\multicolumn{1}{|l}{\mdline{1374} 0x03}&\multicolumn{1}{|l|}{\mdline{1374} Value-set}\\ +\multicolumn{1}{|l}{\mdline{1375} 0x04}&\multicolumn{1}{|l|}{\mdline{1375} Controller header (header type with \mdline{1375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1375} annotation)}\\ +\multicolumn{1}{|l}{\mdline{1376} 0x05\mdline{1376}\dots{}\mdline{1376}0x0f}&\multicolumn{1}{|l|}{\mdline{1376} Reserved (for future P4 built-in objects)}\\ +\multicolumn{1}{|l}{\mdline{1377} 0x10}&\multicolumn{1}{|l|}{\mdline{1377} Reserved (start of PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1378} 0x11}&\multicolumn{1}{|l|}{\mdline{1378} PSA Action profiles / selectors}\\ +\multicolumn{1}{|l}{\mdline{1379} 0x12}&\multicolumn{1}{|l|}{\mdline{1379} PSA Counter}\\ +\multicolumn{1}{|l}{\mdline{1380} 0x13}&\multicolumn{1}{|l|}{\mdline{1380} PSA Direct counter}\\ +\multicolumn{1}{|l}{\mdline{1381} 0x14}&\multicolumn{1}{|l|}{\mdline{1381} PSA Meter}\\ +\multicolumn{1}{|l}{\mdline{1382} 0x15}&\multicolumn{1}{|l|}{\mdline{1382} PSA Direct meter}\\ +\multicolumn{1}{|l}{\mdline{1383} 0x16}&\multicolumn{1}{|l|}{\mdline{1383} PSA Register}\\ +\multicolumn{1}{|l}{\mdline{1384} 0x17}&\multicolumn{1}{|l|}{\mdline{1384} PSA Digest}\\ +\multicolumn{1}{|l}{\mdline{1385} 0x18\mdline{1385}\dots{}\mdline{1385}0x7f}&\multicolumn{1}{|l|}{\mdline{1385} Reserved (for future PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1386} 0x80}&\multicolumn{1}{|l|}{\mdline{1386} Reserved (start of vendor-specific extern types)}\\ +\multicolumn{1}{|l}{\mdline{1387} 0x81\mdline{1387}\dots{}\mdline{1387}0xfe}&\multicolumn{1}{|l|}{\mdline{1387} Vendor-specific extern types}\\ +\multicolumn{1}{|l}{\mdline{1388} 0xff}&\multicolumn{1}{|l|}{\mdline{1388} Reserved (max prefix value)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1390} +\mdhr{}%mdk + +%mdk-data-line={1391} +\noindent\mdline{1391}\mdcaption{\textbf{Table~\mdcaptionlabel{1}.}~\mdcaptiontext{Mapping of P4Info object type to 8-bit ID prefix value}}%mdk +%mdk +\end{mdcenter}\label{tab-mapping-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1394} +\begin{table}[h!]%mdk +\begin{mdblock}{text-align=center,breakable=true}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{cc}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1396} MSB bit 31 \mdline{1396}\dots{}\mdline{1396}\dots{}\mdline{1396}.. bit 24}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1396} bit 23 \mdline{1396}\dots{}\mdline{1396}\dots{}\mdline{1396}\dots{}\mdline{1396}\dots{}\mdline{1396}\dots{}\mdline{1396}\dots{}\mdline{1396}\dots{}\mdline{1396}.. bit 0 LSB}}\\ + +\midrule +\multicolumn{1}{|c}{\mdline{1398} Object type prefix}&\multicolumn{1}{|c|}{\mdline{1398} Generated suffix (\mdline{1398}e.g.\mdline{1398} by the compiler)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1400} +\mdhr{}%mdk + +%mdk-data-line={1401} +\noindent\mdline{1401}\mdcaption{\textbf{Table~\mdcaptionlabel{2}.}~\mdcaptiontext{Format of P4Info object IDs}}%mdk%mdk +\end{mdblock}\label{tab-format-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1405} +\mdline{1405}It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with \mdline{1406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1406} (see Table +\mdline{1407}\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}}\mdline{1407}). The compiler must honor the \mdline{1407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1407} annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (\mdline{1409}i.e.\mdline{1409} if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same \mdline{1411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1411} value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct.%mdk + +%mdk-data-line={1420} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth-7cm)/1}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{\mdinline{width=7cm}{{\bfseries\mdline{1422} P4 declaration(s)}}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1422} Compiler-allocated ID(s)}}\\ + +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1424} \mdline{1424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1424}}}&\multicolumn{1}{|l|}{\mdline{1424} 0x0212ab34}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1426} \mdline{1426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1426}}}&\multicolumn{1}{|l|}{\mdline{1426} \mdline{1426}\textbf{Error}\mdline{1426}(same ID suffixes for 2 objects of the same type)}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1427} \mdline{1427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tB...}}}\mdline{1427}}}&\multicolumn{1}{|l|}{\mdline{1427}}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1429} \mdline{1429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1429}}}&\multicolumn{1}{|l|}{\mdline{1429} 0x0212ab34}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1430} \mdline{1430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~action~act1...}}}\mdline{1430}}}&\multicolumn{1}{|l|}{\mdline{1430} 0x0112ab34}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1432} +\mdhr{}%mdk + +%mdk-data-line={1433} +\noindent\mdline{1433}\mdcaption{\textbf{Table~\mdcaptionlabel{3}.}~\mdcaptiontext{Example of statically-assigned P4Info object IDs}}%mdk +%mdk +\end{mdcenter}\label{tab-exmpl-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1436} +\mdline{1436}The \mdline{1436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1436} annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively).%mdk + +%mdk-data-line={1442} +\subsection{\mdline{1442}6.4.\hspace*{0.5em}\mdline{1442}P4Info Objects}\label{sec-p4info-objects}%mdk%mdk + +%mdk-data-line={1444} +\subsubsection{\mdline{1444}6.4.1.\hspace*{0.5em}\mdline{1444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}\label{sec-table}%mdk%mdk + +%mdk-data-line={1446} +\noindent\mdline{1446}Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields:%mdk + +%mdk-data-line={1449} +\begin{itemize}%mdk + +%mdk-data-line={1449} +\item{} +%mdk-data-line={1449} +\mdline{1449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1449}, a \mdline{1449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1449} message with the ID, name, and alias of this table.%mdk%mdk + +%mdk-data-line={1451} +\item{} +%mdk-data-line={1451} +\mdline{1451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1451}, a repeated field of type \mdline{1451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1451} representing the data to +be used to construct the lookup key matched in this table. Each \mdline{1452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1452} +message is defined with the following fields:%mdk + +%mdk-data-line={1455} +\begin{itemize}%mdk + +%mdk-data-line={1455} +\item{} +%mdk-data-line={1455} +\mdline{1455}id, the \mdline{1455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1455} identifier of this \mdline{1455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1455}, unique in the scope of +this table. No rules are prescribed on the way \mdline{1456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1456} IDs should be +allocated, as long as two \mdline{1457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1457} of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the \mdline{1461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1461} annotation, or let the compiler +choose them.%mdk%mdk + +%mdk-data-line={1464} +\item{} +%mdk-data-line={1464} +\mdline{1464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1464}, the string representing the name of this \mdline{1464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1464}.%mdk%mdk + +%mdk-data-line={1466} +\item{} +%mdk-data-line={1466} +\mdline{1466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1466}, a repeated field of strings, each one representing a P4 +annotation associated to this match field.%mdk%mdk + +%mdk-data-line={1469} +\item{} +%mdk-data-line={1469} +\mdline{1469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1469}, an \mdline{1469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1469} value set to the size in bits of this match field.%mdk%mdk + +%mdk-data-line={1471} +\item{} +%mdk-data-line={1471} +\mdline{1471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1471}, a \mdline{1471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{1471} describing the match behavior for this field; it can be +either:%mdk + +%mdk-data-line={1473} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1473} +\item\mdline{1473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1473}, an enum field of type \mdline{1473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchType}}}\mdline{1473}, which includes all +possible PSA match kinds.%mdk + +%mdk-data-line={1475} +\item\mdline{1475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_match\_type}}}\mdline{1475}, a string field which can be used to encode any +architecture-specific match type.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1478} +\item{} +%mdk-data-line={1478} +\mdline{1478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1478}, a \mdline{1478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1478} message describing this match field.%mdk%mdk + +%mdk-data-line={1480} +\item{} +%mdk-data-line={1480} +\mdline{1480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1480}, which indicates whether the match field has a\mdline{1480}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1481}; this is useful for +\mdline{1482}\mdref{sec-psa-metadata-translation}{translation}\mdline{1482}.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1484} +\item{} +%mdk-data-line={1484} +\mdline{1484}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_refs}}}\mdline{1484}, a repeated \mdline{1484}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1484} field representing the set of possible +actions for this table. The \mdline{1485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1485} message is used to reference an action +specified in the same P4Info message and it includes the following fields:%mdk + +%mdk-data-line={1487} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1487} +\item\mdline{1487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1487}, the \mdline{1487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1487} identifier of the action.%mdk + +%mdk-data-line={1488} +\item\mdline{1488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1488}, an enum value which can take one of three values: + \mdline{1489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1489}, \mdline{1489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1489} and \mdline{1489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1489}. The \mdline{1489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1489} of the + action is determined by the use of the P4 standard annotations + \mdline{1491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1491} and \mdline{1491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1491}~[\mdcite{p4actionannotations}{18}]\mdline{1491}. \mdline{1491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1491} + (\mdline{1492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1492} annotation) means that the action can only appear within + the table, and never as the default action. \mdline{1493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1493} + (\mdline{1494}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1494} annotation) means that the action can only be used as the + default action. \mdline{1495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1495} is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action.%mdk + +%mdk-data-line={1498} +\item\mdline{1498}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1498}, a repeated string field, each one representing a P4 +annotation associated to the action \mdline{1499}\emph{reference}\mdline{1499} in this table.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1501} +\item{} +%mdk-data-line={1501} +\mdline{1501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\_default\_action\_id}}}\mdline{1501}, if this table has a constant default action, this +field will carry the \mdline{1502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1502} identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action\mdline{1505}'\mdline{1505}s +arguments.%mdk%mdk + +%mdk-data-line={1508} +\item{} +%mdk-data-line={1508} +\mdline{1508}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation\_id}}}\mdline{1508}, the \mdline{1508}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1508} identifier of the \mdline{1508}\textquotedblleft{}implementation\textquotedblright{}\mdline{1508} of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (\mdline{1511}e.g.\mdline{1511} a PSA \mdline{1511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1511} or \mdline{1511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{1511} +instance). The table is then referred to as an indirect match table.%mdk%mdk + +%mdk-data-line={1514} +\item{} +%mdk-data-line={1514} +\mdline{1514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_resource\_ids}}}\mdline{1514}, repeated \mdline{1514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1514} identifiers for all the direct +resources attached to this table, such as \mdline{1515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1515} and \mdline{1515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1515} +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2.%mdk%mdk + +%mdk-data-line={1521} +\item{} +%mdk-data-line={1521} +\mdline{1521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1521}, an \mdline{1521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1521} describing the desired number of table entries that the +target should support for the table. See the \mdline{1522}\textquotedblleft{}Size\textquotedblright{}\mdline{1522} subsection within the +\mdline{1523}\textquotedblleft{}Table Properties\textquotedblright{}\mdline{1523} section of the P4\mdline{1523}\mdsub{16}\mdline{1523} language specification for details +\mdline{1524}[\mdcite{p4tableproperties}{30}]\mdline{1524}.%mdk%mdk + +%mdk-data-line={1526} +\item{} +%mdk-data-line={1526} +\mdline{1526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_behavior}}}\mdline{1526}, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +\mdline{1528}\mdref{sec-idle-timeout}{Idle-Timeout}\mdline{1528} section). Value can be any of the +\mdline{1529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutBehavior}}}\mdline{1529} enum:%mdk + +%mdk-data-line={1530} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1530} +\item\mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NO\_TIMEOUT}}}\mdline{1530} (default value), which means that idle timeout is not +supported for this table.%mdk + +%mdk-data-line={1532} +\item\mdline{1532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOTIFY\_CONTROL}}}\mdline{1532}, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +\mdline{1534}\mdref{sec-table-idle-timeout-notification}{Table Idle Timeout Notifications}\mdline{1534}).%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1536} +\item{} +%mdk-data-line={1536} +\mdline{1536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{1536}, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime.%mdk%mdk + +%mdk-data-line={1539} +\item{} +%mdk-data-line={1539} +\mdline{1539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{1539}, an \mdline{1539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1539} Protobuf message\mdline{1539}~[\mdcite{protoany}{31}]\mdline{1539} to embed +architecture-specific table properties\mdline{1540}~[\mdcite{p4tableproperties}{30}]\mdline{1540} which are not part +of the core P4 language or of the PSA architecture.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1543} +\subsubsection{\mdline{1543}6.4.2.\hspace*{0.5em}\mdline{1543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}\label{sec-action}%mdk%mdk + +%mdk-data-line={1545} +\noindent\mdline{1545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1545} messages are used to specify all possible actions of all match-action +tables.%mdk + +%mdk-data-line={1548} +\mdline{1548}The \mdline{1548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1548} message defines the following fields:%mdk + +%mdk-data-line={1550} +\begin{itemize}%mdk + +%mdk-data-line={1550} +\item{} +%mdk-data-line={1550} +\mdline{1550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1550}, a \mdline{1550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1550} message with the ID, name, and alias of this action%mdk%mdk + +%mdk-data-line={1552} +\item{} +%mdk-data-line={1552} +\mdline{1552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{1552}, a repeated field of \mdline{1552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1552} messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each \mdline{1554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1554} message contains the +following fields:%mdk + +%mdk-data-line={1556} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1556} +\item\mdline{1556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1556}, the \mdline{1556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1556} identifier of this parameter. No rules are prescribed +on the way \mdline{1557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1557} IDs should be allocated, as long as two \mdline{1557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1557} of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the \mdline{1561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1561} +annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1563} +\item\mdline{1563}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1563}, the string representing the name of this parameter.%mdk + +%mdk-data-line={1564} +\item\mdline{1564}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1564}, a repeated field of strings, each one representing a P4 +annotation associated to this parameter.%mdk + +%mdk-data-line={1566} +\item\mdline{1566}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1566}, an \mdline{1566}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1566} value set to the size in bits of this parameter.%mdk + +%mdk-data-line={1567} +\item\mdline{1567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1567}, which describes this parameter using a \mdline{1567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1567} message.%mdk + +%mdk-data-line={1568} +\item\mdline{1568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1568}, which indicates whether the action parameter has a +\mdline{1569}\mdref{sec-user-defined-types}{user-defined type}\mdline{1569}; this is useful for +\mdline{1570}\mdref{sec-psa-metadata-translation}{translation}\mdline{1570}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1572} +\subsubsection{\mdline{1572}6.4.3.\hspace*{0.5em}\mdline{1572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}\label{sec-p4info-action-profile}%mdk%mdk + +%mdk-data-line={1574} +\noindent\mdline{1574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1574} messages are used to specify all available instances of Action +Profile and Action Selector PSA externs.%mdk + +%mdk-data-line={1577} +\mdline{1577}PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile \mdline{1581}\emph{member}\mdline{1581}, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime.%mdk + +%mdk-data-line={1585} +\mdline{1585}PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into \mdline{1586}\emph{groups}\mdline{1586}. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime.%mdk + +%mdk-data-line={1595} +\mdline{1595}While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same \mdline{1596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1596} message to describe both.%mdk + +%mdk-data-line={1598} +\mdline{1598}The \mdline{1598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1598} message includes the following fields:%mdk + +%mdk-data-line={1600} +\begin{itemize}%mdk + +%mdk-data-line={1600} +\item{} +%mdk-data-line={1600} +\mdline{1600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1600}, a \mdline{1600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1600} message with the ID, name, and alias of this Action +Profile or Selector.%mdk%mdk + +%mdk-data-line={1603} +\item{} +%mdk-data-line={1603} +\mdline{1603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_ids}}}\mdline{1603}, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector.%mdk%mdk + +%mdk-data-line={1606} +\item{} +%mdk-data-line={1606} +\mdline{1606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}with\_selector}}}\mdline{1606}, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern.%mdk%mdk + +%mdk-data-line={1609} +\item{} +%mdk-data-line={1609} +\mdline{1609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1609}, an \mdline{1609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1609} representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups.%mdk%mdk + +%mdk-data-line={1613} +\item{} +%mdk-data-line={1613} +\mdline{1613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1613}, an \mdline{1613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1613} representing the maximum sum of all member +weights within any given selector group, in the case of an Action Selector, or +0 for an Action Profile. PSA programs can use the \mdline{1615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{1615} annotation +to provide this value for Action Selectors. If the annotation is omitted, the +P4Info field will default to 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1619} +\subsubsection{\mdline{1619}6.4.4.\hspace*{0.5em}\mdline{1619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1619} \mdline{1619}\&\mdline{1619} \mdline{1619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}\label{sec-counter-directcounter}%mdk%mdk + +%mdk-data-line={1621} +\noindent\mdline{1621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1621} and \mdline{1621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1621} messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is:%mdk + +%mdk-data-line={1627} +\begin{itemize}%mdk + +%mdk-data-line={1627} +\item{} +%mdk-data-line={1627} +\mdline{1627}Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index.%mdk%mdk + +%mdk-data-line={1631} +\item{} +%mdk-data-line={1631} +\mdline{1631}Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1634} +\noindent\mdline{1634}Both \mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1634} and \mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1634} messages share the following fields:%mdk + +%mdk-data-line={1636} +\begin{itemize}%mdk + +%mdk-data-line={1636} +\item{} +%mdk-data-line={1636} +\mdline{1636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1636}, a \mdline{1636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1636} message with the ID, name, and alias of this counter +extern instance.%mdk%mdk + +%mdk-data-line={1639} +\item{} +%mdk-data-line={1639} +\mdline{1639}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1639}, a message of of type \mdline{1639}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1639} used to describe the compile-time +configuration of this counter. Currently, the \mdline{1640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1640} message is used to +carry only the counter unit, which can be any of the \mdline{1641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec.Unit}}}\mdline{1641} enum +values:%mdk + +%mdk-data-line={1643} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1643} +\item\mdline{1643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1643}: reserved value.%mdk + +%mdk-data-line={1644} +\item\mdline{1644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1644}: byte counter.%mdk + +%mdk-data-line={1645} +\item\mdline{1645}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1645}: packet counter.%mdk + +%mdk-data-line={1646} +\item\mdline{1646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BOTH}}}\mdline{1646}: combination of both byte and packet counter.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1648} +\noindent\mdline{1648}For indexed counters, the \mdline{1648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1648} message contains also a \mdline{1648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1648} field, an +\mdline{1649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1649} representing the maximum number of independent values that can be held +by this counter array. Conversely, the \mdline{1650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1650} message contains a +\mdline{1651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1651} field that carries the \mdline{1651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}unit32}}}\mdline{1651} identifier of the table to +which this direct counter is attached.%mdk + +%mdk-data-line={1654} +\mdline{1654}For indexed counters, the \mdline{1654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1654} message contains also an \mdline{1654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1654} +field, which indicates whether the index has a\mdline{1655}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1656}. This is useful for +\mdline{1657}\mdref{sec-psa-metadata-translation}{translation}\mdline{1657}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1658}).%mdk + +%mdk-data-line={1660} +\subsubsection{\mdline{1660}6.4.5.\hspace*{0.5em}\mdline{1660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1660} \mdline{1660}\&\mdline{1660} \mdline{1660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}\label{sec-meter-directmeter}%mdk%mdk + +%mdk-data-line={1662} +\noindent\mdline{1662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1662} and \mdline{1662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1662} messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is:%mdk + +%mdk-data-line={1668} +\begin{itemize}%mdk + +%mdk-data-line={1668} +\item{} +%mdk-data-line={1668} +\mdline{1668}Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +\mdline{1670}e.g.\mdline{1670} to set the rate threshold.%mdk%mdk + +%mdk-data-line={1672} +\item{} +%mdk-data-line={1672} +\mdline{1672}Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1675} +\noindent\mdline{1675}Both \mdline{1675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1675} and \mdline{1675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1675} messages share the following fields:%mdk + +%mdk-data-line={1677} +\begin{itemize}%mdk + +%mdk-data-line={1677} +\item{} +%mdk-data-line={1677} +\mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1677}, a \mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1677} message with the ID, name, and alias of this meter +extern instance.%mdk%mdk + +%mdk-data-line={1680} +\item{} +%mdk-data-line={1680} +\mdline{1680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1680}, a message of type \mdline{1680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1680} used to describe the capabilities of +this meter extern instance. Currently, the \mdline{1681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1681} message is used to +carry only the meter unit, which can be any of the \mdline{1682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Unit}}}\mdline{1682} enum +values:%mdk + +%mdk-data-line={1684} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1684} +\item\mdline{1684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1684}: reserved value.%mdk + +%mdk-data-line={1685} +\item\mdline{1685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1685}, which signifies that this meter can be configured with rates +expressed in bytes/second.%mdk + +%mdk-data-line={1687} +\item\mdline{1687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1687}, for rates expressed in packets/second.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1689} +\noindent\mdline{1689}For indexed meters, the \mdline{1689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1689} message contains also a \mdline{1689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1689} field, an \mdline{1689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1689} +representing the maximum number of independent cells that can be held by this +meter. Conversely, the \mdline{1691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1691} message contains a \mdline{1691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1691} field +that carries the \mdline{1692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1692} identifier of the table to which this direct meter is +attached.%mdk + +%mdk-data-line={1695} +\mdline{1695}For indexed meters, the \mdline{1695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1695} message contains also an \mdline{1695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1695} +field, which indicates whether the index has a\mdline{1696}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1697}. This is useful for +\mdline{1698}\mdref{sec-psa-metadata-translation}{translation}\mdline{1698}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1699}).%mdk + +%mdk-data-line={1701} +\subsubsection{\mdline{1701}6.4.6.\hspace*{0.5em}\mdline{1701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\label{sec-controller-packet-meta}%mdk%mdk + +%mdk-data-line={1703} +\noindent\mdline{1703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1703} messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server.%mdk + +%mdk-data-line={1709} +\mdline{1709}When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet.%mdk + +%mdk-data-line={1715} +\mdline{1715}Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +\mdline{1717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_in")}}}\mdline{1717} and \mdline{1717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_out")}}}\mdline{1717}, +respectively. \mdline{1718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1718} messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages).%mdk + +%mdk-data-line={1723} +\mdline{1723}A P4Info message can contain at most two \mdline{1723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata~messages}}}\mdline{1723}, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields:%mdk + +%mdk-data-line={1727} +\begin{itemize}%mdk + +%mdk-data-line={1727} +\item{} +%mdk-data-line={1727} +\mdline{1727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1727}, a \mdline{1727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1727} message where \mdline{1727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble.name}}}\mdline{1727} is set to \mdline{1727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_in"}}}\mdline{1727} +and \mdline{1728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_out"}}}\mdline{1728} for packet-in and packet-out metadata, respectively.%mdk%mdk + +%mdk-data-line={1730} +\item{} +%mdk-data-line={1730} +\mdline{1730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{1730}, a repeated field of type \mdline{1730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1730}, where each \mdline{1730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1730} message +includes the following fields:%mdk + +%mdk-data-line={1732} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1732} +\item\mdline{1732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1732}, a \mdline{1732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1732} identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two \mdline{1733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1733} of the +same \mdline{1734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1734} message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the \mdline{1738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1738} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1739} +\item\mdline{1739}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1739}, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below).%mdk + +%mdk-data-line={1743} +\item\mdline{1743}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1743}, a repeated field of strings, each one representing a P4 +annotation associated to this metadata.%mdk + +%mdk-data-line={1745} +\item\mdline{1745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1745}, an \mdline{1745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1745} representing the size in bits of this metadata.%mdk + +%mdk-data-line={1746} +\item\mdline{1746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1746}, which indicates whether the metadata field has a +\mdline{1747}\mdref{sec-user-defined-types}{user-defined type}\mdline{1747}; this is useful for +\mdline{1748}\mdref{sec-psa-metadata-translation}{translation}\mdline{1748}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1750} +\noindent\mdline{1750}As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding \mdline{1751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1751} +messages.%mdk + +%mdk-data-line={1754} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1755} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~egress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~port~where~the~packet}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~should~be~sent~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~queue\_id;~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~queue~ID~}{\mdcolor{darkgreen}*/}\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~ingress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~data~plane~port~ID~where}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~the~original~packet~was~received~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}1}\textgreater{}~is\_clone;~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~1~if~this~is~a~clone~of~the}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~original~packet~}{\mdcolor{darkgreen}*/}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1770} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1771} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868916615}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_out}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_out}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}egress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}queue\_id}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~\}\\ +\}\\ +\\ +controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868941301}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_in}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_in}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ingress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}is\_clone}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}1}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1808} +\noindent\mdline{1808}Note that the use of \mdline{1808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1808} is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages.%mdk + +%mdk-data-line={1814} +\subsubsection{\mdline{1814}6.4.7.\hspace*{0.5em}\mdline{1814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}\label{sec-valueset}%mdk%mdk + +%mdk-data-line={1816} +\noindent\mdline{1816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1816} messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P4\mdline{1819}\mdsub{16}\mdline{1819} +specification\mdline{1820}~[\mdcite{p4valuesets}{39}]\mdline{1820}.%mdk + +%mdk-data-line={1822} +\mdline{1822}The \mdline{1822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1822} message defines the following fields:%mdk + +%mdk-data-line={1824} +\begin{itemize}%mdk + +%mdk-data-line={1824} +\item{} +%mdk-data-line={1824} +\mdline{1824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1824}, a \mdline{1824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1824} message with the ID, name, and alias of this Value +Set.%mdk%mdk + +%mdk-data-line={1827} +\item{} +%mdk-data-line={1827} +\mdline{1827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1827}, a repeated field of \mdline{1827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1827} messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the \mdline{1830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1830} repeated field in the +\mdline{1831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{1831} message.%mdk%mdk + +%mdk-data-line={1833} +\item{} +%mdk-data-line={1833} +\mdline{1833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1833}, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +\mdline{1835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set}}}\mdline{1835} constructor call.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1837} +\noindent\mdline{1837}According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of \mdline{1840}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1840}, +\mdline{1841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1841}, or \mdline{1841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1841}~[\mdcite{p4selectexpr}{26}]\mdline{1841}. The rest of this section looks at all 3 of +these cases and gives an example \mdline{1842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1842} message when appropriate.%mdk + +%mdk-data-line={1844} +\begin{enumerate}%mdk + +%mdk-data-line={1844} +\item{} +%mdk-data-line={1844} +\mdline{1844}If the type parameter is \mdline{1844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1844}, \mdline{1844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1844} will include exactly one +\mdline{1845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1845} message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used):%mdk + +%mdk-data-line={1848} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1848} +\item\mdline{1848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1848}: set to 1%mdk + +%mdk-data-line={1849} +\item\mdline{1849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1849}: set to the value of \mdline{1849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1849}%mdk + +%mdk-data-line={1850} +\item\mdline{1850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1850}: set to \mdline{1850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1850}%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1852} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1853} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}bit\textless{}8\textgreater{}~\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(hdr.f8)~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1856} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1857} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1871} +\begin{enumerate}[,start=2]%mdk + +%mdk-data-line={1871} +\item{} +%mdk-data-line={1871} +\mdline{1871}If the type parameter is a \mdline{1871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1871}, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program.%mdk%mdk + +%mdk-data-line={1876} +\item{} +%mdk-data-line={1876} +\mdline{1876}If the type parameter is a \mdline{1876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1876}, this version of P4Runtime requires that +all the fields of the struct be of type \mdline{1877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1877} (where \mdline{1877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1877} can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +\mdline{1880}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1880} field will include one \mdline{1880}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1880} message for each field in the +struct, with the following fields:%mdk + +%mdk-data-line={1883} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1883} +\item\mdline{1883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1883}: must be unique with respect to the other \mdline{1883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1883} entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +\mdline{1887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1887} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1888} +\item\mdline{1888}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1888}: set to the name of the corresponding struct field.%mdk + +%mdk-data-line={1889} +\item\mdline{1889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1889}: set to the list of P4 annotations associated with the struct +field, except for the \mdline{1890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1890} annotation, if present (see the \mdline{1890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1890} field +below).%mdk + +%mdk-data-line={1892} +\item\mdline{1892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1892}: set to the value of \mdline{1892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1892} for the corresponding struct field.%mdk + +%mdk-data-line={1893} +\item\mdline{1893}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1893}, which indicates whether the struct field has a\mdline{1893}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1894}; this is useful for +\mdline{1895}\mdref{sec-psa-metadata-translation}{translation}\mdline{1895}.%mdk + +%mdk-data-line={1896} +\item\mdline{1896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1896}: by default \mdline{1896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1896} is set to \mdline{1896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1896}; the P4 programmer can +specify a different match type by using the \mdline{1897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1897} annotation +\mdline{1898}[\mdcite{p4selectexpr}{26}]\mdline{1898}.%mdk + +%mdk-data-line={1899} +\item\mdline{1899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1899}: documentation associated with the struct field.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1901} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1902} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~bit\textless{}8\textgreater{}~f8;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(2)~@match(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(3)~@match(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1910} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1911} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1938} +\noindent\mdline{1938}In the above example, the \mdline{1938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1938} annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs.%mdk + +%mdk-data-line={1941} +\mdline{1941}Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a\mdline{1942}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1943} that resolves to a \mdline{1943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1943}, or a \mdline{1943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1943} where +one or more fields is a\mdline{1944}~\mdref{sec-user-defined-types}{user-defined type}\mdline{1944} that +resolves to a \mdline{1945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1945}. For each \mdline{1945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1945} that corresponds to a user-defined +type, the \mdline{1946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1946} field must be set to the appropriate value (\mdline{1946}i.e.\mdline{1946} the name +of the type).%mdk + +%mdk-data-line={1949} +\subsubsection{\mdline{1949}6.4.8.\hspace*{0.5em}\mdline{1949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}\label{sec-register}%mdk%mdk + +%mdk-data-line={1951} +\noindent\mdline{1951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1951} messages are used to specify all possible instances of Register PSA +externs.%mdk + +%mdk-data-line={1954} +\mdline{1954}Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime.%mdk + +%mdk-data-line={1958} +\mdline{1958}The \mdline{1958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1958} message defines the following fields:%mdk + +%mdk-data-line={1960} +\begin{itemize}%mdk + +%mdk-data-line={1960} +\item{} +%mdk-data-line={1960} +\mdline{1960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1960}, a \mdline{1960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1960} message with the ID, name, and alias of this register +instance.%mdk%mdk + +%mdk-data-line={1963} +\item{} +%mdk-data-line={1963} +\mdline{1963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1963}, which specifies the data type stored by this register, expressed +using a \mdline{1964}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1964} message (see section on\mdline{1964}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary +P4 Types}\mdline{1965}).%mdk%mdk + +%mdk-data-line={1967} +\item{} +%mdk-data-line={1967} +\mdline{1967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1967}, an \mdline{1967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1967} value representing the total number of independent register +cells available.%mdk%mdk + +%mdk-data-line={1970} +\item{} +%mdk-data-line={1970} +\mdline{1970}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1970}, which indicates whether the register index has a +\mdline{1971}\mdref{sec-user-defined-types}{user-defined type}\mdline{1971}. This is useful for +\mdline{1972}\mdref{sec-psa-metadata-translation}{translation}\mdline{1972}. The underlying built-in type +must be a fixed-width unsigned bitstring (\mdline{1973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1973}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1975} +\subsubsection{\mdline{1975}6.4.9.\hspace*{0.5em}\mdline{1975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}\label{sec-digest}%mdk%mdk + +%mdk-data-line={1977} +\noindent\mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1977} messages are used to specify all possible instances of Packet Digest +PSA externs.%mdk + +%mdk-data-line={1980} +\mdline{1980}A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages.%mdk + +%mdk-data-line={1989} +\mdline{1989}The \mdline{1989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1989} message defines the following fields:%mdk + +%mdk-data-line={1991} +\begin{itemize}%mdk + +%mdk-data-line={1991} +\item{} +%mdk-data-line={1991} +\mdline{1991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1991}, a \mdline{1991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1991} message with the ID, name, and alias of this digest +instance.%mdk%mdk + +%mdk-data-line={1994} +\item{} +%mdk-data-line={1994} +\mdline{1994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1994}, which specifies the data type of an individual digest +notification using a \mdline{1995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1995} message (see section on\mdline{1995}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation +of Arbitrary P4 Types}\mdline{1996}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1998} +\subsubsection{\mdline{1998}6.4.10.\hspace*{0.5em}\mdline{1998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}\label{sec-p4info-extern}%mdk%mdk + +%mdk-data-line={2000} +\noindent\mdline{2000}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2000} messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one \mdline{2003}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2003} message instance in P4Info. The \mdline{2003}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2003} message defines +the following fields:%mdk + +%mdk-data-line={2006} +\begin{itemize}%mdk + +%mdk-data-line={2006} +\item{} +%mdk-data-line={2006} +\mdline{2006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{2006}, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the\mdline{2007}~\mdref{sec-id-allocation}{reserved +range}\mdline{2008} \mdline{2008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{}[0x81,~0xfe]}}}\mdline{2008}. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture.%mdk%mdk + +%mdk-data-line={2013} +\item{} +%mdk-data-line={2013} +\mdline{2013}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_name}}}\mdline{2013}, which specifies the fully-qualified P4 name of the extern +type.%mdk%mdk + +%mdk-data-line={2016} +\item{} +%mdk-data-line={2016} +\mdline{2016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instances}}}\mdline{2016}, a repeated field of \mdline{2016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{2016} Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +\mdline{2018}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{2018} in turn defines the following fields:%mdk + +%mdk-data-line={2020} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2020} +\item\mdline{2020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{2020}, a \mdline{2020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{2020} message with the ID, name, and alias of this digest +instance.%mdk + +%mdk-data-line={2022} +\item\mdline{2022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{2022}, an \mdline{2022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{2022} Protobuf message\mdline{2022}~[\mdcite{protoany}{31}]\mdline{2022} which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for \mdline{2024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{2024} should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on\mdline{2026}~\mdref{sec-extending-p4runtime}{Extending +P4Runtime for non-PSA Architectures}\mdline{2027} for more +information.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2030} +\noindent\mdline{2030}If the P4 program does not include any instance of a given extern type, the +\mdline{2031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2031} message instance for that type should be omitted from the P4Info.%mdk + +%mdk-data-line={2033} +\subsection{\mdline{2033}6.5.\hspace*{0.5em}\mdline{2033}Support for Arbitrary P4 Types with P4TypeInfo}\label{sec-support-for-arbitrary-p4-types-with-p4typeinfo}%mdk%mdk + +%mdk-data-line={2035} +\noindent\mdline{2035}See section on\mdline{2035}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary P4 +Types}\mdline{2036}.%mdk + +%mdk-data-line={2038} +\section{\mdline{2038}7.\hspace*{0.5em}\mdline{2038}P4 Forwarding-Pipeline Configuration}\label{sec-p4-fwd-pipe-config}%mdk%mdk + +%mdk-data-line={2040} +\noindent\mdline{2040}The \mdline{2040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2040} captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the \mdline{2042}\textquotedblleft{}Device Configuration\textquotedblright{}\mdline{2042} and sometimes also referred to as +the \mdline{2043}\textquotedblleft{}P4 Blob\textquotedblright{}\mdline{2043}. It is defined as:%mdk + +%mdk-data-line={2045} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2046} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ForwardingPipelineConfig~\{\\ +~~config.P{\mdcolor{purple}4}Info~p4info~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~p4\_device\_config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}message}}~Cookie~\{\\ +~~~~{\bfseries{\mdcolor{navy}uint64}}~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~\}\\ +~~Cookie~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2056} +\noindent\mdline{2056}The \mdline{2056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{2056} field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic.%mdk + +%mdk-data-line={2059} +\mdline{2059}The \mdline{2059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{2059} is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new \mdline{2061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2061} on that target.%mdk + +%mdk-data-line={2063} +\mdline{2063}The \mdline{2063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{2063} field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a \mdline{2068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{2068} RPC. +When writing the config via a \mdline{2069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{2069} RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present.%mdk + +%mdk-data-line={2073} +\section{\mdline{2073}8.\hspace*{0.5em}\mdline{2073}General Principles for Message Formatting}\label{sec-general-principles-for-message-formatting}%mdk%mdk + +%mdk-data-line={2075} +\subsection{\mdline{2075}8.1.\hspace*{0.5em}\mdline{2075}Set / Unset Protobuf Field}\label{sec-set-unset-protobuf-field}%mdk%mdk + +%mdk-data-line={2077} +\noindent\mdline{2077}In Protobuf version 3 (\mdline{2077}\emph{proto3}\mdline{2077}), the default value for a message field is +\mdline{2078}\textquotedblleft{}unset\textquotedblright{}\mdline{2078}~[\mdcite{protodefaults}{4}]\mdline{2078}. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +\mdline{2083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2083} message, an \mdline{2083}\textquotedblleft{}unset\textquotedblright{}\mdline{2083} \mdline{2083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2083} field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the \mdline{2085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2085} message field is +set, a single entry will be read.%mdk + +%mdk-data-line={2088} +\mdline{2088}Let\mdline{2088}'\mdline{2088}s look at the counter example in more details. Based on this specification +document, the C++ server code which processes \mdline{2089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2089} messages may look +like this:%mdk + +%mdk-data-line={2091} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2092} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}auto}}~*counter\_entry~=~...\\ +{\bfseries{\mdcolor{navy}if}}~(counter\_entry-\textgreater{}has\_index())~\{\\ +~~{\bfseries{\mdcolor{navy}auto}}~index~=~counter\_entry-\textgreater{}index().index();\\ +~~read\_one\_entry(counter\_entry-\textgreater{}id(),~index);\\ +\}~{\bfseries{\mdcolor{navy}else}}~\{\\ +~~read\_all\_entries(counter\_entry-\textgreater{}id());\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2101} +\begin{enumerate}%mdk + +%mdk-data-line={2101} +\item{} +%mdk-data-line={2101} +\mdline{2101}Reading a single counter entry at index 0 in the counter array with id +\mdline{2102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textless{}id\textgreater{}}}}\mdline{2102}:%mdk + +%mdk-data-line={2103} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2103} +\item\mdline{2103}Here is the C++ client code: + +%mdk-data-line={2104} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2105} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});\\ +entry.mutable\_index();\\ +{\mdcolor{darkgreen}//~The~above~line~sets~the~index~field;~it~is~equivalent~to:}\\ +{\mdcolor{darkgreen}//~auto~*index~=~entry.mutable\_index();}\\ +{\mdcolor{darkgreen}//~index-\textgreater{}set\_index(0);}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2112} +\item\mdline{2112}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2113} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2114} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}\\ +index~\{\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2117} +\item\mdline{2117}\textbf{Expected behavior}\mdline{2117}: Counter entry at index 0 is read. Notice that the +\mdline{2118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2118} subfield is missing under the \mdline{2118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2118} field message of +\mdline{2119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2119} in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2124} +\item{} +%mdk-data-line={2124} +\mdline{2124}Reading all counter entries by leaving the \mdline{2124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2124} field unset%mdk + +%mdk-data-line={2125} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2125} +\item\mdline{2125}Here is the C++ client code: + +%mdk-data-line={2126} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2127} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2130} +\item\mdline{2130}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2131} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2132} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2134} +\item\mdline{2134}\textbf{Expected behavior}\mdline{2134}: All counter entries for the provided counter +instance are read. Notice that the \mdline{2135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2135} message field is unset (default +value) and is therefore omitted from the textual representation of the +message.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={2139} +\subsection{\mdline{2139}8.2.\hspace*{0.5em}\mdline{2139}Read-Write Symmetry}\label{sec-read-write-symmetry}%mdk%mdk + +%mdk-data-line={2141} +\noindent\mdline{2141}The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example:%mdk + +%mdk-data-line={2147} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2148} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}intended\_value~=~value\\ +\\ +status~=~server.write(intended\_value,~p4\_entity)\\ +observed\_value~=~server.read(p4\_entity)\\ +\\ +assert(intended\_value~==~observed\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2156} +\noindent\mdline{2156}To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If \mdline{2160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{2160} RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol\mdline{2163}'\mdline{2163}s complexities to the client implementations.%mdk + +%mdk-data-line={2165} +\mdline{2165}In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the \mdline{2168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2168} fields in a \mdline{2168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2168} message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +\mdline{2171}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MessageDifferencer}}}\mdline{2171} class\mdline{2171}~[\mdcite{protomessagedifferencer}{36}]\mdline{2171} included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance.%mdk + +%mdk-data-line={2176} +\subsection{\mdline{2176}8.3.\hspace*{0.5em}\mdline{2176}Zero as Reserved Value}\label{sec-zero-as-reserved-value}%mdk%mdk + +%mdk-data-line={2178} +\noindent\mdline{2178}p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a \mdline{2179}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{2179}. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a \mdline{2182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{2182} or a \mdline{2182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfigRequest}}}\mdline{2182}.%mdk + +%mdk-data-line={2184} +\subsection{\mdline{2184}8.4.\hspace*{0.5em}\mdline{2184}Bytestrings}\label{sec-bytestrings}%mdk%mdk + +%mdk-data-line={2186} +\noindent\mdline{2186}P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (\mdline{2188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2188}) or signed (\mdline{2188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2188}), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +\mdline{2191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2191} Protobuf type. The correct bitwidth\mdline{2191} \mdline{2191}\textemdash{}\mdline{2191} as per the P4 program\mdline{2191} \mdline{2191}\textemdash{}\mdline{2191} of +each integer variable exposed through P4Runtime is specified in the P4Info +message.%mdk + +%mdk-data-line={2195} +\mdline{2195}The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals:%mdk + +%mdk-data-line={2198} +\begin{itemize}%mdk + +%mdk-data-line={2198} +\item{} +%mdk-data-line={2198} +\mdline{2198}It ensures that a properly encoded binary string\mdline{2198}'\mdline{2198}s integer value conforms +to the P4Info-specified bitwidth.%mdk%mdk + +%mdk-data-line={2201} +\item{} +%mdk-data-line={2201} +\mdline{2201}It supports\mdline{2201}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2201}.%mdk%mdk + +%mdk-data-line={2203} +\item{} +%mdk-data-line={2203} +\mdline{2203}It helps facilitate non-disruptive P4 program updates.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2205} +\noindent\mdline{2205}In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type \mdline{2210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2210} and/or \mdline{2210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2210}.%mdk + +%mdk-data-line={2212} +\mdline{2212}Note that this representation does \mdline{2212}\emph{not}\mdline{2212} make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range.%mdk + +%mdk-data-line={2221} +\mdline{2221}In the P4Runtime API version 1.0, values of table key fields, action parameters, +and fields in packet-in and packet-out headers between a device and the +controller (see\mdline{2223}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{2223}), may not be of type \mdline{2223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2223}. +The rules for encoding signed values thus only apply to messages of type +\mdline{2225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2225} (see\mdline{2225}~\mdref{sec-p4data-in-p4runtime-proto}{8.5.3}\mdline{2225}).%mdk + +%mdk-data-line={2227} +\mdline{2227}For a value of type \mdline{2227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2227}, the fewest number of bits required to represent +the integer value \mdline{2228}$V > 0$\mdline{2228} is the smallest integer \mdline{2228}$A$\mdline{2228} such that \mdline{2228}$V \leq 2^A -1$\mdline{2229}.%mdk + +%mdk-data-line={2231} +\mdline{2231}For a value of type \mdline{2231}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2231}, the fewest number of bits required to represent +the integer value \mdline{2232}$V \neq 0$\mdline{2232} in 2\mdline{2232}'\mdline{2232}s complement form is the smallest integer \mdline{2232}$A$\mdline{2232} +such that \mdline{2233}$-2^{A-1} \leq V \leq 2^{A-1} - 1$\mdline{2233}.%mdk + +%mdk-data-line={2235} +\mdline{2235}As a special case, define that the value \mdline{2235}$V=0$\mdline{2235} requires at least \mdline{2235}$A=1$\mdline{2235} bit to +represent, regardless of whether it is signed or unsigned.%mdk + +%mdk-data-line={2238} +\mdline{2238}The shortest possible binary string for an integer \mdline{2238}$V$\mdline{2238} that needs \mdline{2238}$A$\mdline{2238} bits to +represent it is computed as:%mdk + +%mdk-data-line={2240} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2241} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size~=~floor(({\mdcolor{teal}A}~+~{\mdcolor{purple}7})~/~{\mdcolor{purple}8})}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2244} +\noindent\mdline{2244}Binary strings with the byte length computed as \mdline{2244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2244} promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies.%mdk + +%mdk-data-line={2248} +\mdline{2248}Any additional bits in the bytes sent for an unsigned integer value (type +\mdline{2249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2249}) must be 0. If additional bytes are transmitted above the +\mdline{2250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2250} minimum required, they must be filled with 0.%mdk + +%mdk-data-line={2252} +\mdline{2252}Any additional bits in the bytes sent for a signed integer value (type \mdline{2252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2252}) +must be copies of the sign bit, \mdline{2253}i.e.\mdline{2253} 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +\mdline{2255}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2255} minimum required, they must be filled with copies of the +sign bit, \mdline{2256}i.e.\mdline{2256} 0 for non-negative values, or 0xff for negative values. In 2\mdline{2256}'\mdline{2256}s +complement representation, this is called \mdline{2257}\textquotedblleft{}sign extension\textquotedblright{}\mdline{2257}, and leaves the +numeric value represented unchanged.%mdk + +%mdk-data-line={2260} +\mdline{2260}Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value.%mdk + +%mdk-data-line={2266} +\mdline{2266}For a received bitstring expected to fit within a \mdline{2266}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2266} type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring\mdline{2268}'\mdline{2268}s width is \mdline{2268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2268} bits or less.%mdk + +%mdk-data-line={2270} +\mdline{2270}For a received bitstring expected to fit within an \mdline{2270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2270} type, the value it +represents is in range if, after \mdline{2271}\textquotedblleft{}undoing sign extension\textquotedblright{}\mdline{2271}, the remaining bit +string\mdline{2272}'\mdline{2272}s width is \mdline{2272}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2272} bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other.%mdk + +%mdk-data-line={2278} +\mdline{2278}If the string\mdline{2278}'\mdline{2278}s byte length is zero, the server always rejects the string.%mdk + +%mdk-data-line={2280} +\mdline{2280}When the server rejects a binary string due to any of the previous criteria, +it returns an \mdline{2281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2281} error.%mdk + +%mdk-data-line={2283} +\mdline{2283}For all binary strings, P4Runtime uses big-endian (\mdline{2283}i.e.\mdline{2283} network) byte-order. +For signed integer values (\mdline{2284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2284} P4 type), P4Runtime uses the same two\mdline{2284}'\mdline{2284}s +complement bitwise representation as P4. Table\mdline{2285}~\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}}\mdline{2285} +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above.%mdk + +%mdk-data-line={2289} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2291} P4 type}}&\multicolumn{1}{|c}{{\bfseries\mdline{2291} Integer value}}&\multicolumn{1}{|c}{{\bfseries\mdline{2291} P4Runtime binary string}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2291} Read-write symmetry}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2293} \mdline{2293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2293}}&\multicolumn{1}{|l}{\mdline{2293} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2293} \mdline{2293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2293}}&\multicolumn{1}{|l|}{\mdline{2293} yes}\\ +\multicolumn{1}{|l}{\mdline{2294} \mdline{2294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2294}}&\multicolumn{1}{|l}{\mdline{2294} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2294} \mdline{2294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2294}}&\multicolumn{1}{|l|}{\mdline{2294} no}\\ +\multicolumn{1}{|l}{\mdline{2295} \mdline{2295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2295}}&\multicolumn{1}{|l}{\mdline{2295} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2295} \mdline{2295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2295}}&\multicolumn{1}{|l|}{\mdline{2295} yes}\\ +\multicolumn{1}{|l}{\mdline{2296} \mdline{2296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2296}}&\multicolumn{1}{|l}{\mdline{2296} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2296} \mdline{2296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x30\textbackslash{}x64}}}\mdline{2296}}&\multicolumn{1}{|l|}{\mdline{2296} yes}\\ +\multicolumn{1}{|l}{\mdline{2297} \mdline{2297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2297}}&\multicolumn{1}{|l}{\mdline{2297} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2297} \mdline{2297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x30\textbackslash{}x64}}}\mdline{2297}}&\multicolumn{1}{|l|}{\mdline{2297} no}\\ +\multicolumn{1}{|l}{\mdline{2298} \mdline{2298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2298}}&\multicolumn{1}{|l}{\mdline{2298} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2298} \mdline{2298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2298}}&\multicolumn{1}{|l|}{\mdline{2298} no}\\ +\multicolumn{1}{|l}{\mdline{2299} \mdline{2299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2299}}&\multicolumn{1}{|l}{\mdline{2299} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2299} \mdline{2299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2299}}&\multicolumn{1}{|l|}{\mdline{2299} yes}\\ +\multicolumn{1}{|l}{\mdline{2300} \mdline{2300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2300}}&\multicolumn{1}{|l}{\mdline{2300} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2300} \mdline{2300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00\textbackslash{}x63}}}\mdline{2300}}&\multicolumn{1}{|l|}{\mdline{2300} no}\\ +\multicolumn{1}{|l}{\mdline{2301} \mdline{2301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2301}}&\multicolumn{1}{|l}{\mdline{2301} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2301} \mdline{2301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2301}}&\multicolumn{1}{|l|}{\mdline{2301} yes}\\ +\multicolumn{1}{|l}{\mdline{2302} \mdline{2302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2302}}&\multicolumn{1}{|l}{\mdline{2302} \mdline{2302}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2302} \mdline{2302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x9d}}}\mdline{2302}}&\multicolumn{1}{|l|}{\mdline{2302} yes}\\ +\multicolumn{1}{|l}{\mdline{2303} \mdline{2303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2303}}&\multicolumn{1}{|l}{\mdline{2303} \mdline{2303}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2303} \mdline{2303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xff\textbackslash{}x9d}}}\mdline{2303}}&\multicolumn{1}{|l|}{\mdline{2303} no}\\ +\multicolumn{1}{|l}{\mdline{2304} \mdline{2304}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2304}}&\multicolumn{1}{|l}{\mdline{2304} \mdline{2304}-739 (-0x2e3)}&\multicolumn{1}{|l}{\mdline{2304} \mdline{2304}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xfd\textbackslash{}x1d}}}\mdline{2304}}&\multicolumn{1}{|l|}{\mdline{2304} yes}\\ +\multicolumn{1}{|l}{\mdline{2305} \mdline{2305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2305}}&\multicolumn{1}{|l}{\mdline{2305} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2305} \mdline{2305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00}}}\mdline{2305}}&\multicolumn{1}{|l|}{\mdline{2305} no}\\ +\multicolumn{1}{|l}{\mdline{2306} \mdline{2306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2306}}&\multicolumn{1}{|l}{\mdline{2306} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2306} \mdline{2306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00}}}\mdline{2306}}&\multicolumn{1}{|l|}{\mdline{2306} yes}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2308} +\mdhr{}%mdk + +%mdk-data-line={2309} +\noindent\mdline{2309}\mdcaption{\textbf{Table~\mdcaptionlabel{4}.}~\mdcaptiontext{Examples of Valid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-valid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2311} +\mdline{2311}Table\mdline{2311}~\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}}\mdline{2311} shows some examples of invalid +P4Runtime binary strings:%mdk + +%mdk-data-line={2314} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2316} P4 type}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2316} P4Runtime binary string}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2318} \mdline{2318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2318}}&\multicolumn{1}{|l|}{\mdline{2318} \mdline{2318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x63}}}\mdline{2318}}\\ +\multicolumn{1}{|l}{\mdline{2319} \mdline{2319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2319}}&\multicolumn{1}{|l|}{\mdline{2319} \mdline{2319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2319}}\\ +\multicolumn{1}{|l}{\mdline{2320} \mdline{2320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2320}}&\multicolumn{1}{|l|}{\mdline{2320} \mdline{2320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2320}}\\ +\multicolumn{1}{|l}{\mdline{2321} \mdline{2321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2321}}&\multicolumn{1}{|l|}{\mdline{2321} \mdline{2321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x10\textbackslash{}x63}}}\mdline{2321}}\\ +\multicolumn{1}{|l}{\mdline{2322} \mdline{2322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2322}}&\multicolumn{1}{|l|}{\mdline{2322} \mdline{2322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2322}}\\ +\multicolumn{1}{|l}{\mdline{2323} \mdline{2323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2323}}&\multicolumn{1}{|l|}{\mdline{2323} \mdline{2323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x40\textbackslash{}x63}}}\mdline{2323}}\\ +\multicolumn{1}{|l}{\mdline{2324} \mdline{2324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2324}}&\multicolumn{1}{|l|}{\mdline{2324} \mdline{2324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x9d}}}\mdline{2324}}\\ +\multicolumn{1}{|l}{\mdline{2325} \mdline{2325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2325}}&\multicolumn{1}{|l|}{\mdline{2325} \mdline{2325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x8d\textbackslash{}x1d}}}\mdline{2325}}\\ +\multicolumn{1}{|l}{\mdline{2326} \mdline{2326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2326}}&\multicolumn{1}{|l|}{\mdline{2326} \mdline{2326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2326}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2328} +\mdhr{}%mdk + +%mdk-data-line={2329} +\noindent\mdline{2329}\mdcaption{\textbf{Table~\mdcaptionlabel{5}.}~\mdcaptiontext{Examples of Invalid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-invalid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2331} +\mdline{2331}As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from \mdline{2336}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2336} to \mdline{2336}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2336}, a server +running the \mdline{2337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2337} version of the P4 program will accept requests from +clients that remain on the \mdline{2338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2338} P4Runtime version.%mdk + +%mdk-data-line={2340} +\mdline{2340}Despite the server\mdline{2340}'\mdline{2340}s binary string flexibility for P4 program update support, +the client and server must both remain aware of the +\mdline{2342}\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2342} +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values.%mdk + +%mdk-data-line={2347} +\mdline{2347}Representation of variable-length integer values (\mdline{2347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2347} P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the \mdline{2349}\emph{dynamic-length}\mdline{2349} of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an \mdline{2352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2352} error code otherwise.%mdk + +%mdk-data-line={2354} +\subsection{\mdline{2354}8.5.\hspace*{0.5em}\mdline{2354}Representation of Arbitrary P4 Types}\label{sec-representation-of-arbitrary-p4-types}%mdk%mdk + +%mdk-data-line={2356} +\subsubsection{\mdline{2356}8.5.1.\hspace*{0.5em}\mdline{2356}Problem Statement}\label{sec-problem-statement}%mdk%mdk + +%mdk-data-line={2358} +\noindent\mdline{2358}The P4\mdline{2358}\mdsub{16}\mdline{2358} language includes more complex types than just binary strings +\mdline{2359}[\mdcite{p4complextypes}{3}]\mdline{2359}. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table\mdline{2362}~\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}}\mdline{2362} shows the different +P4\mdline{2363}\mdsub{16}\mdline{2363} types and how they are allowed to be used, as per the P4\mdline{2363}\mdsub{16}\mdline{2363} +specification.%mdk + +%mdk-data-line={2366} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|l}{{\bfseries\mdline{2368}}}&\multicolumn{3}{|c|}{{\bfseries\mdline{2368} Container type}}\\ +\cmidrule{2-2}\cmidrule{3-3}\cmidrule{4-4} +\multicolumn{1}{|l}{{\bfseries\mdline{2370} Element type}}&\multicolumn{1}{|l}{{\bfseries\mdline{2370} header}}&\multicolumn{1}{|l}{{\bfseries\mdline{2370} header\mdline{2370}\_\mdline{2370}union}}&\multicolumn{1}{|l|}{{\bfseries\mdline{2370} struct or tuple}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2372} \mdline{2372}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2372}}&\multicolumn{1}{|l}{\mdline{2372} allowed}&\multicolumn{1}{|l}{\mdline{2372} error}&\multicolumn{1}{|l|}{\mdline{2372} allowed}\\ +\multicolumn{1}{|l}{\mdline{2373} \mdline{2373}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2373}}&\multicolumn{1}{|l}{\mdline{2373} allowed}&\multicolumn{1}{|l}{\mdline{2373} error}&\multicolumn{1}{|l|}{\mdline{2373} allowed}\\ +\multicolumn{1}{|l}{\mdline{2374} \mdline{2374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2374}}&\multicolumn{1}{|l}{\mdline{2374} allowed}&\multicolumn{1}{|l}{\mdline{2374} error}&\multicolumn{1}{|l|}{\mdline{2374} allowed}\\ +\multicolumn{1}{|l}{\mdline{2375} \mdline{2375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int}}}\mdline{2375}}&\multicolumn{1}{|l}{\mdline{2375} error}&\multicolumn{1}{|l}{\mdline{2375} error}&\multicolumn{1}{|l|}{\mdline{2375} error}\\ +\multicolumn{1}{|l}{\mdline{2376} \mdline{2376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}void}}}\mdline{2376}}&\multicolumn{1}{|l}{\mdline{2376} error}&\multicolumn{1}{|l}{\mdline{2376} error}&\multicolumn{1}{|l|}{\mdline{2376} error}\\ +\multicolumn{1}{|l}{\mdline{2377} \mdline{2377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2377}}&\multicolumn{1}{|l}{\mdline{2377} error}&\multicolumn{1}{|l}{\mdline{2377} error}&\multicolumn{1}{|l|}{\mdline{2377} allowed}\\ +\multicolumn{1}{|l}{\mdline{2378} \mdline{2378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_kind}}}\mdline{2378}}&\multicolumn{1}{|l}{\mdline{2378} error}&\multicolumn{1}{|l}{\mdline{2378} error}&\multicolumn{1}{|l|}{\mdline{2378} error}\\ +\multicolumn{1}{|l}{\mdline{2379} \mdline{2379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2379}}&\multicolumn{1}{|l}{\mdline{2379} error}&\multicolumn{1}{|l}{\mdline{2379} error}&\multicolumn{1}{|l|}{\mdline{2379} allowed}\\ +\multicolumn{1}{|l}{\mdline{2380} \mdline{2380}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2380}}&\multicolumn{1}{|l}{\mdline{2380} allowed\mdline{2380}\mdfootnote{1}{%mdk-data-line={2390} +%mdk-data-line={2390} +\noindent\mdline{2390}an \mdline{2390}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2390} type used as a field in a \mdline{2390}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2390} must specify a +underlying type and representation for \mdline{2391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2391} elements.%mdk +\label{fn-enum_header}%mdk%mdk +}\mdline{2380}}&\multicolumn{1}{|l}{\mdline{2380} error}&\multicolumn{1}{|l|}{\mdline{2380} allowed}\\ +\multicolumn{1}{|l}{\mdline{2381} \mdline{2381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2381}}&\multicolumn{1}{|l}{\mdline{2381} error}&\multicolumn{1}{|l}{\mdline{2381} allowed}&\multicolumn{1}{|l|}{\mdline{2381} allowed}\\ +\multicolumn{1}{|l}{\mdline{2382} header stack}&\multicolumn{1}{|l}{\mdline{2382} error}&\multicolumn{1}{|l}{\mdline{2382} error}&\multicolumn{1}{|l|}{\mdline{2382} allowed}\\ +\multicolumn{1}{|l}{\mdline{2383} \mdline{2383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2383}}&\multicolumn{1}{|l}{\mdline{2383} error}&\multicolumn{1}{|l}{\mdline{2383} error}&\multicolumn{1}{|l|}{\mdline{2383} allowed}\\ +\multicolumn{1}{|l}{\mdline{2384} \mdline{2384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2384}}&\multicolumn{1}{|l}{\mdline{2384} error}&\multicolumn{1}{|l}{\mdline{2384} error}&\multicolumn{1}{|l|}{\mdline{2384} allowed}\\ +\multicolumn{1}{|l}{\mdline{2385} \mdline{2385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2385}}&\multicolumn{1}{|l}{\mdline{2385} error}&\multicolumn{1}{|l}{\mdline{2385} error}&\multicolumn{1}{|l|}{\mdline{2385} allowed}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2387} +\mdhr{}%mdk + +%mdk-data-line={2388} +\noindent\mdline{2388}\mdcaption{\textbf{Table~\mdcaptionlabel{6}.}~\mdcaptiontext{P4 Type Usage}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-type-usage}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2393} +\mdline{2393}For example, the following P4\mdline{2393}\mdsub{16}\mdline{2393} objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects.%mdk + +%mdk-data-line={2396} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2397} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}{\bfseries{\mdcolor{navy}tuple}}\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}4}\textgreater{},~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~\textgreater{}~\textgreater{}()~digest\_complex;\\ +digest\_complex.pack(\{~hdr.ipv4.version,~hdr.ipv4.protocol~\});\\ +{\mdcolor{darkgreen}//~...}\\ +{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2407} +\noindent\mdline{2407}One solution would be to use only binary string (\mdline{2407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2407} type) in +p4runtime.proto and to define a custom serialization format for complex P4\mdline{2408}\mdsub{16}\mdline{2408} +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P4\mdline{2415}\mdsub{16}\mdline{2415} types.%mdk + +%mdk-data-line={2417} +\subsubsection{\mdline{2417}8.5.2.\hspace*{0.5em}\mdline{2417}P4 Type Specifications in p4info.proto}\label{sec-p4-type-specifications-in-p4infoproto}%mdk%mdk + +%mdk-data-line={2419} +\noindent\mdline{2419}In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type \mdline{2423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip\_t}}}\mdline{2423}, which is a header union with 2 possible headers: +\mdline{2424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4}}}\mdline{2424} with type \mdline{2424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4\_t}}}\mdline{2424} and \mdline{2424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6}}}\mdline{2424} with type \mdline{2424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6\_t}}}\mdline{2424}. Similarly, they need to +know the field layout for both of these header types.%mdk + +%mdk-data-line={2427} +\mdline{2427}To achieve this we introduce 2 main Protobuf messages: \mdline{2427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2427} and +\mdline{2428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2428}.%mdk + +%mdk-data-line={2430} +\mdline{2430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2430} is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P4\mdline{2431}\mdsub{16}\mdline{2431} program. These +named types are \mdline{2432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2432}, \mdline{2432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2432}, \mdline{2432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2432}, \mdline{2432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2432} and +\mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2433}; for each of these we have a type specification message, +respectively \mdline{2434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructTypeSpec}}}\mdline{2434}, \mdline{2434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderTypeSpec}}}\mdline{2434}, \mdline{2434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionTypeSpec}}}\mdline{2434}, +\mdline{2435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4EnumTypeSpec}}}\mdline{2435} and \mdline{2435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4SerializableEnumTypeSpec}}}\mdline{2435}. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. \mdline{2437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2437} also includes the list of parser errors for the program, as +a \mdline{2438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4ErrorTypeSpec}}}\mdline{2438} message.%mdk + +%mdk-data-line={2440} +\mdline{2440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2440} is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each \mdline{2442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2442} message corresponds to a compile-time type in the +original P4\mdline{2443}\mdsub{16}\mdline{2443} program (\mdline{2443}e.g.\mdline{2443} the type parameter of an extern). This +compile-time type is represented as a Protobuf \mdline{2444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2444}, which can be:%mdk + +%mdk-data-line={2446} +\begin{itemize}%mdk + +%mdk-data-line={2446} +\item{} +%mdk-data-line={2446} +\mdline{2446}a string representing the name of the type in case of a named type (\mdline{2446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2446}, +\mdline{2447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2447}, \mdline{2447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2447}, \mdline{2447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2447}, \mdline{2447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2447} or user-defined \mdline{2447}\textquotedblleft{}new\textquotedblright{}\mdline{2447} +\mdline{2448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2448}),%mdk%mdk + +%mdk-data-line={2450} +\item{} +%mdk-data-line={2450} +\mdline{2450}an empty Protobuf message for \mdline{2450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2450} and \mdline{2450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2450}, or%mdk%mdk + +%mdk-data-line={2452} +\item{} +%mdk-data-line={2452} +\mdline{2452}a Protobuf message for other anonymous types (\mdline{2452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2452}, \mdline{2452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2452}, \mdline{2452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2452}, +\mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2453} or stack). The \mdline{2453}\textquotedblleft{}binary string\textquotedblright{}\mdline{2453} types (\mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2453}, \mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2453}, and +\mdline{2454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2454}) are grouped together in the \mdline{2454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4BitstringLikeTypeSpec}}}\mdline{2454} message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf \mdline{2456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2456} +type).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2459} +\noindent\mdline{2459}For all P4\mdline{2459}\mdsub{16}\mdline{2459} compound types (\mdline{2459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2459}, \mdline{2459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2459}, \mdline{2459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2459}, and \mdline{2459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2459}), +the order of \mdline{2460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2460} in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P4\mdline{2462}\mdsub{16}\mdline{2462} declaration. The same goes for the order of members of an \mdline{2462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2462} +(serializable or not) or members of \mdline{2463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2463}.%mdk + +%mdk-data-line={2465} +\subsubsection{\mdline{2465}8.5.3.\hspace*{0.5em}\mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2465} in p4runtime.proto}\label{sec-p4data-in-p4runtime-proto}%mdk%mdk + +%mdk-data-line={2467} +\noindent\mdline{2467}P4Runtime uses the \mdline{2467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2467} message to represent values of arbitrary types. The +P4Runtime client must generate correct \mdline{2468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2468} messages based on the type +specification information included in P4Info. The \mdline{2469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2469} message was designed +to introduce little overhead compared to using binary strings in the most common +case (P4\mdline{2471}\mdsub{16}\mdline{2471} \mdline{2471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2471} type).%mdk + +%mdk-data-line={2473} +\mdline{2473}Just like its P4Info counterpart\mdline{2473} \mdline{2473}- \mdline{2473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2473} \mdline{2473}-, \mdline{2473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2473} uses a Protobuf +\mdline{2474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2474} to represent all possible values.%mdk + +%mdk-data-line={2476} +\mdline{2476}We define a canonical representation for \mdline{2476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2476} messages\mdline{2476} \mdline{2476}\textemdash{}\mdline{2476} therefore +guaranteeing read-write symmetry\mdline{2477} \mdline{2477}\textemdash{}\mdline{2477} by introducing the following requirements:%mdk + +%mdk-data-line={2479} +\begin{itemize}%mdk + +%mdk-data-line={2479} +\item{} +%mdk-data-line={2479} +\mdline{2479}The order of \mdline{2479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2479} in \mdline{2479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructLike}}}\mdline{2479} and the order of \mdline{2479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2479} in +\mdline{2480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2480} must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P4\mdline{2481}\mdsub{16}\mdline{2481} type +declaration.%mdk%mdk + +%mdk-data-line={2484} +\item{} +%mdk-data-line={2484} +\mdline{2484}An invalid header is represented by a \mdline{2484}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2484} message where the \mdline{2484}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_valid}}}\mdline{2484} +field is false and the \mdline{2485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2485} repeated field is empty.%mdk%mdk + +%mdk-data-line={2487} +\item{} +%mdk-data-line={2487} +\mdline{2487}An invalid header union (\mdline{2487}i.e.\mdline{2487} all headers in the union are invalid) is +represented by a \mdline{2488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnion}}}\mdline{2488} message where the \mdline{2488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header\_name}}}\mdline{2488} is the +empty string (default value for the field) and the \mdline{2489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header}}}\mdline{2489} is unset.%mdk%mdk + +%mdk-data-line={2491} +\item{} +%mdk-data-line={2491} +\mdline{2491}The order of \mdline{2491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2491} in \mdline{2491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStack}}}\mdline{2491} and \mdline{2491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStack}}}\mdline{2491} is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the \mdline{2493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2493} field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding \mdline{2495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStackTypeSpec}}}\mdline{2495} or +\mdline{2496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStackTypeSpec}}}\mdline{2496} message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2498} +\subsubsection{\mdline{2498}8.5.4.\hspace*{0.5em}\mdline{2498}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={2500} +\noindent\mdline{2500}Let\mdline{2500}'\mdline{2500}s look at the Register example again:%mdk + +%mdk-data-line={2502} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2503} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2510} +\noindent\mdline{2510}Here\mdline{2510}'\mdline{2510}s the corresponding entry in the P4Info message:%mdk + +%mdk-data-line={2512} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2513} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}registers~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}369119267}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~\}\\ +~~type\_spec~\{\\ +~~~~header\_union~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~size:~{\mdcolor{purple}128}\\ +\}\\ +type\_info~\{\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~header\_unions~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2569} +\noindent\mdline{2569}Here\mdline{2569}'\mdline{2569}s a \mdline{2569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.WriteRequest}}}\mdline{2569} to set the value of \mdline{2569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_ip{}[12]}}}\mdline{2569}:%mdk + +%mdk-data-line={2571} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2572} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}update~\{\\ +~~type:~INSERT\\ +~~entity~\{\\ +~~~~register\_entry~\{\\ +~~~~~~register\_id:~{\mdcolor{purple}369119267}\\ +~~~~~~index~\{\\ +~~~~~~~~index:~{\mdcolor{purple}12}\\ +~~~~~~\}\\ +~~~~~~data~\{\\ +~~~~~~~~header\_union~\{\\ +~~~~~~~~~~valid\_header\_name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~~~valid\_header~\{\\ +~~~~~~~~~~~~is\_valid:~true\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x04}{\mdcolor{maroon}"}\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{darkgreen}\#~...}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2595} +\subsubsection{\mdline{2595}8.5.5.\hspace*{0.5em}\mdline{2595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2595}, serializable \mdline{2595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2595} and \mdline{2595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}\label{sec-enum-serializable-enum-and-error}%mdk%mdk + +%mdk-data-line={2597} +\noindent\mdline{2597}P4\mdline{2597}\mdsub{16}\mdline{2597} supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or \mdline{2598}\textquotedblleft{}unsafe\textquotedblright{}\mdline{2598} enum) +\mdline{2599}[\mdcite{p4enums}{5}]\mdline{2599}. For \mdline{2599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2599} types with no underlying type\mdline{2599} \mdline{2599}\textemdash{}\mdline{2599} as well as \mdline{2599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2599} \mdline{2599}\textemdash{}\mdline{2599} +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in \mdline{2602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2602} to represent \mdline{2602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2602} and +\mdline{2603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2603} values.%mdk + +%mdk-data-line={2605} +\mdline{2605}Serializable \mdline{2605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2605} types have an underlying fixed-width unsigned integer +representation (\mdline{2606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2606}). All named enum members must be assigned an integer +value by the P4 programmer, but \mdline{2607}\emph{not all}\mdline{2607} valid numeric values for the +underlying type need to have a corresponding name. \mdline{2608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2608} includes the +mapping between entry name and entry value. When providing serializable enum +values through \mdline{2610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2610}, one must use the assigned integer value (\mdline{2610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum\_value}}}\mdline{2610} +bytestring field). P4Runtime does not provide a way for the client to use the +name\mdline{2612} \mdline{2612}\textemdash{}\mdline{2612} even when the enum member has one\mdline{2612} \mdline{2612}\textemdash{}\mdline{2612} instead of the value, as it makes +it easier for the server to respect the\mdline{2613}~\mdref{sec-read-write-symmetry}{read-write +symmetry}\mdline{2614} principle.%mdk + +%mdk-data-line={2616} +\subsubsection{\mdline{2616}8.5.6.\hspace*{0.5em}\mdline{2616}User-defined types}\label{sec-user-defined-types}%mdk%mdk + +%mdk-data-line={2618} +\noindent\mdline{2618}P4\mdline{2618}\mdsub{16}\mdline{2618} enables programmers to introduce new types\mdline{2618}~[\mdcite{p4newtypes}{11}]\mdline{2618}. While similar +to \mdline{2619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{2619}, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +\mdline{2622}\mdref{sec-psa-metadata-translation}{translation}\mdline{2622}. When introducing a new type, the +declaration can be annotated with \mdline{2623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2623} to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for\mdline{2625}~\mdref{sec-translation-of-port-numbers}{port numbers}\mdline{2625}, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. \mdline{2628}\textbf{The \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}} annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}})}\mdline{2630}. The type exposed to the control plane (referred to as the +\mdline{2631}\emph{controller\_type}\mdline{2631}) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a \mdline{2633}\emph{URI}\mdline{2633} (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the \mdline{2635}\emph{controller\_type}\mdline{2635} of the values exposed to the control plane. The +\mdline{2636}\emph{controller\_type}\mdline{2636} can be either \mdline{2636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2636} where \mdline{2636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2636} is any positive integer, or +\mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{2637}, or a positive integer \mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2637} which has the same meaning as \mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2637}. +Specifying just an integer is deprecated.%mdk + +%mdk-data-line={2640} +\mdline{2640}It is recommended that the URI includes at least the P4 architecture name and +the type name.%mdk + +%mdk-data-line={2643} +\mdline{2643}A \mdline{2643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2643} annotation need not have any effect if it is used to +annotate anything in a P4 program other than a \mdline{2644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2644} declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect.%mdk + +%mdk-data-line={2648} +\mdline{2648}User-defined types are specified using the \mdline{2648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{2648} message, which has +the following fields:%mdk + +%mdk-data-line={2651} +\begin{itemize}%mdk + +%mdk-data-line={2651} +\item{} +%mdk-data-line={2651} +\mdline{2651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}representation}}}\mdline{2651}, a Protobuf \mdline{2651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2651} specifying how values of this type are +exchanged between client and server; it can be either:%mdk + +%mdk-data-line={2654} +\begin{itemize}%mdk + +%mdk-data-line={2654} +\item{} +%mdk-data-line={2654} +\mdline{2654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2654}, if and only if no \mdline{2654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2654} annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 \mdline{2656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2656} declaration is itself a +user-defined type, \mdline{2657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2657} is obtained by \mdline{2657}\textquotedblleft{}walking\textquotedblright{}\mdline{2657} the chain of +\mdline{2658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2658} declarations recursively until a built-in type (\mdline{2658}e.g.\mdline{2658} \mdline{2658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2658}) is +found.%mdk%mdk + +%mdk-data-line={2661} +\item{} +%mdk-data-line={2661} +\mdline{2661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}translated\_type}}}\mdline{2661}, if and only if the P4 \mdline{2661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2661} declaration was annotated +with \mdline{2662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2662}. It is of type \mdline{2662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeTranslation}}}\mdline{2662}, +which itself has two fields\mdline{2663} \mdline{2663}\textemdash{}\mdline{2663} \mdline{2663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uri}}}\mdline{2663} and either \mdline{2663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_string}}}\mdline{2663} or +\mdline{2664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_bitwidth}}}\mdline{2664} \mdline{2664}\textemdash{}\mdline{2664}, which map to the two input parameters to the +annotation.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2667} +\item{} +%mdk-data-line={2667} +\mdline{2667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{2667}, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2670} +\noindent\mdline{2670}For example, an architecture\mdline{2670} \mdline{2670}\textemdash{}\mdline{2670} in this case PSA\mdline{2670} \mdline{2670}\textemdash{}\mdline{2670} may introduce a new type +for port numbers:%mdk + +%mdk-data-line={2672} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2673} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~string,~e.g.~"eth0".}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~32-bit~integer,~e.g.~0xffffffff.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{darkgreen}//~Same~as~above.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_32\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_32\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2686} +\noindent\mdline{2686}In this case, the P4Info message would include the following \mdline{2686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2686} +messages:%mdk + +%mdk-data-line={2689} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2690} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_string:~\{\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2727} +\noindent\mdline{2727}Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (\mdline{2728}e.g.\mdline{2728} through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over \mdline{2730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2730} to enable users +to overwrite annotations included as part of the P4 architecture definition.%mdk + +%mdk-data-line={2733} +\subsubsection{\mdline{2733}8.5.7.\hspace*{0.5em}\mdline{2733}Trade-off for v1.x Releases}\label{sec-trade-off-for-v1x-releases}%mdk%mdk + +%mdk-data-line={2735} +\noindent\mdline{2735}For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +\mdline{2736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2736} with \mdline{2736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2736} in the \mdline{2736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{2736} message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +\mdline{2739}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2739} to provide action parameter values and controller metadata +values. However \mdline{2740}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2740} is used whenever appropriate for PSA externs and we +encourage the use of \mdline{2741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2741} in architecture-specific extensions.%mdk + +%mdk-data-line={2743} +\mdline{2743}In order to support\mdline{2743}~\mdref{sec-psa-metadata-translation}{translation}\mdline{2743} for action +parameters and match fields, we include a \mdline{2744}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2744} field in +\mdline{2745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{2745}, \mdline{2745}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Action.Param}}}\mdline{2745} and +\mdline{2746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ControllerPacketMetadata.Metadata}}}\mdline{2746}. In addition, the \mdline{2746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2746} +field for all of these message types must abide by the following rule when +\mdline{2748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2748} names a translated user-defined type:%mdk + +%mdk-data-line={2750} +\begin{itemize}%mdk + +%mdk-data-line={2750} +\item{} +%mdk-data-line={2750} +\mdline{2750}If the \mdline{2750}\emph{controller\_type}\mdline{2750} is a fixed-width unsigned bitstring, the \mdline{2750}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2750} +field must be set to the bitwidth of the \mdline{2751}\emph{controller\_type}\mdline{2751}. This information +is redundant with the one included in the \mdline{2752}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2752} entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent.%mdk%mdk + +%mdk-data-line={2758} +\item{} +%mdk-data-line={2758} +\mdline{2758}Otherwise (\mdline{2758}i.e.\mdline{2758}, if the \mdline{2758}\emph{controller\_type}\mdline{2758} is a string), the \mdline{2758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2758} must +be \mdline{2759}\textquotedblleft{}unset\textquotedblright{}\mdline{2759}, which, in Protobuf version 3, is the same as setting the field to +0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2762} +\noindent\mdline{2762}For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types:%mdk + +%mdk-data-line={2764} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2765} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{navy}@}{\mdcolor{navy}name}{\mdcolor{maroon}(".t")}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~meta.port1:~exact;~~{\mdcolor{darkgreen}//~meta.port1~has~type~PortId\_String\_t}\\ +~~~~meta.port2:~exact;~~{\mdcolor{darkgreen}//~meta.port2~has~type~PortId\_Bit32\_t}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2783} +\noindent\mdline{2783}This table would have the following representation in the generated P4Info +message:%mdk + +%mdk-data-line={2785} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2786} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tables~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}34728461}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port1}{\mdcolor{maroon}"}\\ +~~~~{\mdcolor{darkgreen}\#~notice~that~bitwidth~is~unset}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port2}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~{\mdcolor{darkgreen}\#~...}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2814} +\section{\mdline{2814}9.\hspace*{0.5em}\mdline{2814}P4 Entity Messages}\label{sec-p4-entity-msgs}%mdk%mdk + +%mdk-data-line={2816} +\noindent\mdline{2816}P4Runtime covers P4 entities that are either part of the P4\mdline{2816}\mdsub{16}\mdline{2816} language, or +defined as PSA externs. The sections below describe the messages for each +supported entity.%mdk + +%mdk-data-line={2820} +\subsection{\mdline{2820}9.1.\hspace*{0.5em}\mdline{2820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}\label{sec-table-entry}%mdk%mdk + +%mdk-data-line={2822} +\noindent\mdline{2822}The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action\mdline{2824}'\mdline{2824}s +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification.%mdk + +%mdk-data-line={2830} +\mdline{2830}P4Runtime supports inserting, modifying, deleting and reading table entries with +the \mdline{2831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2831} entity, which has the following fields:%mdk + +%mdk-data-line={2833} +\begin{itemize}%mdk + +%mdk-data-line={2833} +\item{} +%mdk-data-line={2833} +\mdline{2833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2833}, which identifies the table instance; the \mdline{2833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2833} is determined +by the P4Info message.%mdk%mdk + +%mdk-data-line={2836} +\item{} +%mdk-data-line={2836} +\mdline{2836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2836}, a repeated field of \mdline{2836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2836} messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration.%mdk%mdk + +%mdk-data-line={2840} +\item{} +%mdk-data-line={2840} +\mdline{2840}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2840}, which indicates which of the table\mdline{2840}'\mdline{2840}s actions to execute in case of +match and with which argument values.%mdk%mdk + +%mdk-data-line={2843} +\item{} +%mdk-data-line={2843} +\mdline{2843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2843}, a 32-bit integer used to order entries when the table\mdline{2843}'\mdline{2843}s match key +includes an optional, ternary or range match.%mdk%mdk + +%mdk-data-line={2846} +\item{} +%mdk-data-line={2846} +\mdline{2846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2846}, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +\mdline{2850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{2850} field.%mdk%mdk + +%mdk-data-line={2852} +\item{} +%mdk-data-line={2852} +\mdline{2852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{2852}, an arbitrary \mdline{2852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2852} value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry.%mdk%mdk + +%mdk-data-line={2857} +\item{} +%mdk-data-line={2857} +\mdline{2857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2857}, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See\mdline{2858}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2859} section for more information.%mdk%mdk + +%mdk-data-line={2861} +\item{} +%mdk-data-line={2861} +\mdline{2861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2861}, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See\mdline{2862}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2863} section for more information.%mdk%mdk + +%mdk-data-line={2865} +\item{} +%mdk-data-line={2865} +\mdline{2865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2865}, a boolean flag which indicates whether the table entry is +the default entry for the table. See\mdline{2866}~\mdref{sec-default-entry}{Default entry}\mdline{2866} +section for more information.%mdk%mdk + +%mdk-data-line={2869} +\item{} +%mdk-data-line={2869} +\mdline{2869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2869} and \mdline{2869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2869}, which are two fields used to +implement idle-timeout support for the table, if applicable. See +\mdline{2871}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{2871} section for more information.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2873} +\noindent\mdline{2873}The \mdline{2873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2873} field must be set to a non-zero value if the match key includes a +ternary match (\mdline{2874}i.e.\mdline{2874} in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an \mdline{2875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{2875}, \mdline{2875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2875} or +\mdline{2876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2876} match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches.%mdk + +%mdk-data-line={2885} +\mdline{2885}The \mdline{2885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2885} and \mdline{2885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2885} fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for \mdline{2887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2887} and \mdline{2887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{2887} updates. When deleting +an entry, these key fields (along with \mdline{2888}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2888}) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a \mdline{2890}\emph{keyless}\mdline{2890} +table (the table has an empty match key), the server must reject all attempts to +\mdline{2892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2892} a match entry and return an \mdline{2892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2892} error.%mdk + +%mdk-data-line={2894} +\mdline{2894}The number of match entries that a table \mdline{2894}\emph{should}\mdline{2894} support is indicated in P4Info +(\mdline{2895}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2895} field of \mdline{2895}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{2895} message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P4\mdline{2896}\mdsub{16}\mdline{2896} specification for the +\mdline{2897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2897} property\mdline{2897}~[\mdcite{p4tableproperties}{30}]\mdline{2897}. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +\mdline{2901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{2901} when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached.%mdk + +%mdk-data-line={2906} +\subsubsection{\mdline{2906}9.1.1.\hspace*{0.5em}\mdline{2906}Match Format}\label{sec-match-format}%mdk%mdk + +%mdk-data-line={2908} +\noindent\mdline{2908}The bytes fields in the \mdline{2908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2908} message follow the format described in +\mdline{2909}\mdref{sec-bytestrings}{Bytestrings}\mdline{2909}.%mdk + +%mdk-data-line={2911} +\mdline{2911}For \mdline{2911}\textquotedblleft{}don't care\textquotedblright{}\mdline{2911} matches, the P4Runtime client must omit the field\mdline{2911}'\mdline{2911}s entire +\mdline{2912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2912} entry when building the \mdline{2912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2912} repeated field of the \mdline{2912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2912} +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for \mdline{2914}\textquotedblleft{}don't care\textquotedblright{}\mdline{2914} matches, which is needed +to ensure\mdline{2915}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2915}. For PSA match types, +a \mdline{2916}\textquotedblleft{}don't care\textquotedblright{}\mdline{2916} match for a specific match key field is defined as follows:%mdk + +%mdk-data-line={2918} +\begin{itemize}%mdk + +%mdk-data-line={2918} +\item{} +%mdk-data-line={2918} +\mdline{2918}For a \mdline{2918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2918} match, it is logically equivalent to a mask of zeros.%mdk%mdk + +%mdk-data-line={2920} +\item{} +%mdk-data-line={2920} +\mdline{2920}For a \mdline{2920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{2920} match, it is logically equivalent to a wildcard match.%mdk%mdk + +%mdk-data-line={2922} +\item{} +%mdk-data-line={2922} +\mdline{2922}For an \mdline{2922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2922} match, it is logically equivalent to a prefix\mdline{2922}\_\mdline{2922}len of zero.%mdk%mdk + +%mdk-data-line={2924} +\item{} +%mdk-data-line={2924} +\mdline{2924}For a \mdline{2924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2924} match, it is logically equivalent to a range which includes all +possible values for the field.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2927} +\noindent\mdline{2927}Note that there is no \mdline{2927}\textquotedblleft{}don't care\textquotedblright{}\mdline{2927} value for \mdline{2927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2927} matches and therefore exact +match fields can never be omitted from the \mdline{2928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2928} message.%mdk + +%mdk-data-line={2930} +\mdline{2930}The following example shows a P4Runtime message that treats a \mdline{2930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2930} field +as a \mdline{2931}\textquotedblleft{}don't care\textquotedblright{}\mdline{2931} match. The P4 program defines table \mdline{2931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{2931} with \mdline{2931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2931} +and \mdline{2932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2932} fields in its match key:%mdk + +%mdk-data-line={2934} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2935} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~ternary;\\ +~~~~istd.ingress\_port:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2946} +\noindent\mdline{2946}In this P4Runtime request, the client omits the table\mdline{2946}'\mdline{2946}s \mdline{2946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2946} field +from the repeated \mdline{2947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2947} field to indicate a \mdline{2947}\textquotedblleft{}don't care\textquotedblright{}\mdline{2947} match. As shown +below, the \mdline{2948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2948} specifies only the \mdline{2948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2948} field given by \mdline{2948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id:~2}}}\mdline{2948}.%mdk + +%mdk-data-line={2950} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2951} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}33554439}~~{\mdcolor{darkgreen}\#~Table~t's~ID.}\\ +~~~~match~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~field\_id~1~is~not~present~to~use~the~don't~care~ternary~value.}\\ +~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~exact~\{\\ +~~~~~~~~value:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x20}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~action~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~Action~selection~goes~here.}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2969} +\noindent\mdline{2969}For every member of the \mdline{2969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2969} repeated \mdline{2969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2969} field, \mdline{2969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id}}}\mdline{2969} must be +a valid id for the table, as per the P4Info, and one of the fields in +\mdline{2971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{2971} must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an \mdline{2973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2973} error code.%mdk + +%mdk-data-line={2975} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2975} +\item\mdline{2975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2975} match + +%mdk-data-line={2976} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2976} +\item\mdline{2976}The binary string encoding of the value must conform to the +\mdline{2977}\mdref{sec-bytestrings}{Bytestrings}\mdline{2977} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2979} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2980} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.exact().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2983} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2983} +\item\mdline{2983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2983} match + +%mdk-data-line={2984} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2984} +\item\mdline{2984}The binary string encoding of the value (when present) must conform to the +\mdline{2985}\mdref{sec-bytestrings}{Bytestrings}\mdline{2985} requirements.%mdk + +%mdk-data-line={2986} +\item\mdline{2986}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2986} match must be omitted.%mdk + +%mdk-data-line={2987} +\item\mdline{2987}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2987} bits must be 0 in value.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2989} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2990} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.lpm().value()))\\ +\\ +pLen~=~match.lpm().prefix\_len()\\ +assert(pLen~\textgreater{}~0)\\ +\\ +trailing\_zeros~=~countTrailingZeros(match.lpm().value())\\ +assert(trailing\_zeros~\textgreater{}=~field\_bits~-~pLen)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2999} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2999} +\item\mdline{2999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2999} match + +%mdk-data-line={3000} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3000} +\item\mdline{3000}The binary string encoding of the value (when present) and mask (when +present) must conform to the\mdline{3001}~\mdref{sec-bytestrings}{Bytestrings}\mdline{3001} requirements.%mdk + +%mdk-data-line={3002} +\item\mdline{3002}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3002} match must be omitted.%mdk + +%mdk-data-line={3003} +\item\mdline{3003}Masked bits must be 0 in value. This constraint taken together +with the\mdline{3004}~\mdref{sec-bytestrings}{Bytestrings}\mdline{3004} requirements means that the +value\mdline{3005}'\mdline{3005}s binary string is never longer than the mask\mdline{3005}'\mdline{3005}s binary string. +When the value\mdline{3006}'\mdline{3006}s string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3010} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3011} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.ternary().value()))\\ +assert(BytestringValid(match.ternary().mask()))\\ +assert(match.ternary().value().size()~\textless{}=~match.ternary().mask().size());\\ +\\ +value~=~parseInteger(match.ternary().value())\\ +mask~=~parseInteger(match.ternary().mask())\\ +\\ +assert(mask~!=~0)\\ +\\ +assert(value~\&~mask~==~value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3023} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3023} +\item\mdline{3023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3023} match + +%mdk-data-line={3024} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3024} +\item\mdline{3024}The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the\mdline{3025}~\mdref{sec-bytestrings}{Bytestrings}\mdline{3025} +requirements.%mdk + +%mdk-data-line={3027} +\item\mdline{3027}Low bound must be less than or equal to the high bound.%mdk + +%mdk-data-line={3028} +\item\mdline{3028}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3028} match must be omitted.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3030} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3031} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.range().low()))\\ +assert(BytestringValid(match.range().high()))\\ +\\ +low~=~parseInteger(match.range().low())\\ +high~=~parseInteger(match.range().high())\\ +\\ +assert(low~\textless{}=~high)\\ +\\ +assert(low~!=~min\_field\_value~\textbar{}\textbar{}~high~!=~max\_field\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3042} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3042} +\item\mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3042} match + +%mdk-data-line={3043} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3043} +\item\mdline{3043}The binary string encoding of the value must conform to the +\mdline{3044}\mdref{sec-bytestrings}{Bytestrings}\mdline{3044} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3046} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3047} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.optional().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3050} +\subsubsection{\mdline{3050}9.1.2.\hspace*{0.5em}\mdline{3050}Action Specification}\label{sec-action-specification}%mdk%mdk + +%mdk-data-line={3052} +\noindent\mdline{3052}The \mdline{3052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3052} \mdline{3052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3052} field must be set for every \mdline{3052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3052} update but may be +left unset for \mdline{3053}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3053} updates, in which case the action specification for the +table entry will not be modified (if a \mdline{3054}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3054} update has an unset action field +and does not modify any direct resource attached to the table then the \mdline{3055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3055} +update is a no-op). Based on the implementation property value of the P4 table, +the \mdline{3057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3057} in the \mdline{3057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3057} message will either be:%mdk + +%mdk-data-line={3059} +\begin{itemize}%mdk + +%mdk-data-line={3059} +\item{} +%mdk-data-line={3059} +\mdline{3059}an \mdline{3059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3059} specification for direct tables (with no P4 \mdline{3059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3059} +property)%mdk%mdk + +%mdk-data-line={3062} +\item{} +%mdk-data-line={3062} +\mdline{3062}an action profile member id for indirect tables for which the \mdline{3062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3062} +property is an action profile with no selector.%mdk%mdk + +%mdk-data-line={3065} +\item{} +%mdk-data-line={3065} +\mdline{3065}an action profile member id or group id for indirect tables for which the +\mdline{3066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3066} property is an action profile with selector.%mdk%mdk + +%mdk-data-line={3068} +\item{} +%mdk-data-line={3068} +\mdline{3068}an \mdline{3068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3068} specification for indirect tables for +which the \mdline{3069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3069} property is an action profile with +selector. This usage is described in\mdline{3070}~\mdref{sec-oneshot}{One Shot Action Selector +Programming}\mdline{3071}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3073} +\noindent\mdline{3073}If the \mdline{3073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3073} does not match the table description in the P4Info (\mdline{3073}e.g.\mdline{3073} the +\mdline{3074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3074} is \mdline{3074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member\_id}}}\mdline{3074} for a direct table), the server must +return an \mdline{3075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3075} error code.%mdk + +%mdk-data-line={3077} +\mdline{3077}The \mdline{3077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3077} Protobuf message has the following fields:%mdk + +%mdk-data-line={3079} +\begin{itemize}%mdk + +%mdk-data-line={3079} +\item{} +%mdk-data-line={3079} +\mdline{3079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3079}, which identifies the action instance; the \mdline{3079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3079} is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an \mdline{3081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3081} error +code. If the client uses a valid \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3082} for the table but does not +respect the action scope specified in P4Info (\mdline{3083}e.g.\mdline{3083} tries to set a \mdline{3083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{3083} +action as the default action), the server must return a \mdline{3084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3084} +error code.%mdk%mdk + +%mdk-data-line={3087} +\item{} +%mdk-data-line={3087} +\mdline{3087}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{3087}: a repeated Protobuf field of action parameter values, each encoded +as a \mdline{3088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{3088} message. For each parameter, \mdline{3088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}param\_id}}}\mdline{3088} must be valid for the +action (as per the P4Info) and value must follow the format described in +\mdline{3090}\mdref{sec-bytestrings}{Bytestrings}\mdline{3090}. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an \mdline{3092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3092} error code +if a parameter id is missing, if an extra parameter\mdline{3093} \mdline{3093}\textemdash{}\mdline{3093} id not found in the +P4Info\mdline{3094} \mdline{3094}\textemdash{}\mdline{3094} was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +\mdline{3096}\mdref{sec-bytestrings}{Bytestrings}\mdline{3096} format.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3098} +\noindent\mdline{3098}For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a \mdline{3100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3100} error code.%mdk + +%mdk-data-line={3102} +\subsubsection{\mdline{3102}9.1.3.\hspace*{0.5em}\mdline{3102}Default Entry}\label{sec-default-entry}%mdk%mdk + +%mdk-data-line={3104} +\noindent\mdline{3104}According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer\mdline{3105} \mdline{3105}\textemdash{}\mdline{3105} or defaults to \mdline{3105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3105} +(which is a no-op) otherwise\mdline{3106} \mdline{3106}\textemdash{}\mdline{3106} and assuming it is not declared as \mdline{3106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3106}, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow \mdline{3108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3108} and \mdline{3108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3108} updates on the default entry and the +P4Runtime server must return an \mdline{3109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3109} error code if the client +attempts one.%mdk + +%mdk-data-line={3112} +\mdline{3112}The default entry is identified by setting the \mdline{3112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3112} boolean field +to true. When this flag is set to true, the repeated \mdline{3113}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3113} field must be empty +and the \mdline{3114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3114} field must be set to zero, otherwise the P4Runtime server +must return an \mdline{3115}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3115} error code. When performing a \mdline{3115}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3115} update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its \mdline{3119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3119} and \mdline{3119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3119} value as well as the +configurations for its\mdline{3120}~\mdref{sec-direct-resources}{direct resources}\mdline{3120} will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a \mdline{3122}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3122} +error code if the client attempts to modify it.%mdk + +%mdk-data-line={3125} +\mdline{3125}Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to\mdline{3126}~\mdref{sec-direct-resources}{direct resources}\mdline{3126}.%mdk + +%mdk-data-line={3128} +\mdline{3128}In this P4Runtime release, we have decided to restrict the default entry for +indirect tables\mdline{3129} \mdline{3129}\textemdash{}\mdline{3129} tables with an ActionProfile or ActionSelector +\mdline{3130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3130} property\mdline{3130} \mdline{3130}\textemdash{}\mdline{3130} to a constant \mdline{3130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3130} action entry, with the +hope that it would simplify the implementation of the P4Runtime service.%mdk + +%mdk-data-line={3133} +\subsubsection{\mdline{3133}9.1.4.\hspace*{0.5em}\mdline{3133}Constant Tables}\label{sec-constant-tables}%mdk%mdk + +%mdk-data-line={3135} +\noindent\mdline{3135}Constant tables are defined as tables whose match entries are immutable. They +are identified by the \mdline{3136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3136} flag in P4Info.%mdk + +%mdk-data-line={3138} +\mdline{3138}The only write updates which are allowed for constant tables are \mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3138} +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +\mdline{3142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3142} error. Just like any table entry \mdline{3142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3142} request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a \mdline{3146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3146} error.%mdk + +%mdk-data-line={3148} +\mdline{3148}The contents of const tables can be queried by the client through a +\mdline{3149}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3149}. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: \mdline{3150}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3150}, \mdline{3150}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3150}, \mdline{3150}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3150}, +\mdline{3151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3151}, and \mdline{3151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3151} (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the \mdline{3154}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3154} field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P4\mdline{3156}\mdsub{16}\mdline{3156} does not support assigning explicit priorities to static +entries. When a priority value is required (\mdline{3157}e.g.\mdline{3157} for tables including \mdline{3157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3157}, +\mdline{3158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3158} or \mdline{3158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3158} matches), it is inferred based on the order in which +entries appear in the table declaration.%mdk + +%mdk-data-line={3161} +\subsubsection{\mdline{3161}9.1.5.\hspace*{0.5em}\mdline{3161}Wildcard Reads}\label{sec-table-wildcard-reads}%mdk%mdk + +%mdk-data-line={3163} +\noindent\mdline{3163}When performing a \mdline{3163}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3163}, the P4Runtime client can select all entries +from one or all tables on the target and use several of the \mdline{3164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3164} fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as \mdline{3168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3168} and \mdline{3168}\textquotedblleft{}unset\textquotedblright{}\mdline{3168} for message fields such as \mdline{3168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3168}. The following +fields may be used to select and filter results:%mdk + +%mdk-data-line={3171} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3171} +\item\mdline{3171}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3171}: If default (0), entries from all tables\mdline{3171} \mdline{3171}\textemdash{}\mdline{3171} including constant +tables\mdline{3172} \mdline{3172}\textemdash{}\mdline{3172} will be selected and no other filter can be used. Otherwise only +the specified table will be considered.%mdk + +%mdk-data-line={3174} +\item\mdline{3174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3174}: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned.%mdk + +%mdk-data-line={3178} +\item\mdline{3178}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3178}: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an \mdline{3179}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3179} (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id.%mdk + +%mdk-data-line={3185} +\item\mdline{3185}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3185}: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value.%mdk + +%mdk-data-line={3188} +\item\mdline{3188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3188}: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +\mdline{3190}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3190} value.%mdk + +%mdk-data-line={3191} +\item\mdline{3191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3191}: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided \mdline{3193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3193} value.%mdk + +%mdk-data-line={3194} +\item\mdline{3194}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3194}: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3198} +\noindent\mdline{3198}For example, in order to read all entries from all tables from device 3, the +client can use the following \mdline{3199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3199} message.%mdk + +%mdk-data-line={3201} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3202} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0}\\ +~~~~priority:~{\mdcolor{purple}0}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3213} +\noindent\mdline{3213}In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following \mdline{3214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3214} +message:%mdk + +%mdk-data-line={3217} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3218} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~priority:~{\mdcolor{purple}11}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3229} +\noindent\mdline{3229}The canonical representation of \mdline{3229}\textquotedblleft{}don't care\textquotedblright{}\mdline{3229} matches, combined with the ability +to do a wildcard read on all table entries by leaving the \mdline{3230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3230} field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single \mdline{3232}\textquotedblleft{}don't care\textquotedblright{}\mdline{3232} entry or to do a wildcard +read. If a table has no fields with match kind \mdline{3233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3233}, it is possible via +P4Runtime to add an entry that is \mdline{3234}\textquotedblleft{}don't care\textquotedblright{}\mdline{3234} for all fields (\mdline{3234}i.e.\mdline{3234} has an empty +\mdline{3235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3235} field) but is not the default entry (\mdline{3235}i.e.\mdline{3235} \mdline{3235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3235} is +false). When reading this entry from the table, there is no way to read \mdline{3236}\emph{only}\mdline{3236} +that entry from the table, because it would require providing an unset \mdline{3237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3237} +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single \mdline{3240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{3240} match:%mdk + +%mdk-data-line={3242} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3243} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;~fwd;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3253} +\noindent\mdline{3253}The following \mdline{3253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3253} message can be used to add 2 entries:%mdk + +%mdk-data-line={3254} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3255} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{~{\mdcolor{darkgreen}\#~don't~care~entry}\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +~~table~entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~match~\{\\ +~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~lpm~\{\\ +~~~~~~~~value:~{\mdcolor{purple}0x0a000000}\\ +~~~~~~~~prefix\_len:~{\mdcolor{purple}8}\\ +~~~~~~\}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3274} +\noindent\mdline{3274}The first entry is a \mdline{3274}\textquotedblleft{}don't care\textquotedblright{}\mdline{3274} entry, while the second one matches all +\mdline{3275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}10.0.0.0/8}}}\mdline{3275} addresses. The second entry has higher priority than the first one.%mdk + +%mdk-data-line={3277} +\mdline{3277}The following \mdline{3277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3277} message will return \mdline{3277}\emph{all}\mdline{3277} entries in the table, not +just the \mdline{3278}\textquotedblleft{}don't care\textquotedblright{}\mdline{3278} entry.%mdk + +%mdk-data-line={3279} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3280} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3288} +\noindent\mdline{3288}This issue also exists for tables with \mdline{3288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3288}, \mdline{3288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3288}, and \mdline{3288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3288} +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the \mdline{3291}\textquotedblleft{}don't care\textquotedblright{}\mdline{3291} entry will be returned to the +client. If the client uses distinct priority values for all entries\mdline{3292} \mdline{3292}\textemdash{}\mdline{3292} which is +strongly recommended to achieve\mdline{3293}~\mdref{sec-table-entry}{deterministic behavior}\mdline{3293} \mdline{3293}\textemdash{}\mdline{3293}, +then there is no ambiguity because the wildcard read will actually return a +single entry (the \mdline{3295}\textquotedblleft{}don't care\textquotedblright{}\mdline{3295} entry) as long as the \mdline{3295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3295} field is set to +the correct value.%mdk + +%mdk-data-line={3298} +\subsubsection{\mdline{3298}9.1.6.\hspace*{0.5em}\mdline{3298}Direct Resources}\label{sec-direct-resources}%mdk%mdk + +%mdk-data-line={3300} +\noindent\mdline{3300}In addition to the \mdline{3300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3300} and \mdline{3300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3300} entities, +P4Runtime support reading and writing direct resources as part of the +\mdline{3302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3302} message. This is convenient for two reasons:%mdk + +%mdk-data-line={3304} +\begin{itemize}%mdk + +%mdk-data-line={3304} +\item{} +%mdk-data-line={3304} +\mdline{3304}A table entry and its direct resources can be read with a single entity when +doing a \mdline{3305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{3305} RPC call%mdk%mdk + +%mdk-data-line={3307} +\item{} +%mdk-data-line={3307} +\mdline{3307}The initial configuration for an entry\mdline{3307}'\mdline{3307}s direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can \mdline{3312}\textquotedblleft{}hit\textquotedblright{}\mdline{3312} the table entry without +executing the appropriate meter entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3315} +\noindent\mdline{3315}Once the table entry has been inserted, the P4Runtime client is free to use the +\mdline{3316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3316} and \mdline{3316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3316} messages for read and write +operations on \mdline{3317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3317} and \mdline{3317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3317} instances. For example, it is +usually more convenient as well as more efficient to use \mdline{3318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3318} to +query a counter entry value rather than use \mdline{3319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3319}, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry.%mdk + +%mdk-data-line={3323} +\mdline{3323}The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does \mdline{3324}\emph{not}\mdline{3324} need to be \mdline{3324}\textquotedblleft{}executed\textquotedblright{}\mdline{3324} in +every action bound to the table. It is an error to provide a direct resource +configuration in a \mdline{3326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3326} message when programming an action that does not +execute the direct resource, and the server must return an \mdline{3327}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3327} +error code.%mdk + +%mdk-data-line={3330} +\mdline{3330}We leverage Protobuf\mdline{3330}'\mdline{3330}s ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the \mdline{3332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3332} message. The list below describes how +the server must handle the \mdline{3333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3333} and \mdline{3333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3333} fields for read and +write requests, based on whether the fields are set or not. We do not cover +error cases in the list, \mdline{3335}i.e.\mdline{3335} we assume that we are dealing with a table which +is assigned a direct counter / a direct meter, and that the action being used +for the table entry \mdline{3337}\textquotedblleft{}executes\textquotedblright{}\mdline{3337} the direct resource appropriately.%mdk + +%mdk-data-line={3339} +\begin{itemize}%mdk + +%mdk-data-line={3339} +\item{} +%mdk-data-line={3339} +\mdline{3339}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3339} field%mdk + +%mdk-data-line={3340} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3340} +\item\mdline{3340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3340} + +%mdk-data-line={3341} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3341} +\item\mdline{3341}if \mdline{3341}\textbf{unset}\mdline{3341}: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets).%mdk + +%mdk-data-line={3343} +\item\mdline{3343}if \mdline{3343}\textbf{set}\mdline{3343}: The initial configuration for the meter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3345} +\item\mdline{3345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3345} + +%mdk-data-line={3346} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3346} +\item\mdline{3346}if \mdline{3346}\textbf{unset}\mdline{3346}: The meter entry\mdline{3346}'\mdline{3346}s configuration is reset to the default +(meter returns GREEN for all packets).%mdk + +%mdk-data-line={3348} +\item\mdline{3348}if \mdline{3348}\textbf{set}\mdline{3348}: The value provided by the client is used to re-configure +the meter entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3350} +\item\mdline{3350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3350} + +%mdk-data-line={3351} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3351} +\item\mdline{3351}if \mdline{3351}\textbf{unset}\mdline{3351}: The response does not include the meter entry\mdline{3351}'\mdline{3351}s +configuration (\mdline{3352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3352} is unset in the response).%mdk + +%mdk-data-line={3353} +\item\mdline{3353}if \mdline{3353}\textbf{set}\mdline{3353}: If the meter entry\mdline{3353}'\mdline{3353}s configuration is the default +configuration, \mdline{3354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3354} is unset in the response. Otherwise, the +response includes the meter entry\mdline{3355}'\mdline{3355}s configuration that was written by +the client earlier. This respects the \mdline{3356}\textquotedblleft{}read-write symmetry\textquotedblright{}\mdline{3356} principle.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3358} +\item{} +%mdk-data-line={3358} +\mdline{3358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3358} field%mdk + +%mdk-data-line={3359} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3359} +\item\mdline{3359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3359} + +%mdk-data-line={3360} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3360} +\item\mdline{3360}if \mdline{3360}\textbf{unset}\mdline{3360}: The initial value for the counter entry is the default +(0).%mdk + +%mdk-data-line={3362} +\item\mdline{3362}if \mdline{3362}\textbf{set}\mdline{3362}: The initial value for the counter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3364} +\item\mdline{3364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3364} + +%mdk-data-line={3365} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3365} +\item\mdline{3365}if \mdline{3365}\textbf{unset}\mdline{3365}: The counter entry\mdline{3365}'\mdline{3365}s value is not changed.%mdk + +%mdk-data-line={3366} +\item\mdline{3366}if \mdline{3366}\textbf{set}\mdline{3366}: The value provided by the client is written to the counter +entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3368} +\item\mdline{3368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3368} + +%mdk-data-line={3369} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3369} +\item\mdline{3369}if \mdline{3369}\textbf{unset}\mdline{3369}: The response does not include the counter entry\mdline{3369}'\mdline{3369}s value +(\mdline{3370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3370} is unset in the response).%mdk + +%mdk-data-line={3371} +\item\mdline{3371}if \mdline{3371}\textbf{set}\mdline{3371}: The response includes the counter entry\mdline{3371}'\mdline{3371}s value read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3374} +\noindent\mdline{3374}In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +\mdline{3376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3376} field unset when inserting \mdline{3376}\textbf{or modifying}\mdline{3376} a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the \mdline{3378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3378} message +(\mdline{3379}i.e.\mdline{3379} the \mdline{3379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3379} field must be set to match the existing configuration).%mdk + +%mdk-data-line={3381} +\subsubsection{\mdline{3381}9.1.7.\hspace*{0.5em}\mdline{3381}Idle-timeout}\label{sec-idle-timeout}%mdk%mdk + +%mdk-data-line={3383} +\noindent\mdline{3383}P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not \mdline{3385}\textquotedblleft{}hit\textquotedblright{}\mdline{3385} (\mdline{3385}i.e.\mdline{3385} not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification\mdline{3387} \mdline{3387}\textemdash{}\mdline{3387} using the +\mdline{3388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3388} message\mdline{3388} \mdline{3388}\textemdash{}\mdline{3388} to the primary client, which can then take +action, such as remove the idle table entry.%mdk + +%mdk-data-line={3391} +\mdline{3391}Two fields of the \mdline{3391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3391} Protobuf message are used to implement idle +timeout:%mdk + +%mdk-data-line={3394} +\begin{itemize}%mdk + +%mdk-data-line={3394} +\item{} +%mdk-data-line={3394} +\mdline{3394}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3394}: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, \mdline{3395}i.e.\mdline{3395} no +\mdline{3396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3396} message will ever be generated for this entry. When +a client reads a \mdline{3397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3397}, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry.%mdk%mdk + +%mdk-data-line={3401} +\item{} +%mdk-data-line={3401} +\mdline{3401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3401}: a Protobuf message with a single field (\mdline{3401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{3401}) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The \mdline{3403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3403} field must be unset for a +\mdline{3404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3404} write. When reading a table entry, \mdline{3404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3404} must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3409} +\noindent\mdline{3409}These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an \mdline{3411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3411} error code if at least one of these +conditions is met:%mdk + +%mdk-data-line={3414} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3414} +\item\mdline{3414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3414} is set to a non-zero value, or%mdk + +%mdk-data-line={3415} +\item\mdline{3415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3415} is set%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3417} +\noindent\mdline{3417}The target should do its best to approximate the \mdline{3417}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3417} value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the \mdline{3420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3420} write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for \mdline{3422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3422}.%mdk + +%mdk-data-line={3424} +\mdline{3424}P4Runtime does not support idle timeout for default entries. When the +\mdline{3425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3425} flag is set in a \mdline{3425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3425} message, \mdline{3425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3425} +must be set to 0 (default) and \mdline{3426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3426} must be unset. If the +server receives a \mdline{3427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3427} message which violates this, it must return an +\mdline{3428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3428} error.%mdk + +%mdk-data-line={3430} +\mdline{3430}For more information about idle timeout, in particular regarding +\mdline{3431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3431}, please refer to the\mdline{3431}~\mdref{sec-table-idle-timeout-notification}{Table idle timeout +notifications}\mdline{3432} section.%mdk + +%mdk-data-line={3434} +\subsection{\mdline{3434}9.2.\hspace*{0.5em}\mdline{3434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3434} \mdline{3434}\&\mdline{3434} \mdline{3434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}\label{sec-action-profile-member-and-group}%mdk%mdk + +%mdk-data-line={3436} +\noindent\mdline{3436}P4Runtime defines an API for programming a PSA ActionProfile extern using +\mdline{3437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3437} messages. A PSA ActionSelector extern can be programmed +using both \mdline{3438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3438} and \mdline{3438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3438} messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table \mdline{3442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3442} for L3 routing, implemented with an action +selector \mdline{3443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3443}.%mdk + +%mdk-data-line={3445} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3446} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector(HashAlgorithm.crc32,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}size~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w1024,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}output\_width~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w10)~as;\\ +\\ +{\bfseries{\mdcolor{navy}action}}~set\_nhop(PortId\_t~p,~EthAddr~smac,~EthAddr~dmac)~\{\\ +~~istd.egress\_port~=~p;\\ +~~hdr.ethernet.smac~=~smac;\\ +~~hdr.ethernet.dmac~=~dmac;\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;~~{\mdcolor{darkgreen}//~LPM~on~destination~IP~address}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~set\_nhop;\\ +~~\}\\ +~~implementation~=~as;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3467} +\noindent\mdline{3467}When programming table \mdline{3467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3467} in the example above, a P4Runtime client should +specify the \mdline{3468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3468} in the \mdline{3468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3468} to be a reference to either an +action profile member or group. The reference is a non-zero \mdline{3469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3469} identifier +that uniquely identifies a member or group programmed in the action selector +\mdline{3471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3471}.%mdk + +%mdk-data-line={3473} +\mdline{3473}If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata.%mdk + +%mdk-data-line={3478} +\mdline{3478}If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata.%mdk + +%mdk-data-line={3489} +\subsubsection{\mdline{3489}9.2.1.\hspace*{0.5em}\mdline{3489}Action Profile Member Programming}\label{sec-action-profile-member-programming}%mdk%mdk + +%mdk-data-line={3491} +\noindent\mdline{3491}Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a \mdline{3492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3492} identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the \mdline{3494}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3494} +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the \mdline{3496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3496} attributes of the +tables \mdline{3497}\emph{must have an identical list of P4 actions}\mdline{3497}. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector.%mdk + +%mdk-data-line={3501} +\mdline{3501}An \mdline{3501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3501} entity update message has the following fields:%mdk + +%mdk-data-line={3503} +\begin{itemize}%mdk + +%mdk-data-line={3503} +\item{} +%mdk-data-line={3503} +\mdline{3503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3503} is the \mdline{3503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3503} identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3506} +\item{} +%mdk-data-line={3506} +\mdline{3506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3506} is the non-zero \mdline{3506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3506} identifier of the action profile member +entry being updated.%mdk%mdk + +%mdk-data-line={3509} +\item{} +%mdk-data-line={3509} +\mdline{3509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3509} is the specification of the P4 action instance bound to the action +profile member entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3512} +\noindent\mdline{3512}An action profile member may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3515} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3515} +\item\mdline{3515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3515}: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an \mdline{3517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3517} error +code. The action specification must be provided, or the server must return +\mdline{3519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3519}. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return \mdline{3521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3521}.%mdk + +%mdk-data-line={3522} +\item\mdline{3522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3522}: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return \mdline{3523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3523}, +and the action specification must be provided, or the server must return +\mdline{3525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3525}.%mdk + +%mdk-data-line={3526} +\item\mdline{3526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3526}: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a \mdline{3527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3527} error code. The member +must not be part of an action profile group, or the server must return +\mdline{3529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3529}. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return \mdline{3532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3532}. \mdline{3532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3532} and \mdline{3532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3532} are the only +fields that are considered when performing a \mdline{3533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3533} and every other field +will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3536} +\noindent\mdline{3536}When reading, an \mdline{3536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3536} message with \mdline{3536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3536} and +\mdline{3537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3537} equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with \mdline{3538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3538} equal to the id of +an existing ActionProfile or ActionSelector object, and a \mdline{3539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3539} equal to +0, will read all members of that specified object.%mdk + +%mdk-data-line={3542} +\subsubsection{\mdline{3542}9.2.2.\hspace*{0.5em}\mdline{3542}Action Profile Group Programming}\label{sec-action-profile-group-programming}%mdk%mdk + +%mdk-data-line={3544} +\noindent\mdline{3544}Action profile groups are entries in an ActionSelector and are referenced by a +\mdline{3545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3545} identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type.%mdk + +%mdk-data-line={3549} +\mdline{3549}Within a single ActionSelector object, the \mdline{3549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3549} values used to identify its +members are in a separate \mdline{3550}\textquoteleft{}scope\textquoteright{}\mdline{3550} from the \mdline{3550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3550} values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5.%mdk + +%mdk-data-line={3554} +\mdline{3554}There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it.%mdk + +%mdk-data-line={3560} +\mdline{3560}An \mdline{3560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3560} entity update message has the following fields:%mdk + +%mdk-data-line={3562} +\begin{itemize}%mdk + +%mdk-data-line={3562} +\item{} +%mdk-data-line={3562} +\mdline{3562}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3562} is the \mdline{3562}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3562} identifier of the PSA ActionSelector +extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3565} +\item{} +%mdk-data-line={3565} +\mdline{3565}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3565} is the non-zero \mdline{3565}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3565} identifier of the action profile group +entry being updated.%mdk%mdk + +%mdk-data-line={3568} +\item{} +%mdk-data-line={3568} +\mdline{3568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3568} is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields:%mdk + +%mdk-data-line={3571} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3571} +\item\mdline{3571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3571} for looking up the member table in the selector.%mdk + +%mdk-data-line={3572} +\item\mdline{3572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3572} specifying the probability of the member\mdline{3572}'\mdline{3572}s selection at +runtime. 0 is not a valid \mdline{3573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3573} value and the server must return +\mdline{3574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3574} if the client attempts to use it.%mdk + +%mdk-data-line={3575} +\item\mdline{3575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3575} is the controller-defined port that the member\mdline{3575}'\mdline{3575}s +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +\mdline{3578}\mdref{action-selector-constraints}{9.2.4}\mdline{3578} for notes on the behavior if all members in +a group are excluded for this reason. If \mdline{3579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3579} is empty, then the +member is always included in the selection, regardless of the status of +any port of the device. The value must be empty or the SDN port of an +existing port on the device, otherwise the server must return +\mdline{3583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3583}.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3585} +\item{} +%mdk-data-line={3585} +\mdline{3585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3585} is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +\mdline{3587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3587} update. See the subsection below for the\mdline{3587}~\mdref{sec-max-size-rules}{rules on setting +\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\mdline{3588}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3590} +\noindent\mdline{3590}An action profile group may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3593} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3593} +\item\mdline{3593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3593}: Add a new group entry bound to a set of existing action profile +members. \mdline{3594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}The~group\_id}}}\mdline{3594} must be different from ids of already programmed +groups for that selector, or the server must return an \mdline{3595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3595} error +code. All members specified in the group must exist in the selector, or the +server must return \mdline{3597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3597}. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target.%mdk + +%mdk-data-line={3599} +\item\mdline{3599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3599}: Modify the member set specification of an existing group entry. An +entry with the \mdline{3600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3600} must exist, or the server must return +\mdline{3601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3601}. All members specified in the group entry must exist in the +selector, or the server must return \mdline{3602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3602}. The value of \mdline{3602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3602} must +be identical to the value used when inserting the group, otherwise an +\mdline{3604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3604} error is returned.%mdk + +%mdk-data-line={3605} +\item\mdline{3605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3605}: Delete the group entry and deallocate the \mdline{3605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3605}. The group must +not be referenced in the table action of any table entry, or the server must +return a \mdline{3607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3607} error code. If the \mdline{3607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3607} is invalid, the +server must return \mdline{3608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3608}. \mdline{3608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3608} and \mdline{3608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3608} are the +only fields that are considered when performing a \mdline{3609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3609} and every other +field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3612} +\noindent\mdline{3612}When setting the group membership with \mdline{3612}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3612} or \mdline{3612}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3612}, the \mdline{3612}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3612} +repeated field must not include duplicates, \mdline{3613}i.e.\mdline{3613} members with the same +\mdline{3614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3614}. The \mdline{3614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3614} field is used instead to logically \mdline{3614}\textquotedblleft{}repeat\textquotedblright{}\mdline{3614} the member +inside the group.%mdk + +%mdk-data-line={3617} +\mdline{3617}It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation \mdline{3618}\textquotedblleft{}stores\textquotedblright{}\mdline{3618} the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made.%mdk + +%mdk-data-line={3622} +\mdline{3622}When reading, an \mdline{3622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3622} message with \mdline{3622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3622} and +\mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3623} equal to 0 will read all groups of all ActionSelector objects. A +message with \mdline{3624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3624} equal to the id of an existing ActionSelector +object, and a \mdline{3625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3625} equal to 0, will read all groups of that one specified +object.%mdk + +%mdk-data-line={3628} +\paragraph{\mdline{3628}9.2.2.1.\hspace*{0.5em}\mdline{3628}Rules on Setting \mdline{3628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\label{sec-max-size-rules}%mdk%mdk + +%mdk-data-line={3630} +\noindent\mdline{3630}The valid values for \mdline{3630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3630} depend on the static \mdline{3630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3630} included +in the P4Info message:%mdk + +%mdk-data-line={3633} +\begin{itemize}%mdk + +%mdk-data-line={3633} +\item{} +%mdk-data-line={3633} +\mdline{3633}If \mdline{3633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3633} is greater than 0, then \mdline{3633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3633} must be greater than 0, +and less than or equal to \mdline{3634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3634}. We assume that the target can +support selector groups for which the sum of all member weights is up to +\mdline{3636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3636}, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If \mdline{3637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3637} is greater than \mdline{3637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3637}, the server +must return \mdline{3638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3638}.%mdk%mdk + +%mdk-data-line={3640} +\item{} +%mdk-data-line={3640} +\mdline{3640}Otherwise (\mdline{3640}i.e.\mdline{3640} if \mdline{3640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3640} is 0), the P4Runtime client can set +\mdline{3641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3641} to any value greater than or equal to 0.%mdk + +%mdk-data-line={3643} +\begin{itemize}%mdk + +%mdk-data-line={3643} +\item{} +%mdk-data-line={3643} +\mdline{3643}A \mdline{3643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3643} of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (\mdline{3646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3646} or \mdline{3646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3646}), the target must return a +\mdline{3647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3647} error.%mdk%mdk + +%mdk-data-line={3649} +\item{} +%mdk-data-line={3649} +\mdline{3649}If \mdline{3649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3649} is greater than 0 and the value is not supported by the +target, the server must return a \mdline{3650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3650} error at +group-creation time.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3653} +\subsubsection{\mdline{3653}9.2.3.\hspace*{0.5em}\mdline{3653}One Shot Action Selector Programming}\label{sec-oneshot}%mdk%mdk + +%mdk-data-line={3655} +\noindent\mdline{3655}P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids.%mdk + +%mdk-data-line={3661} +\mdline{3661}One shots are programmed by choosing the \mdline{3661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3661} message as the +\mdline{3662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3662}. The \mdline{3662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3662} message consists of a set of +\mdline{3663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3663} messages, which in turn have the following fields:%mdk + +%mdk-data-line={3665} +\begin{itemize}%mdk + +%mdk-data-line={3665} +\item{} +%mdk-data-line={3665} +\mdline{3665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3665} is one of the actions specified by the table that is being +programmed.%mdk%mdk + +%mdk-data-line={3668} +\item{} +%mdk-data-line={3668} +\mdline{3668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3668} specifying the probability of the action\mdline{3668}'\mdline{3668}s selection at runtime. 0 is +not a valid \mdline{3669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3669} value and the server must return \mdline{3669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3669} if +the client attempts to use it. The sum of all weights across all +\mdline{3671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3671} messages for that \mdline{3671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3671} message must +not exceed the \mdline{3672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3672} specificed in the P4Info (if greater than 0), +or the server must return \mdline{3673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3673}.%mdk%mdk + +%mdk-data-line={3675} +\item{} +%mdk-data-line={3675} +\mdline{3675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3675} is the controller-defined port that the action\mdline{3675}'\mdline{3675}s liveness depends +on. At runtime, the action must be excluded from selection if the watch port +is down. See Section\mdline{3677}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{3677} for more details +on the \mdline{3678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3678} field, which also apply for one shot action selector +programming.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3682} +\noindent\mdline{3682}Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics.%mdk + +%mdk-data-line={3687} +\mdline{3687}To preserve read-write symmetry, an implementation must answer \mdline{3687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3687}s +with the original one shot messages. It may not return a desugared version of +the one shot message.%mdk + +%mdk-data-line={3691} +\mdline{3691}For example, consider the action selector table defined +\mdline{3692}\mdref{sec-action-profile-member-and-group}{here}\mdline{3692}. This table could be programmed +with the following one shot update:%mdk + +%mdk-data-line={3695} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3696} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{\\ +~~~~action\_profile\_action\_set~\{\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}1}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x01}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}2}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x02}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}3}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x03}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3721} +\noindent\mdline{3721}Which would be equivalent to the following updates, where \mdline{3721}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GROUP\_ID}}}\mdline{3721}, +\mdline{3722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_1}}}\mdline{3722}, \mdline{3722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_2}}}\mdline{3722}, and \mdline{3722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_3}}}\mdline{3722} are unused ids:%mdk + +%mdk-data-line={3724} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3725} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_1\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_2\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}1}\\ +~~member\_id:~MEMBER\_ID\_3\\ +~~action~\{~~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +\}\\ +action\_profile\_group~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~group\_id:~GROUP\_ID\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_1\\ +~~~~weight:~{\mdcolor{purple}1}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x01}{\mdcolor{maroon}"}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_2\\ +~~~~weight:~{\mdcolor{purple}2}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x02}{\mdcolor{maroon}"}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_3\\ +~~~~weight:~{\mdcolor{purple}3}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x03}{\mdcolor{maroon}"}\\ +~~\}\\ +\}\\ +table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{~action\_profile\_group\_id:~GROUP\_ID~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3766} +\noindent\mdline{3766}Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure\mdline{3767}~\mdref{sec-batching-and-ordering-of-updates}{correct ordering between the dependent +updates}\mdline{3768}. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct \mdline{3770}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3770} batches are required.%mdk + +%mdk-data-line={3772} +\mdline{3772}It is possible to include several \mdline{3772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3772} messages with the same +exact \mdline{3773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3773} specification in one \mdline{3773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3773} message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the \mdline{3775}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3775} field. Note that to preserve read-write symmetry, the server +must not coalesce multiple \mdline{3776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3776} messages with the same \mdline{3776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3776} +specification into one.%mdk + +%mdk-data-line={3779} +\mdline{3779}All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with \mdline{3780}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3780} and +\mdline{3781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3781} messages. Programming some entries with one shots, and +other entries with \mdline{3782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3782} and \mdline{3782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3782} messages is +not allowed, and the server must return the error code \mdline{3783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3783} in +that case.%mdk + +%mdk-data-line={3786} +\mdline{3786}A P4Runtime server \mdline{3786}\emph{must}\mdline{3786} support the one shot style of programming tables with +an action selector implementation. Support for the \mdline{3787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3787} and +\mdline{3788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3788} style is \mdline{3788}\emph{optional}\mdline{3788}. If \mdline{3788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3788} and +\mdline{3789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3789} are not supported by a server, it must return an +\mdline{3790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3790} error for every \mdline{3790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3790} or \mdline{3790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3790} +message that it receives.%mdk + +%mdk-data-line={3793} +\subsubsection{\mdline{3793}9.2.4.\hspace*{0.5em}\mdline{3793}Constraints on action selector programming}\label{action-selector-constraints}%mdk%mdk + +%mdk-data-line={3795} +\noindent\mdline{3795}The PSA specification states that the following features are \mdline{3795}\emph{optional}\mdline{3795} in +action selector implementations\mdline{3796}~[\mdcite{psaactionselector}{22}]\mdline{3796}:%mdk + +%mdk-data-line={3798} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3798} +\item\mdline{3798}Support for non-empty groups where in the same group, different members are +bound to different actions.%mdk + +%mdk-data-line={3800} +\item\mdline{3800}Predictable data plane behavior when a matched table entry points to an empty +group.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={3803} +\noindent\mdline{3803}For 1., if a client tries to \mdline{3803}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3803} or \mdline{3803}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3803} a group with members bound to +different actions, the server should return \mdline{3804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3804} if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return \mdline{3810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3810} (modifying the action parameter values must be +supported, however).%mdk + +%mdk-data-line={3813} +\mdline{3813}PSA 1.1 introduces the \mdline{3813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3813} table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. \mdline{3817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3817} is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of \mdline{3820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3820} at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +\mdline{3822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3822}. Even when \mdline{3822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3822} is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of \mdline{3826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3826} mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming.%mdk + +%mdk-data-line={3831} +\mdline{3831}The PSA specification includes a discussion on how to implement +\mdline{3832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3832} in software in the P4Runtime server +\mdline{3833}[\mdcite{psaemptygroupactionappendix}{25}]\mdline{3833}.%mdk + +%mdk-data-line={3835} +\mdline{3835}If a P4Runtime implementation does support \mdline{3835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3835}, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down.%mdk + +%mdk-data-line={3839} +\mdline{3839}If a P4Runtime implementation does not support \mdline{3839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3839}, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down.%mdk + +%mdk-data-line={3845} +\subsection{\mdline{3845}9.3.\hspace*{0.5em}\mdline{3845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3845} \mdline{3845}\&\mdline{3845} \mdline{3845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-counterentry-directcounterentry}%mdk%mdk + +%mdk-data-line={3847} +\noindent\mdline{3847}PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The \mdline{3849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3849} +P4Runtime message can be used for all three types of PSA counters\mdline{3850} \mdline{3850}\textemdash{}\mdline{3850} \mdline{3850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{3850}, +\mdline{3851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{3851} and \mdline{3851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3851} \mdline{3851}\textemdash{}\mdline{3851} and consists of the following fields:%mdk + +%mdk-data-line={3853} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3853} +\item\mdline{3853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3853} is an \mdline{3853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3853}, corresponding to the number of octets.%mdk + +%mdk-data-line={3854} +\item\mdline{3854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3854} is an \mdline{3854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3854}, corresponding to the number of packets.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3856} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3857} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterData~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~byte\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}int64}}~packet\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3863} +\noindent\mdline{3863}P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of \mdline{3864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3864} and \mdline{3864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3864} fields, which +is equivalent to specifying the counter type \mdline{3865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3865}. Counters may +be defined as direct or indirect (indexed) instances.%mdk + +%mdk-data-line={3868} +\subsubsection{\mdline{3868}9.3.1.\hspace*{0.5em}\mdline{3868}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-directcounterentry}%mdk%mdk + +%mdk-data-line={3870} +\noindent\mdline{3870}A direct counter is a direct resource associated with a \mdline{3870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3870} (see +\mdline{3871}\mdref{sec-direct-resources}{Direct Resources}\mdline{3871}). The \mdline{3871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3871} field of the +\mdline{3872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3872} message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +\mdline{3875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3875} message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed.%mdk + +%mdk-data-line={3878} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3879} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectCounterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3885} +\noindent\mdline{3885}A \mdline{3885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3885} may only include an \mdline{3885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3885} message of type \mdline{3885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3885} with a +\mdline{3886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3886}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3888} +\begin{itemize}%mdk + +%mdk-data-line={3888} +\item{} +%mdk-data-line={3888} +\mdline{3888}the \mdline{3888}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3888} field must match \mdline{3888}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry.match}}}\mdline{3888} of the table entry +to which this direct counter entry is associated. If a matching \mdline{3889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3889} +is not found, the server returns the error code \mdline{3890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3890}.%mdk%mdk + +%mdk-data-line={3892} +\item{} +%mdk-data-line={3892} +\mdline{3892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3892} is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3896} +\noindent\mdline{3896}Specifying \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3896} in an \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3896} message of type \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3896} or +\mdline{3897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3897} is not allowed, and the server must return the error code +\mdline{3898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3898} in that case.%mdk + +%mdk-data-line={3900} +\mdline{3900}A client may use \mdline{3900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3900} in two ways to read the contents of a +\mdline{3901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3901}:%mdk + +%mdk-data-line={3903} +\begin{itemize}%mdk + +%mdk-data-line={3903} +\item{} +%mdk-data-line={3903} +\mdline{3903}As a direct resource associated with a table entry, request the server to +return the counter value in the \mdline{3904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3904} field of the \mdline{3904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3904} message +(see\mdline{3905}~\mdref{sec-direct-resources}{Direct resources}\mdline{3905}).%mdk%mdk + +%mdk-data-line={3907} +\item{} +%mdk-data-line={3907} +\mdline{3907}Explicitly request the counter value by including the \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3907} in +the \mdline{3908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3908}. The \mdline{3908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3908} field must match the \mdline{3908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3908} +whose counter is being read. If no such entry is found, the server returns the +error code \mdline{3910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3910}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3912} +\subsubsection{\mdline{3912}9.3.2.\hspace*{0.5em}\mdline{3912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}\label{sec-counterentry}%mdk%mdk + +%mdk-data-line={3914} +\noindent\mdline{3914}An indirect or indexed counter is not associated with a specific \mdline{3914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3914} +and may be updated independently of any action. It may be read or written using +the P4Runtime \mdline{3916}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3916} message whose fields are defined as follows:%mdk + +%mdk-data-line={3918} +\begin{itemize}%mdk + +%mdk-data-line={3918} +\item{} +%mdk-data-line={3918} +\mdline{3918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3918} is a \mdline{3918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3918}, the unique identifier for the counter.%mdk%mdk + +%mdk-data-line={3920} +\item{} +%mdk-data-line={3920} +\mdline{3920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3920} is a Protobuf message that encapsulates an \mdline{3920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3920}, used to index into +the counter array.%mdk%mdk + +%mdk-data-line={3923} +\item{} +%mdk-data-line={3923} +\mdline{3923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3923} is a Protobuf message of type \mdline{3923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3923}, which represents the +counter value.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3926} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3927} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~counter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3934} +\noindent\mdline{3934}The \mdline{3934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3934} can only be used in a \mdline{3934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3934} with the \mdline{3934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3934} update +type. The P4Runtime server must return an \mdline{3935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3935} error code for +update types \mdline{3936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3936} and \mdline{3936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3936}. By default all the counter entries in the +array have default value 0.%mdk + +%mdk-data-line={3939} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3939} +\item\mdline{3939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3939}: Server returns the error code \mdline{3939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3939}.%mdk + +%mdk-data-line={3940} +\item\mdline{3940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3940}: Modify an indirect counter instance whose unique id is \mdline{3940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3940} +and array index is specified by \mdline{3941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3941}. The counter value is set to the value +specified by the client in the \mdline{3942}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3942} field. Note that the counter value is +not modified if this Protobuf field is not set. If \mdline{3943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3943} is omitted all +counter values in the array will be set to the value provided by the +client. The server must return \mdline{3945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3945} for a negative index value +and \mdline{3946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3946} if the index value exceeds the size of the counter array.%mdk + +%mdk-data-line={3947} +\item\mdline{3947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3947}: Server returns the error code \mdline{3947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3947}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3949} +\noindent\mdline{3949}A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a \mdline{3950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3950} by including a \mdline{3950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3950} +entity for each of the instances, specifying the \mdline{3951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3951} and +\mdline{3952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3952}. Wildcard reads are also supported as follows.%mdk + +%mdk-data-line={3954} +\begin{itemize}%mdk + +%mdk-data-line={3954} +\item{} +%mdk-data-line={3954} +\mdline{3954}If the \mdline{3954}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3954} field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the \mdline{3955}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3955}.%mdk%mdk + +%mdk-data-line={3957} +\item{} +%mdk-data-line={3957} +\mdline{3957}If the \mdline{3957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3957} field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id \mdline{3958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3958}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3960} +\subsection{\mdline{3960}9.4.\hspace*{0.5em}\mdline{3960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3960} \mdline{3960}\&\mdline{3960} \mdline{3960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-meterentry-directmeterentry}%mdk%mdk + +%mdk-data-line={3962} +\noindent\mdline{3962}Meters are an advanced mechanism for keeping statistics, involving stateful +\mdline{3963}\textquotedblleft{}marking\textquotedblright{}\mdline{3963} and usually \mdline{3963}\textquotedblleft{}throttling\textquotedblright{}\mdline{3963} of packets based on configured rates of +traffic. The PSA metering function is based on the \mdline{3964}\emph{Two Rate Three Color Marker}\mdline{3964} +(trTCM) defined in RFC 2698\mdline{3965}~[\mdcite{rfc2698}{2}]\mdline{3965}. The trTCM meters an arbitrary packet +stream using two configured rates\mdline{3966} \mdline{3966}\textemdash{}\mdline{3966} the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes\mdline{3967} \mdline{3967}\textemdash{}\mdline{3967} and +\mdline{3968}\textquotedblleft{}marks\textquotedblright{}\mdline{3968} its packets as GREEN, YELLOW or RED based on the observed rate.%mdk + +%mdk-data-line={3970} +\mdline{3970}A meter may be configured as a direct or indirect instance, similar to a +counter. The \mdline{3971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{3971} P4Runtime message represents meter configuration.%mdk + +%mdk-data-line={3973} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3974} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterConfig~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~cir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~Committed~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~cburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};~~{\mdcolor{darkgreen}//~Committed~Burst~Size}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};~~{\mdcolor{darkgreen}//~Peak~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};~~{\mdcolor{darkgreen}//~Peak~Burst~Size}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3982} +\subsubsection{\mdline{3982}9.4.1.\hspace*{0.5em}\mdline{3982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-directmeterentry}%mdk%mdk + +%mdk-data-line={3984} +\noindent\mdline{3984}A direct meter is a direct resource associated with a \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3984} (see\mdline{3984}~\mdref{sec-direct-resources}{Direct +resources}\mdline{3985}). The \mdline{3985}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3985} field of the \mdline{3985}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3985} +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +\mdline{3989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3989} message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed.%mdk + +%mdk-data-line={3992} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3993} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectMeterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3999} +\noindent\mdline{3999}A \mdline{3999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3999} may only include an \mdline{3999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3999} message of type \mdline{3999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3999} with a +\mdline{4000}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4000}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={4002} +\begin{itemize}%mdk + +%mdk-data-line={4002} +\item{} +%mdk-data-line={4002} +\mdline{4002}the \mdline{4002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4002} field must match the match key of the \mdline{4002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4002} +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching \mdline{4004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4004} is not found, +the server returns the error code \mdline{4005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4005}.%mdk%mdk + +%mdk-data-line={4007} +\item{} +%mdk-data-line={4007} +\mdline{4007}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4007} is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4011} +\noindent\mdline{4011}Specifying \mdline{4011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4011} in an \mdline{4011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4011} message of type \mdline{4011}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4011} or +\mdline{4012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4012} is not allowed, and the server must return the error code +\mdline{4013}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4013} in that case.%mdk + +%mdk-data-line={4015} +\mdline{4015}A client may use \mdline{4015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4015} in two ways to read a \mdline{4015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{4015} config.%mdk + +%mdk-data-line={4017} +\begin{itemize}%mdk + +%mdk-data-line={4017} +\item{} +%mdk-data-line={4017} +\mdline{4017}As a direct resource associated with a table entry, request the server to +return the meter config in the \mdline{4018}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{4018} field of the \mdline{4018}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4018} +message (see\mdline{4019}~\mdref{sec-direct-resources}{Direct resources}\mdline{4019}).%mdk%mdk + +%mdk-data-line={4021} +\item{} +%mdk-data-line={4021} +\mdline{4021}Explicitly request the meter configuration by including the \mdline{4021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4021} +in the \mdline{4022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4022}. The \mdline{4022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4022} field must match the +\mdline{4023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4023} whose meter config is being read. If no such entry is found, the +server returns the error code \mdline{4024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4024}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4026} +\subsubsection{\mdline{4026}9.4.2.\hspace*{0.5em}\mdline{4026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}\label{sec-meterentry}%mdk%mdk + +%mdk-data-line={4028} +\noindent\mdline{4028}An indirect or indexed meter is not associated with a specific \mdline{4028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4028} and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime \mdline{4030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4030} message whose fields are defined as +follows:%mdk + +%mdk-data-line={4033} +\begin{itemize}%mdk + +%mdk-data-line={4033} +\item{} +%mdk-data-line={4033} +\mdline{4033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4033} is a \mdline{4033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4033}, the unique identifier for the meter.%mdk%mdk + +%mdk-data-line={4035} +\item{} +%mdk-data-line={4035} +\mdline{4035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4035} is a Protobuf message that encapsulates an \mdline{4035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4035}, used to index into +a meter array.%mdk%mdk + +%mdk-data-line={4038} +\item{} +%mdk-data-line={4038} +\mdline{4038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4038} is a Protobuf message of type \mdline{4038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{4038}, which represents the +meter configuration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4041} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4042} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~meter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4049} +\noindent\mdline{4049}The \mdline{4049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4049} can only be used in a \mdline{4049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4049} with the \mdline{4049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4049} update +type. The P4Runtime server must return an \mdline{4050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4050} error code for +update types \mdline{4051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4051} and \mdline{4051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4051}. By default all the meter entries in the +array have a default configuration (GREEN for all packets).%mdk + +%mdk-data-line={4054} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4054} +\item\mdline{4054}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4054}: Server returns the error code \mdline{4054}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4054}.%mdk + +%mdk-data-line={4055} +\item\mdline{4055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4055}: Modify an indirect meter instance whose unique id is \mdline{4055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4055} and +array index is specified by \mdline{4056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4056}. The meter is reconfigured using the +\mdline{4057}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4057} field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the \mdline{4059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4059} field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if \mdline{4061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4061} is unset). The server must return \mdline{4061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4061} for a +negative index value and \mdline{4062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4062} if the index value exceeds the size of +the meter array.%mdk + +%mdk-data-line={4064} +\item\mdline{4064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4064}: Server returns the error code \mdline{4064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4064}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4066} +\noindent\mdline{4066}A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a \mdline{4067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4067} by including a \mdline{4067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4067} entity for each +of the instances, specifying the \mdline{4068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4068} and \mdline{4068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4068}. Wildcard reads are also +supported as follows:%mdk + +%mdk-data-line={4071} +\begin{itemize}%mdk + +%mdk-data-line={4071} +\item{} +%mdk-data-line={4071} +\mdline{4071}If the \mdline{4071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4071} field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the \mdline{4072}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4072}.%mdk%mdk + +%mdk-data-line={4074} +\item{} +%mdk-data-line={4074} +\mdline{4074}If the \mdline{4074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4074} field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id \mdline{4075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4075}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4077} +\subsection{\mdline{4077}9.5.\hspace*{0.5em}\mdline{4077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}\label{sec-packetreplicationengineentry}%mdk%mdk + +%mdk-data-line={4079} +\noindent\mdline{4079}The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets.%mdk + +%mdk-data-line={4085} +\subsubsection{\mdline{4085}9.5.1.\hspace*{0.5em}\mdline{4085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}\label{sec-multicastgroupentry}%mdk%mdk + +%mdk-data-line={4087} +\noindent\mdline{4087}Multicasting is achieved in PSA programs by setting the \mdline{4087}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4087} +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the \mdline{4090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4090} API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example.%mdk + +%mdk-data-line={4095} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4096} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~arp\_multicast({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ethernet.isValid()~\&\&\\ +~~~~~~~~hdr.ethernet.eth\_type~==~ETH\_TYPE\_ARP)~\{\\ +~~~~~~smeta.multicast\_group~=~(MulticastGroup\_t)~{\mdcolor{purple}1};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4106} +\noindent\mdline{4106}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4109} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4110} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~multicast\_group\_entry~\{\\ +~~~~~~multicast\_group\_id:~{\mdcolor{purple}1}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}5}~instance:~{\mdcolor{purple}1}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}12}~instance:~{\mdcolor{purple}2}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}18}~instance:~{\mdcolor{purple}3}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}24}~instance:~{\mdcolor{purple}4}~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4124} +\noindent\mdline{4124}As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +\mdline{4129}\mdref{sec-translation-of-port-numbers}{PSA Metadata Translation}\mdline{4129} section.%mdk + +%mdk-data-line={4131} +\mdline{4131}The egress packets may be distinguished for further processing in the egress +using the \mdline{4132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4132} metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 \mdline{4134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4134} metadata is set to a value that is not +programmed in the PRE, then the packet is dropped.%mdk + +%mdk-data-line={4137} +\mdline{4137}A multicast group may be inserted, modified or deleted as per the following +semantics.%mdk + +%mdk-data-line={4140} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4140} +\item\mdline{4140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4140}: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The \mdline{4141}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4141} field is a \mdline{4141}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4141} and must be greater +than 0 (see explanation\mdline{4142}~\mdref{sec-valid-values-for-mg-id}{below}\mdline{4142}), or the +P4Runtime server must return an \mdline{4143}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4143} error. The replica +\mdline{4144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4144} ID is also a \mdline{4144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4144}, and its value may not exceed the maximum +allowed by the target for the \mdline{4145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4145} type (0 is allowed), or the +server must return an \mdline{4146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4146} error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of \mdline{4148}\emph{both}\mdline{4148} \mdline{4148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{4148} and \mdline{4148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4148}, or the server +must return \mdline{4149}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4149}.%mdk + +%mdk-data-line={4150} +\item\mdline{4150}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4150}: Modify the set of replicas for a given multicast group entry, +indexed by the given \mdline{4151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4151}. Same restrictions as \mdline{4151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4151} apply +here.%mdk + +%mdk-data-line={4153} +\item\mdline{4153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4153}: Delete the multicast group indexed by the given +\mdline{4154}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4154}. The replicas need not be provided for this +operation. Any packets with their \mdline{4155}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4155} metadata in the data plane +set to the deleted \mdline{4156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4156} will be dropped.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4158} +\noindent\mdline{4158}When reading a multicast group, only \mdline{4158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4158} is considered. All +other fields in \mdline{4159}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4159} are ignored. To perform a \mdline{4159}\emph{wildcard}\mdline{4159} +\mdline{4160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4160} on all configured multicast group entries, the \mdline{4160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4160} field +must be set to 0, its default value.%mdk + +%mdk-data-line={4163} +\paragraph{\mdline{4163}9.5.1.1.\hspace*{0.5em}\mdline{4163}Valid Values for \mdline{4163}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}}\label{sec-valid-values-for-mg-id}%mdk%mdk + +%mdk-data-line={4165} +\noindent\mdline{4165}The PSA specification states that the valid \mdline{4165}\emph{data plane}\mdline{4165} values for multicast +group ids (\mdline{4166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroup\_t}}}\mdline{4166}) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target\mdline{4168}~[\mdcite{psatranslation}{24}]\mdline{4168}. This means that, in the absence of +translation, the client must set the \mdline{4169}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4169} field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special \mdline{4171}\emph{wildcard}\mdline{4171} value which is used to read all the multicast groups +configured in the target, the \mdline{4172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4172} field must never be set to 0 +when performing a \mdline{4173}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4173} RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value.%mdk + +%mdk-data-line={4178} +\subsubsection{\mdline{4178}9.5.2.\hspace*{0.5em}\mdline{4178}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}\label{sec-clonesessionentry}%mdk%mdk + +%mdk-data-line={4180} +\noindent\mdline{4180}PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +\mdline{4184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4184} identifier and a boolean flag \mdline{4184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone}}}\mdline{4184} in the packet +metadata. The \mdline{4185}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4185} serves as a handle to the clone attributes, +namely a set \mdline{4186}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}replicas}}}\mdline{4186} of \mdline{4186}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(egress~port,~instance)}}}\mdline{4186} pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +\mdline{4189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4189} API.%mdk + +%mdk-data-line={4191} +\mdline{4191}The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the \mdline{4194}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_low\_ttl}}}\mdline{4194} control block is applied in the ingress +pipeline to create an ingress-to-egress clone.%mdk + +%mdk-data-line={4197} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4198} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~clone\_low\_ttl({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ipv4.isValid()~\&\&\\ +~~~~~~~~hdr.ipv4.ttl~\textless{}=~LOW\_TTL\_THRESHOLD)~\{\\ +~~~~~~smeta.clone\_session\_id~=~{\mdcolor{purple}10}w100;\\ +~~~~~~smeta.clone~=~{\bfseries{\mdcolor{navy}true}};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4210} +\noindent\mdline{4210}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4213} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4214} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~clone\_session\_entry~\{\\ +~~~~~~session\_id:~{\mdcolor{purple}100}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}0xfffffffd}~instance:~{\mdcolor{purple}1}~\}~{\mdcolor{darkgreen}\#~to~CPU}\\ +~~~~~~class\_of\_service:~{\mdcolor{purple}2}\\ +~~~~~~packet\_length\_bytes:~{\mdcolor{purple}4096}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4227} +\noindent\mdline{4227}As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type \mdline{4231}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4231}~[\mdcite{psatranslation}{24}]\mdline{4231}). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes.%mdk + +%mdk-data-line={4236} +\mdline{4236}The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port \mdline{4237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfffffffd}}}\mdline{4237}; see +\mdline{4238}\mdref{sec-translation-of-port-numbers}{Translation of Port Numbers}\mdline{4238}). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port.%mdk + +%mdk-data-line={4241} +\mdline{4241}If the \mdline{4241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4241} data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created.%mdk + +%mdk-data-line={4244} +\mdline{4244}A clone session may be inserted, modified or deleted as per the following +semantics:%mdk + +%mdk-data-line={4247} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4247} +\item\mdline{4247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4247}: Add a new clone session entry bound to a set of egress ports and +replica IDs. The \mdline{4248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4248} is a \mdline{4248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4248} and must be greater than 0 (see +explanation\mdline{4249}~\mdref{sec-valid-values-for-session-id}{below}\mdline{4249}), or the P4Runtime +server must return an \mdline{4250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4250} error. The replica \mdline{4250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4250} ID is +also a \mdline{4251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4251}, and its value may not exceed the maximum allowed by the +target for the \mdline{4252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4252} type (0 is allowed), or the server must also +return an \mdline{4253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4253} error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (\mdline{4256}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}class\_of\_service}}}\mdline{4256} field). This value must be a valid +value for the PSA \mdline{4257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ClassOfService\_t}}}\mdline{4257} type, which supports runtime translation +by default\mdline{4258}~[\mdcite{psatranslation}{24}]\mdline{4258}, or the server must return +\mdline{4259}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4259}. See\mdline{4259}~\mdref{sec-translation-of-port-numbers}{PSA Metadata +Translation}\mdline{4260} for more information. The +\mdline{4261}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4261} field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +\mdline{4263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4263} field is 0 (default), no truncation on the clone will be +performed.%mdk + +%mdk-data-line={4265} +\item\mdline{4265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4265}: Modify the attributes of a given clone session entry, indexed by the +given \mdline{4266}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4266}. Same restrictions as \mdline{4266}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4266} apply here.%mdk + +%mdk-data-line={4267} +\item\mdline{4267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4267}: Delete the clone session indexed by the given +\mdline{4268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4268}. Other fields need not be provided for this operation. Any +packet with their \mdline{4269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4269} metadata in the data plane set to the +deleted \mdline{4270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4270} will no longer be cloned.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4272} +\noindent\mdline{4272}When reading a clone session, only \mdline{4272}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4272} is considered. All other fields +in \mdline{4273}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4273} are ignored. To perform a \mdline{4273}\emph{wildcard}\mdline{4273} \mdline{4273}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4273} on all +configured clone session entries, the \mdline{4274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4274} field must be set to 0, its +default value. The \mdline{4275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4275} field can never be equal to 0 in a \mdline{4275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4275} +RPC. If it does, the server must return an \mdline{4276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4276} error.%mdk + +%mdk-data-line={4278} +\paragraph{\mdline{4278}9.5.2.1.\hspace*{0.5em}\mdline{4278}Valid Values for \mdline{4278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}}\label{sec-valid-values-for-session-id}%mdk%mdk + +%mdk-data-line={4280} +\noindent\mdline{4280}The PSA specification states that the valid \mdline{4280}\emph{data plane}\mdline{4280} values for clone +session ids (\mdline{4281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4281}) range from 0 to the maximum value supported by +the target\mdline{4282}~[\mdcite{psatranslation}{24}]\mdline{4282}. Note that unlike for\mdline{4282}~\mdref{sec-valid-values-for-mg-id}{multicast group +ids}\mdline{4283}, 0 is a valid \mdline{4283}\emph{data plane}\mdline{4283} value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special \mdline{4285}\emph{wildcard}\mdline{4285} value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a \mdline{4286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4286} +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is \mdline{4288}\emph{not}\mdline{4288} enabled, we effectively +\mdline{4289}\textquotedblleft{}lose\textquotedblright{}\mdline{4289} one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (\mdline{4290}e.g.\mdline{4290} because the target supports a very +limited number of clone sessions), one can enable translation on +\mdline{4292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4292} and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id.%mdk + +%mdk-data-line={4295} +\subsection{\mdline{4295}9.6.\hspace*{0.5em}\mdline{4295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}\label{sec-valuesetentry}%mdk%mdk + +%mdk-data-line={4297} +\noindent\mdline{4297}Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the \mdline{4301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4301} state.%mdk + +%mdk-data-line={4303} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4304} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}state}}~parse\_l2~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}(MAX\_TRILL\_TYPES)~trill\_types;}\\ +~~extract(hdr.ethernet);\\ +~~{\bfseries{\mdcolor{navy}select}}~(hdr.ethernet.eth\_type)~\{\\ +~~~~ETH\_TYPE\_IPV4:~parse\_ipv4;\\ +~~~~ETH\_TYPE\_IPV6:~parse\_ipv6;\\ +~~~~trill\_types:~~~parse\_trill\_types;\\ +~~~~\_:~~~~~~~~~~~~~reject;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4316} +\noindent\mdline{4316}The corresponding entry in the P4Info for this Value Set is:%mdk + +%mdk-data-line={4318} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4319} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}trill\_types}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~\textless{}MAX\_TRILL\_TYPES\textgreater{}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4333} +\noindent\mdline{4333}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4336} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4337} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x22f3}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x893b}~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4355} +\noindent\mdline{4355}As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the \mdline{4357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4357} state.%mdk + +%mdk-data-line={4359} +\mdline{4359}A \mdline{4359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4359} entity update message has the following fields:%mdk + +%mdk-data-line={4361} +\begin{itemize}%mdk + +%mdk-data-line={4361} +\item{} +%mdk-data-line={4361} +\mdline{4361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4361} is the \mdline{4361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4361} identifier of the Value Set instance, as +defined in P4Info.%mdk%mdk + +%mdk-data-line={4364} +\item{} +%mdk-data-line={4364} +\mdline{4364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4364} is a repeated field of type \mdline{4364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4364}. When \mdline{4364}\textquotedblleft{}selecting\textquotedblright{}\mdline{4364} +against a Value Set, every member will be considered and if at least one +\mdline{4366}\textquotedblleft{}matches\textquotedblright{}\mdline{4366}, the corresponding parser transition will be taken. Each +\mdline{4367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4367} contains a repeated field of \mdline{4367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4367} messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a \mdline{4369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4369} if and only if +it matches all its \mdline{4370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4370} messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. \mdline{4372}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4372} messages in a \mdline{4372}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4372} follow +the\mdline{4373}~\mdref{sec-match-format}{same rules}\mdline{4373} as in a \mdline{4373}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4373}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4375} +\noindent\mdline{4375}A \mdline{4375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4375} may only be modified. If the update type is \mdline{4375}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4375} or +\mdline{4376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4376}, the server must return an \mdline{4376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4376} error. If the update type +is \mdline{4377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4377}, the server writes the members given in the repeated field to the +Value Set entry indexed by the given \mdline{4378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4378}. The maximum number of +matches must not exceed the maximum size given by the \mdline{4379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{4379} field in P4Info of +the Value Set, otherwise the server must return a \mdline{4380}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4380} error. To +empty a Value Set (\mdline{4381}i.e.\mdline{4381} restore it to its initial state), the P4Runtime client +can perform a \mdline{4382}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4382} update with an empty \mdline{4382}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4382} repeated field.%mdk + +%mdk-data-line={4384} +\mdline{4384}To facilitate\mdline{4384}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{4384}, the server must +return an \mdline{4385}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4385} error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set.%mdk + +%mdk-data-line={4391} +\mdline{4391}See Appendix\mdline{4391}~\mdref{sec-value-set-example}{A.3}\mdline{4391} for a more complex Value Set example.%mdk + +%mdk-data-line={4393} +\subsection{\mdline{4393}9.7.\hspace*{0.5em}\mdline{4393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}\label{sec-registerentry}%mdk%mdk + +%mdk-data-line={4395} +\noindent\mdline{4395}The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The \mdline{4396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4396} P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations.%mdk + +%mdk-data-line={4400} +\mdline{4400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4400} has the following fields:%mdk + +%mdk-data-line={4402} +\begin{itemize}%mdk + +%mdk-data-line={4402} +\item{} +%mdk-data-line={4402} +\mdline{4402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4402}, which identifies the PSA Register extern instance which is +being accessed by the client; the \mdline{4403}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4403} is specified by the P4Info +message.%mdk%mdk + +%mdk-data-line={4406} +\item{} +%mdk-data-line={4406} +\mdline{4406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4406}, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the \mdline{4408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4408} message +used for the request. When an \mdline{4409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4409} is provided , the server must validate +its value, and return \mdline{4410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4410} for a negative index or +\mdline{4411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4411} if the index exceeds the size of the register array.%mdk%mdk + +%mdk-data-line={4413} +\item{} +%mdk-data-line={4413} +\mdline{4413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4413}: the data to be written to the array (if \mdline{4413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4413} is part of a +\mdline{4414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4414} message) or the data read from the array (if \mdline{4414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4414} is +part of a \mdline{4415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4415} message). The \mdline{4415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4415} field is a \mdline{4415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{4415} message and +must match the format described by the \mdline{4416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{4416} field of the corresponding +Register entry in the P4Info, or the server must return an \mdline{4417}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4417} +error.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4420} +\subsection{\mdline{4420}9.8.\hspace*{0.5em}\mdline{4420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}\label{sec-digestentry}%mdk%mdk + +%mdk-data-line={4422} +\noindent\mdline{4422}A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly.%mdk + +%mdk-data-line={4427} +\mdline{4427}The \mdline{4427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4427} P4Runtime entity is used to \mdline{4427}\textbf{configure}\mdline{4427} how the device must +generate digest messages. The \mdline{4428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4428} Protobuf message is not used to +carry digest data, which is done on the \mdline{4429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4429} bidirectional stream +using the \mdline{4430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4430} (digest data sent by the target to the client) and +\mdline{4431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4431} (digest data acknowledgments sent by the client to the target) +Protobuf messages.%mdk + +%mdk-data-line={4434} +\mdline{4434}In this section, we refer to the data learned by a single data plane call to +\mdline{4435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}T\textgreater{}::pack}}}\mdline{4435} as a \mdline{4435}\textquotedblleft{}digest message\textquotedblright{}\mdline{4435} and we use \mdline{4435}\textquotedblleft{}digest list\textquotedblright{}\mdline{4435} to designate +the list of digest messages bundled by the P4Runtime service in a single +\mdline{4437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4437} stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are \mdline{4439}\textquotedblleft{}duplicate\textquotedblright{}\mdline{4439} if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are \mdline{4440}\textquotedblleft{}distinct\textquotedblright{}\mdline{4440} +if they are not duplicate.%mdk + +%mdk-data-line={4443} +\mdline{4443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4443} has the following fields:%mdk + +%mdk-data-line={4445} +\begin{itemize}%mdk + +%mdk-data-line={4445} +\item{} +%mdk-data-line={4445} +\mdline{4445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4445}, which identifies the PSA Digest extern instance which emitted the +data; the \mdline{4446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4446} is determined by the P4Info message.%mdk%mdk + +%mdk-data-line={4448} +\item{} +%mdk-data-line={4448} +\mdline{4448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4448}, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +\mdline{4450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4450}; these parameters are:%mdk + +%mdk-data-line={4452} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4452} +\item\mdline{4452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4452}: the maximum server buffering delay in nanoseconds for an +outstanding digest message.%mdk + +%mdk-data-line={4454} +\item\mdline{4454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4454}: the maximum digest list size\mdline{4454} \mdline{4454}\textemdash{}\mdline{4454} in number of digest +messages\mdline{4455} \mdline{4455}\textemdash{}\mdline{4455} sent by the server to the client as a single \mdline{4455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4455} +Protobuf message.%mdk + +%mdk-data-line={4457} +\item\mdline{4457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4457}: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4461} +\noindent\mdline{4461}Here is the significance of the different \mdline{4461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4461} types for \mdline{4461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4461}:%mdk + +%mdk-data-line={4463} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4463} +\item\mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4463}: Enable server generation of \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4463} messages for given digest +instance and use provided configuration parameters.%mdk + +%mdk-data-line={4465} +\item\mdline{4465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4465}: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance.%mdk + +%mdk-data-line={4467} +\item\mdline{4467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4467}: Disable server generation of \mdline{4467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4467} messages for given digest +instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4470} +\noindent\mdline{4470}A server should buffer digest messages until either:%mdk + +%mdk-data-line={4472} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4472} +\item\mdline{4472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4472} time has passed since the first digest message was added to +the empty buffer, or%mdk + +%mdk-data-line={4474} +\item\mdline{4474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4474} \mdline{4474}\emph{distinct}\mdline{4474} digest messages have been received from the +data plane and added to the buffer%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4477} +\noindent\mdline{4477}At which point the server should, with best effort, generate a \mdline{4477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4477} +stream message with the buffer contents and send it to the primary client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software.%mdk + +%mdk-data-line={4483} +\mdline{4483}To avoid sending duplicate digest messages across different \mdline{4483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4483} +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the primary client indicates that it has received the +digest list and acted on it. The server must keep a \mdline{4486}\textquotedblleft{}cache\textquotedblright{}\mdline{4486} containing the set +of all digest messages that have been sent, but not acknowledged yet by the +primary client, up-to \mdline{4488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4488} in the past. The server must delete all +cache entries for a given digest list when they are at least \mdline{4489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4489} +old or when a matching \mdline{4490}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4490} message (\mdline{4490}i.e.\mdline{4490} with the same \mdline{4490}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4490} +and \mdline{4491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}list\_id}}}\mdline{4491} fields as the \mdline{4491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4491} message) is received.%mdk + +%mdk-data-line={4493} +\mdline{4493}The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged \mdline{4498}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4498} messages.%mdk + +%mdk-data-line={4500} +\mdline{4500}When \mdline{4500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4500} is set to 0 and / or \mdline{4500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4500} is set to 1, the +server should, with best effort, generate a \mdline{4501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4501} message for every +digest message generated by the data plane which is not already in the cache. If +\mdline{4503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4503} is set to 0, the cache must always be an empty set. If +\mdline{4504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4504} is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +\mdline{4506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4506} configuration parameter.%mdk + +%mdk-data-line={4508} +\mdline{4508}The P4Runtime server may empty the digest message cache in case of a client +status change.%mdk + +%mdk-data-line={4511} +\mdline{4511}Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server:%mdk + +%mdk-data-line={4514} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4515} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestStream~stream;\\ +DigestCache~cache;\\ +DigestBuffer~buffers;\\ +\\ +{\mdcolor{darkgreen}//~sends~digest~list~when~it~is~ready}\\ +send\_buffer(Id~digest\_id)~\{\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~stream.write(DigestList(buffer));\\ +~~cache.merge(buffer);~~{\mdcolor{darkgreen}//~updates~cache~with~new~digest~list}\\ +~~buffer.clear();\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~data~plane~digest~messages~from~device}\\ +handle\_dataplane\_digest(Digest~msg)~\{\\ +~~digest\_id~=~msg.digest\_id();\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~{\bfseries{\mdcolor{navy}if}}~(msg~in~cache~{\mdcolor{teal}OR}~msg~in~buffer)~{\bfseries{\mdcolor{navy}return}};\\ +~~buffer.enqueue(msg);\\ +~~{\bfseries{\mdcolor{navy}if}}~(buffer.length()~\textless{}~max\_list\_size(digest\_id))~{\bfseries{\mdcolor{navy}return}};\\ +~~send\_buffer(digest\_id);\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~ack~messages~received~on~the~stream}\\ +handle\_stream\_ack(DigestListAck~ack)~\{\\ +~~{\mdcolor{darkgreen}//~clear~all~cache~entries~matching~the~tuple~(digest\_id,~list\_id)}\\ +~~cache.erase(~(ack.digest\_id(),~ack.list\_id()~)\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~loop~to~enforce~timeouts}\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~now~=~now();\\ +~~{\mdcolor{darkgreen}//~check~for~buffers~that~need~to~be~sent}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~buffer)~in~buffers)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~buffer.first\_enq\_time()~\textgreater{}=~max\_timeout\_ns(digest\_id))\\ +~~~~~~send\_buffer(buffer\_id);\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~check~for~expired~entries~in~cache}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~list\_id,~sent\_time)~in~cache)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~sent\_time~\textgreater{}=~ack\_timeout\_ns(digest\_id))\\ +~~~~~~cache.erase(~(digest\_id,~list\_id)~);\\ +~~\}\\ +~~sleep({\mdcolor{teal}X});\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4560} +\subsection{\mdline{4560}9.9.\hspace*{0.5em}\mdline{4560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\label{sec-extern-entry}%mdk%mdk + +%mdk-data-line={4562} +\noindent\mdline{4562}This is used to support a P4 extern entity that is not part of PSA. It is +defined as:%mdk + +%mdk-data-line={4565} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4566} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ExternEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_type\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~google.protobuf.Any~entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4573} +\noindent\mdline{4573}Each \mdline{4573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4573} entity maps to an \mdline{4573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{4573} message in the +\mdline{4574}\mdref{sec-p4info-extern}{P4Info}\mdline{4574} and an \mdline{4574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4574} message within that +message. The \mdline{4575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{4575} field must be equal to the one in +\mdline{4576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4576}. The \mdline{4576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_id}}}\mdline{4576} field must be equal to the ID included in the +\mdline{4577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{4577} of the corresponding \mdline{4577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4577} message.%mdk + +%mdk-data-line={4579} +\mdline{4579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entry}}}\mdline{4579} itself is embedded as an \mdline{4579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{4579} Protobuf message\mdline{4579}~[\mdcite{protoany}{31}]\mdline{4579} to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on\mdline{4583}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{4584} for more information.%mdk + +%mdk-data-line={4586} +\section{\mdline{4586}10.\hspace*{0.5em}\mdline{4586}Error Reporting Messages}\label{sec-error-reporting-messages}%mdk%mdk + +%mdk-data-line={4588} +\noindent\mdline{4588}P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case.%mdk + +%mdk-data-line={4592} +\mdline{4592}gRPC uses \mdline{4592}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4592}~[\mdcite{grpcstatus}{32}]\mdline{4592} to represent the status returned by an +RPC. It has 3 attributes:%mdk + +%mdk-data-line={4595} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4596} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StatusCode~code\_;\\ +{\mdcolor{navy}grpc::}string~error\_message\_;\\ +{\mdcolor{navy}grpc::}string~binary\_error\_details\_;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4601} +\noindent\mdline{4601}The \mdline{4601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4601} represents a canonical error\mdline{4601}~[\mdcite{grpcstatuscodes}{34}]\mdline{4601} and describes the +overall RPC status. The \mdline{4602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4602} is a developer-facing error message, +which should be in English. The \mdline{4603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}binary\_error\_details\_}}}\mdline{4603} carries a serialized +\mdline{4604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4604} message\mdline{4604}~[\mdcite{protostatus}{28}]\mdline{4604} message, which has 3 fields:%mdk + +%mdk-data-line={4606} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4607} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}int32}}~code~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~see~code.proto}\\ +{\bfseries{\mdcolor{navy}string}}~{\bfseries{\mdcolor{navy}message}}~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +{\bfseries{\mdcolor{navy}repeated}}~google.protobuf.Any~details~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4612} +\noindent\mdline{4612}The code and message fields must be the same as \mdline{4612}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4612} and \mdline{4612}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4612} +fields from \mdline{4613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4613} above. The \mdline{4613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{4613} field is a list that consists of +\mdline{4614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4614} messages that carry error details for individual elements inside +batch-request RPCs (\mdline{4615}e.g.\mdline{4615} \mdline{4615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4615} and \mdline{4615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4615}). \mdline{4615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4615} includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices\mdline{4619}~[\mdcite{grpcstatuscodes}{34}]\mdline{4619}.%mdk + +%mdk-data-line={4621} +\mdline{4621}Figure\mdline{4621}~\mdref{fig-error-report}{\mdcaptionlabel{7}}\mdline{4621} illustrates how these messages fit together.%mdk + +%mdk-data-line={4623} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={4624} +\noindent\mdline{4624}\includegraphics[keepaspectratio=true,width=\dimwidth{0.70}]{build/error-report}{}\mdline{4624}%mdk + +%mdk-data-line={4625} +\mdhr{}%mdk + +%mdk-data-line={4626} +\noindent\mdline{4626}\mdcaption{\textbf{Figure~\mdcaptionlabel{7}.}~\mdcaptiontext{P4Runtime Error Report Message Format}}%mdk +%mdk +\end{mdcenter}\label{fig-error-report}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={4628} +\noindent\mdline{4628}gRPC provides utility functions \mdline{4628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExtractErrorDetails()}}}\mdline{4628} and \mdline{4628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetErrorDetails()}}}\mdline{4628} +\mdline{4629}[\mdcite{grpcerrordetails}{33}]\mdline{4629} to easily convert between \mdline{4629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4629} and +\mdline{4630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4630}.%mdk + +%mdk-data-line={4632} +\mdline{4632}Please see sections on individual P4Runtime RPCs for details on how +\mdline{4633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4633} is populated for reporting errors.%mdk + +%mdk-data-line={4635} +\mdline{4635}Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on\mdline{4638}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{4639} for more information.%mdk + +%mdk-data-line={4641} +\section{\mdline{4641}11.\hspace*{0.5em}\mdline{4641}Atomicity of Individual \mdline{4641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4641} and \mdline{4641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4641} Operations}\label{sec-atomicity-of-individual-write-and-read-operations}%mdk%mdk + +%mdk-data-line={4643} +\noindent\mdline{4643}Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane \mdline{4644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4644} +operation, and every single \mdline{4645}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4645} operation on a table that inserts, deletes, +or modifies one table entry, the \mdline{4646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4646} operation should behave as if that +\mdline{4647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4647} operation has not yet occurred, or as if the \mdline{4647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4647} operation is +complete. The P4 program should never behave as if the \mdline{4648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4648} operation is +partially complete. These guarantees also apply to extern instances: \mdline{4649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4649} and +\mdline{4650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4650} operations on extern entities must execute atomically relative to extern +data plane methods.%mdk + +%mdk-data-line={4653} +\mdline{4653}The atomicity guarantees provided by P4Runtime for individual \mdline{4653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4653} and \mdline{4653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4653} +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification\mdline{4655}~[\mdcite{psaatomicityofcontrolplaneops}{23}]\mdline{4655}.%mdk + +%mdk-data-line={4657} +\mdline{4657}The P4\mdline{4657}\mdsub{16}\mdline{4657} language introduces an \mdline{4657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4657} annotation\mdline{4657}~[\mdcite{p4concurrency}{14}]\mdline{4657}, to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the \mdline{4659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4659} annotation for \mdline{4659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4659} +operations, as well as\mdline{4660}~\mdref{wildcard-reads}{non-wildcard \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} operations}\mdline{4660}, +relative to data plane execution. Consider the following P4 example written for +PSA:%mdk + +%mdk-data-line={4664} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4665} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024)~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\mdcolor{darkgreen}//~...}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~Value\_t~v~=~r1.read((Index\_t){\mdcolor{purple}1});\\ +~~~~~~~~v~=~v~+~{\mdcolor{purple}1};\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~v);\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4681} +\noindent\mdline{4681}If a P4Runtime server is processing messages which write to Register \mdline{4681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4681} at +index \mdline{4682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}1}}}\mdline{4682}, these writes must not happen between the data plane \mdline{4682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}read}}}\mdline{4682} and +\mdline{4683}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}write}}}\mdline{4683}.%mdk + +%mdk-data-line={4685} +\mdline{4685}Now let\mdline{4685}'\mdline{4685}s consider the following example:%mdk + +%mdk-data-line={4687} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4688} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024,~(Value\_t){\mdcolor{purple}0}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~initial~value~}{\mdcolor{darkgreen}*/})~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}100});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}100});\\ +~~~~\}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}200});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}200});\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4706} +\noindent\mdline{4706}If a P4Runtime client issues a \mdline{4706}\emph{wildcard}\mdline{4706} \mdline{4706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4706} on Register \mdline{4706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4706}, there is no +guarantee that \mdline{4707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]~==~r1{}[2]}}}\mdline{4707} in the response, as the read for \mdline{4707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4707} may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for \mdline{4709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4709} may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read \mdline{4711}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4711} and \mdline{4711}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4711} separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +\mdline{4714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4714} message) of individual read requests. Similar to a batch +\mdline{4715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4715}, a wildcard read of a register can execute the reads of the +register array elements (\mdline{4716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4716}, \mdline{4716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4716}, \mdline{4716}\dots{}\mdline{4716}) in an arbitrary order relative +to each other.%mdk + +%mdk-data-line={4719} +\mdline{4719}If the \mdline{4719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4719} annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program.%mdk + +%mdk-data-line={4723} +\section{\mdline{4723}12.\hspace*{0.5em}\mdline{4723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4723} RPC}\label{sec-write-rpc}%mdk%mdk + +%mdk-data-line={4725} +\noindent\mdline{4725}The \mdline{4725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4725} RPC updates one or more P4 entities on the target. The request is +defined as follows:%mdk + +%mdk-data-line={4728} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4729} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~WriteRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint64}}~role\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Update~updates~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\bfseries{\mdcolor{navy}enum}}~Atomicity~\{\\ +~~~~CONTINUE\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~ROLLBACK\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~DATAPLANE\_ATOMIC~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~\}\\ +~~Atomicity~atomicity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4743} +\noindent\mdline{4743}The \mdline{4743}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4743} uniquely identifies the target P4 device. The \mdline{4743}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4743} and +\mdline{4744}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4744} define the client role and election-id as described in the +\mdline{4745}\mdref{sec-client-arbitration-and-controller-replication}{Primary-Backup Arbitration and Controller +Replication}\mdline{4746} +section. The server is expected to perform the following checks (in this order) +before processing the \mdline{4748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}updates}}}\mdline{4748} list:%mdk + +%mdk-data-line={4750} +\begin{enumerate}%mdk + +%mdk-data-line={4750} +\item{} +%mdk-data-line={4750} +\mdline{4750}If \mdline{4750}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4750} does not match any of the devices known to the P4Runtime +server or if \mdline{4751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4751} does not match any of the roles for the device, the +server must return a \mdline{4752}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4752} error.%mdk%mdk + +%mdk-data-line={4754} +\item{} +%mdk-data-line={4754} +\mdline{4754}If the client is not the primary for (\mdline{4754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4754}, \mdline{4754}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{4754}) according to +the \mdline{4755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4755} value, the server must return a \mdline{4755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4755} error.%mdk%mdk + +%mdk-data-line={4757} +\item{} +%mdk-data-line={4757} +\mdline{4757}If the \mdline{4757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4757} is attempted before a \mdline{4757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4757} has been set, +the server must return a \mdline{4758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{4758} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4760} +\noindent\mdline{4760}The updates field is a list of P4 entity updates to be applied. Each update is +defined as:%mdk + +%mdk-data-line={4763} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4764} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Update~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Type~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~INSERT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~MODIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DELETE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~Type~type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Entity~entity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4776} +\noindent\mdline{4776}This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a \mdline{4777}\emph{logical}\mdline{4777} table (\mdline{4777}e.g.\mdline{4777} +\mdline{4778}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4778}) or an actual table (\mdline{4778}e.g.\mdline{4778} \mdline{4778}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4778}) in the P4 data +plane. Each entity in the container is uniquely identified by its \mdline{4779}\emph{key}\mdline{4779}. Please +refer to the\mdline{4780}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4780} section for details on +what parts of the entity specification make up the \mdline{4781}\emph{key}\mdline{4781} for each P4 entity.%mdk + +%mdk-data-line={4783} +\mdline{4783}An update can be one of the following types:%mdk + +%mdk-data-line={4785} +\begin{itemize}%mdk + +%mdk-data-line={4785} +\item{} +%mdk-data-line={4785} +\mdline{4785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4785}: Inserts the given P4 entity in the entity container. +The \mdline{4786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{4786} field always specifies the full state of the P4 entity. +If the entity already exists, an \mdline{4787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4787} error is returned, and +the existing entity remains unchanged. +If the entity is malformed, an \mdline{4789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4789} error is returned. +If the entity cannot be inserted because the container is already full, +a \mdline{4791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4791} error is returned.%mdk%mdk + +%mdk-data-line={4793} +\item{} +%mdk-data-line={4793} +\mdline{4793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4793}: Modifies the P4 entity to its new specified state. This uses +\mdline{4794}\emph{assign}\mdline{4794} or \mdline{4794}\emph{full-snapshot}\mdline{4794} semantics, \mdline{4794}i.e.\mdline{4794} the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an \mdline{4796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4796} error is usually returned (unless a +more specific error code applies\mdline{4797}~[\mdcite{grpcstatuscodes}{34}]\mdline{4797}). If the entity does not +exist, a \mdline{4798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4798} error is returned.%mdk%mdk + +%mdk-data-line={4800} +\item{} +%mdk-data-line={4800} +\mdline{4800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4800}: Deletes the specified P4 entity. If the entity does not exist, a +\mdline{4801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4801} error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4804} +\noindent\mdline{4804}If an update is not allowed under the given controller role, the server must +return a \mdline{4805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4805} error for this update.%mdk + +%mdk-data-line={4807} +\subsection{\mdline{4807}12.1.\hspace*{0.5em}\mdline{4807}Batching and Ordering of Updates}\label{sec-batching-and-ordering-of-updates}%mdk%mdk + +%mdk-data-line={4809} +\noindent\mdline{4809}P4Runtime supports batching of \mdline{4809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4809} operations. The list of updates in a +\mdline{4810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4810} is referred to as a \mdline{4810}\emph{batch}\mdline{4810}. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of \mdline{4812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4812} entities).%mdk + +%mdk-data-line={4814} +\mdline{4814}The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +\mdline{4816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4816}s can also be processed interleaved and/or in parallel. +However, \mdline{4817}\textbf{the processing of requests must be strictly serializable}\mdline{4817}. That +is, given a history \mdline{4818}$S$\mdline{4818} of \mdline{4818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4818}s including the responses to those +requests, there must exist an order \mdline{4819}$L$\mdline{4819} for all updates in \mdline{4819}$S$\mdline{4819}, such that:%mdk + +%mdk-data-line={4821} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4821} +\item\mdline{4821}All updates from the same write request must appear as a contiguous +subsequence in \mdline{4822}$L$\mdline{4822}, but the order within that subsequence can be arbitrary.%mdk + +%mdk-data-line={4823} +\item\mdline{4823}For two updates \mdline{4823}$u_1$\mdline{4823} and \mdline{4823}$u_2$\mdline{4823}, if the write request containing \mdline{4823}$u_1$\mdline{4823} +completed before the write request of \mdline{4824}$u_2$\mdline{4824} was sent, then \mdline{4824}$u_1$\mdline{4824} must appear +before \mdline{4825}$u_2$\mdline{4825} in \mdline{4825}$L$\mdline{4825}.%mdk + +%mdk-data-line={4826} +\item\mdline{4826}Executing all updates in \mdline{4826}$L$\mdline{4826} sequentially must yield the same response for +every update as in \mdline{4827}$S$\mdline{4827}.%mdk + +%mdk-data-line={4828} +\item\mdline{4828}The observable state of the switch after \mdline{4828}$S$\mdline{4828} (\mdline{4828}e.g.\mdline{4828}, through the \mdline{4828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4828} RPC) +is identical to the one obtained by sequentially executing \mdline{4829}$L$\mdline{4829}.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4831} +\noindent\mdline{4831}The \mdline{4831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4831} RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the \mdline{4832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4832} RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (\mdline{4835}e.g.\mdline{4835} inserting an \mdline{4835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4835} +followed by pointing a \mdline{4836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4836} to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding \mdline{4838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4838} RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate \mdline{4842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4842} calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each \mdline{4843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4843} call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one.%mdk + +%mdk-data-line={4848} +\subsection{\mdline{4848}12.2.\hspace*{0.5em}\mdline{4848}Batch Atomicity}\label{sec-batch-atomicity}%mdk%mdk + +%mdk-data-line={4850} +\noindent\mdline{4850}A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the \mdline{4851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4851} +enum. A P4Runtime server is required to support only the modes marked as +\mdline{4853}\emph{Required}\mdline{4853} below:%mdk + +%mdk-data-line={4855} +\begin{itemize}%mdk + +%mdk-data-line={4855} +\item{} +%mdk-data-line={4855} +\mdline{4855}\emph{Required}\mdline{4855}: \mdline{4855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4855}: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that \mdline{4859}\emph{see}\mdline{4859} each of +these intermediate stages.%mdk%mdk + +%mdk-data-line={4862} +\item{} +%mdk-data-line={4862} +\mdline{4862}\emph{Optional}\mdline{4862}: \mdline{4862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ROLLBACK\_ON\_ERROR}}}\mdline{4862}: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is \mdline{4866}\emph{all-or-none}\mdline{4866}, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that \mdline{4870}\emph{see}\mdline{4870} each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure.%mdk + +%mdk-data-line={4875} +\mdline{4875}If a P4Runtime server does not support this option at all, an +\mdline{4876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4876} error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (\mdline{4877}e.g.\mdline{4877} it is +more straightforward to implement batches that contain only \mdline{4878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4878} +operations, vs. those that contain \mdline{4879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4879} operations), an +\mdline{4880}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4880} error is returned when the batch cannot be executed +in a data plane-atomic way.%mdk%mdk + +%mdk-data-line={4883} +\item{} +%mdk-data-line={4883} +\mdline{4883}\emph{Optional}\mdline{4883}: \mdline{4883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4883}: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +\mdline{4887}\emph{transaction}\mdline{4887}. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane\mdline{4889}'\mdline{4889}s table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table.%mdk + +%mdk-data-line={4896} +\mdline{4896}If a P4Runtime server does not support this option at all, an \mdline{4896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4896} +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an \mdline{4898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4898} error is returned when the batch +cannot be executed in a data plane-atomic way.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4901} +\noindent\mdline{4901}There is no expectation that a given client must always use the same \mdline{4901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4901} +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use \mdline{4904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4904} at one time and default behavior +(\mdline{4905}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4905}) at other times.%mdk + +%mdk-data-line={4907} +\subsection{\mdline{4907}12.3.\hspace*{0.5em}\mdline{4907}Error Reporting}\label{sec-error-reporting}%mdk%mdk + +%mdk-data-line={4909} +\noindent\mdline{4909}Please see section\mdline{4909}~\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{4909} for +information on error reporting messages and guidelines. P4Runtime server will +populate \mdline{4911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4911} as follows:%mdk + +%mdk-data-line={4913} +\begin{enumerate}%mdk + +%mdk-data-line={4913} +\item{} +%mdk-data-line={4913} +\mdline{4913}If all batch updates succeeded, set \mdline{4913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4913} to \mdline{4913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4913} and do not +populate any other field.%mdk%mdk + +%mdk-data-line={4916} +\item{} +%mdk-data-line={4916} +\mdline{4916}If an error is encountered before even trying to attempt individual batch +updates, set \mdline{4917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4917} that best describes that RPC-wide +error. For example, use \mdline{4918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNAVAILABLE}}}\mdline{4918} if the P4Runtime service is not yet +ready to handle requests. Set \mdline{4919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4919} to describe the issue. Do not +set \mdline{4920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_details}}}\mdline{4920} in this case.%mdk%mdk + +%mdk-data-line={4922} +\item{} +%mdk-data-line={4922} +\mdline{4922}Otherwise, if one or more updates in the batch (\mdline{4922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest.updates}}}\mdline{4922}) +failed, set \mdline{4923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4923} to \mdline{4923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{4923}. For example, one update in +the batch may fail with \mdline{4924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4924} and another with +\mdline{4925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4925}. A \mdline{4925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4925} message is used to capture the status of +each and every update in the batch. The number of \mdline{4926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4926} messages packed +into \mdline{4927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{4927} field should therefore always match the +number of updates in the \mdline{4928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4928}, and the order of +\mdline{4929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4929} messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +\mdline{4931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4931} should set the code to \mdline{4931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4931} and omit other fields.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4933} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4934} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}\#~Example~of~a~grpc::Status~returned~for~a~Write~RPC~with~a~batch~of~3~updates.}\\ +{\mdcolor{darkgreen}\#~The~first~and~third~updates~encountered~an~error,~while~the~second~update}\\ +{\mdcolor{darkgreen}\#~succeeded.}\\ +code\_~=~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +error\_message\_~=~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +binary\_error\_details~\{\\ +~~code:~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}8}~~{\mdcolor{darkgreen}\#~RESOURCE\_EXHAUSTED}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Table~is~full.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}500}~~{\mdcolor{darkgreen}\#~ERR\_TABLE\_FULL}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}0}~~{\mdcolor{darkgreen}\#~OK}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}6}~~{\mdcolor{darkgreen}\#~ALREADY\_EXISTS}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Entity~already~exists.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}600}~~{\mdcolor{darkgreen}\#~ERR\_ENTITY\_ALREADY\_EXISTS}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4960} +\section{\mdline{4960}13.\hspace*{0.5em}\mdline{4960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4960} RPC}\label{sec-read-rpc}%mdk%mdk + +%mdk-data-line={4962} +\noindent\mdline{4962}The \mdline{4962}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4962} RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as:%mdk + +%mdk-data-line={4965} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4966} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4972} +\noindent\mdline{4972}The \mdline{4972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4972} uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +\mdline{4974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4974} error. The \mdline{4974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{4974} repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server.%mdk + +%mdk-data-line={4977} +\mdline{4977}Since \mdline{4977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4977}s do not mutate any state on the switch, they do not +require an \mdline{4978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4978}, and they do not require the presence of an open +\mdline{4979}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4979} between the server and client.%mdk + +%mdk-data-line={4981} +\mdline{4981}The \mdline{4981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read~}}}\mdline{4981}response consists of a sequence of messages (a gRPC \mdline{4981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}stream}}}\mdline{4981}) with +each message defined as:%mdk + +%mdk-data-line={4984} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4985} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadResponse~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4990} +\noindent\mdline{4990}The \mdline{4990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{4990} repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the \mdline{4994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Finish()}}}\mdline{4994} method on the stream object +\mdline{4995}[\mdcite{grpcstreamc}{10}]\mdline{4995}).%mdk + +%mdk-data-line={4997} +\subsection{\mdline{4997}13.1.\hspace*{0.5em}\mdline{4997}Nomenclature}\label{sec-nomenclature}%mdk%mdk + +%mdk-data-line={4999} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries request}}%mdk + +%mdk-data-line={4999} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{4999}An element of the \mdline{4999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{4999} repeated field. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries batch}}%mdk + +%mdk-data-line={5001} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{5001}Refers to the \mdline{5001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{5001} repeated field.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={5004} +\noindent\mdline{5004}Each \mdline{5004}\emph{request}\mdline{5004} acts as a query filter for that entity type. If a \mdline{5004}\emph{request}\mdline{5004} fully +specifies the entity key, the \mdline{5005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5005} operation should retrieve a single P4 +entity. Please refer to the\mdline{5006}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{5006} section +for details on what parts of the entity specification make up the entity \mdline{5007}\emph{key}\mdline{5007}.%mdk + +%mdk-data-line={5009} +\subsection{\mdline{5009}13.2.\hspace*{0.5em}\mdline{5009}Wildcard Reads}\label{sec-wildcard-reads}%mdk%mdk + +%mdk-data-line={5011} +\noindent\mdline{5011}P4Runtime allows wildcard read of P4 entities. A \mdline{5011}\emph{request}\mdline{5011} may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the\mdline{5013}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{5013} section for details on +what parts of the entity can be wildcarded in a given \mdline{5014}\emph{request}\mdline{5014}.%mdk + +%mdk-data-line={5016} +\mdline{5016}For example, in a \mdline{5016}\emph{request}\mdline{5016} of type \mdline{5016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{5016}:%mdk + +%mdk-data-line={5018} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5018} +\item\mdline{5018}A default \mdline{5018}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{5018} (0) implies a request to read all counter-entries for +all indirect counters.%mdk + +%mdk-data-line={5020} +\item\mdline{5020}A particular (non-default) \mdline{5020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{5020} in conjunction with \mdline{5020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{5020} unset +implies a request to read all counter-entries for the given indirect counter +ID.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5024} +\noindent\mdline{5024}To read the entire forwarding state for a given device, the P4Runtime client can +generate the following \mdline{5025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5025}:%mdk + +%mdk-data-line={5027} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5028} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~\textless{}ID\textgreater{}\\ +entities~\{\\ +~~extern\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~extern~instances~for~all~supported~extern~types}\\ +~~table\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~table~entries~for~all~tables}\\ +~~action\_profile\_member~\{~\}~~{\mdcolor{darkgreen}\#~read~all~members~for~all~action~profiles}\\ +~~action\_profile\_group~\{~\}~~{\mdcolor{darkgreen}\#~read~all~groups~for~all~action~profiles}\\ +~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5038} +\noindent\mdline{5038}The \mdline{5038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5038} oneof field in the \mdline{5038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5038} message must always be set, or the +server must return an \mdline{5039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5039} error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty \mdline{5041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5041} message in the \mdline{5041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5041}. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the \mdline{5043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5043} oneof\mdline{5043}~[\mdcite{protooneofbackwardscompatibility}{20}]\mdline{5043}.%mdk + +%mdk-data-line={5045} +\subsection{\mdline{5045}13.3.\hspace*{0.5em}\mdline{5045}Batch Processing}\label{sec-batch-processing}%mdk%mdk + +%mdk-data-line={5047} +\noindent\mdline{5047}A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type \mdline{5048}\emph{request}\mdline{5048} +appears only once in the batch.%mdk + +%mdk-data-line={5051} +\mdline{5051}A P4Runtime server will process the batch as follows:%mdk + +%mdk-data-line={5053} +\begin{enumerate}%mdk + +%mdk-data-line={5053} +\item{} +%mdk-data-line={5053} +\mdline{5053}Lock state (preventing new writes) and validate each \mdline{5053}\emph{request}\mdline{5053} in the batch:%mdk + +%mdk-data-line={5055} +\begin{enumerate}%mdk + +%mdk-data-line={5055} +\item{} +%mdk-data-line={5055} +\mdline{5055}If it is a valid \mdline{5055}\emph{request}\mdline{5055}, perform the read;%mdk + +%mdk-data-line={5057} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5057} +\item\mdline{5057}If the read was successful, return the entities read in +\mdline{5058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5058} stream.%mdk + +%mdk-data-line={5059} +\item\mdline{5059}If the read failed (exception / critical-error), prepare a \mdline{5059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5059} +with code set to \mdline{5060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INTERNAL}}}\mdline{5060}.%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5062} +\item{} +%mdk-data-line={5062} +\mdline{5062}If the \mdline{5062}\emph{request}\mdline{5062} is invalid (invalid-argument, not-supported, etc.), +prepare a \mdline{5063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5063} with relevant canonical code to capture the error.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5065} +\item{} +%mdk-data-line={5065} +\mdline{5065}Unlock the state (allowing new writes);%mdk%mdk + +%mdk-data-line={5067} +\item{} +%mdk-data-line={5067} +\mdline{5067}Close the \mdline{5067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5067} stream and return a \mdline{5067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5067} as follows:%mdk + +%mdk-data-line={5069} +\begin{enumerate}%mdk + +%mdk-data-line={5069} +\item{} +%mdk-data-line={5069} +\mdline{5069}If no errors were encountered, set code to \mdline{5069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{5069} and do not populate any +other field.%mdk%mdk + +%mdk-data-line={5072} +\item{} +%mdk-data-line={5072} +\mdline{5072}Otherwise, the overall code should be set to \mdline{5072}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{5072}. See section +\mdline{5073}\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{5073} for information +on error reporting messages and guidelines. Assemble a list of \mdline{5074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5074} +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +\mdline{5078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{5078} field. This behavior also matches \mdline{5078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5078} +RPC.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5081} +\subsubsection{\mdline{5081}13.3.1.\hspace*{0.5em}\mdline{5081}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={5083} +\noindent\mdline{5083}If a client asked to read \mdline{5083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{a,b,c,d\}}}}\mdline{5083} and \mdline{5083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}b}}}\mdline{5083} and \mdline{5083}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}d}}}\mdline{5083} \mdline{5083}\emph{requests}\mdline{5083} didn\mdline{5083}'\mdline{5083}t +validate, the server will return entities corresponding to \mdline{5084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5084} and \mdline{5084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}c}}}\mdline{5084}, followed +by a status \mdline{5085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{p4.Error(OK),~p4.Error(xxx),~p4.Error(yyy),~p4.Error(OK)\}}}}\mdline{5085} in the +\mdline{5086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5086} field.%mdk + +%mdk-data-line={5088} +\mdline{5088}The P4Runtime server is not required to perform any optimization (\mdline{5088}e.g.\mdline{5088} merge two +\mdline{5089}\emph{requests}\mdline{5089} in the \mdline{5089}\emph{batch}\mdline{5089} if one is a subset of other). As a result of this, it +is possible for the \mdline{5090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5090} to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging.%mdk + +%mdk-data-line={5093} +\mdline{5093}There is no requirement that each request in the batch will correspond to one +\mdline{5094}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5094} message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit.%mdk + +%mdk-data-line={5099} +\mdline{5099}A P4Runtime server must be prepared to handle multiple concurrent \mdline{5099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5099} RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (\mdline{5104}e.g.\mdline{5104} in a single-threaded architecture), it may choose to serialize +\mdline{5105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5105} RPC processing.%mdk + +%mdk-data-line={5107} +\subsection{\mdline{5107}13.4.\hspace*{0.5em}\mdline{5107}Parallelism of Read and Write Requests}\label{sec-parallelism-of-read-and-write-requests}%mdk%mdk + +%mdk-data-line={5109} +\noindent\mdline{5109}A P4Runtime server may be implemented to serve at most one +\mdline{5110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5110} or \mdline{5110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5110} message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so.%mdk + +%mdk-data-line={5115} +\mdline{5115}For example, imagine a client that wanted to use \mdline{5115}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5115} +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +\mdline{5119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5119} messages with only a few updates to an \mdline{5119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{5119} +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +\mdline{5122}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5122} batch currently being processed, but it will not +complete for a significant amount of time.%mdk + +%mdk-data-line={5125} +\mdline{5125}The restrictions on which a client may rely are:%mdk + +%mdk-data-line={5127} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5127} +\item\mdline{5127}The processing of any two \mdline{5127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5127} messages \mdline{5127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W1}}}\mdline{5127} and \mdline{5127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W2}}}\mdline{5127} must +result in the same state as if one of them was completed before the +other began.%mdk + +%mdk-data-line={5130} +\item\mdline{5130}For any \mdline{5130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5130} \mdline{5130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5130} and any \mdline{5130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5130} \mdline{5130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5130}, \mdline{5130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5130} must +return results consistent with a state where \mdline{5131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5131} has completed +processing, or \mdline{5132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5132} has not yet begun processing.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5134} +\noindent\mdline{5134}For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a \mdline{5137}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5137} message it acquired a write lock for each stateful +object affected by the \mdline{5138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5138}, and before starting the +processing of a \mdline{5139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5139} message it acquired a read lock for each +stateful object accessed by the \mdline{5140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5140}, such an implementation +meets all of the requirements above.%mdk + +%mdk-data-line={5143} +\mdline{5143}It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, \mdline{5145}e.g.\mdline{5145} if the server somehow determined that two +\mdline{5146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5146} messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly.%mdk + +%mdk-data-line={5152} +\section{\mdline{5152}14.\hspace*{0.5em}\mdline{5152}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5152} RPC}\label{sec-setforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5154} +\noindent\mdline{5154}A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the \mdline{5155}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig~RPC}}}\mdline{5155}. The request is defined as:%mdk + +%mdk-data-line={5157} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5158} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~SetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Action~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~VERIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~VERIFY\_AND\_SAVE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~VERIFY\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~~~COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~~~RECONCILE\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint64}}~role\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~Action~action~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5175} +\noindent\mdline{5175}The server is expected to perform the following checks (in this order) +before performing the required \mdline{5176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{5176}:%mdk + +%mdk-data-line={5178} +\begin{enumerate}%mdk + +%mdk-data-line={5178} +\item{} +%mdk-data-line={5178} +\mdline{5178}If \mdline{5178}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5178} does not match any of the devices known to the P4Runtime +server or if \mdline{5179}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{5179} does not match any of the roles for the device, the +server must return a \mdline{5180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5180} error.%mdk%mdk + +%mdk-data-line={5182} +\item{} +%mdk-data-line={5182} +\mdline{5182}If the client is not the primary for (\mdline{5182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5182}, \mdline{5182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{5182}) according to +the \mdline{5183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5183} value, the server must return a \mdline{5183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5183} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5185} +\noindent\mdline{5185}The action is the type of configuration action requested, it can be one of:%mdk + +%mdk-data-line={5187} +\begin{itemize}%mdk + +%mdk-data-line={5187} +\item{} +%mdk-data-line={5187} +\mdline{5187}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY}}}\mdline{5187}: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5188} +error if config is not provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5191} +\item{} +%mdk-data-line={5191} +\mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5191}: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent \mdline{5193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5193} / \mdline{5193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5193} requests must refer to fields in the new +config. Returns an \mdline{5194}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5194} error if the forwarding config is not +provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5197} +\item{} +%mdk-data-line={5197} +\mdline{5197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_COMMIT}}}\mdline{5197}: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an \mdline{5199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5199} error if the forwarding config is not provided or if the +provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5202} +\item{} +%mdk-data-line={5202} +\mdline{5202}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COMMIT}}}\mdline{5202}: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a \mdline{5205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5205} error if no saved config +is found, \mdline{5206}i.e.\mdline{5206} if no \mdline{5206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5206} action preceded this one. Returns an +\mdline{5207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5207} error if a config is provided with this message.%mdk%mdk + +%mdk-data-line={5209} +\item{} +%mdk-data-line={5209} +\mdline{5209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RECONCILE\_AND\_COMMIT}}}\mdline{5209}: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an \mdline{5215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5215} error. For targets that support this option, an +\mdline{5216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5216} error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5220} +\noindent\mdline{5220}The \mdline{5220}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5220} field is a message of type \mdline{5220}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5220} that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(\mdline{5222}e.g.\mdline{5222} generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the\mdline{5223}~\mdref{sec-p4-fwd-pipe-config}{Forwarding-Pipeline +Configuration}\mdline{5224} section for details.%mdk + +%mdk-data-line={5226} +\mdline{5226}A P4Runtime server running on a non-programmable device may not +support \mdline{5227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5227} (\mdline{5227}e.g.\mdline{5227} the forwarding-pipeline +config is part of the device\mdline{5228}'\mdline{5228}s software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +\mdline{5230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5230} error.%mdk + +%mdk-data-line={5232} +\section{\mdline{5232}15.\hspace*{0.5em}\mdline{5232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5232} RPC}\label{sec-getforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5234} +\noindent\mdline{5234}The forwarding-pipeline configuration of the target can be retrieved by invoking +the \mdline{5235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig~RPC}}}\mdline{5235}. The request is defined as:%mdk + +%mdk-data-line={5237} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5238} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~ResponseType~\{\\ +~~~~ALL~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~COOKIE\_ONLY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~P{\mdcolor{purple}4}INFO\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DEVICE\_CONFIG\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~ResponseType~response\_type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5250} +\noindent\mdline{5250}The \mdline{5250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5250} uniquely identifies the target P4 device. A \mdline{5250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5250} error is +returned if the \mdline{5251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5251} is not recognized by the P4Runtime server.%mdk + +%mdk-data-line={5253} +\mdline{5253}The \mdline{5253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5253} is used to specify which fields to populate in the response, +its value can be one of:%mdk + +%mdk-data-line={5256} +\begin{itemize}%mdk + +%mdk-data-line={5256} +\item{} +%mdk-data-line={5256} +\mdline{5256}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5256}: returns a \mdline{5256}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5256} with all fields +set as stored by the target. This is the default behaviour if the +\mdline{5258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5258} field is not set.%mdk%mdk + +%mdk-data-line={5260} +\item{} +%mdk-data-line={5260} +\mdline{5260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COOKIE\_ONLY}}}\mdline{5260}: reply by setting only the \mdline{5260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5260} field in the +\mdline{5261}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5261}, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message.%mdk%mdk + +%mdk-data-line={5265} +\item{} +%mdk-data-line={5265} +\mdline{5265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4INFO\_AND\_COOKIE}}}\mdline{5265}: reply by setting the \mdline{5265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{5265} and \mdline{5265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5265} fields.%mdk%mdk + +%mdk-data-line={5267} +\item{} +%mdk-data-line={5267} +\mdline{5267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEVICE\_CONFIG\_AND\_COOKIE}}}\mdline{5267}: reply by setting the \mdline{5267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5267} and +\mdline{5268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5268} fields.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5270} +\noindent\mdline{5270}The response contains the \mdline{5270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5270} for the specified device:%mdk + +%mdk-data-line={5272} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5273} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigResponse~\{\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5278} +\noindent\mdline{5278}If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level \mdline{5279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5279} field will be unset in the response. Examples are +(i) a server that only allows configuration via \mdline{5280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5280} +but this RPC hasn\mdline{5281}'\mdline{5281}t been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn\mdline{5282}'\mdline{5282}t yet occurred.%mdk + +%mdk-data-line={5284} +\mdline{5284}Once a forwarding-pipeline config is installed on the device (either via +\mdline{5285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5285} or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +\mdline{5287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.p4\_device\_config}}}\mdline{5287} will be empty / unset in the response, even if +\mdline{5288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5288} in the request was set to \mdline{5288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5288}. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the \mdline{5290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5290} RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +\mdline{5292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5292}, the value of \mdline{5292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.cookie}}}\mdline{5292} will be unset.%mdk + +%mdk-data-line={5294} +\mdline{5294}If a P4Runtime server supports both \mdline{5294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5294} as well as +returning the \mdline{5295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5295}, there should be read-write symmetry between +\mdline{5296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5296} and \mdline{5296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5296} RPCs.%mdk + +%mdk-data-line={5298} +\section{\mdline{5298}16.\hspace*{0.5em}\mdline{5298}P4Runtime Stream Messages}\label{sec-p4runtime-stream-messages}%mdk%mdk + +%mdk-data-line={5300} +\subsection{\mdline{5300}16.1.\hspace*{0.5em}\mdline{5300}Packet I/O}\label{sec-packet-i_o}%mdk%mdk + +%mdk-data-line={5302} +\noindent\mdline{5302}P4Runtime supports controller packet-in and packet-out by means of \mdline{5302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5302} +and \mdline{5303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5303} stream messages, respectively.%mdk + +%mdk-data-line={5305} +\mdline{5305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5305} messages are sent by the P4Runtime server to the client. Conversely, +\mdline{5306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5306} messages are sent by the client to the server. Any \mdline{5306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5306} +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a \mdline{5309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5309} message with the \mdline{5309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5309} field set to +report the error to the client. See the section on\mdline{5310}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{5311} for more information on \mdline{5311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5311}.%mdk + +%mdk-data-line={5313} +\mdline{5313}As introduced in the\mdline{5313}~\mdref{sec-controller-packet-meta}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\mdline{5313} +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with \mdline{5315}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5315}. The expected metadata is described +in the P4Info using the \mdline{5316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5316} messages.%mdk + +%mdk-data-line={5318} +\mdline{5318}Both \mdline{5318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5318} and \mdline{5318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5318} stream messages share the same fields and are +defined as follows:%mdk + +%mdk-data-line={5321} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5322} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Packet~sent~from~the~controller~to~the~switch.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketOut~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~Packet~sent~from~the~switch~to~the~controller.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketIn~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~PacketMetadata~\{\\ +~~{\mdcolor{darkgreen}//~This~refers~to~Metadata.id~coming~from~P4Info~ControllerPacketMetadata.}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~metadata\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5341} +\begin{itemize}%mdk + +%mdk-data-line={5341} +\item{} +%mdk-data-line={5341} +\mdline{5341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}payload}}}\mdline{5341} is used to carry the full packet content, including the headers.%mdk%mdk + +%mdk-data-line={5343} +\item{} +%mdk-data-line={5343} +\mdline{5343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5343} is a repeated field of \mdline{5343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{5343} messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +\mdline{5346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5346}. Indeed, when a P4Runtime client (or server) +generates a \mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5347} (or \mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5347}) message, it needs to populate the +\mdline{5348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5348} field with as many values as in \mdline{5348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{5348} +for the packet-out (or packet-in) case. Each \mdline{5349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata.value}}}\mdline{5349} is a +binary string and must conform to the\mdline{5350}~\mdref{sec-bytestrings}{Bytestrings}\mdline{5350} +requirements based on the corresponding P4Info +\mdline{5352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{5352} specification. If the \mdline{5352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5352} field +does not match the P4Info specification, the server must drop the \mdline{5353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5353} +message and may generate a \mdline{5354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5354} message with the \mdline{5354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5354} +field set to report the error to the client which issued the \mdline{5355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5355}. See +the section on\mdline{5356}~\mdref{sec-stream-error-reporting}{Stream Error Reporting}\mdline{5356} for more +information on \mdline{5357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5357}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5359} +\subsection{\mdline{5359}16.2.\hspace*{0.5em}\mdline{5359}Client Arbitration Update}\label{sec-client-arbitration-update}%mdk%mdk + +%mdk-data-line={5361} +\noindent\mdline{5361}P4Runtime\mdline{5361}'\mdline{5361}s client arbitration mechanism ensures that only the current primary +can modify state on the switch, and that the \mdline{5362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5362} is monotonically +increasing. For example, the switch must finish all previous write operations +before before selecting a different primary, and must only accept write requests +from the current primary.%mdk + +%mdk-data-line={5367} +\mdline{5367}As explained earlier in this document, the controller uses the \mdline{5367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5367} +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via \mdline{5369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5369} RPC), +it needs to start a controller session and become a \mdline{5370}\textquotedblleft{}primary\textquotedblright{}\mdline{5370}. To do so, the +controller first opens a bidirectional stream channel to the server via +\mdline{5372}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5372} for each device and sends a \mdline{5372}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5372} message. The +controller populates the \mdline{5373}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5373} field in this message using +its \mdline{5374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{5374} and \mdline{5374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5374} and the \mdline{5374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5374} of the device, as explained +in detail in the\mdline{5375}~\mdref{sec-client-arbitration-and-controller-replication}{Client Arbitration and Controller +Replication}\mdline{5376} +section. For any given \mdline{5377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role\_id)}}}\mdline{5377}, the P4Runtime server keeps track +of the highest \mdline{5378}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5378} that it has ever received. If a controller\mdline{5378}'\mdline{5378}s +\mdline{5379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5379} is equal to the highest \mdline{5379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5379} that the server has ever +received, that controller is the primary. All other controllers are backups. +Note that it is possible that all controllers are backups, and that there is no +primary. There can be at most one primary, because for any given +\mdline{5383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role\_id)}}}\mdline{5383}, each connected controller has a unique \mdline{5383}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5383}.%mdk + +%mdk-data-line={5385} +\mdline{5385}This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest \mdline{5386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5386} after such a restart. +However, across a\mdline{5387}~\mdref{sec-restarts}{full restart}\mdline{5387}, the \mdline{5387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5387} must be +reset. In fact, a full restart is the only way to reset the \mdline{5388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5388}.%mdk + +%mdk-data-line={5390} +\mdline{5390}The \mdline{5390}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5390} message is defined as follows:%mdk + +%mdk-data-line={5392} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5393} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MasterArbitrationUpdate~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~The~role~for~which~the~primary~client~is~being~arbitrated.~For~use-cases}\\ +~~{\mdcolor{darkgreen}//~where~multiple~roles~are~not~needed,~the~controller~can~leave~this~unset,}\\ +~~{\mdcolor{darkgreen}//~implying~default~role~and~full~pipeline~access.}\\ +~~Role~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~The~stream~RPC~with~the~highest~election\_id~is~the~primary.~The~'primary'}\\ +~~{\mdcolor{darkgreen}//~controller~instance~populates~this~with~its~latest~election\_id.~Switch}\\ +~~{\mdcolor{darkgreen}//~populates~with~the~highest~election~ID~it~has~received~from~all~connected}\\ +~~{\mdcolor{darkgreen}//~controllers.}\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Switch~populates~this~with~OK~for~the~client~that~is~the~primary,~and}\\ +~~{\mdcolor{darkgreen}//~with~an~error~status~for~all~other~connected~clients~(at~every~primary}\\ +~~{\mdcolor{darkgreen}//~client~change).~The~controller~does~not~populate~this~field.}\\ +~~.google.{\bfseries{\mdcolor{navy}rpc}}.Status~status~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Role~\{\\ +~~{\mdcolor{darkgreen}//~Uniquely~identifies~this~role.}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Describes~the~role~configuration,~i.e.~what~operations,~P4~entities,}\\ +~~{\mdcolor{darkgreen}//~behaviors,~etc.~are~in~the~scope~of~a~given~role.~If~config~is~not~set}\\ +~~{\mdcolor{darkgreen}//~(default~case),~it~implies~all~P4~objects~and~control~behaviors~are~in}\\ +~~{\mdcolor{darkgreen}//~scope,~i.e.~full~pipeline~access.~The~format~of~this~message~is}\\ +~~{\mdcolor{darkgreen}//~out-of-scope~of~P4Runtime.}\\ +~~.google.protobuf.Any~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5422} +\noindent\mdline{5422}Note that the \mdline{5422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5422} field in the \mdline{5422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5422} message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a \mdline{5424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5424} message back to the controller, in which +it populates the \mdline{5425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5425} message using the \mdline{5425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5425}, +\mdline{5426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5426}, and \mdline{5426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5426} it previously received from the controller. The server +also populates the \mdline{5427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5427} field in the \mdline{5427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5427} according to +the rules in an\mdline{5428}~\mdref{sec-arbitration-updates}{earlier section}\mdline{5428}.%mdk + +%mdk-data-line={5430} +\mdline{5430}The sender need not specify an \mdline{5430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5430}. If the \mdline{5430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5430} is not +specified, the sender\mdline{5431}'\mdline{5431}s \mdline{5431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5431} is considered lower than any +\mdline{5432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5432}, and the sender will thus never become primary. This way, a +controller can choose to be a backup controller, in order to avoid +\mdline{5434}\textquotedblleft{}flapping\textquotedblright{}\mdline{5434} (if a backup controller connects to the switch shortly before the +actual primary controller, therefore becoming primary temporarily).%mdk + +%mdk-data-line={5438} +\subsection{\mdline{5438}16.3.\hspace*{0.5em}\mdline{5438}Digest Messages}\label{sec-digest-messages}%mdk%mdk + +%mdk-data-line={5440} +\noindent\mdline{5440}See the\mdline{5440}~\mdref{sec-digestentry}{DigestEntry}\mdline{5440} section.%mdk + +%mdk-data-line={5442} +\subsection{\mdline{5442}16.4.\hspace*{0.5em}\mdline{5442}Table Idle Timeout Notification}\label{sec-table-idle-timeout-notification}%mdk%mdk + +%mdk-data-line={5444} +\noindent\mdline{5444}When a table supports idle timeout (as per the P4Info message), the primary +client can specify a TTL value for each entry in the table (see +\mdline{5446}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{5446} section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an \mdline{5448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5448} message on the +\mdline{5449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5449} bidirectional stream to the primary client. The primary client +can then take the action of its choice, most likely remove the idle entry.%mdk + +%mdk-data-line={5452} +\mdline{5452}The \mdline{5452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5452} Protobuf message has the following fields:%mdk + +%mdk-data-line={5454} +\begin{itemize}%mdk + +%mdk-data-line={5454} +\item{} +%mdk-data-line={5454} +\mdline{5454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}timestamp}}}\mdline{5454}: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server\mdline{5455}'\mdline{5455}s local clock.%mdk%mdk + +%mdk-data-line={5457} +\item{} +%mdk-data-line={5457} +\mdline{5457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5457}: a repeated field of entries which have expired. Each individual +entry is identified by a single \mdline{5458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5458} message. For each \mdline{5458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5458}, +the \mdline{5459}\emph{key}\mdline{5459} fields (\mdline{5459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{5459}, \mdline{5459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{5459} and \mdline{5459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{5459}) must be set, along with +the \mdline{5460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{5460} field, the \mdline{5460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5460} field, and the +\mdline{5461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{5461} field. Other fields may be set by the server but should be +ignored by the client.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5464} +\noindent\mdline{5464}Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +\mdline{5466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5466} message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an \mdline{5471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5471} +message with an empty \mdline{5472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5472} repeated field.%mdk + +%mdk-data-line={5474} +\mdline{5474}After generating an idle notification, the P4Runtime server must \mdline{5474}\textquotedblleft{}reset\textquotedblright{}\mdline{5474} the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the primary client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle.%mdk + +%mdk-data-line={5481} +\mdline{5481}Here is a reasonable pseudo-code implementation for idle timeout for table +entries:%mdk + +%mdk-data-line={5484} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5485} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutStream~stream;\\ +\\ +scanning\_interval~=~{\mdcolor{purple}10}ms;\\ +\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~{\mdcolor{darkgreen}//~iterate~over~all~tables~which~support~idle~timeout}\\ +~~{\bfseries{\mdcolor{navy}for}}~(table~in~tables)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(!table.idle\_timeout\_supported)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~{\mdcolor{darkgreen}//~we~coalesce~all~idle~notifications~for~the~same~table~in~one}\\ +~~~~{\mdcolor{darkgreen}//~message}\\ +~~~~IdleTimeoutNotification~msg;\\ +~~~~{\mdcolor{darkgreen}//~read~time\_since\_last\_hit~from~device}\\ +~~~~entries~=~device.load\_table\_entries\_from\_hw(table);\\ +~~~~{\bfseries{\mdcolor{navy}for}}~(entry~in~entries)~\{\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.idle\_timeout~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~TTL}\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.time\_since\_last\_hit~\textless{}~entry.idle\_timeout)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~~~msg.table\_entry\_add(entry);\\ +~~~~~~entry.reset\_time\_since\_last\_hit();\\ +~~~~\}\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(msg.table\_entry\_size()~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~notifications}\\ +~~~~msg.set\_timestamp(now());\\ +~~~~stream.write(msg);\\ +~~\}\\ +~~sleep(scanning\_interval);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5512} +\subsection{\mdline{5512}16.5.\hspace*{0.5em}\mdline{5512}Architecture-Specific Notifications}\label{sec-architecture-specific-notifications}%mdk%mdk + +%mdk-data-line={5514} +\noindent\mdline{5514}P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on \mdline{5515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5515}, by including an \mdline{5515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5515} Protobuf field\mdline{5515}~[\mdcite{protoany}{31}]\mdline{5515} +named \mdline{5516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5516} in both \mdline{5516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5516} and \mdline{5516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5516}. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the\mdline{5518}~\mdref{sec-digestentry}{PSA \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}} +extern}\mdline{5519}. See section on\mdline{5519}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{5520} for more information.%mdk + +%mdk-data-line={5522} +\subsection{\mdline{5522}16.6.\hspace*{0.5em}\mdline{5522}Stream Error Reporting}\label{sec-stream-error-reporting}%mdk%mdk + +%mdk-data-line={5524} +\noindent\mdline{5524}The P4Runtime server can asynchronously report errors which occur when +processing \mdline{5525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5525} messages, using the \mdline{5525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5525} message field (of +type \mdline{5526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5526}) in \mdline{5526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5526}. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature.%mdk + +%mdk-data-line={5530} +\mdline{5530}The \mdline{5530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5530} message has the following fields:%mdk + +%mdk-data-line={5532} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5532} +\item\mdline{5532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5532}, which must be set to the appropriate canonical error code +\mdline{5533}[\mdcite{grpcstatuscodes}{34}]\mdline{5533}.%mdk + +%mdk-data-line={5534} +\item\mdline{5534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{5534}, an optional developer-facing error message describing the error.%mdk + +%mdk-data-line={5535} +\item\mdline{5535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5535} and \mdline{5535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5535}, which are optional and can be used by vendors to provide +additional details on the error. \mdline{5536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5536} is a numeric error code drawn from a +vendor\mdline{5537}'\mdline{5537}s chosen error \mdline{5537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5537}.%mdk + +%mdk-data-line={5538} +\item\mdline{5538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5538}, which is a Protobuf \mdline{5538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5538} used to help the client identify which +\mdline{5539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5539} triggered the error. The server is required to set the +appropriate field in the \mdline{5540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5540} so that the client can identify which type +of stream message is responsible for the error (\mdline{5541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5541}, +\mdline{5542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_list\_ack}}}\mdline{5542} or \mdline{5542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5542}), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid \mdline{5544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5544} message from the +client, the \mdline{5545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5545} field (of type \mdline{5545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError)}}}\mdline{5545} should be set in +the \mdline{5546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5546} \mdline{5546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5546}, and the server may additionally set the \mdline{5546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5546} +field in the \mdline{5547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError}}}\mdline{5547} sub-message (by copying it from the invalid +\mdline{5548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5548} message received on the stream channel) so that the client can +know exactly what packet-out triggered the error.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5551} +\noindent\mdline{5551}The appropriate canonical error code\mdline{5551}~[\mdcite{grpcstatuscodes}{34}]\mdline{5551} should be used when +populating the \mdline{5552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5552} field. For example:%mdk + +%mdk-data-line={5554} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5554} +\item\mdline{5554}if a controller is not allowed to send a \mdline{5554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5554} message under its +current role definition, the code should be set to \mdline{5555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5555}.%mdk + +%mdk-data-line={5556} +\item\mdline{5556}if the \mdline{5556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5556} repeated field in \mdline{5556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5556} does not match the P4Info +definition, the code should be set to \mdline{5557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5557}. It may be useful +for the server to set the \mdline{5558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5558} field in this case, so that the client +can find out which set of metadata fields triggered the error.%mdk + +%mdk-data-line={5560} +\item\mdline{5560}if the \mdline{5560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{5560} field in \mdline{5560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{5560} does not match any \mdline{5560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{5560} entry +in P4Info, the code should be set to \mdline{5561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5561}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5563} +\noindent\mdline{5563}The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, \mdline{5564}e.g.\mdline{5564} because of a +burst of \mdline{5565}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5565} messages.%mdk + +%mdk-data-line={5567} +\mdline{5567}Note that client arbitration errors are never reported using the \mdline{5567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5567} +message. Invalid \mdline{5568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5568} messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section\mdline{5570}~\mdref{sec-arbitration-updates}{5.3}\mdline{5570}.%mdk + +%mdk-data-line={5572} +\subsubsection{\mdline{5572}16.6.1.\hspace*{0.5em}\mdline{5572}Examples of \mdline{5572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5572} Messages}\label{sec-examples-of-streamerror-messages}%mdk%mdk + +%mdk-data-line={5574} +\begin{itemize}%mdk + +%mdk-data-line={5574} +\item{} +%mdk-data-line={5574} +\mdline{5574}\textbf{Malformed packet-out metadata.}\mdline{5574} If the server receives a \mdline{5574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5574} +message with a \mdline{5575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5575} field with id 7 which is not included in the P4Info +\mdline{5576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5576} message for \mdline{5576}\textquotedblleft{}packet\_out\textquotedblright{}\mdline{5576}, the server may send the +following \mdline{5577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5577} back to the client:%mdk + +%mdk-data-line={5578} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5579} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Unknown~metadata~field~id~7.}{\mdcolor{maroon}"}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~copied~from~the~PacketOut~message~received~from~the~client}\\ +~~~packet\_out~\{\\ +~~~~~payload:~...\\ +~~~~~metadata~\{\\ +~~~~~~~id:~{\mdcolor{purple}7}\\ +~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}I\_should\_not\_be\_here}{\mdcolor{maroon}"}\\ +~~~~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~~\}\\ +~~~~~{\mdcolor{darkgreen}\#~more~metadata}\\ +~~~\}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={5597} +\item{} +%mdk-data-line={5597} +\mdline{5597}\textbf{Packet-out which exceeds the MTU.}\mdline{5597} If the server receives a \mdline{5597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5597} +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following \mdline{5600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5600}:%mdk + +%mdk-data-line={5601} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5602} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Packet~exceeds~the~MTU~for~port.}{\mdcolor{maroon}"}\\ +~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendor1}{\mdcolor{maroon}"}\\ +~code:~{\mdcolor{purple}123}~~{\mdcolor{darkgreen}\#~MTU\_EXCEEDED}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~we~do~not~set~the~packet\_out~field~as~it~does~not~provide~any}\\ +~~~{\mdcolor{darkgreen}\#~extra~information~to~the~client}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5614} +\section{\mdline{5614}17.\hspace*{0.5em}\mdline{5614}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5614} RPC}\label{sec-capabilities-rpc}%mdk%mdk + +%mdk-data-line={5616} +\noindent\mdline{5616}The \mdline{5616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5616} RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the \mdline{5618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesRequest}}}\mdline{5618} message is empty and the \mdline{5618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5618} +message only includes the \mdline{5619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_api\_version}}}\mdline{5619} string field. This field must +be set to the full semantic version string\mdline{5620}~[\mdcite{semver}{27}]\mdline{5620} corresponding to the +version of the P4Runtime API implemented by the server, \mdline{5621}e.g.\mdline{5621} \mdline{5621}\textquotedblleft{}1.1.0-rc.1\textquotedblright{}\mdline{5621}.%mdk + +%mdk-data-line={5623} +\mdline{5623}Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three\mdline{5624}~\mdref{sec-batch-atomicity}{atomicity +modes}\mdline{5625} for \mdline{5625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5625} batches, two of them being +optional. In the future we may decide to leverage the \mdline{5626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5626} +message to enable the server to report to the client which subset of these +atomicity modes is supported.%mdk + +%mdk-data-line={5630} +\mdline{5630}The semantic version string included in \mdline{5630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5630} can be used by +the client to determine which exact feature set is implemented by the server, +since\mdline{5632}~\mdref{sec-p4runtime-versioning}{minor releases}\mdline{5632} may introduce new +functionality. However, because the \mdline{5633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5633} RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (\mdline{5635}i.e.\mdline{5635} an \mdline{5635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5635} error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0).%mdk + +%mdk-data-line={5639} +\section{\mdline{5639}18.\hspace*{0.5em}\mdline{5639}Portability Considerations}\label{sec-portability-considerations}%mdk%mdk + +%mdk-data-line={5641} +\subsection{\mdline{5641}18.1.\hspace*{0.5em}\mdline{5641}PSA Metadata Translation}\label{sec-psa-metadata-translation}%mdk%mdk + +%mdk-data-line={5643} +\noindent\mdline{5643}The \mdline{5643}\emph{Portable Switch Architecture}\mdline{5643} (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +\mdline{5647}[\mdcite{psatranslation}{24}]\mdline{5647}. For such metadata, a translation between the controller\mdline{5647}'\mdline{5647}s +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the \mdline{5651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5651} annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture.%mdk + +%mdk-data-line={5655} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={5656} +\noindent\mdline{5656}\includegraphics[keepaspectratio=true,height=7cm]{build/psa-metadata-translation}{}\mdline{5656}%mdk + +%mdk-data-line={5657} +\mdhr{}%mdk + +%mdk-data-line={5658} +\noindent\mdline{5658}\mdcaption{\textbf{Figure~\mdcaptionlabel{8}.}~\mdcaptiontext{P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdcenter}\label{fig-psa-metadata-translation}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={5662} +\noindent\mdline{5662}Figure\mdline{5662}~\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}}\mdline{5662} illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller\mdline{5668}'\mdline{5668}s 32 bit port +numbers to a target\mdline{5669}'\mdline{5669}s 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch.%mdk + +%mdk-data-line={5673} +\subsubsection{\mdline{5673}18.1.1.\hspace*{0.5em}\mdline{5673}Translation of Port Numbers}\label{sec-translation-of-port-numbers}%mdk%mdk + +%mdk-data-line={5675} +\noindent\mdline{5675}In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller\mdline{5676}'\mdline{5676}s space and the PSA device\mdline{5676}'\mdline{5676}s space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +\mdline{5680}\mdref{sec-user-defined-types}{user-defined P4 types}\mdline{5680}, namely \mdline{5680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5680} and +\mdline{5681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5681}, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in \mdline{5684}\emph{psa.p4}\mdline{5684} for +the PSA device in Switch 1.%mdk + +%mdk-data-line={5687} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5688} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_t;\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortIdInHeader\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~PortIdInHeader\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5694} +\noindent\mdline{5694}The first argument to the \mdline{5694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5694} annotation is a URI that +indicates to the P4Runtime server which numerical mapping\mdline{5695} \mdline{5695}\textemdash{}\mdline{5695} provided by the +out-of-band switch configuration mechanism\mdline{5696} \mdline{5696}\textemdash{}\mdline{5696} to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports).%mdk + +%mdk-data-line={5700} +\mdline{5700}An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows:%mdk + +%mdk-data-line={5706} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5707} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}enum}}~SdnPort~\{\\ +~~SDN\_PORT\_UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +\\ +~~{\mdcolor{darkgreen}//~SDN~ports~are~numbered~starting~from~1.}\\ +~~SDN\_PORT\_MIN~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\\ +~~{\mdcolor{darkgreen}//~The~maximum~value~of~an~SDN~port~(physical~or~logical).}\\ +~~SDN\_PORT\_MAX~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffeff};\\ +\\ +~~{\mdcolor{darkgreen}//~Reserved~SDN~port~numbers~(0xfffffff0~-~0xffffffff)}\\ +\\ +~~SDN\_PORT\_RECIRCULATE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffa};\\ +~~SDN\_PORT\_CPU~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffd};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5723} +\noindent\mdline{5723}The switch config will map \mdline{5723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_RECIRCULATE}}}\mdline{5723} and \mdline{5723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_CPU}}}\mdline{5723} \mdline{5723}\textemdash{}\mdline{5723} as well +as any SDN port number corresponding to a \mdline{5724}\textquotedblleft{}regular\textquotedblright{}\mdline{5724} front-panel port\mdline{5724} \mdline{5724}\textemdash{}\mdline{5724} to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation.%mdk + +%mdk-data-line={5728} +\mdline{5728}The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs.%mdk + +%mdk-data-line={5731} +\subsubsection{\mdline{5731}18.1.2.\hspace*{0.5em}\mdline{5731}Translation of Packet-IO Header Fields}\label{sec-translation-of-packet-io-header-fields}%mdk%mdk + +%mdk-data-line={5733} +\noindent\mdline{5733}Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:.%mdk + +%mdk-data-line={5736} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5737} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~PortIdInHeader\_t~egress\_port;\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~PortIdInHeader\_t~ingress\_port;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5748} +\noindent\mdline{5748}The header-level annotation \mdline{5748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5748} is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (\mdline{5752}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5752}) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI\mdline{5756} \mdline{5756}\textemdash{}\mdline{5756} first argument to the \mdline{5756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5756} +annotation). Any subsequent reference to the \mdline{5757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5757} field in the +data plane will use the translated value. \mdline{5758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5758} is used in the +header definition instead of \mdline{5759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5759} to guarantee byte-aligned headers in +case this is required by the target.%mdk + +%mdk-data-line={5762} +\mdline{5762}A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target\mdline{5764}'\mdline{5764}s PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the \mdline{5766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ingress\_port}}}\mdline{5766} field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller.%mdk + +%mdk-data-line={5772} +\subsubsection{\mdline{5772}18.1.3.\hspace*{0.5em}\mdline{5772}Translation of Match Fields}\label{sec-translation-of-match-fields}%mdk%mdk + +%mdk-data-line={5774} +\noindent\mdline{5774}Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table\mdline{5775}'\mdline{5775}s match key as shown in the example below:%mdk + +%mdk-data-line={5777} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5778} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~istd.ingress\_port:~exact;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~ingress~port}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5788} +\noindent\mdline{5788}Table \mdline{5788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5788} has an exact match on PSA standard metadata ingress port +(\mdline{5789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}istd.ingress\_port}}}\mdline{5789}). Since the field is of type \mdline{5789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5789}, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in \mdline{5792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5792} from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table \mdline{5797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5797} is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values.%mdk + +%mdk-data-line={5801} +\mdline{5801}Note that it may be infeasible to translate the value-mask pair for ternary +matches: \mdline{5802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5802}, \mdline{5802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5802} or \mdline{5802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5802} match kinds. The P4Runtime server may +require that for these match kinds the port match be either \mdline{5803}\emph{de facto}\mdline{5803} \mdline{5803}\textquotedblleft{}exact\textquotedblright{}\mdline{5803} +(0xffffffff mask for \mdline{5804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5804}, prefix-length of 32 for \mdline{5804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5804}, or same low and +high bounds for \mdline{5805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5805}) or \mdline{5805}\textquotedblleft{}don't care\textquotedblright{}\mdline{5805}.%mdk + +%mdk-data-line={5807} +\subsubsection{\mdline{5807}18.1.4.\hspace*{0.5em}\mdline{5807}Translation of Action Parameters}\label{sec-translation-of-action-parameters}%mdk%mdk + +%mdk-data-line={5809} +\noindent\mdline{5809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5809} type parameters can be part of a P4 action definition as shown in the +example below:%mdk + +%mdk-data-line={5812} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5813} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.h.f:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~a;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5827} +\noindent\mdline{5827}The controller may write entries in table \mdline{5827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5827} with action \mdline{5827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5827} to set the egress +port as shown in the P4 code above. The action parameter \mdline{5828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5828} is of type +\mdline{5829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5829}, which leads to a 32-bit bitwidth for \mdline{5829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5829} being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device.%mdk + +%mdk-data-line={5835} +\subsubsection{\mdline{5835}18.1.5.\hspace*{0.5em}\mdline{5835}Port Translation for PSA Extern APIs}\label{sec-port-translation-for-psa-extern-apis}%mdk%mdk + +%mdk-data-line={5837} +\noindent\mdline{5837}The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The \mdline{5842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{5842} +field is of type \mdline{5843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{5843} to carry the SDN representation of the port being +watched. The P4Runtime server will translate the given watch port into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device.%mdk + +%mdk-data-line={5848} +\mdline{5848}The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type \mdline{5850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5850} to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane.%mdk + +%mdk-data-line={5854} +\subsubsection{\mdline{5854}18.1.6.\hspace*{0.5em}\mdline{5854}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}\label{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}%mdk%mdk + +%mdk-data-line={5856} +\noindent\mdline{5856}P4Runtime supports using a translated value (\mdline{5856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5856} or any other translated +type for which the underlying built-in type is \mdline{5857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5857}) as an index to a +register, indirect counter, or indirect meter.%mdk + +%mdk-data-line={5860} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5861} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~counter~entry~type~}{\mdcolor{darkgreen}*/},~PortId\_t~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~index~type~}{\mdcolor{darkgreen}*/}\textgreater{}(\\ +~~{\mdcolor{purple}32}w1024,~PSA\_CounterType\_t.PACKETS)~counter;\\ +{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +~~counter.count(p);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5869} +\noindent\mdline{5869}This P4 Counter declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={5872} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5873} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counters~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x12000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}counter}{\mdcolor{maroon}"}\\ +~~\}\\ +~~spec~\{\\ +~~~~unit:~PACKETS\\ +~~\}\\ +~~index\_type\_name~\{\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5887} +\noindent\mdline{5887}The controller may read and write counter values from indexed counter \mdline{5887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter}}}\mdline{5887} +using SDN port numbers as indices, and not device-specific port numbers. The +\mdline{5889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{5889} field in the P4Info message is a signal to the P4Runtime +server that translation is required.%mdk + +%mdk-data-line={5892} +\section{\mdline{5892}19.\hspace*{0.5em}\mdline{5892}P4Runtime Versioning}\label{sec-p4runtime-versioning}%mdk%mdk + +%mdk-data-line={5894} +\noindent\mdline{5894}P4Runtime follows the Google guidelines for versioning cloud APIs +\mdline{5895}[\mdcite{apiversioning}{6}]\mdline{5895}. We use a \mdline{5895}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR.MINOR.PATCH}}}\mdline{5895} style version number scheme and +we increment the:%mdk + +%mdk-data-line={5898} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5898} +\item\mdline{5898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5898} version when we make incompatible API changes,%mdk + +%mdk-data-line={5899} +\item\mdline{5899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MINOR}}}\mdline{5899} version when we add functionality in a backwards-compatible manner,%mdk + +%mdk-data-line={5900} +\item\mdline{5900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PATCH}}}\mdline{5900} version when we make backwards-compatible bug fixes.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5902} +\noindent\mdline{5902}The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is \mdline{5904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1}}}\mdline{5904} and the package +name for P4Info is \mdline{5905}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1}}}\mdline{5905}. Even though \mdline{5905}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5905} and \mdline{5905}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5905} are two +different Protobuf packages, \mdline{5906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5906} depends on \mdline{5906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5906} and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence.%mdk + +%mdk-data-line={5910} +\mdline{5910}As recommended in\mdline{5910}~[\mdcite{apiversioning}{6}]\mdline{5910}, we may consider using pre-GA release +suffixes (such as \mdline{5911}\emph{alpha}\mdline{5911} or \mdline{5911}\emph{beta}\mdline{5911}) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1).%mdk + +%mdk-data-line={5915} +\mdline{5915}Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner.\mdline{5916}~[\mdcite{apiversioningbackwardscompatibility}{7}]\mdline{5916} describes +what constitute a backwards-compatible change. We expect \mdline{5917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5917} version bumps +to be a \mdline{5918}\textbf{rare}\mdline{5918} event.%mdk + +%mdk-data-line={5920} +\mdline{5920}Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor\mdline{5925} \mdline{5925}+ patch version numbers in future releases.%mdk + +%mdk-data-line={5927} +\mdline{5927}All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository\mdline{5928}~[\mdcite{p4runtimerepo}{15}]\mdline{5928} and the version label follows +semantic versioning rules\mdline{5929}~[\mdcite{semver}{27}]\mdline{5929}.%mdk + +%mdk-data-line={5931} +\section{\mdline{5931}20.\hspace*{0.5em}\mdline{5931}Extending P4Runtime for non-PSA Architectures}\label{sec-extending-p4runtime}%mdk%mdk + +%mdk-data-line={5933} +\noindent\mdline{5933}P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place.%mdk + +%mdk-data-line={5941} +\mdline{5941}When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names:%mdk + +%mdk-data-line={5945} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5945} +\item\mdline{5945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/config/\textless{}major~version\textgreater{}/p4info.proto}}}\mdline{5945}%mdk + +%mdk-data-line={5946} +\item\mdline{5946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/\textless{}major~version\textgreater{}/p4runtime.proto}}}\mdline{5946}%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5948} +\noindent\mdline{5948}We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they \mdline{5949}\textquotedblleft{}extend\textquotedblright{}\mdline{5949}.%mdk + +%mdk-data-line={5951} +\mdline{5951}For the remainder of this section, we will refer to these two files as +\mdline{5952}\emph{p4info-ext}\mdline{5952} and \mdline{5952}\emph{p4runtime-ext}\mdline{5952} respectively.%mdk + +%mdk-data-line={5954} +\subsection{\mdline{5954}20.1.\hspace*{0.5em}\mdline{5954}Extending P4Runtime for Architecture-Specific Externs}\label{sec-extending-p4runtime-for-architecture-specific-externs}%mdk%mdk + +%mdk-data-line={5956} +\noindent\mdline{5956}Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both \mdline{5957}\emph{p4info-ext}\mdline{5957} and +\mdline{5958}\emph{p4runtime-ext}\mdline{5958}. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example:%mdk + +%mdk-data-line={5962} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5963} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~T~must~be~a~bit\textless{}W\textgreater{}~type,~it~indicates~the~width~of~each~counter~cell}\\ +{\bfseries{\mdcolor{navy}extern}}~MyNewPacketCounter\textless{}T\textgreater{}~\{\\ +~~counter({\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~size);\\ +~~increment({\bfseries{\mdcolor{navy}in}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~index);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5970} +\subsubsection{\mdline{5970}20.1.1.\hspace*{0.5em}\mdline{5970}Extending the P4Info message}\label{sec-extending-the-p4info-message}%mdk%mdk + +%mdk-data-line={5972} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5972} +\item\mdline{5972}Id prefixes \mdline{5972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0x81}}}\mdline{5972} through \mdline{5972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfe}}}\mdline{5972} are reserved for architecture-specific +externs. It is recommended that \mdline{5973}\emph{p4info-ext}\mdline{5973} include a \mdline{5973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Ids}}}\mdline{5973} message based +on the one in p4info.proto that the P4 compiler can refer to when\mdline{5974}~\mdref{sec-id-allocation}{assigning +IDs}\mdline{5975} to each extern instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5977} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5978} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~P{\mdcolor{purple}4}Ids~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Prefix~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~MY\_NEW\_PACKET\_COUNTER~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0x81};\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5986} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5986} +\item\mdline{5986}\emph{p4info-ext}\mdline{5986} should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +\mdline{5990}\mdref{sec-p4info-extern}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ExternInstance}}}}\mdline{5990} message as the \mdline{5990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{5990} +field, which is of type \mdline{5991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5991}~[\mdcite{protoany}{31}]\mdline{5991}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5993} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5994} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\mdcolor{darkgreen}//~corresponds~to~the~T~type~parameter~in~the~P4~extern~definition}\\ +~~p4.config.v1.P{\mdcolor{purple}4}DataTypeSpec~type\_spec~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~constructor~argument}\\ +~~{\bfseries{\mdcolor{navy}int64}}~size~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6002} +\subsubsection{\mdline{6002}20.1.2.\hspace*{0.5em}\mdline{6002}Extending the P4Runtime Service}\label{sec-extending-the-p4runtime-service}%mdk%mdk + +%mdk-data-line={6004} +\noindent\mdline{6004}Just like \mdline{6004}\emph{p4info-ext}\mdline{6004}, \mdline{6004}\emph{p4runtime-ext}\mdline{6004} should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an\mdline{6009}~\mdref{sec-extern-entry}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\mdline{6009} message generated by the +P4Runtime client.%mdk + +%mdk-data-line={6012} +\mdline{6012}Here is a possible Protobuf message for our \mdline{6012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyNewPacketCounter}}}\mdline{6012} P4 extern:%mdk + +%mdk-data-line={6013} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6014} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~This~message~enables~reading~/~writing~data~to~the~counter~at~the~provided}\\ +{\mdcolor{darkgreen}//~index}\\ +{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~p4.v1.P{\mdcolor{purple}4}Data~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6022} +\noindent\mdline{6022}P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an \mdline{6023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6023} Protobuf field\mdline{6023}~[\mdcite{protoany}{31}]\mdline{6023} named \mdline{6023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6023} +in both \mdline{6024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{6024} and +\mdline{6025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{6025}. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in \mdline{6027}\emph{p4runtime-ext}\mdline{6027} and embed instances of these messages in +\mdline{6028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{6028} and \mdline{6028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{6028} as appropriate.%mdk + +%mdk-data-line={6030} +\subsection{\mdline{6030}20.2.\hspace*{0.5em}\mdline{6030}Architecture-Specific Table Extensions}\label{sec-architecture-specific-table-extensions}%mdk%mdk + +%mdk-data-line={6032} +\subsubsection{\mdline{6032}20.2.1.\hspace*{0.5em}\mdline{6032}New Match Types}\label{sec-new-match-types}%mdk%mdk + +%mdk-data-line={6034} +\noindent\mdline{6034}An architecture may introduce new table match types\mdline{6034}~[\mdcite{p4matchtypes}{12}]\mdline{6034}. P4Runtime +accounts for this by providing the following hooks:%mdk + +%mdk-data-line={6037} +\begin{itemize}%mdk + +%mdk-data-line={6037} +\item{} +%mdk-data-line={6037} +\mdline{6037}The \mdline{6037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{6037} field in \mdline{6037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{6037} (p4info.proto) is a \mdline{6037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6037} +which can be either one of the default match types (\mdline{6038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{6038}, \mdline{6038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{6038}, \mdline{6038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{6038}, +\mdline{6039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{6039}, or \mdline{6039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6039}) or an architecture-specific match type encoded as a +string.%mdk%mdk + +%mdk-data-line={6042} +\item{} +%mdk-data-line={6042} +\mdline{6042}The \mdline{6042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{6042} field in \mdline{6042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6042} (p4runtime.proto) is a +\mdline{6043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6043} which includes an \mdline{6043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6043} Protobuf message\mdline{6043}~[\mdcite{protoany}{31}]\mdline{6043} field +(\mdline{6044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6044}). \mdline{6044}\emph{p4info-ext}\mdline{6044} should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in \mdline{6047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6047} as the +\mdline{6048}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6048} field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6051} +\subsubsection{\mdline{6051}20.2.2.\hspace*{0.5em}\mdline{6051}New Table Properties}\label{sec-new-table-properties}%mdk%mdk + +%mdk-data-line={6053} +\noindent\mdline{6053}An architecture may introduce additional table properties +\mdline{6054}[\mdcite{p4tableproperties}{30}]\mdline{6054}. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +\mdline{6056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Table}}}\mdline{6056} message includes the \mdline{6056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{6056} \mdline{6056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6056} Protobuf +field\mdline{6057}~[\mdcite{protoany}{31}]\mdline{6057}. At the moment, there is not any mechanism to extend the +\mdline{6058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.TableEntry}}}\mdline{6058} message based on the value of architecture-specific table +properties, but we may include on in future versions of the API.%mdk + +%mdk-data-line={6061} +\section{\mdline{6061}21.\hspace*{0.5em}\mdline{6061}Known Limitations of Current P4Runtime Version}\label{sec-known-limitations-of-current-p4runtime-version}%mdk%mdk + +%mdk-data-line={6063} +\begin{itemize}%mdk + +%mdk-data-line={6063} +\item{} +%mdk-data-line={6063} +\mdline{6063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6063}, action \mdline{6063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6063}, and controller packet metadata fields only +support unsigned bitstrings, \mdline{6064}i.e.\mdline{6064} values of one of the following types (not +the more general \mdline{6065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{6065}):%mdk + +%mdk-data-line={6066} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6066} +\item\mdline{6066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6066}%mdk + +%mdk-data-line={6067} +\item\mdline{6067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6067}. Note that as far as the \mdline{6067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Info}}}\mdline{6067} message contents and +thus controller software is concerned, such fields of type \mdline{6068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6068} +will be indistinguishable from those that have been declared with +type \mdline{6070}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6070}. P4Runtime server software will automatically +perform any conversion needed between the type \mdline{6071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6071} values in +P4Runtime messages and the data plane representation.%mdk + +%mdk-data-line={6073} +\item\mdline{6073}an \mdline{6073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{6073} with underlying type \mdline{6073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6073}%mdk + +%mdk-data-line={6074} +\item\mdline{6074}a \mdline{6074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6074} or \mdline{6074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6074} with an underlying type that is one of the above (or +in general a \mdline{6075}\textquotedblleft{}chain\textquotedblright{}\mdline{6075} of \mdline{6075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6075} and/or \mdline{6075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6075} that eventually ends with +one of the types above)%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6078} +\item{} +%mdk-data-line={6078} +\mdline{6078}Support for PSA Random \mdline{6078}\&\mdline{6078} Timestamp externs is postponed to a future minor +version update.%mdk%mdk + +%mdk-data-line={6081} +\item{} +%mdk-data-line={6081} +\mdline{6081}P4Info does not include information about which of a table\mdline{6081}'\mdline{6081}s actions execute +which direct resource(s).%mdk%mdk + +%mdk-data-line={6084} +\item{} +%mdk-data-line={6084} +\mdline{6084}The default action for indirect match tables is restricted to a \mdline{6084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\\ +NoAction}}}\mdline{6085} known at compile-time.%mdk%mdk + +%mdk-data-line={6087} +\item{} +%mdk-data-line={6087} +\mdline{6087}There is no mechanism for changing the value of the \mdline{6087}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{6087} +table property at runtime.%mdk%mdk + +%mdk-data-line={6090} +\item{} +%mdk-data-line={6090} +\mdline{6090}There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor\mdline{6091} \mdline{6091}+ +patch version numbers.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6094} +\section{\mdline{6094}A.\hspace*{0.5em}\mdline{6094}Appendix}\label{sec-appendix}%mdk%mdk + +%mdk-data-line={6096} +\subsection{\mdline{6096}A.1.\hspace*{0.5em}\mdline{6096}Revision History}\label{sec-revision-history}%mdk%mdk + +%mdk-data-line={6098} +\subsubsection{\mdline{6098}A.1.1.\hspace*{0.5em}\mdline{6098}Changes in v1.3.0}\label{sec-changes-in-v130}%mdk%mdk + +%mdk-data-line={6100} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6100} +\item\mdline{6100}Add IANA assigned TCP port, 9559, to P4Runtime server discussion.%mdk + +%mdk-data-line={6101} +\item\mdline{6101}Move \mdline{6101}\textquotedblleft{}Security considerations\textquotedblright{}\mdline{6101} section to P4Runtime server discussion.%mdk + +%mdk-data-line={6102} +\item\mdline{6102}Deprecate \mdline{6102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{6102} field (int32) in favor of \mdline{6102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{6102} (bytes). This allows +using the watch port feature with the \mdline{6103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_translation}}}\mdline{6103} feature.%mdk + +%mdk-data-line={6104} +\item\mdline{6104}Replace master, slave, master arbitration with more inclusive language: +primary, backup, and client arbitration%mdk + +%mdk-data-line={6106} +\item\mdline{6106}Clarify that source locations for annotations are optional in the P4Info +message.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6109} +\subsubsection{\mdline{6109}A.1.2.\hspace*{0.5em}\mdline{6109}Changes in v1.2.0}\label{sec-changes-in-v120}%mdk%mdk + +%mdk-data-line={6111} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6111} +\item\mdline{6111}Add new \mdline{6111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6111} match kind. At the moment, \mdline{6111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6111} is only supported by +the v1model architecture\mdline{6112}~[\mdcite{v1model}{38}]\mdline{6112}, and not by PSA. It will eventually be +included in the core P4 language.%mdk + +%mdk-data-line={6114} +\item\mdline{6114}Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists.%mdk + +%mdk-data-line={6116} +\item\mdline{6116}Add a new \mdline{6116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6116} field of type \mdline{6116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{6116} to \mdline{6116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{6116}. This is more +flexible than the now deprecated \mdline{6117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{6117} field.%mdk + +%mdk-data-line={6118} +\item\mdline{6118}Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +\mdline{6120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6120} annotation.%mdk + +%mdk-data-line={6121} +\item\mdline{6121}Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature.%mdk + +%mdk-data-line={6123} +\item\mdline{6123}Support using \mdline{6123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{6123} as the controller type in the \mdline{6123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6123} +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type.%mdk + +%mdk-data-line={6126} +\item\mdline{6126}Add optional P4 source locations to both structured and unstructured +annotations.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6129} +\subsubsection{\mdline{6129}A.1.3.\hspace*{0.5em}\mdline{6129}Changes in v1.1.0}\label{sec-changes-in-v110}%mdk%mdk + +%mdk-data-line={6131} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6131} +\item\mdline{6131}Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously.%mdk + +%mdk-data-line={6137} +\item\mdline{6137}Add \mdline{6137}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{6137} field to stream messages sent by the server.%mdk + +%mdk-data-line={6138} +\item\mdline{6138}Add \mdline{6138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6138} RPC to query the P4Runtime API version implemented by the +server.%mdk + +%mdk-data-line={6140} +\item\mdline{6140}Support wildcard reads for multicast groups and clone sessions.%mdk + +%mdk-data-line={6141} +\item\mdline{6141}Support for modifying direct resources of const tables.%mdk + +%mdk-data-line={6142} +\item\mdline{6142}Support P4 user-defined types for Packet IO metadata fields.%mdk + +%mdk-data-line={6143} +\item\mdline{6143}Clarify consistency requirements for \mdline{6143}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6143} and \mdline{6143}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{6143} RPCs.%mdk + +%mdk-data-line={6144} +\item\mdline{6144}Add Appendix providing implementation advice for avoiding common pitfalls: + +%mdk-data-line={6145} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6145} +\item\mdline{6145}advice on setting gRPC Metadata Maximum Size%mdk + +%mdk-data-line={6146} +\item\mdline{6146}advice on setting gRPC Server Maximum Receive Message Size%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6147} +\item\mdline{6147}Clarify limitations on supported types for \mdline{6147}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6147}, action \mdline{6147}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6147}, and +Packet IO metadata fields.%mdk + +%mdk-data-line={6149} +\item\mdline{6149}Clarify that reading entire forwarding state with empty \mdline{6149}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{6149} is not +supported.%mdk + +%mdk-data-line={6151} +\item\mdline{6151}Document that \mdline{6151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6151} need only be supported when applied to +type declarations in P4.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6154} +\subsection{\mdline{6154}A.2.\hspace*{0.5em}\mdline{6154}P4 Annotations}\label{sec-p4-annotations}%mdk%mdk + +%mdk-data-line={6156} +\noindent\mdline{6156}Table\mdline{6156}~\mdref{tab-p4-annotations}{\mdcaptionlabel{7}}\mdline{6156} lists P4\mdline{6156}\mdsub{16}\mdline{6156} annotations introduced primarily for +the purpose of adding features for the P4Runtime API.%mdk + +%mdk-data-line={6159} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{6161} Annotation}}&\multicolumn{1}{|c|}{{\bfseries\mdline{6161} Description}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{6163} \mdline{6163}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{6163}}&\multicolumn{1}{|l|}{\mdline{6163} See section\mdline{6163}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6163}}\\ +\multicolumn{1}{|l}{\mdline{6164} \mdline{6164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{6164}}&\multicolumn{1}{|l|}{\mdline{6164} See section\mdline{6164}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{6164}}\\ +\multicolumn{1}{|l}{\mdline{6165} \mdline{6165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{6165}}&\multicolumn{1}{|l|}{\mdline{6165} See section\mdline{6165}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6165}}\\ +\multicolumn{1}{|l}{\mdline{6166} \mdline{6166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6166}}&\multicolumn{1}{|l|}{\mdline{6166} See section\mdline{6166}~\mdref{sec-id-allocation}{6.3}\mdline{6166}}\\ +\multicolumn{1}{|l}{\mdline{6167} \mdline{6167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{6167}}&\multicolumn{1}{|l|}{\mdline{6167} See sections\mdline{6167}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{6167},\mdline{6167}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{6167}}\\ +\multicolumn{1}{|l}{\mdline{6168} \mdline{6168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{6168}}&\multicolumn{1}{|l|}{\mdline{6168} See section\mdline{6168}~\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1}\mdline{6168}}\\ +\multicolumn{1}{|l}{\mdline{6169} \mdline{6169}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6169}}&\multicolumn{1}{|l|}{\mdline{6169} See sections\mdline{6169}~\mdref{sec-user-defined-types}{8.5.6}\mdline{6169},\mdline{6169}~\mdref{sec-translation-of-port-numbers}{18.1.1}\mdline{6169}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={6171} +\mdhr{}%mdk + +%mdk-data-line={6172} +\noindent\mdline{6172}\mdcaption{\textbf{Table~\mdcaptionlabel{7}.}~\mdcaptiontext{P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-annotations}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={6175} +\subsection{\mdline{6175}A.3.\hspace*{0.5em}\mdline{6175}A More Complex Value Set Example}\label{sec-value-set-example}%mdk%mdk + +%mdk-data-line={6177} +\noindent\mdline{6177}This section includes a more complex Value Set example, with multiple matches of +different kinds.%mdk + +%mdk-data-line={6180} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6181} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6190} +\noindent\mdline{6190}This P4 Value Set declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={6193} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6194} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6221} +\noindent\mdline{6221}A P4Runtime client can set the membership for this Value Set with \mdline{6221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6221} +messages similar to this one:%mdk + +%mdk-data-line={6224} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6225} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xac}~\}\\ +~~~~~~\}\\ +~~~~~~{\mdcolor{darkgreen}\#~match~for~field\_id~2~is~missing~=\textgreater{}~don't~care~match}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xdc}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~~~ternary~\{~value:~{\mdcolor{purple}0x88}~mask:~{\mdcolor{purple}8}f~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6259} +\subsection{\mdline{6259}A.4.\hspace*{0.5em}\mdline{6259}Guidelines for Implementations}\label{sec-guidelines-for-implementations}%mdk%mdk + +%mdk-data-line={6261} +\noindent\mdline{6261}This section contains practical advice for implementing P4Runtime clients and +servers.%mdk + +%mdk-data-line={6264} +\subsubsection{\mdline{6264}A.4.1.\hspace*{0.5em}\mdline{6264}gRPC Metadata Maximum Size}\label{sec-grpc-metadata-maximum-size}%mdk%mdk + +%mdk-data-line={6266} +\noindent\mdline{6266}In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the \mdline{6267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6267} gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the \mdline{6268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6268} P4Runtime RPC. The \mdline{6268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6268} RPC +returns an individual error for every item in a batch (see Section +\mdline{6270}\mdref{sec-write-rpc}{12}\mdline{6270}), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +\mdline{6272}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{6272} error, without any of the individual errors.%mdk + +%mdk-data-line={6274} +\mdline{6274}To fix this problem, one can set the \mdline{6274}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6274} option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it\mdline{6276}'\mdline{6276}s +limit, as only the receiving side\mdline{6277}'\mdline{6277}s limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every \mdline{6279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{6279}, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +\mdline{6281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}8192~+~MAX\_UPDATES\_PER\_WRITE~*~100}}}\mdline{6281} bytes of metadata.%mdk + +%mdk-data-line={6283} +\mdline{6283}For example, in C++, one can create a client channel as follows:%mdk + +%mdk-data-line={6284} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6285} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}~=~{\mdcolor{purple}100};\\ +::{\mdcolor{navy}grpc::}ChannelArguments~arguments;\\ +arguments{\bfseries{\mdcolor{navy}.}}SetInt({\mdcolor{teal}GRPC\_ARG\_MAX\_METADATA\_SIZE},~{\mdcolor{purple}8192}~+~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}*{\mdcolor{purple}100});\\ +{\bfseries{\mdcolor{navy}return}}~{\mdcolor{navy}grpc::}CreateCustomChannel(address,~credentials,~arguments);}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6291} +\subsubsection{\mdline{6291}A.4.2.\hspace*{0.5em}\mdline{6291}gRPC Server Maximum Receive Message Size}\label{sec-grpc-server-maximum-receive-message-size}%mdk%mdk + +%mdk-data-line={6293} +\noindent\mdline{6293}At the time of writing, the default maximum receive message size in gRPC is 4MB +\mdline{6294}\textemdash{}\mdline{6294} while the default maximum send message size is unlimited. This can be a +problem for the \mdline{6295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{6295} RPC, since for some targets the +binary \mdline{6296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6296} can exceed 4MB, in which case by default the P4Runtime +server would return an \mdline{6297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6297} error. To a lesser extent, this may +affect the \mdline{6298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6298} RPC as well, in case of extremely large batches.%mdk + +%mdk-data-line={6300} +\mdline{6300}To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of \mdline{6302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6302} for their target(s). This can be done by +setting the \mdline{6303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_receive\_message\_length}}}\mdline{6303} when building the gRPC server.%mdk + +%mdk-data-line={6305} +\mdline{6305}For example, in C++, one can set the maximum receive message size as follows:%mdk + +%mdk-data-line={6306} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6307} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE}~=~{\mdcolor{purple}128}~*~{\mdcolor{purple}1024}~*~{\mdcolor{purple}1024};~~{\mdcolor{darkgreen}//~128MB}\\ +::{\mdcolor{navy}grpc::}ServerBuilder~server\_builder;\\ +builder{\bfseries{\mdcolor{navy}.}}AddListeningPort({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});\\ +builder{\bfseries{\mdcolor{navy}.}}RegisterService({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});~~{\mdcolor{darkgreen}//~register~P4Runtime~service}\\ +builder{\bfseries{\mdcolor{navy}.}}SetMaxReceiveMessageSize({\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE});\\ +builder{\bfseries{\mdcolor{navy}.}}BuildAndStart();}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6315} +\noindent\mdline{6315}On the client side, we recommend that P4Runtime clients do not use \mdline{6315}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6315} +batches larger than the default maximum receive message size (4MB)\mdline{6316} \mdline{6316}\textemdash{}\mdline{6316} in case +the server did not deem necessary to increase the default value\mdline{6317} \mdline{6317}\textemdash{}\mdline{6317}, unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB).%mdk + +%mdk-data-line={6322;build/P4Runtime-Spec-bib.bbl.mdk:1} +%mdk-data-line={6322;build/P4Runtime-Spec-bib.bbl.mdk:2} +\mdsetrefname{References}%mdk +{\mdbibindent{0}%mdk +\begin{thebibliography}{39}%mdk +\label{sec-bibliography}%mdk + +%mdk-data-line={references.bib:68} +\bibitem{p4spec}\mdbibitemlabel{{}[1]}\textquotedblleft{}$P4_{16}$ 1.2.1 Specification.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html}}.\label{p4spec}%mdk%mdk + +%mdk-data-line={references.bib:134} +\bibitem{rfc2698}\mdbibitemlabel{{}[2]}\textquotedblleft{}A Two Rate Three Color Marker.\textquotedblright{} \href{https://tools.ietf.org/html/rfc2698}{{\ttfamily https://\hspace{0pt}tools.\hspace{0pt}ietf.\hspace{0pt}org/\hspace{0pt}html/\hspace{0pt}rfc2698}}.\label{rfc2698}%mdk%mdk + +%mdk-data-line={references.bib:32} +\bibitem{p4complextypes}\mdbibitemlabel{{}[3]}\textquotedblleft{}Complex Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-p4-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}p4-\hspace{0pt}type}}.\label{p4complextypes}%mdk%mdk + +%mdk-data-line={references.bib:37} +\bibitem{protodefaults}\mdbibitemlabel{{}[4]}\textquotedblleft{}Default Values for Protobuf 3 ($proto3$) Fields.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23default}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}default}}.\label{protodefaults}%mdk%mdk + +%mdk-data-line={references.bib:78} +\bibitem{p4enums}\mdbibitemlabel{{}[5]}\textquotedblleft{}Enums in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-enum-types}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}enum-\hspace{0pt}types}}.\label{p4enums}%mdk%mdk + +%mdk-data-line={references.bib:119} +\bibitem{apiversioning}\mdbibitemlabel{{}[6]}\textquotedblleft{}Google Cloud APIs Versioning.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning}}.\label{apiversioning}%mdk%mdk + +%mdk-data-line={references.bib:124} +\bibitem{apiversioningbackwardscompatibility}\mdbibitemlabel{{}[7]}\textquotedblleft{}Google Cloud APIs Versioning - Backwards-Compatibility.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning\%23backwards_compatibility}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning\#\hspace{0pt}backwards\_\hspace{0pt}compatibility}}.\label{apiversioningbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:149} +\bibitem{grpcauth}\mdbibitemlabel{{}[8]}\textquotedblleft{}gRPC Authentication.\textquotedblright{} \href{https://grpc.io/docs/guides/auth.html}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}guides/\hspace{0pt}auth.\hspace{0pt}html}}.\label{grpcauth}%mdk%mdk + +%mdk-data-line={references.bib:7} +\bibitem{grpc}\mdbibitemlabel{{}[9]}\textquotedblleft{}gRPC Main Site.\textquotedblright{} \href{https://grpc.io}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io}}.\label{grpc}%mdk%mdk + +%mdk-data-line={references.bib:144} +\bibitem{grpcstreamc}\mdbibitemlabel{{}[10]}\textquotedblleft{}gRPC Streaming RPCs in C++.\textquotedblright{} \href{https://grpc.io/docs/tutorials/basic/c.html\%23streaming-rpcs}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}tutorials/\hspace{0pt}basic/\hspace{0pt}c.\hspace{0pt}html\#\hspace{0pt}streaming-\hspace{0pt}rpcs}}.\label{grpcstreamc}%mdk%mdk + +%mdk-data-line={references.bib:114} +\bibitem{p4newtypes}\mdbibitemlabel{{}[11]}\textquotedblleft{}Introducing New Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-newtype}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}newtype}}.\label{p4newtypes}%mdk%mdk + +%mdk-data-line={references.bib:139} +\bibitem{p4matchtypes}\mdbibitemlabel{{}[12]}\textquotedblleft{}Match Types in P4.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-match-kind-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}match-\hspace{0pt}kind-\hspace{0pt}type}}.\label{p4matchtypes}%mdk%mdk + +%mdk-data-line={references.bib:194} +\bibitem{p4annotations}\mdbibitemlabel{{}[13]}\textquotedblleft{}P4 Annotations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-annotations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}annotations}}.\label{p4annotations}%mdk%mdk + +%mdk-data-line={references.bib:174} +\bibitem{p4concurrency}\mdbibitemlabel{{}[14]}\textquotedblleft{}P4 Concurrency Model.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-concurrency}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}concurrency}}.\label{p4concurrency}%mdk%mdk + +%mdk-data-line={references.bib:1} +\bibitem{p4runtimerepo}\mdbibitemlabel{{}[15]}\textquotedblleft{}p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.\textquotedblright{} \href{https://github.com/p4lang/p4runtime}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4runtime}}.\label{p4runtimerepo}%mdk%mdk + +%mdk-data-line={references.bib:42} +\bibitem{pirepo}\mdbibitemlabel{{}[16]}\textquotedblleft{}p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.\textquotedblright{} \href{https://github.com/p4lang/PI}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}PI}}.\label{pirepo}%mdk%mdk + +%mdk-data-line={references.bib:109} +\bibitem{p4apiwgcharter}\mdbibitemlabel{{}[17]}\textquotedblleft{}P4.org API Working Group Charter.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4_API_WG_charter.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4\_\hspace{0pt}API\_\hspace{0pt}WG\_\hspace{0pt}charter.\hspace{0pt}html}}.\label{p4apiwgcharter}%mdk%mdk + +%mdk-data-line={references.bib:154} +\bibitem{p4actionannotations}\mdbibitemlabel{{}[18]}\textquotedblleft{}P4 Standard Annotations on Table Actions.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-action-anno}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}action-\hspace{0pt}anno}}.\label{p4actionannotations}%mdk%mdk + +%mdk-data-line={references.bib:73} +\bibitem{psa}\mdbibitemlabel{{}[19]}\textquotedblleft{}Portable Switch Architecture Specification (v1.1.0).\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html}}.\label{psa}%mdk%mdk + +%mdk-data-line={references.bib:189} +\bibitem{protooneofbackwardscompatibility}\mdbibitemlabel{{}[20]}\textquotedblleft{}Protobuf OneOf Backwards-Compatibility Issues.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23backwards-compatibility-issues}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}backwards-\hspace{0pt}compatibility-\hspace{0pt}issues}}.\label{protooneofbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:12} +\bibitem{proto}\mdbibitemlabel{{}[21]}\textquotedblleft{}Protocol Buffers Main Site.\textquotedblright{} \href{https://developers.google.com/protocol-buffers}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers}}.\label{proto}%mdk%mdk + +%mdk-data-line={references.bib:159} +\bibitem{psaactionselector}\mdbibitemlabel{{}[22]}\textquotedblleft{}PSA Action Selector.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-action-selector}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}action-\hspace{0pt}selector}}.\label{psaactionselector}%mdk%mdk + +%mdk-data-line={references.bib:169} +\bibitem{psaatomicityofcontrolplaneops}\mdbibitemlabel{{}[23]}\textquotedblleft{}PSA Atomicity of Control Plane Operations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-atomicity-of-control-plane-api-operations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}atomicity-\hspace{0pt}of-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}api-\hspace{0pt}operations}}.\label{psaatomicityofcontrolplaneops}%mdk%mdk + +%mdk-data-line={references.bib:179} +\bibitem{psatranslation}\mdbibitemlabel{{}[24]}\textquotedblleft{}PSA Data Plane vs Control Plane Types.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-data-plane-vs-control-plane-values}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}data-\hspace{0pt}plane-\hspace{0pt}vs-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}values}}.\label{psatranslation}%mdk%mdk + +%mdk-data-line={references.bib:164} +\bibitem{psaemptygroupactionappendix}\mdbibitemlabel{{}[25]}\textquotedblleft{}PSA Empty Group Action Appendix.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23appendix-empty-action-selector-groups}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}appendix-\hspace{0pt}empty-\hspace{0pt}action-\hspace{0pt}selector-\hspace{0pt}groups}}.\label{psaemptygroupactionappendix}%mdk%mdk + +%mdk-data-line={references.bib:58} +\bibitem{p4selectexpr}\mdbibitemlabel{{}[26]}\textquotedblleft{}Select Expressions in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-select}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}select}}.\label{p4selectexpr}%mdk%mdk + +%mdk-data-line={references.bib:129} +\bibitem{semver}\mdbibitemlabel{{}[27]}\textquotedblleft{}Semantic Versioning.\textquotedblright{} \href{https://semver.org/}{{\ttfamily https://\hspace{0pt}semver.\hspace{0pt}org/\hspace{0pt}}}.\label{semver}%mdk%mdk + +%mdk-data-line={references.bib:98} +\bibitem{protostatus}\mdbibitemlabel{{}[28]}\textquotedblleft{}Status.proto:the Protobuf Status Message.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}src/\hspace{0pt}proto/\hspace{0pt}grpc/\hspace{0pt}status/\hspace{0pt}status.\hspace{0pt}proto}}.\label{protostatus}%mdk%mdk + +%mdk-data-line={references.bib:63} +\bibitem{p4revisions110}\mdbibitemlabel{{}[29]}\textquotedblleft{}Summary of Changes Made in $P4_{16}$ Version 1.1.0.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-summary-of-changes-made-in-version-110}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}summary-\hspace{0pt}of-\hspace{0pt}changes-\hspace{0pt}made-\hspace{0pt}in-\hspace{0pt}version-\hspace{0pt}110}}.\label{p4revisions110}%mdk%mdk + +%mdk-data-line={references.bib:48} +\bibitem{p4tableproperties}\mdbibitemlabel{{}[30]}\textquotedblleft{}Table Properties in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-props}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}props}}.\label{p4tableproperties}%mdk%mdk + +%mdk-data-line={references.bib:83} +\bibitem{protoany}\mdbibitemlabel{{}[31]}\textquotedblleft{}The Any Protobuf Message.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23any}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}any}}.\label{protoany}%mdk%mdk + +%mdk-data-line={references.bib:88} +\bibitem{grpcstatus}\mdbibitemlabel{{}[32]}\textquotedblleft{}The gRPC $Status$ Class.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/status.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}impl/\hspace{0pt}codegen/\hspace{0pt}status.\hspace{0pt}h}}.\label{grpcstatus}%mdk%mdk + +%mdk-data-line={references.bib:104} +\bibitem{grpcerrordetails}\mdbibitemlabel{{}[33]}\textquotedblleft{}The gRPC C++ Error Details Library.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/support/error_details.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}support/\hspace{0pt}error\_\hspace{0pt}details.\hspace{0pt}h}}.\label{grpcerrordetails}%mdk%mdk + +%mdk-data-line={references.bib:93} +\bibitem{grpcstatuscodes}\mdbibitemlabel{{}[34]}\textquotedblleft{}The gRPC Canonical Status Codes.\textquotedblright{} \href{https://developers.google.com/maps-booking/reference/grpc-api/status_codes}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}maps-\hspace{0pt}booking/\hspace{0pt}reference/\hspace{0pt}grpc-\hspace{0pt}api/\hspace{0pt}status\_\hspace{0pt}codes}}.\label{grpcstatuscodes}%mdk%mdk + +%mdk-data-line={references.bib:22} +\bibitem{openconfig}\mdbibitemlabel{{}[35]}\textquotedblleft{}The OpenConfig Project.\textquotedblright{} \href{http://openconfig.net}{{\ttfamily http://\hspace{0pt}openconfig.\hspace{0pt}net}}.\label{openconfig}%mdk%mdk + +%mdk-data-line={references.bib:184} +\bibitem{protomessagedifferencer}\mdbibitemlabel{{}[36]}\textquotedblleft{}The Protobuf MessageDifferencer in the C++ API.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.util.message_differencer}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}reference/\hspace{0pt}cpp/\hspace{0pt}google.\hspace{0pt}protobuf.\hspace{0pt}util.\hspace{0pt}message\_\hspace{0pt}differencer}}.\label{protomessagedifferencer}%mdk%mdk + +%mdk-data-line={references.bib:27} +\bibitem{stratum}\mdbibitemlabel{{}[37]}\textquotedblleft{}The Stratum Project.\textquotedblright{} \href{https://stratumproject.org/}{{\ttfamily https://\hspace{0pt}stratumproject.\hspace{0pt}org/\hspace{0pt}}}.\label{stratum}%mdk%mdk + +%mdk-data-line={references.bib:199} +\bibitem{v1model}\mdbibitemlabel{{}[38]}\textquotedblleft{}v1model Architecture Definition.\textquotedblright{} \href{https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4c/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}p4include/\hspace{0pt}v1model.\hspace{0pt}p4}}.\label{v1model}%mdk%mdk + +%mdk-data-line={references.bib:53} +\bibitem{p4valuesets}\mdbibitemlabel{{}[39]}\textquotedblleft{}Value Sets in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-value-set}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}value-\hspace{0pt}set}}.\label{p4valuesets}%mdk%mdk +\par%mdk +\end{thebibliography}}%mdk%mdk +}%mdk + + +\end{document} diff --git a/spec/v1.3.0/ellipse.sty b/spec/v1.3.0/ellipse.sty new file mode 100644 index 00000000..7c0ecb3e --- /dev/null +++ b/spec/v1.3.0/ellipse.sty @@ -0,0 +1,318 @@ +%% +%% This is file `ellipse.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ellipse.dtx (with options: `package') +%% +%% Copyright (C) 2015 +%% Daan Leijen +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". +%% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{ellipse} + [2004/11/05 v1.0 .dtx ellipse file] +\RequirePackage{pict2e} + +\providecommand*\pIIe@csedef[1]{\expandafter\edef\csname #1\endcsname} +\newcommand*\pIIe@ellip@csqrt[3]{% + \@ovxx=#1\relax + \ifdim\@ovxx<\z@\@ovxx-\@ovxx\fi + \@ovyy=#2\relax + \ifdim\@ovyy<\z@\@ovyy-\@ovyy\fi + \edef\pIIe@csname{@csqrt(\number\@ovxx,\number\@ovyy)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@ellip@csqrt@% + \pIIe@csedef{\pIIe@csname}{\the\dimen@}% + #3\dimen@ + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} +\newcommand*\pIIe@ellip@csqrt@{% + \@ovdx\@ovxx + \advance\@ovdx by \@ovyy + \dimen@0.7071067\@ovdx + \ifdim\dimen@<\@ovyy\dimen@\@ovyy\fi + \ifdim\dimen@<\@ovxx\dimen@\@ovxx\fi + \ifdim\@ovdx<128\p@ + \edef\@tempa{\strip@pt\@ovxx}% + \@ovxx\@tempa\@ovxx + \edef\@tempa{\strip@pt\@ovyy}% + \@ovyy\@tempa\@ovyy + \advance\@ovxx by \@ovyy + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \fi +} + +\newcommand*\pIIe@atan@{% + \@tempdima\dimen@ + \@tempdimb\@tempdima + \ifdim\@tempdimb<\z@\@tempdimb-\@tempdimb\fi + \dimen@0.0663\@tempdimb + \advance\dimen@ 0.2447pt\relax + \advance\@tempdimb -1pt\relax + \edef\@tempa{\strip@pt\@tempdimb}% + \dimen@\@tempa\dimen@ + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \dimen@-\dimen@ + \advance\dimen@ 0.7853\@tempdima +} + +\newcommand*\pIIe@atantwo[3]{% + \edef\pIIe@csname{@atan2(\number\dimexpr#1\relax,\number\dimexpr#2\relax)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@atantwo@{#1}{#2}{#3}% + \pIIe@csedef{\pIIe@csname}{\the\dimexpr#3\relax}% + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} + +\newcommand*\pIIe@atantwo@[3]{% + \@tempdima\dimexpr#2\relax + \@tempdimb\dimexpr#1\relax + \ifdim\@tempdima=\z@\relax + \ifdim\@tempdimb>\z@\relax\dimen@90\p@ + \else\ifdim\@tempdimb<\z@\relax\dimen@-90\p@ + \else\dimen@0\p@ + \fi\fi + \else + \@tempdimd\z@ + \ifdim\@tempdima<\z@\relax + \ifdim\@tempdimb<\z@\relax\@tempdimd-180\p@ + \else\@tempdimd180\p@ + \fi + \fi + \dimen@\dimexpr1pt * \@tempdimb/\@tempdima\relax + \@tempdimc\dimen@ + \ifdim\@tempdimc<\z@\relax\@tempdimc-\@tempdimc\fi + \ifdim\@tempdimc>\p@\relax + \dimen@\dimexpr1pt * \@tempdima/\@tempdimb\relax + \ifdim\dimen@<\z@\relax\def\@tempsign{-}\else\def\@tempsign{}\fi + \pIIe@atan@ + \dimen@-\dimen@ + \advance\dimen@ by \@tempsign1.5707pt\relax + \else + \pIIe@atan@ + \fi + \dimen@57.29578\dimen@ + \advance\dimen@ by \@tempdimd + \fi + #3\dimen@% +} + +\newcommand*\pIIe@noneto[2]{} +\newcommand*\pIIe@ellip@sincost@[2]{% + \CalculateSin{#1}% + \CalculateCos{#1}% + \@tempdima\UseSin{#1}\p@ + \@tempdimb\UseCos{#1}\p@ + \ifdim\@tempdima=\p@\relax + \pIIe@csedef{@ellipsin#2}{1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else\ifdim\@tempdima=-\p@\relax + \pIIe@csedef{@ellipsin#2}{-1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else + \@tempdimc\@ellipratio\dimexpr1pt * \@tempdima/\@tempdimb\relax + %\typeout{ i#2=\the\@tempdimc, sin(#1)=\the\@tempdima}% + \pIIe@ellip@csqrt{\p@}{\@tempdimc}\@tempdimd + \ifdim\@tempdimb<\z@\relax\@tempdimd-\@tempdimd\fi + \pIIe@csedef{@ellipsin#2}{\strip@pt\dimexpr1pt * \@tempdimc/\@tempdimd\relax}% + \pIIe@csedef{@ellipcos#2}{\strip@pt\dimexpr1pt * \p@/\@tempdimd\relax}% + \fi\fi +} + +\newcommand*\pIIe@ellip@sincost[2]{% + %\typeout{ calc sin cos: angles (#1,#2), radii: (\the\@ovro,\the\@ovri)}% + \edef\@ellipratio{\strip@pt\dimexpr1pt * \@ovro/\@ovri\relax}% + \pIIe@ellip@sincost@{#1}{one}% + \pIIe@ellip@sincost@{#2}{two}% + %\typeout{ sincos(a=#1)=(\@ellipsinone,\@ellipcosone), sincos(a=#2)=(\@ellipsintwo,\@ellipcostwo), }% +} +\newcommand*\pIIe@omega[3]{% + \@tempdima\csname @ellipcos#3\endcsname\@ovro + \advance\@tempdima by #1\relax + \@tempdimb\csname @ellipsin#3\endcsname\@ovri + \advance\@tempdimb by #2\relax +} + +\newcommand*\pIIe@omegai[1]{% + \@tempdimc\csname @ellipsin#1\endcsname\@ovro + \@tempdimc-\@tempdimc + \@tempdimd\csname @ellipcos#1\endcsname\@ovri +} + +\newcommand*\pIIe@ellip@kappa{% + \@ovyy\@ellipsinone\p@ + \@ovxx\@ellipcosone\p@ + \@tempdima\@ellipcostwo\@ovyy + \@tempdima-\@tempdima + \advance\@tempdima by \@ellipsintwo\@ovxx + \@tempdimb\@ellipcostwo\@ovxx + \advance\@tempdimb by \@ellipsintwo\@ovyy + \ifdim\@tempdima=\z@\relax + \edef\@ellipkappa{0}% + \else + \dimen@\dimexpr1pt - \@tempdimb\relax + \dimen@\dimexpr1pt * \dimen@/\@tempdima\relax + \pIIe@ellip@csqrt{2\p@}{1.73205\dimen@}{\dimen@}% + \advance\dimen@ by -\p@ + \divide\dimen@ by 3% + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \edef\@ellipkappa{\strip@pt\dimen@}% + \fi + %\typeout{ calculated kappa: \@ellipkappa}% +} + +\newcommand*\pIIe@elliparc@[5]{% + %\typeout{elliparc: #1, center: (#2, #3), radius (\the\@ovro, \the\@ovri),angle (#4, #5)}% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \pIIe@ellip@sincost{#4}{#5}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@t[5]{% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \CalculateSin{#4}\CalculateCos{#4}% + \edef\@ellipsinone{\UseSin{#4}}% + \edef\@ellipcosone{\UseCos{#4}}% + \CalculateSin{#5}\CalculateCos{#5}% + \edef\@ellipsintwo{\UseSin{#5}}% + \edef\@ellipcostwo{\UseCos{#5}}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@draw[2]{% + \pIIe@ellip@kappa% + \pIIe@omega{#1}{#2}{one}% + %\typeout{ point one: (\the\@tempdima,\the\@tempdimb)}% + \@ellip@startto\@tempdima\@tempdimb + \pIIe@omegai{one}% + \advance\@tempdima by \@ellipkappa\@tempdimc + \advance\@tempdimb by \@ellipkappa\@tempdimd + \pIIe@add@nums\@tempdima\@tempdimb + %\typeout{ control one: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@omega{#1}{#2}{two}% + \pIIe@omegai{two}% + \@tempdimc\@ellipkappa\@tempdimc + \@tempdimd\@ellipkappa\@tempdimd + \@tempdimc-\@tempdimc + \@tempdimd-\@tempdimd + \advance\@tempdimc by \@tempdima + \advance\@tempdimd by \@tempdimb + \pIIe@add@nums\@tempdimc\@tempdimd + %\typeout{ control two: (\the\@tempdimc,\the\@tempdimd)}% + \pIIe@add@CP\@tempdima\@tempdimb + %\typeout{ point two: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@addtoGraph\pIIe@curveto@op +} +\newcommand*\pIIe@elliparc[7][0]{% + \@ovro #4\relax + \@ovri #5\relax + \iffalse%dim\@ovro=\@ovri + \pIIe@arc[#1]{#2}{#3}{#4}{#6}{#7} + \else + \ifdim \@ovro<\z@ \pIIe@badcircarg\else + \ifdim \@ovri<\z@ \pIIe@badcircarg\else + \@arclen #7\p@ \advance\@arclen -#6\p@ + \ifdim \@arclen<\z@ \def\@tempsign{-}\else\def\@tempsign{}\fi + \ifdim \@tempsign\@arclen>720\p@ + \PackageWarning {ellipse}{The arc angle is reduced to -720..720}% + \@whiledim \@tempsign\@arclen>720\p@ \do {\advance\@arclen-\@tempsign360\p@}% + \@tempdima #6\p@ \advance\@tempdima \@arclen + \edef\@angleend{\strip@pt\@tempdima}% + \pIIe@@elliparc{#1}{#2}{#3}{#6}{\@angleend}% + \else + \pIIe@@elliparc{#1}{#2}{#3}{#6}{#7}% + \fi + \fi + \fi + \fi +} +\newcommand*\pIIe@@elliparc[5]{% + \begingroup + \ifdim \@tempsign\@arclen>90\p@ + \divide\@arclen 2% + \@tempdima #4\p@\advance\@tempdima by \@arclen + \edef\@anglemid{\strip@pt\@tempdima}% + \def\@tempa{\pIIe@@elliparc{#1}{#2}{#3}{#4}}% + \expandafter\@tempa\expandafter{\@anglemid}% + \def\@tempa{\pIIe@@elliparc{2}{#2}{#3}}% + \expandafter\@tempa\expandafter{\@anglemid}{#5}% + \else + \pIIe@elliparc@{#1}{#2}{#3}{#4}{#5}% + \fi + \endgroup +}% + +\newcommand*\pIIeelliparc[7][0]{% + \@killglue + \pIIe@elliparc[#1]{#2\unitlength}{#3\unitlength}{#4\unitlength}{#5\unitlength}{#6}{#7}% + \ignorespaces% +} +\ifx\undefined\elliparc\else + \PackageWarning{ellipse}{\protect\elliparc\space is redefined}% +\fi +\let\elliparc\pIIeelliparc + +\newcommand*\pIIeearc + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\newcommand*\pIIe@earc@[3][0,360]{\pIIe@earc@@(#1){#2}{#3}} +\def\pIIe@earc@@(#1,#2)#3#4{% + \if@tempswa + \pIIe@moveto\z@\z@ + \pIIe@elliparc{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@closepath\pIIe@fillGraph + \else + \pIIe@elliparc[1]{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@strokeGraph + \fi} +\ifx\undefined\earc\else + \PackageWarning{ellipse}{\protect\earc\space is redefined}% +\fi +\let\earc\pIIeearc + +\newcommand*\pIIeellipse + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\let\ellipse\pIIeellipse + +\endinput +%% +%% End of file `ellipse.sty'. diff --git a/spec/v1.3.0/embedded-plus-single-remote-controller.png b/spec/v1.3.0/embedded-plus-single-remote-controller.png new file mode 100644 index 00000000..2e0f1803 Binary files /dev/null and b/spec/v1.3.0/embedded-plus-single-remote-controller.png differ diff --git a/spec/v1.3.0/embedded-plus-single-remote-controller.svg b/spec/v1.3.0/embedded-plus-single-remote-controller.svg new file mode 100644 index 00000000..9fe2ce9c --- /dev/null +++ b/spec/v1.3.0/embedded-plus-single-remote-controller.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spec/v1.3.0/embedded-plus-two-remote-controllers.png b/spec/v1.3.0/embedded-plus-two-remote-controllers.png new file mode 100644 index 00000000..b6dc04fc Binary files /dev/null and b/spec/v1.3.0/embedded-plus-two-remote-controllers.png differ diff --git a/spec/v1.3.0/embedded-plus-two-remote-controllers.svg b/spec/v1.3.0/embedded-plus-two-remote-controllers.svg new file mode 100644 index 00000000..0f97ba38 --- /dev/null +++ b/spec/v1.3.0/embedded-plus-two-remote-controllers.svg @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + + + Entities + + + + + + + \ No newline at end of file diff --git a/spec/v1.3.0/embedded-plus-two-remote-ha-controllers.png b/spec/v1.3.0/embedded-plus-two-remote-ha-controllers.png new file mode 100644 index 00000000..392f8963 Binary files /dev/null and b/spec/v1.3.0/embedded-plus-two-remote-ha-controllers.png differ diff --git a/spec/v1.3.0/embedded-plus-two-remote-ha-controllers.svg b/spec/v1.3.0/embedded-plus-two-remote-ha-controllers.svg new file mode 100644 index 00000000..97ab6fc3 --- /dev/null +++ b/spec/v1.3.0/embedded-plus-two-remote-ha-controllers.svg @@ -0,0 +1,511 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + Primary (Active) + + + + + + Backup (Standby) + + + + + + + \ No newline at end of file diff --git a/spec/v1.3.0/error-report.png b/spec/v1.3.0/error-report.png new file mode 100644 index 00000000..766cb77f Binary files /dev/null and b/spec/v1.3.0/error-report.png differ diff --git a/spec/v1.3.0/error-report.svg b/spec/v1.3.0/error-report.svg new file mode 100644 index 00000000..a2709a72 --- /dev/null +++ b/spec/v1.3.0/error-report.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StatusCode error_code_; // canonical error codestring error_message_;string binary_error_details_; // serialized google.rpc.Status + + + + + + + + + + + + + google.rpc.Status + + + + + + int32 error_code; // canonical error codestring message;repeated Any details; // P4Error + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + + + p4.Error + + + + + + p4.Error + + + + + + + + + + + + + + + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + grpc::Status + + + + + + + \ No newline at end of file diff --git a/spec/v1.3.0/longbox.sty b/spec/v1.3.0/longbox.sty new file mode 100644 index 00000000..cab48934 --- /dev/null +++ b/spec/v1.3.0/longbox.sty @@ -0,0 +1,853 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longbox}[2015/12/01, Daan Leijen, Provides basic longbox that can break over pages] +\RequirePackage{options} + +\@ifclassloaded{beamer}{% + \newcommand\lb@savefootnotes{}% + \newcommand\lb@restorefootnotes{}% +}% +{\RequirePackage{footnote}% + \newcommand\lb@savefootnotes{\savenotes}% + \newcommand\lb@restorefootnotes{\spewnotes}% +} + + +% -------------------------------------------------------- +% Debugging +% -------------------------------------------------------- + +\newcommand*\lb@debug[1]{% + \ontoggle{lb@debug}{\typeout{longbox debug: #1}}% +} +\newcommand*\lb@typeout[1]{% + \ontoggle{lb@verbose}{\typeout{longbox: #1}}% +} +\newcommand*\lb@warncannotsplit{% + \PackageWarning{longbox}{Cannot split box; it seems you are using a non-splittable contents}% +} +\newcommand*\lb@warnbadsplit[1]{% + \PackageWarning{longbox}{Bad split (underful vbox by \the#1)}% +} + + +% -------------------------------------------------------- +% Utilities for LaTeX internals +% -------------------------------------------------------- + +% Suppress the indentation on the following paragraph +\providecommand\nofirstindent{\@afterindentfalse\@afterheading} + +% Suppress the paragraph skip on the following paragraph +\providecommand\nofirstparskip{\addvskip{-\parskip}} + +% In contrast to addvspace, addvskip is not suppressed in a minipage +\providecommand\addvskip[1]{% + \ifvmode + \ifdim\lastskip=\z@ + \vskip #1\relax + \else + \@tempskipb#1\relax\@xaddvskip + \fi + \else\@noitemerr\fi +} + + +% Skip to 0.3\baselineskip multiple taking prevdepth into account. +\newskip\lb@prevdepth +\newcommand\lb@skiptobaseline{% + \global\lb@prevdepth=-\@m\p@\relax + \ifvmode + \ifdim\lastskip=\z@\relax + \ifdim\prevdepth=-\@m\p@\else + \dimen@\prevdepth + % Calculate the modulus of the previous depth with 0.3|\baselineskip| in |\dimen@|. + \@tempcnta\prevdepth + \@tempskipa=0.3\baselineskip\relax + \@tempcntb=\@tempskipa\relax + \divide \@tempcnta by \@tempcntb + \dimen@\prevdepth + \advance\dimen@ -\@tempcnta\@tempskipa + % Skip back by that amount, and then skip by 0.3|\baselineskip|. + \vskip -\dimen@ + \vskip \@tempskipa\relax + \global\lb@prevdepth=\@tempskipa\relax + \fi + \fi + \fi +} + +% unvbox a box, and return a vbox with a given background color +% \unvcolorbox{}{} +\newcommand\unvcolorbox[2]{% + \ifoptionblank{#1}{\vbox{\unvbox#2}}{% + \lb@debug{vcolorbox: #1}% + \vbox{\offinterlineskip + \hbox to \z@{\vbox to \z@{\optioncolor{#1}\hrule\@width\wd#2\@height\ht#2\@depth\dp#2\vss}\hss}% + \unvbox#2% + }% + }% +} + +% create a vbox with a given background color +\newcommand\vcolorbox[2]{% + \eifblank{#1}{\vbox{#2}}{% + \setbox\z@=\vbox{#2}\relax + \unvcolorbox{#1}{\z@}% + }% +}% + +% -------------------------------------------------------- +% The following macros come from mdframed +% -------------------------------------------------------- + +% Determine the amount of free space left on the current page +\newlength\lb@freevspace +\newcommand*\lb@setfreevspace@page{% + \lb@debug{ determine free space}% + \bgroup\@nobreakfalse\addpenalty\z@\egroup% + \penalty\@M\relax\vskip 2\baselineskip\relax% + \penalty9999\relax\vskip -2\baselineskip\relax% + \penalty9999% + \ifdim\pagegoal=\maxdimen\relax% + \lb@freevspace=\vsize% + \else + \lb@freevspace=\dimexpr\pagegoal-\pagetotal-\parskip\relax% + \fi + \lb@debug{free space: \the\lb@freevspace, in page: \the\textheight, vsize=\the\vsize}% +} + +\newcommand*\lb@shiftdim[2]{% + %\letoption{#1}\lb@list + \expandafter\lb@setheadtail@#1,\relax + \eifblank{\lb@head}{}{\option@invoke{/longbox/@breakat-previous}{\lb@head}}% + #2\option{/longbox/@breakat-previous}% + \eifblank{\lb@tail}{}{\let#1\lb@tail}% push back tail +} +\def\lb@comma{,}% +\def\lb@setheadtail@#1,#2\relax{% + \def\lb@head{#1}% + \def\lb@tail{#2}% adds commas! +} + +\newcommand*\lb@setfreevspace{% + \eifblank{\lb@breakat}{\lb@setfreevspace@page}{% + \def\lb@eject{\par}%no eject + \lb@extrasplit=\z@\relax% + \lb@shiftdim{\lb@breakat}\lb@freevspace + \ifdim\lb@freevspace>\z@\else\lb@setfreevspace@page\fi + }% +} + + +% Suppress overfull-underfull vbox messages +\newcommand*\lb@ignorevbadness{% + \edef\lb@currentvbadness{\the\vbadness}% + \edef\lb@currentvfuzz{\the\vfuzz}% + \vbadness=\@M\relax% + \vfuzz=\maxdimen\relax% + \afterassignment\lb@restorevbadness +} +\newcommand*\lb@restorevbadness{% + \vbadness=\lb@currentvbadness\relax + \vfuzz=\lb@currentvfuzz\relax +} + + +% -------------------------------------------------------- +% The 'long vbox' (lvbox) environment collects long material +% into a long \vbox, instead of a \hbox like a lrbox in latex. +% The collected box can contain any box, minipage, lrbox, fbox etc, +% but not outer-par material like a figure. Footnotes can be +% dealt with useing lb@savefootnotes. +% +% The material is typeset in a \vbox according to a given width. +% inside the environment, the boolean 'inlvbox' is true. +% +% \begin{lvbox}{}{} +% -------------------------------------------------------- + +\newif\ifinlvbox +\newcommand\lvbox[4]{% + \setbox#1\vbox\bgroup + \begingroup + \inlvboxtrue + % reset defaults + \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\par\@@par + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + % set margin and linewidth + \leftmargin=#2\relax\rightmargin=#4\relax + \@totalleftmargin=\leftmargin% + %\leftskip=#2\relax\rightskip=#4\relax\@rightskip=#4\relax + \linewidth=#3\relax + % set primitive tex margins + \leftskip=\@totalleftmargin% + \rightskip=\rightmargin% + \@rightskip=\rightmargin% + \hsize=\dimexpr\@totalleftmargin+\linewidth+\rightmargin\relax + \columnwidth\hsize + \textwidth\hsize + \nofirstindent + %\nofirstparskip +} +\def\endlvbox{\endgroup\egroup} + + + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + + +\newsavebox\lb@headbox +\newsavebox\lb@savebox +\newsavebox\lb@mainbox + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@setbaseline[1]{% + %\typeout{ set baseline, \the\dp#1,\the\ht#1}% + \ifcase\lb@baseline% + \relax%bottom + \or%middle + \setbox#1=\vbox{\hbox{\lower \dimexpr(\dp#1 + \ht#1)/2 - \dp#1\relax\vbox{\unvbox#1}}}% + \or%top + \setbox#1=\vtop{\unvbox#1}% + \fi + %\typeout{ .new dim: \the\dp#1, \the\ht#1}% +} + + +\@ifundefined{define@key}{}% + {\define@key{longbox}{options}{\options{#1}\option{/longbox/adjust-options}}}% + +\newcommand*\lb@render@breakbox{% + %\typeout{render breakbox entry (in output routine), height=\the\bb@height}% + \bb@restorekeys{longbox}% + \lb@skiptop=\ifbb@isfirst\option{/longbox/skip-top}\else\option{/longbox/skip-break-top}\fi\relax + \lb@skipbottom=\ifbb@islast\option{/longbox/skip-bottom}\else\option{/longbox/skip-break-bottom}\fi\relax + \lb@skipbreaktop=\ifbb@isfirst 0pt\else\option{/longbox/skip-break-top}\fi + \lb@skipbreakbottom=\ifbb@islast 0pt\else\option{/longbox/skip-break-bottom}\fi + %\typeout{ render: skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom, break-top=\the\dimexpr\option{/longbox/skip-bottom}}% + \options{% + /longbox/@part-height=\bb@height + \lb@skipbreaktop + \lb@skipbreakbottom, + /longbox/@part-width=\option{/longbox/width} + \option{/longbox/skip-left} + \option{/longbox/skip-right},%\bb@width, + /longbox/@part-depth=0pt, + /longbox/@part-needtop=\ifbb@isfirst true\else false\fi, + /longbox/@part-needbottom=\ifbb@islast true\else false\fi, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-depth=\option{/longbox/@part-depth}, + }% + %\typeout{breakbox: width=\expandafter\the\option{/longbox/width}, \the\bb@width, \the\dimexpr\option{/longbox/@part-width}}% + \vbox{% + \kern -\lb@skipbreaktop% todo: move to breakbox? + \option{/longbox/render}% + \kern -\lb@skipbreakbottom + }% +} + +\newcommand*\lb@render@vbox[1]{% + \lb@debug{render vbox entry}% + \lb@restoreoptions + \lb@skiptop=\dimexpr\iftoggle{/longbox/@part-needtop}{\option{/longbox/skip-top}}{\option{/longbox/skip-break-top}}\relax + \lb@skipbottom=\dimexpr\iftoggle{/longbox/@part-needbottom}{\option{/longbox/skip-bottom}}{\option{/longbox/skip-break-bottom}}\relax + %\typeout{ skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom}% + % add top skip while maintaining the baseline. + \ifdim\lb@skiptop=\z@\relax\else + \setbox\z@=\vtop{\unvcopy#1}% + \dimen@=\ht\z@ + \setbox#1=\vbox{\offinterlineskip + \hrule width \z@ height \dimexpr\dimen@ + \lb@skiptop\relax depth -\dimen@ + \unvbox#1% + }% + \fi + % add bottom skip while maintaining the baseline. + \ifdim\lb@skipbottom=\z@\relax\else + \dimen@=\dp#1% + \setbox#1=\vbox{\offinterlineskip\unvbox#1\hrule width \z@ height -\dimen@ depth \dimexpr\dimen@ + \lb@skipbottom\relax}% + \fi + \lb@setbaseline{#1}% + \options{% + /longbox/@part-height=\dimexpr\ht#1 + \dp#1\relax, + /longbox/@part-width=\dimexpr\wd#1 + \option{/longbox/skip-left} + \option{/longbox/skip-right}\relax, + /longbox/@part-depth=\dp#1, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-depth=\option{/longbox/@part-depth} - \lb@skipbottom, + }% + %\typeout{ longbox: height=\the\dimexpr\option{/longbox/@content-box-height}, outer height=\the\dimexpr\option{/longbox/@part-height}\relax}% + % lower the box depending on vertical alignment + \ifcase\option{/longbox/vertical-align/@ord}\relax + \@tempdima\z@ + \or + %bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%middle + \@tempdima\dimexpr0.5\option{/longbox/@part-height} - \option{/longbox/@part-depth}\relax + \or%top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%text-bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%text-top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%super + \@tempdima=-0.9ex% + \or%sub + \@tempdima=0.7ex% + \else + \@tempdima\z@ + \fi + \advance\@tempdima by -\option{/longbox/raise}% + \option@invoke{/longbox/@lower}{\@tempdima}% + \noindent\hbox{\lower \@tempdima\vbox{\offinterlineskip + \hbox to \z@{% + \vbox to \z@{% + \hbox{\lower \option{/longbox/@part-height}\vbox{\offinterlineskip{\option{/longbox/render}}}}% + \vss}% + \hss + }% + \hbox{% + \ifdim\option{/longbox/skip-left}=\z@\else\hskip\option{/longbox/skip-left}\fi + \box#1% + \ifdim\option{/longbox/skip-right}=\z@\else\hskip\option{/longbox/skip-right}\fi + %$\box#1% + }% + }}% +} + +\newcommand*\lb@single@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} +\newcommand*\lb@first@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@middle@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@last@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand*\lb@env@start{% + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore +} + +\newcount\lb@usevbox +\newlength\lb@width +\newlength\lb@height +\newlength\lb@skiptop +\newlength\lb@skipright +\newlength\lb@skipbottom +\newlength\lb@skipleft +\newlength\lb@skipbreaktop +\newlength\lb@skipbreakbottom +\newlength\lb@outerwidth +\newlength\lb@extrasplit +\newcount\lb@textalign +\newcount\lb@baseline +\newtoggle{lb@baselineskip}% +\newtoggle{lb@breakable}% +\newtoggle{lb@debug}% +\newtoggle{lb@verbose}% +\def\lb@breakat{}% +\def\lb@halign{}% +\def\lb@eject{}% +\def\lb@insertafter{} +\def\lb@insertbefore{} + +\newcommand*\lb@peekoptions[1]{% + % process options inside a group and just set necessary parameters + % this way, nested boxes don't influence each other's parameters + \begingroup + \options{#1}% + \option{/longbox/adjust-options}% + \protected@edef\lb@temp{\endgroup + \lb@width=\the\dimexpr\option{/longbox/width}\relax + \lb@height=\the\dimexpr\option{/longbox/height}\relax + \lb@textalign=\the\numexpr\option{/longbox/text-align/@ord}\relax + \lb@baseline=\the\numexpr\option{/longbox/baseline/@ord}\relax + \lb@skiptop=\the\dimexpr\option{/longbox/skip-top}\relax + \lb@skipright=\the\dimexpr\option{/longbox/skip-right}\relax + \lb@skipbottom=\the\dimexpr\option{/longbox/skip-bottom}\relax + \lb@skipleft=\the\dimexpr\option{/longbox/skip-left}\relax + \lb@skipbreaktop=\the\dimexpr\option{/longbox/skip-break-top}\relax + \lb@skipbreakbottom=\the\dimexpr\option{/longbox/skip-break-bottom}\relax + \lb@usevbox=\iftoggle{/longbox/use-vbox}{1}{0}\relax + \lb@outerwidth=\the\dimexpr\option{/longbox/outer-width}\relax + \lb@extrasplit=\the\dimexpr\option{/longbox/split-minimum}\relax + \def\noexpand\lb@insertafter{\option{/longbox/insert-after}}% + \def\noexpand\lb@insertbefore{\option{/longbox/insert-before}}% + \def\noexpand\lb@breakat{\option{/longbox/breakat}}% + \def\noexpand\lb@halign{\option{/longbox/height-align}}% + \def\noexpand\lb@eject{\option{/longbox/eject}}% + \noexpand\csname toggle\iftoggle{/longbox/baseline-skip}{true}{false}\endcsname{lb@baselineskip}% + \noexpand\csname toggle\iftoggle{/longbox/breakable}{true}{false}\endcsname{lb@breakable}% + \noexpand\csname toggle\iftoggle{/longbox/debug}{true}{false}\endcsname{lb@debug}% + \noexpand\csname toggle\iftoggle{/longbox/verbose}{true}{false}\endcsname{lb@verbose}% + }% + \lb@temp +} + +\newenvironment{longbox@env}[2]{% + % save options + \lb@peekoptions{#1,#2}% + % + \ifnum\lb@usevbox=0\relax + \lb@debug{start breakbox}% + \let\bb@render\lb@render@breakbox + \bb@savekeys{longbox}{options={#1,#2,outer-width=\the\lb@outerwidth}}% + \iftoggle{lb@baselineskip}{\typeout{**insert bskip}}{\typeout{**suppress bskip}\vskip 1pt}% + \begin{breakbox}% + \ifdim\lb@skiptop=\z@\relax\else\vspace{\lb@skiptop}\fi% + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \begin{bb@margins}{\lb@skipleft}{\dimen@}% + \else + \lb@debug{start vbox}% + \def\lb@restoreoptions{\options{#1,#2}\option{/longbox/adjust-options}}% + \lb@savefootnotes + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \lb@debug{ width=\the\lb@width, linewidth=\the\linewidth, skipleft=\the\lb@skipleft, right=\the\lb@skipright, total right=\the\dimen@}% + \iftoggle{lb@baselineskip}{\lb@skiptobaseline}{\lb@prevdepth=-\@m pt}% + \lvbox{\lb@mainbox}{0pt}{\lb@width}{0pt}%{\lb@skipleft}{\lb@width}{\lb@skipright}% + \prevdepth=\lb@prevdepth + \fi + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore + \begingroup +}{% + \par\unskip + \endgroup + \lb@insertafter + %\ifdim\lb@skipbottom=\z@\relax\else\vskip\lb@skipbottom\fi% + \ifnum\lb@usevbox=0\relax + \end{bb@margins}% + \ifdim\lb@skipbottom=\z@\relax\else\hrule width \z@ height \lb@skipbottom\fi%\vspace{\lb@skipbottom}\fi% + \iftoggle{lb@baselineskip}{}{\vskip 1sp}% + \end{breakbox}% + \lb@debug{end breakbox}% + \else + \ontoggle{lb@baselineskip}{\lb@skiptobaseline}% + \endlvbox% + \lb@debug{initial lvbox: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@processbox + %\setbox\lb@mainbox=\hbox{\lower \lb@skipbottom\vbox{\offinterlineskip\unvbox\lb@mainbox}}% + \lb@restorefootnotes + \lb@debug{end vbox}% + \fi +} + +\newcommand\longbox@cmd[3]{% + \begingroup + %\options{/options/collectunknown,/longbox/scoped,#2}% set scoped options first + %\option{/longbox/scoped/@adjust-options}% + \lb@peekoptions{#1,#2}% + \leavevmode + %\setbox\lb@mainbox=\hbox{% + % \begingroup + % #3% + % \endgroup + %}% + \setbox\lb@mainbox=\hbox{% + \begingroup + \ifcase\lb@textalign\relax + %default=left + \or%left + \or\hss%center + \or\hss%right + \else%justify + \fi + \lb@insertbefore + #3% + \lb@insertafter + \ifnum\lb@textalign<3\relax\hss\fi% default,left,center + \endgroup + }% + \options{#1,#2}% + \ifdim\option{/longbox/width}=-1sp\relax + \options{/longbox/width=\wd\lb@mainbox}%set to natural width + \fi + \option{/longbox/adjust-options}% + % make it a vbox + \setbox\lb@mainbox=\vbox{\offinterlineskip% + \hbox to \option{/longbox/width}{% + \unhbox\lb@mainbox + }% + }% + \def\lb@restoreoptions{}% + \letoption{/longbox/height-align}\lb@halign + \lb@height=\option{/longbox/height}\relax + \lb@baseline=\option{/longbox/baseline/@ord}\relax + \lb@processbox + \endgroup +} + +\newcommand\lb@processbox{% + \ifdim\lb@height<0pt\relax + \lb@setbaseline{\lb@mainbox}% + \else + \lb@restrictheight + \fi + \lb@typesetbox +} + +\newcommand\lb@typesetbox{% + \ifinlvbox + \iftoggle{lb@breakable}{% + %\lb@debug{disable breakable due to nesting of long-boxes}% + \togglefalse{lb@breakable}% + }{}% + \fi + \ifhmode\lb@single@{\lb@mainbox}\else\lb@typeset\fi +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@restrictheight{% + \lb@typeout{restrict height to \the\lb@height}% + \lb@splitheight=\lb@height% + %lb@debug{before height split: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + %split failed.. do nothing + \lb@debug{could not restrict height}% + \else + % store splitted off content in the mainbox (and discard the rest) + \setbox\lb@mainbox\vbox{\unvbox\lb@headbox}% + \lb@debug{restricted height to \the\ht\lb@mainbox}% + \fi + % set baseline + \lb@setbaseline{\lb@mainbox}% + % height align + %\letoption{/longbox/height-align}\lb@halign + \eifstrequal{\lb@halign}{bottom}% + {\setbox\lb@mainbox=\vbox{\hbox{\vbox to \lb@splitheight{\vss\unvbox\lb@mainbox}}}}% + {\eifstrequal{\lb@halign}{middle}% + {\dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\hbox{% + \lower \dimexpr0.5\dimen@ + \dp\lb@mainbox\relax% + \vbox to \lb@splitheight{\vss\unvbox\lb@mainbox\vss}}}}% + {% default is top + \dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\vtop to \lb@splitheight{\box\lb@mainbox\vss}}% + }% + }% +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newlength\lb@neededvspace +\newcommand\lb@typeset[1][0pt]{% + \iftoggle{lb@breakable}{% + \lb@setfreevspace + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skiptop+\lb@skipbottom\relax}% + \lb@debug{needed: \the\lb@neededvspace, available: \the\lb@freevspace}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@single@{\lb@mainbox}% + \else + \lb@typeout{longbox needs splitting}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skiptop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \ifdim\dimexpr\lb@freevspace + #1\relax<\textheight\relax % test if we were at a fresh page.. (and prevent infinite recursion) + \lb@debug{failed to split the box, inserting a page break}% + \hrule \@height\z@ \@width\hsize + \lb@eject% + \lb@typeset[\textheight]% try again, but pass \textheight to guard against infinite recursion + \else + % on a fresh page we should not fail anymore.. just output as is.. + % lb@warncannotsplit + \lb@single@{\lb@mainbox}% + \fi + \else + % first part success + \lb@typeout{first part splitted}% + \lb@first@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest + \fi + \fi + }{%\else + \lb@debug{unbreakable box}% + \lb@single@{\lb@mainbox}% always directly output an unbreakable box + }% +} + +\newcommand\lb@typesetrest{% + \lb@setfreevspace% + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skipbottom+\lb@skipbreaktop\relax}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@typeout{output last part of box}% + \lb@last@{\lb@mainbox}% + \else + \lb@debug{split box further}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skipbreaktop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \lb@typeout{failed to split box!}% + \lb@last@{\lb@mainbox}% + \else + % middle part success + \lb@typeout{output middle part of box}% + \lb@middle@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest% continue the iteration... + \fi + \fi +} + +% -------------------------------------------------------- +% Split a long vbox over multiple pages. +% This code is based on similar code in the mdframed package +% -------------------------------------------------------- + +\newlength\lb@splitheight +\newlength\lb@insurance % tiny extra space to ensure our box will really fit +\setlength\lb@insurance{1pt} + +% expects split target height in lb@splitheight, and splits off the start of lb@mainbox to lb@headbox +\newcommand\lb@splitbox{% + \ifdim\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax>\lb@splitheight\relax + % the main box is larger than our target split height.. + \ifdim\lb@extrasplit>\lb@splitheight\relax + % not enough space to bother + \lb@typeout{not enough space on page for a split}% + \setbox\lb@headbox=\vbox{}% empty head + \else + % try a split; lower the split height a bit so we are sure to fit + \advance\lb@splitheight -\lb@insurance\relax + \lb@debug{split: \the\lb@splitheight, from \the\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax}% + \setbox\lb@savebox=\vbox{\unvcopy\lb@mainbox}% save original + \lb@trysplit{\lb@splitheight}% + \ifdim\dimexpr\ht\lb@headbox + \dp\lb@headbox>\lb@splitheight\relax + % too big, bad split. Try other splits.. iterate N times with 1 or 5pt less before giving up + \dimen@=\lb@splitheight\relax + \@tempcnta=\z@\relax + \loop + \ifdim\dimexpr\ht\lb@headbox+\dp\lb@headbox\relax>\lb@splitheight\relax + \ifnum\@tempcnta<50% + \advance\dimen@ by -\p@\relax% try a slightly smaller height.. + \else + \advance\dimen@ by -5\p@\relax% try larger increase after 50pt.. + \fi + \advance\@tempcnta by \@ne\relax + \lb@ignorevbadness + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \lb@trysplit{\dimen@}% + \ifdim\lb@extrasplit<\dimen@\relax\else\lb@splitstop\fi % don't try to split too small + \ifnum\@tempcnta<100\relax\else\lb@splitstop\fi % and not more than N attempts + \repeat% + \ifnum\@tempcnta<100\relax + \dimen@=\dimexpr\lb@splitheight - \ht\lb@headbox - \dp\lb@headbox\relax + \ifdim\dimen@>\option{/longbox/split-badness}\relax + \lb@warnbadsplit{\dimen@}% + \fi + \fi + \fi + \fi + \else + % mainbox fits in our target lb@splitheight + \setbox\lb@headbox=\vbox{\unvbox\lb@mainbox}% + \setbox\lb@mainbox=\vbox{}% + \fi +} + +\newcommand\lb@splitstop{% + \lb@typeout{cannot find a good split}% + \let\iterate\relax + \lb@warncannotsplit + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \setbox\lb@headbox=\vbox{}% empty head + \@tempcnta=\@M\relax +} + +\newcommand\lb@trysplit[1]{% try to split at given height + \lb@typeout{try to split at: \the\dimexpr #1\relax}% + \lb@ignorevbadness + \setbox\lb@headbox=\vsplit\lb@mainbox to #1\relax% + \setbox\lb@headbox=\vbox{\unvbox\lb@headbox}% + \setbox\lb@mainbox=\vbox{\unvbox\lb@mainbox}% +} + +% -------------------------------------------------------- +% The longbox environment uses options to set its options +% -------------------------------------------------------- + + +% keys and styles that can be set once globally +\options{% + /longbox/.new family, +}% + +\options{/longbox,% + % computed + @part-needtop/.new toggle, + @part-needbottom/.new toggle, + @part-height/.new length, + @part-width/.new length, + @part-depth/.new length, + @content-box-height/.new length, + @content-box-width/.new length, + @content-box-depth/.new length, + @breakat-previous/.new length, + @lower/.new length, + % + debug/.new toggle, + verbose/.new toggle, + render/.new value =\lb@render@fbox, + adjust-options/.new value = {\longbox@adjustoptions}, + eject/.new value = {\protect\vfill\protect\eject}, + use-vbox/.new toggle = true, + split-minimum/.new length = {1.5\baselineskip}, + split-badness/.new length = \baselineskip, + % + height-align/.new choice= {top,middle,bottom}, + baseline/.new choice = {bottom,middle,top}, + text-align/.new choice = {default,left,center,right,justify}, + vertical-align/.new choice = {baseline,bottom,middle,top,text-bottom,text-top,super,sub}, + raise/.new length = {0pt}, + baseline-skip/.new toggle =true, + % + height/.new length = -1sp, + width/.new length = -1sp, + outer-height/.new length= -1sp, + outer-width/.new length = -1sp, + insert-before/.new value= {}, + insert-after/.new value = {}, + breakat/.new value = {}, + breakable/.new toggle = false, + skip/.new style = {skip-top=#1,skip-right=#1,skip-bottom=#1,skip-left=#1}, + skip-top/.new length, + skip-right/.new length, + skip-bottom/.new length, + skip-left/.new length, + skip-break-bottom/.new length, + skip-break-top/.new length, +} + +\newcommand\longbox@adjustoptions{% + %\typeout{ standard longbox adjustoptions}% + \lb@debug{ current width=\the\dimexpr\option{/longbox/width}, outer=\the\dimexpr\option{/longbox/outer-width}, linewidth=\the\linewidth}% + \ontoggle{/longbox/debug}{\option@invoke{/longbox/verbose}{true}}% + % adjust height + \ifdim\option{/longbox/height}=-1sp\relax + \ifdim\option{/longbox/outer-height}=-1sp\else + \option@invoke{/longbox/height}% + {\option{/longbox/outer-height}-\option{/longbox/skip-top}-\option{/longbox/skip-bottom}}% + \fi + \fi + % set width + \ifdim\option{/longbox/width}=-1sp\relax + \ifdim\option{/longbox/outer-width}=-1sp\relax + \option@invoke{/longbox/outer-width}{\linewidth}% + \fi + \dimen@=\dimexpr\option{/longbox/outer-width}-\option{/longbox/skip-left}-\option{/longbox/skip-right}\relax + \ifdim\dimen@<\z@\relax\dimen@=\z@\fi + \option@invoke{/longbox/width}{\dimen@}% + \fi + % use a breakbox whenever we are in external vertical mode and not width or height restricted. + \iftoggle{/longbox/use-vbox}{}{% + \ifinner\toggletrue{/longbox/use-vbox}\else + \ifhmode\toggletrue{/longbox/use-vbox}\else + \ifdim\option{/longbox/height}>-1sp\toggletrue{/longbox/use-vbox}\else + \iftoggle{/longbox/breakable}{}{\toggletrue{/longbox/use-vbox}}% + \ifoptionblank{/longbox/breakat}{}{\toggletrue{/longbox/use-vbox}}% + \fi\fi\fi + }% +} + +\newenvironment{longbox}[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \begin{longbox@env}{/longbox}{#1}% +}{\end{longbox@env}} + +\newcommand\lbox[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \longbox@cmd{/longbox}{#1}% +} + +\newcommand*\lb@render@fbox{% + %\typeout{render defaultbox: bgcolor=\bb@bgcolor, needtop=\iftoggle{/longbox/@part-needtop}{true}{false}}% + \@ovdx=\dimexpr\option{/longbox/@part-width} - 2\fboxrule\relax% + \@ovdy=\dimexpr\option{/longbox/@part-height}\relax% + \iftoggle{/longbox/@part-needbottom}% + {\@tempdima=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdima=\dimexpr\fboxrule + \bb@stickout\relax + \advance\bb@height by \@tempdima + \advance\@ovdy by \@tempdima}% + \iftoggle{/longbox/@part-needtop}% + {\@tempdimb=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdimb=\dimexpr\bb@stickout\relax + \advance\bb@height by \@tempdimb + \advance\@ovdy by \@tempdimb}% + % + \hbox{\lower \@tempdima\vbox{% + \vskip -\@tempdimb + \ontoggle{/longbox/@part-needtop}{\lb@debug{toprule wd=\expandafter\the\option{/longbox/width}}\hrule width \option{/longbox/@part-width} height \fboxrule}% + \hbox{% + \vrule width \fboxrule height \@ovdy% + \ifx\bb@bgcolor\@empty + \vrule width \@ovdx height \z@\relax + \else + {\color{\bb@bgcolor}\vrule width \@ovdx height \@ovdy}% + \fi + \vrule width \fboxrule height \@ovdy% + }% + \ontoggle{/longbox/@part-needbottom}{\hrule width \option{/longbox/@part-width} height \fboxrule}% + }}% +} \ No newline at end of file diff --git a/spec/v1.3.0/longfbox.sty b/spec/v1.3.0/longfbox.sty new file mode 100644 index 00000000..0df01331 --- /dev/null +++ b/spec/v1.3.0/longfbox.sty @@ -0,0 +1,1344 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longfbox}[2015/12/01, Daan Leijen, Provides long fbox that can break over pages] + +\RequirePackage{options} +\RequirePackage{longbox} +\RequirePackage{pict2e} +\RequirePackage{ellipse} + +% -------------------------------------------------------- +% Dimension calulations +% -------------------------------------------------------- + +% dimmin/dimmax return minimum or maximum dimension +\providecommand\dim@min[2]{\ifdim#1>#2#2\else #1\fi} +\providecommand\dim@max[2]{\ifdim#1>#2#1\else #2\fi} + +\newcommand*\option@dimmin[2]{\dim@min{\option{#1}}{\option{#2}}} +\newcommand*\option@dimmax[2]{\dim@max{\option{#1}}{\option{#2}}} + + +% -------------------------------------------------------- +% Add a new 'sides' option type +% -------------------------------------------------------- + +\options{ + /handlers/new sides/.new handler = []{ + \ifblank{#2}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#1-top={##1}, #1-right={##2}, #1-bottom={##3}, #1-left={##4}}}}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#2}}}% + \optionsalso{ + #1/.new cmdx = {##1,##2,##3,##4,##5\relax}{,,,,\relax}{% + \ifblank{##2##3##4}{\option{#1/@cmd@sides}{##1}{##1}{##1}{##1}}% + {\ifblank{##3##4}{\option{#1/@cmd@sides}{##1}{##2}{##1}{##2}}% + {\ifblank{##4}{\option{#1/@cmd@sides}{##1}{##2}{##3}{##2}}% + {\option{#1/@cmd@sides}{##1}{##2}{##3}{##4}}% + }% + }% + }, + #1/.type = sides, + }% + },% +} + +\newcommand*\optionlengthlimit[3]{% len, min, max + \letoption{#1}\opt@temp + \ifdim\opt@temp<\dimexpr#2\relax + \option@invoke{#1}{#2}% + \else\ifdim\opt@temp>\dimexpr#3\relax + \option@invoke{#1}{#3}% + \fi\fi +} + +\newcommand*\optionradiuslimit[4]{% r1, r2, min, max + \letoption{#1}\opt@tempa + \letoption{#2}\opt@tempb + \ifdim\opt@tempa<\dimexpr#3\relax\option@invoke{#1}{#3}\fi + \ifdim\opt@tempb<\dimexpr#3\relax\option@invoke{#2}{#3}\fi + \ifdim\dimexpr\opt@tempa + \opt@tempb\relax=\z@\relax\else + \ifdim\dimexpr\opt@tempa+\opt@tempb\relax>\dimexpr#4\relax + \edef\opt@perc{\the\numexpr(\number\dimexpr#4\relax)/% + (\number\dimexpr(\opt@tempa+\opt@tempb)/100\relax)}% + %\typeout{scale:\the\opt@tempa,\the\opt@tempb, by \opt@perc percent to make \the\dimexpr#4\relax}% + \edef\opt@temp{\dimexpr\opt@perc\dimexpr\the\opt@tempa\relax / 100\relax}% + \option@einvoke{#1}{\opt@temp}% + \option@einvoke{#2}{\dimexpr#4 - \opt@temp\relax}% + %\typeout{ scaled to: \the\opt@temp,\the\dimexpr#4 - \opt@temp\relax}% + \fi + \fi +} + + +% \begin{macro}{\trig@atantan} +% \marg{a}\marg{b}\marg{$\alpha$}{dimen$_\mathit{reg}$}\\ +% Assigns $\atan_2(\frac{\sin(\alpha)}{b},\frac{\cos(\alpha)}{a})$ to dimension register \textit{dimen$_\mathit{reg}$}, +% where $a$ and $b$ are dimensions. +% Returns $\alpha$ when $a = b$, or when $a=0$ or $b=0$. +% \begin{macrocode} +\newcommand*\trig@atantan[4]{% + %\typeout{ atantan:(\the#1,\the#2,\the#3, #4)}% + \@tempdima\dimexpr#1\relax + \@tempdimb\dimexpr#2\relax +% \end{macrocode} +% If $a = b$, we have a circle and the result is $\alpha$. +% \begin{macrocode} + \ifdim\@tempdima=\@tempdimb + #4\dimexpr#3\relax + \else\ifdim\@tempdima=\z@ + #4\dimexpr#3\relax + \else\ifdim\@tempdimb=\z@ + #4\dimexpr#3\relax + \else + \edef\trig@temp{\strip@pt\dimexpr#3\relax}% + \CalculateSin{\trig@temp}\CalculateCos{\trig@temp}% + \@tempdimc\dimexpr1\p@ * \dimexpr\UseSin{\trig@temp}\p@\relax/\@tempdimb\relax + \@tempdimd\dimexpr1\p@ * \dimexpr\UseCos{\trig@temp}\p@\relax/\@tempdima\relax + \pIIe@atantwo{\@tempdimc}{\@tempdimd}\dimen@ + \ifdim\dimen@<\z@ + \ifdim\dimexpr#3\relax<\z@\else\advance\dimen@360\p@\fi + \fi + \@tempdima\dimexpr#3 - \dimen@\relax + \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi + \ifdim\@tempdima<360\p@\else\advance\dimen@360\p@\fi + %\typeout{atan: \the\dimexpr#3\relax versus. \the\dimen@ }% + #4\dimen@ + \fi\fi\fi +} +% \end{macrocode} +% \end{macro} + +% rough approximation of the perimeter; +% if |radius-x == radius-y| = 0 (a circle), the approximation is precise. +% otherwise, works best when |angle2-angle1| <= 45 and gets worse from there on. +\newcommand*\ellip@letarcperimeter[5]{% 'radius-x', 'radius-y', 'angle-1', 'angle-2', '\result' + \@tempdima\dimexpr#3\relax + \@tempdimb\dimexpr#4\relax + \@tempdimc\dimexpr\@tempdima - \@tempdimb\relax + \ifdim\@tempdimc<\z@\@tempdimc-\@tempdimc\fi + \ifdim#1=#2\relax% circle? + \edef\@tempa{\strip@pt\@tempdimc}% angle difference delta as factor + \dimen@\@tempa\dimexpr#1\relax% r*delta + \dimen@0.017453\dimen@% (2*pi/360) * r * delta = 2*pi*r * (delta/360) + \else% ellipse: take the distance between the points on the ellipse, works pretty good if delta <= 45, and ok'ish for delta <= 90 + \@ovro\dimexpr#1\relax + \@ovri\dimexpr#2\relax + \edef\fbox@tempa{\strip@pt\@tempdima}% + \edef\fbox@tempb{\strip@pt\@tempdimb}% + \pIIe@ellip@sincost{\fbox@tempa}{\fbox@tempb}% + \@tempdima\@ellipcosone\@ovro + \@tempdimb\@ellipsinone\@ovri + \@tempdimc\@ellipcostwo\@ovro + \@tempdimd\@ellipsintwo\@ovri + \advance\@tempdimc by -\@tempdima% + \advance\@tempdimd by -\@tempdimb% + \pIIe@ellip@csqrt{\@tempdimc}{\@tempdimd}{\dimen@}% + %\typeout{ distance: \the\dimen@, from (x,y)=(\the\@tempdimc,\the\@tempdimd), radii=(\the#1,\the#2), angles=(\the#3,\the#4)}% + \fi + \edef#5{\the\dimen@}% +} + + +% ------------------------------------------------------------------------------ +% Borders using the picture environment +% ------------------------------------------------------------------------------ + +\newcommand*\fbox@border@pict{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \begingroup + \hbox{% + \unitlength\p@ + \begin{picture}(0,0)(0,\optionunit{/fbox/@border-box-height})% bottom-left is origin + % markers + \ontoggle{/fbox/show-markers}{% + \linethickness{\option{/fbox/marker-width}}% + \optioncolor{/fbox/marker-color}% + \fbox@rect{0pt}{0pt}{\option{/fbox/@border-box-width}}{\option{/fbox/@border-box-height}}% + \fbox@rect{\option{/fbox/border-left-width}}{\option{/fbox/border-\fbox@bottom-width}}% + {\option{/fbox/@border-box-width}-\option{/fbox/border-right-width}}% + {\option{/fbox/@border-box-height}-\option{/fbox/border-\fbox@top-width}}%S + }% + %compute corner coordinates + \fbox@border@calccorners + %put down the background color + \fbox@border@colorbackground + \option{/fbox/picture-insert-before}% + %put down the sides + \fbox@border@side{3}{-2}{0}%top + \fbox@border@side{5}{-4}{3}%left + \fbox@border@side{-6}{7}{2}%bottom + \fbox@border@side{-8}{1}{1}%right + \end{picture}% + }% + \endgroup + \fi +} + +\newcommand*\fbox@border@pict@after{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \letoption{/fbox/picture-insert-after}\fbox@insertafter + \eifblank{\fbox@insertafter}{}{% + \begingroup + \hbox{% + \begin{picture}(0,0)(0,0)% bottom-left is origin + \fbox@insertafter + \end{picture}% + }% + \endgroup + }% + \fi +} + +\newcommand*\fbox@border@side[3]{% + \fbox@setoct@angles{#1}% + \edef\fbox@style{\option{/fbox/border-\fbox@side-style}}% + \optioncolor{/fbox/border-\fbox@side-color}% + \option{/fbox/picture-side-insert-before}% + \ifcsdef{fbox@border@pict@\fbox@style}% + {\csuse{fbox@border@pict@\fbox@style}{#1}{#2}{#3}}% + {\PackageWarning{longfbox}{Unknown style "\fbox@style". Using "solid" instead.}% + \fbox@border@pict@solid{#1}{#2}{#3}}% + \option{/fbox/picture-side-insert-after}% +} + +% ------------------------------------------------------------------------------ +% Define standard border styles for the picture environment +% +% a style has the form \fbox@border@pict@ + + + + + + +
+
+
+
P4Runtime Specification
+
version 1.3.0
+
+
+
The P4.org API Working Group
+
2022-03-23
+
+

Abstract. P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.

+ + +

1. Introduction and Scope

+

This document is published by the P4.org API Working Group, which was +chartered [17] to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called P4Runtime. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +https://github.com/p4lang/p4runtime/tree/v1.3.0/proto. +

1.1. P4 Language Version Applicability

+

P4Runtime is designed to be implemented in conjunction with the P416 language +version or later. P414 programs should be translated into P416 to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P416 1.0, but were introduced in P416 1.1.0 [29]. For +this version of P4Runtime, we recommend using P416 1.2.1 [1]. +

1.2. In Scope

+

This specification document defines the semantics of P4Runtime messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime: +

+
    +
  • Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA) [19] externs (e.g. Counters, Meters, Action +Profiles, ). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0. +
  • +
  • Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism. +
  • +
  • Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy. +
  • +
  • Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities. +
  • +
  • Packet I/O to enable streaming packets to & from the control plane. +
  • +
  • Batching support, with different atomicity guarantees. +
  • +
  • In-the-field device-reconfiguration with a new P4 data plane. +
+ +

The following are in the scope of this specification document: +

+
    +
  • Rationale for the P4Runtime design. +
  • +
  • Reference architecture and use-cases for deploying a P4Runtime service. +
  • +
  • Detailed description of the API semantics. +
  • +
  • Requirements for conformant implementations of the API. +
+

1.3. Not In Scope

+

The following are not in scope of P4Runtime: +

+
    +
  • Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +[35]. An open source implementation of these APIs is also in progress +as part of the Stratum project [37]. +
  • +
  • Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures. +
+ +

The following are not in scope of this specification document: +

+
    +
  • Description of the P4 programming language; it is assumed that the reader is +already familiar with P416 [1]. +
  • +
  • Descriptions of gRPC and Protobuf files in general. +
  • +
  • Controller role definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme. +
+

2. Terms and Definitions

+
+
arbitration
+
Refers to the process through which P4Runtime ensures that at any given +time, there is a single primary controller (i.e. a client with write access) +for a given role. Also referred to as “client arbitration”. +
+
client
+
The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +
+
COS
+
Class of Service. +
+
device
+
Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +
+
entity
+
An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +
+
gRPC
+
gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +[9]. +
+
HA
+
High-Availability. Refers to a redundancy architecture. +
+
Instrumentation
+
The part of the P4Runtime server which implements the calls to the device or +target native “SDK” or backend. +
+
IPC
+
Inter-Process Communication. +
+
P4 Blob
+
A more colloquial term for P4 Device Config (Blob = Binary Large Object). +
+
P4 Device Config
+
The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its “program.” +
+
P4Info
+
Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +
+
P4RT
+
Abbreviation for P4Runtime. +
+
Protobuf (Protocol Buffers)
+
The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See [21]. +
+
PSA
+
Portable Switch Architecture [19]; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +
+
RPC
+
Remote Procedure Call. +
+
RTT
+
Round-trip time. +
+
SDN
+
Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network controller. +
+
SDN port
+
A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +
+
server
+
The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +
+
stream
+
Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (StreamChannel), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and client arbitration, among other things. +
+
switch config
+
Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +
+
target
+
The hardware or software entity which “executes” the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with “device”. +
+
URI
+
Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.

3. Reference Architecture

+

Figure 1 represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. P4Runtime only grants write access to a +single primary controller for each read/write entity. A role defines a grouping +of P4 entities. P4Runtime allows for a primary controller for each role, and a +role-based client arbitration scheme ensures only one controller has +write access to each read/write entity, or the pipeline config itself. Any +controller may perform read access to any entity or the pipeline config. Later +sections describe this in detail. For the sake of brevity, the term controller +may refer to one or more controllers. +

+

The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +[15]. It may be compiled via protoc the Protobuf compiler +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server. +

+

Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository [16]. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, e.g. via callbacks, thus reducing the burden of implementing +P4Runtime. +

+

The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard. +

+

The controller can also set the ForwardingPipelineConfig, which amounts to +installing and running the compiled P4 program output, which is included in the +p4_device_config Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +ForwardingPipelineConfig to retrieve the device config and the P4Info. +

+
+

reference-architecture +

+
+ +
Figure 1. P4Runtime Reference Architecture.

3.1. P4Runtime Service Implementation

+

The P4Runtime API is implemented by a program that runs a gRPC server which +binds an implementation of auto-generated P4Runtime Service interface. This +program is called the “P4Runtime server.” The server must listen on TCP port +9559 by default, which is the port that has been allocated by IANA for the +P4Runtime service. Servers should allow users to override the default port +using a configuration file or flag when starting the server. Uses of other +port numbers as the default should be discontinued. +

3.1.1. Security concerns

+

Appropriate measures and security best practices must be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. Mutual TLS (mTLS) may +be used to facilitate the authentication of the client by the server and +vice-versa. +

3.2. Idealized Workflow

+

In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the ForwardingPipelineConfig +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a SetForwardingPipelineConfig +RPC. Metadata in the P4Info describes both the overall program itself +(PkgInfo) as well as all entity instances derived from the P4 program +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise “handle” used in API +calls. +

+

In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible. +

+

In some use cases, it is expected that a controller will store a +collection of multiple P4 “packages”, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the ForwardingPipelineConfig from the target via the +GetForwardingPipelineRequest RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state. +

3.3. P4 as a Behavioral Description Language

+

P4 can be considered a behavioral description of a switching device which may or +may not execute “P4” natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a SetForwardingPipelineRequest to +change its pipeline “program”, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device. +

+

While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API. +

+

In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the PkgInfo +message as well as the embedded doc fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections. +

3.4. Alternative Workflows

+

Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary. +

3.4.1. P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config

+

In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +p4_device_config. The device's configuration might be derived via some other +means to implement the P4 source code's intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane. +

3.4.2. No P4 Source Available, P4Info Available

+

In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are: +

+
    +
  1. +

    The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security. +

  2. +
  3. +

    The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info. +

+ +

As discussed in Section 3.3, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, e.g. documentation. +

3.4.3. Partial P4Info and P4 Source are Available

+

In this situation, a subset of the target's pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code. +

3.4.4. P4Info Role-Based Subsets

+

In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more. +

3.5. P4Runtime State Across Restarts

+

All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade. +

4. Controller Use-cases

+

P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +section. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime's flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex. +

4.1. Single Embedded Controller

+

Figure 2 shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases. +

+

P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC. +

+
+

single-embedded-controller +

+
+ +
Figure 2. Use-Case: Single Embedded Controller

4.2. Single Remote Controller

+

Figure 3 shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections. +

+
+

single-remote-controller +

+
+ +
Figure 3. Use-Case: Single Remote Controller

4.3. Embedded + Single Remote Controller

+

Figure 4 illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller. +

+

For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables. +

+
+

embedded-plus-single-remote-controller +

+
+ +
Figure 4. Use-Case: Embedded Plus Single Remote Controller

4.4. Embedded + Two Remote Controllers

+

Figure 5 illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +e.g. routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership. +

+
+

embedded-plus-two-remote-controllers +

+
+ +
Figure 5. Use-Case: Embedded Plus Two Remote Controllers

4.5. Embedded Controller + Two High-Availability Remote Controllers

+

Figure 6 illustrates a single +embedded controller plus two remote controllers in an active-standby (i.e. +primary-backup) HA (High-Availability) configuration. Controller #1 is the +active controller and is in charge of some entities. If it fails, Controller #2 +takes over and manages the tables formerly owned by Controller #1. The mechanics +of HA architectures are beyond the scope of this document, but the P4Runtime +role-based client arbitration scheme supports it. +

+
+

embedded-plus-two-remote-ha-controllers +

+
+ +
Figure 6. Use-Case: Embedded Plus Two Remote High-Availability Controllers

5. Client Arbitration and Controller Replication

+

The P4Runtime interface allows multiple clients (i.e. controllers) to be +connected to the P4Runtime server running on the device at the same time for the +following reasons: +

+
    +
  1. +

    Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, “roles” (or “realms”) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +primary and the rest are backups. Role definition, i.e. how P4 entities get +assigned to each role, is out-of-scope of this document. +

  2. +
  3. +

    Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby backup controllers. These can already have a connection +open, which can help them become primary more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved. +

+ +

To support multiple controllers, P4Runtime uses the streaming channel (available +via StreamChannel RPC) for session management. The workflow is described as +follows: +

+
    +
  • +

    Each controller instance (e.g. a controller process) can participate in one or +more roles. For each (device_id, role), the controller receives an +election_id. This election_id can be the same for different roles and/or +devices, as long as the tuple (device_id, role, election_id) is +unique. For each (device_id, role) that the controller wishes to +control, it establishes a StreamChannel with the P4Runtime server +responsible for that device, and sends a MasterArbitrationUpdate message +containing that tuple of (device_id, role, election_id) values. The +P4Runtime server selects a primary independently for each (device_id, +role) pair. The primary is the client that has the highest election_id +that the device has ever received for the same (device_id, +role) values. A connection between a controller instance and a device id + which involves a persistent StreamChannel can be referred to as a +P4Runtime client. +

    +

    Note that the P4Runtime server does not assign a role or election_id to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the election_id values used for each +StreamChannel. The P4Runtime server only keeps track of the (device_id, +role, election_id) of each StreamChannel that has sent a successful +MasterArbitrationUpdate message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +WriteRequest message to identify which client is making the WriteRequest, +not only the election_id. This enables controllers to re-use the same +numeric election_id values across different (device_id, role) +pairs. P4Runtime does not require election_id values be reused across such +different (device_id, role) pairs; it allows it. +

  • +
  • +

    To start a controller session, a controller first opens a bidirectional stream +channel to the server via the StreamChannel RPC for each device. This stream +will be used for two purposes: +

    +
      +
    • +

      Session management: As soon as the controller opens the stream +channel, it sends a StreamMessageRequest message to the switch. The +controller populates the MasterArbitrationUpdate field in this message +using its role and election_id, as well as the device_id of the +device. Note that the status field in the MasterArbitrationUpdate is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below. +

    • +
    • +

      Streaming of notifications (e.g. digests) and packet I/O: The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the primary controller can participate in +packet I/O. This feature is explained in more details in the Packet +I/O section. +

    + +

    Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state. +

  • +
  • +

    Note that the stream is opened per device. In case a switching platform has +multiple devices (e.g. multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different primary clients for +different devices. In this case, it is the responsibility of the P4Runtime +server to keep track of the primary for each device (and role). More +specifically, the P4Runtime server will know which stream corresponds to the +primary controller for each pair of (device_id, role) at any point of +time. +

  • +
  • +

    The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered “offline” or +“dead” as soon as its stream channel to the switch is broken. When a primary +channel gets broken: (i) an advisory message is sent to all other controllers +for that device_id and role, as described in the +following section (ii) the P4Runtime server +will be without a primary controller, until a client sends a successful +MasterArbitrationUpdate (as per the rules in a +later section). +

  • +
  • +

    The mechanism via which the controller receives the P4Runtime server details +which includes the device_id, ip and port, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +device_id) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks. +

+ +

gRPC enables the server to identify which client originated each message in the +StreamChannel stream. For example, the C++ gRPC library [10] in +synchronous mode enables a server process to cause a function to be called when +a new client creates a StreamChannel stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +StreamChannel is closed normally (or broken, e.g. because a client process +unexpectedly terminated). Thus the server can easily associate all +StreamChannel messages received from the same client, because they are +processed within the context of the same function call. +

+

A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values device_id, role, and election_id in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods [8] that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server. +

5.1. Default Role

+

A controller can omit the role message in MasterArbitrationUpdate. This +implies the “default role”, which corresponds to “full pipeline access”. +This also implies that a default role has a role_id of "" (default). +If using a default role, all RPCs from the controller (e.g. Write) must +leave the role unset. +

5.2. Role Config

+

The role.config field in the MasterArbitrationUpdate message sent by the +controller describes the role configuration, i.e. which operations are in the +scope of a given role. In particular, the definition of a role may include the +following: +

+
    +
  • A list of P4 entities for which the controller may issue Write updates and +receive notification messages (e.g. DigestList and +IdleTimeoutNotification). +
  • +
  • Whether the controller is able to receive PacketIn messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketIn messages should be sent to the controller. +
  • +
  • Whether the controller is able to send PacketOut messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketOut messages are allowed to be sent by the controller. +
+ +

An unset role.config implies “full pipeline access” (similar to the default +role explained above). In order to support different role definition schemes, +role.config is defined as an Any Protobuf message [31]. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion. +

+

It is the job of the P4Runtime server to remember the role.config for every +device_id and role pair. +

5.3. Rules for Handling MasterArbitrationUpdate Messages Received from Controllers

+
    +
  1. +

    If the MasterArbitrationUpdate message is received for the first time on +this particular channel (i.e. for a newly connected controller): +

    +
      +
    1. +

      If device_id does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +NOT_FOUND error. +

    2. +
    3. +

      If the election_id is set and is already used by another controller for +the same (device_id, role), the P4Runtime server shall terminate +the stream by returning an INVALID_ARGUMENT error. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the number of open streams for the given (device_id, role) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a RESOURCE_EXHAUSTED error. +

    8. +
    9. +

      Otherwise, the controller is added to a list of connected controllers for +the given (device_id, role) and the server remembers the +controllers device_id, role and election_id for this gRPC +channel. See below for the rules to determine if this controller becomes +a primary or backup, and what notifications are sent as a consequence. +

    +
  2. +
  3. +

    Otherwise, if the MasterArbitrationUpdate message is received from an +already connected controller: +

    +
      +
    1. +

      If the device_id does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. +

    2. +
    3. +

      If the role does not match the current role assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. If the controller wishes to change its role, +it must close the current stream channel and open a new one. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the election_id is set and is already used by another controller +(excluding the controller making the request) for the same +(device_id, role), the P4Runtime server shall terminate the stream +by returning an INVALID_ARGUMENT error. +

    8. +
    9. +

      Otherwise, the server updates the election_id it has stored for this +controller. This change might cause a change in the primary client (this +controller might become primary, or the controller might have downgraded +itself to a backup, see below), as well as notifications being sent to +one or more controllers. +

    +
+ +

If the MasterArbitrationUpdate is accepted by either of the two steps above +(cases 1.5. and 2.5. above), then the server determines if there are changes in +the primary client. Let election_id_past be the highest election ID the server +has ever seen for the given device_id and role (including the one of the +current primary if there is one). +

+
    +
  1. +

    If election_id is greater than or equal to election_id_past, then the +controller becomes, or stays, primary. The server updates the role +configuration to role.config for the given role. Furthermore: +

    +
      +
    1. +

      If there was no primary for this device_id and role before and +there are no Write requests still processing from a previous primary, +then the server immediately sends an advisory notification to all +controllers for this device_id and role. See the +following section for the format of the +advisory message. +

    2. +
    3. +

      If there was a previous primary, including this controller, or Write +requests in flight, then the server carries out the following steps +(in this order): +

      +
        +
      1. +

        The server stops accepting Write requests from the previous primary +(if there is one). At this point, the server will reject all Write +requests with PERMISSION_DENIED. +

      2. +
      3. +

        The server notifies all controllers other than the new primary client +of the change by sending the advisory notification described in +the following section. +

      4. +
      5. +

        The server will finish processing any Write requests that have +already started. If there are errors, they are reported as usual to +the previous primary. If the previous primary has already +disconnected, any possible errors are dropped and not reported. +

      6. +
      7. +

        The server now accepts the current controller as the new primary, +thus accepting Write requests from this controller. The server +updates the highest election ID (i.e. election_id_past) it has seen +for this device_id and role to election_id. +

      8. +
      9. +

        The server notifies the new primary by sending the advisory message +described in the following section. +

      +
    +
  2. +
  3. +

    Otherwise, the controller becomes a backup. If the controller was previously +a primary (and downgraded itself), then an advisory message is sent to all +controllers for this device_id and role. Otherwise, the advisory +message is only sent to the controller that sent the initial +MasterArbitrationUpdate. See the +following section for the format of the +advisory message. +

+

5.4. Client Arbitration Notifications

+

For any given device_id and role, any time a new primary is chosen, a +primary downgrades its status to a backup, a primary disconnects, or the +role.config is updated by the primary, all controllers for that +(device_id, role) are informed of this by sending a +StreamMessageResponse. The MasterArbitrationUpdate is populated as follows: +

+
    +
  • +

    device_id and role as given. +

  • +
  • +

    role.config is set to the role configuration the server received most +recently in a MasterArbitrationUpdate from a primary. +

  • +
  • +

    election_id is populated as follows: +

    +
      +
    • +

      If there has not been any primary at all, the election_id is left unset. +

    • +
    • +

      Otherwise, election_id is set to the highest election ID that the server +has seen for this device_id and role (which is the election_id of +the current primary if there is any). +

    +
  • +
  • +

    status is set differently based on whether the notification is sent to the +primary or a backup controller: +

    +
      +
    • +

      If there is a primary: +

      +
        +
      • +

        For the primary, status is OK (with status.code set to +google.rpc.OK). +

      • +
      • +

        For all backup controllers, status is set to non-OK (with +status.code set to google.rpc.ALREADY_EXISTS). +

      +
    • +
    • +

      Otherwise, if there is no primary currently, for all backup controllers, +status is set to non-OK (with status.code set to +google.rpc.NOT_FOUND). +

    +
+ +

Note that on primary client changes with outstanding Write request, some +notifications might be delayed, see the +previous section for details. +

6. The P4Info Message

+

The purpose of P4Info was described under +Reference Architecture. +Here we describe the various +components. +

6.1. Common Messages

+

These messages appear nested within many other messages. +

6.1.1. Documentation Message

+

Documentation is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers. +

+
+
+
message Documentation {
+  // A brief description of something, e.g. one sentence
+  string brief = 1;
+  // A more verbose description of something.
+  // Multiline is accepted. Markup format (if any) is TBD.
+  string description = 2;
+}

6.1.2. Preamble Message

+

The preamble serves as the “descriptor” for each entity and contains the unique +instance ID, name, alias, annotations and documentation. +

+
+
+
message Preamble {
+  // ids share the same number-space; e.g. table ids cannot overlap with counter
+  // ids. Even though this is irrelevant to this proto definition, the ids are
+  // allocated in such a way that it is possible based on an id to deduce the
+  // resource type (e.g. table, action, counter, ...). This means that code
+  // using these ids can detect if the wrong resource type is used
+  // somewhere. This also means that ids of different types can be mixed
+  // (e.g. direct resource list for a table) without ambiguity. Note that id 0
+  // is reserved and means "invalid id".
+  uint32 id = 1;
+  // fully qualified name of the P4 object, e.g. c1.c2.ipv4_lpm
+  string name = 2;
+  // an alias (alternative name) for the P4 object, probably shorter than its
+  // fully qualified name. The only constraint is for it to be unique with
+  // respect to other P4 objects of the same type. By default, the compiler uses
+  // the shortest suffix of the name that uniquely identifies the object. For
+  // example if the P4 program contains two tables with names s.c1.t and s.c2.t,
+  // the default aliases will respectively be c1.t and c2.t. In the future, the
+  // P4 programmer may also be able to override the default alias for any P4
+  // object (TBD).
+  string alias = 3;
+  repeated string annotations = 4;
+  // Optional. If present, the location of `annotations[i]` is given by
+ // `annotation_locations[i]`.
+  repeated SourceLocation annotation_locations = 7;
+  // Documentation of the entity
+  Documentation doc = 5;
+  repeated StructuredAnnotation structured_annotations = 6;
+}

6.1.3. Annotating P4 Entities with Documentation

+

P4 entities may be annotated using the following annotations: +

+
+
+
@brief(string...)
+@description(string...)
+

Attaching either or both of these annotations to an entity will generate a +P4Info Documentation Message, which in turn will +appear in the Preamble Message for the entity. +

+

The P4 compiler should not emit annotation messages in the P4Info for these +specific cases; instead, it should generate the Documentation messages as +described. +

+

The following example shows documentation annotations for a table entity: +

+
+
+
@brief("Match IPv4 addresses to next-hop MAC and port")
+@description("Match IPv4 addresses to next-hop MAC and port. \
+Uses LPM match type.")
+table my_ipv4_lkup {
+  ...
+}

6.1.4. Structured Annotations

+

P4 supports both unstructured and structured annotations [13]. +Unstructured annotations of the form MyAnno1 or MyAnno2(body-content) can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +MyAnno3[] or MyAnno4[kvList|expressionList] have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this. +

+

The annotations described up to this point, e.g. @brief(), have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as repeated string annotations fields in the various messages. +Similarly, structured annotations are represented in repeated +StructuredAnnotation structured_annotations fields which are siblings to the +unstructured annotations. The structured_annotations contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations. +

+

The structured annotation messages are defined in p4types.proto. +

+
+
+
message KeyValuePair {
+  string key = 1;
+  Expression value = 2;
+}
+
+message KeyValuePairList {
+  repeated KeyValuePair kv_pairs = 1;
+}
+
+message Expression {
+  oneof value {
+    string string_value = 1;
+    int64 int64_value = 2;
+    bool bool_value = 3;
+  }
+}
+
+message ExpressionList {
+  repeated Expression expressions = 1;
+}
+
+message StructuredAnnotation {
+  string name = 1;
+  oneof body {
+    ExpressionList expression_list = 2;
+    KeyValuePairList kv_pair_list = 3;
+  }
+  // Optional. Location of the '@' symbol of this annotation in the source code.
+  SourceLocation source_location = 4;
+}
+

The StructuredAnnotation message can represent either a KeyValuePairList +or an ExpressionList. +

+

The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The p4c +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don't match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler may print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions. +

+

The following invariants hold: +

+
    +
  1. +

    For any P4 entity, there are no two StructuredAnnotations that have the +same name. +

  2. +
  3. +

    Within a KeyValuePairList, there are no two KeyValuePairs that have the +same key. +

+
6.1.4.1. Structured Annotation Examples
+

We omit the source_location field in the following examples. +

+

Empty Expression List +

+
+
+
@Empty[]
+table t {
+    ...
+}
+

The generated P4Info will contain the following. +

+
+
+
structured_annotations {
+  name: "Empty"
+}
+

Mixed Expression List +

+
+
+
#define TEXT_CONST "hello"
+#define NUM_CONST 6
+@MixedExprList[1,TEXT_CONST,true,1==2,5+NUM_CONST]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedExprList"
+  expression_list {
+    expressions {
+      int64_value: 1
+    }
+    expressions {
+      string_value: "hello"
+    }
+    expressions {
+      bool_value: true
+    }
+    expressions {
+      bool_value: false
+    }
+    expressions {
+      int64_value: 11
+    }
+  }
+}
+

kvList of Mixed Expressions +

+
+
+
@MixedKV[label="text", my_bool=true, int_val=2*3]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedKV"
+  kv_pair_list {
+    kv_pairs {
+      key: "label"
+      value {
+        string_value: "text"
+      }
+    }
+    kv_pairs {
+      key: "my_bool"
+      value {
+        bool_value: true
+      }
+    }
+    kv_pairs {
+      key: "int_val"
+      value {
+        int64_value: 6
+      }
+    }
+  }
+}

6.1.5. SourceLocation Message

+

A source location describes a location within a .p4-source file. The +SourceLocation message is defined in p4types.proto as follows: +

+
+
+
// Location of code relative to a given source file.
+message SourceLocation {
+  // Path to the source file (absolute or relative to the working directory).
+  string file = 1;
+  // Line and column numbers within the source file, 1-based.
+  int32 line = 2;
+  int32 column = 3;
+}
+

We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations. +

+

The SourceLocation message associated with an annotation holds the location of +the @ symbol introducing the annotation in the P4 source code; the message can +be found in the following place: +

+
    +
  • +

    For unstructured annotations, every message containing a field +repeated string annotations also contains a field +repeated SourceLocation annotation_locations. The field must either be empty + or match the size of annotations. In the latter case, the i-th member of +annotation_locations is the source location of the i-th member of +annotations. +

  • +
  • +

    For structured annotations, every StructuredAnnotation message contains +an optional field SourceLocation source_location holding its source +location, if present. +

+

6.2. PkgInfo Message

+

The PkgInfo message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. PkgInfo can be extracted +and used to facilitate “browsing” of available P4 programs from a +library. Although all fields are technically “optional,” every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included. +

+
+
+
// Can be used to manage multiple P4 packages.
+message PkgInfo {
+  // a definitive name for this configuration, e.g. switch.p4_v1.0
+  string name = 1;
+  // configuration version, free-format string
+  string version = 2;
+  // brief and detailed descriptions
+  Documentation doc = 3;
+  // Miscellaneous metadata, free-form; a way to extend PkgInfo
+  repeated string annotations = 4;
+  // the target architecture, e.g. "psa"
+  string arch = 5;
+  // organization which produced the configuration, e.g. "p4.org"
+  string organization = 6;
+  // contact info for support,e.g. "tech-support@acme.org"
+  string contact = 7;
+  // url for more information, e.g. "http://support.p4.org/ref/p4/switch.p4_v1.0"
+  string url = 8;
+  // Miscellaneous metadata, structured; a way to extend PkgInfo
+  repeated StructuredAnnotation structured_annotations = 9;
+}

6.2.1. Annotating P4 code with PkgInfo

+

A P4 progam's PkgInfo may be declared using one or more of the following +annotations, attached to the main block only: +

+
+
+
@pkginfo(key=value)
+@pkginfo(key=value[,key=value,...])
+@brief("A brief description")
+@description("A longer\
+description")
+@custom_annotation(...)
+@another_custom_annotation(...)
+

Above we see several different types of annotations: +

+
    +
  • +

    @pkginfo - This is used to populate a specific field within the PkgInfo +message. Multiple @pkginfo annotations are allowed. For compactness, +multiple key-value pairs can appear in a single @pkginfo annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The keys must be from +among the message fields inside PkgInfo, for example, name, version, +etc. Each key-value pair assigns a value to the corresponding field inside the +single PkgInfo message for the program's P4Info. One exception is that the +Documentation field of PkgInfo must be expressed as individual +@description and @brief annotations, see next bullets. The key arch will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself. +

  • +
  • +

    @brief - This will populate the PkgInfo.doc.brief message field. +

  • +
  • +

    @description - This will populate the PkgInfo.doc.description message +field +

  • +
  • +

    @<anything else> - This will create a PkgInfo.annotation entry +

+ +

Declaring one or more of these annotations on main will +generate a single corresponding PkgInfo message in the P4Info as described in +PkgInfo Message. +

+

The following example shows @pkginfo annotations using a mixture of single and +multiple key-value pairs. It also shows @brief and @description annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the PkgInfo message. The custom annotations will +be appended to the PkgInfo.annotations list. +

+
+
+
@pkginfo(name="switch.p4",version="2")
+@pkginfo(organization="p4.org")
+@pkginfo(contact="info@p4.org")
+@pkginfo(url="www.p4.org")
+@brief("L2/L3 switch")
+@description("L2/L3 switch.\
+Built for data-center profile.")
+@my_annotation1(...) // Not well-known, this will appear in PkgInfo annotations
+@my_annotation2(...) // Not well-known, this will appear in PkgInfo annotations
+PSA_Switch(IgPipeline, PacketReplicationEngine(), EgPipeline,
+           BufferingQueueingEngine()) main;

6.3. ID Allocation for P4Info Objects

+

P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(e.g. table, action, counter, ). The most significant 8 bits of the ID +encodes the object type (as per Table 1). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (p4.config.v1.P4Ids.Prefix). These values must +be used (e.g. by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table 2 shows the ID +layout. +

+
+ + + + + + + + + + + + + + + + + + + + + +
8-bit prefix value P4 object type
0x00 Reserved (unspecified)
0x01 Action
0x02 Table
0x03 Value-set
0x04 Controller header (header type with @controller_header annotation)
0x050x0f Reserved (for future P4 built-in objects)
0x10 Reserved (start of PSA extern types)
0x11 PSA Action profiles / selectors
0x12 PSA Counter
0x13 PSA Direct counter
0x14 PSA Meter
0x15 PSA Direct meter
0x16 PSA Register
0x17 PSA Digest
0x180x7f Reserved (for future PSA extern types)
0x80 Reserved (start of vendor-specific extern types)
0x810xfe Vendor-specific extern types
0xff Reserved (max prefix value)
+
+ +
Table 1. Mapping of P4Info object type to 8-bit ID prefix value
+
+ + + + +
MSB bit 31 .. bit 24 bit 23 .. bit 0 LSB
Object type prefix Generated suffix (e.g. by the compiler)
+
+ +
Table 2. Format of P4Info object IDs
+

It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with @id (see Table +3). The compiler must honor the @id annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (i.e. if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same @id value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct. +

+
+ + + + + + + + + + +
P4 declaration(s) Compiler-allocated ID(s)
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) table tA... Error(same ID suffixes for 2 objects of the same type)
@id(0x12ab34) table tB...
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) action act1... 0x0112ab34
+
+ +
Table 3. Example of statically-assigned P4Info object IDs
+

The @id annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively). +

6.4. P4Info Objects

6.4.1. Table

+

Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this table. +

  • +
  • +

    match_fields, a repeated field of type MatchField representing the data to +be used to construct the lookup key matched in this table. Each MatchField +message is defined with the following fields: +

    +
      +
    • +

      id, the uint32 identifier of this MatchField, unique in the scope of +this table. No rules are prescribed on the way MatchField IDs should be +allocated, as long as two MatchField of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the @id annotation, or let the compiler +choose them. +

    • +
    • +

      name, the string representing the name of this MatchField. +

    • +
    • +

      annotations, a repeated field of strings, each one representing a P4 +annotation associated to this match field. +

    • +
    • +

      bitwidth, an int32 value set to the size in bits of this match field. +

    • +
    • +

      match, a oneof describing the match behavior for this field; it can be +either: +

      +
        +
      • match_type, an enum field of type MatchType, which includes all +possible PSA match kinds. +
      • +
      • other_match_type, a string field which can be used to encode any +architecture-specific match type. +
      +
    • +
    • +

      doc, a Documentation message describing this match field. +

    • +
    • +

      type_name, which indicates whether the match field has a user-defined +type; this is useful for +translation. +

    +
  • +
  • +

    action_refs, a repeated ActionRef field representing the set of possible +actions for this table. The ActionRef message is used to reference an action +specified in the same P4Info message and it includes the following fields: +

    +
      +
    • id, the uint32 identifier of the action. +
    • +
    • scope, an enum value which can take one of three values: + TABLE_AND_DEFAULT, TABLE_ONLY and DEFAULT_ONLY. The scope of the + action is determined by the use of the P4 standard annotations + @tableonly and @defaultonly [18]. TABLE_ONLY + (@tableonly annotation) means that the action can only appear within + the table, and never as the default action. DEFAULT_ONLY + (@defaultonly annotation) means that the action can only be used as the + default action. TABLE_AND_DEFAULT is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action. +
    • +
    • annotations, a repeated string field, each one representing a P4 +annotation associated to the action reference in this table. +
    +
  • +
  • +

    const_default_action_id, if this table has a constant default action, this +field will carry the uint32 identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action's +arguments. +

  • +
  • +

    implementation_id, the uint32 identifier of the “implementation” of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (e.g. a PSA ActionProfile or ActionSelector +instance). The table is then referred to as an indirect match table. +

  • +
  • +

    direct_resource_ids, repeated uint32 identifiers for all the direct +resources attached to this table, such as DirectMeter and DirectCounter +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2. +

  • +
  • +

    size, an int64 describing the desired number of table entries that the +target should support for the table. See the “Size” subsection within the +“Table Properties” section of the P416 language specification for details +[30]. +

  • +
  • +

    idle_timeout_behavior, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +Idle-Timeout section). Value can be any of the +IdleTimeoutBehavior enum: +

    +
      +
    • NO_TIMEOUT (default value), which means that idle timeout is not +supported for this table. +
    • +
    • NOTIFY_CONTROL, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +Table Idle Timeout Notifications). +
    +
  • +
  • +

    is_const_table, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime. +

  • +
  • +

    other_properties, an Any Protobuf message [31] to embed +architecture-specific table properties [30] which are not part +of the core P4 language or of the PSA architecture. +

+

6.4.2. Action

+

Action messages are used to specify all possible actions of all match-action +tables. +

+

The Action message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this action +

  • +
  • +

    params, a repeated field of Param messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each Param message contains the +following fields: +

    +
      +
    • id, the uint32 identifier of this parameter. No rules are prescribed +on the way Param IDs should be allocated, as long as two Param of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the @id +annotation, or let the compiler choose them. +
    • +
    • name, the string representing the name of this parameter. +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this parameter. +
    • +
    • bitwidth, an int32 value set to the size in bits of this parameter. +
    • +
    • doc, which describes this parameter using a Documentation message. +
    • +
    • type_name, which indicates whether the action parameter has a +user-defined type; this is useful for +translation. +
    +
+

6.4.3. ActionProfile

+

ActionProfile messages are used to specify all available instances of Action +Profile and Action Selector PSA externs. +

+

PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile member, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime. +

+

PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into groups. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime. +

+

While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same ActionProfile message to describe both. +

+

The ActionProfile message includes the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Action +Profile or Selector. +

  • +
  • +

    table_ids, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector. +

  • +
  • +

    with_selector, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern. +

  • +
  • +

    size, an int64 representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups. +

  • +
  • +

    max_group_size, an int32 which is 0 for an Action Profile, or, for an +Action Selector, represents the maximum sum of all member weights within any +given selector group. The max_group_size must be no larger than size. PSA +programs can use the @max_group_size annotation to provide this value for +Action Selectors. If the annotation is omitted, the P4Info field will default +to 0. +

+

6.4.4. Counter & DirectCounter

+

Counter and DirectCounter messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is: +

+
    +
  • +

    Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index. +

  • +
  • +

    Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table. +

+ +

Both Counter and DirectCounter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this counter +extern instance. +

  • +
  • +

    spec, a message of of type CounterSpec used to describe the compile-time +configuration of this counter. Currently, the CounterSpec message is used to +carry only the counter unit, which can be any of the CounterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES: byte counter. +
    • +
    • PACKETS: packet counter. +
    • +
    • BOTH: combination of both byte and packet counter. +
    +
+ +

For indexed counters, the Counter message contains also a size field, an +int64 representing the maximum number of independent values that can be held +by this counter array. Conversely, the DirectCounter message contains a +direct_table_id field that carries the unit32 identifier of the table to +which this direct counter is attached. +

+

For indexed counters, the Counter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.5. Meter & DirectMeter

+

Meter and DirectMeter messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is: +

+
    +
  • +

    Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +e.g. to set the rate threshold. +

  • +
  • +

    Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table. +

+ +

Both Meter and DirectMeter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this meter +extern instance. +

  • +
  • +

    spec, a message of type MeterSpec used to describe the capabilities of +this meter extern instance. Currently, the MeterSpec message is used to +carry only the meter unit, which can be any of the MeterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES, which signifies that this meter can be configured with rates +expressed in bytes/second. +
    • +
    • PACKETS, for rates expressed in packets/second. +
    +
+ +

For indexed meters, the Meter message contains also a size field, an int64 +representing the maximum number of independent cells that can be held by this +meter. Conversely, the DirectMeter message contains a direct_table_id field +that carries the uint32 identifier of the table to which this direct meter is +attached. +

+

For indexed meters, the Meter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.6. ControllerPacketMetadata

+

ControllerPacketMetadata messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server. +

+

When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet. +

+

Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +@controller_header("packet_in") and @controller_header("packet_out"), +respectively. ControllerPacketMetadata messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages). +

+

A P4Info message can contain at most two ControllerPacketMetadata messages, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message where preamble.name is set to "packet_in" +and "packet_out" for packet-in and packet-out metadata, respectively. +

  • +
  • +

    metadata, a repeated field of type Metadata, where each Metadata message +includes the following fields: +

    +
      +
    • id, a uint32 identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two Metadata of the +same ControllerPacketMetadata message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the @id annotation, or let the compiler choose them. +
    • +
    • name, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below). +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this metadata. +
    • +
    • bitwidth, an int32 representing the size in bits of this metadata. +
    • +
    • type_name, which indicates whether the metadata field has a +user-defined type; this is useful for +translation. +
    +
+ +

As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding ControllerPacketMetadata +messages. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  bit<9> egress_port; /* suggested port where the packet
+                         should be sent */
+  bit<8> queue_id;    /* suggested queue ID */
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  bit<9> ingress_port; /* data plane port ID where
+                          the original packet was received */
+  bit<1> is_clone;     /* 1 if this is a clone of the
+                          original packet */
+}
+
+
+
controller_packet_metadata {
+  preamble {
+    id: 2868916615
+    name: "packet_out"
+    annotations: "@controller_header(\"packet_out\")"
+  }
+  metadata {
+    id: 1
+    name: "egress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "queue_id"
+    bitwidth: 8
+  }
+}
+
+controller_packet_metadata {
+  preamble {
+    id: 2868941301
+    name: "packet_in"
+    annotations: "@controller_header(\"packet_in\")"
+  }
+  metadata {
+    id: 1
+    name: "ingress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "is_clone"
+    bitwidth: 1
+  }
+}
+

Note that the use of @controller_header is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages. +

6.4.7. ValueSet

+

ValueSet messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P416 +specification [39]. +

+

The ValueSet message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Value +Set. +

  • +
  • +

    match, a repeated field of MatchField messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the match_fields repeated field in the +Table message. +

  • +
  • +

    size, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +value_set constructor call. +

+ +

According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of bit<W>, +tuple, or struct [26]. The rest of this section looks at all 3 of +these cases and gives an example ValueSet message when appropriate. +

+
    +
  1. +

    If the type parameter is bit<W>, match will include exactly one +MatchField message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used): +

    +
      +
    • id: set to 1 +
    • +
    • bitwidth: set to the value of W +
    • +
    • match_type: set to EXACT +
    +
+ +
+
+
@id(1) value_set<bit<8> >(4) pvs;
+select (hdr.f8) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    bitwidth: 8
+    match_type: EXACT
+  }
+  size: 4
+}
+
    +
  1. +

    If the type parameter is a tuple, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program. +

  2. +
  3. +

    If the type parameter is a struct, this version of P4Runtime requires that +all the fields of the struct be of type bit<W> (where W can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +match field will include one MatchField message for each field in the +struct, with the following fields: +

    +
      +
    • id: must be unique with respect to the other match entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +@id annotation, or let the compiler choose them. +
    • +
    • name: set to the name of the corresponding struct field. +
    • +
    • annotations: set to the list of P4 annotations associated with the struct +field, except for the @match annotation, if present (see the match field +below). +
    • +
    • bitwidth: set to the value of W for the corresponding struct field. +
    • +
    • type_name, which indicates whether the struct field has a user-defined +type; this is useful for +translation. +
    • +
    • match: by default match_type is set to EXACT; the P4 programmer can +specify a different match type by using the @match annotation +[26]. +
    • +
    • doc: documentation associated with the struct field. +
    +
+ +
+
+
struct match_t {
+  @id(1) bit<8> f8;
+  @id(2) @match(ternary) bit<16> f16;
+  @id(3) @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

In the above example, the @id annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs. +

+

Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a user-defined +type that resolves to a bit<W>, or a struct where +one or more fields is a user-defined type that +resolves to a bit<W>. For each MatchField that corresponds to a user-defined +type, the type_name field must be set to the appropriate value (i.e. the name +of the type). +

6.4.8. Register

+

Register messages are used to specify all possible instances of Register PSA +externs. +

+

Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime. +

+

The Register message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this register +instance. +

  • +
  • +

    type_spec, which specifies the data type stored by this register, expressed +using a P4DataTypeSpec message (see section on Representation of Arbitrary +P4 Types). +

  • +
  • +

    size, an int32 value representing the total number of independent register +cells available. +

  • +
  • +

    index_type_name, which indicates whether the register index has a +user-defined type. This is useful for +translation. The underlying built-in type +must be a fixed-width unsigned bitstring (bit<W>). +

+

6.4.9. Digest

+

Digest messages are used to specify all possible instances of Packet Digest +PSA externs. +

+

A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages. +

+

The Digest message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this digest +instance. +

  • +
  • +

    type_spec, which specifies the data type of an individual digest +notification using a P4DataTypeSpec message (see section on Representation +of Arbitrary P4 Types). +

+

6.4.10. Extern

+

Extern messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one Extern message instance in P4Info. The Extern message defines +the following fields: +

+
    +
  • +

    extern_type_id, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the reserved +range [0x81, 0xfe]. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture. +

  • +
  • +

    extern_type_name, which specifies the fully-qualified P4 name of the extern +type. +

  • +
  • +

    instances, a repeated field of ExternInstance Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +ExternInstance in turn defines the following fields: +

    +
      +
    • preamble, a Preamble message with the ID, name, and alias of this digest +instance. +
    • +
    • info, an Any Protobuf message [31] which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for info should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on Extending +P4Runtime for non-PSA Architectures for more +information. +
    +
+ +

If the P4 program does not include any instance of a given extern type, the +Extern message instance for that type should be omitted from the P4Info. +

6.5. Support for Arbitrary P4 Types with P4TypeInfo

+

See section on Representation of Arbitrary P4 +Types. +

7. P4 Forwarding-Pipeline Configuration

+

The ForwardingPipelineConfig captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the “Device Configuration” and sometimes also referred to as +the “P4 Blob”. It is defined as: +

+
+
+
message ForwardingPipelineConfig {
+  config.P4Info p4info = 1;
+  bytes p4_device_config = 2;
+  message Cookie {
+    uint64 cookie = 1;
+  }
+  Cookie cookie = 3;
+}
+

The p4info field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic. +

+

The p4_device_config is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new ForwardingPipelineConfig on that target. +

+

The cookie field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a GetForwardingPipelineConfig RPC. +When writing the config via a SetForwardingPipelineConfig RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present. +

8. General Principles for Message Formatting

8.1. Set / Unset Protobuf Field

+

In Protobuf version 3 (proto3), the default value for a message field is +“unset” [4]. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +CounterEntry message, an “unset” index field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the index message field is +set, a single entry will be read. +

+

Let's look at the counter example in more details. Based on this specification +document, the C++ server code which processes CounterEntry messages may look +like this: +

+
+
+
auto *counter_entry = ...
+if (counter_entry->has_index()) {
+  auto index = counter_entry->index().index();
+  read_one_entry(counter_entry->id(), index);
+} else {
+  read_all_entries(counter_entry->id());
+}
+
    +
  1. +

    Reading a single counter entry at index 0 in the counter array with id +<id>: +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
      +entry.mutable_index();
      +// The above line sets the index field; it is equivalent to:
      +// auto *index = entry.mutable_index();
      +// index->set_index(0);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
      +index {}
    • +
    • Expected behavior: Counter entry at index 0 is read. Notice that the +index subfield is missing under the index field message of +CounterEntry in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages. +
    +
  2. +
  3. +

    Reading all counter entries by leaving the index field unset +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
    • +
    • Expected behavior: All counter entries for the provided counter +instance are read. Notice that the index message field is unset (default +value) and is therefore omitted from the textual representation of the +message. +
    +
+

8.2. Read-Write Symmetry

+

The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example: +

+
+
+
intended_value = value
+
+status = server.write(intended_value, p4_entity)
+observed_value = server.read(p4_entity)
+
+assert(intended_value == observed_value)
+

To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If Read RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol's complexities to the client implementations. +

+

In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the match fields in a TableEntry message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +MessageDifferencer class [36] included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance. +

8.3. Zero as Reserved Value

+

p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a uint32. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a WriteRequest or a SetForwardingPipelineConfigRequest. +

8.4. Bytestrings

+

P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (bit<W>) or signed (int<W>), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +bytes Protobuf type. The correct bitwidth as per the P4 program of +each integer variable exposed through P4Runtime is specified in the P4Info +message. +

+

The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals: +

+
    +
  • +

    It ensures that a properly encoded binary string's integer value conforms +to the P4Info-specified bitwidth. +

  • +
  • +

    It supports read-write symmetry. +

  • +
  • +

    It helps facilitate non-disruptive P4 program updates. +

+ +

In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type bit<W> and/or int<W>. +

+

Note that this representation does not make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range. +

+

In the P4Runtime API version 1.0 (including minor version revisions), values +of table key fields, action parameters, and fields in packet-in and packet-out +headers between a device and the controller (see 6.4.6), +may not be of type int<W>. The rules for encoding signed values thus only +apply to messages of type P4Data (see 8.5.3). +

+

For a value of type bit<W>, the fewest number of bits required to represent +the integer value $V > 0$ is the smallest integer $A$ such that $V \leq 2^A -1$. +

+

For a value of type int<W>, the fewest number of bits required to represent +the integer value $V \neq 0$ in 2's complement form is the smallest integer $A$ +such that $-2^{A-1} \leq V \leq 2^{A-1} - 1$. +

+

As a special case, define that the value $V=0$ requires at least $A=1$ bit to +represent, regardless of whether it is signed or unsigned. +

+

The shortest possible binary string for an integer $V$ that needs $A$ bits to +represent it is computed as: +

+
+
+
minimum_string_size = floor((A + 7) / 8)
+

Binary strings with the byte length computed as minimum_string_size promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies. +

+

Any additional bits in the bytes sent for an unsigned integer value (type +bit<W>) must be 0. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with 0. +

+

Any additional bits in the bytes sent for a signed integer value (type int<W>) +must be copies of the sign bit, i.e. 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with copies of the +sign bit, i.e. 0 for non-negative values, or 0xff for negative values. In 2's +complement representation, this is called “sign extension”, and leaves the +numeric value represented unchanged. +

+

Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value. +

+

For a received bitstring expected to fit within a bit<W> type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring's width is W bits or less. +

+

For a received bitstring expected to fit within an int<W> type, the value it +represents is in range if, after “undoing sign extension”, the remaining bit +string's width is W bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other. +

+

If the string's byte length is zero, the server always rejects the string. +

+

When the server rejects a binary string due to any of the previous criteria, +it returns an OUT_OF_RANGE error. +

+

For all binary strings, P4Runtime uses big-endian (i.e. network) byte-order. +For signed integer values (int<W> P4 type), P4Runtime uses the same two's +complement bitwise representation as P4. Table 4 +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above. +

+
+ + + + + + + + + + + + + + + + + +
P4 type Integer value P4Runtime binary string Read-write symmetry
bit<8> 99 (0x63) \x63 yes
bit<16> 99 (0x63) \x00\x63 no
bit<16> 99 (0x63) \x63 yes
bit<16> 12388 (0x3064) \x30\x64 yes
bit<16> 12388 (0x3064) \x00\x30\x64 no
bit<12> 99 (0x63) \x00\x63 no
bit<12> 99 (0x63) \x63 yes
bit<12> 99 (0x63) \x00\x00\x63 no
int<8> 99 (0x63) \x63 yes
int<8> -99 (-0x63) \x9d yes
int<8> -99 (-0x63) \xff\x9d no
int<12> -739 (-0x2e3) \xfd\x1d yes
int<16> 0 (0x0) \x00\x00 no
int<16> 0 (0x0) \x00 yes
+
+ +
Table 4. Examples of Valid Bytestring Encoding
+

Table 5 shows some examples of invalid +P4Runtime binary strings: +

+
+ + + + + + + + + + + + +
P4 type P4Runtime binary string
bit<8> \x01\x63
bit<8> empty string
bit<16> \x01\x00\x63
bit<12> \x10\x63
bit<12> \x01\x00\x63
bit<12> \x00\x40\x63
int<8> \x00\x9d
int<12> \x8d\x1d
int<16> empty string
+
+ +
Table 5. Examples of Invalid Bytestring Encoding
+

As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from bit<8> to bit<9>, a server +running the bit<9> version of the P4 program will accept requests from +clients that remain on the bit<8> P4Runtime version. +

+

Despite the server's binary string flexibility for P4 program update support, +the client and server must both remain aware of the +read-write symmetry +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values. +

+

Representation of variable-length integer values (varbit<W> P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the dynamic-length of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an OUT_OF_RANGE error code otherwise. +

8.5. Representation of Arbitrary P4 Types

8.5.1. Problem Statement

+

The P416 language includes more complex types than just binary strings +[3]. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table 6 shows the different +P416 types and how they are allowed to be used, as per the P416 +specification. +

+
+ + + + + + + + + + + + + + + + + + + +
Container type
Element type header header_union struct or tuple
bit<W> allowed error allowed
int<W> allowed error allowed
varbit<W> allowed error allowed
int error error error
void error error error
error error error allowed
match_kind error error error
bool error error allowed
enum allowed1 error allowed
header error allowed allowed
header stack error error allowed
header_union error error allowed
struct error error allowed
tuple error error allowed
+
+ +
Table 6. P4 Type Usage
+

For example, the following P416 objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects. +

+
+
+
Digest<tuple<bit<4>, bit<8> > >() digest_complex;
+digest_complex.pack({ hdr.ipv4.version, hdr.ipv4.protocol });
+// ...
+header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

One solution would be to use only binary string (bytes type) in +p4runtime.proto and to define a custom serialization format for complex P416 +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P416 types. +

8.5.2. P4 Type Specifications in p4info.proto

+

In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type ip_t, which is a header union with 2 possible headers: +ipv4 with type ipv4_t and ipv6 with type ipv6_t. Similarly, they need to +know the field layout for both of these header types. +

+

To achieve this we introduce 2 main Protobuf messages: P4TypeInfo and +P4DataTypeSpec. +

+

P4TypeInfo is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P416 program. These +named types are struct, header, header_union, enum and +serializable_enum; for each of these we have a type specification message, +respectively P4StructTypeSpec, P4HeaderTypeSpec, P4HeaderUnionTypeSpec, +P4EnumTypeSpec and P4SerializableEnumTypeSpec. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. P4TypeInfo also includes the list of parser errors for the program, as +a P4ErrorTypeSpec message. +

+

P4DataTypeSpec is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each P4DataTypeSpec message corresponds to a compile-time type in the +original P416 program (e.g. the type parameter of an extern). This +compile-time type is represented as a Protobuf oneof, which can be: +

+
    +
  • +

    a string representing the name of the type in case of a named type (struct, +header, header_union, enum, serializable_enum or user-defined “new” +type), +

  • +
  • +

    an empty Protobuf message for bool and error, or +

  • +
  • +

    a Protobuf message for other anonymous types (bit<W>, int<W>, varbit<W>, +tuple or stack). The “binary string” types (bit<W>, int<W>, and +varbit<W>) are grouped together in the P4BitstringLikeTypeSpec message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf bytes +type). +

+ +

For all P416 compound types (tuple, struct, header, and header_union), +the order of members in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P416 declaration. The same goes for the order of members of an enum +(serializable or not) or members of error. +

8.5.3. P4Data in p4runtime.proto

+

P4Runtime uses the P4Data message to represent values of arbitrary types. The +P4Runtime client must generate correct P4Data messages based on the type +specification information included in P4Info. The P4Data message was designed +to introduce little overhead compared to using binary strings in the most common +case (P416 bit<W> type). +

+

Just like its P4Info counterpart - P4DataTypeSpec -, P4Data uses a Protobuf +oneof to represent all possible values. +

+

We define a canonical representation for P4Data messages therefore +guaranteeing read-write symmetry by introducing the following requirements: +

+
    +
  • +

    The order of members in P4StructLike and the order of bitstrings in +P4Header must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P416 type +declaration. +

  • +
  • +

    An invalid header is represented by a P4Header message where the is_valid +field is false and the bitstrings repeated field is empty. +

  • +
  • +

    An invalid header union (i.e. all headers in the union are invalid) is +represented by a P4HeaderUnion message where the valid_header_name is the +empty string (default value for the field) and the valid_header is unset. +

  • +
  • +

    The order of entries in P4HeaderStack and P4HeaderUnionStack is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the entries field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding P4HeaderStackTypeSpec or +P4HeaderUnionStackTypeSpec message. +

+

8.5.4. Example

+

Let's look at the Register example again: +

+
+
+
header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

Here's the corresponding entry in the P4Info message: +

+
+
+
registers {
+  preamble {
+    id: 369119267
+    name: "register_ip"
+    alias: "register_ip"
+  }
+  type_spec {
+    header_union {
+      name: "ip_t"
+    }
+  }
+  size: 128
+}
+type_info {
+  headers {
+    key: "ipv4_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  headers {
+    key: "ipv6_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  header_unions {
+    key: "ip_t"
+    value {
+      members {
+        name: "ipv4"
+        header {
+          name: "ipv4_t"
+        }
+      }
+      members {
+        name: "ipv6"
+        header {
+          name: "ipv6_t"
+        }
+      }
+    }
+  }
+}
+

Here's a p4.WriteRequest to set the value of register_ip[12]: +

+
+
+
update {
+  type: INSERT
+  entity {
+    register_entry {
+      register_id: 369119267
+      index {
+        index: 12
+      }
+      data {
+        header_union {
+          valid_header_name: "ipv4"
+          valid_header {
+            is_valid: true
+            bitstrings: "\x04"
+            bitstrings: # ...
+          }
+        }
+      }
+    }
+  }
+}

8.5.5. enum, serializable enum and error

+

P416 supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or “unsafe” enum) +[5]. For enum types with no underlying type as well as error +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in P4Data to represent enum and +error values. +

+

Serializable enum types have an underlying fixed-width unsigned integer +representation (bit<W>). All named enum members must be assigned an integer +value by the P4 programmer, but not all valid numeric values for the +underlying type need to have a corresponding name. P4TypeInfo includes the +mapping between entry name and entry value. When providing serializable enum +values through P4Data, one must use the assigned integer value (enum_value +bytestring field). P4Runtime does not provide a way for the client to use the +name even when the enum member has one instead of the value, as it makes +it easier for the server to respect the read-write +symmetry principle. +

8.5.6. User-defined types

+

P416 enables programmers to introduce new types [11]. While similar +to typedef, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +translation. When introducing a new type, the +declaration can be annotated with @p4runtime_translation to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for port numbers, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. The @p4runtime_translation annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (bit<W>). The type exposed to the control plane (referred to as the +controller_type) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a URI (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the controller_type of the values exposed to the control plane. The +controller_type can be either bit<W> where W is any positive integer, or +string, or a positive integer W which has the same meaning as bit<W>. +Specifying just an integer is deprecated. +

+

It is recommended that the URI includes at least the P4 architecture name and +the type name. +

+

A @p4runtime_translation annotation need not have any effect if it is used to +annotate anything in a P4 program other than a type declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect. +

+

User-defined types are specified using the P4NewTypeSpec message, which has +the following fields: +

+
    +
  • +

    representation, a Protobuf oneof specifying how values of this type are +exchanged between client and server; it can be either: +

    +
      +
    • +

      original_type, if and only if no @p4runtime_translation annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 type declaration is itself a +user-defined type, original_type is obtained by “walking” the chain of +type declarations recursively until a built-in type (e.g. bit<W>) is +found. +

    • +
    • +

      translated_type, if and only if the P4 type declaration was annotated +with @p4runtime_translation. It is of type P4NewTypeTranslation, +which itself has two fields uri and either sdn_string or +sdn_bitwidth , which map to the two input parameters to the +annotation. +

    +
  • +
  • +

    annotations, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration. +

+ +

For example, an architecture in this case PSA may introduce a new type +for port numbers: +

+
+
+
// Controller refers to ports as a string, e.g. "eth0".
+@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+// Controller refers to ports as a 32-bit integer, e.g. 0xffffffff.
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+// Same as above.
+@p4runtime_translation("p4.org/psa/v1/PortId_32_t", 32)
+type bit<9> PortId_32_t;
+

In this case, the P4Info message would include the following P4TypeInfo +messages: +

+
+
+
type_info {
+  new_types {
+    key: "PortId_String_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_String_t"
+        sdn_string: {}
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_Bit32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_Bit32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+

Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (e.g. through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over @p4runtime_translation to enable users +to overwrite annotations included as part of the P4 architecture definition. +

8.5.7. Trade-off for v1.x Releases

+

For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +bytes with P4Data in the p4.v1.FieldMatch message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +bytes to provide action parameter values and controller metadata +values. However P4Data is used whenever appropriate for PSA externs and we +encourage the use of P4Data in architecture-specific extensions. +

+

In order to support translation for action +parameters and match fields, we include a type_name field in +p4.config.v1.MatchField, p4.config.v1.Action.Param and +p4.config.v1.ControllerPacketMetadata.Metadata. In addition, the bitwidth +field for all of these message types must abide by the following rule when +type_name names a translated user-defined type: +

+
    +
  • +

    If the controller_type is a fixed-width unsigned bitstring, the bitwidth +field must be set to the bitwidth of the controller_type. This information +is redundant with the one included in the P4TypeInfo entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent. +

  • +
  • +

    Otherwise (i.e., if the controller_type is a string), the bitwidth must +be “unset”, which, in Protobuf version 3, is the same as setting the field to +0. +

+ +

For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types: +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+@name(".t")
+table t {
+  key = {
+    meta.port1: exact;  // meta.port1 has type PortId_String_t
+    meta.port2: exact;  // meta.port2 has type PortId_Bit32_t
+  }
+  actions = {
+    drop;
+  }
+}
+

This table would have the following representation in the generated P4Info +message: +

+
+
+
tables {
+  preamble {
+    id: 34728461
+    name: "t"
+    alias: "t"
+  }
+  match_fields {
+    id: 1
+    name: "meta.port1"
+    # notice that bitwidth is unset
+    match_type: EXACT
+    type_name {
+      name: "PortId_String_t"
+    }
+  }
+  match_fields {
+    id: 2
+    name: "meta.port2"
+    bitwidth: 32
+    match_type: EXACT
+    type_name {
+      name: "PortId_Bit32_t"
+    }
+  }
+  # ...
+}

9. P4 Entity Messages

+

P4Runtime covers P4 entities that are either part of the P416 language, or +defined as PSA externs. The sections below describe the messages for each +supported entity. +

9.1. TableEntry

+

The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action's +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification. +

+

P4Runtime supports inserting, modifying, deleting and reading table entries with +the TableEntry entity, which has the following fields: +

+
    +
  • +

    table_id, which identifies the table instance; the table_id is determined +by the P4Info message. +

  • +
  • +

    match, a repeated field of FieldMatch messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration. +

  • +
  • +

    action, which indicates which of the table's actions to execute in case of +match and with which argument values. +

  • +
  • +

    priority, a 32-bit integer used to order entries when the table's match key +includes an optional, ternary or range match. +

  • +
  • +

    controller_metadata, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +metadata field. +

  • +
  • +

    metadata, an arbitrary bytes value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. +

  • +
  • +

    meter_config, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    counter_data, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    meter_counter_data, which is used to read and write the per-color counter +values for the direct meter entry attached to this table entry, if any. +See Direct resources section for more information. +

  • +
  • +

    is_default_action, a boolean flag which indicates whether the table entry is +the default entry for the table. See Default entry +section for more information. +

  • +
  • +

    idle_timeout_ns and time_since_last_hit, which are two fields used to +implement idle-timeout support for the table, if applicable. See +Idle-timeout section for more information. +

+ +

The priority field must be set to a non-zero value if the match key includes a +ternary match (i.e. in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an OPTIONAL, TERNARY or +RANGE match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches. +

+

The match and priority fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for MODIFY and DELETE updates. When deleting +an entry, these key fields (along with is_default_action) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a keyless +table (the table has an empty match key), the server must reject all attempts to +INSERT a match entry and return an INVALID_ARGUMENT error. +

+

The number of match entries that a table should support is indicated in P4Info +(size field of Table message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P416 specification for the +size property [30]. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +RESOURCE_EXHAUSTED when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached. +

9.1.1. Match Format

+

The bytes fields in the FieldMatch message follow the format described in +Bytestrings. +

+

For “don't care” matches, the P4Runtime client must omit the field's entire +FieldMatch entry when building the match repeated field of the TableEntry +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for “don't care” matches, which is needed +to ensure read-write symmetry. For PSA match types, +a “don't care” match for a specific match key field is defined as follows: +

+
    +
  • +

    For a TERNARY match, it is logically equivalent to a mask of zeros. +

  • +
  • +

    For a OPTIONAL match, it is logically equivalent to a wildcard match. +

  • +
  • +

    For an LPM match, it is logically equivalent to a prefix_len of zero. +

  • +
  • +

    For a RANGE match, it is logically equivalent to a range which includes all +possible values for the field. +

+ +

Note that there is no “don't care” value for EXACT matches and therefore exact +match fields can never be omitted from the TableEntry message. +

+

The following example shows a P4Runtime message that treats a TERNARY field +as a “don't care” match. The P4 program defines table t with TERNARY +and EXACT fields in its match key: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: ternary;
+    istd.ingress_port: exact;
+  }
+  actions = {
+    drop;
+  }
+}
+

In this P4Runtime request, the client omits the table's TERNARY field +from the repeated match field to indicate a “don't care” match. As shown +below, the match specifies only the EXACT field given by field_id: 2. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 33554439  # Table t's ID.
+    match {
+      # field_id 1 is not present to use the don't care ternary value.
+      field_id: 2
+      exact {
+        value: "\x20"
+      }
+    }
+    action {
+      # Action selection goes here.
+    }
+  }
+}
+

For every member of the TableEntry repeated match field, field_id must be +a valid id for the table, as per the P4Info, and one of the fields in +field_match_type must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an INVALID_ARGUMENT error code. +

+
    +
  • EXACT match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.exact().value()))
+
    +
  • LPM match + +
      +
    • The binary string encoding of the value (when present) must conform to the +Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • “Don't care” bits must be 0 in value. +
+ +
+
+
assert(BytestringValid(match.lpm().value()))
+
+pLen = match.lpm().prefix_len()
+assert(pLen > 0)
+
+trailing_zeros = countTrailingZeros(match.lpm().value())
+assert(trailing_zeros >= field_bits - pLen)
+
    +
  • TERNARY match + +
      +
    • The binary string encoding of the value (when present) and mask (when +present) must conform to the Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • Masked bits must be 0 in value. This constraint taken together +with the Bytestrings requirements means that the +value's binary string is never longer than the mask's binary string. +When the value's string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask. +
+ +
+
+
assert(BytestringValid(match.ternary().value()))
+assert(BytestringValid(match.ternary().mask()))
+assert(match.ternary().value().size() <= match.ternary().mask().size());
+
+value = parseInteger(match.ternary().value())
+mask = parseInteger(match.ternary().mask())
+
+assert(mask != 0)
+
+assert(value & mask == value)
+
    +
  • RANGE match + +
      +
    • The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the Bytestrings +requirements. +
    • +
    • Low bound must be less than or equal to the high bound. +
    • +
    • “Don't care” match must be omitted. +
+ +
+
+
assert(BytestringValid(match.range().low()))
+assert(BytestringValid(match.range().high()))
+
+low = parseInteger(match.range().low())
+high = parseInteger(match.range().high())
+
+assert(low <= high)
+
+assert(low != min_field_value || high != max_field_value)
+
    +
  • OPTIONAL match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.optional().value()))

9.1.2. Action Specification

+

The TableEntry action field must be set for every INSERT update but may be +left unset for MODIFY updates, in which case the action specification for the +table entry will not be modified (if a MODIFY update has an unset action field +and does not modify any direct resource attached to the table then the MODIFY +update is a no-op). Based on the implementation property value of the P4 table, +the oneof in the TableAction message will either be: +

+
    +
  • +

    an Action specification for direct tables (with no P4 implementation +property) +

  • +
  • +

    an action profile member id for indirect tables for which the implementation +property is an action profile with no selector. +

  • +
  • +

    an action profile member id or group id for indirect tables for which the +implementation property is an action profile with selector. +

  • +
  • +

    an ActionProfileActionSet specification for indirect tables for +which the implementation property is an action profile with +selector. This usage is described in One Shot Action Selector +Programming +

+ +

If the oneof does not match the table description in the P4Info (e.g. the +oneof is action_profile_member_id for a direct table), the server must +return an INVALID_ARGUMENT error code. +

+

The Action Protobuf message has the following fields: +

+
    +
  • +

    action_id, which identifies the action instance; the action_id is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an INVALID_ARGUMENT error +code. If the client uses a valid action_id for the table but does not +respect the action scope specified in P4Info (e.g. tries to set a TABLE_ONLY +action as the default action), the server must return a PERMISSION_DENIED +error code. +

  • +
  • +

    params: a repeated Protobuf field of action parameter values, each encoded +as a Param message. For each parameter, param_id must be valid for the +action (as per the P4Info) and value must follow the format described in +Bytestrings. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an INVALID_ARGUMENT error code +if a parameter id is missing, if an extra parameter id not found in the +P4Info was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +Bytestrings format. +

+ +

For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a NOT_FOUND error code. +

9.1.3. Default Entry

+

According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer or defaults to NoAction +(which is a no-op) otherwise and assuming it is not declared as const, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow INSERT and DELETE updates on the default entry and the +P4Runtime server must return an INVALID_ARGUMENT error code if the client +attempts one. +

+

The default entry is identified by setting the is_default_action boolean field +to true. When this flag is set to true, the repeated match field must be empty +and the priority field must be set to zero, otherwise the P4Runtime server +must return an INVALID_ARGUMENT error code. When performing a MODIFY update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its controller_metadata and metadata value as well as the +configurations for its direct resources will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a PERMISSION_DENIED +error code if the client attempts to modify it. +

+

Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to direct resources. +

+

In this P4Runtime release, we have decided to restrict the default entry for +indirect tables tables with an ActionProfile or ActionSelector +implementation property to a constant NoAction action entry, with the +hope that it would simplify the implementation of the P4Runtime service. +

9.1.4. Constant Tables

+

Constant tables are defined as tables whose match entries are immutable. They +are identified by the is_const_table flag in P4Info. +

+

The only write updates which are allowed for constant tables are MODIFY +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +PERMISSION_DENIED error. Just like any table entry MODIFY request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a PERMISSION_DENIED error. +

+

The contents of const tables can be queried by the client through a +ReadRequest. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: table_id, match, action, +is_default_action, and priority (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the priority field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P416 does not support assigning explicit priorities to static +entries. When a priority value is required (e.g. for tables including RANGE, +TERNARY or OPTIONAL matches), it is inferred based on the order in which +entries appear in the table declaration. +

9.1.5. Wildcard Reads

+

When performing a ReadRequest, the P4Runtime client can select all entries +from one or all tables on the target and use several of the TableEntry fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as priority and “unset” for message fields such as match. The following +fields may be used to select and filter results: +

+
    +
  • table_id: If default (0), entries from all tables including constant +tables will be selected and no other filter can be used. Otherwise only +the specified table will be considered. +
  • +
  • match: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned. +
  • +
  • action: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an action_id (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id. +
  • +
  • priority: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value. +
  • +
  • controller_metadata: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +controller_metadata value. +
  • +
  • metadata: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided metadata value. +
  • +
  • is_default_action: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered. +
  • +
  • role: If default (unset), all table entries will be considered. Otherwise, +table entries will be filtered based on the provided role value. +
+ +

For example, in order to read all entries from all tables from device 3, the +client can use the following ReadRequest message. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0
+    priority: 0
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following ReadRequest +message: +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+    priority: 11
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

The canonical representation of “don't care” matches, combined with the ability +to do a wildcard read on all table entries by leaving the match field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single “don't care” entry or to do a wildcard +read. If a table has no fields with match kind EXACT, it is possible via +P4Runtime to add an entry that is “don't care” for all fields (i.e. has an empty +match field) but is not the default entry (i.e. is_default_action is +false). When reading this entry from the table, there is no way to read only +that entry from the table, because it would require providing an unset match +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single LPM match: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: lpm;
+  }
+  actions = {
+    drop; fwd;
+  }
+}
+

The following WriteRequest message can be used to add 2 entries: +

+
+
+
device_id: 3
+entities {
+  table_entry { # don't care entry
+    table_id: 0x0212ab34
+    # ...
+  }
+  table entry {
+    table_id: 0x0212ab34
+    match {
+      field_id: 1
+      lpm {
+        value: 0x0a000000
+        prefix_len: 8
+      }
+    # ...
+  }
+}
+

The first entry is a “don't care” entry, while the second one matches all +10.0.0.0/8 addresses. The second entry has higher priority than the first one. +

+

The following ReadRequest message will return all entries in the table, not +just the “don't care” entry. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+  }
+}
+

This issue also exists for tables with TERNARY, RANGE, and OPTIONAL +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the “don't care” entry will be returned to the +client. If the client uses distinct priority values for all entries which is +strongly recommended to achieve deterministic behavior , +then there is no ambiguity because the wildcard read will actually return a +single entry (the “don't care” entry) as long as the priority field is set to +the correct value. +

9.1.6. Direct Resources

+

In addition to the DirectCounterEntry and DirectMeterEntry entities, +P4Runtime support reading and writing direct resources as part of the +TableEntry message. This is convenient for two reasons: +

+
    +
  • +

    A table entry and its direct resources can be read with a single entity when +doing a Read RPC call +

  • +
  • +

    The initial configuration for an entry's direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can “hit” the table entry without +executing the appropriate meter entry. +

+ +

Once the table entry has been inserted, the P4Runtime client is free to use the +DirectCounterEntry and DirectMeterEntry messages for read and write +operations on DirectCounter and DirectMeter instances. For example, it is +usually more convenient as well as more efficient to use DirectCounterEntry to +query a counter entry value rather than use TableEntry, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry. +

+

The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does not need to be “executed” in +every action bound to the table. It is an error to provide a direct resource +configuration in a TableEntry message when programming an action that does not +execute the direct resource, and the server must return an INVALID_ARGUMENT +error code. +

+

We leverage Protobuf's ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the TableEntry message. The list below describes how +the server must handle the meter_config, counter_data and +meter_counter_data fields for read and write requests, based on whether the +fields are set or not. We do not cover error cases in the list, i.e. we assume +that we are dealing with a table which is assigned a direct counter / a direct +meter, and that the action being used for the table entry “executes” the direct +resource appropriately. +

+
    +
  • +

    meter_config field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets). +
      • +
      • if set: The initial configuration for the meter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The meter entry's configuration is reset to the default +(meter returns GREEN for all packets). +
      • +
      • if set: The value provided by the client is used to re-configure +the meter entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the meter entry's +configuration (meter_config is unset in the response). +
      • +
      • if set: If the meter entry's configuration is the default +configuration, meter_config is unset in the response. Otherwise, the +response includes the meter entry's configuration that was written by +the client earlier. This respects the “read-write symmetry” principle. +
    +
  • +
  • +

    counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for the counter entry is the default +(0). +
      • +
      • if set: The initial value for the counter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The counter entry's value is not changed. +
      • +
      • if set: The value provided by the client is written to the counter +entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the counter entry's value +(counter_data is unset in the response). +
      • +
      • if set: The response includes the counter entry's value read from +the target. +
    +
  • +
  • +

    meter_counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for all 3 counter entries is the +default (0). +
      • +
      • if set: The initial value for all 3 counter entries is the +default (0). Sub-field, if any, can only have zero (0) as its value. +INVALID_ARGUMENT error is returned for any non-zero sub-field value. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: All the 3 counter entries are unchanged. +
      • +
      • if set: All the 3 counters are reset to 0. Sub-field, if any, can +only have zero (0) as its value. INVALID_ARGUMENT error is returned +for any non-zero sub-field value. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include counter values +(meter_counter_data is unset in the response). +
      • +
      • if set: The response includes all the 3 counter values read from +the target. +
    +
+ +

In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +meter_config field unset when inserting or modifying a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the TableEntry message +(i.e. the meter_config field must be set to match the existing configuration). +

9.1.7. Idle-timeout

+

P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not “hit” (i.e. not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification using the +IdleTimeoutNotification message to the primary client, which can then take +action, such as remove the idle table entry. +

+

Two fields of the TableEntry Protobuf message are used to implement idle +timeout: +

+
    +
  • +

    idle_timeout_ns: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, i.e. no +IdleTimeoutNotification message will ever be generated for this entry. When +a client reads a TableEntry, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry. +

  • +
  • +

    time_since_last_hit: a Protobuf message with a single field (elapsed_ns) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The time_since_last_hit field must be unset for a +TableEntry write. When reading a table entry, time_since_last_hit must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0. +

+ +

These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an INVALID_ARGUMENT error code if at least one of these +conditions is met: +

+
    +
  • idle_timeout_ns is set to a non-zero value, or +
  • +
  • time_since_last_hit is set +
+ +

The target should do its best to approximate the idle_timeout_ns value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the TableEntry write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for time_since_last_hit. +

+

P4Runtime does not support idle timeout for default entries. When the +is_default_action flag is set in a TableEntry message, idle_timeout_ns +must be set to 0 (default) and time_since_last_hit must be unset. If the +server receives a TableEntry message which violates this, it must return an +INVALID_ARGUMENT error. +

+

For more information about idle timeout, in particular regarding +IdleTimeoutNotification, please refer to the Table idle timeout +notifications section. +

9.2. ActionProfileMember & ActionProfileGroup

+

P4Runtime defines an API for programming a PSA ActionProfile extern using +ActionProfileMember messages. A PSA ActionSelector extern can be programmed +using both ActionProfileMember and ActionProfileGroup messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table t for L3 routing, implemented with an action +selector as. +

+
+
+
ActionSelector(HashAlgorithm.crc32,
+               /*size = */ 32w1024,
+               /*output_width = */ 32w10) as;
+
+action set_nhop(PortId_t p, EthAddr smac, EthAddr dmac) {
+  istd.egress_port = p;
+  hdr.ethernet.smac = smac;
+  hdr.ethernet.dmac = dmac;
+}
+
+table t {
+  key = {
+    hdr.ipv4.dip: lpm;  // LPM on destination IP address
+  }
+  actions = {
+    set_nhop;
+  }
+  implementation = as;
+}
+

When programming table t in the example above, a P4Runtime client should +specify the TableAction in the TableEntry to be a reference to either an +action profile member or group. The reference is a non-zero uint32 identifier +that uniquely identifies a member or group programmed in the action selector +as. +

+

If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata. +

+

If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata. +

9.2.1. Action Profile Member Programming

+

Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a uint32 identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the actions +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the actions attributes of the +tables must have an identical list of P4 actions. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector. +

+

An ActionProfileMember entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info. +

  • +
  • +

    member_id is the non-zero uint32 identifier of the action profile member +entry being updated. +

  • +
  • +

    action is the specification of the P4 action instance bound to the action +profile member entry. +

+ +

An action profile member may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an ALREADY_EXISTS error +code. The action specification must be provided, or the server must return +INVALID_ARGUMENT. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return RESOURCE_EXHAUSTED. +
  • +
  • MODIFY: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return NOT_FOUND, +and the action specification must be provided, or the server must return +INVALID_ARGUMENT. +
  • +
  • DELETE: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a NOT_FOUND error code. The member +must not be part of an action profile group, or the server must return +FAILED_PRECONDITION. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return FAILED_PRECONDITION. action_profile_id and member_id are the only +fields that are considered when performing a DELETE and every other field +will be ignored. +
+ +

When reading, an ActionProfileMember message with action_profile_id and +member_id equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with action_profile_id equal to the id of +an existing ActionProfile or ActionSelector object, and a member_id equal to +0, will read all members of that specified object. +

9.2.2. Action Profile Group Programming

+

Action profile groups are entries in an ActionSelector and are referenced by a +uint32 identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type. +

+

Within a single ActionSelector object, the uint32 values used to identify its +members are in a separate ‘scope’ from the uint32 values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5. +

+

There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it. +

+

An ActionProfileGroup entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionSelector +extern instance, as defined in P4Info. +

  • +
  • +

    group_id is the non-zero uint32 identifier of the action profile group +entry being updated. +

  • +
  • +

    members is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields: +

    +
      +
    • member_id for looking up the member table in the selector. +
    • +
    • weight specifying the probability of the member's selection at +runtime. 0 is not a valid weight value and the server must return +INVALID_ARGUMENT if the client attempts to use it. +
    • +
    • watch_port is the controller-defined port that the member's +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +9.2.4 for notes on the behavior if all members in +a group are excluded for this reason. If watch_port is empty, then the +member is always included in the selection, regardless of the status of +any port of the device. The value must be empty or the SDN port of an +existing port on the device, otherwise the server must return +INVALID_ARGUMENT. +
    +
  • +
  • +

    max_size is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +MODIFY update. See the subsection below for the rules on setting +max_size. +

+ +

An action profile group may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new group entry bound to a set of existing action profile +members. The group_id must be different from ids of already programmed +groups for that selector, or the server must return an ALREADY_EXISTS error +code. All members specified in the group must exist in the selector, or the +server must return NOT_FOUND. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target. +
  • +
  • MODIFY: Modify the member set specification of an existing group entry. An +entry with the group_id must exist, or the server must return +NOT_FOUND. All members specified in the group entry must exist in the +selector, or the server must return NOT_FOUND. The value of max_size must +be identical to the value used when inserting the group, otherwise an +INVALID_ARGUMENT error is returned. +
  • +
  • DELETE: Delete the group entry and deallocate the group_id. The group must +not be referenced in the table action of any table entry, or the server must +return a FAILED_PRECONDITION error code. If the group_id is invalid, the +server must return NOT_FOUND. action_profile_id and group_id are the +only fields that are considered when performing a DELETE and every other +field will be ignored. +
+ +

When setting the group membership with INSERT or MODIFY, the members +repeated field must not include duplicates, i.e. members with the same +member_id. The weight field is used instead to logically “repeat” the member +inside the group. +

+

It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation “stores” the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made. +

+

When reading, an ActionProfileGroup message with action_profile_id and +group_id equal to 0 will read all groups of all ActionSelector objects. A +message with action_profile_id equal to the id of an existing ActionSelector +object, and a group_id equal to 0, will read all groups of that one specified +object. +

9.2.2.1. Rules on Setting max_size
+

The valid values for max_size depend on the static max_group_size included +in the P4Info message: +

+
    +
  • +

    If max_group_size is greater than 0, then max_size must be greater than 0, +and less than or equal to max_group_size. We assume that the target can +support selector groups for which the sum of all member weights is up to +max_group_size, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If max_size is greater than max_group_size, the server +must return INVALID_ARGUMENT. +

  • +
  • +

    Otherwise (i.e. if max_group_size is 0), the P4Runtime client can set +max_size to any value greater than or equal to 0. +

    +
      +
    • +

      A max_size of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (INSERT or MODIFY), the target must return a +RESOURCE_EXHAUSTED error. +

    • +
    • +

      If max_size is greater than 0 and the value is not supported by the +target, the server must return a RESOURCE_EXHAUSTED error at +group-creation time. +

    +
+

9.2.3. One Shot Action Selector Programming

+

P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids. +

+

One shots are programmed by choosing the ActionProfileActionSet message as the +TableAction. The ActionProfileActionSet message consists of a set of +ActionProfileAction messages, which in turn have the following fields: +

+
    +
  • +

    action is one of the actions specified by the table that is being +programmed. +

  • +
  • +

    weight specifying the probability of the action's selection at runtime. 0 is +not a valid weight value and the server must return INVALID_ARGUMENT if +the client attempts to use it. The sum of all weights across all +ActionProfileAction messages for that ActionProfileActionSet message must +not exceed the max_group_size specificed in the P4Info (if greater than 0), +or the server must return INVALID_ARGUMENT. +

  • +
  • +

    watch_port is the controller-defined port that the action's liveness depends +on. At runtime, the action must be excluded from selection if the watch port +is down. See Section 9.2.2 for more details +on the watch_port field, which also apply for one shot action selector +programming. +

+ +

Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics. +

+

To preserve read-write symmetry, an implementation must answer ReadRequests +with the original one shot messages. It may not return a desugared version of +the one shot message. +

+

For example, consider the action selector table defined +here. This table could be programmed +with the following one shot update: +

+
+
+
table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action {
+    action_profile_action_set {
+      action_profile_actions {
+        action { /* set nexthop 1 */ }
+        weight: 1
+        watch_port: "\x01"
+      }
+      action_profile_actions {
+        action { /* set nexthop 2 */ }
+        weight: 2
+        watch_port: "\x02"
+      }
+      action_profile_actions {
+        action { /* set nexthop 3 */ }
+        weight: 3
+        watch_port: "\x03"
+      }
+    }
+  }
+}
+

Which would be equivalent to the following updates, where GROUP_ID, +MEMBER_ID_1, MEMBER_ID_2, and MEMBER_ID_3 are unused ids: +

+
+
+
action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_1
+  action { /* set nexthop 1 */ }
+}
+action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_2
+  action { /* set nexthop 2 */ }
+}
+action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_3
+  action {  /* set nexthop 3 */ }
+}
+action_profile_group {
+  action_profile_id: 0x11ab12cd
+  group_id: GROUP_ID
+  members {
+    member_id: MEMBER_ID_1
+    weight: 1
+    watch_port: "\x01"
+  }
+  members {
+    member_id: MEMBER_ID_2
+    weight: 2
+    watch_port: "\x02"
+  }
+  members {
+    member_id: MEMBER_ID_3
+    weight: 3
+    watch_port: "\x03"
+  }
+}
+table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action { action_profile_group_id: GROUP_ID }
+}
+

Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure correct ordering between the dependent +updates. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct WriteRequest batches are required. +

+

It is possible to include several ActionProfileAction messages with the same +exact action specification in one ActionProfileActionSet message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the weight field. Note that to preserve read-write symmetry, the server +must not coalesce multiple ActionProfileAction messages with the same action +specification into one. +

+

All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with ActionProfileMember and +ActionProfileGroup messages. Programming some entries with one shots, and +other entries with ActionProfileMember and ActionProfileGroup messages is +not allowed, and the server must return the error code INVALID_ARGUMENT in +that case. +

+

A P4Runtime server must support the one shot style of programming tables with +an action selector implementation. Support for the ActionProfileMember and +ActionProfileGroup style is optional. If ActionProfileMember and +ActionProfileGroup are not supported by a server, it must return an +UNIMPLEMENTED error for every ActionProfileMember or ActionProfileGroup +message that it receives. +

9.2.4. Constraints on action selector programming

+

The PSA specification states that the following features are optional in +action selector implementations [22]: +

+
    +
  1. Support for non-empty groups where in the same group, different members are +bound to different actions. +
  2. +
  3. Predictable data plane behavior when a matched table entry points to an empty +group. +
+ +

For 1., if a client tries to INSERT or MODIFY a group with members bound to +different actions, the server should return UNIMPLEMENTED if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return UNIMPLEMENTED (modifying the action parameter values must be +supported, however). +

+

PSA 1.1 introduces the psa_empty_group_action table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. psa_empty_group_action is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of psa_empty_group_action at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +NoAction. Even when psa_empty_group_action is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of psa_empty_group_action mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming. +

+

The PSA specification includes a discussion on how to implement +psa_empty_group_action in software in the P4Runtime server +[25]. +

+

If a P4Runtime implementation does support psa_empty_group_action, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down. +

+

If a P4Runtime implementation does not support psa_empty_group_action, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down. +

9.3. CounterEntry & DirectCounterEntry

+

PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The CounterData +P4Runtime message can be used for all three types of PSA counters PACKETS, +BYTES and PACKETS_AND_BYTES and consists of the following fields: +

+
    +
  • byte_count is an int64, corresponding to the number of octets. +
  • +
  • packet_count is an int64, corresponding to the number of packets. +
+ +
+
+
message CounterData {
+  int64 byte_count = 1;
+  int64 packet_count = 2;
+}
+

P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of byte_count and packet_count fields, which +is equivalent to specifying the counter type PACKETS_AND_BYTES. Counters may +be defined as direct or indirect (indexed) instances. +

9.3.1. DirectCounterEntry

+

A direct counter is a direct resource associated with a TableEntry (see +Direct Resources). The counter_data field of the +TableEntry message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +DirectCounterEntry message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed. +

+
+
+
message DirectCounterEntry {
+  TableEntry table_entry = 1;
+  CounterData data = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectCounterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match TableEntry.match of the table entry +to which this direct counter entry is associated. If a matching TableEntry +is not found, the server returns the error code NOT_FOUND. +

  • +
  • +

    data is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified. +

+ +

Specifying DirectCounterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read the contents of a +DirectCounter: +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the counter value in the counter_data field of the TableEntry message +(see Direct resources). +

  • +
  • +

    Explicitly request the counter value by including the DirectCounterEntry in +the ReadRequest. The table_entry.match field must match the TableEntry +whose counter is being read. If no such entry is found, the server returns the +error code NOT_FOUND. +

+

9.3.2. CounterEntry

+

An indirect or indexed counter is not associated with a specific TableEntry +and may be updated independently of any action. It may be read or written using +the P4Runtime CounterEntry message whose fields are defined as follows: +

+
    +
  • +

    counter_id is a uint32, the unique identifier for the counter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +the counter array. +

  • +
  • +

    data is a Protobuf message of type CounterData, which represents the +counter value. +

+ +
+
+
message CounterEntry {
+  uint32 counter_id = 1;
+  Index index = 2;
+  CounterData data = 3;
+}
+

The CounterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the counter entries in the +array have default value 0. +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect counter instance whose unique id is counter_id +and array index is specified by index. The counter value is set to the value +specified by the client in the data field. Note that the counter value is +not modified if this Protobuf field is not set. If index is omitted all +counter values in the array will be set to the value provided by the +client. The server must return INVALID_ARGUMENT for a negative index value +and OUT_OF_RANGE if the index value exceeds the size of the counter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a ReadRequest by including a CounterEntry +entity for each of the instances, specifying the counter_id and +index. Wildcard reads are also supported as follows. +

+
    +
  • +

    If the counter_id field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id counter_id. +

+

9.4. MeterEntry & DirectMeterEntry

+

Meters are an advanced mechanism for keeping statistics, involving stateful +“marking” and usually “throttling” of packets based on configured rates of +traffic. The PSA metering function is based on the Two Rate Three Color Marker +(trTCM) defined in RFC 2698 [2]. The trTCM meters an arbitrary packet +stream using two configured rates the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes and +“marks” its packets as GREEN, YELLOW or RED based on the observed rate. +

+

MeterEntry & DirectMeterEntry have an additional field counter_data that +may hold per color counter data for targets that support it, and that must +always be unset for targets that do not support it. If set in a request and +unsupported by a target, an UNIMPLEMENTED error code should be returned. +These counters provide a granular list of the counters applicable to the +possible meter colors GREEN, YELLOW and RED. The counter associated with a +specific color is incremented when a packet is “marked” with that color. The +primary purpose of the color counters is for debugging purposes. +

+

A meter may be configured as a direct or indirect instance, similar to a +counter. The MeterConfig P4Runtime message represents meter configuration. +

+
+
+
message MeterConfig {
+  int64 cir = 1;  // Committed Information Rate
+  int64 cburst = 2;  // Committed Burst Size
+  int64 pir = 3;  // Peak Information Rate
+  int64 pburst = 4;  // Peak Burst Size
+}

9.4.1. DirectMeterEntry

+

A direct meter is a direct resource associated with a TableEntry (see Direct +resources). The meter_config field of the TableEntry +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +DirectMeterEntry message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed. +

+
+
+
message DirectMeterEntry {
+  TableEntry table_entry = 1;
+  MeterConfig config = 2;
+  MeterCounterData counter_data = 3;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectMeterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match the match key of the TableEntry +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching TableEntry is not found, +the server returns the error code NOT_FOUND. +

  • +
  • +

    config is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets). +

  • +
  • +

    counter_data is used to set the per color counter values to the default +value of (0), which is essentially clearing the counters. If the field is +unset, the counter values are left untouched. If the field is set, targets +supporting these counters should reset all the color counters to (0), if any +of the sub-fields are set to a non-zero value, then an INVALID_ARGUMENT +error should be returned. +

+ +

Specifying DirectMeterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read a DirectMeter config. +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the meter config in the meter_config field of the TableEntry +message (see Direct resources). +

  • +
  • +

    Explicitly request the meter configuration by including the DirectMeterEntry +in the ReadRequest. The table_entry.match field must match the +TableEntry whose meter config is being read. If no such entry is found, the +server returns the error code NOT_FOUND. Read responses also include the +per color counter data for the meter entry, if supported and specified in +the request message. +

+

9.4.2. MeterEntry

+

An indirect or indexed meter is not associated with a specific TableEntry and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime MeterEntry message whose fields are defined as +follows: +

+
    +
  • +

    meter_id is a uint32, the unique identifier for the meter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +a meter array. +

  • +
  • +

    config is a Protobuf message of type MeterConfig, which represents the +meter configuration. +

  • +
  • +

    counter_data is a Protobuf message of type MeterCounterData, which +represents the per color counter values associated with the corresponding +meter. +

+ +
+
+
message MeterEntry {
+  uint32 meter_id = 1;
+  Index index = 2;
+  MeterConfig config = 3;
+  MeterCounterData counter_data = 4;
+}
+

The MeterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the meter entries in the +array have a default configuration (GREEN for all packets). +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect meter instance whose unique id is meter_id and +array index is specified by index. The meter is reconfigured using the +config field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the index field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if config is unset). The server must return INVALID_ARGUMENT for a +negative index value and OUT_OF_RANGE if the index value exceeds the size of +the meter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a ReadRequest by including a MeterEntry entity for each +of the instances, specifying the meter_id and index. Wildcard reads are also +supported as follows: +

+
    +
  • +

    If the meter_id field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id meter_id. +

+

9.4.3. MeterCounterData

+

The MeterCounterData P4Runtime message represents the per color counters +associated with a meter entry. Whenever a meter is executed and returns +a color, the corresponding color counter GREEN, YELLOW or RED is updated. +

+

As seen above, these counters can be associated with a DirectMeterEntry or +MeterEntry. Targets not capable of supporting these counters should return +UNIMPLEMENTED if a MeterCounterData field was set in a read or write +request. +

+
+
+
message MeterCounterData {
+  CounterData green = 1;
+  CounterData yellow = 2;
+  CounterData red = 3;
+}

9.5. PacketReplicationEngineEntry

+

The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets. +

9.5.1. MulticastGroupEntry

+

Multicasting is achieved in PSA programs by setting the multicast_group +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the MulticastGroupEntry API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example. +

+
+
+
control arp_multicast(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ethernet.isValid() &&
+        hdr.ethernet.eth_type == ETH_TYPE_ARP) {
+      smeta.multicast_group = (MulticastGroup_t) 1;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    multicast_group_entry {
+      multicast_group_id: 1
+      replicas { egress_port: 5 instance: 1 }
+      replicas { egress_port: 12 instance: 2 }
+      replicas { egress_port: 18 instance: 3 }
+      replicas { egress_port: 24 instance: 4 }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +PSA Metadata Translation section. +

+

The egress packets may be distinguished for further processing in the egress +using the instance metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 multicast_group metadata is set to a value that is not +programmed in the PRE, then the packet is dropped. +

+

A multicast group may be inserted, modified or deleted as per the following +semantics. +

+
    +
  • INSERT: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The multicast_group_id field is a uint32 and must be greater +than 0 (see explanation below), or the +P4Runtime server must return an INVALID_ARGUMENT error. The replica +instance ID is also a uint32, and its value may not exceed the maximum +allowed by the target for the EgressInstance_t type (0 is allowed), or the +server must return an INVALID_ARGUMENT error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of both egress_port and instance, or the server +must return INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify the set of replicas for a given multicast group entry, +indexed by the given multicast_group_id. Same restrictions as INSERT apply +here. +
  • +
  • DELETE: Delete the multicast group indexed by the given +multicast_group_id. The replicas need not be provided for this +operation. Any packets with their multicast_group metadata in the data plane +set to the deleted multicast_group_id will be dropped. +
+ +

When reading a multicast group, only multicast_group_id is considered. All +other fields in MulticastGroupEntry are ignored. To perform a wildcard +Read on all configured multicast group entries, the multicast_group_id field +must be set to 0, its default value. +

9.5.1.1. Valid Values for multicast_group_id
+

The PSA specification states that the valid data plane values for multicast +group ids (MulticastGroup_t) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target [24]. This means that, in the absence of +translation, the client must set the multicast_group_id field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special wildcard value which is used to read all the multicast groups +configured in the target, the multicast_group_id field must never be set to 0 +when performing a Write RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value. +

9.5.2. CloneSessionEntry

+

PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +clone_session_id identifier and a boolean flag clone in the packet +metadata. The clone_session_id serves as a handle to the clone attributes, +namely a set replicas of (egress port, instance) pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +CloneSessionEntry API. +

+

The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the clone_low_ttl control block is applied in the ingress +pipeline to create an ingress-to-egress clone. +

+
+
+
control clone_low_ttl(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ipv4.isValid() &&
+        hdr.ipv4.ttl <= LOW_TTL_THRESHOLD) {
+      smeta.clone_session_id = 10w100;
+      smeta.clone = true;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    clone_session_entry {
+      session_id: 100
+      replicas { egress_port: 0xfffffffd instance: 1 } # to CPU
+      class_of_service: 2
+      packet_length_bytes: 4096
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type CloneSessionId_t [24]). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes. +

+

The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port 0xfffffffd; see +Translation of Port Numbers). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port. +

+

If the clone_session_id data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created. +

+

A clone session may be inserted, modified or deleted as per the following +semantics: +

+
    +
  • INSERT: Add a new clone session entry bound to a set of egress ports and +replica IDs. The session_id is a uint32 and must be greater than 0 (see +explanation below), or the P4Runtime +server must return an INVALID_ARGUMENT error. The replica instance ID is +also a uint32, and its value may not exceed the maximum allowed by the +target for the EgressInstance_t type (0 is allowed), or the server must also +return an INVALID_ARGUMENT error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (class_of_service field). This value must be a valid +value for the PSA ClassOfService_t type, which supports runtime translation +by default [24], or the server must return +INVALID_ARGUMENT. See PSA Metadata +Translation for more information. The +packet_length_bytes field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +packet_length_bytes field is 0 (default), no truncation on the clone will be +performed. +
  • +
  • MODIFY: Modify the attributes of a given clone session entry, indexed by the +given clone_session_id. Same restrictions as INSERT apply here. +
  • +
  • DELETE: Delete the clone session indexed by the given +clone_session_id. Other fields need not be provided for this operation. Any +packet with their clone_session_id metadata in the data plane set to the +deleted session_id will no longer be cloned. +
+ +

When reading a clone session, only session_id is considered. All other fields +in CloneSessionEntry are ignored. To perform a wildcard Read on all +configured clone session entries, the session_id field must be set to 0, its +default value. The session_id field can never be equal to 0 in a Write +RPC. If it does, the server must return an INVALID_ARGUMENT error. +

9.5.2.1. Valid Values for session_id
+

The PSA specification states that the valid data plane values for clone +session ids (CloneSessionId_t) range from 0 to the maximum value supported by +the target [24]. Note that unlike for multicast group +ids, 0 is a valid data plane value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special wildcard value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a session_id +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is not enabled, we effectively +“lose” one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (e.g. because the target supports a very +limited number of clone sessions), one can enable translation on +CloneSessionId_t and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id. +

9.6. ValueSetEntry

+

Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the parse_trill_types state. +

+
+
+
state parse_l2 {
+  @id(1) value_set<ETH_TYPE_BITWIDTH>(MAX_TRILL_TYPES) trill_types;
+  extract(hdr.ethernet);
+  select (hdr.ethernet.eth_type) {
+    ETH_TYPE_IPV4: parse_ipv4;
+    ETH_TYPE_IPV6: parse_ipv6;
+    trill_types:   parse_trill_types;
+    _:             reject;
+  }
+}
+

The corresponding entry in the P4Info for this Value Set is: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "trill_types"
+  }
+  match {
+    id: 1
+    bitwidth: <ETH_TYPE_BITWIDTH>
+    match_type: EXACT
+  }
+  size: <MAX_TRILL_TYPES>
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0x22f3 }
+      }
+      match {
+        field_id: 1
+        exact { value: 0x893b }
+      }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the parse_trill_types state. +

+

A ValueSetEntry entity update message has the following fields: +

+
    +
  • +

    value_set_id is the uint32 identifier of the Value Set instance, as +defined in P4Info. +

  • +
  • +

    members is a repeated field of type ValueSetMember. When “selecting” +against a Value Set, every member will be considered and if at least one +“matches”, the corresponding parser transition will be taken. Each +ValueSetMember contains a repeated field of FieldMatch messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a ValueSetMember if and only if +it matches all its FieldMatch messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. FieldMatch messages in a ValueSetEntry follow +the same rules as in a TableEntry. +

+ +

A ValueSetEntry may only be modified. If the update type is INSERT or +DELETE, the server must return an INVALID_ARGUMENT error. If the update type +is MODIFY, the server writes the members given in the repeated field to the +Value Set entry indexed by the given value_set_id. The maximum number of +matches must not exceed the maximum size given by the size field in P4Info of +the Value Set, otherwise the server must return a RESOURCE_EXHAUSTED error. To +empty a Value Set (i.e. restore it to its initial state), the P4Runtime client +can perform a MODIFY update with an empty members repeated field. +

+

To facilitate read-write symmetry, the server must +return an ALREADY_EXISTS error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set. +

+

See Appendix A.3 for a more complex Value Set example. +

9.7. RegisterEntry

+

The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The RegisterEntry P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations. +

+

RegisterEntry has the following fields: +

+
    +
  • +

    register_id, which identifies the PSA Register extern instance which is +being accessed by the client; the register_id is specified by the P4Info +message. +

  • +
  • +

    index, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the RegisterEntry message +used for the request. When an index is provided , the server must validate +its value, and return INVALID_ARGUMENT for a negative index or +OUT_OF_RANGE if the index exceeds the size of the register array. +

  • +
  • +

    data: the data to be written to the array (if RegisterEntry is part of a +WriteRequest message) or the data read from the array (if RegisterEntry is +part of a ReadResponse message). The data field is a P4Data message and +must match the format described by the type_spec field of the corresponding +Register entry in the P4Info, or the server must return an INVALID_ARGUMENT +error. +

+

9.8. DigestEntry

+

A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly. +

+

The DigestEntry P4Runtime entity is used to configure how the device must +generate digest messages. The DigestEntry Protobuf message is not used to +carry digest data, which is done on the StreamChannel bidirectional stream +using the DigestList (digest data sent by the target to the client) and +DigestListAck (digest data acknowledgments sent by the client to the target) +Protobuf messages. +

+

In this section, we refer to the data learned by a single data plane call to +Digest<T>::pack as a “digest message” and we use “digest list” to designate +the list of digest messages bundled by the P4Runtime service in a single +DigestList stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are “duplicate” if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are “distinct” +if they are not duplicate. +

+

DigestEntry has the following fields: +

+
    +
  • +

    digest_id, which identifies the PSA Digest extern instance which emitted the +data; the digest_id is determined by the P4Info message. +

  • +
  • +

    config, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +digest_id; these parameters are: +

    +
      +
    • max_timeout_ns: the maximum server buffering delay in nanoseconds for an +outstanding digest message. +
    • +
    • max_list_size: the maximum digest list size in number of digest +messages sent by the server to the client as a single DigestList +Protobuf message. +
    • +
    • ack_timeout_ns: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data. +
    +
+ +

Here is the significance of the different Update types for DigestEntry: +

+
    +
  • INSERT: Enable server generation of DigestList messages for given digest +instance and use provided configuration parameters. +
  • +
  • MODIFY: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance. +
  • +
  • DELETE: Disable server generation of DigestList messages for given digest +instance. +
+ +

A server should buffer digest messages until either: +

+
    +
  • max_timeout_ns time has passed since the first digest message was added to +the empty buffer, or +
  • +
  • max_list_size distinct digest messages have been received from the +data plane and added to the buffer +
+ +

At which point the server should, with best effort, generate a DigestList +stream message with the buffer contents and send it to the primary client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software. +

+

To avoid sending duplicate digest messages across different DigestList +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the primary client indicates that it has received the +digest list and acted on it. The server must keep a “cache” containing the set +of all digest messages that have been sent, but not acknowledged yet by the +primary client, up-to ack_timeout_ns in the past. The server must delete all +cache entries for a given digest list when they are at least ack_timeout_ns +old or when a matching DigestListAck message (i.e. with the same digest_id +and list_id fields as the DigestList message) is received. +

+

The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged DigestList messages. +

+

When max_timeout_ns is set to 0 and / or max_list_size is set to 1, the +server should, with best effort, generate a DigestList message for every +digest message generated by the data plane which is not already in the cache. If +ack_timeout_ns is set to 0, the cache must always be an empty set. If +max_list_size is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +max_timeout_ns configuration parameter. +

+

The P4Runtime server may empty the digest message cache in case of a client +status change. +

+

Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server: +

+
+
+
DigestStream stream;
+DigestCache cache;
+DigestBuffer buffers;
+
+// sends digest list when it is ready
+send_buffer(Id digest_id) {
+  buffer = buffers[digest_id];
+  stream.write(DigestList(buffer));
+  cache.merge(buffer);  // updates cache with new digest list
+  buffer.clear();
+}
+
+// callback which handles data plane digest messages from device
+handle_dataplane_digest(Digest msg) {
+  digest_id = msg.digest_id();
+  buffer = buffers[digest_id];
+  if (msg in cache OR msg in buffer) return;
+  buffer.enqueue(msg);
+  if (buffer.length() < max_list_size(digest_id)) return;
+  send_buffer(digest_id);
+}
+
+// callback which handles ack messages received on the stream
+handle_stream_ack(DigestListAck ack) {
+  // clear all cache entries matching the tuple (digest_id, list_id)
+  cache.erase( (ack.digest_id(), ack.list_id() )
+}
+
+// loop to enforce timeouts
+while (true) {
+  now = now();
+  // check for buffers that need to be sent
+  for ((digest_id, buffer) in buffers) {
+    if (now - buffer.first_enq_time() >= max_timeout_ns(digest_id))
+      send_buffer(buffer_id);
+  }
+  // check for expired entries in cache
+  for ((digest_id, list_id, sent_time) in cache) {
+    if (now - sent_time >= ack_timeout_ns(digest_id))
+      cache.erase( (digest_id, list_id) );
+  }
+  sleep(X);
+}

9.9. ExternEntry

+

This is used to support a P4 extern entity that is not part of PSA. It is +defined as: +

+
+
+
message ExternEntry {
+  uint32 extern_type_id = 1;
+  uint32 extern_id = 2;
+  google.protobuf.Any entry = 3;
+}
+

Each ExternEntry entity maps to an Extern message in the +P4Info and an ExternInstance message within that +message. The extern_type_id field must be equal to the one in +ExternEntry. The extern_id field must be equal to the ID included in the +preamble of the corresponding ExternInstance message. +

+

entry itself is embedded as an Any Protobuf message [31] to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on Extending P4Runtime for non-PSA +Architectures for more information. +

10. Error Reporting Messages

+

P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case. +

+

gRPC uses grpc::Status [32] to represent the status returned by an +RPC. It has 3 attributes: +

+
+
+
StatusCode code_;
+grpc::string error_message_;
+grpc::string binary_error_details_;
+

The code_ represents a canonical error [34] and describes the +overall RPC status. The error_message_ is a developer-facing error message, +which should be in English. The binary_error_details_ carries a serialized +google.rpc.Status message [28] message, which has 3 fields: +

+
+
+
int32 code = 1;  // see code.proto
+string message = 2;
+repeated google.protobuf.Any details = 3;
+

The code and message fields must be the same as code_ and error_message_ +fields from grpc::Status above. The details field is a list that consists of +p4.Error messages that carry error details for individual elements inside +batch-request RPCs (e.g. Write and Read). p4.Error includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices [34]. +

+

Figure 7 illustrates how these messages fit together. +

+
+

error-report +

+
+ +
Figure 7. P4Runtime Error Report Message Format
+

gRPC provides utility functions ExtractErrorDetails() and SetErrorDetails() +[33] to easily convert between grpc::Status and +google.rpc.Status. +

+

Please see sections on individual P4Runtime RPCs for details on how +grpc::Status is populated for reporting errors. +

+

Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on Stream Error +Reporting for more information. +

11. Atomicity of Individual Write and Read Operations

+

Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane apply +operation, and every single Write operation on a table that inserts, deletes, +or modifies one table entry, the apply operation should behave as if that +Write operation has not yet occurred, or as if the Write operation is +complete. The P4 program should never behave as if the Write operation is +partially complete. These guarantees also apply to extern instances: Read and +Write operations on extern entities must execute atomically relative to extern +data plane methods. +

+

The atomicity guarantees provided by P4Runtime for individual Read and Write +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification [23]. +

+

The P416 language introduces an @atomic annotation [14], to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the @atomic annotation for Write +operations, as well as non-wildcard Read operations, +relative to data plane execution. Consider the following P4 example written for +PSA: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024) r1;
+
+  apply {
+    // ...
+    @atomic {
+        Value_t v = r1.read((Index_t)1);
+        v = v + 1;
+        r1.write((Index_t)1, v);
+    }
+  }
+}
+

If a P4Runtime server is processing messages which write to Register r1 at +index 1, these writes must not happen between the data plane read and +write. +

+

Now let's consider the following example: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024, (Value_t)0 /* initial value */) r1;
+
+  apply {
+    @atomic {
+        r1.write((Index_t)1, (Value_t)100);
+        r1.write((Index_t)2, (Value_t)100);
+    }
+    @atomic {
+        r1.write((Index_t)1, (Value_t)200);
+        r1.write((Index_t)2, (Value_t)200);
+    }
+  }
+}
+

If a P4Runtime client issues a wildcard Read on Register r1, there is no +guarantee that r1[1] == r1[2] in the response, as the read for r1[1] may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for r1[2] may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read r1[1] and r1[2] separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +ReadRequest message) of individual read requests. Similar to a batch +ReadRequest, a wildcard read of a register can execute the reads of the +register array elements (r1[1], r1[2], ) in an arbitrary order relative +to each other. +

+

If the @atomic annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program. +

12. Write RPC

+

The Write RPC updates one or more P4 entities on the target. The request is +defined as follows: +

+
+
+
message WriteRequest {
+  uint64 device_id = 1;
+  string role = 6;
+  Uint128 election_id = 3;
+  repeated Update updates = 4;
+  enum Atomicity {
+    CONTINUE_ON_ERROR = 0;
+    ROLLBACK_ON_ERROR = 1;
+    DATAPLANE_ATOMIC = 2;
+  }
+  Atomicity atomicity = 5;
+}
+

The device_id uniquely identifies the target P4 device. The role and +election_id define the client role and election-id as described in the +Primary-Backup Arbitration and Controller +Replication +section. The server is expected to perform the following checks (in this order) +before processing the updates list: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the primary for (device_id, role) according to +the election_id value, the server must return a PERMISSION_DENIED error. +

  4. +
  5. +

    If the Write is attempted before a ForwardingPipelineConfig has been set, +the server must return a FAILED_PRECONDITION error. +

+ +

The updates field is a list of P4 entity updates to be applied. Each update is +defined as: +

+
+
+
message Update {
+  enum Type {
+    UNSPECIFIED = 0;
+    INSERT = 1;
+    MODIFY = 2;
+    DELETE = 3;
+  }
+  Type type = 1;
+  Entity entity = 2;
+}
+

This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a logical table (e.g. +CounterEntry) or an actual table (e.g. TableEntry) in the P4 data +plane. Each entity in the container is uniquely identified by its key. Please +refer to the P4 Entity Messages section for details on +what parts of the entity specification make up the key for each P4 entity. +

+

An update can be one of the following types: +

+
    +
  • +

    INSERT: Inserts the given P4 entity in the entity container. +The entity field always specifies the full state of the P4 entity. +If the entity already exists, an ALREADY_EXISTS error is returned, and +the existing entity remains unchanged. If the entity is malformed, an +INVALID_ARGUMENT error is usually returned (unless a more specific error +code applies [34]). If the entity cannot be inserted because the +container is already full, a RESOURCE_EXHAUSTED error is returned. +

  • +
  • +

    MODIFY: Modifies the P4 entity to its new specified state. This uses +assign or full-snapshot semantics, i.e. the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an INVALID_ARGUMENT error is usually returned (unless a +more specific error code applies [34]). If the entity does not +exist, a NOT_FOUND error is returned. +

  • +
  • +

    DELETE: Deletes the specified P4 entity. If the entity does not exist, a +NOT_FOUND error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored. +

+ +

If an update is not allowed under the given controller role, the server must +return a PERMISSION_DENIED error for this update. +

12.1. Batching and Ordering of Updates

+

P4Runtime supports batching of Write operations. The list of updates in a +WriteRequest is referred to as a batch. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of TableEntry entities). +

+

The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +WriteRequests can also be processed interleaved and/or in parallel. +However, the processing of requests must be strictly serializable. That +is, given a history $S$ of WriteRequests including the responses to those +requests, there must exist an order $L$ for all updates in $S$, such that: +

+
    +
  1. All updates from the same write request must appear as a contiguous +subsequence in $L$, but the order within that subsequence can be arbitrary. +
  2. +
  3. For two updates $u_1$ and $u_2$, if the write request containing $u_1$ +completed before the write request of $u_2$ was sent, then $u_1$ must appear +before $u_2$ in $L$. +
  4. +
  5. Executing all updates in $L$ sequentially must yield the same response for +every update as in $S$. +
  6. +
  7. The observable state of the switch after $S$ (e.g., through the Read RPC) +is identical to the one obtained by sequentially executing $L$. +
+ +

The Write RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the Write RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (e.g. inserting an ActionProfileMember +followed by pointing a TableEntry to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding Write RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate Write calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each Write call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one. +

12.2. Batch Atomicity

+

A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the Atomicity +enum. A P4Runtime server is required to support only the modes marked as +Required below: +

+
    +
  • +

    Required: CONTINUE_ON_ERROR: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that see each of +these intermediate stages. +

  • +
  • +

    Optional: ROLLBACK_ON_ERROR: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is all-or-none, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that see each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure. +

    +

    If a P4Runtime server does not support this option at all, an +UNIMPLEMENTED error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (e.g. it is +more straightforward to implement batches that contain only INSERT +operations, vs. those that contain DELETE operations), an +UNIMPLEMENTED error is returned when the batch cannot be executed +in a data plane-atomic way. +

  • +
  • +

    Optional: DATAPLANE_ATOMIC: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +transaction. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane's table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table. +

    +

    If a P4Runtime server does not support this option at all, an UNIMPLEMENTED +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an UNIMPLEMENTED error is returned when the batch +cannot be executed in a data plane-atomic way. +

+ +

There is no expectation that a given client must always use the same Atomicity +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use DATAPLANE_ATOMIC at one time and default behavior +(CONTINUE_ON_ERROR) at other times. +

12.3. Error Reporting

+

Please see section Error Reporting Messages for +information on error reporting messages and guidelines. P4Runtime server will +populate grpc::Status as follows: +

+
    +
  1. +

    If all batch updates succeeded, set grpc::Status::code_ to OK and do not +populate any other field. +

  2. +
  3. +

    If an error is encountered before even trying to attempt individual batch +updates, set grpc::Status::code_ that best describes that RPC-wide +error. For example, use UNAVAILABLE if the P4Runtime service is not yet +ready to handle requests. Set error_message_ to describe the issue. Do not +set error_details in this case. +

  4. +
  5. +

    Otherwise, if one or more updates in the batch (WriteRequest.updates) +failed, set grpc::Status::code_ to UNKNOWN. For example, one update in +the batch may fail with RESOURCE_EXHAUSTED and another with +INVALID_ARGUMENT. A p4.Error message is used to capture the status of +each and every update in the batch. The number of p4.Error messages packed +into google.rpc.Status.details field should therefore always match the +number of updates in the WriteRequest, and the order of +p4.Error messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +p4.Error should set the code to OK and omit other fields. +

+ +
+
+
# Example of a grpc::Status returned for a Write RPC with a batch of 3 updates.
+# The first and third updates encountered an error, while the second update
+# succeeded.
+code_ = 2  # UNKNOWN
+error_message_ = "Write failure."
+binary_error_details {
+  code: 2  # UNKNOWN
+  message: "Write failure."
+  details {
+    canonical_code: 8  # RESOURCE_EXHAUSTED
+    message: "Table is full."
+    space: "targetX-psa-vendorY"
+    code: 500  # ERR_TABLE_FULL
+  }
+  details {
+    canonical_code: 0  # OK
+  }
+  details {
+    canonical_code: 6  # ALREADY_EXISTS
+    message: "Entity already exists."
+    space: "targetX-psa-vendorY"
+    code: 600  # ERR_ENTITY_ALREADY_EXISTS
+  }
+}

13. Read RPC

+

The Read RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as: +

+
+
+
message ReadRequest {
+  uint64 device_id = 1;
+  string role = 3;
+  repeated Entity entities = 2;
+}
+

The device_id uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +NOT_FOUND error. +If the Read is attempted before ForwardingPipelineConfig has been set, the +server must return a FAILED_PRECONDITION error. +The role field acts as a filter, restricting the reported entities based on +the role to which the entity belongs. +The entities repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server. +

+

Since ReadRequests do not mutate any state on the switch, they do not +require an election_id, and they do not require the presence of an open +StreamChannel between the server and client. +

+

The Read response consists of a sequence of messages (a gRPC stream) with +each message defined as: +

+
+
+
message ReadResponse {
+  repeated Entity entities = 1;
+}
+

The entities repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the Finish() method on the stream object +[10]). +

13.1. Nomenclature

+
+
request
+
An element of the p4.ReadRequest.entities repeated field. +
+
batch
+
Refers to the p4.ReadRequest.entities repeated field.
+

Each request acts as a query filter for that entity type. If a request fully +specifies the entity key, the Read operation should retrieve a single P4 +entity. Please refer to the P4 Entity Messages section +for details on what parts of the entity specification make up the entity key. +

13.2. Wildcard Reads

+

P4Runtime allows wildcard read of P4 entities. A request may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the P4 Entity Messages section for details on +what parts of the entity can be wildcarded in a given request. +

+

For example, in a request of type CounterEntry: +

+
    +
  • A default counter_id (0) implies a request to read all counter-entries for +all indirect counters. +
  • +
  • A particular (non-default) counter_id in conjunction with index unset +implies a request to read all counter-entries for the given indirect counter +ID. +
+ +

To read the entire forwarding state for a given device, the P4Runtime client can +generate the following ReadRequest: +

+
+
+
device_id: <ID>
+entities {
+  extern_entry { }  # read all extern instances for all supported extern types
+  table_entry { }  # read all table entries for all tables
+  action_profile_member { }  # read all members for all action profiles
+  action_profile_group { }  # read all groups for all action profiles
+  ...
+}
+

The entity oneof field in the Entity message must always be set, or the +server must return an INVALID_ARGUMENT error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty Entity message in the ReadRequest. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the entity oneof [20]. +

13.3. Batch Processing

+

A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type request +appears only once in the batch. +

+

A P4Runtime server will process the batch as follows: +

+
    +
  1. +

    Lock state (preventing new writes) and validate each request in the batch: +

    +
      +
    1. +

      If it is a valid request, perform the read; +

      +
        +
      1. If the read was successful, return the entities read in +ReadResponse stream. +
      2. +
      3. If the read failed (exception / critical-error), prepare a p4.Error +with code set to INTERNAL. +
      +
    2. +
    3. +

      If the request is invalid (invalid-argument, not-supported, etc.), +prepare a p4.Error with relevant canonical code to capture the error. +

    +
  2. +
  3. +

    Unlock the state (allowing new writes); +

  4. +
  5. +

    Close the ReadResponse stream and return a grpc::Status as follows: +

    +
      +
    1. +

      If no errors were encountered, set code to OK and do not populate any +other field. +

    2. +
    3. +

      Otherwise, the overall code should be set to UNKNOWN. See section +Error Reporting Messages for information +on error reporting messages and guidelines. Assemble a list of p4.Error +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +google.rpc.Status.details field. This behavior also matches Write +RPC. +

    +
+

13.3.1. Example

+

If a client asked to read {a,b,c,d} and b and d requests didn't +validate, the server will return entities corresponding to a and c, followed +by a status {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} in the +details field. +

+

The P4Runtime server is not required to perform any optimization (e.g. merge two +requests in the batch if one is a subset of other). As a result of this, it +is possible for the ReadResponse to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging. +

+

There is no requirement that each request in the batch will correspond to one +ReadResponse message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit. +

+

A P4Runtime server must be prepared to handle multiple concurrent Read RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (e.g. in a single-threaded architecture), it may choose to serialize +Read RPC processing. +

13.4. Parallelism of Read and Write Requests

+

A P4Runtime server may be implemented to serve at most one +ReadRequest or WriteRequest message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so. +

+

For example, imagine a client that wanted to use WriteRequest +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +WriteRequest messages with only a few updates to an ActionSelector +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +WriteRequest batch currently being processed, but it will not +complete for a significant amount of time. +

+

The restrictions on which a client may rely are: +

+
    +
  • The processing of any two WriteRequest messages W1 and W2 must +result in the same state as if one of them was completed before the +other began. +
  • +
  • For any WriteRequest W and any ReadRequest R, R must +return results consistent with a state where W has completed +processing, or W has not yet begun processing. +
+ +

For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a WriteRequest message it acquired a write lock for each stateful +object affected by the WriteRequest, and before starting the +processing of a ReadRequest message it acquired a read lock for each +stateful object accessed by the ReadRequest, such an implementation +meets all of the requirements above. +

+

It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, e.g. if the server somehow determined that two +WriteRequest messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly. +

14. SetForwardingPipelineConfig RPC

+

A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the SetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message SetForwardingPipelineConfigRequest {
+  enum Action {
+    UNSPECIFIED = 0;
+    VERIFY = 1;
+    VERIFY_AND_SAVE = 2;
+    VERIFY_AND_COMMIT = 3;
+    COMMIT = 4;
+    RECONCILE_AND_COMMIT = 5;
+  }
+  uint64 device_id = 1;
+  string role = 6;
+  Uint128 election_id = 3;
+  Action action = 4;
+  ForwardingPipelineConfig config = 5;
+}
+

The server is expected to perform the following checks (in this order) +before performing the required action: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the primary for (device_id, role) according to +the election_id value, the server must return a PERMISSION_DENIED error. +

+ +

The action is the type of configuration action requested, it can be one of: +

+
    +
  • +

    VERIFY: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an INVALID_ARGUMENT +error if config is not provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_SAVE: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent Read / Write requests must refer to fields in the new +config. Returns an INVALID_ARGUMENT error if the forwarding config is not +provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_COMMIT: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an INVALID_ARGUMENT error if the forwarding config is not provided or if the +provided config cannot be realized. +

  • +
  • +

    COMMIT: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a NOT_FOUND error if no saved config +is found, i.e. if no VERIFY_AND_SAVE action preceded this one. Returns an +INVALID_ARGUMENT error if a config is provided with this message. +

  • +
  • +

    RECONCILE_AND_COMMIT: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an UNIMPLEMENTED error. For targets that support this option, an +INVALID_ARGUMENT error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target. +

+ +

The config field is a message of type ForwardingPipelineConfig that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(e.g. generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the Forwarding-Pipeline +Configuration section for details. +

+

A P4Runtime server running on a non-programmable device may not +support SetForwardingPipelineConfig (e.g. the forwarding-pipeline +config is part of the device's software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +UNIMPLEMENTED error. +

15. GetForwardingPipelineConfig RPC

+

The forwarding-pipeline configuration of the target can be retrieved by invoking +the GetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message GetForwardingPipelineConfigRequest {
+  enum ResponseType {
+    ALL = 0;
+    COOKIE_ONLY = 1;
+    P4INFO_AND_COOKIE = 2;
+    DEVICE_CONFIG_AND_COOKIE = 3;
+  }
+  uint64 device_id = 1;
+  ResponseType response_type = 2;
+}
+

The device_id uniquely identifies the target P4 device. A NOT_FOUND error is +returned if the device_id is not recognized by the P4Runtime server. +

+

The response_type is used to specify which fields to populate in the response, +its value can be one of: +

+
    +
  • +

    ALL: returns a ForwardingPipelineConfig with all fields +set as stored by the target. This is the default behaviour if the +response_type field is not set. +

  • +
  • +

    COOKIE_ONLY: reply by setting only the cookie field in the +ForwardingPipelineConfig, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message. +

  • +
  • +

    P4INFO_AND_COOKIE: reply by setting the p4info and cookie fields. +

  • +
  • +

    DEVICE_CONFIG_AND_COOKIE: reply by setting the p4_device_config and +cookie fields. +

+ +

The response contains the ForwardingPipelineConfig for the specified device: +

+
+
+
message GetForwardingPipelineConfigResponse {
+  ForwardingPipelineConfig config = 1;
+}
+

If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level config field will be unset in the response. Examples are +(i) a server that only allows configuration via SetForwardingPipelineConfig +but this RPC hasn't been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn't yet occurred. +

+

Once a forwarding-pipeline config is installed on the device (either via +SetForwardingPipelineConfig or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +config.p4_device_config will be empty / unset in the response, even if +response_type in the request was set to ALL. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the SetForwardingPipelineConfig RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +SetForwardingPipelineConfig, the value of config.cookie will be unset. +

+

If a P4Runtime server supports both SetForwardingPipelineConfig as well as +returning the p4_device_config, there should be read-write symmetry between +SetForwardingPipelineConfig and GetForwardingPipelineConfig RPCs. +

16. P4Runtime Stream Messages

16.1. Packet I/O

+

P4Runtime supports controller packet-in and packet-out by means of PacketIn +and PacketOut stream messages, respectively. +

+

PacketIn messages are sent by the P4Runtime server to the client. Conversely, +PacketOut messages are sent by the client to the server. Any PacketOut +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a StreamMessageResponse message with the error field set to +report the error to the client. See the section on Stream Error +Reporting for more information on error. +

+

As introduced in the ControllerPacketMetadata +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with @controller_header. The expected metadata is described +in the P4Info using the ControllerPacketMetadata messages. +

+

Both PacketIn and PacketOut stream messages share the same fields and are +defined as follows: +

+
+
+
// Packet sent from the controller to the switch.
+message PacketOut {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+// Packet sent from the switch to the controller.
+message PacketIn {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+message PacketMetadata {
+  // This refers to Metadata.id coming from P4Info ControllerPacketMetadata.
+  uint32 metadata_id = 1;
+  bytes value = 2;
+}
+
    +
  • +

    payload is used to carry the full packet content, including the headers. +

  • +
  • +

    metadata is a repeated field of PacketMetadata messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +ControllerPacketMetadata. Indeed, when a P4Runtime client (or server) +generates a PacketOut (or PacketIn) message, it needs to populate the +metadata field with as many values as in ControllerPacketMetadata.metadata +for the packet-out (or packet-in) case. Each PacketMetadata.value is a +binary string and must conform to the Bytestrings +requirements based on the corresponding P4Info +ControllerPacketMetadata.metadata specification. If the metadata field +does not match the P4Info specification, the server must drop the PacketOut +message and may generate a StreamMessageResponse message with the error +field set to report the error to the client which issued the PacketOut. See +the section on Stream Error Reporting for more +information on error. +

+

16.2. Client Arbitration Update

+

P4Runtime's client arbitration mechanism ensures that only the current primary +can modify state on the switch, and that the election_id is monotonically +increasing. For example, the switch must finish all previous write operations +before before selecting a different primary, and must only accept write requests +from the current primary. +

+

As explained earlier in this document, the controller uses the StreamChannel +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via Write RPC), +it needs to start a controller session and become a “primary”. To do so, the +controller first opens a bidirectional stream channel to the server via +StreamChannel for each device and sends a StreamMessageRequest message. The +controller populates the MasterArbitrationUpdate field in this message using +its role and election_id and the device_id of the device, as explained +in detail in the Client Arbitration and Controller +Replication +section. For any given (device_id, role), the P4Runtime server keeps track +of the highest election_id that it has ever received. If a controller's +election_id is equal to the highest election_id that the server has ever +received, that controller is the primary. All other controllers are backups. +Note that it is possible that all controllers are backups, and that there is no +primary. There can be at most one primary, because for any given +(device_id, role), each connected controller has a unique election_id. +

+

This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest election_id after such a restart. +However, across a full restart, the election_id must be +reset. In fact, a full restart is the only way to reset the election_id. +

+

The MasterArbitrationUpdate message is defined as follows: +

+
+
+
message MasterArbitrationUpdate {
+  uint64 device_id = 1;
+  // The role for which the primary client is being arbitrated. For use-cases
+  // where multiple roles are not needed, the controller can leave this unset,
+  // implying default role and full pipeline access.
+  Role role = 2;
+  // The stream RPC with the highest election_id is the primary. The 'primary'
+  // controller instance populates this with its latest election_id. Switch
+  // populates with the highest election ID it has received from all connected
+  // controllers.
+  Uint128 election_id = 3;
+  // Switch populates this with OK for the client that is the primary, and
+  // with an error status for all other connected clients (at every primary
+  // client change). The controller does not populate this field.
+  .google.rpc.Status status = 4;
+}
+
+message Role {
+  // Uniquely identifies this role.
+  string name = 3;
+  // Describes the role configuration, i.e. what operations, P4 entities,
+  // behaviors, etc. are in the scope of a given role. If config is not set
+  // (default case), it implies all P4 objects and control behaviors are in
+  // scope, i.e. full pipeline access. The format of this message is
+  // out-of-scope of P4Runtime.
+  .google.protobuf.Any config = 2;
+}
+

Note that the status field in the MasterArbitrationUpdate message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a StreamMessageResponse message back to the controller, in which +it populates the MasterArbitrationUpdate message using the device_id, +role, and election_id it previously received from the controller. The server +also populates the status field in the MasterArbitrationUpdate according to +the rules in an earlier section. +

+

The sender need not specify an election_id. If the election_id is not +specified, the sender's election_id is considered lower than any +election_id, and the sender will thus never become primary. This way, a +controller can choose to be a backup controller, in order to avoid +“flapping” (if a backup controller connects to the switch shortly before the +actual primary controller, therefore becoming primary temporarily). +

16.3. Digest Messages

+

See the DigestEntry section. +

16.4. Table Idle Timeout Notification

+

When a table supports idle timeout (as per the P4Info message), the primary +client can specify a TTL value for each entry in the table (see +Idle-timeout section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an IdleTimeoutNotification message on the +StreamChannel bidirectional stream to the primary client. The primary client +can then take the action of its choice, most likely remove the idle entry. +

+

The IdleTimeoutNotification Protobuf message has the following fields: +

+
    +
  • +

    timestamp: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server's local clock. +

  • +
  • +

    table_entry: a repeated field of entries which have expired. Each individual +entry is identified by a single TableEntry message. For each TableEntry, +the key fields (table_id, match and priority) must be set, along with +the controller_metadata field, the metadata field, and the +idle_timeout_ns field. Other fields may be set by the server but should be +ignored by the client. +

+ +

Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +IdleTimeoutNotification message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an IdleTimeoutNotification +message with an empty table_entry repeated field. +

+

After generating an idle notification, the P4Runtime server must “reset” the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the primary client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle. +

+

Here is a reasonable pseudo-code implementation for idle timeout for table +entries: +

+
+
+
IdleTimeoutStream stream;
+
+scanning_interval = 10ms;
+
+while (true) {
+  // iterate over all tables which support idle timeout
+  for (table in tables) {
+    if (!table.idle_timeout_supported) continue;
+    // we coalesce all idle notifications for the same table in one
+    // message
+    IdleTimeoutNotification msg;
+    // read time_since_last_hit from device
+    entries = device.load_table_entries_from_hw(table);
+    for (entry in entries) {
+      if (entry.idle_timeout == 0) continue;  // no TTL
+      if (entry.time_since_last_hit < entry.idle_timeout) continue;
+      msg.table_entry_add(entry);
+      entry.reset_time_since_last_hit();
+    }
+    if (msg.table_entry_size() == 0) continue;  // no notifications
+    msg.set_timestamp(now());
+    stream.write(msg);
+  }
+  sleep(scanning_interval);
+}

16.5. Architecture-Specific Notifications

+

P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on StreamChannel, by including an Any Protobuf field [31] +named other in both StreamMessageRequest and StreamMessageResponse. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the PSA Digest +extern. See section on Extending P4Runtime for non-PSA +Architectures for more information. +

16.6. Stream Error Reporting

+

The P4Runtime server can asynchronously report errors which occur when +processing StreamMessageRequest messages, using the error message field (of +type StreamError) in StreamMessageResponse. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature. +

+

The StreamError message has the following fields: +

+
    +
  • canonical_code, which must be set to the appropriate canonical error code +[34]. +
  • +
  • message, an optional developer-facing error message describing the error. +
  • +
  • space and code, which are optional and can be used by vendors to provide +additional details on the error. code is a numeric error code drawn from a +vendor's chosen error space. +
  • +
  • details, which is a Protobuf oneof used to help the client identify which +StreamMessageRequest triggered the error. The server is required to set the +appropriate field in the oneof so that the client can identify which type +of stream message is responsible for the error (packet_out, +digest_list_ack or other), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid PacketOut message from the +client, the packet_out field (of type PacketOutError) should be set in +the details oneof, and the server may additionally set the packet_out +field in the PacketOutError sub-message (by copying it from the invalid +PacketOut message received on the stream channel) so that the client can +know exactly what packet-out triggered the error. +
+ +

The appropriate canonical error code [34] should be used when +populating the canonical_code field. For example: +

+
    +
  • if a controller is not allowed to send a PacketOut message under its +current role definition, the code should be set to PERMISSION_DENIED. +
  • +
  • if the metadata repeated field in PacketOut does not match the P4Info +definition, the code should be set to INVALID_ARGUMENT. It may be useful +for the server to set the packet_out field in this case, so that the client +can find out which set of metadata fields triggered the error. +
  • +
  • if the digest_id field in DigestListAck does not match any Digest entry +in P4Info, the code should be set to INVALID_ARGUMENT. +
+ +

The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, e.g. because of a +burst of PacketIn messages. +

+

Note that client arbitration errors are never reported using the StreamError +message. Invalid MasterArbitrationUpdate messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section 5.3. +

16.6.1. Examples of StreamError Messages

+
    +
  • +

    Malformed packet-out metadata. If the server receives a PacketOut +message with a metadata field with id 7 which is not included in the P4Info +ControllerPacketMetadata message for “packet_out”, the server may send the +following StreamMessageResponse back to the client: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Unknown metadata field id 7."
    + packet_out {
    +   # copied from the PacketOut message received from the client
    +   packet_out {
    +     payload: ...
    +     metadata {
    +       id: 7
    +       name: "I_should_not_be_here"
    +       bitwidth: 32
    +     }
    +     # more metadata
    +   }
    + }
    +}
  • +
  • +

    Packet-out which exceeds the MTU. If the server receives a PacketOut +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following StreamMessageResponse: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Packet exceeds the MTU for port."
    + space: "targetX-psa-vendor1"
    + code: 123  # MTU_EXCEEDED
    + packet_out {
    +   # we do not set the packet_out field as it does not provide any
    +   # extra information to the client
    + }
    +}
+

17. Capabilities RPC

+

The Capabilities RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the CapabilitiesRequest message is empty and the CapabilitiesResponse +message only includes the p4runtime_api_version string field. This field must +be set to the full semantic version string [27] corresponding to the +version of the P4Runtime API implemented by the server, e.g. “1.1.0-rc.1”. +

+

Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three atomicity +modes for WriteRequest batches, two of them being +optional. In the future we may decide to leverage the CapabilitiesResponse +message to enable the server to report to the client which subset of these +atomicity modes is supported. +

+

The semantic version string included in CapabilitiesResponse can be used by +the client to determine which exact feature set is implemented by the server, +since minor releases may introduce new +functionality. However, because the Capabilities RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (i.e. an UNIMPLEMENTED error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0). +

18. Portability Considerations

18.1. PSA Metadata Translation

+

The Portable Switch Architecture (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +[24]. For such metadata, a translation between the controller's +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the @p4runtime_translation annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture. +

+
+

psa-metadata-translation +

+
+ +
Figure 8. P4Runtime Metadata Translation for the Portable Switch Architecture
+

Figure 8 illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller's 32 bit port +numbers to a target's 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch. +

18.1.1. Translation of Port Numbers

+

In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller's space and the PSA device's space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +user-defined P4 types, namely PortId_t and +PortIdInHeader_t, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in psa.p4 for +the PSA device in Switch 1. +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type bit<9> PortId_t;
+@p4runtime_translation("p4.org/psa/v1/PortIdInHeader_t", 32)
+type bit<32> PortIdInHeader_t;
+

The first argument to the @p4runtime_translation annotation is a URI that +indicates to the P4Runtime server which numerical mapping provided by the +out-of-band switch configuration mechanism to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports). +

+

An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows: +

+
+
+
enum SdnPort {
+  SDN_PORT_UNSPECIFIED = 0;
+
+  // SDN ports are numbered starting from 1.
+  SDN_PORT_MIN = 1;
+
+  // The maximum value of an SDN port (physical or logical).
+  SDN_PORT_MAX = 0xfffffeff;
+
+  // Reserved SDN port numbers (0xfffffff0 - 0xffffffff)
+
+  SDN_PORT_RECIRCULATE = 0xfffffffa;
+  SDN_PORT_CPU = 0xfffffffd;
+}
+

The switch config will map SDN_PORT_RECIRCULATE and SDN_PORT_CPU as well +as any SDN port number corresponding to a “regular” front-panel port to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation. +

+

The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs. +

18.1.2. Translation of Packet-IO Header Fields

+

Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  PortIdInHeader_t egress_port;
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  PortIdInHeader_t ingress_port;
+}
+

The header-level annotation @controller_header is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (egress_port) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI first argument to the @p4runtime_translation +annotation). Any subsequent reference to the egress_port field in the +data plane will use the translated value. PortIdInHeader_t is used in the +header definition instead of PortId_t to guarantee byte-aligned headers in +case this is required by the target. +

+

A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target's PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the ingress_port field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller. +

18.1.3. Translation of Match Fields

+

Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table's match key as shown in the example below: +

+
+
+
table t {
+  key = {
+    istd.ingress_port: exact;  // PSA standard metadata ingress port
+  }
+  actions = {
+    drop;
+  }
+}
+

Table t has an exact match on PSA standard metadata ingress port +(istd.ingress_port). Since the field is of type PortId_t, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in t from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table t is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values. +

+

Note that it may be infeasible to translate the value-mask pair for ternary +matches: LPM, TERNARY or RANGE match kinds. The P4Runtime server may +require that for these match kinds the port match be either de facto “exact” +(0xffffffff mask for TERNARY, prefix-length of 32 for LPM, or same low and +high bounds for RANGE) or “don't care”. +

18.1.4. Translation of Action Parameters

+

PortId_t type parameters can be part of a P4 action definition as shown in the +example below: +

+
+
+
action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+}
+
+table t {
+  key = {
+    hdr.h.f: exact;
+  }
+  actions = {
+    a;
+  }
+}
+

The controller may write entries in table t with action a to set the egress +port as shown in the P4 code above. The action parameter p is of type +PortId_t, which leads to a 32-bit bitwidth for p being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device. +

18.1.5. Port Translation for PSA Extern APIs

+

The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch_port +field is of type bytes to carry the SDN representation of the port being +watched. The P4Runtime server will translate the given watch port into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device. +

+

The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type uint32 to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane. +

18.1.6. Using Port as an Index to a Register, Indirect Counter or Indirect Meter

+

P4Runtime supports using a translated value (PortId_t or any other translated +type for which the underlying built-in type is bit<W>) as an index to a +register, indirect counter, or indirect meter. +

+
+
+
Counter<bit<32> /* counter entry type */, PortId_t /* index type */>(
+  32w1024, PSA_CounterType_t.PACKETS) counter;
+action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+  counter.count(p);
+}
+

This P4 Counter declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
counters {
+  preamble {
+    id: 0x12000001
+    name: "counter"
+  }
+  spec {
+    unit: PACKETS
+  }
+  index_type_name {
+    name: "PortId_t"
+  }
+}
+

The controller may read and write counter values from indexed counter counter +using SDN port numbers as indices, and not device-specific port numbers. The +index_type_name field in the P4Info message is a signal to the P4Runtime +server that translation is required. +

19. P4Runtime Versioning

+

P4Runtime follows the Google guidelines for versioning cloud APIs +[6]. We use a MAJOR.MINOR.PATCH style version number scheme and +we increment the: +

+
    +
  • MAJOR version when we make incompatible API changes, +
  • +
  • MINOR version when we add functionality in a backwards-compatible manner, +
  • +
  • PATCH version when we make backwards-compatible bug fixes. +
+ +

The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is p4.v1 and the package +name for P4Info is p4.config.v1. Even though p4 and p4.config are two +different Protobuf packages, p4 depends on p4.config and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence. +

+

As recommended in [6], we may consider using pre-GA release +suffixes (such as alpha or beta) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1). +

+

Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner. [7] describes +what constitute a backwards-compatible change. We expect MAJOR version bumps +to be a rare event. +

+

Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor + patch version numbers in future releases. +

+

All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository [15] and the version label follows +semantic versioning rules [27]. +

20. Extending P4Runtime for non-PSA Architectures

+

P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place. +

+

When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names: +

+
    +
  • p4/[organization]/arch/config/<major version>/p4info.proto +
  • +
  • p4/[organization]/arch/<major version>/p4runtime.proto +
+ +

We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they “extend”. +

+

For the remainder of this section, we will refer to these two files as +p4info-ext and p4runtime-ext respectively. +

20.1. Extending P4Runtime for Architecture-Specific Externs

+

Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both p4info-ext and +p4runtime-ext. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example: +

+
+
+
// T must be a bit<W> type, it indicates the width of each counter cell
+extern MyNewPacketCounter<T> {
+  counter(bit<32> size);
+  increment(in bit<32> index);
+}

20.1.1. Extending the P4Info message

+
    +
  • Id prefixes 0x81 through 0xfe are reserved for architecture-specific +externs. It is recommended that p4info-ext include a P4Ids message based +on the one in p4info.proto that the P4 compiler can refer to when assigning +IDs to each extern instance. +
+ +
+
+
message P4Ids {
+  enum Prefix {
+    UNSPECIFIED = 0;
+    MY_NEW_PACKET_COUNTER = 0x81;
+  }
+}
+
    +
  • p4info-ext should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +p4.config.v1.ExternInstance message as the info +field, which is of type Any [31]. +
+ +
+
+
message MyNewPacketCounter {
+  // corresponds to the T type parameter in the P4 extern definition
+  p4.config.v1.P4DataTypeSpec type_spec = 1;
+  // constructor argument
+  int64 size = 2;
+}

20.1.2. Extending the P4Runtime Service

+

Just like p4info-ext, p4runtime-ext should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an ExternEntry message generated by the +P4Runtime client. +

+

Here is a possible Protobuf message for our MyNewPacketCounter P4 extern: +

+
+
+
// This message enables reading / writing data to the counter at the provided
+// index
+message MyNewPacketCounter {
+  int64 index = 1;
+  p4.v1.P4Data data = 2;
+}
+

P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an Any Protobuf field [31] named other +in both p4.v1.StreamMessageRequest and +p4.v1.StreamMessageResponse. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in p4runtime-ext and embed instances of these messages in +p4.v1.StreamMessageRequest and p4.v1.StreamMessageResponse as appropriate. +

20.2. Architecture-Specific Table Extensions

20.2.1. New Match Types

+

An architecture may introduce new table match types [12]. P4Runtime +accounts for this by providing the following hooks: +

+
    +
  • +

    The match field in p4.config.v1.MatchField (p4info.proto) is a oneof +which can be either one of the default match types (EXACT, LPM, TERNARY, +RANGE, or OPTIONAL) or an architecture-specific match type encoded as a +string. +

  • +
  • +

    The field_match_type field in p4.v1.FieldMatch (p4runtime.proto) is a +oneof which includes an Any Protobuf message [31] field +(other). p4info-ext should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in p4.v1.FieldMatch as the +other field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info. +

+

20.2.2. New Table Properties

+

An architecture may introduce additional table properties +[30]. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +p4.config.v1.Table message includes the other_properties Any Protobuf +field [31]. At the moment, there is not any mechanism to extend the +p4.v1.TableEntry message based on the value of architecture-specific table +properties, but we may include on in future versions of the API. +

21. Known Limitations of Current P4Runtime Version

+
    +
  • +

    FieldMatch, action Param, and controller packet metadata fields only +support unsigned bitstrings, i.e. values of one of the following types (not +the more general P4Data): +

    +
      +
    • bit<W> +
    • +
    • bool. Note that as far as the P4Info message contents and +thus controller software is concerned, such fields of type bool +will be indistinguishable from those that have been declared with +type bit<1>. P4Runtime server software will automatically +perform any conversion needed between the type bit<1> values in +P4Runtime messages and the data plane representation. +
    • +
    • an enum with underlying type bit<W> +
    • +
    • a type or typedef with an underlying type that is one of the above (or +in general a “chain” of type and/or typedef that eventually ends with +one of the types above) +
    +
  • +
  • +

    Support for PSA Random & Timestamp externs is postponed to a future minor +version update. +

  • +
  • +

    P4Info does not include information about which of a table's actions execute +which direct resource(s). +

  • +
  • +

    The default action for indirect match tables is restricted to a const +NoAction known at compile-time. +

  • +
  • +

    There is no mechanism for changing the value of the psa_empty_group_action +table property at runtime. +

  • +
  • +

    There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor + +patch version numbers. +

+

A. Appendix

A.1. Revision History

A.1.1. Changes in v1.3.0

+
    +
  • Add IANA assigned TCP port, 9559, to P4Runtime server discussion. +
  • +
  • Move “Security considerations” section to P4Runtime server discussion. +
  • +
  • Deprecate watch field (int32) in favor of watch_port (bytes). This allows +using the watch port feature with the p4runtime_translation feature. +
  • +
  • Replace master, slave, master arbitration with more inclusive language: +primary, backup, and client arbitration +
  • +
  • Clarify that source locations for annotations are optional in the P4Info +message. +
+

A.1.2. Changes in v1.2.0

+
    +
  • Add new OPTIONAL match kind. At the moment, OPTIONAL is only supported by +the v1model architecture [38], and not by PSA. It will eventually be +included in the core P4 language. +
  • +
  • Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists. +
  • +
  • Add a new metadata field of type bytes to TableEntry. This is more +flexible than the now deprecated controller_metadata field. +
  • +
  • Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +@id annotation. +
  • +
  • Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature. +
  • +
  • Support using string as the controller type in the @p4runtime_translation +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type. +
  • +
  • Add optional P4 source locations to both structured and unstructured +annotations. +
+

A.1.3. Changes in v1.1.0

+
    +
  • Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously. +
  • +
  • Add error field to stream messages sent by the server. +
  • +
  • Add Capabilities RPC to query the P4Runtime API version implemented by the +server. +
  • +
  • Support wildcard reads for multicast groups and clone sessions. +
  • +
  • Support for modifying direct resources of const tables. +
  • +
  • Support P4 user-defined types for Packet IO metadata fields. +
  • +
  • Clarify consistency requirements for Write and Read RPCs. +
  • +
  • Add Appendix providing implementation advice for avoiding common pitfalls: + +
      +
    • advice on setting gRPC Metadata Maximum Size +
    • +
    • advice on setting gRPC Server Maximum Receive Message Size +
  • +
  • Clarify limitations on supported types for FieldMatch, action Param, and +Packet IO metadata fields. +
  • +
  • Clarify that reading entire forwarding state with empty entity is not +supported. +
  • +
  • Document that @p4runtime_translation need only be supported when applied to +type declarations in P4. +
+

A.2. P4 Annotations

+

Table 7 lists P416 annotations introduced primarily for +the purpose of adding features for the P4Runtime API. +

+
+ + + + + + + + + + +
Annotation Description
@brief See section 6.1.3
@controller_header See section 6.4.6
@description See section 6.1.3
@id See section 6.3
@max_group_size See sections 6.4.3, 9.2.2
@pkginfo See section 6.2.1
@p4runtime_translation See sections 8.5.6, 18.1.1
+
+ +
Table 7. P4 annotations introduced by P4Runtime

A.3. A More Complex Value Set Example

+

This section includes a more complex Value Set example, with multiple matches of +different kinds. +

+
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+

This P4 Value Set declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

A P4Runtime client can set the membership for this Value Set with WriteRequest +messages similar to this one: +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xac }
+      }
+      # match for field_id 2 is missing => don't care match
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xdc }
+      }
+      match {
+        field_id: 2
+        ternary { value: 0x88 mask: 8f }
+      }
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+  }
+}

A.4. Guidelines for Implementations

+

This section contains practical advice for implementing P4Runtime clients and +servers. +

A.4.1. gRPC Metadata Maximum Size

+

In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the grpc.max_metadata_size gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the Write P4Runtime RPC. The Write RPC +returns an individual error for every item in a batch (see Section +12), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +RESOURCE_EXHAUSTED error, without any of the individual errors. +

+

To fix this problem, one can set the grpc.max_metadata_size option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it's +limit, as only the receiving side's limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every p4.Error, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +8192 + MAX_UPDATES_PER_WRITE * 100 bytes of metadata. +

+

For example, in C++, one can create a client channel as follows: +

+
+
+
const int MAX_UPDATES_PER_WRITE = 100;
+::grpc::ChannelArguments arguments;
+arguments.SetInt(GRPC_ARG_MAX_METADATA_SIZE, 8192 + MAX_UPDATES_PER_WRITE*100);
+return grpc::CreateCustomChannel(address, credentials, arguments);

A.4.2. gRPC Server Maximum Receive Message Size

+

At the time of writing, the default maximum receive message size in gRPC is 4MB + while the default maximum send message size is unlimited. This can be a +problem for the SetForwardingPipelineConfig RPC, since for some targets the +binary p4_device_config can exceed 4MB, in which case by default the P4Runtime +server would return an INVALID_ARGUMENT error. To a lesser extent, this may +affect the Write RPC as well, in case of extremely large batches. +

+

To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of p4_device_config for their target(s). This can be done by +setting the grpc.max_receive_message_length when building the gRPC server. +

+

For example, in C++, one can set the maximum receive message size as follows: +

+
+
+
const int MAX_RECEIVE_MESSAGE_SIZE = 128 * 1024 * 1024;  // 128MB
+::grpc::ServerBuilder server_builder;
+builder.AddListeningPort(/*...*/);
+builder.RegisterService(/*...*/);  // register P4Runtime service
+builder.SetMaxReceiveMessageSize(MAX_RECEIVE_MESSAGE_SIZE);
+builder.BuildAndStart();
+

On the client side, we recommend that P4Runtime clients do not use Write +batches larger than the default maximum receive message size (4MB) in case +the server did not deem necessary to increase the default value , unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB). +

+

References

+
+ +
[2]“A Two Rate Three Color Marker.” https://​tools.​ietf.​org/​html/​rfc2698.
+ + + + +
[7]“Google Cloud APIs Versioning - Backwards-Compatibility.” https://​cloud.​google.​com/​apis/​design/​versioning#​backwards_​compatibility.
+ +
[9]“gRPC Main Site.” https://​grpc.​io.
+ + + + + +
[15]“p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” https://​github.​com/​p4lang/​p4runtime.
+
[16]“p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.” https://​github.​com/​p4lang/​PI.
+ + +
[19]“Portable Switch Architecture Specification (v1.1.0).” https://​p4.​org/​p4-​spec/​docs/​PSA-​v1.​1.​0.​html.
+ + + + + + + +
[27]“Semantic Versioning.” https://​semver.​org/​.
+ + + + + + + +
[35]“The OpenConfig Project.” http://​openconfig.​net.
+ +
[37]“The Stratum Project.” https://​stratumproject.​org/​.
+ +
+
+
+ +
+

1.an enum type used as a field in a header must specify a +underlying type and representation for enum elements. +

+ + + diff --git a/spec/v1.4.0-rc.2/P4Runtime-Spec.log b/spec/v1.4.0-rc.2/P4Runtime-Spec.log new file mode 100644 index 00000000..d145e021 --- /dev/null +++ b/spec/v1.4.0-rc.2/P4Runtime-Spec.log @@ -0,0 +1,14758 @@ +This is XeTeX, Version 3.14159265-2.6-0.99992 (TeX Live 2015/Debian) (preloaded format=xelatex 2018.8.17) 23 MAR 2022 19:30 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**build/P4Runtime-Spec.tex +(./build/P4Runtime-Spec.tex +LaTeX2e <2016/02/01> +Babel <3.9q> and hyphenation patterns for 81 language(s) loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2014/09/29 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo +File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@section=\count80 +\c@subsection=\count81 +\c@subsubsection=\count82 +\c@paragraph=\count83 +\c@subparagraph=\count84 +\c@figure=\count85 +\c@table=\count86 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) (build/madoko2.sty (/usr/share/texlive/texmf-dist/tex/latex/colortbl/colortbl.sty +Package: colortbl 2012/02/13 v1.0a Color table columns (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty +Package: array 2014/10/28 v2.4c Tabular extension package (FMi) +\col@sep=\dimen103 +\extrarowheight=\dimen104 +\NC@list=\toks14 +\extratabsurround=\skip43 +\backup@length=\skip44 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty +Package: color 2016/01/03 v1.1b Standard LaTeX Color (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package color Info: Driver file: xetex.def on input line 143. +(/usr/share/texlive/texmf-dist/tex/xelatex/xetex-def/xetex.def +File: xetex.def 2015/09/11 v4.06 LaTeX color/graphics driver for XeTeX (TeX Live/RRM/JK) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +))) +\everycr=\toks15 +\minrowclearance=\skip45 +) (/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: xetex.def on input line 225. +LaTeX Info: Redefining \color on input line 702. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) (build/options.sty +Package: options 2015/03/01, Daan Leijen, Provides convenient path-value (or key-value) options +(/usr/share/texlive/texmf-dist/tex/latex/etoolbox/etoolbox.sty +Package: etoolbox 2015/08/02 v2.2a e-TeX tools for LaTeX (JAW) +\etb@tempcnta=\count87 +) +\opt@nesting=\count88 +\opt@idx=\count89 +\opt@choiceord=\count90 +) (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty +Package: iftex 2013/04/04 v0.2 Provides if(tex) conditional for PDFTeX, XeTeX, and LuaTeX +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2014/10/28 v1.0g Enhanced LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks16 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2016/01/03 v1.0q Standard LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2016/01/03 v1.10 sin cos tan (DPC) +) (/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg +File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live +) +Package graphics Info: Driver file: xetex.def on input line 95. +) +\Gin@req@height=\dimen105 +\Gin@req@width=\dimen106 +) (build/longfbox.sty +Package: longfbox 2015/12/01, Daan Leijen, Provides long fbox that can break over pages +(build/longbox.sty +Package: longbox 2015/12/01, Daan Leijen, Provides basic longbox that can break over pages +(/usr/share/texlive/texmf-dist/tex/latex/mdwtools/footnote.sty +Package: footnote 1997/01/28 1.13 Save footnotes around boxes +\fn@notes=\box26 +\fn@width=\dimen107 +) +\lb@prevdepth=\skip46 +\lb@freevspace=\skip47 +\lb@headbox=\box27 +\lb@savebox=\box28 +\lb@mainbox=\box29 +\lb@usevbox=\count91 +\lb@width=\skip48 +\lb@height=\skip49 +\lb@skiptop=\skip50 +\lb@skipright=\skip51 +\lb@skipbottom=\skip52 +\lb@skipleft=\skip53 +\lb@skipbreaktop=\skip54 +\lb@skipbreakbottom=\skip55 +\lb@outerwidth=\skip56 +\lb@extrasplit=\skip57 +\lb@textalign=\count92 +\lb@baseline=\count93 +\lb@neededvspace=\skip58 +\lb@splitheight=\skip59 +\lb@insurance=\skip60 +\/longbox/@part-height=\skip61 +\/longbox/@part-width=\skip62 +\/longbox/@part-depth=\skip63 +\/longbox/@content-box-height=\skip64 +\/longbox/@content-box-width=\skip65 +\/longbox/@content-box-depth=\skip66 +\/longbox/@breakat-previous=\skip67 +\/longbox/@lower=\skip68 +\/longbox/split-minimum=\skip69 +\/longbox/split-badness=\skip70 +\/longbox/raise=\skip71 +\/longbox/height=\skip72 +\/longbox/width=\skip73 +\/longbox/outer-height=\skip74 +\/longbox/outer-width=\skip75 +\/longbox/skip-top=\skip76 +\/longbox/skip-right=\skip77 +\/longbox/skip-bottom=\skip78 +\/longbox/skip-left=\skip79 +\/longbox/skip-break-bottom=\skip80 +\/longbox/skip-break-top=\skip81 +) (/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.sty +Package: pict2e 2016/02/05 v0.3b Improved picture commands (HjG,RN,JT) +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.cfg +File: pict2e.cfg 2016/02/05 v0.1u pict2e configuration for teTeX/TeXLive +) +Package pict2e Info: Driver file: xetex.def on input line 119. +Package pict2e Info: Driver file for pict2e: p2e-xetex.def on input line 121. +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/p2e-xetex.def +File: p2e-xetex.def 2016/02/05 v0.1u Driver-dependant file (RN,HjG,JT) +) +\pIIe@GRAPH=\toks17 +\@arclen=\dimen108 +\@arcrad=\dimen109 +\@tempdimd=\dimen110 +) (build/ellipse.sty +Package: ellipse 2004/11/05 v1.0 .dtx ellipse file +) +\fbox@oct=\count94 +\fbox@quad=\count95 +\fbox@diaq=\count96 +\fbox@sign=\count97 +\fbox@anglestart=\skip82 +\fbox@angleend=\skip83 +\fbox@dash=\skip84 +\fbox@dashskip=\skip85 +\fbox@anglecur=\skip86 +\fbox@dashangle=\skip87 +\fbox@dashskipangle=\skip88 +\fbox@delta=\skip89 +\fbox@from=\skip90 +\fbox@to=\skip91 +\/fbox/padding-top=\skip92 +\/fbox/padding-right=\skip93 +\/fbox/padding-bottom=\skip94 +\/fbox/padding-left=\skip95 +\/fbox/padding-break-top=\skip96 +\/fbox/padding-break-bottom=\skip97 +\/fbox/margin-top=\skip98 +\/fbox/margin-right=\skip99 +\/fbox/margin-bottom=\skip100 +\/fbox/margin-left=\skip101 +\/fbox/margin-break-top=\skip102 +\/fbox/margin-break-bottom=\skip103 +\/fbox/border-top-width=\skip104 +\/fbox/border-right-width=\skip105 +\/fbox/border-bottom-width=\skip106 +\/fbox/border-left-width=\skip107 +\/fbox/border-break-top-width=\skip108 +\/fbox/border-break-bottom-width=\skip109 +\/fbox/@lower=\skip110 +\/fbox/@padding-box-height=\skip111 +\/fbox/@padding-box-depth=\skip112 +\/fbox/@padding-box-width=\skip113 +\/fbox/@border-box-width=\skip114 +\/fbox/@border-box-height=\skip115 +\/fbox/@border-box-depth=\skip116 +\/fbox/@border-top-left-radius-x=\skip117 +\/fbox/@border-top-right-radius-x=\skip118 +\/fbox/@border-bottom-left-radius-x=\skip119 +\/fbox/@border-bottom-right-radius-x=\skip120 +\/fbox/@border-top-left-radius-y=\skip121 +\/fbox/@border-top-right-radius-y=\skip122 +\/fbox/@border-bottom-left-radius-y=\skip123 +\/fbox/@border-bottom-right-radius-y=\skip124 +\/fbox/@border-top-left-ix=\skip125 +\/fbox/@border-top-left-iy=\skip126 +\/fbox/@border-top-right-ix=\skip127 +\/fbox/@border-top-right-iy=\skip128 +\/fbox/@border-bottom-left-ix=\skip129 +\/fbox/@border-bottom-left-iy=\skip130 +\/fbox/@border-bottom-right-ix=\skip131 +\/fbox/@border-bottom-right-iy=\skip132 +\/fbox/@border-top-left-phi=\skip133 +\/fbox/@border-top-right-phi=\skip134 +\/fbox/@border-bottom-left-phi=\skip135 +\/fbox/@border-bottom-right-phi=\skip136 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2016/03/03 v2.15a AMS math features +\@mathmargin=\skip137 +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2000/06/29 v2.01 AMS text +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen111 +)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen112 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 1999/12/14 v2.01 operator names +) +\inf@bad=\count98 +LaTeX Info: Redefining \frac on input line 199. +\uproot@=\count99 +\leftroot@=\count100 +LaTeX Info: Redefining \overline on input line 297. +\classnum@=\count101 +\DOTSCASE@=\count102 +LaTeX Info: Redefining \ldots on input line 394. +LaTeX Info: Redefining \dots on input line 397. +LaTeX Info: Redefining \cdots on input line 518. +\Mathstrutbox@=\box30 +\strutbox@=\box31 +\big@size=\dimen113 +LaTeX Font Info: Redeclaring font encoding OML on input line 630. +LaTeX Font Info: Redeclaring font encoding OMS on input line 631. +\macc@depth=\count103 +\c@MaxMatrixCols=\count104 +\dotsspace@=\muskip10 +\c@parentequation=\count105 +\dspbrk@lvl=\count106 +\tag@help=\toks19 +\row@=\count107 +\column@=\count108 +\maxfields@=\count109 +\andhelp@=\toks20 +\eqnshift@=\dimen114 +\alignsep@=\dimen115 +\tagshift@=\dimen116 +\tagwidth@=\dimen117 +\totwidth@=\dimen118 +\lineht@=\dimen119 +\@envbody=\toks21 +\multlinegap=\skip138 +\multlinetaggap=\skip139 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2735. +LaTeX Info: Redefining \] on input line 2736. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +) (/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/stmaryrd.sty +Package: stmaryrd 1994/03/03 St Mary's Road symbol package +\symstmry=\mathgroup6 +LaTeX Font Info: Overwriting symbol font `stmry' in version `bold' +(Font) U/stmry/m/n --> U/stmry/b/n on input line 89. +) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty +Package: textcomp 2005/09/27 v1.99g Standard LaTeX package +Package textcomp Info: Sub-encoding information: +(textcomp) 5 = only ISO-Adobe without \textcurrency +(textcomp) 4 = 5 + \texteuro +(textcomp) 3 = 4 + \textohm +(textcomp) 2 = 3 + \textestimated + \textcurrency +(textcomp) 1 = TS1 - \textcircled - \t +(textcomp) 0 = TS1 (full) +(textcomp) Font families with sub-encoding setting implement +(textcomp) only a restricted character set as indicated. +(textcomp) Family '?' is the default used for unknown fonts. +(textcomp) See the documentation for details. +Package textcomp Info: Setting ? sub-encoding to TS1/1 on input line 79. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +) +LaTeX Info: Redefining \oldstylenums on input line 334. +Package textcomp Info: Setting cmr sub-encoding to TS1/0 on input line 349. +Package textcomp Info: Setting cmss sub-encoding to TS1/0 on input line 350. +Package textcomp Info: Setting cmtt sub-encoding to TS1/0 on input line 351. +Package textcomp Info: Setting cmvtt sub-encoding to TS1/0 on input line 352. +Package textcomp Info: Setting cmbr sub-encoding to TS1/0 on input line 353. +Package textcomp Info: Setting cmtl sub-encoding to TS1/0 on input line 354. +Package textcomp Info: Setting ccr sub-encoding to TS1/0 on input line 355. +Package textcomp Info: Setting ptm sub-encoding to TS1/4 on input line 356. +Package textcomp Info: Setting pcr sub-encoding to TS1/4 on input line 357. +Package textcomp Info: Setting phv sub-encoding to TS1/4 on input line 358. +Package textcomp Info: Setting ppl sub-encoding to TS1/3 on input line 359. +Package textcomp Info: Setting pag sub-encoding to TS1/4 on input line 360. +Package textcomp Info: Setting pbk sub-encoding to TS1/4 on input line 361. +Package textcomp Info: Setting pnc sub-encoding to TS1/4 on input line 362. +Package textcomp Info: Setting pzc sub-encoding to TS1/4 on input line 363. +Package textcomp Info: Setting bch sub-encoding to TS1/4 on input line 364. +Package textcomp Info: Setting put sub-encoding to TS1/5 on input line 365. +Package textcomp Info: Setting uag sub-encoding to TS1/5 on input line 366. +Package textcomp Info: Setting ugq sub-encoding to TS1/5 on input line 367. +Package textcomp Info: Setting ul8 sub-encoding to TS1/4 on input line 368. +Package textcomp Info: Setting ul9 sub-encoding to TS1/4 on input line 369. +Package textcomp Info: Setting augie sub-encoding to TS1/5 on input line 370. +Package textcomp Info: Setting dayrom sub-encoding to TS1/3 on input line 371. +Package textcomp Info: Setting dayroms sub-encoding to TS1/3 on input line 372. +Package textcomp Info: Setting pxr sub-encoding to TS1/0 on input line 373. +Package textcomp Info: Setting pxss sub-encoding to TS1/0 on input line 374. +Package textcomp Info: Setting pxtt sub-encoding to TS1/0 on input line 375. +Package textcomp Info: Setting txr sub-encoding to TS1/0 on input line 376. +Package textcomp Info: Setting txss sub-encoding to TS1/0 on input line 377. +Package textcomp Info: Setting txtt sub-encoding to TS1/0 on input line 378. +Package textcomp Info: Setting lmr sub-encoding to TS1/0 on input line 379. +Package textcomp Info: Setting lmdh sub-encoding to TS1/0 on input line 380. +Package textcomp Info: Setting lmss sub-encoding to TS1/0 on input line 381. +Package textcomp Info: Setting lmssq sub-encoding to TS1/0 on input line 382. +Package textcomp Info: Setting lmvtt sub-encoding to TS1/0 on input line 383. +Package textcomp Info: Setting lmtt sub-encoding to TS1/0 on input line 384. +Package textcomp Info: Setting qhv sub-encoding to TS1/0 on input line 385. +Package textcomp Info: Setting qag sub-encoding to TS1/0 on input line 386. +Package textcomp Info: Setting qbk sub-encoding to TS1/0 on input line 387. +Package textcomp Info: Setting qcr sub-encoding to TS1/0 on input line 388. +Package textcomp Info: Setting qcs sub-encoding to TS1/0 on input line 389. +Package textcomp Info: Setting qpl sub-encoding to TS1/0 on input line 390. +Package textcomp Info: Setting qtm sub-encoding to TS1/0 on input line 391. +Package textcomp Info: Setting qzc sub-encoding to TS1/0 on input line 392. +Package textcomp Info: Setting qhvc sub-encoding to TS1/0 on input line 393. +Package textcomp Info: Setting futs sub-encoding to TS1/4 on input line 394. +Package textcomp Info: Setting futx sub-encoding to TS1/4 on input line 395. +Package textcomp Info: Setting futj sub-encoding to TS1/4 on input line 396. +Package textcomp Info: Setting hlh sub-encoding to TS1/3 on input line 397. +Package textcomp Info: Setting hls sub-encoding to TS1/3 on input line 398. +Package textcomp Info: Setting hlst sub-encoding to TS1/3 on input line 399. +Package textcomp Info: Setting hlct sub-encoding to TS1/5 on input line 400. +Package textcomp Info: Setting hlx sub-encoding to TS1/5 on input line 401. +Package textcomp Info: Setting hlce sub-encoding to TS1/5 on input line 402. +Package textcomp Info: Setting hlcn sub-encoding to TS1/5 on input line 403. +Package textcomp Info: Setting hlcw sub-encoding to TS1/5 on input line 404. +Package textcomp Info: Setting hlcf sub-encoding to TS1/5 on input line 405. +Package textcomp Info: Setting pplx sub-encoding to TS1/3 on input line 406. +Package textcomp Info: Setting pplj sub-encoding to TS1/3 on input line 407. +Package textcomp Info: Setting ptmx sub-encoding to TS1/4 on input line 408. +Package textcomp Info: Setting ptmj sub-encoding to TS1/4 on input line 409. +) (/usr/share/texlive/texmf-dist/tex/latex/psnfss/pifont.sty +Package: pifont 2005/04/12 PSNFSS-v9.2a Pi font support (SPQR) +LaTeX Font Info: Try loading font information for U+pzd on input line 63. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upzd.fd +File: upzd.fd 2001/06/04 font definitions for U/pzd. +) +LaTeX Font Info: Try loading font information for U+psy on input line 64. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upsy.fd +File: upsy.fd 2001/06/04 font definitions for U/psy. +)) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2012/11/06 v6.83m Hypertext links for LaTeX +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO) +Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO) +Package hobsub Info: Skipping package `infwarerr' (already loaded). +Package hobsub Info: Skipping package `ltxcmds' (already loaded). +Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO) +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is not detected. +Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) +Package etexcmds Info: Could not find \expanded. +(etexcmds) That can mean that you are not using pdfTeX 1.50 or +(etexcmds) that some package has redefined \expanded. +(etexcmds) In the latter case, load this package earlier. +Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) +Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO) +Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: pdfTeX >= 1.30 not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode not found. +Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO) +Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO) +Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO) +Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO) +Package: xcolor-patch 2011/01/30 xcolor patch +Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO) +Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO) +Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO) +Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2011/03/04 v1.3 Hooks for auxiliary files (HO) +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) +) +\@linkdim=\dimen120 +\Hy@linkcounter=\count110 +\Hy@pagecounter=\count111 +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count112 +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Hyper figures OFF on input line 4443. +Package hyperref Info: Link nesting OFF on input line 4448. +Package hyperref Info: Hyper index ON on input line 4451. +Package hyperref Info: Plain pages OFF on input line 4458. +Package hyperref Info: Backreferencing OFF on input line 4463. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4688. +\c@Hy@tempcnt=\count113 +(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip11 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 5041. +\XeTeXLinkMargin=\dimen121 +\Fld@menulength=\count114 +\Field@Width=\dimen122 +\Fld@charsize=\dimen123 +Package hyperref Info: Hyper figures OFF on input line 6295. +Package hyperref Info: Link nesting OFF on input line 6300. +Package hyperref Info: Hyper index ON on input line 6303. +Package hyperref Info: backreferencing OFF on input line 6310. +Package hyperref Info: Link coloring OFF on input line 6315. +Package hyperref Info: Link coloring with OCG OFF on input line 6320. +Package hyperref Info: PDF/A mode OFF on input line 6325. +LaTeX Info: Redefining \ref on input line 6365. +LaTeX Info: Redefining \pageref on input line 6369. +\Hy@abspage=\count115 +\c@Item=\count116 +\c@Hfootnote=\count117 +) + +Package hyperref Message: Driver (autodetected): hxetex. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hxetex.def +File: hxetex.def 2012/11/06 v6.83m Hyperref driver for XeTeX +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def +File: puenc.def 2012/11/06 v6.83m Hyperref: PDF Unicode definition (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/stringenc.sty +Package: stringenc 2011/12/02 v1.10 Convert strings between diff. encodings (HO) +) +\pdfm@box=\box32 +\c@Hy@AnnotLevel=\count118 +\HyField@AnnotCount=\count119 +\Fld@listcount=\count120 +\c@bookmark@seq@number=\count121 +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO) +Package rerunfilecheck Info: Feature \pdfmdfivesum is not available +(rerunfilecheck) (e.g. pdfTeX or LuaTeX with package `pdftexcmds'). +(rerunfilecheck) Therefore file contents cannot be checked efficiently +(rerunfilecheck) and the loading of the package is aborted. +) +\Hy@SectionHShift=\skip140 +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bookmark.sty +Package: bookmark 2011/12/02 v1.24 PDF bookmarks (HO) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bkm-dvipdfm.def +File: bkm-dvipdfm.def 2011/12/02 v1.24 bookmark driver for dvipdfm (HO) +\BKM@id=\count122 +)) (/usr/share/texlive/texmf-dist/tex/latex/booktabs/booktabs.sty +Package: booktabs 2005/04/14 v1.61803 publication quality tables +\heavyrulewidth=\dimen124 +\lightrulewidth=\dimen125 +\cmidrulewidth=\dimen126 +\belowrulesep=\dimen127 +\belowbottomsep=\dimen128 +\aboverulesep=\dimen129 +\abovetopsep=\dimen130 +\cmidrulesep=\dimen131 +\cmidrulekern=\dimen132 +\defaultaddspace=\dimen133 +\@cmidla=\count123 +\@cmidlb=\count124 +\@aboverulesep=\dimen134 +\@belowrulesep=\dimen135 +\@thisruleclass=\count125 +\@lastruleclass=\count126 +\@thisrulewidth=\dimen136 +) (/usr/share/texlive/texmf-dist/tex/latex/tools/longtable.sty +Package: longtable 2014/10/28 v4.11 Multi-page Table package (DPC) +\LTleft=\skip141 +\LTright=\skip142 +\LTpre=\skip143 +\LTpost=\skip144 +\LTchunksize=\count127 +\LTcapwidth=\dimen137 +\LT@head=\box33 +\LT@firsthead=\box34 +\LT@foot=\box35 +\LT@lastfoot=\box36 +\LT@cols=\count128 +\LT@rows=\count129 +\c@LT@tables=\count130 +\c@LT@chunks=\count131 +\LT@p@ftn=\toks23 +) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Package: anyfontsize 2007/11/22 anyfontsize.sty by pts +) (/usr/share/texlive/texmf-dist/tex/latex/enumitem/enumitem.sty +Package: enumitem 2011/09/28 v3.5.2 Customized lists +\labelindent=\skip145 +\enit@outerparindent=\dimen138 +\enit@toks=\toks24 +\enit@inbox=\box37 +\enitdp@description=\count132 +) (/usr/share/texlive/texmf-dist/tex/latex/wrapfig/wrapfig.sty +\wrapoverhang=\dimen139 +\WF@size=\dimen140 +\c@WF@wrappedlines=\count133 +\WF@box=\box38 +\WF@everypar=\toks25 +Package: wrapfig 2003/01/31 v 3.6 +) (/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.sty (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty +Package: expl3 2016/01/19 v6377 L3 programming layer (loader) +(/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3-code.tex +Package: expl3 2016/01/19 v6377 L3 programming layer (code) +L3 Module: l3bootstrap 2016/01/01 v6339 L3 Bootstrap code +L3 Module: l3names 2015/12/21 v6328 L3 Namespace for primitives +L3 Module: l3basics 2015/11/22 v6315 L3 Basic definitions +L3 Module: l3expan 2015/09/10 v5983 L3 Argument expansion +L3 Module: l3tl 2015/09/29 v6121 L3 Token lists +L3 Module: l3str 2016/01/03 v6357 L3 Strings +L3 Module: l3seq 2015/08/05 v5777 L3 Sequences and stacks +L3 Module: l3int 2016/01/05 v6366 L3 Integers +\c_max_int=\count134 +\l_tmpa_int=\count135 +\l_tmpb_int=\count136 +\g_tmpa_int=\count137 +\g_tmpb_int=\count138 +L3 Module: l3quark 2015/08/17 v5855 L3 Quarks +L3 Module: l3prg 2015/11/01 v6216 L3 Control structures +\g__prg_map_int=\count139 +L3 Module: l3clist 2015/09/02 v5901 L3 Comma separated lists +L3 Module: l3token 2015/11/11 v6249 L3 Experimental token manipulation +L3 Module: l3prop 2016/01/05 v6366 L3 Property lists +L3 Module: l3msg 2015/09/28 v6113 L3 Messages +L3 Module: l3file 2015/12/03 v6317 L3 File and I/O operations +\l_iow_line_count_int=\count140 +\l__iow_target_count_int=\count141 +\l__iow_current_line_int=\count142 +\l__iow_current_word_int=\count143 +\l__iow_current_indentation_int=\count144 +L3 Module: l3skip 2016/01/05 v6366 L3 Dimensions and skips +\c_zero_dim=\dimen141 +\c_max_dim=\dimen142 +\l_tmpa_dim=\dimen143 +\l_tmpb_dim=\dimen144 +\g_tmpa_dim=\dimen145 +\g_tmpb_dim=\dimen146 +\c_zero_skip=\skip146 +\c_max_skip=\skip147 +\l_tmpa_skip=\skip148 +\l_tmpb_skip=\skip149 +\g_tmpa_skip=\skip150 +\g_tmpb_skip=\skip151 +\c_zero_muskip=\muskip12 +\c_max_muskip=\muskip13 +\l_tmpa_muskip=\muskip14 +\l_tmpb_muskip=\muskip15 +\g_tmpa_muskip=\muskip16 +\g_tmpb_muskip=\muskip17 +L3 Module: l3keys 2015/11/17 v6284 L3 Key-value interfaces +\g__keyval_level_int=\count145 +\l_keys_choice_int=\count146 +L3 Module: l3fp 2015/08/25 v5890 L3 Floating points +\c__fp_leading_shift_int=\count147 +\c__fp_middle_shift_int=\count148 +\c__fp_trailing_shift_int=\count149 +\c__fp_big_leading_shift_int=\count150 +\c__fp_big_middle_shift_int=\count151 +\c__fp_big_trailing_shift_int=\count152 +\c__fp_Bigg_leading_shift_int=\count153 +\c__fp_Bigg_middle_shift_int=\count154 +\c__fp_Bigg_trailing_shift_int=\count155 +L3 Module: l3box 2015/08/09 v5822 L3 Experimental boxes +\c_empty_box=\box39 +\l_tmpa_box=\box40 +\l_tmpb_box=\box41 +\g_tmpa_box=\box42 +\g_tmpb_box=\box43 +L3 Module: l3coffins 2015/08/06 v5789 L3 Coffin code layer +\l__coffin_internal_box=\box44 +\l__coffin_internal_dim=\dimen147 +\l__coffin_offset_x_dim=\dimen148 +\l__coffin_offset_y_dim=\dimen149 +\l__coffin_x_dim=\dimen150 +\l__coffin_y_dim=\dimen151 +\l__coffin_x_prime_dim=\dimen152 +\l__coffin_y_prime_dim=\dimen153 +\c_empty_coffin=\box45 +\l__coffin_aligned_coffin=\box46 +\l__coffin_aligned_internal_coffin=\box47 +\l_tmpa_coffin=\box48 +\l_tmpb_coffin=\box49 +\l__coffin_display_coffin=\box50 +\l__coffin_display_coord_coffin=\box51 +\l__coffin_display_pole_coffin=\box52 +\l__coffin_display_offset_dim=\dimen154 +\l__coffin_display_x_dim=\dimen155 +\l__coffin_display_y_dim=\dimen156 +L3 Module: l3color 2014/08/23 v5354 L3 Experimental color support +L3 Module: l3sys 2015/09/25 v6087 L3 Experimental system/runtime functions +L3 Module: l3candidates 2016/01/14 v6376 L3 Experimental additions to l3kernel +\l__box_top_dim=\dimen157 +\l__box_bottom_dim=\dimen158 +\l__box_left_dim=\dimen159 +\l__box_right_dim=\dimen160 +\l__box_top_new_dim=\dimen161 +\l__box_bottom_new_dim=\dimen162 +\l__box_left_new_dim=\dimen163 +\l__box_right_new_dim=\dimen164 +\l__box_internal_box=\box53 +\l__coffin_bounding_shift_dim=\dimen165 +\l__coffin_left_corner_dim=\dimen166 +\l__coffin_right_corner_dim=\dimen167 +\l__coffin_bottom_corner_dim=\dimen168 +\l__coffin_top_corner_dim=\dimen169 +\l__coffin_scaled_total_height_dim=\dimen170 +\l__coffin_scaled_width_dim=\dimen171 +L3 Module: l3luatex 2015/11/11 v6250 L3 Experimental LuaTeX-specific functions +) (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def +File: l3xdvidpfmx.def 2015/11/11 v6250 L3 Experimental driver: xdvipdfmx +)) (/usr/share/texlive/texmf-dist/tex/latex/l3packages/xparse/xparse.sty +Package: xparse 2016/01/19 v6377 L3 Experimental document command parser +\l__xparse_current_arg_int=\count156 +\l__xparse_m_args_int=\count157 +\l__xparse_mandatory_args_int=\count158 +\l__xparse_processor_int=\count159 +\l__xparse_v_nesting_int=\count160 +) +Package: fontspec 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec-xetex.sty +Package: fontspec-xetex 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +\l_fontspec_script_int=\count161 +\l_fontspec_language_int=\count162 +\l_fontspec_strnum_int=\count163 +\l__fontspec_tmpa_dim=\dimen172 +\l__fontspec_tmpb_dim=\dimen173 +\l__fontspec_tmpc_dim=\dimen174 +\g__file_internal_ior=\read1 +(/usr/share/texlive/texmf-dist/tex/latex/base/fontenc.sty +Package: fontenc 2005/09/27 v1.99g Standard LaTeX package +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1enc.def +File: eu1enc.def 2010/05/27 v0.1h Experimental Unicode font encodings +) +LaTeX Font Info: Try loading font information for EU1+lmr on input line 105. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmr.fd +File: eu1lmr.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) (/usr/share/texlive/texmf-dist/tex/xelatex/xunicode/xunicode.sty +File: xunicode.sty 2011/09/09 v0.981 provides access to latin accents and many other characters in Unicode lower plane +(/usr/share/texmf/tex/latex/tipa/t3enc.def +File: t3enc.def 2001/12/31 T3 encoding +LaTeX Font Info: Try loading font information for EU1+lmss on input line 357. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmss.fd +File: eu1lmss.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) +\tipaTiiicode=\count164 +\tipasavetokens=\toks26 +\tipachecktokens=\toks27 +) +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \__fontspec_post_arg:w with sig. 'mmO{}' on line 353. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \fontspec with sig. 'om' on line 355. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmainfont with sig. 'om' on line 365. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setsansfont with sig. 'om' on line 375. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmonofont with sig. 'om' on line 385. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathrm with sig. 'om' on line 399. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setboldmathrm with sig. 'om' on line 407. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathsf with sig. 'om' on line 415. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathtt with sig. 'om' on line 423. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfamily with sig. 'mom' on line 437. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontface with sig. 'mom' on line 453. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \defaultfontfeatures with sig. 't+om' on line 467. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \addfontfeatures with sig. 'm' on line 529. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfeature with sig. 'mm' on line 540. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newAATfeature with sig. 'mmmm' on line 548. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newopentypefeature with sig. 'mmm' on line 556. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeature with sig. 'mm' on line 577. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeatureoption with sig. 'mmm' on line 586. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontscript with sig. 'mm' on line 590. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontlanguage with sig. 'mm' on line 594. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \DeclareFontsExtensions with sig. 'm' on line 599. +................................................. +\l__fontspec_tmp_int=\count165 +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.cfg) +LaTeX Info: Redefining \itshape on input line 2705. +LaTeX Info: Redefining \slshape on input line 2710. +LaTeX Info: Redefining \scshape on input line 2715. +LaTeX Info: Redefining \upshape on input line 2720. +\l__fontspec_em_int=\count166 +\l__fontspec_emdef_int=\count167 +LaTeX Info: Redefining \em on input line 2736. +LaTeX Info: Redefining \emph on input line 2742. +LaTeX Info: Redefining \- on input line 2746. +................................................. +. LaTeX info: "xparse/redefine-command" +. +. Redefining command \oldstylenums with sig. 'm' on line 2841. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \liningnums with sig. 'm' on line 2845. +................................................. +)) +Package hyperref Info: Option `colorlinks' set `true' on input line 87. +\px=\skip152 +\c@md@targetcount=\count168 +\mdcompactskip=\skip153 +\mdcompacttopsep=\skip154 +\dim@rem=\skip155 +\dim@ch=\skip156 +\md@height=\skip157 +\dim@marginbottom=\skip158 +\dim@paddingbottom=\skip159 +\md@interaction=\count169 +\mddefinitionsskip=\skip160 +\md@captionlen=\skip161 +\mdtoclevel=\count170 +\c@mdtoclevelbold=\count171 +\c@mdtocleveldots=\count172 +\mdtocskip=\skip162 +\mdpreskip=\skip163 +\presp=\skip164 +LaTeX Font Info: Try loading font information for EU1+lmtt on input line 801. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmtt.fd +File: eu1lmtt.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +\md@postskip=\skip165 +\ppresp=\skip166 +\md@thmcaption=\box54 +\md@defaultcolwidth=\skip167 +\mdtabularskip=\skip168 +\mdbibindentunit=\skip169 +\c@md@authorcount=\count173 +\c@mdx@authorcount=\count174 +\c@@mdTargetCount=\count175 +\@snippetBox=\box55 +\@snippetWidth=\skip170 +\@snippetHeight=\skip171 +\@snippetDepth=\skip172 +\c@snippets=\count176 +) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty +Package: geometry 2010/09/12 v5.6 Page Geometry +\Gm@cnth=\count177 +\Gm@cntv=\count178 +\c@Gm@tempcnt=\count179 +\Gm@bindingoffset=\dimen175 +\Gm@wd@mp=\dimen176 +\Gm@odd@mp=\dimen177 +\Gm@even@mp=\dimen178 +\Gm@layoutwidth=\dimen179 +\Gm@layoutheight=\dimen180 +\Gm@layouthoffset=\dimen181 +\Gm@layoutvoffset=\dimen182 +\Gm@dimlist=\toks28 +) (/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +\fancy@headwidth=\skip173 +\f@ncyO@elh=\skip174 +\f@ncyO@erh=\skip175 +\f@ncyO@olh=\skip176 +\f@ncyO@orh=\skip177 +\f@ncyO@elf=\skip178 +\f@ncyO@erf=\skip179 +\f@ncyO@olf=\skip180 +\f@ncyO@orf=\skip181 +) (build/P4Runtime-Spec.aux + +LaTeX Warning: Label `sec-example' multiply defined. + +) +\openout1 = `P4Runtime-Spec.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for TS1+cmr on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1cmr.fd +File: ts1cmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions +) +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for EU1/lmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T3/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for T3+cmr on input line 14. +(/usr/share/texmf/tex/latex/tipa/t3cmr.fd +File: t3cmr.fd 2001/12/31 TIPA font definitions +) +LaTeX Font Info: ... okay on input line 14. +\AtBeginShipoutBox=\box56 +Package hyperref Info: Link coloring ON on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2012/10/27 v2.43 Cross-referencing by name of section +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO) +) +\c@section@level=\count180 +) +LaTeX Info: Redefining \ref on input line 14. +LaTeX Info: Redefining \pageref on input line 14. +LaTeX Info: Redefining \nameref on input line 14. +................................................. +. fontspec info: "setup-math" +. +. Adjusting the maths setup (use [no-math] to avoid this). +................................................. +\symlegacymaths=\mathgroup7 +LaTeX Font Info: Overwriting symbol font `legacymaths' in version `bold' +(Font) OT1/cmr/m/n --> OT1/cmr/bx/n on input line 14. +LaTeX Font Info: Redeclaring math accent \acute on input line 14. +LaTeX Font Info: Redeclaring math accent \grave on input line 14. +LaTeX Font Info: Redeclaring math accent \ddot on input line 14. +LaTeX Font Info: Redeclaring math accent \tilde on input line 14. +LaTeX Font Info: Redeclaring math accent \bar on input line 14. +LaTeX Font Info: Redeclaring math accent \breve on input line 14. +LaTeX Font Info: Redeclaring math accent \check on input line 14. +LaTeX Font Info: Redeclaring math accent \hat on input line 14. +LaTeX Font Info: Redeclaring math accent \dot on input line 14. +LaTeX Font Info: Redeclaring math accent \mathring on input line 14. +LaTeX Font Info: Redeclaring math symbol \Gamma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Delta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Theta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Lambda on input line 14. +LaTeX Font Info: Redeclaring math symbol \Xi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Pi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Sigma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Upsilon on input line 14. +LaTeX Font Info: Redeclaring math symbol \Phi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Psi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Omega on input line 14. +LaTeX Font Info: Redeclaring math symbol \mathdollar on input line 14. +LaTeX Font Info: Redeclaring symbol font `operators' on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `normal' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/cmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `bold' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/cmr/bx/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) EU1/lmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/cmr/m/it --> EU1/lmr/m/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/cmr/bx/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/cmss/m/n --> EU1/lmss/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/cmtt/m/n --> EU1/lmtt/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) EU1/lmr/m/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' +(Font) OT1/cmr/bx/it --> EU1/lmr/bx/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/cmss/bx/n --> EU1/lmss/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/cmtt/m/n --> EU1/lmtt/bx/n on input line 14. +*geometry* driver: auto-detecting +*geometry* detected driver: xetex +*geometry* verbose mode - [ preamble ] result: +* driver: xetex +* paper: +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: +* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt) +* v-part:(T,H,B)=(72.26999pt, 632.3625pt, 90.3375pt) +* \paperwidth=614.295pt +* \paperheight=794.96999pt +* \textwidth=469.75502pt +* \textheight=632.3625pt +* \oddsidemargin=0.0pt +* \evensidemargin=0.0pt +* \topmargin=-37.0pt +* \headheight=30.0pt +* \headsep=25.0pt +* \topskip=11.0pt +* \footskip=30.0pt +* \marginparwidth=59.0pt +* \marginparsep=10.0pt +* \columnsep=10.0pt +* \skip\footins=10.0pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +resolve font stack: UtopiaStd-Regular + +\g__fontspec_family_UtopiaStd-Regular_int=\count181 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'UtopiaStd-Regular(0)' created for font 'UtopiaStd-Regular' with +. options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;" +. - 'small caps' (m/sc) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;+smcp;" +................................................. + +resolved font stack 'UtopiaStd-Regular' to: UtopiaStd-Regular +LaTeX Font Info: Try loading font information for U+msa on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Try loading font information for U+msb on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Try loading font information for U+stmry on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/Ustmry.fd) + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/bx/n' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 35. + +resolve font stack: LuxiMono + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +\g__fontspec_family_LuxiMono_int=\count182 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'LuxiMono(0)' created for font 'LuxiMono' with options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: <->"LuxiMono/OT:" +. - 'small caps' (m/sc) with NFSS spec.: +................................................. + +resolved font stack 'LuxiMono' to: LuxiMono +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/se-ascii-print.def +File: se-ascii-print.def 2011/12/02 v1.10 stringenc: Printable ASCII characters +) [1 + +] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[2] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <10.95> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 309. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Font Warning: Font shape `EU1/LuxiMono(0)/bx/n' undefined +(Font) using `EU1/LuxiMono(0)/m/n' instead on input line 309. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[3] [4] + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/m/it' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 519. + +[5] [6] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[7] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/reference-architecture.png Graphic file (type QTm) + [8] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[9] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[10] +File: build/single-embedded-controller.png Graphic file (type QTm) + [11] +File: build/single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-controllers.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-ha-controllers.png Graphic file (type QTm) + [12] [13] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[14] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[15] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <12> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 1530. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1530. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[16] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[17] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (65.03293pt too wide) in paragraph at lines 1798--1801 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For all backup controllers, \EU1/LuxiMono(0)/bx/n/8.2125 status \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set to non-OK (with \EU1/LuxiMono(0)/bx/n/8.2125 status.code \EU1/UtopiaStd-Regular(0)/m/it/10.95 set to \EU1/LuxiMono(0)/bx/n/8.2125 google.rpc.ALREADY_EXISTS\EU1/UtopiaStd-Regular(0)/m/it/10.95 ). + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[18] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1835. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1859. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[19] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1904. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[20] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[21] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[22] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2187. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[23] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1057) in paragraph at lines 2237--2241 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For structured annotations, every \EU1/LuxiMono(0)/bx/n/8.2125 StructuredAnnotation \EU1/UtopiaStd-Regular(0)/m/it/10.95 message contains an optional field + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2244. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[24] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[25] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[26] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (12.45624pt too wide) in paragraph at lines 2475--2488 + [] + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2511. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[27] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[28] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2702. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2762. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[29] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2836. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[30] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2917. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.59204pt too wide) in paragraph at lines 2971--2973 +[]\EU1/LuxiMono(0)/bx/n/8.2125 BYTES\EU1/UtopiaStd-Regular(0)/m/it/10.95 , which signifies that this meter can be configured with rates expressed in bytes/second. + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2996. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[31] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (18.74199pt too wide) in paragraph at lines 3013--3020 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 carrying P4 standard annotations \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_in") \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_out")\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[32] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[33] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3155. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[34] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[35] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3383. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3430. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[36] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3468. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[37] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[38] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[39] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[40] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[41] [42] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1629) in paragraph at lines 4072--4074 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For example, the following P4$[]$ objects involve complex types that need to be exposed in + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[43] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1454) in paragraph at lines 4120--4129 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 ification for all the named types in the P4$[]$ program. These named types are \EU1/LuxiMono(0)/bx/n/8.2125 struct\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 header\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + + +Underfull \hbox (badness 1831) in paragraph at lines 4120--4129 +\EU1/LuxiMono(0)/bx/n/8.2125 header_union\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 enum \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 serializable_enum\EU1/UtopiaStd-Regular(0)/m/it/10.95 ; for each of these we have a type specification mes- + [] + + +Underfull \hbox (badness 1845) in paragraph at lines 4120--4129 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 sage, respectively \EU1/LuxiMono(0)/bx/n/8.2125 P4StructTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnionTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4EnumTypeSpec \EU1/UtopiaStd-Regular(0)/m/it/10.95 and + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (33.06564pt too wide) in paragraph at lines 4155--4162 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 “binary string” types (\EU1/LuxiMono(0)/bx/n/8.2125 bit\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 int\EU1/UtopiaStd-Regular(0)/m/it/10.95 , and \EU1/LuxiMono(0)/bx/n/8.2125 varbit\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) are grouped together in the \EU1/LuxiMono(0)/bx/n/8.2125 P4BitstringLikeTypeSpec + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[44] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4172. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.46094pt too wide) in paragraph at lines 4209--4212 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 An invalid header union (i.e. all headers in the union are invalid) is represented by a \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnion + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[45] [46] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4346. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[47] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (24.68944pt too wide) in paragraph at lines 4434--4440 +[]\EU1/LuxiMono(0)/bx/n/8.2125 translated_type\EU1/UtopiaStd-Regular(0)/m/it/10.95 , if and only if the P4 \EU1/LuxiMono(0)/bx/n/8.2125 type \EU1/UtopiaStd-Regular(0)/m/it/10.95 declaration was annotated with \EU1/LuxiMono(0)/bx/n/8.2125 @p4runtime_translation\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[48] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[49] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (32.59732pt too wide) in paragraph at lines 4542--4548 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 in \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.MatchField\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.Action.Param \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.ControllerPacketMetadata.Metadata\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[50] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4649. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[51] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[52] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[53] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[54] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.53593pt too wide) in paragraph at lines 5112--5115 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 If the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 does not match the table description in the P4Info (e.g. the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 is \EU1/LuxiMono(0)/bx/n/8.2125 action_profile_member_id + [] + +[55] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[56] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[57] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[58] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[59] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[60] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[61] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5749. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[62] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[63] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[64] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (9.29865pt too wide) in paragraph at lines 6033--6035 + []\EU1/lmr/bx/n/10.95 9.2.2.1.| Rules on Setting \EU1/LuxiMono(0)/bx/n/8.2125 max_size[] \EU1/UtopiaStd-Regular(0)/m/it/10.95 The valid values for \EU1/LuxiMono(0)/bx/n/8.2125 max_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 depend on the static \EU1/LuxiMono(0)/bx/n/8.2125 max_group_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[65] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[66] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[67] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[68] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6321. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6361. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1331) in paragraph at lines 6364--6371 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 A direct counter is a direct resource associated with a \EU1/LuxiMono(0)/bx/n/8.2125 TableEntry \EU1/UtopiaStd-Regular(0)/m/it/10.95 (see [][]Direct Resources[][]). The + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[69] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6438. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[70] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6531. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6572. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[71] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6662. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[72] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6766. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6794. + +[73] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6804. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[74] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6928. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[75] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.93839pt too wide) in paragraph at lines 7039--7041 +[]\EU1/LuxiMono(0)/bx/n/8.2125 MODIFY\EU1/UtopiaStd-Regular(0)/m/it/10.95 : Modify the attributes of a given clone session entry, indexed by the given \EU1/LuxiMono(0)/bx/n/8.2125 clone_session_id\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[76] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7077. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[77] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[78] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7213. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7257. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[79] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[80] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7455. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[81] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/error-report.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[82] +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <14.4> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 7579. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7579. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: Hyper reference `wildcard-reads' on page 83 undefined on input line 7601. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[83] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7681. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[84] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[85] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[86] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (34.34796pt too wide) in paragraph at lines 7965--7970 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If an error is encountered before even trying to attempt individual batch updates, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +[87] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.66206pt too wide) in paragraph at lines 7974--7985 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 Otherwise, if one or more updates in the batch (\EU1/LuxiMono(0)/bx/n/8.2125 WriteRequest.updates\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) failed, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8021. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[88] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[89] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.4752pt too wide) in paragraph at lines 8256--8260 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 responding to \EU1/LuxiMono(0)/bx/n/8.2125 a \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 c\EU1/UtopiaStd-Regular(0)/m/it/10.95 , followed by a status \EU1/LuxiMono(0)/bx/n/8.2125 {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[90] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8342. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[91] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[92] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8465. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[93] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 8563--8566 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If a P4Runtime server supports both \EU1/LuxiMono(0)/bx/n/8.2125 SetForwardingPipelineConfig \EU1/UtopiaStd-Regular(0)/m/it/10.95 as well as returning the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[94] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[95] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[96] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[97] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[98] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8932. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[99] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 9000. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/psa-metadata-translation.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[100] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[101] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[102] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[103] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[104] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[105] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 9510--9517 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 p4info-ext should include a Protobuf message definition for every extern type that can + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[106] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 4036) in paragraph at lines 9565--9572 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 P4Runtime also supports streaming arbitrary Protobuf messages between the server and the + [] + + +Underfull \hbox (badness 1629) in paragraph at lines 9565--9572 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 client, by including an \EU1/LuxiMono(0)/bx/n/8.2125 Any \EU1/UtopiaStd-Regular(0)/m/it/10.95 Protobuf field [[][]31[][]] named \EU1/LuxiMono(0)/bx/n/8.2125 other \EU1/UtopiaStd-Regular(0)/m/it/10.95 in both \EU1/LuxiMono(0)/bx/n/8.2125 p4.v1.StreamMessageRequest + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[107] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[108] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1997) in paragraph at lines 9826--9828 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 Table [][]7[][] lists P4$[]$ annotations introduced primarily for the purpose of adding features for the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[109] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[110] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.61781pt too wide) in paragraph at lines 9973--9980 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 In gRPC, the status of a RPC request is sent as metadata, whose size is limited by the \EU1/LuxiMono(0)/bx/n/8.2125 grpc.max_metadata_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[111] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 10000) in paragraph at lines 10064--10065 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Complex Types in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- p4- + [] + +[112] +Underfull \hbox (badness 4001) in paragraph at lines 10076--10077 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Google Cloud APIs Versioning - Backwards-Compatibility.” [][]\EU1/lmtt/m/n/10.95 https:// cloud. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10085--10086 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “gRPC Streaming RPCs in C++.” [][]\EU1/lmtt/m/n/10.95 https:// grpc. io/ docs/ tutorials/ basic/ c. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10097--10098 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “P4 Concurrency Model.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10100--10101 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10115--10116 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Protobuf OneOf Backwards-Compatibility Issues.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10121--10122 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Action Selector.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# sec- action- + [] + + +Underfull \hbox (badness 2409) in paragraph at lines 10130--10131 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Empty Group Action Appendix.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# + [] + +[113] +Underfull \hbox (badness 10000) in paragraph at lines 10133--10134 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Select Expressions in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 1668) in paragraph at lines 10148--10149 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Any Protobuf Message.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ protocol- buffers/ docs/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10154--10155 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC C++ Error Details Library.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ grpc/ grpc/ blob/ master/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10157--10158 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC Canonical Status Codes.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ maps- booking/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10163--10164 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Protobuf MessageDifferencer in the C++ API.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10169--10170 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “v1model Architecture Definition.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ p4lang/ p4c/ blob/ master/ + [] + +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 10178. +[114] +Package atveryend Info: Empty hook `AfterLastShipout' on input line 10178. +(build/P4Runtime-Spec.aux) +Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 10178. +Package atveryend Info: Empty hook `AtEndAfterFileList' on input line 10178. + +LaTeX Font Warning: Some font shapes were not available, defaults substituted. + + +LaTeX Warning: There were undefined references. + + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 27553 strings out of 493638 + 517940 string characters out of 6146796 + 565041 words of memory out of 5000000 + 30655 multiletter control sequences out of 15000+600000 + 14633 words of font info for 98 fonts, out of 8000000 for 9000 + 1328 hyphenation exceptions out of 8191 + 48i,19n,81p,10429b,790s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on build/P4Runtime-Spec.pdf (114 pages). diff --git a/spec/v1.4.0-rc.2/P4Runtime-Spec.pdf b/spec/v1.4.0-rc.2/P4Runtime-Spec.pdf new file mode 100644 index 00000000..716b87cf Binary files /dev/null and b/spec/v1.4.0-rc.2/P4Runtime-Spec.pdf differ diff --git a/spec/v1.4.0-rc.2/P4Runtime-Spec.tex b/spec/v1.4.0-rc.2/P4Runtime-Spec.tex new file mode 100644 index 00000000..251c97d2 --- /dev/null +++ b/spec/v1.4.0-rc.2/P4Runtime-Spec.tex @@ -0,0 +1,10178 @@ +\documentclass[11pt]{article} +% generated by Madoko, version 1.1.4 +%mdk-data-line={1} + + +\usepackage[heading-base={2},section-num={False},bib-label={hide},fontspec={True}]{madoko2} +\usepackage[top=1in, bottom=1.25in, left=1in, right=1in]{geometry} +\usepackage{fancyhdr} +%mdk-data-line={11} + + \setlength{\headheight}{30pt} + \setlength{\emergencystretch}{2em} + +\begin{document} + + + +{\mdfontfamily{UtopiaStd-Regular} +%mdk-data-line={203} +\mdxtitleblockstart{} +%mdk-data-line={203} +\mdxtitle{{\sffamily{\bfseries\mdline{203}P4Runtime Specification}}}%mdk + +%mdk-data-line={206} +\mdxtitlenote{{\sffamily{\bfseries\mdline{206}version 1.3.0}}}%mdk +\mdxauthorstart{} +%mdk-data-line={211} +\mdxauthorname{\mdline{211}The P4.org API Working Group}%mdk +\mdxauthorend +%mdk-data-line={220} +\mdxtitlefooter{{\sffamily{\bfseries\mdline{220}2022-03-23}}}%mdk +\mdtitleauthorrunning{}{}\mdxtitleblockend%mdk + +%mdk-data-line={205} +\begin{abstract}%mdk + +%mdk-data-line={206} +\noindent\mdline{206}P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.%mdk +%mdk +\end{abstract}%mdk +\mdline{214} +\begin{mdtoc}%mdk + +\section*{Contents}\label{sec-contents}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-introduction-and-scope}{\mdref{sec-introduction-and-scope}{1.\hspace*{0.5em}Introduction and Scope}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-language-version-applicability}{\mdref{sec-p4-language-version-applicability}{1.1.\hspace*{0.5em}P4 Language Version Applicability}}%mdk + +\mdtocitemx{sec-in-scope}{\mdref{sec-in-scope}{1.2.\hspace*{0.5em}In Scope}}%mdk + +\mdtocitemx{sec-not-in-scope}{\mdref{sec-not-in-scope}{1.3.\hspace*{0.5em}Not In Scope}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-terms-and-definitions}{\mdref{sec-terms-and-definitions}{2.\hspace*{0.5em}Terms and Definitions}}%mdk + +\mdtocitemx{sec-reference-architecture}{\mdref{sec-reference-architecture}{3.\hspace*{0.5em}Reference Architecture}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-service-implementation}{\mdref{sec-p4runtime-service-implementation}{3.1.\hspace*{0.5em}P4Runtime Service Implementation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-security-concerns}{\mdref{sec-security-concerns}{3.1.1.\hspace*{0.5em}Security concerns}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-idealized-workflow}{\mdref{sec-idealized-workflow}{3.2.\hspace*{0.5em}Idealized Workflow}}%mdk + +\mdtocitemx{sec-p4-as-behavioral-description-language}{\mdref{sec-p4-as-behavioral-description-language}{3.3.\hspace*{0.5em}P4 as a Behavioral Description Language}}%mdk + +\mdtocitemx{sec-alternative-workflows}{\mdref{sec-alternative-workflows}{3.4.\hspace*{0.5em}Alternative Workflows}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{\mdref{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{3.4.1.\hspace*{0.5em}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}}%mdk + +\mdtocitemx{sec-no-p4-source-available-p4info-available}{\mdref{sec-no-p4-source-available-p4info-available}{3.4.2.\hspace*{0.5em}No P4 Source Available, P4Info Available}}%mdk + +\mdtocitemx{sec-partial-p4info-and-p4-source-are-available}{\mdref{sec-partial-p4info-and-p4-source-are-available}{3.4.3.\hspace*{0.5em}Partial P4Info and P4 Source are Available}}%mdk + +\mdtocitemx{sec-p4info-role-based-subsets}{\mdref{sec-p4info-role-based-subsets}{3.4.4.\hspace*{0.5em}P4Info Role-Based Subsets}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-restarts}{\mdref{sec-restarts}{3.5.\hspace*{0.5em}P4Runtime State Across Restarts}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-controller-use-cases}{\mdref{sec-controller-use-cases}{4.\hspace*{0.5em}Controller Use-cases}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-single-embedded-controller}{\mdref{sec-single-embedded-controller}{4.1.\hspace*{0.5em}Single Embedded Controller}}%mdk + +\mdtocitemx{sec-single-remote-controller}{\mdref{sec-single-remote-controller}{4.2.\hspace*{0.5em}Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-single-remote-controller}{\mdref{sec-embedded-single-remote-controller}{4.3.\hspace*{0.5em}Embedded + Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-two-remote-controllers}{\mdref{sec-embedded-two-remote-controllers}{4.4.\hspace*{0.5em}Embedded + Two Remote Controllers}}%mdk + +\mdtocitemx{sec-embedded-controller-two-high-availability-remote-controllers}{\mdref{sec-embedded-controller-two-high-availability-remote-controllers}{4.5.\hspace*{0.5em}Embedded Controller + Two High-Availability Remote Controllers}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-client-arbitration-and-controller-replication}{\mdref{sec-client-arbitration-and-controller-replication}{5.\hspace*{0.5em}Client Arbitration and Controller Replication}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-default-role}{\mdref{sec-default-role}{5.1.\hspace*{0.5em}Default Role}}%mdk + +\mdtocitemx{sec-arbitration-role-config}{\mdref{sec-arbitration-role-config}{5.2.\hspace*{0.5em}Role Config}}%mdk + +\mdtocitemx{sec-arbitration-updates}{\mdref{sec-arbitration-updates}{5.3.\hspace*{0.5em}Rules for Handling \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}} Messages Received from Controllers}}%mdk + +\mdtocitemx{sec-arbitration-notification}{\mdref{sec-arbitration-notification}{5.4.\hspace*{0.5em}Client Arbitration Notifications}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-the-p4info-message}{\mdref{sec-the-p4info-message}{6.\hspace*{0.5em}The P4Info Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-common-messages}{\mdref{sec-common-messages}{6.1.\hspace*{0.5em}Common Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-documentation-message}{\mdref{sec-documentation-message}{6.1.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}} Message}}%mdk + +\mdtocitemx{sec-preamble-message}{\mdref{sec-preamble-message}{6.1.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}} Message}}%mdk + +\mdtocitemx{sec-annotating-p4-entities-with-documentation}{\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3.\hspace*{0.5em}Annotating P4 Entities with \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}}%mdk + +\mdtocitemx{sec-structured-annotations}{\mdref{sec-structured-annotations}{6.1.4.\hspace*{0.5em}Structured Annotations}}%mdk + +\mdtocitemx{sec-sourcelocation-message}{\mdref{sec-sourcelocation-message}{6.1.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}} Message}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-pkginfo-message}{\mdref{sec-pkginfo-message}{6.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}} Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-annotating-p4-code-with-pkginfo}{\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1.\hspace*{0.5em}Annotating P4 code with PkgInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-id-allocation}{\mdref{sec-id-allocation}{6.3.\hspace*{0.5em}ID Allocation for P4Info Objects}}%mdk + +\mdtocitemx{sec-p4info-objects}{\mdref{sec-p4info-objects}{6.4.\hspace*{0.5em}P4Info Objects}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table}{\mdref{sec-table}{6.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}}%mdk + +\mdtocitemx{sec-action}{\mdref{sec-action}{6.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}}%mdk + +\mdtocitemx{sec-p4info-action-profile}{\mdref{sec-p4info-action-profile}{6.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}}%mdk + +\mdtocitemx{sec-counter-directcounter}{\mdref{sec-counter-directcounter}{6.4.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}}%mdk + +\mdtocitemx{sec-meter-directmeter}{\mdref{sec-meter-directmeter}{6.4.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}}%mdk + +\mdtocitemx{sec-controller-packet-meta}{\mdref{sec-controller-packet-meta}{6.4.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}}%mdk + +\mdtocitemx{sec-valueset}{\mdref{sec-valueset}{6.4.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}}%mdk + +\mdtocitemx{sec-register}{\mdref{sec-register}{6.4.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}}%mdk + +\mdtocitemx{sec-digest}{\mdref{sec-digest}{6.4.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}}%mdk + +\mdtocitemx{sec-p4info-extern}{\mdref{sec-p4info-extern}{6.4.10.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{\mdref{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{6.5.\hspace*{0.5em}Support for Arbitrary P4 Types with P4TypeInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-fwd-pipe-config}{\mdref{sec-p4-fwd-pipe-config}{7.\hspace*{0.5em}P4 Forwarding-Pipeline Configuration}}%mdk + +\mdtocitemx{sec-general-principles-for-message-formatting}{\mdref{sec-general-principles-for-message-formatting}{8.\hspace*{0.5em}General Principles for Message Formatting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-set-unset-protobuf-field}{\mdref{sec-set-unset-protobuf-field}{8.1.\hspace*{0.5em}Set / Unset Protobuf Field}}%mdk + +\mdtocitemx{sec-read-write-symmetry}{\mdref{sec-read-write-symmetry}{8.2.\hspace*{0.5em}Read-Write Symmetry}}%mdk + +\mdtocitemx{sec-zero-as-reserved-value}{\mdref{sec-zero-as-reserved-value}{8.3.\hspace*{0.5em}Zero as Reserved Value}}%mdk + +\mdtocitemx{sec-bytestrings}{\mdref{sec-bytestrings}{8.4.\hspace*{0.5em}Bytestrings}}%mdk + +\mdtocitemx{sec-representation-of-arbitrary-p4-types}{\mdref{sec-representation-of-arbitrary-p4-types}{8.5.\hspace*{0.5em}Representation of Arbitrary P4 Types}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-problem-statement}{\mdref{sec-problem-statement}{8.5.1.\hspace*{0.5em}Problem Statement}}%mdk + +\mdtocitemx{sec-p4-type-specifications-in-p4infoproto}{\mdref{sec-p4-type-specifications-in-p4infoproto}{8.5.2.\hspace*{0.5em}P4 Type Specifications in p4info.proto}}%mdk + +\mdtocitemx{sec-p4data-in-p4runtime-proto}{\mdref{sec-p4data-in-p4runtime-proto}{8.5.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}} in p4runtime.proto}}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{8.5.4.\hspace*{0.5em}Example}}%mdk + +\mdtocitemx{sec-enum-serializable-enum-and-error}{\mdref{sec-enum-serializable-enum-and-error}{8.5.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}, serializable \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}}%mdk + +\mdtocitemx{sec-user-defined-types}{\mdref{sec-user-defined-types}{8.5.6.\hspace*{0.5em}User-defined types}}%mdk + +\mdtocitemx{sec-trade-off-for-v1x-releases}{\mdref{sec-trade-off-for-v1x-releases}{8.5.7.\hspace*{0.5em}Trade-off for v1.x Releases}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-entity-msgs}{\mdref{sec-p4-entity-msgs}{9.\hspace*{0.5em}P4 Entity Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table-entry}{\mdref{sec-table-entry}{9.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-match-format}{\mdref{sec-match-format}{9.1.1.\hspace*{0.5em}Match Format}}%mdk + +\mdtocitemx{sec-action-specification}{\mdref{sec-action-specification}{9.1.2.\hspace*{0.5em}Action Specification}}%mdk + +\mdtocitemx{sec-default-entry}{\mdref{sec-default-entry}{9.1.3.\hspace*{0.5em}Default Entry}}%mdk + +\mdtocitemx{sec-constant-tables}{\mdref{sec-constant-tables}{9.1.4.\hspace*{0.5em}Constant Tables}}%mdk + +\mdtocitemx{sec-table-wildcard-reads}{\mdref{sec-table-wildcard-reads}{9.1.5.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-direct-resources}{\mdref{sec-direct-resources}{9.1.6.\hspace*{0.5em}Direct Resources}}%mdk + +\mdtocitemx{sec-idle-timeout}{\mdref{sec-idle-timeout}{9.1.7.\hspace*{0.5em}Idle-timeout}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-and-group}{\mdref{sec-action-profile-member-and-group}{9.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-programming}{\mdref{sec-action-profile-member-programming}{9.2.1.\hspace*{0.5em}Action Profile Member Programming}}%mdk + +\mdtocitemx{sec-action-profile-group-programming}{\mdref{sec-action-profile-group-programming}{9.2.2.\hspace*{0.5em}Action Profile Group Programming}}%mdk + +\mdtocitemx{sec-oneshot}{\mdref{sec-oneshot}{9.2.3.\hspace*{0.5em}One Shot Action Selector Programming}}%mdk + +\mdtocitemx{action-selector-constraints}{\mdref{action-selector-constraints}{9.2.4.\hspace*{0.5em}Constraints on action selector programming}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-counterentry-directcounterentry}{\mdref{sec-counterentry-directcounterentry}{9.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directcounterentry}{\mdref{sec-directcounterentry}{9.3.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\mdtocitemx{sec-counterentry}{\mdref{sec-counterentry}{9.3.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-meterentry-directmeterentry}{\mdref{sec-meterentry-directmeterentry}{9.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directmeterentry}{\mdref{sec-directmeterentry}{9.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\mdtocitemx{sec-meterentry}{\mdref{sec-meterentry}{9.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}}%mdk + +\mdtocitemx{sec-metercounterdata}{\mdref{sec-metercounterdata}{9.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-packetreplicationengineentry}{\mdref{sec-packetreplicationengineentry}{9.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-multicastgroupentry}{\mdref{sec-multicastgroupentry}{9.5.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}}%mdk + +\mdtocitemx{sec-clonesessionentry}{\mdref{sec-clonesessionentry}{9.5.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-valuesetentry}{\mdref{sec-valuesetentry}{9.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}}%mdk + +\mdtocitemx{sec-registerentry}{\mdref{sec-registerentry}{9.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}}%mdk + +\mdtocitemx{sec-digestentry}{\mdref{sec-digestentry}{9.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}}%mdk + +\mdtocitemx{sec-extern-entry}{\mdref{sec-extern-entry}{9.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-error-reporting-messages}{\mdref{sec-error-reporting-messages}{10.\hspace*{0.5em}Error Reporting Messages}}%mdk + +\mdtocitemx{sec-atomicity-of-individual-write-and-read-operations}{\mdref{sec-atomicity-of-individual-write-and-read-operations}{11.\hspace*{0.5em}Atomicity of Individual \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} Operations}}%mdk + +\mdtocitemx{sec-write-rpc}{\mdref{sec-write-rpc}{12.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-batching-and-ordering-of-updates}{\mdref{sec-batching-and-ordering-of-updates}{12.1.\hspace*{0.5em}Batching and Ordering of Updates}}%mdk + +\mdtocitemx{sec-batch-atomicity}{\mdref{sec-batch-atomicity}{12.2.\hspace*{0.5em}Batch Atomicity}}%mdk + +\mdtocitemx{sec-error-reporting}{\mdref{sec-error-reporting}{12.3.\hspace*{0.5em}Error Reporting}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-read-rpc}{\mdref{sec-read-rpc}{13.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-nomenclature}{\mdref{sec-nomenclature}{13.1.\hspace*{0.5em}Nomenclature}}%mdk + +\mdtocitemx{sec-wildcard-reads}{\mdref{sec-wildcard-reads}{13.2.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-batch-processing}{\mdref{sec-batch-processing}{13.3.\hspace*{0.5em}Batch Processing}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{13.3.1.\hspace*{0.5em}Example}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-parallelism-of-read-and-write-requests}{\mdref{sec-parallelism-of-read-and-write-requests}{13.4.\hspace*{0.5em}Parallelism of Read and Write Requests}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-setforwardingpipelineconfig-rpc}{\mdref{sec-setforwardingpipelineconfig-rpc}{14.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-getforwardingpipelineconfig-rpc}{\mdref{sec-getforwardingpipelineconfig-rpc}{15.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-p4runtime-stream-messages}{\mdref{sec-p4runtime-stream-messages}{16.\hspace*{0.5em}P4Runtime Stream Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-packet-i_o}{\mdref{sec-packet-i_o}{16.1.\hspace*{0.5em}Packet I/O}}%mdk + +\mdtocitemx{sec-client-arbitration-update}{\mdref{sec-client-arbitration-update}{16.2.\hspace*{0.5em}Client Arbitration Update}}%mdk + +\mdtocitemx{sec-digest-messages}{\mdref{sec-digest-messages}{16.3.\hspace*{0.5em}Digest Messages}}%mdk + +\mdtocitemx{sec-table-idle-timeout-notification}{\mdref{sec-table-idle-timeout-notification}{16.4.\hspace*{0.5em}Table Idle Timeout Notification}}%mdk + +\mdtocitemx{sec-architecture-specific-notifications}{\mdref{sec-architecture-specific-notifications}{16.5.\hspace*{0.5em}Architecture-Specific Notifications}}%mdk + +\mdtocitemx{sec-stream-error-reporting}{\mdref{sec-stream-error-reporting}{16.6.\hspace*{0.5em}Stream Error Reporting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-examples-of-streamerror-messages}{\mdref{sec-examples-of-streamerror-messages}{16.6.1.\hspace*{0.5em}Examples of \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}} Messages}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-capabilities-rpc}{\mdref{sec-capabilities-rpc}{17.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}} RPC}}%mdk + +\mdtocitemx{sec-portability-considerations}{\mdref{sec-portability-considerations}{18.\hspace*{0.5em}Portability Considerations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-psa-metadata-translation}{\mdref{sec-psa-metadata-translation}{18.1.\hspace*{0.5em}PSA Metadata Translation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-translation-of-port-numbers}{\mdref{sec-translation-of-port-numbers}{18.1.1.\hspace*{0.5em}Translation of Port Numbers}}%mdk + +\mdtocitemx{sec-translation-of-packet-io-header-fields}{\mdref{sec-translation-of-packet-io-header-fields}{18.1.2.\hspace*{0.5em}Translation of Packet-IO Header Fields}}%mdk + +\mdtocitemx{sec-translation-of-match-fields}{\mdref{sec-translation-of-match-fields}{18.1.3.\hspace*{0.5em}Translation of Match Fields}}%mdk + +\mdtocitemx{sec-translation-of-action-parameters}{\mdref{sec-translation-of-action-parameters}{18.1.4.\hspace*{0.5em}Translation of Action Parameters}}%mdk + +\mdtocitemx{sec-port-translation-for-psa-extern-apis}{\mdref{sec-port-translation-for-psa-extern-apis}{18.1.5.\hspace*{0.5em}Port Translation for PSA Extern APIs}}%mdk + +\mdtocitemx{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{\mdref{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{18.1.6.\hspace*{0.5em}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-versioning}{\mdref{sec-p4runtime-versioning}{19.\hspace*{0.5em}P4Runtime Versioning}}%mdk + +\mdtocitemx{sec-extending-p4runtime}{\mdref{sec-extending-p4runtime}{20.\hspace*{0.5em}Extending P4Runtime for non-PSA Architectures}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-p4runtime-for-architecture-specific-externs}{\mdref{sec-extending-p4runtime-for-architecture-specific-externs}{20.1.\hspace*{0.5em}Extending P4Runtime for Architecture-Specific Externs}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-the-p4info-message}{\mdref{sec-extending-the-p4info-message}{20.1.1.\hspace*{0.5em}Extending the P4Info message}}%mdk + +\mdtocitemx{sec-extending-the-p4runtime-service}{\mdref{sec-extending-the-p4runtime-service}{20.1.2.\hspace*{0.5em}Extending the P4Runtime Service}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-architecture-specific-table-extensions}{\mdref{sec-architecture-specific-table-extensions}{20.2.\hspace*{0.5em}Architecture-Specific Table Extensions}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-new-match-types}{\mdref{sec-new-match-types}{20.2.1.\hspace*{0.5em}New Match Types}}%mdk + +\mdtocitemx{sec-new-table-properties}{\mdref{sec-new-table-properties}{20.2.2.\hspace*{0.5em}New Table Properties}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-known-limitations-of-current-p4runtime-version}{\mdref{sec-known-limitations-of-current-p4runtime-version}{21.\hspace*{0.5em}Known Limitations of Current P4Runtime Version}}%mdk + +\mdtocitemx{sec-appendix}{\mdref{sec-appendix}{A.\hspace*{0.5em}Appendix}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-revision-history}{\mdref{sec-revision-history}{A.1.\hspace*{0.5em}Revision History}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-changes-in-v130}{\mdref{sec-changes-in-v130}{A.1.1.\hspace*{0.5em}Changes in v1.3.0}}%mdk + +\mdtocitemx{sec-changes-in-v120}{\mdref{sec-changes-in-v120}{A.1.2.\hspace*{0.5em}Changes in v1.2.0}}%mdk + +\mdtocitemx{sec-changes-in-v110}{\mdref{sec-changes-in-v110}{A.1.3.\hspace*{0.5em}Changes in v1.1.0}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-annotations}{\mdref{sec-p4-annotations}{A.2.\hspace*{0.5em}P4 Annotations}}%mdk + +\mdtocitemx{sec-value-set-example}{\mdref{sec-value-set-example}{A.3.\hspace*{0.5em}A More Complex Value Set Example}}%mdk + +\mdtocitemx{sec-guidelines-for-implementations}{\mdref{sec-guidelines-for-implementations}{A.4.\hspace*{0.5em}Guidelines for Implementations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-grpc-metadata-maximum-size}{\mdref{sec-grpc-metadata-maximum-size}{A.4.1.\hspace*{0.5em}gRPC Metadata Maximum Size}}%mdk + +\mdtocitemx{sec-grpc-server-maximum-receive-message-size}{\mdref{sec-grpc-server-maximum-receive-message-size}{A.4.2.\hspace*{0.5em}gRPC Server Maximum Receive Message Size}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-bibliography}{\mdref{sec-bibliography}{References}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{215} +\begin{mdtoc}%mdk + +\section*{Figures}\label{sec-figures}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{fig-reference-architecture}{\mdref{fig-reference-architecture}{\mdcaptionlabel{1}. P4Runtime Reference Architecture.}}%mdk + +\mdtocitemx{fig-single-embedded-controller}{\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}. Use-Case: Single Embedded Controller}}%mdk + +\mdtocitemx{fig-single-remote-controller}{\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}. Use-Case: Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-single-remote-controller}{\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}. Use-Case: Embedded Plus Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-controllers}{\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}. Use-Case: Embedded Plus Two Remote Controllers}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-ha-controllers}{\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}. Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk + +\mdtocitemx{fig-error-report}{\mdref{fig-error-report}{\mdcaptionlabel{7}. P4Runtime Error Report Message Format}}%mdk + +\mdtocitemx{fig-psa-metadata-translation}{\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}. P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{216} +\begin{mdtoc}%mdk + +\section*{Tables}\label{sec-tables}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{tab-mapping-p4-obj-ids}{\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}. Mapping of P4Info object type to 8-bit ID prefix value}}%mdk + +\mdtocitemx{tab-format-p4-obj-ids}{\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}. Format of P4Info object IDs}}%mdk + +\mdtocitemx{tab-exmpl-p4-obj-ids}{\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}. Example of statically-assigned P4Info object IDs}}%mdk + +\mdtocitemx{tab-valid-bytestring-encoding}{\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}. Examples of Valid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-invalid-bytestring-encoding}{\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}. Examples of Invalid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-p4-type-usage}{\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}. P4 Type Usage}}%mdk + +\mdtocitemx{tab-p4-annotations}{\mdref{tab-p4-annotations}{\mdcaptionlabel{7}. P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk + +%mdk-data-line={218} +\section{\mdline{218}1.\hspace*{0.5em}\mdline{218}Introduction and Scope}\label{sec-introduction-and-scope}%mdk%mdk + +%mdk-data-line={220} +\noindent\mdline{220}This document is published by the \mdline{220}\emph{P4.org API Working Group}\mdline{220}, which was +chartered\mdline{221}~[\mdcite{p4apiwgcharter}{17}]\mdline{221} to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called \mdline{223}\emph{P4Runtime}\mdline{223}. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +\mdline{226}\href{https://github.com/p4lang/p4runtime/tree/v1.3.0/proto}{https://github.com/p4lang/p4runtime/tree/v1.3.0/proto}\mdline{226}.%mdk + +%mdk-data-line={228} +\subsection{\mdline{228}1.1.\hspace*{0.5em}\mdline{228}P4 Language Version Applicability}\label{sec-p4-language-version-applicability}%mdk%mdk + +%mdk-data-line={230} +\noindent\mdline{230}P4Runtime is designed to be implemented in conjunction with the P4\mdline{230}\mdsub{16}\mdline{230} language +version or later. P4\mdline{231}\mdsub{14}\mdline{231} programs should be translated into P4\mdline{231}\mdsub{16}\mdline{231} to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P4\mdline{233}\mdsub{16}\mdline{233} 1.0, but were introduced in P4\mdline{233}\mdsub{16}\mdline{233} 1.1.0\mdline{233}~[\mdcite{p4revisions110}{29}]\mdline{233}. For +this version of P4Runtime, we recommend using P4\mdline{234}\mdsub{16}\mdline{234} 1.2.1\mdline{234}~[\mdcite{p4spec}{1}]\mdline{234}.%mdk + +%mdk-data-line={236} +\subsection{\mdline{236}1.2.\hspace*{0.5em}\mdline{236}In Scope}\label{sec-in-scope}%mdk%mdk + +%mdk-data-line={238} +\noindent\mdline{238}This specification document defines the \mdline{238}\emph{semantics}\mdline{238} of \mdline{238}\emph{P4Runtime}\mdline{238} messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime:%mdk + +%mdk-data-line={242} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={242} +\item\mdline{242}Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA)\mdline{243}~[\mdcite{psa}{19}]\mdline{243} externs (\mdline{243}e.g.\mdline{243} Counters, Meters, Action +Profiles, \mdline{244}\dots{}\mdline{244}). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0.%mdk + +%mdk-data-line={246} +\item\mdline{246}Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism.%mdk + +%mdk-data-line={248} +\item\mdline{248}Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy.%mdk + +%mdk-data-line={251} +\item\mdline{251}Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities.%mdk + +%mdk-data-line={253} +\item\mdline{253}Packet I/O to enable streaming packets to \mdline{253}\&\mdline{253} from the control plane.%mdk + +%mdk-data-line={254} +\item\mdline{254}Batching support, with different atomicity guarantees.%mdk + +%mdk-data-line={255} +\item\mdline{255}In-the-field device-reconfiguration with a new P4 data plane.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={257} +\noindent\mdline{257}The following are in the scope of this specification document:%mdk + +%mdk-data-line={259} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={259} +\item\mdline{259}Rationale for the P4Runtime design.%mdk + +%mdk-data-line={260} +\item\mdline{260}Reference architecture and use-cases for deploying a P4Runtime service.%mdk + +%mdk-data-line={261} +\item\mdline{261}Detailed description of the API semantics.%mdk + +%mdk-data-line={262} +\item\mdline{262}Requirements for conformant implementations of the API.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={264} +\subsection{\mdline{264}1.3.\hspace*{0.5em}\mdline{264}Not In Scope}\label{sec-not-in-scope}%mdk%mdk + +%mdk-data-line={266} +\noindent\mdline{266}The following are not in scope of P4Runtime:%mdk + +%mdk-data-line={268} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={268} +\item\mdline{268}Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +\mdline{273}[\mdcite{openconfig}{35}]\mdline{273}. An open source implementation of these APIs is also in progress +as part of the Stratum project\mdline{274}~[\mdcite{stratum}{37}]\mdline{274}.%mdk + +%mdk-data-line={275} +\item\mdline{275}Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={280} +\noindent\mdline{280}The following are not in scope of this specification document:%mdk + +%mdk-data-line={282} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={282} +\item\mdline{282}Description of the P4 programming language; it is assumed that the reader is +already familiar with P4\mdline{283}\mdsub{16}\mdline{283}~[\mdcite{p4spec}{1}]\mdline{283}.%mdk + +%mdk-data-line={284} +\item\mdline{284}Descriptions of gRPC and Protobuf files in general.%mdk + +%mdk-data-line={285} +\item\mdline{285}Controller\mdline{285}~\mdref{sec-arbitration-role-config}{role}\mdline{285} definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={289} +\section{\mdline{289}2.\hspace*{0.5em}\mdline{289}Terms and Definitions}\label{sec-terms-and-definitions}%mdk%mdk + +%mdk-data-line={291} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries arbitration}}%mdk + +%mdk-data-line={291} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{291}Refers to the process through which P4Runtime ensures that at any given +time, there is a single primary controller (\mdline{292}i.e.\mdline{292} a client with write access) +for a given role. Also referred to as \mdline{293}\textquotedblleft{}client arbitration\textquotedblright{}\mdline{293}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries client}}%mdk + +%mdk-data-line={295} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{295}The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries COS}}%mdk + +%mdk-data-line={299} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{299}Class of Service. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries device}}%mdk + +%mdk-data-line={301} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{301}Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries entity}}%mdk + +%mdk-data-line={305} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{305}An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries gRPC}}%mdk + +%mdk-data-line={308} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{308}gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +\mdline{309}[\mdcite{grpc}{9}]\mdline{309}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries HA}}%mdk + +%mdk-data-line={311} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{311}High-Availability. Refers to a redundancy architecture. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Instrumentation}}%mdk + +%mdk-data-line={313} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{313}The part of the P4Runtime server which implements the calls to the device or +target native \mdline{314}\textquotedblleft{}SDK\textquotedblright{}\mdline{314} or backend. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries IPC}}%mdk + +%mdk-data-line={316} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{316}Inter-Process Communication. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Blob}}%mdk + +%mdk-data-line={318} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{318}A more colloquial term for P4 Device Config (Blob = Binary Large Object). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Device Config}}%mdk + +%mdk-data-line={320} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{320}The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its \mdline{322}\textquotedblleft{}program.\textquotedblright{}\mdline{322} +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4Info}}%mdk + +%mdk-data-line={324} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{324}Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4RT}}%mdk + +%mdk-data-line={328} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{328}Abbreviation for P4Runtime. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Protobuf (Protocol Buffers)}}%mdk + +%mdk-data-line={330} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{330}The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See\mdline{331}~[\mdcite{proto}{21}]\mdline{331}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries PSA}}%mdk + +%mdk-data-line={333} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{333}Portable Switch Architecture\mdline{333}~[\mdcite{psa}{19}]\mdline{333}; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RPC}}%mdk + +%mdk-data-line={337} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{337}Remote Procedure Call. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RTT}}%mdk + +%mdk-data-line={339} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{339}Round-trip time. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN}}%mdk + +%mdk-data-line={341} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{341}Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network \mdline{346}\emph{controller}\mdline{346}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN port}}%mdk + +%mdk-data-line={348} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{348}A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries server}}%mdk + +%mdk-data-line={352} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{352}The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries stream}}%mdk + +%mdk-data-line={356} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{356}Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (\mdline{357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{357}), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and client arbitration, among other things. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries switch config}}%mdk + +%mdk-data-line={361} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{361}Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries target}}%mdk + +%mdk-data-line={366} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{366}The hardware or software entity which \mdline{366}\textquotedblleft{}executes\textquotedblright{}\mdline{366} the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with \mdline{367}\textquotedblleft{}device\textquotedblright{}\mdline{367}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries URI}}%mdk + +%mdk-data-line={369} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{369}Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={373} +\section{\mdline{373}3.\hspace*{0.5em}\mdline{373}Reference Architecture}\label{sec-reference-architecture}%mdk%mdk + +%mdk-data-line={375} +\noindent\mdline{375}Figure\mdline{375}~\mdref{fig-reference-architecture}{\mdcaptionlabel{1}}\mdline{375} represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. P4Runtime only grants write access to a +single primary controller for each read/write entity. A role defines a grouping +of P4 entities. P4Runtime allows for a primary controller for each role, and a +role-based client arbitration scheme ensures only one controller has +write access to each read/write entity, or the pipeline config itself. Any +controller may perform read access to any entity or the pipeline config. Later +sections describe this in detail. For the sake of brevity, the term controller +may refer to one or more controllers.%mdk + +%mdk-data-line={386} +\mdline{386}The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +\mdline{389}[\mdcite{p4runtimerepo}{15}]\mdline{389}. It may be compiled via protoc\mdline{389} \mdline{389}\textemdash{}\mdline{389} the Protobuf compiler\mdline{389} \mdline{389}\textemdash{}\mdline{389} +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server.%mdk + +%mdk-data-line={394} +\mdline{394}Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository\mdline{395}~[\mdcite{pirepo}{16}]\mdline{395}. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, \mdline{397}e.g.\mdline{397} via callbacks, thus reducing the burden of implementing +P4Runtime.%mdk + +%mdk-data-line={400} +\mdline{400}The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard.%mdk + +%mdk-data-line={404} +\mdline{404}The controller can also set the \mdline{404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{404}, which amounts to +installing and running the compiled P4 program output, which is included in the +\mdline{406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{406} Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +\mdline{408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{408} to retrieve the device config and the P4Info.%mdk + +%mdk-data-line={411} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={412} +\noindent\mdline{412}\includegraphics[keepaspectratio=true,height=7cm]{build/reference-architecture}{}\mdline{412}%mdk + +%mdk-data-line={413} +\mdhr{}%mdk + +%mdk-data-line={414} +\noindent\mdline{414}\mdcaption{\textbf{Figure~\mdcaptionlabel{1}.}~\mdcaptiontext{P4Runtime Reference Architecture.}}%mdk +%mdk +\end{mdcenter}\label{fig-reference-architecture}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={418} +\subsection{\mdline{418}3.1.\hspace*{0.5em}\mdline{418}P4Runtime Service Implementation}\label{sec-p4runtime-service-implementation}%mdk%mdk + +%mdk-data-line={420} +\noindent\mdline{420}The P4Runtime API is implemented by a program that runs a gRPC server which +binds an implementation of auto-generated P4Runtime Service interface. This +program is called the \mdline{422}\textquotedblleft{}P4Runtime server.\textquotedblright{}\mdline{422} The server must listen on TCP port +9559 by default, which is the port that has been allocated by IANA for the +P4Runtime service. Servers should allow users to override the default port +using a configuration file or flag when starting the server. Uses of other +port numbers as the default should be discontinued.%mdk + +%mdk-data-line={428} +\subsubsection{\mdline{428}3.1.1.\hspace*{0.5em}\mdline{428}Security concerns}\label{sec-security-concerns}%mdk%mdk + +%mdk-data-line={430} +\noindent\mdline{430}Appropriate measures and security best practices must be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. Mutual TLS (mTLS) may +be used to facilitate the authentication of the client by the server and +vice-versa.%mdk + +%mdk-data-line={439} +\subsection{\mdline{439}3.2.\hspace*{0.5em}\mdline{439}Idealized Workflow}\label{sec-idealized-workflow}%mdk%mdk + +%mdk-data-line={441} +\noindent\mdline{441}In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the \mdline{442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{442} +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a \mdline{444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{444} +RPC. Metadata in the P4Info describes both the overall program itself +(\mdline{446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{446}) as well as all entity instances derived from the P4 program\mdline{446} \mdline{446}\textemdash{}\mdline{446} +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise \mdline{448}\textquotedblleft{}handle\textquotedblright{}\mdline{448} used in API +calls.%mdk + +%mdk-data-line={451} +\mdline{451}In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible.%mdk + +%mdk-data-line={457} +\mdline{457}In some use cases, it is expected that a controller will store a +collection of multiple P4 \mdline{458}\textquotedblleft{}packages\textquotedblright{}\mdline{458}, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the \mdline{460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{460} from the target via the +\mdline{461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineRequest}}}\mdline{461} RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state.%mdk + +%mdk-data-line={465} +\subsection{\mdline{465}3.3.\hspace*{0.5em}\mdline{465}P4 as a Behavioral Description Language}\label{sec-p4-as-behavioral-description-language}%mdk%mdk + +%mdk-data-line={467} +\noindent\mdline{467}P4 can be considered a behavioral description of a switching device which may or +may not execute \mdline{468}\textquotedblleft{}P4\textquotedblright{}\mdline{468} natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a \mdline{470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineRequest}}}\mdline{470} to +change its pipeline \mdline{471}\textquotedblleft{}program\textquotedblright{}\mdline{471}, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device.%mdk + +%mdk-data-line={477} +\mdline{477}While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API.%mdk + +%mdk-data-line={486} +\mdline{486}In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the \mdline{487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{487} +message as well as the embedded \mdline{488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{488} fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections.%mdk + +%mdk-data-line={492} +\subsection{\mdline{492}3.4.\hspace*{0.5em}\mdline{492}Alternative Workflows}\label{sec-alternative-workflows}%mdk%mdk + +%mdk-data-line={494} +\noindent\mdline{494}Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary.%mdk + +%mdk-data-line={498} +\subsubsection{\mdline{498}3.4.1.\hspace*{0.5em}\mdline{498}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}\label{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}%mdk%mdk + +%mdk-data-line={500} +\noindent\mdline{500}In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +\mdline{502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{502}. The device\mdline{502}'\mdline{502}s configuration might be derived via some other +means to implement the P4 source code\mdline{503}'\mdline{503}s intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane.%mdk + +%mdk-data-line={507} +\subsubsection{\mdline{507}3.4.2.\hspace*{0.5em}\mdline{507}No P4 Source Available, P4Info Available}\label{sec-no-p4-source-available-p4info-available}%mdk%mdk + +%mdk-data-line={509} +\noindent\mdline{509}In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are:%mdk + +%mdk-data-line={512} +\begin{enumerate}%mdk + +%mdk-data-line={512} +\item{} +%mdk-data-line={512} +\mdline{512}The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security.%mdk%mdk + +%mdk-data-line={515} +\item{} +%mdk-data-line={515} +\mdline{515}The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={518} +\noindent\mdline{518}As discussed in Section\mdline{518}~\mdref{sec-p4-as-behavioral-description-language}{3.3}\mdline{518}, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, \mdline{521}e.g.\mdline{521} documentation.%mdk + +%mdk-data-line={523} +\subsubsection{\mdline{523}3.4.3.\hspace*{0.5em}\mdline{523}Partial P4Info and P4 Source are Available}\label{sec-partial-p4info-and-p4-source-are-available}%mdk%mdk + +%mdk-data-line={525} +\noindent\mdline{525}In this situation, a subset of the target\mdline{525}'\mdline{525}s pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code.%mdk + +%mdk-data-line={532} +\subsubsection{\mdline{532}3.4.4.\hspace*{0.5em}\mdline{532}P4Info Role-Based Subsets}\label{sec-p4info-role-based-subsets}%mdk%mdk + +%mdk-data-line={534} +\noindent\mdline{534}In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more.%mdk + +%mdk-data-line={538} +\subsection{\mdline{538}3.5.\hspace*{0.5em}\mdline{538}P4Runtime State Across Restarts}\label{sec-restarts}%mdk%mdk + +%mdk-data-line={540} +\noindent\mdline{540}All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade.%mdk + +%mdk-data-line={546} +\section{\mdline{546}4.\hspace*{0.5em}\mdline{546}Controller Use-cases}\label{sec-controller-use-cases}%mdk%mdk + +%mdk-data-line={548} +\noindent\mdline{548}P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +\mdline{550}\mdref{sec-client-arbitration-and-controller-replication}{section}\mdline{550}. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime\mdline{552}'\mdline{552}s flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex.%mdk + +%mdk-data-line={555} +\subsection{\mdline{555}4.1.\hspace*{0.5em}\mdline{555}Single Embedded Controller}\label{sec-single-embedded-controller}%mdk%mdk + +%mdk-data-line={557} +\noindent\mdline{557}Figure\mdline{557}~\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}}\mdline{557} shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases.%mdk + +%mdk-data-line={562} +\mdline{562}P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC.%mdk + +%mdk-data-line={567} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={568} +\noindent\mdline{568}\includegraphics[keepaspectratio=true,height=6cm]{build/single-embedded-controller}{}\mdline{568}%mdk + +%mdk-data-line={569} +\mdhr{}%mdk + +%mdk-data-line={570} +\noindent\mdline{570}\mdcaption{\textbf{Figure~\mdcaptionlabel{2}.}~\mdcaptiontext{Use-Case: Single Embedded Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-embedded-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={574} +\subsection{\mdline{574}4.2.\hspace*{0.5em}\mdline{574}Single Remote Controller}\label{sec-single-remote-controller}%mdk%mdk + +%mdk-data-line={576} +\noindent\mdline{576}Figure\mdline{576}~\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}}\mdline{576} shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections.%mdk + +%mdk-data-line={581} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={582} +\noindent\mdline{582}\includegraphics[keepaspectratio=true,height=7cm]{build/single-remote-controller}{}\mdline{582}%mdk + +%mdk-data-line={583} +\mdhr{}%mdk + +%mdk-data-line={584} +\noindent\mdline{584}\mdcaption{\textbf{Figure~\mdcaptionlabel{3}.}~\mdcaptiontext{Use-Case: Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={588} +\subsection{\mdline{588}4.3.\hspace*{0.5em}\mdline{588}Embedded\mdline{588} \mdline{588}+ Single Remote Controller}\label{sec-embedded-single-remote-controller}%mdk%mdk + +%mdk-data-line={590} +\noindent\mdline{590}Figure\mdline{590}~\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}}\mdline{590} illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller.%mdk + +%mdk-data-line={597} +\mdline{597}For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables.%mdk + +%mdk-data-line={601} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={602} +\noindent\mdline{602}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-single-remote-controller}{}\mdline{602}%mdk + +%mdk-data-line={603} +\mdhr{}%mdk + +%mdk-data-line={604} +\noindent\mdline{604}\mdcaption{\textbf{Figure~\mdcaptionlabel{4}.}~\mdcaptiontext{Use-Case: Embedded Plus Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={609} +\subsection{\mdline{609}4.4.\hspace*{0.5em}\mdline{609}Embedded\mdline{609} \mdline{609}+ Two Remote Controllers}\label{sec-embedded-two-remote-controllers}%mdk%mdk + +%mdk-data-line={611} +\noindent\mdline{611}Figure\mdline{611}~\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}}\mdline{611} illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +\mdline{614}e.g.\mdline{614} routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership.%mdk + +%mdk-data-line={617} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={618} +\noindent\mdline{618}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-controllers}{}\mdline{618}%mdk + +%mdk-data-line={619} +\mdhr{}%mdk + +%mdk-data-line={620} +\noindent\mdline{620}\mdcaption{\textbf{Figure~\mdcaptionlabel{5}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={625} +\subsection{\mdline{625}4.5.\hspace*{0.5em}\mdline{625}Embedded Controller\mdline{625} \mdline{625}+ Two High-Availability Remote Controllers}\label{sec-embedded-controller-two-high-availability-remote-controllers}%mdk%mdk + +%mdk-data-line={627} +\noindent\mdline{627}Figure\mdline{627}~\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}}\mdline{627} illustrates a single +embedded controller plus two remote controllers in an active-standby (\mdline{628}i.e.\mdline{628} +primary-backup) HA (High-Availability) configuration. Controller \mdline{629}\#\mdline{629}1 is the +active controller and is in charge of some entities. If it fails, Controller \mdline{630}\#\mdline{630}2 +takes over and manages the tables formerly owned by Controller \mdline{631}\#\mdline{631}1. The mechanics +of HA architectures are beyond the scope of this document, but the P4Runtime +role-based client arbitration scheme supports it.%mdk + +%mdk-data-line={635} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={636} +\noindent\mdline{636}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-ha-controllers}{}\mdline{636}%mdk + +%mdk-data-line={637} +\mdhr{}%mdk + +%mdk-data-line={638} +\noindent\mdline{638}\mdcaption{\textbf{Figure~\mdcaptionlabel{6}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-ha-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={643} +\section{\mdline{643}5.\hspace*{0.5em}\mdline{643}Client Arbitration and Controller Replication}\label{sec-client-arbitration-and-controller-replication}%mdk%mdk + +%mdk-data-line={646} +\noindent\mdline{646}The P4Runtime interface allows multiple clients (\mdline{646}i.e.\mdline{646} controllers) to be +connected to the P4Runtime server running on the device at the same time for the +following reasons:%mdk + +%mdk-data-line={650} +\begin{enumerate}%mdk + +%mdk-data-line={650} +\item{} +%mdk-data-line={650} +\mdline{650}Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, \mdline{651}\textquotedblleft{}roles\textquotedblright{}\mdline{651} (or \mdline{651}\textquotedblleft{}realms\textquotedblright{}\mdline{651}) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +primary and the rest are backups. Role definition, \mdline{654}i.e.\mdline{654} how P4 entities get +assigned to each role, is \mdline{655}\textbf{out-of-scope}\mdline{655} of this document.%mdk%mdk + +%mdk-data-line={657} +\item{} +%mdk-data-line={657} +\mdline{657}Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby backup controllers. These can already have a connection +open, which can help them become primary more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={663} +\noindent\mdline{663}To support multiple controllers, P4Runtime uses the streaming channel (available +via \mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{664} RPC) for session management. The workflow is described as +follows:%mdk + +%mdk-data-line={667} +\begin{itemize}%mdk + +%mdk-data-line={667} +\item{} +%mdk-data-line={667} +\mdline{667}Each controller instance (\mdline{667}e.g.\mdline{667} a controller process) can participate in one or +more roles. For each (\mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{668}, \mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{668}), the controller receives an +\mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{669}. This \mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{669} can be the same for different roles and/or +devices, as long as the tuple (\mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{670}, \mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{670}, \mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{670}) is +unique. For each (\mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{671}, \mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{671}) that the controller wishes to +control, it establishes a \mdline{672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{672} with the P4Runtime server +responsible for that device, and sends a \mdline{673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{673} message +containing that tuple of (\mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{674}, \mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{674}, \mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{674}) values. The +P4Runtime server selects a primary independently for each (\mdline{675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{675}, +\mdline{676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{676}) pair. The primary is the client that has the highest \mdline{676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{676} +that the device has ever received for the same (\mdline{677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{677}, +\mdline{678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{678}) values. A connection between a controller instance and a device id +\mdline{679}\textemdash{}\mdline{679} which involves a persistent \mdline{679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{679} \mdline{679}\textemdash{}\mdline{679} can be referred to as a +P4Runtime client.%mdk + +%mdk-data-line={682} +\mdline{682}Note that the P4Runtime server does not assign a \mdline{682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{682} or \mdline{682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{682} to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the \mdline{684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{684} values used for each +\mdline{685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{685}. The P4Runtime server only keeps track of the (\mdline{685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{685}, +\mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{686}, \mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{686}) of each \mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{686} that has sent a successful +\mdline{687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{687} message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +\mdline{689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{689} message to identify which client is making the \mdline{689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{689}, +not only the \mdline{690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{690}. This enables controllers to re-use the same +numeric \mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{691} values across different (\mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{691}, \mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{691}) +pairs. P4Runtime does not require \mdline{692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{692} values be reused across such +different (\mdline{693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{693}, \mdline{693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{693}) pairs; it allows it.%mdk%mdk + +%mdk-data-line={695} +\item{} +%mdk-data-line={695} +\mdline{695}To start a controller session, a controller first opens a bidirectional stream +channel to the server via the \mdline{696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{696} RPC for each device. This stream +will be used for two purposes:%mdk + +%mdk-data-line={699} +\begin{itemize}%mdk + +%mdk-data-line={699} +\item{} +%mdk-data-line={699} +\mdline{699}\textbf{Session management:}\mdline{699} As soon as the controller opens the stream +channel, it sends a \mdline{700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{700} message to the switch. The +controller populates the \mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{701} field in this message +using its \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{702} and \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{702}, as well as the \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{702} of the +device. Note that the \mdline{703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{703} field in the \mdline{703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{703} is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below.%mdk%mdk + +%mdk-data-line={707} +\item{} +%mdk-data-line={707} +\mdline{707}\textbf{Streaming of notifications (e.g. digests) and packet I/O:}\mdline{707} The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the primary controller can participate in +packet I/O. This feature is explained in more details in the\mdline{711}~\mdref{sec-packet-i_o}{Packet +I/O}\mdline{712} section.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={714} +\mdline{714}Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state.%mdk%mdk + +%mdk-data-line={717} +\item{} +%mdk-data-line={717} +\mdline{717}Note that the stream is opened per device. In case a switching platform has +multiple devices (\mdline{718}e.g.\mdline{718} multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different primary clients for +different devices. In this case, it is the responsibility of the P4Runtime +server to keep track of the primary for each device (and role). More +specifically, the P4Runtime server will know which stream corresponds to the +primary controller for each pair of (\mdline{723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{723}, \mdline{723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{723}) at any point of +time.%mdk%mdk + +%mdk-data-line={726} +\item{} +%mdk-data-line={726} +\mdline{726}The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered \mdline{727}\textquotedblleft{}offline\textquotedblright{}\mdline{727} or +\mdline{728}\textquotedblleft{}dead\textquotedblright{}\mdline{728} as soon as its stream channel to the switch is broken. When a primary +channel gets broken: (i) an advisory message is sent to all other controllers +for that \mdline{730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{730} and \mdline{730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{730}, as described in the +\mdline{731}\mdref{sec-arbitration-notification}{following section}\mdline{731} (ii) the P4Runtime server +will be without a primary controller, until a client sends a successful +\mdline{733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{733} (as per the rules in a +\mdline{734}\mdref{sec-arbitration-updates}{later section}\mdline{734}).%mdk%mdk + +%mdk-data-line={736} +\item{} +%mdk-data-line={736} +\mdline{736}The mechanism via which the controller receives the P4Runtime server details +which includes the \mdline{737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{737}, \mdline{737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip}}}\mdline{737} and \mdline{737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{737}, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +\mdline{741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{741}) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={746} +\noindent\mdline{746}gRPC enables the server to identify which client originated each message in the +\mdline{747}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{747} stream. For example, the C++ gRPC library\mdline{747}~[\mdcite{grpcstreamc}{10}]\mdline{747} in +synchronous mode enables a server process to cause a function to be called when +a new client creates a \mdline{749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{749} stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +\mdline{751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{751} is closed normally (or broken, \mdline{751}e.g.\mdline{751} because a client process +unexpectedly terminated). Thus the server can easily associate all +\mdline{753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{753} messages received from the same client, because they are +processed within the context of the same function call.%mdk + +%mdk-data-line={756} +\mdline{756}A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values \mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{761}, \mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{761}, and \mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{761} in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods\mdline{763}~[\mdcite{grpcauth}{8}]\mdline{763} that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server.%mdk + +%mdk-data-line={767} +\subsection{\mdline{767}5.1.\hspace*{0.5em}\mdline{767}Default Role}\label{sec-default-role}%mdk%mdk + +%mdk-data-line={769} +\noindent\mdline{769}A controller can omit the role message in \mdline{769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{769}. This +implies the \mdline{770}\textquotedblleft{}default role\textquotedblright{}\mdline{770}, which corresponds to \mdline{770}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{770}. +This also implies that a default role has a \mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{771} of \mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}""}}}\mdline{771} (default). +If using a default role, all RPCs from the controller (\mdline{772}e.g.\mdline{772} \mdline{772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{772}) must +leave the \mdline{773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{773} unset.%mdk + +%mdk-data-line={775} +\subsection{\mdline{775}5.2.\hspace*{0.5em}\mdline{775}Role Config}\label{sec-arbitration-role-config}%mdk%mdk + +%mdk-data-line={777} +\noindent\mdline{777}The \mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{777} field in the \mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{777} message sent by the +controller describes the role configuration, \mdline{778}i.e.\mdline{778} which operations are in the +scope of a given role. In particular, the definition of a role may include the +following:%mdk + +%mdk-data-line={782} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={782} +\item\mdline{782}A list of P4 entities for which the controller may issue \mdline{782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{782} updates and +receive notification messages (\mdline{783}e.g.\mdline{783} \mdline{783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{783} and +\mdline{784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{784}).%mdk + +%mdk-data-line={785} +\item\mdline{785}Whether the controller is able to receive \mdline{785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{785} messages, along with a +filtering mechanism based on the values of the \mdline{786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{786} fields to +select which \mdline{787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{787} messages should be sent to the controller.%mdk + +%mdk-data-line={788} +\item\mdline{788}Whether the controller is able to send \mdline{788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{788} messages, along with a +filtering mechanism based on the values of the \mdline{789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{789} fields to +select which \mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{790} messages are allowed to be sent by the controller.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={792} +\noindent\mdline{792}An unset \mdline{792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{792} implies \mdline{792}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{792} (similar to the default +role explained above). In order to support different role definition schemes, +\mdline{794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{794} is defined as an \mdline{794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{794} Protobuf message\mdline{794}~[\mdcite{protoany}{31}]\mdline{794}. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion.%mdk + +%mdk-data-line={799} +\mdline{799}It is the job of the P4Runtime server to remember the \mdline{799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{799} for every +\mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{800} and \mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{800} pair.%mdk + +%mdk-data-line={802} +\subsection{\mdline{802}5.3.\hspace*{0.5em}\mdline{802}Rules for Handling \mdline{802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{802} Messages Received from Controllers}\label{sec-arbitration-updates}%mdk%mdk + +%mdk-data-line={804} +\begin{enumerate}%mdk + +%mdk-data-line={804} +\item{} +%mdk-data-line={804} +\mdline{804}If the \mdline{804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{804} message is received for the first time on +this particular channel (\mdline{805}i.e.\mdline{805} for a newly connected controller):%mdk + +%mdk-data-line={807} +\begin{enumerate}%mdk + +%mdk-data-line={807} +\item{} +%mdk-data-line={807} +\mdline{807}If \mdline{807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{807} does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +\mdline{809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{809} error.%mdk%mdk + +%mdk-data-line={811} +\item{} +%mdk-data-line={811} +\mdline{811}If the \mdline{811}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{811} is set and is already used by another controller for +the same (\mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{812}, \mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{812}), the P4Runtime server shall terminate +the stream by returning an \mdline{813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{813} error.%mdk%mdk + +%mdk-data-line={815} +\item{} +%mdk-data-line={815} +\mdline{815}If \mdline{815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{815} does not match the \mdline{815}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{815} scheme previously +agreed upon, the server must return an \mdline{816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{816} error.%mdk%mdk + +%mdk-data-line={818} +\item{} +%mdk-data-line={818} +\mdline{818}If the number of open streams for the given (\mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{818}, \mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{818}) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a \mdline{820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{820} error.%mdk%mdk + +%mdk-data-line={822} +\item{} +%mdk-data-line={822} +\mdline{822}Otherwise, the controller is added to a list of connected controllers for +the given (\mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{823}, \mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{823}) and the server remembers the +controllers \mdline{824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{824}, \mdline{824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{824} and \mdline{824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{824} for this gRPC +channel. See below for the rules to determine if this controller becomes +a primary or backup, and what notifications are sent as a consequence.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={828} +\item{} +%mdk-data-line={828} +\mdline{828}Otherwise, if the \mdline{828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{828} message is received from an +already connected controller:%mdk + +%mdk-data-line={831} +\begin{enumerate}%mdk + +%mdk-data-line={831} +\item{} +%mdk-data-line={831} +\mdline{831}If the \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{831} does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{833} error.%mdk%mdk + +%mdk-data-line={835} +\item{} +%mdk-data-line={835} +\mdline{835}If the \mdline{835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{835} does not match the current \mdline{835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{835} assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{837} error. If the controller wishes to change its role, +it must close the current stream channel and open a new one.%mdk%mdk + +%mdk-data-line={840} +\item{} +%mdk-data-line={840} +\mdline{840}If \mdline{840}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{840} does not match the \mdline{840}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{840} scheme previously +agreed upon, the server must return an \mdline{841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{841} error.%mdk%mdk + +%mdk-data-line={843} +\item{} +%mdk-data-line={843} +\mdline{843}If the \mdline{843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{843} is set and is already used by another controller +(excluding the controller making the request) for the same +(\mdline{845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{845}, \mdline{845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{845}), the P4Runtime server shall terminate the stream +by returning an \mdline{846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{846} error.%mdk%mdk + +%mdk-data-line={848} +\item{} +%mdk-data-line={848} +\mdline{848}Otherwise, the server updates the \mdline{848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{848} it has stored for this +controller. This change might cause a change in the primary client (this +controller might become primary, or the controller might have downgraded +itself to a backup, see below), as well as notifications being sent to +one or more controllers.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={854} +\noindent\mdline{854}If the \mdline{854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{854} is accepted by either of the two steps above +(cases 1.5. and 2.5. above), then the server determines if there are changes in +the primary client. Let \mdline{856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{856} be the highest election ID the server +has ever seen for the given \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{857} and \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{857} (including the one of the +current primary if there is one).%mdk + +%mdk-data-line={860} +\begin{enumerate}%mdk + +%mdk-data-line={860} +\item{} +%mdk-data-line={860} +\mdline{860}If \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{860} is greater than or equal to \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{860}, then the +controller becomes, or stays, primary. The server updates the role +configuration to \mdline{862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{862} for the given \mdline{862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{862}. Furthermore:%mdk + +%mdk-data-line={864} +\begin{enumerate}%mdk + +%mdk-data-line={864} +\item{} +%mdk-data-line={864} +\mdline{864}If there was no primary for this \mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{864} and \mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{864} before and +there are no \mdline{865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{865} requests still processing from a previous primary, +then the server immediately sends an advisory notification to all +controllers for this \mdline{867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{867} and \mdline{867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{867}. See the +\mdline{868}\mdref{sec-arbitration-notification}{following section}\mdline{868} for the format of the +advisory message.%mdk%mdk + +%mdk-data-line={871} +\item{} +%mdk-data-line={871} +\mdline{871}If there was a previous primary, including this controller, or \mdline{871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{871} +requests in flight, then the server carries out the following steps +(in this order):%mdk + +%mdk-data-line={875} +\begin{enumerate}%mdk + +%mdk-data-line={875} +\item{} +%mdk-data-line={875} +\mdline{875}The server stops accepting \mdline{875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{875} requests from the previous primary +(if there is one). At this point, the server will reject all \mdline{876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{876} +requests with \mdline{877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{877}.%mdk%mdk + +%mdk-data-line={879} +\item{} +%mdk-data-line={879} +\mdline{879}The server notifies all controllers other than the new primary client +of the change by sending the advisory notification described in +the\mdline{881}~\mdref{sec-arbitration-notification}{following section}\mdline{881}.%mdk%mdk + +%mdk-data-line={883} +\item{} +%mdk-data-line={883} +\mdline{883}The server will finish processing any \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{883} requests that have +already started. If there are errors, they are reported as usual to +the previous primary. If the previous primary has already +disconnected, any possible errors are dropped and not reported.%mdk%mdk + +%mdk-data-line={888} +\item{} +%mdk-data-line={888} +\mdline{888}The server now accepts the current controller as the new primary, +thus accepting \mdline{889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{889} requests from this controller. The server +updates the highest election ID (\mdline{890}i.e.\mdline{890} \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{890}) it has seen +for this \mdline{891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{891} and \mdline{891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{891} to \mdline{891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{891}.%mdk%mdk + +%mdk-data-line={893} +\item{} +%mdk-data-line={893} +\mdline{893}The server notifies the new primary by sending the advisory message +described in the\mdline{894}~\mdref{sec-arbitration-notification}{following section}\mdline{894}.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={896} +\item{} +%mdk-data-line={896} +\mdline{896}Otherwise, the controller becomes a backup. If the controller was previously +a primary (and downgraded itself), then an advisory message is sent to all +controllers for this \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{898} and \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{898}. Otherwise, the advisory +message is only sent to the controller that sent the initial +\mdline{900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{900}. See the +\mdline{901}\mdref{sec-arbitration-notification}{following section}\mdline{901} for the format of the +advisory message.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={904} +\subsection{\mdline{904}5.4.\hspace*{0.5em}\mdline{904}Client Arbitration Notifications}\label{sec-arbitration-notification}%mdk%mdk + +%mdk-data-line={906} +\noindent\mdline{906}For any given \mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{906} and \mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{906}, any time a new primary is chosen, a +primary downgrades its status to a backup, a primary disconnects, or the +\mdline{908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{908} is updated by the primary, all controllers for that +(\mdline{909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{909}, \mdline{909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{909}) are informed of this by sending a +\mdline{910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{910}. The \mdline{910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{910} is populated as follows:%mdk + +%mdk-data-line={912} +\begin{itemize}%mdk + +%mdk-data-line={912} +\item{} +%mdk-data-line={912} +\mdline{912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{912} and \mdline{912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{912} as given.%mdk%mdk + +%mdk-data-line={914} +\item{} +%mdk-data-line={914} +\mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{914} is set to the role configuration the server received most +recently in a \mdline{915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{915} from a primary.%mdk%mdk + +%mdk-data-line={917} +\item{} +%mdk-data-line={917} +\mdline{917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{917} is populated as follows:%mdk + +%mdk-data-line={919} +\begin{itemize}%mdk + +%mdk-data-line={919} +\item{} +%mdk-data-line={919} +\mdline{919}If there has not been any primary at all, the election\mdline{919}\_\mdline{919}id is left unset.%mdk%mdk + +%mdk-data-line={921} +\item{} +%mdk-data-line={921} +\mdline{921}Otherwise, \mdline{921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{921} is set to the highest election ID that the server +has seen for this \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{922} and \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{922} (which is the \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{922} of +the current primary if there is any).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={925} +\item{} +%mdk-data-line={925} +\mdline{925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{925} is set differently based on whether the notification is sent to the +primary or a backup controller:%mdk + +%mdk-data-line={928} +\begin{itemize}%mdk + +%mdk-data-line={928} +\item{} +%mdk-data-line={928} +\mdline{928}If there is a primary:%mdk + +%mdk-data-line={930} +\begin{itemize}%mdk + +%mdk-data-line={930} +\item{} +%mdk-data-line={930} +\mdline{930}For the primary, \mdline{930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{930} is OK (with \mdline{930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{930} set to +\mdline{931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.OK}}}\mdline{931}).%mdk%mdk + +%mdk-data-line={933} +\item{} +%mdk-data-line={933} +\mdline{933}For all backup controllers, \mdline{933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{933} is set to non-OK (with +\mdline{934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{934} set to \mdline{934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.ALREADY\_EXISTS}}}\mdline{934}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={936} +\item{} +%mdk-data-line={936} +\mdline{936}Otherwise, if there is no primary currently, for all backup controllers, +\mdline{937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{937} is set to non-OK (with \mdline{937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{937} set to +\mdline{938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.NOT\_FOUND}}}\mdline{938}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={940} +\noindent\mdline{940}Note that on primary client changes with outstanding \mdline{940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{940} request, some +notifications might be delayed, see the +\mdline{942}\mdref{sec-arbitration-updates}{previous section}\mdline{942} for details.%mdk + +%mdk-data-line={944} +\section{\mdline{944}6.\hspace*{0.5em}\mdline{944}The P4Info Message}\label{sec-the-p4info-message}%mdk%mdk + +%mdk-data-line={946} +\noindent\mdline{946}The purpose of P4Info was described under +\mdline{947}\mdref{sec-reference-architecture}{Reference Architecture}\mdline{947}. +Here we describe the various +components.%mdk + +%mdk-data-line={951} +\subsection{\mdline{951}6.1.\hspace*{0.5em}\mdline{951}Common Messages}\label{sec-common-messages}%mdk%mdk + +%mdk-data-line={953} +\noindent\mdline{953}These messages appear nested within many other messages.%mdk + +%mdk-data-line={955} +\subsubsection{\mdline{955}6.1.1.\hspace*{0.5em}\mdline{955}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{955} Message}\label{sec-documentation-message}%mdk%mdk + +%mdk-data-line={957} +\noindent\mdline{957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{957} is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers.%mdk + +%mdk-data-line={961} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={962} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Documentation~\{\\ +~~{\mdcolor{darkgreen}//~A~brief~description~of~something,~e.g.~one~sentence}\\ +~~{\bfseries{\mdcolor{navy}string}}~brief~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~A~more~verbose~description~of~something.}\\ +~~{\mdcolor{darkgreen}//~Multiline~is~accepted.~Markup~format~(if~any)~is~TBD.}\\ +~~{\bfseries{\mdcolor{navy}string}}~description~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={971} +\subsubsection{\mdline{971}6.1.2.\hspace*{0.5em}\mdline{971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{971} Message}\label{sec-preamble-message}%mdk%mdk + +%mdk-data-line={973} +\noindent\mdline{973}The preamble serves as the \mdline{973}\textquotedblleft{}descriptor\textquotedblright{}\mdline{973} for each entity and contains the unique +instance ID, name, alias, annotations and documentation.%mdk + +%mdk-data-line={976} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={977} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Preamble~\{\\ +~~{\mdcolor{darkgreen}//~ids~share~the~same~number-space;~e.g.~table~ids~cannot~overlap~with~counter}\\ +~~{\mdcolor{darkgreen}//~ids.~Even~though~this~is~irrelevant~to~this~proto~definition,~the~ids~are}\\ +~~{\mdcolor{darkgreen}//~allocated~in~such~a~way~that~it~is~possible~based~on~an~id~to~deduce~the}\\ +~~{\mdcolor{darkgreen}//~resource~type~(e.g.~table,~action,~counter,~...).~This~means~that~code}\\ +~~{\mdcolor{darkgreen}//~using~these~ids~can~detect~if~the~wrong~resource~type~is~used}\\ +~~{\mdcolor{darkgreen}//~somewhere.~This~also~means~that~ids~of~different~types~can~be~mixed}\\ +~~{\mdcolor{darkgreen}//~(e.g.~direct~resource~list~for~a~table)~without~ambiguity.~Note~that~id~0}\\ +~~{\mdcolor{darkgreen}//~is~reserved~and~means~"invalid~id".}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name~of~the~P4~object,~e.g.~c1.c2.ipv4\_lpm}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~an~alias~(alternative~name)~for~the~P4~object,~probably~shorter~than~its}\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name.~The~only~constraint~is~for~it~to~be~unique~with}\\ +~~{\mdcolor{darkgreen}//~respect~to~other~P4~objects~of~the~same~type.~By~default,~the~compiler~uses}\\ +~~{\mdcolor{darkgreen}//~the~shortest~suffix~of~the~name~that~uniquely~identifies~the~object.~For}\\ +~~{\mdcolor{darkgreen}//~example~if~the~P4~program~contains~two~tables~with~names~s.c1.t~and~s.c2.t,}\\ +~~{\mdcolor{darkgreen}//~the~default~aliases~will~respectively~be~c1.t~and~c2.t.~In~the~future,~the}\\ +~~{\mdcolor{darkgreen}//~P4~programmer~may~also~be~able~to~override~the~default~alias~for~any~P4}\\ +~~{\mdcolor{darkgreen}//~object~(TBD).}\\ +~~{\bfseries{\mdcolor{navy}string}}~alias~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~Optional.~If~present,~the~location~of~`annotations{}[i]`~is~given~by}\\ +~{\mdcolor{darkgreen}//~`annotation\_locations{}[i]`.}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~SourceLocation~annotation\_locations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~Documentation~of~the~entity}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1008} +\subsubsection{\mdline{1008}6.1.3.\hspace*{0.5em}\mdline{1008}Annotating P4 Entities with \mdline{1008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}\label{sec-annotating-p4-entities-with-documentation}%mdk%mdk + +%mdk-data-line={1010} +\noindent\mdline{1010}P4 entities may be annotated using the following annotations:%mdk + +%mdk-data-line={1012} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1013} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}(string...)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}(string...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1017} +\noindent\mdline{1017}Attaching either or both of these annotations to an entity will generate a +P4Info\mdline{1018}~\mdref{sec-documentation-message}{Documentation Message}\mdline{1018}, which in turn will +appear in the\mdline{1019}~\mdref{sec-preamble-message}{Preamble Message}\mdline{1019} for the entity.%mdk + +%mdk-data-line={1021} +\mdline{1021}The P4 compiler should not emit \mdline{1021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation}}}\mdline{1021} messages in the P4Info for these +specific cases; instead, it should generate the \mdline{1022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1022} messages as +described.%mdk + +%mdk-data-line={1025} +\mdline{1025}The following example shows documentation annotations for a \mdline{1025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table}}}\mdline{1025} entity:%mdk + +%mdk-data-line={1027} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1028} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port.~\textbackslash{}}\\ +Uses~LPM~match~{\bfseries{\mdcolor{navy}type}}.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}table~my\_ipv4\_lkup~\{}\\ +{\mdcolor{maroon}~~...}\\ +{\mdcolor{maroon}\}}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1036} +\subsubsection{\mdline{1036}6.1.4.\hspace*{0.5em}\mdline{1036}Structured Annotations}\label{sec-structured-annotations}%mdk%mdk + +%mdk-data-line={1038} +\noindent\mdline{1038}P4 supports both unstructured and structured annotations\mdline{1038}~[\mdcite{p4annotations}{13}]\mdline{1038}. +Unstructured annotations of the form \mdline{1039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno1}}}\mdline{1039} or \mdline{1039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno2(body-content)}}}\mdline{1039} can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +\mdline{1042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno3{}[]}}}\mdline{1042} or \mdline{1042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno4{}[kvList\textbar{}expressionList]}}}\mdline{1042} have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this.%mdk + +%mdk-data-line={1047} +\mdline{1047}The annotations described up to this point, \mdline{1047}e.g.\mdline{1047} \mdline{1047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief()}}}\mdline{1047}, have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as \mdline{1049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1049} fields in the various \mdline{1049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{1049}s. +Similarly, structured annotations are represented in \mdline{1050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated\\ +StructuredAnnotation~structured\_annotations}}}\mdline{1051} fields which are siblings to the +unstructured \mdline{1052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1052}. The \mdline{1052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations}}}\mdline{1052} contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations.%mdk + +%mdk-data-line={1057} +\mdline{1057}The structured annotation messages are defined in p4types.proto.%mdk + +%mdk-data-line={1059} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1060} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~KeyValuePair~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~key~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Expression~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~KeyValuePairList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~KeyValuePair~kv\_pairs~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Expression~\{\\ +~~{\bfseries{\mdcolor{navy}oneof}}~value~\{\\ +~~~~{\bfseries{\mdcolor{navy}string}}~string\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~{\bfseries{\mdcolor{navy}int64}}~int64\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~{\bfseries{\mdcolor{navy}bool}}~bool\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~ExpressionList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Expression~expressions~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~StructuredAnnotation~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}oneof}}~body~\{\\ +~~~~ExpressionList~expression\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~KeyValuePairList~kv\_pair\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~Optional.~Location~of~the~'@'~symbol~of~this~annotation~in~the~source~code.}\\ +~~SourceLocation~source\_location~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1092} +\noindent\mdline{1092}The \mdline{1092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1092} message can represent either a \mdline{1092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1092} +or an \mdline{1093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExpressionList}}}\mdline{1093}.%mdk + +%mdk-data-line={1095} +\mdline{1095}The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The \mdline{1096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{1096} +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don\mdline{1098}'\mdline{1098}t match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler \mdline{1100}\emph{may}\mdline{1100} print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions.%mdk + +%mdk-data-line={1104} +\mdline{1104}The following invariants hold:%mdk + +%mdk-data-line={1106} +\begin{enumerate}%mdk + +%mdk-data-line={1106} +\item{} +%mdk-data-line={1106} +\mdline{1106}For any P4 entity, there are no two \mdline{1106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1106}s that have the +same name.%mdk%mdk + +%mdk-data-line={1109} +\item{} +%mdk-data-line={1109} +\mdline{1109}Within a \mdline{1109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1109}, there are no two \mdline{1109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePair}}}\mdline{1109}s that have the +same \mdline{1110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key.}}}\mdline{1110}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1112} +\paragraph{\mdline{1112}6.1.4.1.\hspace*{0.5em}\mdline{1112}Structured Annotation Examples}\label{sec-structured-annotation-examples}%mdk%mdk + +%mdk-data-line={1114} +\noindent\mdline{1114}We omit the \mdline{1114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}source\_location}}}\mdline{1114} field in the following examples.%mdk + +%mdk-data-line={1116} +\mdline{1116}\textbf{Empty Expression List}\mdline{1116}%mdk + +%mdk-data-line={1118} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1119} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}Empty}{\mdcolor{maroon}{}[]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1125} +\noindent\mdline{1125}The generated P4Info will contain the following.%mdk + +%mdk-data-line={1127} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1128} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}Empty}{\mdcolor{maroon}"}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1133} +\noindent\mdline{1133}\textbf{Mixed Expression List}\mdline{1133}%mdk + +%mdk-data-line={1135} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1136} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~TEXT\_CONST~"hello"}\\ +{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~NUM\_CONST~6}\\ +{\mdcolor{gray}@}{\mdcolor{gray}MixedExprList}{\mdcolor{maroon}{}[1,TEXT\_CONST,true,1==2,5+NUM\_CONST]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1144} +\noindent\mdline{1144}The generated P4Info will contain:%mdk + +%mdk-data-line={1146} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1147} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedExprList}{\mdcolor{maroon}"}\\ +~~expression\_list~\{\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}1}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}hello}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~true\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~false\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}11}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1169} +\noindent\mdline{1169}\textbf{kvList of Mixed Expressions}\mdline{1169}%mdk + +%mdk-data-line={1171} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1172} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}MixedKV}{\mdcolor{maroon}{}[label="text",~my\_bool=true,~int\_val=2*3]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1178} +\noindent\mdline{1178}The generated P4Info will contain:%mdk + +%mdk-data-line={1180} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1181} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedKV}{\mdcolor{maroon}"}\\ +~~kv\_pair\_list~\{\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}label}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}text}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}my\_bool}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~bool\_value:~true\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}int\_val}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~int64\_value:~{\mdcolor{purple}6}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1206} +\subsubsection{\mdline{1206}6.1.5.\hspace*{0.5em}\mdline{1206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1206} Message}\label{sec-sourcelocation-message}%mdk%mdk + +%mdk-data-line={1208} +\noindent\mdline{1208}A source location describes a location within a \mdline{1208}\emph{.p4}\mdline{1208}-source file. The +\mdline{1209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1209} message is defined in p4types.proto as follows:%mdk + +%mdk-data-line={1211} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1212} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Location~of~code~relative~to~a~given~source~file.}\\ +{\bfseries{\mdcolor{navy}message}}~SourceLocation~\{\\ +~~{\mdcolor{darkgreen}//~Path~to~the~source~file~(absolute~or~relative~to~the~working~directory).}\\ +~~{\bfseries{\mdcolor{navy}string}}~file~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Line~and~column~numbers~within~the~source~file,~1-based.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~line~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}int32}}~column~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1222} +\noindent\mdline{1222}We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations.%mdk + +%mdk-data-line={1227} +\mdline{1227}The \mdline{1227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1227} message associated with an annotation holds the location of +the \mdline{1228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@}}}\mdline{1228} symbol introducing the annotation in the P4 source code; the message can +be found in the following place:%mdk + +%mdk-data-line={1231} +\begin{itemize}%mdk + +%mdk-data-line={1231} +\item{} +%mdk-data-line={1231} +\mdline{1231}For \mdline{1231}\textbf{unstructured annotations}\mdline{1231}, every message containing a field +\mdline{1232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1232} also contains a field +\mdline{1233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~SourceLocation~annotation\_locations}}}\mdline{1233}. The field must either be empty + or match the size of \mdline{1234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1234}. In the latter case, the i-th member of +\mdline{1235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation\_locations}}}\mdline{1235} is the source location of the i-th member of +\mdline{1236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1236}.%mdk%mdk + +%mdk-data-line={1238} +\item{} +%mdk-data-line={1238} +\mdline{1238}For \mdline{1238}\textbf{structured annotations}\mdline{1238}, every \mdline{1238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1238} message contains +an optional field \mdline{1239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation~source\_location}}}\mdline{1239} holding its source +location, if present.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1243} +\subsection{\mdline{1243}6.2.\hspace*{0.5em}\mdline{1243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1243} Message}\label{sec-pkginfo-message}%mdk%mdk + +%mdk-data-line={1245} +\noindent\mdline{1245}The \mdline{1245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1245} message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. \mdline{1246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1246} can be extracted +and used to facilitate \mdline{1247}\textquotedblleft{}browsing\textquotedblright{}\mdline{1247} of available P4 programs from a +library. Although all fields are technically \mdline{1248}\textquotedblleft{}optional,\textquotedblright{}\mdline{1248} every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included.%mdk + +%mdk-data-line={1252} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1253} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Can~be~used~to~manage~multiple~P4~packages.}\\ +{\bfseries{\mdcolor{navy}message}}~PkgInfo~\{\\ +~~{\mdcolor{darkgreen}//~a~definitive~name~for~this~configuration,~e.g.~switch.p4\_v1.0}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~configuration~version,~free-format~string}\\ +~~{\bfseries{\mdcolor{navy}string}}~version~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~brief~and~detailed~descriptions}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~free-form;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~the~target~architecture,~e.g.~"psa"}\\ +~~{\bfseries{\mdcolor{navy}string}}~arch~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\mdcolor{darkgreen}//~organization~which~produced~the~configuration,~e.g.~"p4.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~organization~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~{\mdcolor{darkgreen}//~contact~info~for~support,e.g.~"tech-support@acme.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~contact~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~url~for~more~information,~e.g.~"http://support.p4.org/ref/p4/switch.p4\_v1.0"}\\ +~~{\bfseries{\mdcolor{navy}string}}~url~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}8};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~structured;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}9};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1276} +\subsubsection{\mdline{1276}6.2.1.\hspace*{0.5em}\mdline{1276}Annotating P4 code with PkgInfo}\label{sec-annotating-p4-code-with-pkginfo}%mdk%mdk + +%mdk-data-line={1278} +\noindent\mdline{1278}A P4 progam\mdline{1278}'\mdline{1278}s \mdline{1278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1278} may be declared using one or more of the following +annotations, attached to the \mdline{1279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1279} block only:%mdk + +%mdk-data-line={1281} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1282} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value{}[,key=value,...])}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("A~brief~description")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("A~longer\textbackslash{}}\\ +description{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@custom\_annotation(...)}\\ +{\mdcolor{maroon}@another\_custom\_annotation(...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1291} +\noindent\mdline{1291}Above we see several different types of annotations:%mdk + +%mdk-data-line={1293} +\begin{itemize}%mdk + +%mdk-data-line={1293} +\item{} +%mdk-data-line={1293} +\mdline{1293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1293} \mdline{1293}- This is used to populate a specific field within the \mdline{1293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1293} +message. Multiple \mdline{1294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1294} annotations are allowed. For compactness, +multiple key-value pairs can appear in a single \mdline{1295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1295} annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The \mdline{1297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{1297}s must be from +among the message fields inside \mdline{1298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1298}, for example, \mdline{1298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1298}, \mdline{1298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}version}}}\mdline{1298}, +etc. Each key-value pair assigns a value to the corresponding field inside the +single \mdline{1300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1300} message for the program\mdline{1300}'\mdline{1300}s P4Info. One exception is that the +\mdline{1301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1301} field of \mdline{1301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1301} must be expressed as individual +\mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1302} and \mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1302} annotations, see next bullets. The key \mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}arch}}}\mdline{1302} will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself.%mdk%mdk + +%mdk-data-line={1306} +\item{} +%mdk-data-line={1306} +\mdline{1306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1306} \mdline{1306}- This will populate the \mdline{1306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.brief}}}\mdline{1306} message field.%mdk%mdk + +%mdk-data-line={1308} +\item{} +%mdk-data-line={1308} +\mdline{1308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1308} \mdline{1308}- This will populate the \mdline{1308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.description}}}\mdline{1308} message +field%mdk%mdk + +%mdk-data-line={1311} +\item{} +%mdk-data-line={1311} +\mdline{1311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@\textless{}anything~else\textgreater{}}}}\mdline{1311} \mdline{1311}- This will create a \mdline{1311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotation}}}\mdline{1311} entry%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1313} +\noindent\mdline{1313}Declaring one or more of these annotations on \mdline{1313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1313} will +generate a single corresponding \mdline{1314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1314} message in the P4Info as described in +\mdline{1315}\mdref{sec-pkginfo-message}{PkgInfo Message}\mdline{1315}.%mdk + +%mdk-data-line={1317} +\mdline{1317}The following example shows \mdline{1317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1317} annotations using a mixture of single and +multiple key-value pairs. It also shows \mdline{1318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1318} and \mdline{1318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1318} annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the \mdline{1320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1320} message. The custom annotations will +be appended to the \mdline{1321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotations}}}\mdline{1321} list.%mdk + +%mdk-data-line={1323} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1324} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(name="switch.p4",version="2")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(organization="p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(contact="info@p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(url="www.p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("L2/L3~switch")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("L2/L3~switch.\textbackslash{}}\\ +Built~for~data-center~profile.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@my\_annotation1(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}@my\_annotation2(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}PSA\_Switch(IgPipeline,~PacketReplicationEngine(),~EgPipeline,}\\ +{\mdcolor{maroon}~~~~~~~~~~~BufferingQueueingEngine())~main;}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1337} +\subsection{\mdline{1337}6.3.\hspace*{0.5em}\mdline{1337}ID Allocation for P4Info Objects}\label{sec-id-allocation}%mdk%mdk + +%mdk-data-line={1339} +\noindent\mdline{1339}P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(\mdline{1343}e.g.\mdline{1343} table, action, counter, \mdline{1343}\dots{}\mdline{1343}). The most significant 8 bits of the ID +encodes the object type (as per Table\mdline{1344}~\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}}\mdline{1344}). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (\mdline{1346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.P4Ids.Prefix}}}\mdline{1346}). These values must +be used (\mdline{1347}e.g.\mdline{1347} by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table\mdline{1349}~\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}}\mdline{1349} shows the ID +layout.%mdk + +%mdk-data-line={1352} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1354} 8-bit prefix value}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1354} P4 object type}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{1356} 0x00}&\multicolumn{1}{|l|}{\mdline{1356} Reserved (unspecified)}\\ +\multicolumn{1}{|l}{\mdline{1357} 0x01}&\multicolumn{1}{|l|}{\mdline{1357} Action}\\ +\multicolumn{1}{|l}{\mdline{1358} 0x02}&\multicolumn{1}{|l|}{\mdline{1358} Table}\\ +\multicolumn{1}{|l}{\mdline{1359} 0x03}&\multicolumn{1}{|l|}{\mdline{1359} Value-set}\\ +\multicolumn{1}{|l}{\mdline{1360} 0x04}&\multicolumn{1}{|l|}{\mdline{1360} Controller header (header type with \mdline{1360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1360} annotation)}\\ +\multicolumn{1}{|l}{\mdline{1361} 0x05\mdline{1361}\dots{}\mdline{1361}0x0f}&\multicolumn{1}{|l|}{\mdline{1361} Reserved (for future P4 built-in objects)}\\ +\multicolumn{1}{|l}{\mdline{1362} 0x10}&\multicolumn{1}{|l|}{\mdline{1362} Reserved (start of PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1363} 0x11}&\multicolumn{1}{|l|}{\mdline{1363} PSA Action profiles / selectors}\\ +\multicolumn{1}{|l}{\mdline{1364} 0x12}&\multicolumn{1}{|l|}{\mdline{1364} PSA Counter}\\ +\multicolumn{1}{|l}{\mdline{1365} 0x13}&\multicolumn{1}{|l|}{\mdline{1365} PSA Direct counter}\\ +\multicolumn{1}{|l}{\mdline{1366} 0x14}&\multicolumn{1}{|l|}{\mdline{1366} PSA Meter}\\ +\multicolumn{1}{|l}{\mdline{1367} 0x15}&\multicolumn{1}{|l|}{\mdline{1367} PSA Direct meter}\\ +\multicolumn{1}{|l}{\mdline{1368} 0x16}&\multicolumn{1}{|l|}{\mdline{1368} PSA Register}\\ +\multicolumn{1}{|l}{\mdline{1369} 0x17}&\multicolumn{1}{|l|}{\mdline{1369} PSA Digest}\\ +\multicolumn{1}{|l}{\mdline{1370} 0x18\mdline{1370}\dots{}\mdline{1370}0x7f}&\multicolumn{1}{|l|}{\mdline{1370} Reserved (for future PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1371} 0x80}&\multicolumn{1}{|l|}{\mdline{1371} Reserved (start of vendor-specific extern types)}\\ +\multicolumn{1}{|l}{\mdline{1372} 0x81\mdline{1372}\dots{}\mdline{1372}0xfe}&\multicolumn{1}{|l|}{\mdline{1372} Vendor-specific extern types}\\ +\multicolumn{1}{|l}{\mdline{1373} 0xff}&\multicolumn{1}{|l|}{\mdline{1373} Reserved (max prefix value)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1375} +\mdhr{}%mdk + +%mdk-data-line={1376} +\noindent\mdline{1376}\mdcaption{\textbf{Table~\mdcaptionlabel{1}.}~\mdcaptiontext{Mapping of P4Info object type to 8-bit ID prefix value}}%mdk +%mdk +\end{mdcenter}\label{tab-mapping-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1379} +\begin{table}[h!]%mdk +\begin{mdblock}{text-align=center,breakable=true}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{cc}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1381} MSB bit 31 \mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}.. bit 24}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1381} bit 23 \mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}.. bit 0 LSB}}\\ + +\midrule +\multicolumn{1}{|c}{\mdline{1383} Object type prefix}&\multicolumn{1}{|c|}{\mdline{1383} Generated suffix (\mdline{1383}e.g.\mdline{1383} by the compiler)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1385} +\mdhr{}%mdk + +%mdk-data-line={1386} +\noindent\mdline{1386}\mdcaption{\textbf{Table~\mdcaptionlabel{2}.}~\mdcaptiontext{Format of P4Info object IDs}}%mdk%mdk +\end{mdblock}\label{tab-format-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1390} +\mdline{1390}It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with \mdline{1391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1391} (see Table +\mdline{1392}\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}}\mdline{1392}). The compiler must honor the \mdline{1392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1392} annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (\mdline{1394}i.e.\mdline{1394} if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same \mdline{1396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1396} value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct.%mdk + +%mdk-data-line={1405} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth-7cm)/1}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{\mdinline{width=7cm}{{\bfseries\mdline{1407} P4 declaration(s)}}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1407} Compiler-allocated ID(s)}}\\ + +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1409} \mdline{1409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1409}}}&\multicolumn{1}{|l|}{\mdline{1409} 0x0212ab34}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1411} \mdline{1411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1411}}}&\multicolumn{1}{|l|}{\mdline{1411} \mdline{1411}\textbf{Error}\mdline{1411}(same ID suffixes for 2 objects of the same type)}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1412} \mdline{1412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tB...}}}\mdline{1412}}}&\multicolumn{1}{|l|}{\mdline{1412}}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1414} \mdline{1414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1414}}}&\multicolumn{1}{|l|}{\mdline{1414} 0x0212ab34}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1415} \mdline{1415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~action~act1...}}}\mdline{1415}}}&\multicolumn{1}{|l|}{\mdline{1415} 0x0112ab34}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1417} +\mdhr{}%mdk + +%mdk-data-line={1418} +\noindent\mdline{1418}\mdcaption{\textbf{Table~\mdcaptionlabel{3}.}~\mdcaptiontext{Example of statically-assigned P4Info object IDs}}%mdk +%mdk +\end{mdcenter}\label{tab-exmpl-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1421} +\mdline{1421}The \mdline{1421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1421} annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively).%mdk + +%mdk-data-line={1427} +\subsection{\mdline{1427}6.4.\hspace*{0.5em}\mdline{1427}P4Info Objects}\label{sec-p4info-objects}%mdk%mdk + +%mdk-data-line={1429} +\subsubsection{\mdline{1429}6.4.1.\hspace*{0.5em}\mdline{1429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}\label{sec-table}%mdk%mdk + +%mdk-data-line={1431} +\noindent\mdline{1431}Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields:%mdk + +%mdk-data-line={1434} +\begin{itemize}%mdk + +%mdk-data-line={1434} +\item{} +%mdk-data-line={1434} +\mdline{1434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1434}, a \mdline{1434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1434} message with the ID, name, and alias of this table.%mdk%mdk + +%mdk-data-line={1436} +\item{} +%mdk-data-line={1436} +\mdline{1436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1436}, a repeated field of type \mdline{1436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1436} representing the data to +be used to construct the lookup key matched in this table. Each \mdline{1437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1437} +message is defined with the following fields:%mdk + +%mdk-data-line={1440} +\begin{itemize}%mdk + +%mdk-data-line={1440} +\item{} +%mdk-data-line={1440} +\mdline{1440}id, the \mdline{1440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1440} identifier of this \mdline{1440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1440}, unique in the scope of +this table. No rules are prescribed on the way \mdline{1441}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1441} IDs should be +allocated, as long as two \mdline{1442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1442} of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the \mdline{1446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1446} annotation, or let the compiler +choose them.%mdk%mdk + +%mdk-data-line={1449} +\item{} +%mdk-data-line={1449} +\mdline{1449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1449}, the string representing the name of this \mdline{1449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1449}.%mdk%mdk + +%mdk-data-line={1451} +\item{} +%mdk-data-line={1451} +\mdline{1451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1451}, a repeated field of strings, each one representing a P4 +annotation associated to this match field.%mdk%mdk + +%mdk-data-line={1454} +\item{} +%mdk-data-line={1454} +\mdline{1454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1454}, an \mdline{1454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1454} value set to the size in bits of this match field.%mdk%mdk + +%mdk-data-line={1456} +\item{} +%mdk-data-line={1456} +\mdline{1456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1456}, a \mdline{1456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{1456} describing the match behavior for this field; it can be +either:%mdk + +%mdk-data-line={1458} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1458} +\item\mdline{1458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1458}, an enum field of type \mdline{1458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchType}}}\mdline{1458}, which includes all +possible PSA match kinds.%mdk + +%mdk-data-line={1460} +\item\mdline{1460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_match\_type}}}\mdline{1460}, a string field which can be used to encode any +architecture-specific match type.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1463} +\item{} +%mdk-data-line={1463} +\mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1463}, a \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1463} message describing this match field.%mdk%mdk + +%mdk-data-line={1465} +\item{} +%mdk-data-line={1465} +\mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1465}, which indicates whether the match field has a\mdline{1465}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1466}; this is useful for +\mdline{1467}\mdref{sec-psa-metadata-translation}{translation}\mdline{1467}.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1469} +\item{} +%mdk-data-line={1469} +\mdline{1469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_refs}}}\mdline{1469}, a repeated \mdline{1469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1469} field representing the set of possible +actions for this table. The \mdline{1470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1470} message is used to reference an action +specified in the same P4Info message and it includes the following fields:%mdk + +%mdk-data-line={1472} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1472} +\item\mdline{1472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1472}, the \mdline{1472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1472} identifier of the action.%mdk + +%mdk-data-line={1473} +\item\mdline{1473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1473}, an enum value which can take one of three values: + \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1474}, \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1474} and \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1474}. The \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1474} of the + action is determined by the use of the P4 standard annotations + \mdline{1476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1476} and \mdline{1476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1476}~[\mdcite{p4actionannotations}{18}]\mdline{1476}. \mdline{1476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1476} + (\mdline{1477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1477} annotation) means that the action can only appear within + the table, and never as the default action. \mdline{1478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1478} + (\mdline{1479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1479} annotation) means that the action can only be used as the + default action. \mdline{1480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1480} is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action.%mdk + +%mdk-data-line={1483} +\item\mdline{1483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1483}, a repeated string field, each one representing a P4 +annotation associated to the action \mdline{1484}\emph{reference}\mdline{1484} in this table.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1486} +\item{} +%mdk-data-line={1486} +\mdline{1486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\_default\_action\_id}}}\mdline{1486}, if this table has a constant default action, this +field will carry the \mdline{1487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1487} identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action\mdline{1490}'\mdline{1490}s +arguments.%mdk%mdk + +%mdk-data-line={1493} +\item{} +%mdk-data-line={1493} +\mdline{1493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation\_id}}}\mdline{1493}, the \mdline{1493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1493} identifier of the \mdline{1493}\textquotedblleft{}implementation\textquotedblright{}\mdline{1493} of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (\mdline{1496}e.g.\mdline{1496} a PSA \mdline{1496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1496} or \mdline{1496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{1496} +instance). The table is then referred to as an indirect match table.%mdk%mdk + +%mdk-data-line={1499} +\item{} +%mdk-data-line={1499} +\mdline{1499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_resource\_ids}}}\mdline{1499}, repeated \mdline{1499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1499} identifiers for all the direct +resources attached to this table, such as \mdline{1500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1500} and \mdline{1500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1500} +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2.%mdk%mdk + +%mdk-data-line={1506} +\item{} +%mdk-data-line={1506} +\mdline{1506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1506}, an \mdline{1506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1506} describing the desired number of table entries that the +target should support for the table. See the \mdline{1507}\textquotedblleft{}Size\textquotedblright{}\mdline{1507} subsection within the +\mdline{1508}\textquotedblleft{}Table Properties\textquotedblright{}\mdline{1508} section of the P4\mdline{1508}\mdsub{16}\mdline{1508} language specification for details +\mdline{1509}[\mdcite{p4tableproperties}{30}]\mdline{1509}.%mdk%mdk + +%mdk-data-line={1511} +\item{} +%mdk-data-line={1511} +\mdline{1511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_behavior}}}\mdline{1511}, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +\mdline{1513}\mdref{sec-idle-timeout}{Idle-Timeout}\mdline{1513} section). Value can be any of the +\mdline{1514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutBehavior}}}\mdline{1514} enum:%mdk + +%mdk-data-line={1515} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1515} +\item\mdline{1515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NO\_TIMEOUT}}}\mdline{1515} (default value), which means that idle timeout is not +supported for this table.%mdk + +%mdk-data-line={1517} +\item\mdline{1517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOTIFY\_CONTROL}}}\mdline{1517}, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +\mdline{1519}\mdref{sec-table-idle-timeout-notification}{Table Idle Timeout Notifications}\mdline{1519}).%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1521} +\item{} +%mdk-data-line={1521} +\mdline{1521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{1521}, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime.%mdk%mdk + +%mdk-data-line={1524} +\item{} +%mdk-data-line={1524} +\mdline{1524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{1524}, an \mdline{1524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1524} Protobuf message\mdline{1524}~[\mdcite{protoany}{31}]\mdline{1524} to embed +architecture-specific table properties\mdline{1525}~[\mdcite{p4tableproperties}{30}]\mdline{1525} which are not part +of the core P4 language or of the PSA architecture.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1528} +\subsubsection{\mdline{1528}6.4.2.\hspace*{0.5em}\mdline{1528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}\label{sec-action}%mdk%mdk + +%mdk-data-line={1530} +\noindent\mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1530} messages are used to specify all possible actions of all match-action +tables.%mdk + +%mdk-data-line={1533} +\mdline{1533}The \mdline{1533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1533} message defines the following fields:%mdk + +%mdk-data-line={1535} +\begin{itemize}%mdk + +%mdk-data-line={1535} +\item{} +%mdk-data-line={1535} +\mdline{1535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1535}, a \mdline{1535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1535} message with the ID, name, and alias of this action%mdk%mdk + +%mdk-data-line={1537} +\item{} +%mdk-data-line={1537} +\mdline{1537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{1537}, a repeated field of \mdline{1537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1537} messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each \mdline{1539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1539} message contains the +following fields:%mdk + +%mdk-data-line={1541} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1541} +\item\mdline{1541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1541}, the \mdline{1541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1541} identifier of this parameter. No rules are prescribed +on the way \mdline{1542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1542} IDs should be allocated, as long as two \mdline{1542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1542} of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the \mdline{1546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1546} +annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1548} +\item\mdline{1548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1548}, the string representing the name of this parameter.%mdk + +%mdk-data-line={1549} +\item\mdline{1549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1549}, a repeated field of strings, each one representing a P4 +annotation associated to this parameter.%mdk + +%mdk-data-line={1551} +\item\mdline{1551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1551}, an \mdline{1551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1551} value set to the size in bits of this parameter.%mdk + +%mdk-data-line={1552} +\item\mdline{1552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1552}, which describes this parameter using a \mdline{1552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1552} message.%mdk + +%mdk-data-line={1553} +\item\mdline{1553}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1553}, which indicates whether the action parameter has a +\mdline{1554}\mdref{sec-user-defined-types}{user-defined type}\mdline{1554}; this is useful for +\mdline{1555}\mdref{sec-psa-metadata-translation}{translation}\mdline{1555}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1557} +\subsubsection{\mdline{1557}6.4.3.\hspace*{0.5em}\mdline{1557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}\label{sec-p4info-action-profile}%mdk%mdk + +%mdk-data-line={1559} +\noindent\mdline{1559}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1559} messages are used to specify all available instances of Action +Profile and Action Selector PSA externs.%mdk + +%mdk-data-line={1562} +\mdline{1562}PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile \mdline{1566}\emph{member}\mdline{1566}, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime.%mdk + +%mdk-data-line={1570} +\mdline{1570}PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into \mdline{1571}\emph{groups}\mdline{1571}. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime.%mdk + +%mdk-data-line={1580} +\mdline{1580}While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same \mdline{1581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1581} message to describe both.%mdk + +%mdk-data-line={1583} +\mdline{1583}The \mdline{1583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1583} message includes the following fields:%mdk + +%mdk-data-line={1585} +\begin{itemize}%mdk + +%mdk-data-line={1585} +\item{} +%mdk-data-line={1585} +\mdline{1585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1585}, a \mdline{1585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1585} message with the ID, name, and alias of this Action +Profile or Selector.%mdk%mdk + +%mdk-data-line={1588} +\item{} +%mdk-data-line={1588} +\mdline{1588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_ids}}}\mdline{1588}, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector.%mdk%mdk + +%mdk-data-line={1591} +\item{} +%mdk-data-line={1591} +\mdline{1591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}with\_selector}}}\mdline{1591}, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern.%mdk%mdk + +%mdk-data-line={1594} +\item{} +%mdk-data-line={1594} +\mdline{1594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1594}, an \mdline{1594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1594} representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups.%mdk%mdk + +%mdk-data-line={1598} +\item{} +%mdk-data-line={1598} +\mdline{1598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1598}, an \mdline{1598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1598} which is 0 for an Action Profile, or, for an +Action Selector, represents the maximum sum of all member weights within any +given selector group. The \mdline{1600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1600} must be no larger than \mdline{1600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1600}. PSA +programs can use the \mdline{1601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{1601} annotation to provide this value for +Action Selectors. If the annotation is omitted, the P4Info field will default +to 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1605} +\subsubsection{\mdline{1605}6.4.4.\hspace*{0.5em}\mdline{1605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1605} \mdline{1605}\&\mdline{1605} \mdline{1605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}\label{sec-counter-directcounter}%mdk%mdk + +%mdk-data-line={1607} +\noindent\mdline{1607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1607} and \mdline{1607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1607} messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is:%mdk + +%mdk-data-line={1613} +\begin{itemize}%mdk + +%mdk-data-line={1613} +\item{} +%mdk-data-line={1613} +\mdline{1613}Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index.%mdk%mdk + +%mdk-data-line={1617} +\item{} +%mdk-data-line={1617} +\mdline{1617}Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1620} +\noindent\mdline{1620}Both \mdline{1620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1620} and \mdline{1620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1620} messages share the following fields:%mdk + +%mdk-data-line={1622} +\begin{itemize}%mdk + +%mdk-data-line={1622} +\item{} +%mdk-data-line={1622} +\mdline{1622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1622}, a \mdline{1622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1622} message with the ID, name, and alias of this counter +extern instance.%mdk%mdk + +%mdk-data-line={1625} +\item{} +%mdk-data-line={1625} +\mdline{1625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1625}, a message of of type \mdline{1625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1625} used to describe the compile-time +configuration of this counter. Currently, the \mdline{1626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1626} message is used to +carry only the counter unit, which can be any of the \mdline{1627}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec.Unit}}}\mdline{1627} enum +values:%mdk + +%mdk-data-line={1629} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1629} +\item\mdline{1629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1629}: reserved value.%mdk + +%mdk-data-line={1630} +\item\mdline{1630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1630}: byte counter.%mdk + +%mdk-data-line={1631} +\item\mdline{1631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1631}: packet counter.%mdk + +%mdk-data-line={1632} +\item\mdline{1632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BOTH}}}\mdline{1632}: combination of both byte and packet counter.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1634} +\noindent\mdline{1634}For indexed counters, the \mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1634} message contains also a \mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1634} field, an +\mdline{1635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1635} representing the maximum number of independent values that can be held +by this counter array. Conversely, the \mdline{1636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1636} message contains a +\mdline{1637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1637} field that carries the \mdline{1637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}unit32}}}\mdline{1637} identifier of the table to +which this direct counter is attached.%mdk + +%mdk-data-line={1640} +\mdline{1640}For indexed counters, the \mdline{1640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1640} message contains also an \mdline{1640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1640} +field, which indicates whether the index has a\mdline{1641}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1642}. This is useful for +\mdline{1643}\mdref{sec-psa-metadata-translation}{translation}\mdline{1643}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1644}).%mdk + +%mdk-data-line={1646} +\subsubsection{\mdline{1646}6.4.5.\hspace*{0.5em}\mdline{1646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1646} \mdline{1646}\&\mdline{1646} \mdline{1646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}\label{sec-meter-directmeter}%mdk%mdk + +%mdk-data-line={1648} +\noindent\mdline{1648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1648} and \mdline{1648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1648} messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is:%mdk + +%mdk-data-line={1654} +\begin{itemize}%mdk + +%mdk-data-line={1654} +\item{} +%mdk-data-line={1654} +\mdline{1654}Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +\mdline{1656}e.g.\mdline{1656} to set the rate threshold.%mdk%mdk + +%mdk-data-line={1658} +\item{} +%mdk-data-line={1658} +\mdline{1658}Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1661} +\noindent\mdline{1661}Both \mdline{1661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1661} and \mdline{1661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1661} messages share the following fields:%mdk + +%mdk-data-line={1663} +\begin{itemize}%mdk + +%mdk-data-line={1663} +\item{} +%mdk-data-line={1663} +\mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1663}, a \mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1663} message with the ID, name, and alias of this meter +extern instance.%mdk%mdk + +%mdk-data-line={1666} +\item{} +%mdk-data-line={1666} +\mdline{1666}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1666}, a message of type \mdline{1666}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1666} used to describe the capabilities of +this meter extern instance. Currently, the \mdline{1667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1667} message is used to +carry only the meter unit, which can be any of the \mdline{1668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Unit}}}\mdline{1668} enum +values:%mdk + +%mdk-data-line={1670} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1670} +\item\mdline{1670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1670}: reserved value.%mdk + +%mdk-data-line={1671} +\item\mdline{1671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1671}, which signifies that this meter can be configured with rates +expressed in bytes/second.%mdk + +%mdk-data-line={1673} +\item\mdline{1673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1673}, for rates expressed in packets/second.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1675} +\noindent\mdline{1675}For indexed meters, the \mdline{1675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1675} message contains also a \mdline{1675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1675} field, an \mdline{1675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1675} +representing the maximum number of independent cells that can be held by this +meter. Conversely, the \mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1677} message contains a \mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1677} field +that carries the \mdline{1678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1678} identifier of the table to which this direct meter is +attached.%mdk + +%mdk-data-line={1681} +\mdline{1681}For indexed meters, the \mdline{1681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1681} message contains also an \mdline{1681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1681} +field, which indicates whether the index has a\mdline{1682}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1683}. This is useful for +\mdline{1684}\mdref{sec-psa-metadata-translation}{translation}\mdline{1684}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1685}).%mdk + +%mdk-data-line={1687} +\subsubsection{\mdline{1687}6.4.6.\hspace*{0.5em}\mdline{1687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\label{sec-controller-packet-meta}%mdk%mdk + +%mdk-data-line={1689} +\noindent\mdline{1689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1689} messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server.%mdk + +%mdk-data-line={1695} +\mdline{1695}When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet.%mdk + +%mdk-data-line={1701} +\mdline{1701}Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +\mdline{1703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_in")}}}\mdline{1703} and \mdline{1703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_out")}}}\mdline{1703}, +respectively. \mdline{1704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1704} messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages).%mdk + +%mdk-data-line={1709} +\mdline{1709}A P4Info message can contain at most two \mdline{1709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata~messages}}}\mdline{1709}, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields:%mdk + +%mdk-data-line={1713} +\begin{itemize}%mdk + +%mdk-data-line={1713} +\item{} +%mdk-data-line={1713} +\mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1713}, a \mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1713} message where \mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble.name}}}\mdline{1713} is set to \mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_in"}}}\mdline{1713} +and \mdline{1714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_out"}}}\mdline{1714} for packet-in and packet-out metadata, respectively.%mdk%mdk + +%mdk-data-line={1716} +\item{} +%mdk-data-line={1716} +\mdline{1716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{1716}, a repeated field of type \mdline{1716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1716}, where each \mdline{1716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1716} message +includes the following fields:%mdk + +%mdk-data-line={1718} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1718} +\item\mdline{1718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1718}, a \mdline{1718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1718} identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two \mdline{1719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1719} of the +same \mdline{1720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1720} message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the \mdline{1724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1724} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1725} +\item\mdline{1725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1725}, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below).%mdk + +%mdk-data-line={1729} +\item\mdline{1729}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1729}, a repeated field of strings, each one representing a P4 +annotation associated to this metadata.%mdk + +%mdk-data-line={1731} +\item\mdline{1731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1731}, an \mdline{1731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1731} representing the size in bits of this metadata.%mdk + +%mdk-data-line={1732} +\item\mdline{1732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1732}, which indicates whether the metadata field has a +\mdline{1733}\mdref{sec-user-defined-types}{user-defined type}\mdline{1733}; this is useful for +\mdline{1734}\mdref{sec-psa-metadata-translation}{translation}\mdline{1734}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1736} +\noindent\mdline{1736}As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding \mdline{1737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1737} +messages.%mdk + +%mdk-data-line={1740} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1741} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~egress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~port~where~the~packet}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~should~be~sent~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~queue\_id;~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~queue~ID~}{\mdcolor{darkgreen}*/}\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~ingress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~data~plane~port~ID~where}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~the~original~packet~was~received~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}1}\textgreater{}~is\_clone;~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~1~if~this~is~a~clone~of~the}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~original~packet~}{\mdcolor{darkgreen}*/}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1756} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1757} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868916615}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_out}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_out}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}egress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}queue\_id}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~\}\\ +\}\\ +\\ +controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868941301}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_in}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_in}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ingress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}is\_clone}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}1}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1794} +\noindent\mdline{1794}Note that the use of \mdline{1794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1794} is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages.%mdk + +%mdk-data-line={1800} +\subsubsection{\mdline{1800}6.4.7.\hspace*{0.5em}\mdline{1800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}\label{sec-valueset}%mdk%mdk + +%mdk-data-line={1802} +\noindent\mdline{1802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1802} messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P4\mdline{1805}\mdsub{16}\mdline{1805} +specification\mdline{1806}~[\mdcite{p4valuesets}{39}]\mdline{1806}.%mdk + +%mdk-data-line={1808} +\mdline{1808}The \mdline{1808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1808} message defines the following fields:%mdk + +%mdk-data-line={1810} +\begin{itemize}%mdk + +%mdk-data-line={1810} +\item{} +%mdk-data-line={1810} +\mdline{1810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1810}, a \mdline{1810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1810} message with the ID, name, and alias of this Value +Set.%mdk%mdk + +%mdk-data-line={1813} +\item{} +%mdk-data-line={1813} +\mdline{1813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1813}, a repeated field of \mdline{1813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1813} messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the \mdline{1816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1816} repeated field in the +\mdline{1817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{1817} message.%mdk%mdk + +%mdk-data-line={1819} +\item{} +%mdk-data-line={1819} +\mdline{1819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1819}, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +\mdline{1821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set}}}\mdline{1821} constructor call.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1823} +\noindent\mdline{1823}According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of \mdline{1826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1826}, +\mdline{1827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1827}, or \mdline{1827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1827}~[\mdcite{p4selectexpr}{26}]\mdline{1827}. The rest of this section looks at all 3 of +these cases and gives an example \mdline{1828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1828} message when appropriate.%mdk + +%mdk-data-line={1830} +\begin{enumerate}%mdk + +%mdk-data-line={1830} +\item{} +%mdk-data-line={1830} +\mdline{1830}If the type parameter is \mdline{1830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1830}, \mdline{1830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1830} will include exactly one +\mdline{1831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1831} message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used):%mdk + +%mdk-data-line={1834} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1834} +\item\mdline{1834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1834}: set to 1%mdk + +%mdk-data-line={1835} +\item\mdline{1835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1835}: set to the value of \mdline{1835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1835}%mdk + +%mdk-data-line={1836} +\item\mdline{1836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1836}: set to \mdline{1836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1836}%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1838} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1839} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}bit\textless{}8\textgreater{}~\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(hdr.f8)~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1842} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1843} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1857} +\begin{enumerate}[,start=2]%mdk + +%mdk-data-line={1857} +\item{} +%mdk-data-line={1857} +\mdline{1857}If the type parameter is a \mdline{1857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1857}, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program.%mdk%mdk + +%mdk-data-line={1862} +\item{} +%mdk-data-line={1862} +\mdline{1862}If the type parameter is a \mdline{1862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1862}, this version of P4Runtime requires that +all the fields of the struct be of type \mdline{1863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1863} (where \mdline{1863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1863} can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +\mdline{1866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1866} field will include one \mdline{1866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1866} message for each field in the +struct, with the following fields:%mdk + +%mdk-data-line={1869} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1869} +\item\mdline{1869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1869}: must be unique with respect to the other \mdline{1869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1869} entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +\mdline{1873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1873} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1874} +\item\mdline{1874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1874}: set to the name of the corresponding struct field.%mdk + +%mdk-data-line={1875} +\item\mdline{1875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1875}: set to the list of P4 annotations associated with the struct +field, except for the \mdline{1876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1876} annotation, if present (see the \mdline{1876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1876} field +below).%mdk + +%mdk-data-line={1878} +\item\mdline{1878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1878}: set to the value of \mdline{1878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1878} for the corresponding struct field.%mdk + +%mdk-data-line={1879} +\item\mdline{1879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1879}, which indicates whether the struct field has a\mdline{1879}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1880}; this is useful for +\mdline{1881}\mdref{sec-psa-metadata-translation}{translation}\mdline{1881}.%mdk + +%mdk-data-line={1882} +\item\mdline{1882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1882}: by default \mdline{1882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1882} is set to \mdline{1882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1882}; the P4 programmer can +specify a different match type by using the \mdline{1883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1883} annotation +\mdline{1884}[\mdcite{p4selectexpr}{26}]\mdline{1884}.%mdk + +%mdk-data-line={1885} +\item\mdline{1885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1885}: documentation associated with the struct field.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1887} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1888} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~bit\textless{}8\textgreater{}~f8;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(2)~@match(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(3)~@match(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1896} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1897} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1924} +\noindent\mdline{1924}In the above example, the \mdline{1924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1924} annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs.%mdk + +%mdk-data-line={1927} +\mdline{1927}Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a\mdline{1928}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1929} that resolves to a \mdline{1929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1929}, or a \mdline{1929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1929} where +one or more fields is a\mdline{1930}~\mdref{sec-user-defined-types}{user-defined type}\mdline{1930} that +resolves to a \mdline{1931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1931}. For each \mdline{1931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1931} that corresponds to a user-defined +type, the \mdline{1932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1932} field must be set to the appropriate value (\mdline{1932}i.e.\mdline{1932} the name +of the type).%mdk + +%mdk-data-line={1935} +\subsubsection{\mdline{1935}6.4.8.\hspace*{0.5em}\mdline{1935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}\label{sec-register}%mdk%mdk + +%mdk-data-line={1937} +\noindent\mdline{1937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1937} messages are used to specify all possible instances of Register PSA +externs.%mdk + +%mdk-data-line={1940} +\mdline{1940}Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime.%mdk + +%mdk-data-line={1944} +\mdline{1944}The \mdline{1944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1944} message defines the following fields:%mdk + +%mdk-data-line={1946} +\begin{itemize}%mdk + +%mdk-data-line={1946} +\item{} +%mdk-data-line={1946} +\mdline{1946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1946}, a \mdline{1946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1946} message with the ID, name, and alias of this register +instance.%mdk%mdk + +%mdk-data-line={1949} +\item{} +%mdk-data-line={1949} +\mdline{1949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1949}, which specifies the data type stored by this register, expressed +using a \mdline{1950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1950} message (see section on\mdline{1950}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary +P4 Types}\mdline{1951}).%mdk%mdk + +%mdk-data-line={1953} +\item{} +%mdk-data-line={1953} +\mdline{1953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1953}, an \mdline{1953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1953} value representing the total number of independent register +cells available.%mdk%mdk + +%mdk-data-line={1956} +\item{} +%mdk-data-line={1956} +\mdline{1956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1956}, which indicates whether the register index has a +\mdline{1957}\mdref{sec-user-defined-types}{user-defined type}\mdline{1957}. This is useful for +\mdline{1958}\mdref{sec-psa-metadata-translation}{translation}\mdline{1958}. The underlying built-in type +must be a fixed-width unsigned bitstring (\mdline{1959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1959}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1961} +\subsubsection{\mdline{1961}6.4.9.\hspace*{0.5em}\mdline{1961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}\label{sec-digest}%mdk%mdk + +%mdk-data-line={1963} +\noindent\mdline{1963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1963} messages are used to specify all possible instances of Packet Digest +PSA externs.%mdk + +%mdk-data-line={1966} +\mdline{1966}A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages.%mdk + +%mdk-data-line={1975} +\mdline{1975}The \mdline{1975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1975} message defines the following fields:%mdk + +%mdk-data-line={1977} +\begin{itemize}%mdk + +%mdk-data-line={1977} +\item{} +%mdk-data-line={1977} +\mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1977}, a \mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1977} message with the ID, name, and alias of this digest +instance.%mdk%mdk + +%mdk-data-line={1980} +\item{} +%mdk-data-line={1980} +\mdline{1980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1980}, which specifies the data type of an individual digest +notification using a \mdline{1981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1981} message (see section on\mdline{1981}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation +of Arbitrary P4 Types}\mdline{1982}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1984} +\subsubsection{\mdline{1984}6.4.10.\hspace*{0.5em}\mdline{1984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}\label{sec-p4info-extern}%mdk%mdk + +%mdk-data-line={1986} +\noindent\mdline{1986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1986} messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one \mdline{1989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1989} message instance in P4Info. The \mdline{1989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1989} message defines +the following fields:%mdk + +%mdk-data-line={1992} +\begin{itemize}%mdk + +%mdk-data-line={1992} +\item{} +%mdk-data-line={1992} +\mdline{1992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{1992}, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the\mdline{1993}~\mdref{sec-id-allocation}{reserved +range}\mdline{1994} \mdline{1994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{}[0x81,~0xfe]}}}\mdline{1994}. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture.%mdk%mdk + +%mdk-data-line={1999} +\item{} +%mdk-data-line={1999} +\mdline{1999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_name}}}\mdline{1999}, which specifies the fully-qualified P4 name of the extern +type.%mdk%mdk + +%mdk-data-line={2002} +\item{} +%mdk-data-line={2002} +\mdline{2002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instances}}}\mdline{2002}, a repeated field of \mdline{2002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{2002} Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +\mdline{2004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{2004} in turn defines the following fields:%mdk + +%mdk-data-line={2006} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2006} +\item\mdline{2006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{2006}, a \mdline{2006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{2006} message with the ID, name, and alias of this digest +instance.%mdk + +%mdk-data-line={2008} +\item\mdline{2008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{2008}, an \mdline{2008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{2008} Protobuf message\mdline{2008}~[\mdcite{protoany}{31}]\mdline{2008} which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for \mdline{2010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{2010} should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on\mdline{2012}~\mdref{sec-extending-p4runtime}{Extending +P4Runtime for non-PSA Architectures}\mdline{2013} for more +information.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2016} +\noindent\mdline{2016}If the P4 program does not include any instance of a given extern type, the +\mdline{2017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2017} message instance for that type should be omitted from the P4Info.%mdk + +%mdk-data-line={2019} +\subsection{\mdline{2019}6.5.\hspace*{0.5em}\mdline{2019}Support for Arbitrary P4 Types with P4TypeInfo}\label{sec-support-for-arbitrary-p4-types-with-p4typeinfo}%mdk%mdk + +%mdk-data-line={2021} +\noindent\mdline{2021}See section on\mdline{2021}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary P4 +Types}\mdline{2022}.%mdk + +%mdk-data-line={2024} +\section{\mdline{2024}7.\hspace*{0.5em}\mdline{2024}P4 Forwarding-Pipeline Configuration}\label{sec-p4-fwd-pipe-config}%mdk%mdk + +%mdk-data-line={2026} +\noindent\mdline{2026}The \mdline{2026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2026} captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the \mdline{2028}\textquotedblleft{}Device Configuration\textquotedblright{}\mdline{2028} and sometimes also referred to as +the \mdline{2029}\textquotedblleft{}P4 Blob\textquotedblright{}\mdline{2029}. It is defined as:%mdk + +%mdk-data-line={2031} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2032} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ForwardingPipelineConfig~\{\\ +~~config.P{\mdcolor{purple}4}Info~p4info~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~p4\_device\_config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}message}}~Cookie~\{\\ +~~~~{\bfseries{\mdcolor{navy}uint64}}~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~\}\\ +~~Cookie~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2042} +\noindent\mdline{2042}The \mdline{2042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{2042} field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic.%mdk + +%mdk-data-line={2045} +\mdline{2045}The \mdline{2045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{2045} is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new \mdline{2047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2047} on that target.%mdk + +%mdk-data-line={2049} +\mdline{2049}The \mdline{2049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{2049} field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a \mdline{2054}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{2054} RPC. +When writing the config via a \mdline{2055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{2055} RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present.%mdk + +%mdk-data-line={2059} +\section{\mdline{2059}8.\hspace*{0.5em}\mdline{2059}General Principles for Message Formatting}\label{sec-general-principles-for-message-formatting}%mdk%mdk + +%mdk-data-line={2061} +\subsection{\mdline{2061}8.1.\hspace*{0.5em}\mdline{2061}Set / Unset Protobuf Field}\label{sec-set-unset-protobuf-field}%mdk%mdk + +%mdk-data-line={2063} +\noindent\mdline{2063}In Protobuf version 3 (\mdline{2063}\emph{proto3}\mdline{2063}), the default value for a message field is +\mdline{2064}\textquotedblleft{}unset\textquotedblright{}\mdline{2064}~[\mdcite{protodefaults}{4}]\mdline{2064}. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +\mdline{2069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2069} message, an \mdline{2069}\textquotedblleft{}unset\textquotedblright{}\mdline{2069} \mdline{2069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2069} field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the \mdline{2071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2071} message field is +set, a single entry will be read.%mdk + +%mdk-data-line={2074} +\mdline{2074}Let\mdline{2074}'\mdline{2074}s look at the counter example in more details. Based on this specification +document, the C++ server code which processes \mdline{2075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2075} messages may look +like this:%mdk + +%mdk-data-line={2077} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2078} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}auto}}~*counter\_entry~=~...\\ +{\bfseries{\mdcolor{navy}if}}~(counter\_entry-\textgreater{}has\_index())~\{\\ +~~{\bfseries{\mdcolor{navy}auto}}~index~=~counter\_entry-\textgreater{}index().index();\\ +~~read\_one\_entry(counter\_entry-\textgreater{}id(),~index);\\ +\}~{\bfseries{\mdcolor{navy}else}}~\{\\ +~~read\_all\_entries(counter\_entry-\textgreater{}id());\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2087} +\begin{enumerate}%mdk + +%mdk-data-line={2087} +\item{} +%mdk-data-line={2087} +\mdline{2087}Reading a single counter entry at index 0 in the counter array with id +\mdline{2088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textless{}id\textgreater{}}}}\mdline{2088}:%mdk + +%mdk-data-line={2089} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2089} +\item\mdline{2089}Here is the C++ client code: + +%mdk-data-line={2090} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2091} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});\\ +entry.mutable\_index();\\ +{\mdcolor{darkgreen}//~The~above~line~sets~the~index~field;~it~is~equivalent~to:}\\ +{\mdcolor{darkgreen}//~auto~*index~=~entry.mutable\_index();}\\ +{\mdcolor{darkgreen}//~index-\textgreater{}set\_index(0);}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2098} +\item\mdline{2098}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2099} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2100} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}\\ +index~\{\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2103} +\item\mdline{2103}\textbf{Expected behavior}\mdline{2103}: Counter entry at index 0 is read. Notice that the +\mdline{2104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2104} subfield is missing under the \mdline{2104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2104} field message of +\mdline{2105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2105} in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2110} +\item{} +%mdk-data-line={2110} +\mdline{2110}Reading all counter entries by leaving the \mdline{2110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2110} field unset%mdk + +%mdk-data-line={2111} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2111} +\item\mdline{2111}Here is the C++ client code: + +%mdk-data-line={2112} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2113} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2116} +\item\mdline{2116}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2117} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2118} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2120} +\item\mdline{2120}\textbf{Expected behavior}\mdline{2120}: All counter entries for the provided counter +instance are read. Notice that the \mdline{2121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2121} message field is unset (default +value) and is therefore omitted from the textual representation of the +message.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={2125} +\subsection{\mdline{2125}8.2.\hspace*{0.5em}\mdline{2125}Read-Write Symmetry}\label{sec-read-write-symmetry}%mdk%mdk + +%mdk-data-line={2127} +\noindent\mdline{2127}The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example:%mdk + +%mdk-data-line={2133} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2134} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}intended\_value~=~value\\ +\\ +status~=~server.write(intended\_value,~p4\_entity)\\ +observed\_value~=~server.read(p4\_entity)\\ +\\ +assert(intended\_value~==~observed\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2142} +\noindent\mdline{2142}To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If \mdline{2146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{2146} RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol\mdline{2149}'\mdline{2149}s complexities to the client implementations.%mdk + +%mdk-data-line={2151} +\mdline{2151}In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the \mdline{2154}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2154} fields in a \mdline{2154}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2154} message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +\mdline{2157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MessageDifferencer}}}\mdline{2157} class\mdline{2157}~[\mdcite{protomessagedifferencer}{36}]\mdline{2157} included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance.%mdk + +%mdk-data-line={2162} +\subsection{\mdline{2162}8.3.\hspace*{0.5em}\mdline{2162}Zero as Reserved Value}\label{sec-zero-as-reserved-value}%mdk%mdk + +%mdk-data-line={2164} +\noindent\mdline{2164}p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a \mdline{2165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{2165}. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a \mdline{2168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{2168} or a \mdline{2168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfigRequest}}}\mdline{2168}.%mdk + +%mdk-data-line={2170} +\subsection{\mdline{2170}8.4.\hspace*{0.5em}\mdline{2170}Bytestrings}\label{sec-bytestrings}%mdk%mdk + +%mdk-data-line={2172} +\noindent\mdline{2172}P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (\mdline{2174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2174}) or signed (\mdline{2174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2174}), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +\mdline{2177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2177} Protobuf type. The correct bitwidth\mdline{2177} \mdline{2177}\textemdash{}\mdline{2177} as per the P4 program\mdline{2177} \mdline{2177}\textemdash{}\mdline{2177} of +each integer variable exposed through P4Runtime is specified in the P4Info +message.%mdk + +%mdk-data-line={2181} +\mdline{2181}The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals:%mdk + +%mdk-data-line={2184} +\begin{itemize}%mdk + +%mdk-data-line={2184} +\item{} +%mdk-data-line={2184} +\mdline{2184}It ensures that a properly encoded binary string\mdline{2184}'\mdline{2184}s integer value conforms +to the P4Info-specified bitwidth.%mdk%mdk + +%mdk-data-line={2187} +\item{} +%mdk-data-line={2187} +\mdline{2187}It supports\mdline{2187}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2187}.%mdk%mdk + +%mdk-data-line={2189} +\item{} +%mdk-data-line={2189} +\mdline{2189}It helps facilitate non-disruptive P4 program updates.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2191} +\noindent\mdline{2191}In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type \mdline{2196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2196} and/or \mdline{2196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2196}.%mdk + +%mdk-data-line={2198} +\mdline{2198}Note that this representation does \mdline{2198}\emph{not}\mdline{2198} make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range.%mdk + +%mdk-data-line={2207} +\mdline{2207}In the P4Runtime API version 1.0 (including minor version revisions), values +of table key fields, action parameters, and fields in packet-in and packet-out +headers between a device and the controller (see\mdline{2209}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{2209}), +may not be of type \mdline{2210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2210}. The rules for encoding signed values thus only +apply to messages of type \mdline{2211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2211} (see\mdline{2211}~\mdref{sec-p4data-in-p4runtime-proto}{8.5.3}\mdline{2211}).%mdk + +%mdk-data-line={2213} +\mdline{2213}For a value of type \mdline{2213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2213}, the fewest number of bits required to represent +the integer value \mdline{2214}$V > 0$\mdline{2214} is the smallest integer \mdline{2214}$A$\mdline{2214} such that \mdline{2214}$V \leq 2^A -1$\mdline{2215}.%mdk + +%mdk-data-line={2217} +\mdline{2217}For a value of type \mdline{2217}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2217}, the fewest number of bits required to represent +the integer value \mdline{2218}$V \neq 0$\mdline{2218} in 2\mdline{2218}'\mdline{2218}s complement form is the smallest integer \mdline{2218}$A$\mdline{2218} +such that \mdline{2219}$-2^{A-1} \leq V \leq 2^{A-1} - 1$\mdline{2219}.%mdk + +%mdk-data-line={2221} +\mdline{2221}As a special case, define that the value \mdline{2221}$V=0$\mdline{2221} requires at least \mdline{2221}$A=1$\mdline{2221} bit to +represent, regardless of whether it is signed or unsigned.%mdk + +%mdk-data-line={2224} +\mdline{2224}The shortest possible binary string for an integer \mdline{2224}$V$\mdline{2224} that needs \mdline{2224}$A$\mdline{2224} bits to +represent it is computed as:%mdk + +%mdk-data-line={2226} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2227} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size~=~floor(({\mdcolor{teal}A}~+~{\mdcolor{purple}7})~/~{\mdcolor{purple}8})}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2230} +\noindent\mdline{2230}Binary strings with the byte length computed as \mdline{2230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2230} promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies.%mdk + +%mdk-data-line={2234} +\mdline{2234}Any additional bits in the bytes sent for an unsigned integer value (type +\mdline{2235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2235}) must be 0. If additional bytes are transmitted above the +\mdline{2236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2236} minimum required, they must be filled with 0.%mdk + +%mdk-data-line={2238} +\mdline{2238}Any additional bits in the bytes sent for a signed integer value (type \mdline{2238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2238}) +must be copies of the sign bit, \mdline{2239}i.e.\mdline{2239} 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +\mdline{2241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2241} minimum required, they must be filled with copies of the +sign bit, \mdline{2242}i.e.\mdline{2242} 0 for non-negative values, or 0xff for negative values. In 2\mdline{2242}'\mdline{2242}s +complement representation, this is called \mdline{2243}\textquotedblleft{}sign extension\textquotedblright{}\mdline{2243}, and leaves the +numeric value represented unchanged.%mdk + +%mdk-data-line={2246} +\mdline{2246}Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value.%mdk + +%mdk-data-line={2252} +\mdline{2252}For a received bitstring expected to fit within a \mdline{2252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2252} type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring\mdline{2254}'\mdline{2254}s width is \mdline{2254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2254} bits or less.%mdk + +%mdk-data-line={2256} +\mdline{2256}For a received bitstring expected to fit within an \mdline{2256}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2256} type, the value it +represents is in range if, after \mdline{2257}\textquotedblleft{}undoing sign extension\textquotedblright{}\mdline{2257}, the remaining bit +string\mdline{2258}'\mdline{2258}s width is \mdline{2258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2258} bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other.%mdk + +%mdk-data-line={2264} +\mdline{2264}If the string\mdline{2264}'\mdline{2264}s byte length is zero, the server always rejects the string.%mdk + +%mdk-data-line={2266} +\mdline{2266}When the server rejects a binary string due to any of the previous criteria, +it returns an \mdline{2267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2267} error.%mdk + +%mdk-data-line={2269} +\mdline{2269}For all binary strings, P4Runtime uses big-endian (\mdline{2269}i.e.\mdline{2269} network) byte-order. +For signed integer values (\mdline{2270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2270} P4 type), P4Runtime uses the same two\mdline{2270}'\mdline{2270}s +complement bitwise representation as P4. Table\mdline{2271}~\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}}\mdline{2271} +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above.%mdk + +%mdk-data-line={2275} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2277} P4 type}}&\multicolumn{1}{|c}{{\bfseries\mdline{2277} Integer value}}&\multicolumn{1}{|c}{{\bfseries\mdline{2277} P4Runtime binary string}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2277} Read-write symmetry}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2279} \mdline{2279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2279}}&\multicolumn{1}{|l}{\mdline{2279} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2279} \mdline{2279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2279}}&\multicolumn{1}{|l|}{\mdline{2279} yes}\\ +\multicolumn{1}{|l}{\mdline{2280} \mdline{2280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2280}}&\multicolumn{1}{|l}{\mdline{2280} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2280} \mdline{2280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2280}}&\multicolumn{1}{|l|}{\mdline{2280} no}\\ +\multicolumn{1}{|l}{\mdline{2281} \mdline{2281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2281}}&\multicolumn{1}{|l}{\mdline{2281} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2281} \mdline{2281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2281}}&\multicolumn{1}{|l|}{\mdline{2281} yes}\\ +\multicolumn{1}{|l}{\mdline{2282} \mdline{2282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2282}}&\multicolumn{1}{|l}{\mdline{2282} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2282} \mdline{2282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x30\textbackslash{}x64}}}\mdline{2282}}&\multicolumn{1}{|l|}{\mdline{2282} yes}\\ +\multicolumn{1}{|l}{\mdline{2283} \mdline{2283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2283}}&\multicolumn{1}{|l}{\mdline{2283} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2283} \mdline{2283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x30\textbackslash{}x64}}}\mdline{2283}}&\multicolumn{1}{|l|}{\mdline{2283} no}\\ +\multicolumn{1}{|l}{\mdline{2284} \mdline{2284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2284}}&\multicolumn{1}{|l}{\mdline{2284} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2284} \mdline{2284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2284}}&\multicolumn{1}{|l|}{\mdline{2284} no}\\ +\multicolumn{1}{|l}{\mdline{2285} \mdline{2285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2285}}&\multicolumn{1}{|l}{\mdline{2285} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2285} \mdline{2285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2285}}&\multicolumn{1}{|l|}{\mdline{2285} yes}\\ +\multicolumn{1}{|l}{\mdline{2286} \mdline{2286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2286}}&\multicolumn{1}{|l}{\mdline{2286} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2286} \mdline{2286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00\textbackslash{}x63}}}\mdline{2286}}&\multicolumn{1}{|l|}{\mdline{2286} no}\\ +\multicolumn{1}{|l}{\mdline{2287} \mdline{2287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2287}}&\multicolumn{1}{|l}{\mdline{2287} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2287} \mdline{2287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2287}}&\multicolumn{1}{|l|}{\mdline{2287} yes}\\ +\multicolumn{1}{|l}{\mdline{2288} \mdline{2288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2288}}&\multicolumn{1}{|l}{\mdline{2288} \mdline{2288}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2288} \mdline{2288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x9d}}}\mdline{2288}}&\multicolumn{1}{|l|}{\mdline{2288} yes}\\ +\multicolumn{1}{|l}{\mdline{2289} \mdline{2289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2289}}&\multicolumn{1}{|l}{\mdline{2289} \mdline{2289}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2289} \mdline{2289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xff\textbackslash{}x9d}}}\mdline{2289}}&\multicolumn{1}{|l|}{\mdline{2289} no}\\ +\multicolumn{1}{|l}{\mdline{2290} \mdline{2290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2290}}&\multicolumn{1}{|l}{\mdline{2290} \mdline{2290}-739 (-0x2e3)}&\multicolumn{1}{|l}{\mdline{2290} \mdline{2290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xfd\textbackslash{}x1d}}}\mdline{2290}}&\multicolumn{1}{|l|}{\mdline{2290} yes}\\ +\multicolumn{1}{|l}{\mdline{2291} \mdline{2291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2291}}&\multicolumn{1}{|l}{\mdline{2291} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2291} \mdline{2291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00}}}\mdline{2291}}&\multicolumn{1}{|l|}{\mdline{2291} no}\\ +\multicolumn{1}{|l}{\mdline{2292} \mdline{2292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2292}}&\multicolumn{1}{|l}{\mdline{2292} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2292} \mdline{2292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00}}}\mdline{2292}}&\multicolumn{1}{|l|}{\mdline{2292} yes}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2294} +\mdhr{}%mdk + +%mdk-data-line={2295} +\noindent\mdline{2295}\mdcaption{\textbf{Table~\mdcaptionlabel{4}.}~\mdcaptiontext{Examples of Valid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-valid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2297} +\mdline{2297}Table\mdline{2297}~\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}}\mdline{2297} shows some examples of invalid +P4Runtime binary strings:%mdk + +%mdk-data-line={2300} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2302} P4 type}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2302} P4Runtime binary string}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2304} \mdline{2304}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2304}}&\multicolumn{1}{|l|}{\mdline{2304} \mdline{2304}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x63}}}\mdline{2304}}\\ +\multicolumn{1}{|l}{\mdline{2305} \mdline{2305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2305}}&\multicolumn{1}{|l|}{\mdline{2305} \mdline{2305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2305}}\\ +\multicolumn{1}{|l}{\mdline{2306} \mdline{2306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2306}}&\multicolumn{1}{|l|}{\mdline{2306} \mdline{2306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2306}}\\ +\multicolumn{1}{|l}{\mdline{2307} \mdline{2307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2307}}&\multicolumn{1}{|l|}{\mdline{2307} \mdline{2307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x10\textbackslash{}x63}}}\mdline{2307}}\\ +\multicolumn{1}{|l}{\mdline{2308} \mdline{2308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2308}}&\multicolumn{1}{|l|}{\mdline{2308} \mdline{2308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2308}}\\ +\multicolumn{1}{|l}{\mdline{2309} \mdline{2309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2309}}&\multicolumn{1}{|l|}{\mdline{2309} \mdline{2309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x40\textbackslash{}x63}}}\mdline{2309}}\\ +\multicolumn{1}{|l}{\mdline{2310} \mdline{2310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2310}}&\multicolumn{1}{|l|}{\mdline{2310} \mdline{2310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x9d}}}\mdline{2310}}\\ +\multicolumn{1}{|l}{\mdline{2311} \mdline{2311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2311}}&\multicolumn{1}{|l|}{\mdline{2311} \mdline{2311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x8d\textbackslash{}x1d}}}\mdline{2311}}\\ +\multicolumn{1}{|l}{\mdline{2312} \mdline{2312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2312}}&\multicolumn{1}{|l|}{\mdline{2312} \mdline{2312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2312}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2314} +\mdhr{}%mdk + +%mdk-data-line={2315} +\noindent\mdline{2315}\mdcaption{\textbf{Table~\mdcaptionlabel{5}.}~\mdcaptiontext{Examples of Invalid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-invalid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2317} +\mdline{2317}As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from \mdline{2322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2322} to \mdline{2322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2322}, a server +running the \mdline{2323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2323} version of the P4 program will accept requests from +clients that remain on the \mdline{2324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2324} P4Runtime version.%mdk + +%mdk-data-line={2326} +\mdline{2326}Despite the server\mdline{2326}'\mdline{2326}s binary string flexibility for P4 program update support, +the client and server must both remain aware of the +\mdline{2328}\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2328} +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values.%mdk + +%mdk-data-line={2333} +\mdline{2333}Representation of variable-length integer values (\mdline{2333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2333} P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the \mdline{2335}\emph{dynamic-length}\mdline{2335} of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an \mdline{2338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2338} error code otherwise.%mdk + +%mdk-data-line={2340} +\subsection{\mdline{2340}8.5.\hspace*{0.5em}\mdline{2340}Representation of Arbitrary P4 Types}\label{sec-representation-of-arbitrary-p4-types}%mdk%mdk + +%mdk-data-line={2342} +\subsubsection{\mdline{2342}8.5.1.\hspace*{0.5em}\mdline{2342}Problem Statement}\label{sec-problem-statement}%mdk%mdk + +%mdk-data-line={2344} +\noindent\mdline{2344}The P4\mdline{2344}\mdsub{16}\mdline{2344} language includes more complex types than just binary strings +\mdline{2345}[\mdcite{p4complextypes}{3}]\mdline{2345}. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table\mdline{2348}~\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}}\mdline{2348} shows the different +P4\mdline{2349}\mdsub{16}\mdline{2349} types and how they are allowed to be used, as per the P4\mdline{2349}\mdsub{16}\mdline{2349} +specification.%mdk + +%mdk-data-line={2352} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|l}{{\bfseries\mdline{2354}}}&\multicolumn{3}{|c|}{{\bfseries\mdline{2354} Container type}}\\ +\cmidrule{2-2}\cmidrule{3-3}\cmidrule{4-4} +\multicolumn{1}{|l}{{\bfseries\mdline{2356} Element type}}&\multicolumn{1}{|l}{{\bfseries\mdline{2356} header}}&\multicolumn{1}{|l}{{\bfseries\mdline{2356} header\mdline{2356}\_\mdline{2356}union}}&\multicolumn{1}{|l|}{{\bfseries\mdline{2356} struct or tuple}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2358} \mdline{2358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2358}}&\multicolumn{1}{|l}{\mdline{2358} allowed}&\multicolumn{1}{|l}{\mdline{2358} error}&\multicolumn{1}{|l|}{\mdline{2358} allowed}\\ +\multicolumn{1}{|l}{\mdline{2359} \mdline{2359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2359}}&\multicolumn{1}{|l}{\mdline{2359} allowed}&\multicolumn{1}{|l}{\mdline{2359} error}&\multicolumn{1}{|l|}{\mdline{2359} allowed}\\ +\multicolumn{1}{|l}{\mdline{2360} \mdline{2360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2360}}&\multicolumn{1}{|l}{\mdline{2360} allowed}&\multicolumn{1}{|l}{\mdline{2360} error}&\multicolumn{1}{|l|}{\mdline{2360} allowed}\\ +\multicolumn{1}{|l}{\mdline{2361} \mdline{2361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int}}}\mdline{2361}}&\multicolumn{1}{|l}{\mdline{2361} error}&\multicolumn{1}{|l}{\mdline{2361} error}&\multicolumn{1}{|l|}{\mdline{2361} error}\\ +\multicolumn{1}{|l}{\mdline{2362} \mdline{2362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}void}}}\mdline{2362}}&\multicolumn{1}{|l}{\mdline{2362} error}&\multicolumn{1}{|l}{\mdline{2362} error}&\multicolumn{1}{|l|}{\mdline{2362} error}\\ +\multicolumn{1}{|l}{\mdline{2363} \mdline{2363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2363}}&\multicolumn{1}{|l}{\mdline{2363} error}&\multicolumn{1}{|l}{\mdline{2363} error}&\multicolumn{1}{|l|}{\mdline{2363} allowed}\\ +\multicolumn{1}{|l}{\mdline{2364} \mdline{2364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_kind}}}\mdline{2364}}&\multicolumn{1}{|l}{\mdline{2364} error}&\multicolumn{1}{|l}{\mdline{2364} error}&\multicolumn{1}{|l|}{\mdline{2364} error}\\ +\multicolumn{1}{|l}{\mdline{2365} \mdline{2365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2365}}&\multicolumn{1}{|l}{\mdline{2365} error}&\multicolumn{1}{|l}{\mdline{2365} error}&\multicolumn{1}{|l|}{\mdline{2365} allowed}\\ +\multicolumn{1}{|l}{\mdline{2366} \mdline{2366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2366}}&\multicolumn{1}{|l}{\mdline{2366} allowed\mdline{2366}\mdfootnote{1}{%mdk-data-line={2376} +%mdk-data-line={2376} +\noindent\mdline{2376}an \mdline{2376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2376} type used as a field in a \mdline{2376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2376} must specify a +underlying type and representation for \mdline{2377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2377} elements.%mdk +\label{fn-enum_header}%mdk%mdk +}\mdline{2366}}&\multicolumn{1}{|l}{\mdline{2366} error}&\multicolumn{1}{|l|}{\mdline{2366} allowed}\\ +\multicolumn{1}{|l}{\mdline{2367} \mdline{2367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2367}}&\multicolumn{1}{|l}{\mdline{2367} error}&\multicolumn{1}{|l}{\mdline{2367} allowed}&\multicolumn{1}{|l|}{\mdline{2367} allowed}\\ +\multicolumn{1}{|l}{\mdline{2368} header stack}&\multicolumn{1}{|l}{\mdline{2368} error}&\multicolumn{1}{|l}{\mdline{2368} error}&\multicolumn{1}{|l|}{\mdline{2368} allowed}\\ +\multicolumn{1}{|l}{\mdline{2369} \mdline{2369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2369}}&\multicolumn{1}{|l}{\mdline{2369} error}&\multicolumn{1}{|l}{\mdline{2369} error}&\multicolumn{1}{|l|}{\mdline{2369} allowed}\\ +\multicolumn{1}{|l}{\mdline{2370} \mdline{2370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2370}}&\multicolumn{1}{|l}{\mdline{2370} error}&\multicolumn{1}{|l}{\mdline{2370} error}&\multicolumn{1}{|l|}{\mdline{2370} allowed}\\ +\multicolumn{1}{|l}{\mdline{2371} \mdline{2371}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2371}}&\multicolumn{1}{|l}{\mdline{2371} error}&\multicolumn{1}{|l}{\mdline{2371} error}&\multicolumn{1}{|l|}{\mdline{2371} allowed}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2373} +\mdhr{}%mdk + +%mdk-data-line={2374} +\noindent\mdline{2374}\mdcaption{\textbf{Table~\mdcaptionlabel{6}.}~\mdcaptiontext{P4 Type Usage}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-type-usage}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2379} +\mdline{2379}For example, the following P4\mdline{2379}\mdsub{16}\mdline{2379} objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects.%mdk + +%mdk-data-line={2382} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2383} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}{\bfseries{\mdcolor{navy}tuple}}\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}4}\textgreater{},~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~\textgreater{}~\textgreater{}()~digest\_complex;\\ +digest\_complex.pack(\{~hdr.ipv4.version,~hdr.ipv4.protocol~\});\\ +{\mdcolor{darkgreen}//~...}\\ +{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2393} +\noindent\mdline{2393}One solution would be to use only binary string (\mdline{2393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2393} type) in +p4runtime.proto and to define a custom serialization format for complex P4\mdline{2394}\mdsub{16}\mdline{2394} +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P4\mdline{2401}\mdsub{16}\mdline{2401} types.%mdk + +%mdk-data-line={2403} +\subsubsection{\mdline{2403}8.5.2.\hspace*{0.5em}\mdline{2403}P4 Type Specifications in p4info.proto}\label{sec-p4-type-specifications-in-p4infoproto}%mdk%mdk + +%mdk-data-line={2405} +\noindent\mdline{2405}In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type \mdline{2409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip\_t}}}\mdline{2409}, which is a header union with 2 possible headers: +\mdline{2410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4}}}\mdline{2410} with type \mdline{2410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4\_t}}}\mdline{2410} and \mdline{2410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6}}}\mdline{2410} with type \mdline{2410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6\_t}}}\mdline{2410}. Similarly, they need to +know the field layout for both of these header types.%mdk + +%mdk-data-line={2413} +\mdline{2413}To achieve this we introduce 2 main Protobuf messages: \mdline{2413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2413} and +\mdline{2414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2414}.%mdk + +%mdk-data-line={2416} +\mdline{2416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2416} is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P4\mdline{2417}\mdsub{16}\mdline{2417} program. These +named types are \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2418}, \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2418}, \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2418}, \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2418} and +\mdline{2419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2419}; for each of these we have a type specification message, +respectively \mdline{2420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructTypeSpec}}}\mdline{2420}, \mdline{2420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderTypeSpec}}}\mdline{2420}, \mdline{2420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionTypeSpec}}}\mdline{2420}, +\mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4EnumTypeSpec}}}\mdline{2421} and \mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4SerializableEnumTypeSpec}}}\mdline{2421}. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. \mdline{2423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2423} also includes the list of parser errors for the program, as +a \mdline{2424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4ErrorTypeSpec}}}\mdline{2424} message.%mdk + +%mdk-data-line={2426} +\mdline{2426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2426} is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each \mdline{2428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2428} message corresponds to a compile-time type in the +original P4\mdline{2429}\mdsub{16}\mdline{2429} program (\mdline{2429}e.g.\mdline{2429} the type parameter of an extern). This +compile-time type is represented as a Protobuf \mdline{2430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2430}, which can be:%mdk + +%mdk-data-line={2432} +\begin{itemize}%mdk + +%mdk-data-line={2432} +\item{} +%mdk-data-line={2432} +\mdline{2432}a string representing the name of the type in case of a named type (\mdline{2432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2432}, +\mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2433} or user-defined \mdline{2433}\textquotedblleft{}new\textquotedblright{}\mdline{2433} +\mdline{2434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2434}),%mdk%mdk + +%mdk-data-line={2436} +\item{} +%mdk-data-line={2436} +\mdline{2436}an empty Protobuf message for \mdline{2436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2436} and \mdline{2436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2436}, or%mdk%mdk + +%mdk-data-line={2438} +\item{} +%mdk-data-line={2438} +\mdline{2438}a Protobuf message for other anonymous types (\mdline{2438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2438}, \mdline{2438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2438}, \mdline{2438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2438}, +\mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2439} or stack). The \mdline{2439}\textquotedblleft{}binary string\textquotedblright{}\mdline{2439} types (\mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2439}, \mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2439}, and +\mdline{2440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2440}) are grouped together in the \mdline{2440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4BitstringLikeTypeSpec}}}\mdline{2440} message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf \mdline{2442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2442} +type).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2445} +\noindent\mdline{2445}For all P4\mdline{2445}\mdsub{16}\mdline{2445} compound types (\mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2445}, \mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2445}, \mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2445}, and \mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2445}), +the order of \mdline{2446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2446} in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P4\mdline{2448}\mdsub{16}\mdline{2448} declaration. The same goes for the order of members of an \mdline{2448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2448} +(serializable or not) or members of \mdline{2449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2449}.%mdk + +%mdk-data-line={2451} +\subsubsection{\mdline{2451}8.5.3.\hspace*{0.5em}\mdline{2451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2451} in p4runtime.proto}\label{sec-p4data-in-p4runtime-proto}%mdk%mdk + +%mdk-data-line={2453} +\noindent\mdline{2453}P4Runtime uses the \mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2453} message to represent values of arbitrary types. The +P4Runtime client must generate correct \mdline{2454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2454} messages based on the type +specification information included in P4Info. The \mdline{2455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2455} message was designed +to introduce little overhead compared to using binary strings in the most common +case (P4\mdline{2457}\mdsub{16}\mdline{2457} \mdline{2457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2457} type).%mdk + +%mdk-data-line={2459} +\mdline{2459}Just like its P4Info counterpart\mdline{2459} \mdline{2459}- \mdline{2459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2459} \mdline{2459}-, \mdline{2459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2459} uses a Protobuf +\mdline{2460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2460} to represent all possible values.%mdk + +%mdk-data-line={2462} +\mdline{2462}We define a canonical representation for \mdline{2462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2462} messages\mdline{2462} \mdline{2462}\textemdash{}\mdline{2462} therefore +guaranteeing read-write symmetry\mdline{2463} \mdline{2463}\textemdash{}\mdline{2463} by introducing the following requirements:%mdk + +%mdk-data-line={2465} +\begin{itemize}%mdk + +%mdk-data-line={2465} +\item{} +%mdk-data-line={2465} +\mdline{2465}The order of \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2465} in \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructLike}}}\mdline{2465} and the order of \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2465} in +\mdline{2466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2466} must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P4\mdline{2467}\mdsub{16}\mdline{2467} type +declaration.%mdk%mdk + +%mdk-data-line={2470} +\item{} +%mdk-data-line={2470} +\mdline{2470}An invalid header is represented by a \mdline{2470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2470} message where the \mdline{2470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_valid}}}\mdline{2470} +field is false and the \mdline{2471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2471} repeated field is empty.%mdk%mdk + +%mdk-data-line={2473} +\item{} +%mdk-data-line={2473} +\mdline{2473}An invalid header union (\mdline{2473}i.e.\mdline{2473} all headers in the union are invalid) is +represented by a \mdline{2474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnion}}}\mdline{2474} message where the \mdline{2474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header\_name}}}\mdline{2474} is the +empty string (default value for the field) and the \mdline{2475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header}}}\mdline{2475} is unset.%mdk%mdk + +%mdk-data-line={2477} +\item{} +%mdk-data-line={2477} +\mdline{2477}The order of \mdline{2477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2477} in \mdline{2477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStack}}}\mdline{2477} and \mdline{2477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStack}}}\mdline{2477} is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the \mdline{2479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2479} field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding \mdline{2481}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStackTypeSpec}}}\mdline{2481} or +\mdline{2482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStackTypeSpec}}}\mdline{2482} message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2484} +\subsubsection{\mdline{2484}8.5.4.\hspace*{0.5em}\mdline{2484}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={2486} +\noindent\mdline{2486}Let\mdline{2486}'\mdline{2486}s look at the Register example again:%mdk + +%mdk-data-line={2488} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2489} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2496} +\noindent\mdline{2496}Here\mdline{2496}'\mdline{2496}s the corresponding entry in the P4Info message:%mdk + +%mdk-data-line={2498} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2499} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}registers~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}369119267}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~\}\\ +~~type\_spec~\{\\ +~~~~header\_union~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~size:~{\mdcolor{purple}128}\\ +\}\\ +type\_info~\{\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~header\_unions~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2555} +\noindent\mdline{2555}Here\mdline{2555}'\mdline{2555}s a \mdline{2555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.WriteRequest}}}\mdline{2555} to set the value of \mdline{2555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_ip{}[12]}}}\mdline{2555}:%mdk + +%mdk-data-line={2557} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2558} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}update~\{\\ +~~type:~INSERT\\ +~~entity~\{\\ +~~~~register\_entry~\{\\ +~~~~~~register\_id:~{\mdcolor{purple}369119267}\\ +~~~~~~index~\{\\ +~~~~~~~~index:~{\mdcolor{purple}12}\\ +~~~~~~\}\\ +~~~~~~data~\{\\ +~~~~~~~~header\_union~\{\\ +~~~~~~~~~~valid\_header\_name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~~~valid\_header~\{\\ +~~~~~~~~~~~~is\_valid:~true\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x04}{\mdcolor{maroon}"}\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{darkgreen}\#~...}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2581} +\subsubsection{\mdline{2581}8.5.5.\hspace*{0.5em}\mdline{2581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2581}, serializable \mdline{2581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2581} and \mdline{2581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}\label{sec-enum-serializable-enum-and-error}%mdk%mdk + +%mdk-data-line={2583} +\noindent\mdline{2583}P4\mdline{2583}\mdsub{16}\mdline{2583} supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or \mdline{2584}\textquotedblleft{}unsafe\textquotedblright{}\mdline{2584} enum) +\mdline{2585}[\mdcite{p4enums}{5}]\mdline{2585}. For \mdline{2585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2585} types with no underlying type\mdline{2585} \mdline{2585}\textemdash{}\mdline{2585} as well as \mdline{2585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2585} \mdline{2585}\textemdash{}\mdline{2585} +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in \mdline{2588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2588} to represent \mdline{2588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2588} and +\mdline{2589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2589} values.%mdk + +%mdk-data-line={2591} +\mdline{2591}Serializable \mdline{2591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2591} types have an underlying fixed-width unsigned integer +representation (\mdline{2592}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2592}). All named enum members must be assigned an integer +value by the P4 programmer, but \mdline{2593}\emph{not all}\mdline{2593} valid numeric values for the +underlying type need to have a corresponding name. \mdline{2594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2594} includes the +mapping between entry name and entry value. When providing serializable enum +values through \mdline{2596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2596}, one must use the assigned integer value (\mdline{2596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum\_value}}}\mdline{2596} +bytestring field). P4Runtime does not provide a way for the client to use the +name\mdline{2598} \mdline{2598}\textemdash{}\mdline{2598} even when the enum member has one\mdline{2598} \mdline{2598}\textemdash{}\mdline{2598} instead of the value, as it makes +it easier for the server to respect the\mdline{2599}~\mdref{sec-read-write-symmetry}{read-write +symmetry}\mdline{2600} principle.%mdk + +%mdk-data-line={2602} +\subsubsection{\mdline{2602}8.5.6.\hspace*{0.5em}\mdline{2602}User-defined types}\label{sec-user-defined-types}%mdk%mdk + +%mdk-data-line={2604} +\noindent\mdline{2604}P4\mdline{2604}\mdsub{16}\mdline{2604} enables programmers to introduce new types\mdline{2604}~[\mdcite{p4newtypes}{11}]\mdline{2604}. While similar +to \mdline{2605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{2605}, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +\mdline{2608}\mdref{sec-psa-metadata-translation}{translation}\mdline{2608}. When introducing a new type, the +declaration can be annotated with \mdline{2609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2609} to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for\mdline{2611}~\mdref{sec-translation-of-port-numbers}{port numbers}\mdline{2611}, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. \mdline{2614}\textbf{The \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}} annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}})}\mdline{2616}. The type exposed to the control plane (referred to as the +\mdline{2617}\emph{controller\_type}\mdline{2617}) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a \mdline{2619}\emph{URI}\mdline{2619} (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the \mdline{2621}\emph{controller\_type}\mdline{2621} of the values exposed to the control plane. The +\mdline{2622}\emph{controller\_type}\mdline{2622} can be either \mdline{2622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2622} where \mdline{2622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2622} is any positive integer, or +\mdline{2623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{2623}, or a positive integer \mdline{2623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2623} which has the same meaning as \mdline{2623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2623}. +Specifying just an integer is deprecated.%mdk + +%mdk-data-line={2626} +\mdline{2626}It is recommended that the URI includes at least the P4 architecture name and +the type name.%mdk + +%mdk-data-line={2629} +\mdline{2629}A \mdline{2629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2629} annotation need not have any effect if it is used to +annotate anything in a P4 program other than a \mdline{2630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2630} declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect.%mdk + +%mdk-data-line={2634} +\mdline{2634}User-defined types are specified using the \mdline{2634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{2634} message, which has +the following fields:%mdk + +%mdk-data-line={2637} +\begin{itemize}%mdk + +%mdk-data-line={2637} +\item{} +%mdk-data-line={2637} +\mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}representation}}}\mdline{2637}, a Protobuf \mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2637} specifying how values of this type are +exchanged between client and server; it can be either:%mdk + +%mdk-data-line={2640} +\begin{itemize}%mdk + +%mdk-data-line={2640} +\item{} +%mdk-data-line={2640} +\mdline{2640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2640}, if and only if no \mdline{2640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2640} annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 \mdline{2642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2642} declaration is itself a +user-defined type, \mdline{2643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2643} is obtained by \mdline{2643}\textquotedblleft{}walking\textquotedblright{}\mdline{2643} the chain of +\mdline{2644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2644} declarations recursively until a built-in type (\mdline{2644}e.g.\mdline{2644} \mdline{2644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2644}) is +found.%mdk%mdk + +%mdk-data-line={2647} +\item{} +%mdk-data-line={2647} +\mdline{2647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}translated\_type}}}\mdline{2647}, if and only if the P4 \mdline{2647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2647} declaration was annotated +with \mdline{2648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2648}. It is of type \mdline{2648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeTranslation}}}\mdline{2648}, +which itself has two fields\mdline{2649} \mdline{2649}\textemdash{}\mdline{2649} \mdline{2649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uri}}}\mdline{2649} and either \mdline{2649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_string}}}\mdline{2649} or +\mdline{2650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_bitwidth}}}\mdline{2650} \mdline{2650}\textemdash{}\mdline{2650}, which map to the two input parameters to the +annotation.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2653} +\item{} +%mdk-data-line={2653} +\mdline{2653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{2653}, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2656} +\noindent\mdline{2656}For example, an architecture\mdline{2656} \mdline{2656}\textemdash{}\mdline{2656} in this case PSA\mdline{2656} \mdline{2656}\textemdash{}\mdline{2656} may introduce a new type +for port numbers:%mdk + +%mdk-data-line={2658} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2659} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~string,~e.g.~"eth0".}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~32-bit~integer,~e.g.~0xffffffff.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{darkgreen}//~Same~as~above.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_32\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_32\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2672} +\noindent\mdline{2672}In this case, the P4Info message would include the following \mdline{2672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2672} +messages:%mdk + +%mdk-data-line={2675} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2676} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_string:~\{\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2713} +\noindent\mdline{2713}Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (\mdline{2714}e.g.\mdline{2714} through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over \mdline{2716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2716} to enable users +to overwrite annotations included as part of the P4 architecture definition.%mdk + +%mdk-data-line={2719} +\subsubsection{\mdline{2719}8.5.7.\hspace*{0.5em}\mdline{2719}Trade-off for v1.x Releases}\label{sec-trade-off-for-v1x-releases}%mdk%mdk + +%mdk-data-line={2721} +\noindent\mdline{2721}For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +\mdline{2722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2722} with \mdline{2722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2722} in the \mdline{2722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{2722} message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +\mdline{2725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2725} to provide action parameter values and controller metadata +values. However \mdline{2726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2726} is used whenever appropriate for PSA externs and we +encourage the use of \mdline{2727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2727} in architecture-specific extensions.%mdk + +%mdk-data-line={2729} +\mdline{2729}In order to support\mdline{2729}~\mdref{sec-psa-metadata-translation}{translation}\mdline{2729} for action +parameters and match fields, we include a \mdline{2730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2730} field in +\mdline{2731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{2731}, \mdline{2731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Action.Param}}}\mdline{2731} and +\mdline{2732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ControllerPacketMetadata.Metadata}}}\mdline{2732}. In addition, the \mdline{2732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2732} +field for all of these message types must abide by the following rule when +\mdline{2734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2734} names a translated user-defined type:%mdk + +%mdk-data-line={2736} +\begin{itemize}%mdk + +%mdk-data-line={2736} +\item{} +%mdk-data-line={2736} +\mdline{2736}If the \mdline{2736}\emph{controller\_type}\mdline{2736} is a fixed-width unsigned bitstring, the \mdline{2736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2736} +field must be set to the bitwidth of the \mdline{2737}\emph{controller\_type}\mdline{2737}. This information +is redundant with the one included in the \mdline{2738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2738} entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent.%mdk%mdk + +%mdk-data-line={2744} +\item{} +%mdk-data-line={2744} +\mdline{2744}Otherwise (\mdline{2744}i.e.\mdline{2744}, if the \mdline{2744}\emph{controller\_type}\mdline{2744} is a string), the \mdline{2744}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2744} must +be \mdline{2745}\textquotedblleft{}unset\textquotedblright{}\mdline{2745}, which, in Protobuf version 3, is the same as setting the field to +0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2748} +\noindent\mdline{2748}For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types:%mdk + +%mdk-data-line={2750} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2751} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{navy}@}{\mdcolor{navy}name}{\mdcolor{maroon}(".t")}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~meta.port1:~exact;~~{\mdcolor{darkgreen}//~meta.port1~has~type~PortId\_String\_t}\\ +~~~~meta.port2:~exact;~~{\mdcolor{darkgreen}//~meta.port2~has~type~PortId\_Bit32\_t}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2769} +\noindent\mdline{2769}This table would have the following representation in the generated P4Info +message:%mdk + +%mdk-data-line={2771} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2772} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tables~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}34728461}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port1}{\mdcolor{maroon}"}\\ +~~~~{\mdcolor{darkgreen}\#~notice~that~bitwidth~is~unset}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port2}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~{\mdcolor{darkgreen}\#~...}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2800} +\section{\mdline{2800}9.\hspace*{0.5em}\mdline{2800}P4 Entity Messages}\label{sec-p4-entity-msgs}%mdk%mdk + +%mdk-data-line={2802} +\noindent\mdline{2802}P4Runtime covers P4 entities that are either part of the P4\mdline{2802}\mdsub{16}\mdline{2802} language, or +defined as PSA externs. The sections below describe the messages for each +supported entity.%mdk + +%mdk-data-line={2806} +\subsection{\mdline{2806}9.1.\hspace*{0.5em}\mdline{2806}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}\label{sec-table-entry}%mdk%mdk + +%mdk-data-line={2808} +\noindent\mdline{2808}The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action\mdline{2810}'\mdline{2810}s +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification.%mdk + +%mdk-data-line={2816} +\mdline{2816}P4Runtime supports inserting, modifying, deleting and reading table entries with +the \mdline{2817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2817} entity, which has the following fields:%mdk + +%mdk-data-line={2819} +\begin{itemize}%mdk + +%mdk-data-line={2819} +\item{} +%mdk-data-line={2819} +\mdline{2819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2819}, which identifies the table instance; the \mdline{2819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2819} is determined +by the P4Info message.%mdk%mdk + +%mdk-data-line={2822} +\item{} +%mdk-data-line={2822} +\mdline{2822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2822}, a repeated field of \mdline{2822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2822} messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration.%mdk%mdk + +%mdk-data-line={2826} +\item{} +%mdk-data-line={2826} +\mdline{2826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2826}, which indicates which of the table\mdline{2826}'\mdline{2826}s actions to execute in case of +match and with which argument values.%mdk%mdk + +%mdk-data-line={2829} +\item{} +%mdk-data-line={2829} +\mdline{2829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2829}, a 32-bit integer used to order entries when the table\mdline{2829}'\mdline{2829}s match key +includes an optional, ternary or range match.%mdk%mdk + +%mdk-data-line={2832} +\item{} +%mdk-data-line={2832} +\mdline{2832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2832}, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +\mdline{2836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{2836} field.%mdk%mdk + +%mdk-data-line={2838} +\item{} +%mdk-data-line={2838} +\mdline{2838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{2838}, an arbitrary \mdline{2838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2838} value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry.%mdk%mdk + +%mdk-data-line={2843} +\item{} +%mdk-data-line={2843} +\mdline{2843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2843}, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See\mdline{2844}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2845} section for more information.%mdk%mdk + +%mdk-data-line={2847} +\item{} +%mdk-data-line={2847} +\mdline{2847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2847}, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See\mdline{2848}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2849} section for more information.%mdk%mdk + +%mdk-data-line={2851} +\item{} +%mdk-data-line={2851} +\mdline{2851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{2851}, which is used to read and write the per-color counter +values for the direct meter entry attached to this table entry, if any. +See\mdline{2853}~\mdref{sec-direct-resources}{Direct resources}\mdline{2853} section for more information.%mdk%mdk + +%mdk-data-line={2855} +\item{} +%mdk-data-line={2855} +\mdline{2855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2855}, a boolean flag which indicates whether the table entry is +the default entry for the table. See\mdline{2856}~\mdref{sec-default-entry}{Default entry}\mdline{2856} +section for more information.%mdk%mdk + +%mdk-data-line={2859} +\item{} +%mdk-data-line={2859} +\mdline{2859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2859} and \mdline{2859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2859}, which are two fields used to +implement idle-timeout support for the table, if applicable. See +\mdline{2861}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{2861} section for more information.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2863} +\noindent\mdline{2863}The \mdline{2863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2863} field must be set to a non-zero value if the match key includes a +ternary match (\mdline{2864}i.e.\mdline{2864} in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an \mdline{2865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{2865}, \mdline{2865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2865} or +\mdline{2866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2866} match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches.%mdk + +%mdk-data-line={2875} +\mdline{2875}The \mdline{2875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2875} and \mdline{2875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2875} fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for \mdline{2877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2877} and \mdline{2877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{2877} updates. When deleting +an entry, these key fields (along with \mdline{2878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2878}) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a \mdline{2880}\emph{keyless}\mdline{2880} +table (the table has an empty match key), the server must reject all attempts to +\mdline{2882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2882} a match entry and return an \mdline{2882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2882} error.%mdk + +%mdk-data-line={2884} +\mdline{2884}The number of match entries that a table \mdline{2884}\emph{should}\mdline{2884} support is indicated in P4Info +(\mdline{2885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2885} field of \mdline{2885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{2885} message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P4\mdline{2886}\mdsub{16}\mdline{2886} specification for the +\mdline{2887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2887} property\mdline{2887}~[\mdcite{p4tableproperties}{30}]\mdline{2887}. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +\mdline{2891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{2891} when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached.%mdk + +%mdk-data-line={2896} +\subsubsection{\mdline{2896}9.1.1.\hspace*{0.5em}\mdline{2896}Match Format}\label{sec-match-format}%mdk%mdk + +%mdk-data-line={2898} +\noindent\mdline{2898}The bytes fields in the \mdline{2898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2898} message follow the format described in +\mdline{2899}\mdref{sec-bytestrings}{Bytestrings}\mdline{2899}.%mdk + +%mdk-data-line={2901} +\mdline{2901}For \mdline{2901}\textquotedblleft{}don't care\textquotedblright{}\mdline{2901} matches, the P4Runtime client must omit the field\mdline{2901}'\mdline{2901}s entire +\mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2902} entry when building the \mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2902} repeated field of the \mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2902} +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for \mdline{2904}\textquotedblleft{}don't care\textquotedblright{}\mdline{2904} matches, which is needed +to ensure\mdline{2905}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2905}. For PSA match types, +a \mdline{2906}\textquotedblleft{}don't care\textquotedblright{}\mdline{2906} match for a specific match key field is defined as follows:%mdk + +%mdk-data-line={2908} +\begin{itemize}%mdk + +%mdk-data-line={2908} +\item{} +%mdk-data-line={2908} +\mdline{2908}For a \mdline{2908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2908} match, it is logically equivalent to a mask of zeros.%mdk%mdk + +%mdk-data-line={2910} +\item{} +%mdk-data-line={2910} +\mdline{2910}For a \mdline{2910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{2910} match, it is logically equivalent to a wildcard match.%mdk%mdk + +%mdk-data-line={2912} +\item{} +%mdk-data-line={2912} +\mdline{2912}For an \mdline{2912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2912} match, it is logically equivalent to a prefix\mdline{2912}\_\mdline{2912}len of zero.%mdk%mdk + +%mdk-data-line={2914} +\item{} +%mdk-data-line={2914} +\mdline{2914}For a \mdline{2914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2914} match, it is logically equivalent to a range which includes all +possible values for the field.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2917} +\noindent\mdline{2917}Note that there is no \mdline{2917}\textquotedblleft{}don't care\textquotedblright{}\mdline{2917} value for \mdline{2917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2917} matches and therefore exact +match fields can never be omitted from the \mdline{2918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2918} message.%mdk + +%mdk-data-line={2920} +\mdline{2920}The following example shows a P4Runtime message that treats a \mdline{2920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2920} field +as a \mdline{2921}\textquotedblleft{}don't care\textquotedblright{}\mdline{2921} match. The P4 program defines table \mdline{2921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{2921} with \mdline{2921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2921} +and \mdline{2922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2922} fields in its match key:%mdk + +%mdk-data-line={2924} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2925} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~ternary;\\ +~~~~istd.ingress\_port:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2936} +\noindent\mdline{2936}In this P4Runtime request, the client omits the table\mdline{2936}'\mdline{2936}s \mdline{2936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2936} field +from the repeated \mdline{2937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2937} field to indicate a \mdline{2937}\textquotedblleft{}don't care\textquotedblright{}\mdline{2937} match. As shown +below, the \mdline{2938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2938} specifies only the \mdline{2938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2938} field given by \mdline{2938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id:~2}}}\mdline{2938}.%mdk + +%mdk-data-line={2940} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2941} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}33554439}~~{\mdcolor{darkgreen}\#~Table~t's~ID.}\\ +~~~~match~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~field\_id~1~is~not~present~to~use~the~don't~care~ternary~value.}\\ +~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~exact~\{\\ +~~~~~~~~value:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x20}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~action~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~Action~selection~goes~here.}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2959} +\noindent\mdline{2959}For every member of the \mdline{2959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2959} repeated \mdline{2959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2959} field, \mdline{2959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id}}}\mdline{2959} must be +a valid id for the table, as per the P4Info, and one of the fields in +\mdline{2961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{2961} must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an \mdline{2963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2963} error code.%mdk + +%mdk-data-line={2965} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2965} +\item\mdline{2965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2965} match + +%mdk-data-line={2966} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2966} +\item\mdline{2966}The binary string encoding of the value must conform to the +\mdline{2967}\mdref{sec-bytestrings}{Bytestrings}\mdline{2967} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2969} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2970} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.exact().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2973} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2973} +\item\mdline{2973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2973} match + +%mdk-data-line={2974} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2974} +\item\mdline{2974}The binary string encoding of the value (when present) must conform to the +\mdline{2975}\mdref{sec-bytestrings}{Bytestrings}\mdline{2975} requirements.%mdk + +%mdk-data-line={2976} +\item\mdline{2976}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2976} match must be omitted.%mdk + +%mdk-data-line={2977} +\item\mdline{2977}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2977} bits must be 0 in value.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2979} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2980} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.lpm().value()))\\ +\\ +pLen~=~match.lpm().prefix\_len()\\ +assert(pLen~\textgreater{}~0)\\ +\\ +trailing\_zeros~=~countTrailingZeros(match.lpm().value())\\ +assert(trailing\_zeros~\textgreater{}=~field\_bits~-~pLen)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2989} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2989} +\item\mdline{2989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2989} match + +%mdk-data-line={2990} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2990} +\item\mdline{2990}The binary string encoding of the value (when present) and mask (when +present) must conform to the\mdline{2991}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2991} requirements.%mdk + +%mdk-data-line={2992} +\item\mdline{2992}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2992} match must be omitted.%mdk + +%mdk-data-line={2993} +\item\mdline{2993}Masked bits must be 0 in value. This constraint taken together +with the\mdline{2994}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2994} requirements means that the +value\mdline{2995}'\mdline{2995}s binary string is never longer than the mask\mdline{2995}'\mdline{2995}s binary string. +When the value\mdline{2996}'\mdline{2996}s string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3000} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3001} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.ternary().value()))\\ +assert(BytestringValid(match.ternary().mask()))\\ +assert(match.ternary().value().size()~\textless{}=~match.ternary().mask().size());\\ +\\ +value~=~parseInteger(match.ternary().value())\\ +mask~=~parseInteger(match.ternary().mask())\\ +\\ +assert(mask~!=~0)\\ +\\ +assert(value~\&~mask~==~value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3013} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3013} +\item\mdline{3013}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3013} match + +%mdk-data-line={3014} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3014} +\item\mdline{3014}The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the\mdline{3015}~\mdref{sec-bytestrings}{Bytestrings}\mdline{3015} +requirements.%mdk + +%mdk-data-line={3017} +\item\mdline{3017}Low bound must be less than or equal to the high bound.%mdk + +%mdk-data-line={3018} +\item\mdline{3018}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3018} match must be omitted.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3020} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3021} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.range().low()))\\ +assert(BytestringValid(match.range().high()))\\ +\\ +low~=~parseInteger(match.range().low())\\ +high~=~parseInteger(match.range().high())\\ +\\ +assert(low~\textless{}=~high)\\ +\\ +assert(low~!=~min\_field\_value~\textbar{}\textbar{}~high~!=~max\_field\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3032} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3032} +\item\mdline{3032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3032} match + +%mdk-data-line={3033} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3033} +\item\mdline{3033}The binary string encoding of the value must conform to the +\mdline{3034}\mdref{sec-bytestrings}{Bytestrings}\mdline{3034} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3036} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3037} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.optional().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3040} +\subsubsection{\mdline{3040}9.1.2.\hspace*{0.5em}\mdline{3040}Action Specification}\label{sec-action-specification}%mdk%mdk + +%mdk-data-line={3042} +\noindent\mdline{3042}The \mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3042} \mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3042} field must be set for every \mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3042} update but may be +left unset for \mdline{3043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3043} updates, in which case the action specification for the +table entry will not be modified (if a \mdline{3044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3044} update has an unset action field +and does not modify any direct resource attached to the table then the \mdline{3045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3045} +update is a no-op). Based on the implementation property value of the P4 table, +the \mdline{3047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3047} in the \mdline{3047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3047} message will either be:%mdk + +%mdk-data-line={3049} +\begin{itemize}%mdk + +%mdk-data-line={3049} +\item{} +%mdk-data-line={3049} +\mdline{3049}an \mdline{3049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3049} specification for direct tables (with no P4 \mdline{3049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3049} +property)%mdk%mdk + +%mdk-data-line={3052} +\item{} +%mdk-data-line={3052} +\mdline{3052}an action profile member id for indirect tables for which the \mdline{3052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3052} +property is an action profile with no selector.%mdk%mdk + +%mdk-data-line={3055} +\item{} +%mdk-data-line={3055} +\mdline{3055}an action profile member id or group id for indirect tables for which the +\mdline{3056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3056} property is an action profile with selector.%mdk%mdk + +%mdk-data-line={3058} +\item{} +%mdk-data-line={3058} +\mdline{3058}an \mdline{3058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3058} specification for indirect tables for +which the \mdline{3059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3059} property is an action profile with +selector. This usage is described in\mdline{3060}~\mdref{sec-oneshot}{One Shot Action Selector +Programming}\mdline{3061}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3063} +\noindent\mdline{3063}If the \mdline{3063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3063} does not match the table description in the P4Info (\mdline{3063}e.g.\mdline{3063} the +\mdline{3064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3064} is \mdline{3064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member\_id}}}\mdline{3064} for a direct table), the server must +return an \mdline{3065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3065} error code.%mdk + +%mdk-data-line={3067} +\mdline{3067}The \mdline{3067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3067} Protobuf message has the following fields:%mdk + +%mdk-data-line={3069} +\begin{itemize}%mdk + +%mdk-data-line={3069} +\item{} +%mdk-data-line={3069} +\mdline{3069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3069}, which identifies the action instance; the \mdline{3069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3069} is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an \mdline{3071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3071} error +code. If the client uses a valid \mdline{3072}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3072} for the table but does not +respect the action scope specified in P4Info (\mdline{3073}e.g.\mdline{3073} tries to set a \mdline{3073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{3073} +action as the default action), the server must return a \mdline{3074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3074} +error code.%mdk%mdk + +%mdk-data-line={3077} +\item{} +%mdk-data-line={3077} +\mdline{3077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{3077}: a repeated Protobuf field of action parameter values, each encoded +as a \mdline{3078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{3078} message. For each parameter, \mdline{3078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}param\_id}}}\mdline{3078} must be valid for the +action (as per the P4Info) and value must follow the format described in +\mdline{3080}\mdref{sec-bytestrings}{Bytestrings}\mdline{3080}. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3082} error code +if a parameter id is missing, if an extra parameter\mdline{3083} \mdline{3083}\textemdash{}\mdline{3083} id not found in the +P4Info\mdline{3084} \mdline{3084}\textemdash{}\mdline{3084} was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +\mdline{3086}\mdref{sec-bytestrings}{Bytestrings}\mdline{3086} format.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3088} +\noindent\mdline{3088}For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a \mdline{3090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3090} error code.%mdk + +%mdk-data-line={3092} +\subsubsection{\mdline{3092}9.1.3.\hspace*{0.5em}\mdline{3092}Default Entry}\label{sec-default-entry}%mdk%mdk + +%mdk-data-line={3094} +\noindent\mdline{3094}According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer\mdline{3095} \mdline{3095}\textemdash{}\mdline{3095} or defaults to \mdline{3095}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3095} +(which is a no-op) otherwise\mdline{3096} \mdline{3096}\textemdash{}\mdline{3096} and assuming it is not declared as \mdline{3096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3096}, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow \mdline{3098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3098} and \mdline{3098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3098} updates on the default entry and the +P4Runtime server must return an \mdline{3099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3099} error code if the client +attempts one.%mdk + +%mdk-data-line={3102} +\mdline{3102}The default entry is identified by setting the \mdline{3102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3102} boolean field +to true. When this flag is set to true, the repeated \mdline{3103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3103} field must be empty +and the \mdline{3104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3104} field must be set to zero, otherwise the P4Runtime server +must return an \mdline{3105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3105} error code. When performing a \mdline{3105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3105} update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its \mdline{3109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3109} and \mdline{3109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3109} value as well as the +configurations for its\mdline{3110}~\mdref{sec-direct-resources}{direct resources}\mdline{3110} will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a \mdline{3112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3112} +error code if the client attempts to modify it.%mdk + +%mdk-data-line={3115} +\mdline{3115}Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to\mdline{3116}~\mdref{sec-direct-resources}{direct resources}\mdline{3116}.%mdk + +%mdk-data-line={3118} +\mdline{3118}In this P4Runtime release, we have decided to restrict the default entry for +indirect tables\mdline{3119} \mdline{3119}\textemdash{}\mdline{3119} tables with an ActionProfile or ActionSelector +\mdline{3120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3120} property\mdline{3120} \mdline{3120}\textemdash{}\mdline{3120} to a constant \mdline{3120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3120} action entry, with the +hope that it would simplify the implementation of the P4Runtime service.%mdk + +%mdk-data-line={3123} +\subsubsection{\mdline{3123}9.1.4.\hspace*{0.5em}\mdline{3123}Constant Tables}\label{sec-constant-tables}%mdk%mdk + +%mdk-data-line={3125} +\noindent\mdline{3125}Constant tables are defined as tables whose match entries are immutable. They +are identified by the \mdline{3126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3126} flag in P4Info.%mdk + +%mdk-data-line={3128} +\mdline{3128}The only write updates which are allowed for constant tables are \mdline{3128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3128} +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +\mdline{3132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3132} error. Just like any table entry \mdline{3132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3132} request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a \mdline{3136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3136} error.%mdk + +%mdk-data-line={3138} +\mdline{3138}The contents of const tables can be queried by the client through a +\mdline{3139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3139}. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: \mdline{3140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3140}, \mdline{3140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3140}, \mdline{3140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3140}, +\mdline{3141}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3141}, and \mdline{3141}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3141} (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the \mdline{3144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3144} field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P4\mdline{3146}\mdsub{16}\mdline{3146} does not support assigning explicit priorities to static +entries. When a priority value is required (\mdline{3147}e.g.\mdline{3147} for tables including \mdline{3147}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3147}, +\mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3148} or \mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3148} matches), it is inferred based on the order in which +entries appear in the table declaration.%mdk + +%mdk-data-line={3151} +\subsubsection{\mdline{3151}9.1.5.\hspace*{0.5em}\mdline{3151}Wildcard Reads}\label{sec-table-wildcard-reads}%mdk%mdk + +%mdk-data-line={3153} +\noindent\mdline{3153}When performing a \mdline{3153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3153}, the P4Runtime client can select all entries +from one or all tables on the target and use several of the \mdline{3154}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3154} fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as \mdline{3158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3158} and \mdline{3158}\textquotedblleft{}unset\textquotedblright{}\mdline{3158} for message fields such as \mdline{3158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3158}. The following +fields may be used to select and filter results:%mdk + +%mdk-data-line={3161} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3161} +\item\mdline{3161}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3161}: If default (0), entries from all tables\mdline{3161} \mdline{3161}\textemdash{}\mdline{3161} including constant +tables\mdline{3162} \mdline{3162}\textemdash{}\mdline{3162} will be selected and no other filter can be used. Otherwise only +the specified table will be considered.%mdk + +%mdk-data-line={3164} +\item\mdline{3164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3164}: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned.%mdk + +%mdk-data-line={3168} +\item\mdline{3168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3168}: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an \mdline{3169}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3169} (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id.%mdk + +%mdk-data-line={3175} +\item\mdline{3175}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3175}: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value.%mdk + +%mdk-data-line={3178} +\item\mdline{3178}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3178}: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +\mdline{3180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3180} value.%mdk + +%mdk-data-line={3181} +\item\mdline{3181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3181}: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided \mdline{3183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3183} value.%mdk + +%mdk-data-line={3184} +\item\mdline{3184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3184}: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered.%mdk + +%mdk-data-line={3187} +\item\mdline{3187}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{3187}: If default (unset), all table entries will be considered. Otherwise, +table entries will be filtered based on the provided role value.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3190} +\noindent\mdline{3190}For example, in order to read all entries from all tables from device 3, the +client can use the following \mdline{3191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3191} message.%mdk + +%mdk-data-line={3193} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3194} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0}\\ +~~~~priority:~{\mdcolor{purple}0}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3205} +\noindent\mdline{3205}In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following \mdline{3206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3206} +message:%mdk + +%mdk-data-line={3209} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3210} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~priority:~{\mdcolor{purple}11}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3221} +\noindent\mdline{3221}The canonical representation of \mdline{3221}\textquotedblleft{}don't care\textquotedblright{}\mdline{3221} matches, combined with the ability +to do a wildcard read on all table entries by leaving the \mdline{3222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3222} field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single \mdline{3224}\textquotedblleft{}don't care\textquotedblright{}\mdline{3224} entry or to do a wildcard +read. If a table has no fields with match kind \mdline{3225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3225}, it is possible via +P4Runtime to add an entry that is \mdline{3226}\textquotedblleft{}don't care\textquotedblright{}\mdline{3226} for all fields (\mdline{3226}i.e.\mdline{3226} has an empty +\mdline{3227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3227} field) but is not the default entry (\mdline{3227}i.e.\mdline{3227} \mdline{3227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3227} is +false). When reading this entry from the table, there is no way to read \mdline{3228}\emph{only}\mdline{3228} +that entry from the table, because it would require providing an unset \mdline{3229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3229} +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single \mdline{3232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{3232} match:%mdk + +%mdk-data-line={3234} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3235} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;~fwd;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3245} +\noindent\mdline{3245}The following \mdline{3245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3245} message can be used to add 2 entries:%mdk + +%mdk-data-line={3246} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3247} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{~{\mdcolor{darkgreen}\#~don't~care~entry}\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +~~table~entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~match~\{\\ +~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~lpm~\{\\ +~~~~~~~~value:~{\mdcolor{purple}0x0a000000}\\ +~~~~~~~~prefix\_len:~{\mdcolor{purple}8}\\ +~~~~~~\}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3266} +\noindent\mdline{3266}The first entry is a \mdline{3266}\textquotedblleft{}don't care\textquotedblright{}\mdline{3266} entry, while the second one matches all +\mdline{3267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}10.0.0.0/8}}}\mdline{3267} addresses. The second entry has higher priority than the first one.%mdk + +%mdk-data-line={3269} +\mdline{3269}The following \mdline{3269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3269} message will return \mdline{3269}\emph{all}\mdline{3269} entries in the table, not +just the \mdline{3270}\textquotedblleft{}don't care\textquotedblright{}\mdline{3270} entry.%mdk + +%mdk-data-line={3271} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3272} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3280} +\noindent\mdline{3280}This issue also exists for tables with \mdline{3280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3280}, \mdline{3280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3280}, and \mdline{3280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3280} +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the \mdline{3283}\textquotedblleft{}don't care\textquotedblright{}\mdline{3283} entry will be returned to the +client. If the client uses distinct priority values for all entries\mdline{3284} \mdline{3284}\textemdash{}\mdline{3284} which is +strongly recommended to achieve\mdline{3285}~\mdref{sec-table-entry}{deterministic behavior}\mdline{3285} \mdline{3285}\textemdash{}\mdline{3285}, +then there is no ambiguity because the wildcard read will actually return a +single entry (the \mdline{3287}\textquotedblleft{}don't care\textquotedblright{}\mdline{3287} entry) as long as the \mdline{3287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3287} field is set to +the correct value.%mdk + +%mdk-data-line={3290} +\subsubsection{\mdline{3290}9.1.6.\hspace*{0.5em}\mdline{3290}Direct Resources}\label{sec-direct-resources}%mdk%mdk + +%mdk-data-line={3292} +\noindent\mdline{3292}In addition to the \mdline{3292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3292} and \mdline{3292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3292} entities, +P4Runtime support reading and writing direct resources as part of the +\mdline{3294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3294} message. This is convenient for two reasons:%mdk + +%mdk-data-line={3296} +\begin{itemize}%mdk + +%mdk-data-line={3296} +\item{} +%mdk-data-line={3296} +\mdline{3296}A table entry and its direct resources can be read with a single entity when +doing a \mdline{3297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{3297} RPC call%mdk%mdk + +%mdk-data-line={3299} +\item{} +%mdk-data-line={3299} +\mdline{3299}The initial configuration for an entry\mdline{3299}'\mdline{3299}s direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can \mdline{3304}\textquotedblleft{}hit\textquotedblright{}\mdline{3304} the table entry without +executing the appropriate meter entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3307} +\noindent\mdline{3307}Once the table entry has been inserted, the P4Runtime client is free to use the +\mdline{3308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3308} and \mdline{3308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3308} messages for read and write +operations on \mdline{3309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3309} and \mdline{3309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3309} instances. For example, it is +usually more convenient as well as more efficient to use \mdline{3310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3310} to +query a counter entry value rather than use \mdline{3311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3311}, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry.%mdk + +%mdk-data-line={3315} +\mdline{3315}The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does \mdline{3316}\emph{not}\mdline{3316} need to be \mdline{3316}\textquotedblleft{}executed\textquotedblright{}\mdline{3316} in +every action bound to the table. It is an error to provide a direct resource +configuration in a \mdline{3318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3318} message when programming an action that does not +execute the direct resource, and the server must return an \mdline{3319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3319} +error code.%mdk + +%mdk-data-line={3322} +\mdline{3322}We leverage Protobuf\mdline{3322}'\mdline{3322}s ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the \mdline{3324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3324} message. The list below describes how +the server must handle the \mdline{3325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3325}, \mdline{3325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3325} and +\mdline{3326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3326} fields for read and write requests, based on whether the +fields are set or not. We do not cover error cases in the list, \mdline{3327}i.e.\mdline{3327} we assume +that we are dealing with a table which is assigned a direct counter / a direct +meter, and that the action being used for the table entry \mdline{3329}\textquotedblleft{}executes\textquotedblright{}\mdline{3329} the direct +resource appropriately.%mdk + +%mdk-data-line={3332} +\begin{itemize}%mdk + +%mdk-data-line={3332} +\item{} +%mdk-data-line={3332} +\mdline{3332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3332} field%mdk + +%mdk-data-line={3333} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3333} +\item\mdline{3333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3333} + +%mdk-data-line={3334} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3334} +\item\mdline{3334}if \mdline{3334}\textbf{unset}\mdline{3334}: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets).%mdk + +%mdk-data-line={3336} +\item\mdline{3336}if \mdline{3336}\textbf{set}\mdline{3336}: The initial configuration for the meter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3338} +\item\mdline{3338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3338} + +%mdk-data-line={3339} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3339} +\item\mdline{3339}if \mdline{3339}\textbf{unset}\mdline{3339}: The meter entry\mdline{3339}'\mdline{3339}s configuration is reset to the default +(meter returns GREEN for all packets).%mdk + +%mdk-data-line={3341} +\item\mdline{3341}if \mdline{3341}\textbf{set}\mdline{3341}: The value provided by the client is used to re-configure +the meter entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3343} +\item\mdline{3343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3343} + +%mdk-data-line={3344} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3344} +\item\mdline{3344}if \mdline{3344}\textbf{unset}\mdline{3344}: The response does not include the meter entry\mdline{3344}'\mdline{3344}s +configuration (\mdline{3345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3345} is unset in the response).%mdk + +%mdk-data-line={3346} +\item\mdline{3346}if \mdline{3346}\textbf{set}\mdline{3346}: If the meter entry\mdline{3346}'\mdline{3346}s configuration is the default +configuration, \mdline{3347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3347} is unset in the response. Otherwise, the +response includes the meter entry\mdline{3348}'\mdline{3348}s configuration that was written by +the client earlier. This respects the \mdline{3349}\textquotedblleft{}read-write symmetry\textquotedblright{}\mdline{3349} principle.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3351} +\item{} +%mdk-data-line={3351} +\mdline{3351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3351} field%mdk + +%mdk-data-line={3352} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3352} +\item\mdline{3352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3352} + +%mdk-data-line={3353} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3353} +\item\mdline{3353}if \mdline{3353}\textbf{unset}\mdline{3353}: The initial value for the counter entry is the default +(0).%mdk + +%mdk-data-line={3355} +\item\mdline{3355}if \mdline{3355}\textbf{set}\mdline{3355}: The initial value for the counter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3357} +\item\mdline{3357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3357} + +%mdk-data-line={3358} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3358} +\item\mdline{3358}if \mdline{3358}\textbf{unset}\mdline{3358}: The counter entry\mdline{3358}'\mdline{3358}s value is not changed.%mdk + +%mdk-data-line={3359} +\item\mdline{3359}if \mdline{3359}\textbf{set}\mdline{3359}: The value provided by the client is written to the counter +entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3361} +\item\mdline{3361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3361} + +%mdk-data-line={3362} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3362} +\item\mdline{3362}if \mdline{3362}\textbf{unset}\mdline{3362}: The response does not include the counter entry\mdline{3362}'\mdline{3362}s value +(\mdline{3363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3363} is unset in the response).%mdk + +%mdk-data-line={3364} +\item\mdline{3364}if \mdline{3364}\textbf{set}\mdline{3364}: The response includes the counter entry\mdline{3364}'\mdline{3364}s value read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3367} +\item{} +%mdk-data-line={3367} +\mdline{3367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3367} field%mdk + +%mdk-data-line={3368} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3368} +\item\mdline{3368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3368} + +%mdk-data-line={3369} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3369} +\item\mdline{3369}if \mdline{3369}\textbf{unset}\mdline{3369}: The initial value for all 3 counter entries is the +default (0).%mdk + +%mdk-data-line={3371} +\item\mdline{3371}if \mdline{3371}\textbf{set}\mdline{3371}: The initial value for all 3 counter entries is the +default (0). Sub-field, if any, can only have zero (0) as its value. +\mdline{3373}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3373} error is returned for any non-zero sub-field value.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3374} +\item\mdline{3374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3374} + +%mdk-data-line={3375} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3375} +\item\mdline{3375}if \mdline{3375}\textbf{unset}\mdline{3375}: All the 3 counter entries are unchanged.%mdk + +%mdk-data-line={3376} +\item\mdline{3376}if \mdline{3376}\textbf{set}\mdline{3376}: All the 3 counters are reset to 0. Sub-field, if any, can +only have zero (0) as its value. \mdline{3377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3377} error is returned +for any non-zero sub-field value.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3379} +\item\mdline{3379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3379} + +%mdk-data-line={3380} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3380} +\item\mdline{3380}if \mdline{3380}\textbf{unset}\mdline{3380}: The response does not include counter values +(\mdline{3381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3381} is unset in the response).%mdk + +%mdk-data-line={3382} +\item\mdline{3382}if \mdline{3382}\textbf{set}\mdline{3382}: The response includes all the 3 counter values read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3385} +\noindent\mdline{3385}In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +\mdline{3387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3387} field unset when inserting \mdline{3387}\textbf{or modifying}\mdline{3387} a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the \mdline{3389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3389} message +(\mdline{3390}i.e.\mdline{3390} the \mdline{3390}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3390} field must be set to match the existing configuration).%mdk + +%mdk-data-line={3392} +\subsubsection{\mdline{3392}9.1.7.\hspace*{0.5em}\mdline{3392}Idle-timeout}\label{sec-idle-timeout}%mdk%mdk + +%mdk-data-line={3394} +\noindent\mdline{3394}P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not \mdline{3396}\textquotedblleft{}hit\textquotedblright{}\mdline{3396} (\mdline{3396}i.e.\mdline{3396} not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification\mdline{3398} \mdline{3398}\textemdash{}\mdline{3398} using the +\mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3399} message\mdline{3399} \mdline{3399}\textemdash{}\mdline{3399} to the primary client, which can then take +action, such as remove the idle table entry.%mdk + +%mdk-data-line={3402} +\mdline{3402}Two fields of the \mdline{3402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3402} Protobuf message are used to implement idle +timeout:%mdk + +%mdk-data-line={3405} +\begin{itemize}%mdk + +%mdk-data-line={3405} +\item{} +%mdk-data-line={3405} +\mdline{3405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3405}: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, \mdline{3406}i.e.\mdline{3406} no +\mdline{3407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3407} message will ever be generated for this entry. When +a client reads a \mdline{3408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3408}, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry.%mdk%mdk + +%mdk-data-line={3412} +\item{} +%mdk-data-line={3412} +\mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3412}: a Protobuf message with a single field (\mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{3412}) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The \mdline{3414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3414} field must be unset for a +\mdline{3415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3415} write. When reading a table entry, \mdline{3415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3415} must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3420} +\noindent\mdline{3420}These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an \mdline{3422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3422} error code if at least one of these +conditions is met:%mdk + +%mdk-data-line={3425} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3425} +\item\mdline{3425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3425} is set to a non-zero value, or%mdk + +%mdk-data-line={3426} +\item\mdline{3426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3426} is set%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3428} +\noindent\mdline{3428}The target should do its best to approximate the \mdline{3428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3428} value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the \mdline{3431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3431} write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for \mdline{3433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3433}.%mdk + +%mdk-data-line={3435} +\mdline{3435}P4Runtime does not support idle timeout for default entries. When the +\mdline{3436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3436} flag is set in a \mdline{3436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3436} message, \mdline{3436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3436} +must be set to 0 (default) and \mdline{3437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3437} must be unset. If the +server receives a \mdline{3438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3438} message which violates this, it must return an +\mdline{3439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3439} error.%mdk + +%mdk-data-line={3441} +\mdline{3441}For more information about idle timeout, in particular regarding +\mdline{3442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3442}, please refer to the\mdline{3442}~\mdref{sec-table-idle-timeout-notification}{Table idle timeout +notifications}\mdline{3443} section.%mdk + +%mdk-data-line={3445} +\subsection{\mdline{3445}9.2.\hspace*{0.5em}\mdline{3445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3445} \mdline{3445}\&\mdline{3445} \mdline{3445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}\label{sec-action-profile-member-and-group}%mdk%mdk + +%mdk-data-line={3447} +\noindent\mdline{3447}P4Runtime defines an API for programming a PSA ActionProfile extern using +\mdline{3448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3448} messages. A PSA ActionSelector extern can be programmed +using both \mdline{3449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3449} and \mdline{3449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3449} messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table \mdline{3453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3453} for L3 routing, implemented with an action +selector \mdline{3454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3454}.%mdk + +%mdk-data-line={3456} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3457} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector(HashAlgorithm.crc32,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}size~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w1024,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}output\_width~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w10)~as;\\ +\\ +{\bfseries{\mdcolor{navy}action}}~set\_nhop(PortId\_t~p,~EthAddr~smac,~EthAddr~dmac)~\{\\ +~~istd.egress\_port~=~p;\\ +~~hdr.ethernet.smac~=~smac;\\ +~~hdr.ethernet.dmac~=~dmac;\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;~~{\mdcolor{darkgreen}//~LPM~on~destination~IP~address}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~set\_nhop;\\ +~~\}\\ +~~implementation~=~as;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3478} +\noindent\mdline{3478}When programming table \mdline{3478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3478} in the example above, a P4Runtime client should +specify the \mdline{3479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3479} in the \mdline{3479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3479} to be a reference to either an +action profile member or group. The reference is a non-zero \mdline{3480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3480} identifier +that uniquely identifies a member or group programmed in the action selector +\mdline{3482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3482}.%mdk + +%mdk-data-line={3484} +\mdline{3484}If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata.%mdk + +%mdk-data-line={3489} +\mdline{3489}If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata.%mdk + +%mdk-data-line={3500} +\subsubsection{\mdline{3500}9.2.1.\hspace*{0.5em}\mdline{3500}Action Profile Member Programming}\label{sec-action-profile-member-programming}%mdk%mdk + +%mdk-data-line={3502} +\noindent\mdline{3502}Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a \mdline{3503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3503} identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the \mdline{3505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3505} +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the \mdline{3507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3507} attributes of the +tables \mdline{3508}\emph{must have an identical list of P4 actions}\mdline{3508}. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector.%mdk + +%mdk-data-line={3512} +\mdline{3512}An \mdline{3512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3512} entity update message has the following fields:%mdk + +%mdk-data-line={3514} +\begin{itemize}%mdk + +%mdk-data-line={3514} +\item{} +%mdk-data-line={3514} +\mdline{3514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3514} is the \mdline{3514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3514} identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3517} +\item{} +%mdk-data-line={3517} +\mdline{3517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3517} is the non-zero \mdline{3517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3517} identifier of the action profile member +entry being updated.%mdk%mdk + +%mdk-data-line={3520} +\item{} +%mdk-data-line={3520} +\mdline{3520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3520} is the specification of the P4 action instance bound to the action +profile member entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3523} +\noindent\mdline{3523}An action profile member may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3526} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3526} +\item\mdline{3526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3526}: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an \mdline{3528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3528} error +code. The action specification must be provided, or the server must return +\mdline{3530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3530}. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return \mdline{3532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3532}.%mdk + +%mdk-data-line={3533} +\item\mdline{3533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3533}: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return \mdline{3534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3534}, +and the action specification must be provided, or the server must return +\mdline{3536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3536}.%mdk + +%mdk-data-line={3537} +\item\mdline{3537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3537}: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a \mdline{3538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3538} error code. The member +must not be part of an action profile group, or the server must return +\mdline{3540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3540}. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return \mdline{3543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3543}. \mdline{3543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3543} and \mdline{3543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3543} are the only +fields that are considered when performing a \mdline{3544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3544} and every other field +will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3547} +\noindent\mdline{3547}When reading, an \mdline{3547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3547} message with \mdline{3547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3547} and +\mdline{3548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3548} equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with \mdline{3549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3549} equal to the id of +an existing ActionProfile or ActionSelector object, and a \mdline{3550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3550} equal to +0, will read all members of that specified object.%mdk + +%mdk-data-line={3553} +\subsubsection{\mdline{3553}9.2.2.\hspace*{0.5em}\mdline{3553}Action Profile Group Programming}\label{sec-action-profile-group-programming}%mdk%mdk + +%mdk-data-line={3555} +\noindent\mdline{3555}Action profile groups are entries in an ActionSelector and are referenced by a +\mdline{3556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3556} identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type.%mdk + +%mdk-data-line={3560} +\mdline{3560}Within a single ActionSelector object, the \mdline{3560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3560} values used to identify its +members are in a separate \mdline{3561}\textquoteleft{}scope\textquoteright{}\mdline{3561} from the \mdline{3561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3561} values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5.%mdk + +%mdk-data-line={3565} +\mdline{3565}There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it.%mdk + +%mdk-data-line={3571} +\mdline{3571}An \mdline{3571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3571} entity update message has the following fields:%mdk + +%mdk-data-line={3573} +\begin{itemize}%mdk + +%mdk-data-line={3573} +\item{} +%mdk-data-line={3573} +\mdline{3573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3573} is the \mdline{3573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3573} identifier of the PSA ActionSelector +extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3576} +\item{} +%mdk-data-line={3576} +\mdline{3576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3576} is the non-zero \mdline{3576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3576} identifier of the action profile group +entry being updated.%mdk%mdk + +%mdk-data-line={3579} +\item{} +%mdk-data-line={3579} +\mdline{3579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3579} is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields:%mdk + +%mdk-data-line={3582} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3582} +\item\mdline{3582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3582} for looking up the member table in the selector.%mdk + +%mdk-data-line={3583} +\item\mdline{3583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3583} specifying the probability of the member\mdline{3583}'\mdline{3583}s selection at +runtime. 0 is not a valid \mdline{3584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3584} value and the server must return +\mdline{3585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3585} if the client attempts to use it.%mdk + +%mdk-data-line={3586} +\item\mdline{3586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3586} is the controller-defined port that the member\mdline{3586}'\mdline{3586}s +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +\mdline{3589}\mdref{action-selector-constraints}{9.2.4}\mdline{3589} for notes on the behavior if all members in +a group are excluded for this reason. If \mdline{3590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3590} is empty, then the +member is always included in the selection, regardless of the status of +any port of the device. The value must be empty or the SDN port of an +existing port on the device, otherwise the server must return +\mdline{3594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3594}.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3596} +\item{} +%mdk-data-line={3596} +\mdline{3596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3596} is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +\mdline{3598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3598} update. See the subsection below for the\mdline{3598}~\mdref{sec-max-size-rules}{rules on setting +\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\mdline{3599}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3601} +\noindent\mdline{3601}An action profile group may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3604} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3604} +\item\mdline{3604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3604}: Add a new group entry bound to a set of existing action profile +members. \mdline{3605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}The~group\_id}}}\mdline{3605} must be different from ids of already programmed +groups for that selector, or the server must return an \mdline{3606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3606} error +code. All members specified in the group must exist in the selector, or the +server must return \mdline{3608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3608}. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target.%mdk + +%mdk-data-line={3610} +\item\mdline{3610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3610}: Modify the member set specification of an existing group entry. An +entry with the \mdline{3611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3611} must exist, or the server must return +\mdline{3612}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3612}. All members specified in the group entry must exist in the +selector, or the server must return \mdline{3613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3613}. The value of \mdline{3613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3613} must +be identical to the value used when inserting the group, otherwise an +\mdline{3615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3615} error is returned.%mdk + +%mdk-data-line={3616} +\item\mdline{3616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3616}: Delete the group entry and deallocate the \mdline{3616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3616}. The group must +not be referenced in the table action of any table entry, or the server must +return a \mdline{3618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3618} error code. If the \mdline{3618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3618} is invalid, the +server must return \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3619}. \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3619} and \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3619} are the +only fields that are considered when performing a \mdline{3620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3620} and every other +field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3623} +\noindent\mdline{3623}When setting the group membership with \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3623} or \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3623}, the \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3623} +repeated field must not include duplicates, \mdline{3624}i.e.\mdline{3624} members with the same +\mdline{3625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3625}. The \mdline{3625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3625} field is used instead to logically \mdline{3625}\textquotedblleft{}repeat\textquotedblright{}\mdline{3625} the member +inside the group.%mdk + +%mdk-data-line={3628} +\mdline{3628}It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation \mdline{3629}\textquotedblleft{}stores\textquotedblright{}\mdline{3629} the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made.%mdk + +%mdk-data-line={3633} +\mdline{3633}When reading, an \mdline{3633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3633} message with \mdline{3633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3633} and +\mdline{3634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3634} equal to 0 will read all groups of all ActionSelector objects. A +message with \mdline{3635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3635} equal to the id of an existing ActionSelector +object, and a \mdline{3636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3636} equal to 0, will read all groups of that one specified +object.%mdk + +%mdk-data-line={3639} +\paragraph{\mdline{3639}9.2.2.1.\hspace*{0.5em}\mdline{3639}Rules on Setting \mdline{3639}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\label{sec-max-size-rules}%mdk%mdk + +%mdk-data-line={3641} +\noindent\mdline{3641}The valid values for \mdline{3641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3641} depend on the static \mdline{3641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3641} included +in the P4Info message:%mdk + +%mdk-data-line={3644} +\begin{itemize}%mdk + +%mdk-data-line={3644} +\item{} +%mdk-data-line={3644} +\mdline{3644}If \mdline{3644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3644} is greater than 0, then \mdline{3644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3644} must be greater than 0, +and less than or equal to \mdline{3645}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3645}. We assume that the target can +support selector groups for which the sum of all member weights is up to +\mdline{3647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3647}, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If \mdline{3648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3648} is greater than \mdline{3648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3648}, the server +must return \mdline{3649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3649}.%mdk%mdk + +%mdk-data-line={3651} +\item{} +%mdk-data-line={3651} +\mdline{3651}Otherwise (\mdline{3651}i.e.\mdline{3651} if \mdline{3651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3651} is 0), the P4Runtime client can set +\mdline{3652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3652} to any value greater than or equal to 0.%mdk + +%mdk-data-line={3654} +\begin{itemize}%mdk + +%mdk-data-line={3654} +\item{} +%mdk-data-line={3654} +\mdline{3654}A \mdline{3654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3654} of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (\mdline{3657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3657} or \mdline{3657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3657}), the target must return a +\mdline{3658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3658} error.%mdk%mdk + +%mdk-data-line={3660} +\item{} +%mdk-data-line={3660} +\mdline{3660}If \mdline{3660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3660} is greater than 0 and the value is not supported by the +target, the server must return a \mdline{3661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3661} error at +group-creation time.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3664} +\subsubsection{\mdline{3664}9.2.3.\hspace*{0.5em}\mdline{3664}One Shot Action Selector Programming}\label{sec-oneshot}%mdk%mdk + +%mdk-data-line={3666} +\noindent\mdline{3666}P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids.%mdk + +%mdk-data-line={3672} +\mdline{3672}One shots are programmed by choosing the \mdline{3672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3672} message as the +\mdline{3673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3673}. The \mdline{3673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3673} message consists of a set of +\mdline{3674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3674} messages, which in turn have the following fields:%mdk + +%mdk-data-line={3676} +\begin{itemize}%mdk + +%mdk-data-line={3676} +\item{} +%mdk-data-line={3676} +\mdline{3676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3676} is one of the actions specified by the table that is being +programmed.%mdk%mdk + +%mdk-data-line={3679} +\item{} +%mdk-data-line={3679} +\mdline{3679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3679} specifying the probability of the action\mdline{3679}'\mdline{3679}s selection at runtime. 0 is +not a valid \mdline{3680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3680} value and the server must return \mdline{3680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3680} if +the client attempts to use it. The sum of all weights across all +\mdline{3682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3682} messages for that \mdline{3682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3682} message must +not exceed the \mdline{3683}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3683} specificed in the P4Info (if greater than 0), +or the server must return \mdline{3684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3684}.%mdk%mdk + +%mdk-data-line={3686} +\item{} +%mdk-data-line={3686} +\mdline{3686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3686} is the controller-defined port that the action\mdline{3686}'\mdline{3686}s liveness depends +on. At runtime, the action must be excluded from selection if the watch port +is down. See Section\mdline{3688}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{3688} for more details +on the \mdline{3689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3689} field, which also apply for one shot action selector +programming.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3693} +\noindent\mdline{3693}Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics.%mdk + +%mdk-data-line={3698} +\mdline{3698}To preserve read-write symmetry, an implementation must answer \mdline{3698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3698}s +with the original one shot messages. It may not return a desugared version of +the one shot message.%mdk + +%mdk-data-line={3702} +\mdline{3702}For example, consider the action selector table defined +\mdline{3703}\mdref{sec-action-profile-member-and-group}{here}\mdline{3703}. This table could be programmed +with the following one shot update:%mdk + +%mdk-data-line={3706} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3707} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{\\ +~~~~action\_profile\_action\_set~\{\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}1}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x01}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}2}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x02}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}3}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x03}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3732} +\noindent\mdline{3732}Which would be equivalent to the following updates, where \mdline{3732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GROUP\_ID}}}\mdline{3732}, +\mdline{3733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_1}}}\mdline{3733}, \mdline{3733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_2}}}\mdline{3733}, and \mdline{3733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_3}}}\mdline{3733} are unused ids:%mdk + +%mdk-data-line={3735} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3736} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_1\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_2\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_3\\ +~~action~\{~~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +\}\\ +action\_profile\_group~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~group\_id:~GROUP\_ID\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_1\\ +~~~~weight:~{\mdcolor{purple}1}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x01}{\mdcolor{maroon}"}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_2\\ +~~~~weight:~{\mdcolor{purple}2}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x02}{\mdcolor{maroon}"}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_3\\ +~~~~weight:~{\mdcolor{purple}3}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x03}{\mdcolor{maroon}"}\\ +~~\}\\ +\}\\ +table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{~action\_profile\_group\_id:~GROUP\_ID~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3777} +\noindent\mdline{3777}Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure\mdline{3778}~\mdref{sec-batching-and-ordering-of-updates}{correct ordering between the dependent +updates}\mdline{3779}. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct \mdline{3781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3781} batches are required.%mdk + +%mdk-data-line={3783} +\mdline{3783}It is possible to include several \mdline{3783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3783} messages with the same +exact \mdline{3784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3784} specification in one \mdline{3784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3784} message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the \mdline{3786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3786} field. Note that to preserve read-write symmetry, the server +must not coalesce multiple \mdline{3787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3787} messages with the same \mdline{3787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3787} +specification into one.%mdk + +%mdk-data-line={3790} +\mdline{3790}All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with \mdline{3791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3791} and +\mdline{3792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3792} messages. Programming some entries with one shots, and +other entries with \mdline{3793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3793} and \mdline{3793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3793} messages is +not allowed, and the server must return the error code \mdline{3794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3794} in +that case.%mdk + +%mdk-data-line={3797} +\mdline{3797}A P4Runtime server \mdline{3797}\emph{must}\mdline{3797} support the one shot style of programming tables with +an action selector implementation. Support for the \mdline{3798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3798} and +\mdline{3799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3799} style is \mdline{3799}\emph{optional}\mdline{3799}. If \mdline{3799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3799} and +\mdline{3800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3800} are not supported by a server, it must return an +\mdline{3801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3801} error for every \mdline{3801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3801} or \mdline{3801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3801} +message that it receives.%mdk + +%mdk-data-line={3804} +\subsubsection{\mdline{3804}9.2.4.\hspace*{0.5em}\mdline{3804}Constraints on action selector programming}\label{action-selector-constraints}%mdk%mdk + +%mdk-data-line={3806} +\noindent\mdline{3806}The PSA specification states that the following features are \mdline{3806}\emph{optional}\mdline{3806} in +action selector implementations\mdline{3807}~[\mdcite{psaactionselector}{22}]\mdline{3807}:%mdk + +%mdk-data-line={3809} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3809} +\item\mdline{3809}Support for non-empty groups where in the same group, different members are +bound to different actions.%mdk + +%mdk-data-line={3811} +\item\mdline{3811}Predictable data plane behavior when a matched table entry points to an empty +group.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={3814} +\noindent\mdline{3814}For 1., if a client tries to \mdline{3814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3814} or \mdline{3814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3814} a group with members bound to +different actions, the server should return \mdline{3815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3815} if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return \mdline{3821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3821} (modifying the action parameter values must be +supported, however).%mdk + +%mdk-data-line={3824} +\mdline{3824}PSA 1.1 introduces the \mdline{3824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3824} table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. \mdline{3828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3828} is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of \mdline{3831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3831} at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +\mdline{3833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3833}. Even when \mdline{3833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3833} is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of \mdline{3837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3837} mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming.%mdk + +%mdk-data-line={3842} +\mdline{3842}The PSA specification includes a discussion on how to implement +\mdline{3843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3843} in software in the P4Runtime server +\mdline{3844}[\mdcite{psaemptygroupactionappendix}{25}]\mdline{3844}.%mdk + +%mdk-data-line={3846} +\mdline{3846}If a P4Runtime implementation does support \mdline{3846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3846}, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down.%mdk + +%mdk-data-line={3850} +\mdline{3850}If a P4Runtime implementation does not support \mdline{3850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3850}, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down.%mdk + +%mdk-data-line={3856} +\subsection{\mdline{3856}9.3.\hspace*{0.5em}\mdline{3856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3856} \mdline{3856}\&\mdline{3856} \mdline{3856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-counterentry-directcounterentry}%mdk%mdk + +%mdk-data-line={3858} +\noindent\mdline{3858}PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The \mdline{3860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3860} +P4Runtime message can be used for all three types of PSA counters\mdline{3861} \mdline{3861}\textemdash{}\mdline{3861} \mdline{3861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{3861}, +\mdline{3862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{3862} and \mdline{3862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3862} \mdline{3862}\textemdash{}\mdline{3862} and consists of the following fields:%mdk + +%mdk-data-line={3864} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3864} +\item\mdline{3864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3864} is an \mdline{3864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3864}, corresponding to the number of octets.%mdk + +%mdk-data-line={3865} +\item\mdline{3865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3865} is an \mdline{3865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3865}, corresponding to the number of packets.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3867} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3868} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterData~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~byte\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}int64}}~packet\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3874} +\noindent\mdline{3874}P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of \mdline{3875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3875} and \mdline{3875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3875} fields, which +is equivalent to specifying the counter type \mdline{3876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3876}. Counters may +be defined as direct or indirect (indexed) instances.%mdk + +%mdk-data-line={3879} +\subsubsection{\mdline{3879}9.3.1.\hspace*{0.5em}\mdline{3879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-directcounterentry}%mdk%mdk + +%mdk-data-line={3881} +\noindent\mdline{3881}A direct counter is a direct resource associated with a \mdline{3881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3881} (see +\mdline{3882}\mdref{sec-direct-resources}{Direct Resources}\mdline{3882}). The \mdline{3882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3882} field of the +\mdline{3883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3883} message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +\mdline{3886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3886} message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed.%mdk + +%mdk-data-line={3889} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3890} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectCounterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3896} +\noindent\mdline{3896}A \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3896} may only include an \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3896} message of type \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3896} with a +\mdline{3897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3897}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3899} +\begin{itemize}%mdk + +%mdk-data-line={3899} +\item{} +%mdk-data-line={3899} +\mdline{3899}the \mdline{3899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3899} field must match \mdline{3899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry.match}}}\mdline{3899} of the table entry +to which this direct counter entry is associated. If a matching \mdline{3900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3900} +is not found, the server returns the error code \mdline{3901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3901}.%mdk%mdk + +%mdk-data-line={3903} +\item{} +%mdk-data-line={3903} +\mdline{3903}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3903} is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3907} +\noindent\mdline{3907}Specifying \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3907} in an \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3907} message of type \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3907} or +\mdline{3908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3908} is not allowed, and the server must return the error code +\mdline{3909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3909} in that case.%mdk + +%mdk-data-line={3911} +\mdline{3911}A client may use \mdline{3911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3911} in two ways to read the contents of a +\mdline{3912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3912}:%mdk + +%mdk-data-line={3914} +\begin{itemize}%mdk + +%mdk-data-line={3914} +\item{} +%mdk-data-line={3914} +\mdline{3914}As a direct resource associated with a table entry, request the server to +return the counter value in the \mdline{3915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3915} field of the \mdline{3915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3915} message +(see\mdline{3916}~\mdref{sec-direct-resources}{Direct resources}\mdline{3916}).%mdk%mdk + +%mdk-data-line={3918} +\item{} +%mdk-data-line={3918} +\mdline{3918}Explicitly request the counter value by including the \mdline{3918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3918} in +the \mdline{3919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3919}. The \mdline{3919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3919} field must match the \mdline{3919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3919} +whose counter is being read. If no such entry is found, the server returns the +error code \mdline{3921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3921}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3923} +\subsubsection{\mdline{3923}9.3.2.\hspace*{0.5em}\mdline{3923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}\label{sec-counterentry}%mdk%mdk + +%mdk-data-line={3925} +\noindent\mdline{3925}An indirect or indexed counter is not associated with a specific \mdline{3925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3925} +and may be updated independently of any action. It may be read or written using +the P4Runtime \mdline{3927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3927} message whose fields are defined as follows:%mdk + +%mdk-data-line={3929} +\begin{itemize}%mdk + +%mdk-data-line={3929} +\item{} +%mdk-data-line={3929} +\mdline{3929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3929} is a \mdline{3929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3929}, the unique identifier for the counter.%mdk%mdk + +%mdk-data-line={3931} +\item{} +%mdk-data-line={3931} +\mdline{3931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3931} is a Protobuf message that encapsulates an \mdline{3931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3931}, used to index into +the counter array.%mdk%mdk + +%mdk-data-line={3934} +\item{} +%mdk-data-line={3934} +\mdline{3934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3934} is a Protobuf message of type \mdline{3934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3934}, which represents the +counter value.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3937} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3938} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~counter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3945} +\noindent\mdline{3945}The \mdline{3945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3945} can only be used in a \mdline{3945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3945} with the \mdline{3945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3945} update +type. The P4Runtime server must return an \mdline{3946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3946} error code for +update types \mdline{3947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3947} and \mdline{3947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3947}. By default all the counter entries in the +array have default value 0.%mdk + +%mdk-data-line={3950} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3950} +\item\mdline{3950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3950}: Server returns the error code \mdline{3950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3950}.%mdk + +%mdk-data-line={3951} +\item\mdline{3951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3951}: Modify an indirect counter instance whose unique id is \mdline{3951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3951} +and array index is specified by \mdline{3952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3952}. The counter value is set to the value +specified by the client in the \mdline{3953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3953} field. Note that the counter value is +not modified if this Protobuf field is not set. If \mdline{3954}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3954} is omitted all +counter values in the array will be set to the value provided by the +client. The server must return \mdline{3956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3956} for a negative index value +and \mdline{3957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3957} if the index value exceeds the size of the counter array.%mdk + +%mdk-data-line={3958} +\item\mdline{3958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3958}: Server returns the error code \mdline{3958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3958}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3960} +\noindent\mdline{3960}A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a \mdline{3961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3961} by including a \mdline{3961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3961} +entity for each of the instances, specifying the \mdline{3962}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3962} and +\mdline{3963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3963}. Wildcard reads are also supported as follows.%mdk + +%mdk-data-line={3965} +\begin{itemize}%mdk + +%mdk-data-line={3965} +\item{} +%mdk-data-line={3965} +\mdline{3965}If the \mdline{3965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3965} field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the \mdline{3966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3966}.%mdk%mdk + +%mdk-data-line={3968} +\item{} +%mdk-data-line={3968} +\mdline{3968}If the \mdline{3968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3968} field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id \mdline{3969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3969}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3971} +\subsection{\mdline{3971}9.4.\hspace*{0.5em}\mdline{3971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3971} \mdline{3971}\&\mdline{3971} \mdline{3971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-meterentry-directmeterentry}%mdk%mdk + +%mdk-data-line={3973} +\noindent\mdline{3973}Meters are an advanced mechanism for keeping statistics, involving stateful +\mdline{3974}\textquotedblleft{}marking\textquotedblright{}\mdline{3974} and usually \mdline{3974}\textquotedblleft{}throttling\textquotedblright{}\mdline{3974} of packets based on configured rates of +traffic. The PSA metering function is based on the \mdline{3975}\emph{Two Rate Three Color Marker}\mdline{3975} +(trTCM) defined in RFC 2698\mdline{3976}~[\mdcite{rfc2698}{2}]\mdline{3976}. The trTCM meters an arbitrary packet +stream using two configured rates\mdline{3977} \mdline{3977}\textemdash{}\mdline{3977} the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes\mdline{3978} \mdline{3978}\textemdash{}\mdline{3978} and +\mdline{3979}\textquotedblleft{}marks\textquotedblright{}\mdline{3979} its packets as GREEN, YELLOW or RED based on the observed rate.%mdk + +%mdk-data-line={3981} +\mdline{3981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3981} \mdline{3981}\&\mdline{3981} \mdline{3981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3981} have an additional field \mdline{3981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3981} that +may hold per color counter data for targets that support it, and that must +always be unset for targets that do not support it. If set in a request and +unsupported by a target, an \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3984} error code should be returned. +These counters provide a granular list of the counters applicable to the +possible meter colors GREEN, YELLOW and RED. The counter associated with a +specific color is incremented when a packet is \mdline{3987}\textquotedblleft{}marked\textquotedblright{}\mdline{3987} with that color. The +primary purpose of the color counters is for debugging purposes.%mdk + +%mdk-data-line={3990} +\mdline{3990}A meter may be configured as a direct or indirect instance, similar to a +counter. The \mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{3991} P4Runtime message represents meter configuration.%mdk + +%mdk-data-line={3993} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3994} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterConfig~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~cir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~Committed~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~cburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};~~{\mdcolor{darkgreen}//~Committed~Burst~Size}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};~~{\mdcolor{darkgreen}//~Peak~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};~~{\mdcolor{darkgreen}//~Peak~Burst~Size}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4002} +\subsubsection{\mdline{4002}9.4.1.\hspace*{0.5em}\mdline{4002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-directmeterentry}%mdk%mdk + +%mdk-data-line={4004} +\noindent\mdline{4004}A direct meter is a direct resource associated with a \mdline{4004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4004} (see\mdline{4004}~\mdref{sec-direct-resources}{Direct +resources}\mdline{4005}). The \mdline{4005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{4005} field of the \mdline{4005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4005} +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +\mdline{4009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4009} message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed.%mdk + +%mdk-data-line={4012} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4013} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectMeterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterCounterData~counter\_data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4020} +\noindent\mdline{4020}A \mdline{4020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4020} may only include an \mdline{4020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4020} message of type \mdline{4020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4020} with a +\mdline{4021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4021}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={4023} +\begin{itemize}%mdk + +%mdk-data-line={4023} +\item{} +%mdk-data-line={4023} +\mdline{4023}the \mdline{4023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4023} field must match the match key of the \mdline{4023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4023} +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching \mdline{4025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4025} is not found, +the server returns the error code \mdline{4026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4026}.%mdk%mdk + +%mdk-data-line={4028} +\item{} +%mdk-data-line={4028} +\mdline{4028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4028} is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets).%mdk%mdk + +%mdk-data-line={4032} +\item{} +%mdk-data-line={4032} +\mdline{4032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4032} is used to set the per color counter values to the default +value of (0), which is essentially clearing the counters. If the field is +unset, the counter values are left untouched. If the field is set, targets +supporting these counters should reset all the color counters to (0), if any +of the sub-fields are set to a non-zero value, then an \mdline{4036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4036} +error should be returned.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4039} +\noindent\mdline{4039}Specifying \mdline{4039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4039} in an \mdline{4039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4039} message of type \mdline{4039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4039} or +\mdline{4040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4040} is not allowed, and the server must return the error code +\mdline{4041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4041} in that case.%mdk + +%mdk-data-line={4043} +\mdline{4043}A client may use \mdline{4043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4043} in two ways to read a \mdline{4043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{4043} config.%mdk + +%mdk-data-line={4045} +\begin{itemize}%mdk + +%mdk-data-line={4045} +\item{} +%mdk-data-line={4045} +\mdline{4045}As a direct resource associated with a table entry, request the server to +return the meter config in the \mdline{4046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{4046} field of the \mdline{4046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4046} +message (see\mdline{4047}~\mdref{sec-direct-resources}{Direct resources}\mdline{4047}).%mdk%mdk + +%mdk-data-line={4049} +\item{} +%mdk-data-line={4049} +\mdline{4049}Explicitly request the meter configuration by including the \mdline{4049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4049} +in the \mdline{4050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4050}. The \mdline{4050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4050} field must match the +\mdline{4051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4051} whose meter config is being read. If no such entry is found, the +server returns the error code \mdline{4052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4052}. Read responses also include the +per color counter data for the meter entry, if supported and specified in +the request message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4056} +\subsubsection{\mdline{4056}9.4.2.\hspace*{0.5em}\mdline{4056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}\label{sec-meterentry}%mdk%mdk + +%mdk-data-line={4058} +\noindent\mdline{4058}An indirect or indexed meter is not associated with a specific \mdline{4058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4058} and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime \mdline{4060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4060} message whose fields are defined as +follows:%mdk + +%mdk-data-line={4063} +\begin{itemize}%mdk + +%mdk-data-line={4063} +\item{} +%mdk-data-line={4063} +\mdline{4063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4063} is a \mdline{4063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4063}, the unique identifier for the meter.%mdk%mdk + +%mdk-data-line={4065} +\item{} +%mdk-data-line={4065} +\mdline{4065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4065} is a Protobuf message that encapsulates an \mdline{4065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4065}, used to index into +a meter array.%mdk%mdk + +%mdk-data-line={4068} +\item{} +%mdk-data-line={4068} +\mdline{4068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4068} is a Protobuf message of type \mdline{4068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{4068}, which represents the +meter configuration.%mdk%mdk + +%mdk-data-line={4071} +\item{} +%mdk-data-line={4071} +\mdline{4071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4071} is a Protobuf message of type \mdline{4071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4071}, which +represents the per color counter values associated with the corresponding +meter.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4075} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4076} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~meter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~MeterCounterData~counter\_data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4084} +\noindent\mdline{4084}The \mdline{4084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4084} can only be used in a \mdline{4084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4084} with the \mdline{4084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4084} update +type. The P4Runtime server must return an \mdline{4085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4085} error code for +update types \mdline{4086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4086} and \mdline{4086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4086}. By default all the meter entries in the +array have a default configuration (GREEN for all packets).%mdk + +%mdk-data-line={4089} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4089} +\item\mdline{4089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4089}: Server returns the error code \mdline{4089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4089}.%mdk + +%mdk-data-line={4090} +\item\mdline{4090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4090}: Modify an indirect meter instance whose unique id is \mdline{4090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4090} and +array index is specified by \mdline{4091}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4091}. The meter is reconfigured using the +\mdline{4092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4092} field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the \mdline{4094}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4094} field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if \mdline{4096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4096} is unset). The server must return \mdline{4096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4096} for a +negative index value and \mdline{4097}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4097} if the index value exceeds the size of +the meter array.%mdk + +%mdk-data-line={4099} +\item\mdline{4099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4099}: Server returns the error code \mdline{4099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4099}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4101} +\noindent\mdline{4101}A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a \mdline{4102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4102} by including a \mdline{4102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4102} entity for each +of the instances, specifying the \mdline{4103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4103} and \mdline{4103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4103}. Wildcard reads are also +supported as follows:%mdk + +%mdk-data-line={4106} +\begin{itemize}%mdk + +%mdk-data-line={4106} +\item{} +%mdk-data-line={4106} +\mdline{4106}If the \mdline{4106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4106} field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the \mdline{4107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4107}.%mdk%mdk + +%mdk-data-line={4109} +\item{} +%mdk-data-line={4109} +\mdline{4109}If the \mdline{4109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4109} field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id \mdline{4110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4110}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4112} +\subsubsection{\mdline{4112}9.4.3.\hspace*{0.5em}\mdline{4112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}}\label{sec-metercounterdata}%mdk%mdk + +%mdk-data-line={4114} +\noindent\mdline{4114}The \mdline{4114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4114} P4Runtime message represents the per color counters +associated with a meter entry. Whenever a meter is executed and returns +a color, the corresponding color counter GREEN, YELLOW or RED is updated.%mdk + +%mdk-data-line={4118} +\mdline{4118}As seen above, these counters can be associated with a \mdline{4118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4118} or +\mdline{4119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4119}. Targets not capable of supporting these counters should return +\mdline{4120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4120} if a \mdline{4120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4120} field was set in a read or write +request.%mdk + +%mdk-data-line={4123} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4124} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterCounterData~\{\\ +~~CounterData~green~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~yellow~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~red~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4132} +\subsection{\mdline{4132}9.5.\hspace*{0.5em}\mdline{4132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}\label{sec-packetreplicationengineentry}%mdk%mdk + +%mdk-data-line={4134} +\noindent\mdline{4134}The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets.%mdk + +%mdk-data-line={4140} +\subsubsection{\mdline{4140}9.5.1.\hspace*{0.5em}\mdline{4140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}\label{sec-multicastgroupentry}%mdk%mdk + +%mdk-data-line={4142} +\noindent\mdline{4142}Multicasting is achieved in PSA programs by setting the \mdline{4142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4142} +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the \mdline{4145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4145} API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example.%mdk + +%mdk-data-line={4150} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4151} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~arp\_multicast({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ethernet.isValid()~\&\&\\ +~~~~~~~~hdr.ethernet.eth\_type~==~ETH\_TYPE\_ARP)~\{\\ +~~~~~~smeta.multicast\_group~=~(MulticastGroup\_t)~{\mdcolor{purple}1};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4161} +\noindent\mdline{4161}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4164} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4165} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~multicast\_group\_entry~\{\\ +~~~~~~multicast\_group\_id:~{\mdcolor{purple}1}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}5}~instance:~{\mdcolor{purple}1}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}12}~instance:~{\mdcolor{purple}2}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}18}~instance:~{\mdcolor{purple}3}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}24}~instance:~{\mdcolor{purple}4}~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4179} +\noindent\mdline{4179}As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +\mdline{4184}\mdref{sec-translation-of-port-numbers}{PSA Metadata Translation}\mdline{4184} section.%mdk + +%mdk-data-line={4186} +\mdline{4186}The egress packets may be distinguished for further processing in the egress +using the \mdline{4187}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4187} metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 \mdline{4189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4189} metadata is set to a value that is not +programmed in the PRE, then the packet is dropped.%mdk + +%mdk-data-line={4192} +\mdline{4192}A multicast group may be inserted, modified or deleted as per the following +semantics.%mdk + +%mdk-data-line={4195} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4195} +\item\mdline{4195}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4195}: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The \mdline{4196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4196} field is a \mdline{4196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4196} and must be greater +than 0 (see explanation\mdline{4197}~\mdref{sec-valid-values-for-mg-id}{below}\mdline{4197}), or the +P4Runtime server must return an \mdline{4198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4198} error. The replica +\mdline{4199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4199} ID is also a \mdline{4199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4199}, and its value may not exceed the maximum +allowed by the target for the \mdline{4200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4200} type (0 is allowed), or the +server must return an \mdline{4201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4201} error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of \mdline{4203}\emph{both}\mdline{4203} \mdline{4203}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{4203} and \mdline{4203}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4203}, or the server +must return \mdline{4204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4204}.%mdk + +%mdk-data-line={4205} +\item\mdline{4205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4205}: Modify the set of replicas for a given multicast group entry, +indexed by the given \mdline{4206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4206}. Same restrictions as \mdline{4206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4206} apply +here.%mdk + +%mdk-data-line={4208} +\item\mdline{4208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4208}: Delete the multicast group indexed by the given +\mdline{4209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4209}. The replicas need not be provided for this +operation. Any packets with their \mdline{4210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4210} metadata in the data plane +set to the deleted \mdline{4211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4211} will be dropped.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4213} +\noindent\mdline{4213}When reading a multicast group, only \mdline{4213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4213} is considered. All +other fields in \mdline{4214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4214} are ignored. To perform a \mdline{4214}\emph{wildcard}\mdline{4214} +\mdline{4215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4215} on all configured multicast group entries, the \mdline{4215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4215} field +must be set to 0, its default value.%mdk + +%mdk-data-line={4218} +\paragraph{\mdline{4218}9.5.1.1.\hspace*{0.5em}\mdline{4218}Valid Values for \mdline{4218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}}\label{sec-valid-values-for-mg-id}%mdk%mdk + +%mdk-data-line={4220} +\noindent\mdline{4220}The PSA specification states that the valid \mdline{4220}\emph{data plane}\mdline{4220} values for multicast +group ids (\mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroup\_t}}}\mdline{4221}) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target\mdline{4223}~[\mdcite{psatranslation}{24}]\mdline{4223}. This means that, in the absence of +translation, the client must set the \mdline{4224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4224} field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special \mdline{4226}\emph{wildcard}\mdline{4226} value which is used to read all the multicast groups +configured in the target, the \mdline{4227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4227} field must never be set to 0 +when performing a \mdline{4228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4228} RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value.%mdk + +%mdk-data-line={4233} +\subsubsection{\mdline{4233}9.5.2.\hspace*{0.5em}\mdline{4233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}\label{sec-clonesessionentry}%mdk%mdk + +%mdk-data-line={4235} +\noindent\mdline{4235}PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +\mdline{4239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4239} identifier and a boolean flag \mdline{4239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone}}}\mdline{4239} in the packet +metadata. The \mdline{4240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4240} serves as a handle to the clone attributes, +namely a set \mdline{4241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}replicas}}}\mdline{4241} of \mdline{4241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(egress~port,~instance)}}}\mdline{4241} pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +\mdline{4244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4244} API.%mdk + +%mdk-data-line={4246} +\mdline{4246}The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the \mdline{4249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_low\_ttl}}}\mdline{4249} control block is applied in the ingress +pipeline to create an ingress-to-egress clone.%mdk + +%mdk-data-line={4252} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4253} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~clone\_low\_ttl({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ipv4.isValid()~\&\&\\ +~~~~~~~~hdr.ipv4.ttl~\textless{}=~LOW\_TTL\_THRESHOLD)~\{\\ +~~~~~~smeta.clone\_session\_id~=~{\mdcolor{purple}10}w100;\\ +~~~~~~smeta.clone~=~{\bfseries{\mdcolor{navy}true}};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4265} +\noindent\mdline{4265}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4268} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4269} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~clone\_session\_entry~\{\\ +~~~~~~session\_id:~{\mdcolor{purple}100}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}0xfffffffd}~instance:~{\mdcolor{purple}1}~\}~{\mdcolor{darkgreen}\#~to~CPU}\\ +~~~~~~class\_of\_service:~{\mdcolor{purple}2}\\ +~~~~~~packet\_length\_bytes:~{\mdcolor{purple}4096}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4282} +\noindent\mdline{4282}As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type \mdline{4286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4286}~[\mdcite{psatranslation}{24}]\mdline{4286}). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes.%mdk + +%mdk-data-line={4291} +\mdline{4291}The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port \mdline{4292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfffffffd}}}\mdline{4292}; see +\mdline{4293}\mdref{sec-translation-of-port-numbers}{Translation of Port Numbers}\mdline{4293}). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port.%mdk + +%mdk-data-line={4296} +\mdline{4296}If the \mdline{4296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4296} data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created.%mdk + +%mdk-data-line={4299} +\mdline{4299}A clone session may be inserted, modified or deleted as per the following +semantics:%mdk + +%mdk-data-line={4302} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4302} +\item\mdline{4302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4302}: Add a new clone session entry bound to a set of egress ports and +replica IDs. The \mdline{4303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4303} is a \mdline{4303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4303} and must be greater than 0 (see +explanation\mdline{4304}~\mdref{sec-valid-values-for-session-id}{below}\mdline{4304}), or the P4Runtime +server must return an \mdline{4305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4305} error. The replica \mdline{4305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4305} ID is +also a \mdline{4306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4306}, and its value may not exceed the maximum allowed by the +target for the \mdline{4307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4307} type (0 is allowed), or the server must also +return an \mdline{4308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4308} error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (\mdline{4311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}class\_of\_service}}}\mdline{4311} field). This value must be a valid +value for the PSA \mdline{4312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ClassOfService\_t}}}\mdline{4312} type, which supports runtime translation +by default\mdline{4313}~[\mdcite{psatranslation}{24}]\mdline{4313}, or the server must return +\mdline{4314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4314}. See\mdline{4314}~\mdref{sec-translation-of-port-numbers}{PSA Metadata +Translation}\mdline{4315} for more information. The +\mdline{4316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4316} field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +\mdline{4318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4318} field is 0 (default), no truncation on the clone will be +performed.%mdk + +%mdk-data-line={4320} +\item\mdline{4320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4320}: Modify the attributes of a given clone session entry, indexed by the +given \mdline{4321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4321}. Same restrictions as \mdline{4321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4321} apply here.%mdk + +%mdk-data-line={4322} +\item\mdline{4322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4322}: Delete the clone session indexed by the given +\mdline{4323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4323}. Other fields need not be provided for this operation. Any +packet with their \mdline{4324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4324} metadata in the data plane set to the +deleted \mdline{4325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4325} will no longer be cloned.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4327} +\noindent\mdline{4327}When reading a clone session, only \mdline{4327}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4327} is considered. All other fields +in \mdline{4328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4328} are ignored. To perform a \mdline{4328}\emph{wildcard}\mdline{4328} \mdline{4328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4328} on all +configured clone session entries, the \mdline{4329}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4329} field must be set to 0, its +default value. The \mdline{4330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4330} field can never be equal to 0 in a \mdline{4330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4330} +RPC. If it does, the server must return an \mdline{4331}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4331} error.%mdk + +%mdk-data-line={4333} +\paragraph{\mdline{4333}9.5.2.1.\hspace*{0.5em}\mdline{4333}Valid Values for \mdline{4333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}}\label{sec-valid-values-for-session-id}%mdk%mdk + +%mdk-data-line={4335} +\noindent\mdline{4335}The PSA specification states that the valid \mdline{4335}\emph{data plane}\mdline{4335} values for clone +session ids (\mdline{4336}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4336}) range from 0 to the maximum value supported by +the target\mdline{4337}~[\mdcite{psatranslation}{24}]\mdline{4337}. Note that unlike for\mdline{4337}~\mdref{sec-valid-values-for-mg-id}{multicast group +ids}\mdline{4338}, 0 is a valid \mdline{4338}\emph{data plane}\mdline{4338} value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special \mdline{4340}\emph{wildcard}\mdline{4340} value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a \mdline{4341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4341} +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is \mdline{4343}\emph{not}\mdline{4343} enabled, we effectively +\mdline{4344}\textquotedblleft{}lose\textquotedblright{}\mdline{4344} one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (\mdline{4345}e.g.\mdline{4345} because the target supports a very +limited number of clone sessions), one can enable translation on +\mdline{4347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4347} and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id.%mdk + +%mdk-data-line={4350} +\subsection{\mdline{4350}9.6.\hspace*{0.5em}\mdline{4350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}\label{sec-valuesetentry}%mdk%mdk + +%mdk-data-line={4352} +\noindent\mdline{4352}Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the \mdline{4356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4356} state.%mdk + +%mdk-data-line={4358} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4359} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}state}}~parse\_l2~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}(MAX\_TRILL\_TYPES)~trill\_types;}\\ +~~extract(hdr.ethernet);\\ +~~{\bfseries{\mdcolor{navy}select}}~(hdr.ethernet.eth\_type)~\{\\ +~~~~ETH\_TYPE\_IPV4:~parse\_ipv4;\\ +~~~~ETH\_TYPE\_IPV6:~parse\_ipv6;\\ +~~~~trill\_types:~~~parse\_trill\_types;\\ +~~~~\_:~~~~~~~~~~~~~reject;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4371} +\noindent\mdline{4371}The corresponding entry in the P4Info for this Value Set is:%mdk + +%mdk-data-line={4373} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4374} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}trill\_types}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~\textless{}MAX\_TRILL\_TYPES\textgreater{}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4388} +\noindent\mdline{4388}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4391} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4392} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x22f3}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x893b}~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4410} +\noindent\mdline{4410}As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the \mdline{4412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4412} state.%mdk + +%mdk-data-line={4414} +\mdline{4414}A \mdline{4414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4414} entity update message has the following fields:%mdk + +%mdk-data-line={4416} +\begin{itemize}%mdk + +%mdk-data-line={4416} +\item{} +%mdk-data-line={4416} +\mdline{4416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4416} is the \mdline{4416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4416} identifier of the Value Set instance, as +defined in P4Info.%mdk%mdk + +%mdk-data-line={4419} +\item{} +%mdk-data-line={4419} +\mdline{4419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4419} is a repeated field of type \mdline{4419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4419}. When \mdline{4419}\textquotedblleft{}selecting\textquotedblright{}\mdline{4419} +against a Value Set, every member will be considered and if at least one +\mdline{4421}\textquotedblleft{}matches\textquotedblright{}\mdline{4421}, the corresponding parser transition will be taken. Each +\mdline{4422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4422} contains a repeated field of \mdline{4422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4422} messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a \mdline{4424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4424} if and only if +it matches all its \mdline{4425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4425} messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. \mdline{4427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4427} messages in a \mdline{4427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4427} follow +the\mdline{4428}~\mdref{sec-match-format}{same rules}\mdline{4428} as in a \mdline{4428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4428}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4430} +\noindent\mdline{4430}A \mdline{4430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4430} may only be modified. If the update type is \mdline{4430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4430} or +\mdline{4431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4431}, the server must return an \mdline{4431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4431} error. If the update type +is \mdline{4432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4432}, the server writes the members given in the repeated field to the +Value Set entry indexed by the given \mdline{4433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4433}. The maximum number of +matches must not exceed the maximum size given by the \mdline{4434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{4434} field in P4Info of +the Value Set, otherwise the server must return a \mdline{4435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4435} error. To +empty a Value Set (\mdline{4436}i.e.\mdline{4436} restore it to its initial state), the P4Runtime client +can perform a \mdline{4437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4437} update with an empty \mdline{4437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4437} repeated field.%mdk + +%mdk-data-line={4439} +\mdline{4439}To facilitate\mdline{4439}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{4439}, the server must +return an \mdline{4440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4440} error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set.%mdk + +%mdk-data-line={4446} +\mdline{4446}See Appendix\mdline{4446}~\mdref{sec-value-set-example}{A.3}\mdline{4446} for a more complex Value Set example.%mdk + +%mdk-data-line={4448} +\subsection{\mdline{4448}9.7.\hspace*{0.5em}\mdline{4448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}\label{sec-registerentry}%mdk%mdk + +%mdk-data-line={4450} +\noindent\mdline{4450}The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The \mdline{4451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4451} P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations.%mdk + +%mdk-data-line={4455} +\mdline{4455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4455} has the following fields:%mdk + +%mdk-data-line={4457} +\begin{itemize}%mdk + +%mdk-data-line={4457} +\item{} +%mdk-data-line={4457} +\mdline{4457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4457}, which identifies the PSA Register extern instance which is +being accessed by the client; the \mdline{4458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4458} is specified by the P4Info +message.%mdk%mdk + +%mdk-data-line={4461} +\item{} +%mdk-data-line={4461} +\mdline{4461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4461}, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4463} message +used for the request. When an \mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4464} is provided , the server must validate +its value, and return \mdline{4465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4465} for a negative index or +\mdline{4466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4466} if the index exceeds the size of the register array.%mdk%mdk + +%mdk-data-line={4468} +\item{} +%mdk-data-line={4468} +\mdline{4468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4468}: the data to be written to the array (if \mdline{4468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4468} is part of a +\mdline{4469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4469} message) or the data read from the array (if \mdline{4469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4469} is +part of a \mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4470} message). The \mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4470} field is a \mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{4470} message and +must match the format described by the \mdline{4471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{4471} field of the corresponding +Register entry in the P4Info, or the server must return an \mdline{4472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4472} +error.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4475} +\subsection{\mdline{4475}9.8.\hspace*{0.5em}\mdline{4475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}\label{sec-digestentry}%mdk%mdk + +%mdk-data-line={4477} +\noindent\mdline{4477}A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly.%mdk + +%mdk-data-line={4482} +\mdline{4482}The \mdline{4482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4482} P4Runtime entity is used to \mdline{4482}\textbf{configure}\mdline{4482} how the device must +generate digest messages. The \mdline{4483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4483} Protobuf message is not used to +carry digest data, which is done on the \mdline{4484}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4484} bidirectional stream +using the \mdline{4485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4485} (digest data sent by the target to the client) and +\mdline{4486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4486} (digest data acknowledgments sent by the client to the target) +Protobuf messages.%mdk + +%mdk-data-line={4489} +\mdline{4489}In this section, we refer to the data learned by a single data plane call to +\mdline{4490}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}T\textgreater{}::pack}}}\mdline{4490} as a \mdline{4490}\textquotedblleft{}digest message\textquotedblright{}\mdline{4490} and we use \mdline{4490}\textquotedblleft{}digest list\textquotedblright{}\mdline{4490} to designate +the list of digest messages bundled by the P4Runtime service in a single +\mdline{4492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4492} stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are \mdline{4494}\textquotedblleft{}duplicate\textquotedblright{}\mdline{4494} if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are \mdline{4495}\textquotedblleft{}distinct\textquotedblright{}\mdline{4495} +if they are not duplicate.%mdk + +%mdk-data-line={4498} +\mdline{4498}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4498} has the following fields:%mdk + +%mdk-data-line={4500} +\begin{itemize}%mdk + +%mdk-data-line={4500} +\item{} +%mdk-data-line={4500} +\mdline{4500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4500}, which identifies the PSA Digest extern instance which emitted the +data; the \mdline{4501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4501} is determined by the P4Info message.%mdk%mdk + +%mdk-data-line={4503} +\item{} +%mdk-data-line={4503} +\mdline{4503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4503}, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +\mdline{4505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4505}; these parameters are:%mdk + +%mdk-data-line={4507} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4507} +\item\mdline{4507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4507}: the maximum server buffering delay in nanoseconds for an +outstanding digest message.%mdk + +%mdk-data-line={4509} +\item\mdline{4509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4509}: the maximum digest list size\mdline{4509} \mdline{4509}\textemdash{}\mdline{4509} in number of digest +messages\mdline{4510} \mdline{4510}\textemdash{}\mdline{4510} sent by the server to the client as a single \mdline{4510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4510} +Protobuf message.%mdk + +%mdk-data-line={4512} +\item\mdline{4512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4512}: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4516} +\noindent\mdline{4516}Here is the significance of the different \mdline{4516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4516} types for \mdline{4516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4516}:%mdk + +%mdk-data-line={4518} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4518} +\item\mdline{4518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4518}: Enable server generation of \mdline{4518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4518} messages for given digest +instance and use provided configuration parameters.%mdk + +%mdk-data-line={4520} +\item\mdline{4520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4520}: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance.%mdk + +%mdk-data-line={4522} +\item\mdline{4522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4522}: Disable server generation of \mdline{4522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4522} messages for given digest +instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4525} +\noindent\mdline{4525}A server should buffer digest messages until either:%mdk + +%mdk-data-line={4527} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4527} +\item\mdline{4527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4527} time has passed since the first digest message was added to +the empty buffer, or%mdk + +%mdk-data-line={4529} +\item\mdline{4529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4529} \mdline{4529}\emph{distinct}\mdline{4529} digest messages have been received from the +data plane and added to the buffer%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4532} +\noindent\mdline{4532}At which point the server should, with best effort, generate a \mdline{4532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4532} +stream message with the buffer contents and send it to the primary client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software.%mdk + +%mdk-data-line={4538} +\mdline{4538}To avoid sending duplicate digest messages across different \mdline{4538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4538} +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the primary client indicates that it has received the +digest list and acted on it. The server must keep a \mdline{4541}\textquotedblleft{}cache\textquotedblright{}\mdline{4541} containing the set +of all digest messages that have been sent, but not acknowledged yet by the +primary client, up-to \mdline{4543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4543} in the past. The server must delete all +cache entries for a given digest list when they are at least \mdline{4544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4544} +old or when a matching \mdline{4545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4545} message (\mdline{4545}i.e.\mdline{4545} with the same \mdline{4545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4545} +and \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}list\_id}}}\mdline{4546} fields as the \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4546} message) is received.%mdk + +%mdk-data-line={4548} +\mdline{4548}The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged \mdline{4553}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4553} messages.%mdk + +%mdk-data-line={4555} +\mdline{4555}When \mdline{4555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4555} is set to 0 and / or \mdline{4555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4555} is set to 1, the +server should, with best effort, generate a \mdline{4556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4556} message for every +digest message generated by the data plane which is not already in the cache. If +\mdline{4558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4558} is set to 0, the cache must always be an empty set. If +\mdline{4559}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4559} is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +\mdline{4561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4561} configuration parameter.%mdk + +%mdk-data-line={4563} +\mdline{4563}The P4Runtime server may empty the digest message cache in case of a client +status change.%mdk + +%mdk-data-line={4566} +\mdline{4566}Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server:%mdk + +%mdk-data-line={4569} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4570} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestStream~stream;\\ +DigestCache~cache;\\ +DigestBuffer~buffers;\\ +\\ +{\mdcolor{darkgreen}//~sends~digest~list~when~it~is~ready}\\ +send\_buffer(Id~digest\_id)~\{\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~stream.write(DigestList(buffer));\\ +~~cache.merge(buffer);~~{\mdcolor{darkgreen}//~updates~cache~with~new~digest~list}\\ +~~buffer.clear();\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~data~plane~digest~messages~from~device}\\ +handle\_dataplane\_digest(Digest~msg)~\{\\ +~~digest\_id~=~msg.digest\_id();\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~{\bfseries{\mdcolor{navy}if}}~(msg~in~cache~{\mdcolor{teal}OR}~msg~in~buffer)~{\bfseries{\mdcolor{navy}return}};\\ +~~buffer.enqueue(msg);\\ +~~{\bfseries{\mdcolor{navy}if}}~(buffer.length()~\textless{}~max\_list\_size(digest\_id))~{\bfseries{\mdcolor{navy}return}};\\ +~~send\_buffer(digest\_id);\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~ack~messages~received~on~the~stream}\\ +handle\_stream\_ack(DigestListAck~ack)~\{\\ +~~{\mdcolor{darkgreen}//~clear~all~cache~entries~matching~the~tuple~(digest\_id,~list\_id)}\\ +~~cache.erase(~(ack.digest\_id(),~ack.list\_id()~)\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~loop~to~enforce~timeouts}\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~now~=~now();\\ +~~{\mdcolor{darkgreen}//~check~for~buffers~that~need~to~be~sent}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~buffer)~in~buffers)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~buffer.first\_enq\_time()~\textgreater{}=~max\_timeout\_ns(digest\_id))\\ +~~~~~~send\_buffer(buffer\_id);\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~check~for~expired~entries~in~cache}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~list\_id,~sent\_time)~in~cache)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~sent\_time~\textgreater{}=~ack\_timeout\_ns(digest\_id))\\ +~~~~~~cache.erase(~(digest\_id,~list\_id)~);\\ +~~\}\\ +~~sleep({\mdcolor{teal}X});\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4615} +\subsection{\mdline{4615}9.9.\hspace*{0.5em}\mdline{4615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\label{sec-extern-entry}%mdk%mdk + +%mdk-data-line={4617} +\noindent\mdline{4617}This is used to support a P4 extern entity that is not part of PSA. It is +defined as:%mdk + +%mdk-data-line={4620} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4621} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ExternEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_type\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~google.protobuf.Any~entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4628} +\noindent\mdline{4628}Each \mdline{4628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4628} entity maps to an \mdline{4628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{4628} message in the +\mdline{4629}\mdref{sec-p4info-extern}{P4Info}\mdline{4629} and an \mdline{4629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4629} message within that +message. The \mdline{4630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{4630} field must be equal to the one in +\mdline{4631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4631}. The \mdline{4631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_id}}}\mdline{4631} field must be equal to the ID included in the +\mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{4632} of the corresponding \mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4632} message.%mdk + +%mdk-data-line={4634} +\mdline{4634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entry}}}\mdline{4634} itself is embedded as an \mdline{4634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{4634} Protobuf message\mdline{4634}~[\mdcite{protoany}{31}]\mdline{4634} to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on\mdline{4638}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{4639} for more information.%mdk + +%mdk-data-line={4641} +\section{\mdline{4641}10.\hspace*{0.5em}\mdline{4641}Error Reporting Messages}\label{sec-error-reporting-messages}%mdk%mdk + +%mdk-data-line={4643} +\noindent\mdline{4643}P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case.%mdk + +%mdk-data-line={4647} +\mdline{4647}gRPC uses \mdline{4647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4647}~[\mdcite{grpcstatus}{32}]\mdline{4647} to represent the status returned by an +RPC. It has 3 attributes:%mdk + +%mdk-data-line={4650} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4651} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StatusCode~code\_;\\ +{\mdcolor{navy}grpc::}string~error\_message\_;\\ +{\mdcolor{navy}grpc::}string~binary\_error\_details\_;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4656} +\noindent\mdline{4656}The \mdline{4656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4656} represents a canonical error\mdline{4656}~[\mdcite{grpcstatuscodes}{34}]\mdline{4656} and describes the +overall RPC status. The \mdline{4657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4657} is a developer-facing error message, +which should be in English. The \mdline{4658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}binary\_error\_details\_}}}\mdline{4658} carries a serialized +\mdline{4659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4659} message\mdline{4659}~[\mdcite{protostatus}{28}]\mdline{4659} message, which has 3 fields:%mdk + +%mdk-data-line={4661} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4662} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}int32}}~code~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~see~code.proto}\\ +{\bfseries{\mdcolor{navy}string}}~{\bfseries{\mdcolor{navy}message}}~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +{\bfseries{\mdcolor{navy}repeated}}~google.protobuf.Any~details~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4667} +\noindent\mdline{4667}The code and message fields must be the same as \mdline{4667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4667} and \mdline{4667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4667} +fields from \mdline{4668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4668} above. The \mdline{4668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{4668} field is a list that consists of +\mdline{4669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4669} messages that carry error details for individual elements inside +batch-request RPCs (\mdline{4670}e.g.\mdline{4670} \mdline{4670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4670} and \mdline{4670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4670}). \mdline{4670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4670} includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices\mdline{4674}~[\mdcite{grpcstatuscodes}{34}]\mdline{4674}.%mdk + +%mdk-data-line={4676} +\mdline{4676}Figure\mdline{4676}~\mdref{fig-error-report}{\mdcaptionlabel{7}}\mdline{4676} illustrates how these messages fit together.%mdk + +%mdk-data-line={4678} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={4679} +\noindent\mdline{4679}\includegraphics[keepaspectratio=true,width=\dimwidth{0.70}]{build/error-report}{}\mdline{4679}%mdk + +%mdk-data-line={4680} +\mdhr{}%mdk + +%mdk-data-line={4681} +\noindent\mdline{4681}\mdcaption{\textbf{Figure~\mdcaptionlabel{7}.}~\mdcaptiontext{P4Runtime Error Report Message Format}}%mdk +%mdk +\end{mdcenter}\label{fig-error-report}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={4683} +\noindent\mdline{4683}gRPC provides utility functions \mdline{4683}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExtractErrorDetails()}}}\mdline{4683} and \mdline{4683}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetErrorDetails()}}}\mdline{4683} +\mdline{4684}[\mdcite{grpcerrordetails}{33}]\mdline{4684} to easily convert between \mdline{4684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4684} and +\mdline{4685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4685}.%mdk + +%mdk-data-line={4687} +\mdline{4687}Please see sections on individual P4Runtime RPCs for details on how +\mdline{4688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4688} is populated for reporting errors.%mdk + +%mdk-data-line={4690} +\mdline{4690}Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on\mdline{4693}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{4694} for more information.%mdk + +%mdk-data-line={4696} +\section{\mdline{4696}11.\hspace*{0.5em}\mdline{4696}Atomicity of Individual \mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4696} and \mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4696} Operations}\label{sec-atomicity-of-individual-write-and-read-operations}%mdk%mdk + +%mdk-data-line={4698} +\noindent\mdline{4698}Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane \mdline{4699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4699} +operation, and every single \mdline{4700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4700} operation on a table that inserts, deletes, +or modifies one table entry, the \mdline{4701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4701} operation should behave as if that +\mdline{4702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4702} operation has not yet occurred, or as if the \mdline{4702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4702} operation is +complete. The P4 program should never behave as if the \mdline{4703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4703} operation is +partially complete. These guarantees also apply to extern instances: \mdline{4704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4704} and +\mdline{4705}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4705} operations on extern entities must execute atomically relative to extern +data plane methods.%mdk + +%mdk-data-line={4708} +\mdline{4708}The atomicity guarantees provided by P4Runtime for individual \mdline{4708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4708} and \mdline{4708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4708} +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification\mdline{4710}~[\mdcite{psaatomicityofcontrolplaneops}{23}]\mdline{4710}.%mdk + +%mdk-data-line={4712} +\mdline{4712}The P4\mdline{4712}\mdsub{16}\mdline{4712} language introduces an \mdline{4712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4712} annotation\mdline{4712}~[\mdcite{p4concurrency}{14}]\mdline{4712}, to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the \mdline{4714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4714} annotation for \mdline{4714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4714} +operations, as well as\mdline{4715}~\mdref{wildcard-reads}{non-wildcard \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} operations}\mdline{4715}, +relative to data plane execution. Consider the following P4 example written for +PSA:%mdk + +%mdk-data-line={4719} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4720} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024)~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\mdcolor{darkgreen}//~...}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~Value\_t~v~=~r1.read((Index\_t){\mdcolor{purple}1});\\ +~~~~~~~~v~=~v~+~{\mdcolor{purple}1};\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~v);\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4736} +\noindent\mdline{4736}If a P4Runtime server is processing messages which write to Register \mdline{4736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4736} at +index \mdline{4737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}1}}}\mdline{4737}, these writes must not happen between the data plane \mdline{4737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}read}}}\mdline{4737} and +\mdline{4738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}write}}}\mdline{4738}.%mdk + +%mdk-data-line={4740} +\mdline{4740}Now let\mdline{4740}'\mdline{4740}s consider the following example:%mdk + +%mdk-data-line={4742} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4743} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024,~(Value\_t){\mdcolor{purple}0}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~initial~value~}{\mdcolor{darkgreen}*/})~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}100});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}100});\\ +~~~~\}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}200});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}200});\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4761} +\noindent\mdline{4761}If a P4Runtime client issues a \mdline{4761}\emph{wildcard}\mdline{4761} \mdline{4761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4761} on Register \mdline{4761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4761}, there is no +guarantee that \mdline{4762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]~==~r1{}[2]}}}\mdline{4762} in the response, as the read for \mdline{4762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4762} may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for \mdline{4764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4764} may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read \mdline{4766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4766} and \mdline{4766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4766} separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +\mdline{4769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4769} message) of individual read requests. Similar to a batch +\mdline{4770}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4770}, a wildcard read of a register can execute the reads of the +register array elements (\mdline{4771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4771}, \mdline{4771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4771}, \mdline{4771}\dots{}\mdline{4771}) in an arbitrary order relative +to each other.%mdk + +%mdk-data-line={4774} +\mdline{4774}If the \mdline{4774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4774} annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program.%mdk + +%mdk-data-line={4778} +\section{\mdline{4778}12.\hspace*{0.5em}\mdline{4778}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4778} RPC}\label{sec-write-rpc}%mdk%mdk + +%mdk-data-line={4780} +\noindent\mdline{4780}The \mdline{4780}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4780} RPC updates one or more P4 entities on the target. The request is +defined as follows:%mdk + +%mdk-data-line={4783} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4784} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~WriteRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Update~updates~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\bfseries{\mdcolor{navy}enum}}~Atomicity~\{\\ +~~~~CONTINUE\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~ROLLBACK\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~DATAPLANE\_ATOMIC~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~\}\\ +~~Atomicity~atomicity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4798} +\noindent\mdline{4798}The \mdline{4798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4798} uniquely identifies the target P4 device. The \mdline{4798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{4798} and +\mdline{4799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4799} define the client role and election-id as described in the +\mdline{4800}\mdref{sec-client-arbitration-and-controller-replication}{Primary-Backup Arbitration and Controller +Replication}\mdline{4801} +section. The server is expected to perform the following checks (in this order) +before processing the \mdline{4803}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}updates}}}\mdline{4803} list:%mdk + +%mdk-data-line={4805} +\begin{enumerate}%mdk + +%mdk-data-line={4805} +\item{} +%mdk-data-line={4805} +\mdline{4805}If \mdline{4805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4805} does not match any of the devices known to the P4Runtime +server or if \mdline{4806}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{4806} does not match any of the roles for the device, the +server must return a \mdline{4807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4807} error.%mdk%mdk + +%mdk-data-line={4809} +\item{} +%mdk-data-line={4809} +\mdline{4809}If the client is not the primary for (\mdline{4809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4809}, \mdline{4809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{4809}) according to +the \mdline{4810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4810} value, the server must return a \mdline{4810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4810} error.%mdk%mdk + +%mdk-data-line={4812} +\item{} +%mdk-data-line={4812} +\mdline{4812}If the \mdline{4812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4812} is attempted before a \mdline{4812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4812} has been set, +the server must return a \mdline{4813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{4813} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4815} +\noindent\mdline{4815}The updates field is a list of P4 entity updates to be applied. Each update is +defined as:%mdk + +%mdk-data-line={4818} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4819} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Update~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Type~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~INSERT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~MODIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DELETE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~Type~type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Entity~entity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4831} +\noindent\mdline{4831}This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a \mdline{4832}\emph{logical}\mdline{4832} table (\mdline{4832}e.g.\mdline{4832} +\mdline{4833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4833}) or an actual table (\mdline{4833}e.g.\mdline{4833} \mdline{4833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4833}) in the P4 data +plane. Each entity in the container is uniquely identified by its \mdline{4834}\emph{key}\mdline{4834}. Please +refer to the\mdline{4835}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4835} section for details on +what parts of the entity specification make up the \mdline{4836}\emph{key}\mdline{4836} for each P4 entity.%mdk + +%mdk-data-line={4838} +\mdline{4838}An update can be one of the following types:%mdk + +%mdk-data-line={4840} +\begin{itemize}%mdk + +%mdk-data-line={4840} +\item{} +%mdk-data-line={4840} +\mdline{4840}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4840}: Inserts the given P4 entity in the entity container. +The \mdline{4841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{4841} field always specifies the full state of the P4 entity. +If the entity already exists, an \mdline{4842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4842} error is returned, and +the existing entity remains unchanged. If the entity is malformed, an +\mdline{4844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4844} error is usually returned (unless a more specific error +code applies\mdline{4845}~[\mdcite{grpcstatuscodes}{34}]\mdline{4845}). If the entity cannot be inserted because the +container is already full, a \mdline{4846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4846} error is returned.%mdk%mdk + +%mdk-data-line={4848} +\item{} +%mdk-data-line={4848} +\mdline{4848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4848}: Modifies the P4 entity to its new specified state. This uses +\mdline{4849}\emph{assign}\mdline{4849} or \mdline{4849}\emph{full-snapshot}\mdline{4849} semantics, \mdline{4849}i.e.\mdline{4849} the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an \mdline{4851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4851} error is usually returned (unless a +more specific error code applies\mdline{4852}~[\mdcite{grpcstatuscodes}{34}]\mdline{4852}). If the entity does not +exist, a \mdline{4853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4853} error is returned.%mdk%mdk + +%mdk-data-line={4855} +\item{} +%mdk-data-line={4855} +\mdline{4855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4855}: Deletes the specified P4 entity. If the entity does not exist, a +\mdline{4856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4856} error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4859} +\noindent\mdline{4859}If an update is not allowed under the given controller role, the server must +return a \mdline{4860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4860} error for this update.%mdk + +%mdk-data-line={4862} +\subsection{\mdline{4862}12.1.\hspace*{0.5em}\mdline{4862}Batching and Ordering of Updates}\label{sec-batching-and-ordering-of-updates}%mdk%mdk + +%mdk-data-line={4864} +\noindent\mdline{4864}P4Runtime supports batching of \mdline{4864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4864} operations. The list of updates in a +\mdline{4865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4865} is referred to as a \mdline{4865}\emph{batch}\mdline{4865}. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of \mdline{4867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4867} entities).%mdk + +%mdk-data-line={4869} +\mdline{4869}The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +\mdline{4871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4871}s can also be processed interleaved and/or in parallel. +However, \mdline{4872}\textbf{the processing of requests must be strictly serializable}\mdline{4872}. That +is, given a history \mdline{4873}$S$\mdline{4873} of \mdline{4873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4873}s including the responses to those +requests, there must exist an order \mdline{4874}$L$\mdline{4874} for all updates in \mdline{4874}$S$\mdline{4874}, such that:%mdk + +%mdk-data-line={4876} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4876} +\item\mdline{4876}All updates from the same write request must appear as a contiguous +subsequence in \mdline{4877}$L$\mdline{4877}, but the order within that subsequence can be arbitrary.%mdk + +%mdk-data-line={4878} +\item\mdline{4878}For two updates \mdline{4878}$u_1$\mdline{4878} and \mdline{4878}$u_2$\mdline{4878}, if the write request containing \mdline{4878}$u_1$\mdline{4878} +completed before the write request of \mdline{4879}$u_2$\mdline{4879} was sent, then \mdline{4879}$u_1$\mdline{4879} must appear +before \mdline{4880}$u_2$\mdline{4880} in \mdline{4880}$L$\mdline{4880}.%mdk + +%mdk-data-line={4881} +\item\mdline{4881}Executing all updates in \mdline{4881}$L$\mdline{4881} sequentially must yield the same response for +every update as in \mdline{4882}$S$\mdline{4882}.%mdk + +%mdk-data-line={4883} +\item\mdline{4883}The observable state of the switch after \mdline{4883}$S$\mdline{4883} (\mdline{4883}e.g.\mdline{4883}, through the \mdline{4883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4883} RPC) +is identical to the one obtained by sequentially executing \mdline{4884}$L$\mdline{4884}.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4886} +\noindent\mdline{4886}The \mdline{4886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4886} RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the \mdline{4887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4887} RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (\mdline{4890}e.g.\mdline{4890} inserting an \mdline{4890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4890} +followed by pointing a \mdline{4891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4891} to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding \mdline{4893}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4893} RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate \mdline{4897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4897} calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each \mdline{4898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4898} call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one.%mdk + +%mdk-data-line={4903} +\subsection{\mdline{4903}12.2.\hspace*{0.5em}\mdline{4903}Batch Atomicity}\label{sec-batch-atomicity}%mdk%mdk + +%mdk-data-line={4905} +\noindent\mdline{4905}A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the \mdline{4906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4906} +enum. A P4Runtime server is required to support only the modes marked as +\mdline{4908}\emph{Required}\mdline{4908} below:%mdk + +%mdk-data-line={4910} +\begin{itemize}%mdk + +%mdk-data-line={4910} +\item{} +%mdk-data-line={4910} +\mdline{4910}\emph{Required}\mdline{4910}: \mdline{4910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4910}: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that \mdline{4914}\emph{see}\mdline{4914} each of +these intermediate stages.%mdk%mdk + +%mdk-data-line={4917} +\item{} +%mdk-data-line={4917} +\mdline{4917}\emph{Optional}\mdline{4917}: \mdline{4917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ROLLBACK\_ON\_ERROR}}}\mdline{4917}: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is \mdline{4921}\emph{all-or-none}\mdline{4921}, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that \mdline{4925}\emph{see}\mdline{4925} each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure.%mdk + +%mdk-data-line={4930} +\mdline{4930}If a P4Runtime server does not support this option at all, an +\mdline{4931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4931} error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (\mdline{4932}e.g.\mdline{4932} it is +more straightforward to implement batches that contain only \mdline{4933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4933} +operations, vs. those that contain \mdline{4934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4934} operations), an +\mdline{4935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4935} error is returned when the batch cannot be executed +in a data plane-atomic way.%mdk%mdk + +%mdk-data-line={4938} +\item{} +%mdk-data-line={4938} +\mdline{4938}\emph{Optional}\mdline{4938}: \mdline{4938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4938}: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +\mdline{4942}\emph{transaction}\mdline{4942}. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane\mdline{4944}'\mdline{4944}s table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table.%mdk + +%mdk-data-line={4951} +\mdline{4951}If a P4Runtime server does not support this option at all, an \mdline{4951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4951} +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an \mdline{4953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4953} error is returned when the batch +cannot be executed in a data plane-atomic way.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4956} +\noindent\mdline{4956}There is no expectation that a given client must always use the same \mdline{4956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4956} +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use \mdline{4959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4959} at one time and default behavior +(\mdline{4960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4960}) at other times.%mdk + +%mdk-data-line={4962} +\subsection{\mdline{4962}12.3.\hspace*{0.5em}\mdline{4962}Error Reporting}\label{sec-error-reporting}%mdk%mdk + +%mdk-data-line={4964} +\noindent\mdline{4964}Please see section\mdline{4964}~\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{4964} for +information on error reporting messages and guidelines. P4Runtime server will +populate \mdline{4966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4966} as follows:%mdk + +%mdk-data-line={4968} +\begin{enumerate}%mdk + +%mdk-data-line={4968} +\item{} +%mdk-data-line={4968} +\mdline{4968}If all batch updates succeeded, set \mdline{4968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4968} to \mdline{4968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4968} and do not +populate any other field.%mdk%mdk + +%mdk-data-line={4971} +\item{} +%mdk-data-line={4971} +\mdline{4971}If an error is encountered before even trying to attempt individual batch +updates, set \mdline{4972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4972} that best describes that RPC-wide +error. For example, use \mdline{4973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNAVAILABLE}}}\mdline{4973} if the P4Runtime service is not yet +ready to handle requests. Set \mdline{4974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4974} to describe the issue. Do not +set \mdline{4975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_details}}}\mdline{4975} in this case.%mdk%mdk + +%mdk-data-line={4977} +\item{} +%mdk-data-line={4977} +\mdline{4977}Otherwise, if one or more updates in the batch (\mdline{4977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest.updates}}}\mdline{4977}) +failed, set \mdline{4978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4978} to \mdline{4978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{4978}. For example, one update in +the batch may fail with \mdline{4979}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4979} and another with +\mdline{4980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4980}. A \mdline{4980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4980} message is used to capture the status of +each and every update in the batch. The number of \mdline{4981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4981} messages packed +into \mdline{4982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{4982} field should therefore always match the +number of updates in the \mdline{4983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4983}, and the order of +\mdline{4984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4984} messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +\mdline{4986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4986} should set the code to \mdline{4986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4986} and omit other fields.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4988} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4989} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}\#~Example~of~a~grpc::Status~returned~for~a~Write~RPC~with~a~batch~of~3~updates.}\\ +{\mdcolor{darkgreen}\#~The~first~and~third~updates~encountered~an~error,~while~the~second~update}\\ +{\mdcolor{darkgreen}\#~succeeded.}\\ +code\_~=~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +error\_message\_~=~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +binary\_error\_details~\{\\ +~~code:~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}8}~~{\mdcolor{darkgreen}\#~RESOURCE\_EXHAUSTED}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Table~is~full.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}500}~~{\mdcolor{darkgreen}\#~ERR\_TABLE\_FULL}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}0}~~{\mdcolor{darkgreen}\#~OK}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}6}~~{\mdcolor{darkgreen}\#~ALREADY\_EXISTS}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Entity~already~exists.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}600}~~{\mdcolor{darkgreen}\#~ERR\_ENTITY\_ALREADY\_EXISTS}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5015} +\section{\mdline{5015}13.\hspace*{0.5em}\mdline{5015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5015} RPC}\label{sec-read-rpc}%mdk%mdk + +%mdk-data-line={5017} +\noindent\mdline{5017}The \mdline{5017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5017} RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as:%mdk + +%mdk-data-line={5020} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5021} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5028} +\noindent\mdline{5028}The \mdline{5028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5028} uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +\mdline{5030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5030} error. +If the \mdline{5031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5031} is attempted before \mdline{5031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5031} has been set, the +server must return a \mdline{5032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{5032} error. +The \mdline{5033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5033} field acts as a filter, restricting the reported entities based on +the role to which the entity belongs. +The \mdline{5035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{5035} repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server.%mdk + +%mdk-data-line={5038} +\mdline{5038}Since \mdline{5038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5038}s do not mutate any state on the switch, they do not +require an \mdline{5039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5039}, and they do not require the presence of an open +\mdline{5040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5040} between the server and client.%mdk + +%mdk-data-line={5042} +\mdline{5042}The \mdline{5042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read~}}}\mdline{5042}response consists of a sequence of messages (a gRPC \mdline{5042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}stream}}}\mdline{5042}) with +each message defined as:%mdk + +%mdk-data-line={5045} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5046} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadResponse~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5051} +\noindent\mdline{5051}The \mdline{5051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{5051} repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the \mdline{5055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Finish()}}}\mdline{5055} method on the stream object +\mdline{5056}[\mdcite{grpcstreamc}{10}]\mdline{5056}).%mdk + +%mdk-data-line={5058} +\subsection{\mdline{5058}13.1.\hspace*{0.5em}\mdline{5058}Nomenclature}\label{sec-nomenclature}%mdk%mdk + +%mdk-data-line={5060} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries request}}%mdk + +%mdk-data-line={5060} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{5060}An element of the \mdline{5060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{5060} repeated field. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries batch}}%mdk + +%mdk-data-line={5062} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{5062}Refers to the \mdline{5062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{5062} repeated field.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={5065} +\noindent\mdline{5065}Each \mdline{5065}\emph{request}\mdline{5065} acts as a query filter for that entity type. If a \mdline{5065}\emph{request}\mdline{5065} fully +specifies the entity key, the \mdline{5066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5066} operation should retrieve a single P4 +entity. Please refer to the\mdline{5067}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{5067} section +for details on what parts of the entity specification make up the entity \mdline{5068}\emph{key}\mdline{5068}.%mdk + +%mdk-data-line={5070} +\subsection{\mdline{5070}13.2.\hspace*{0.5em}\mdline{5070}Wildcard Reads}\label{sec-wildcard-reads}%mdk%mdk + +%mdk-data-line={5072} +\noindent\mdline{5072}P4Runtime allows wildcard read of P4 entities. A \mdline{5072}\emph{request}\mdline{5072} may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the\mdline{5074}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{5074} section for details on +what parts of the entity can be wildcarded in a given \mdline{5075}\emph{request}\mdline{5075}.%mdk + +%mdk-data-line={5077} +\mdline{5077}For example, in a \mdline{5077}\emph{request}\mdline{5077} of type \mdline{5077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{5077}:%mdk + +%mdk-data-line={5079} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5079} +\item\mdline{5079}A default \mdline{5079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{5079} (0) implies a request to read all counter-entries for +all indirect counters.%mdk + +%mdk-data-line={5081} +\item\mdline{5081}A particular (non-default) \mdline{5081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{5081} in conjunction with \mdline{5081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{5081} unset +implies a request to read all counter-entries for the given indirect counter +ID.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5085} +\noindent\mdline{5085}To read the entire forwarding state for a given device, the P4Runtime client can +generate the following \mdline{5086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5086}:%mdk + +%mdk-data-line={5088} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5089} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~\textless{}ID\textgreater{}\\ +entities~\{\\ +~~extern\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~extern~instances~for~all~supported~extern~types}\\ +~~table\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~table~entries~for~all~tables}\\ +~~action\_profile\_member~\{~\}~~{\mdcolor{darkgreen}\#~read~all~members~for~all~action~profiles}\\ +~~action\_profile\_group~\{~\}~~{\mdcolor{darkgreen}\#~read~all~groups~for~all~action~profiles}\\ +~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5099} +\noindent\mdline{5099}The \mdline{5099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5099} oneof field in the \mdline{5099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5099} message must always be set, or the +server must return an \mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5100} error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty \mdline{5102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5102} message in the \mdline{5102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5102}. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the \mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5104} oneof\mdline{5104}~[\mdcite{protooneofbackwardscompatibility}{20}]\mdline{5104}.%mdk + +%mdk-data-line={5106} +\subsection{\mdline{5106}13.3.\hspace*{0.5em}\mdline{5106}Batch Processing}\label{sec-batch-processing}%mdk%mdk + +%mdk-data-line={5108} +\noindent\mdline{5108}A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type \mdline{5109}\emph{request}\mdline{5109} +appears only once in the batch.%mdk + +%mdk-data-line={5112} +\mdline{5112}A P4Runtime server will process the batch as follows:%mdk + +%mdk-data-line={5114} +\begin{enumerate}%mdk + +%mdk-data-line={5114} +\item{} +%mdk-data-line={5114} +\mdline{5114}Lock state (preventing new writes) and validate each \mdline{5114}\emph{request}\mdline{5114} in the batch:%mdk + +%mdk-data-line={5116} +\begin{enumerate}%mdk + +%mdk-data-line={5116} +\item{} +%mdk-data-line={5116} +\mdline{5116}If it is a valid \mdline{5116}\emph{request}\mdline{5116}, perform the read;%mdk + +%mdk-data-line={5118} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5118} +\item\mdline{5118}If the read was successful, return the entities read in +\mdline{5119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5119} stream.%mdk + +%mdk-data-line={5120} +\item\mdline{5120}If the read failed (exception / critical-error), prepare a \mdline{5120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5120} +with code set to \mdline{5121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INTERNAL}}}\mdline{5121}.%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5123} +\item{} +%mdk-data-line={5123} +\mdline{5123}If the \mdline{5123}\emph{request}\mdline{5123} is invalid (invalid-argument, not-supported, etc.), +prepare a \mdline{5124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5124} with relevant canonical code to capture the error.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5126} +\item{} +%mdk-data-line={5126} +\mdline{5126}Unlock the state (allowing new writes);%mdk%mdk + +%mdk-data-line={5128} +\item{} +%mdk-data-line={5128} +\mdline{5128}Close the \mdline{5128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5128} stream and return a \mdline{5128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5128} as follows:%mdk + +%mdk-data-line={5130} +\begin{enumerate}%mdk + +%mdk-data-line={5130} +\item{} +%mdk-data-line={5130} +\mdline{5130}If no errors were encountered, set code to \mdline{5130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{5130} and do not populate any +other field.%mdk%mdk + +%mdk-data-line={5133} +\item{} +%mdk-data-line={5133} +\mdline{5133}Otherwise, the overall code should be set to \mdline{5133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{5133}. See section +\mdline{5134}\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{5134} for information +on error reporting messages and guidelines. Assemble a list of \mdline{5135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5135} +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +\mdline{5139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{5139} field. This behavior also matches \mdline{5139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5139} +RPC.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5142} +\subsubsection{\mdline{5142}13.3.1.\hspace*{0.5em}\mdline{5142}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={5144} +\noindent\mdline{5144}If a client asked to read \mdline{5144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{a,b,c,d\}}}}\mdline{5144} and \mdline{5144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}b}}}\mdline{5144} and \mdline{5144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}d}}}\mdline{5144} \mdline{5144}\emph{requests}\mdline{5144} didn\mdline{5144}'\mdline{5144}t +validate, the server will return entities corresponding to \mdline{5145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5145} and \mdline{5145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}c}}}\mdline{5145}, followed +by a status \mdline{5146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{p4.Error(OK),~p4.Error(xxx),~p4.Error(yyy),~p4.Error(OK)\}}}}\mdline{5146} in the +\mdline{5147}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5147} field.%mdk + +%mdk-data-line={5149} +\mdline{5149}The P4Runtime server is not required to perform any optimization (\mdline{5149}e.g.\mdline{5149} merge two +\mdline{5150}\emph{requests}\mdline{5150} in the \mdline{5150}\emph{batch}\mdline{5150} if one is a subset of other). As a result of this, it +is possible for the \mdline{5151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5151} to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging.%mdk + +%mdk-data-line={5154} +\mdline{5154}There is no requirement that each request in the batch will correspond to one +\mdline{5155}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5155} message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit.%mdk + +%mdk-data-line={5160} +\mdline{5160}A P4Runtime server must be prepared to handle multiple concurrent \mdline{5160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5160} RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (\mdline{5165}e.g.\mdline{5165} in a single-threaded architecture), it may choose to serialize +\mdline{5166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5166} RPC processing.%mdk + +%mdk-data-line={5168} +\subsection{\mdline{5168}13.4.\hspace*{0.5em}\mdline{5168}Parallelism of Read and Write Requests}\label{sec-parallelism-of-read-and-write-requests}%mdk%mdk + +%mdk-data-line={5170} +\noindent\mdline{5170}A P4Runtime server may be implemented to serve at most one +\mdline{5171}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5171} or \mdline{5171}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5171} message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so.%mdk + +%mdk-data-line={5176} +\mdline{5176}For example, imagine a client that wanted to use \mdline{5176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5176} +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +\mdline{5180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5180} messages with only a few updates to an \mdline{5180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{5180} +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +\mdline{5183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5183} batch currently being processed, but it will not +complete for a significant amount of time.%mdk + +%mdk-data-line={5186} +\mdline{5186}The restrictions on which a client may rely are:%mdk + +%mdk-data-line={5188} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5188} +\item\mdline{5188}The processing of any two \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5188} messages \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W1}}}\mdline{5188} and \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W2}}}\mdline{5188} must +result in the same state as if one of them was completed before the +other began.%mdk + +%mdk-data-line={5191} +\item\mdline{5191}For any \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5191} \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5191} and any \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5191} \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5191}, \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5191} must +return results consistent with a state where \mdline{5192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5192} has completed +processing, or \mdline{5193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5193} has not yet begun processing.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5195} +\noindent\mdline{5195}For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a \mdline{5198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5198} message it acquired a write lock for each stateful +object affected by the \mdline{5199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5199}, and before starting the +processing of a \mdline{5200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5200} message it acquired a read lock for each +stateful object accessed by the \mdline{5201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5201}, such an implementation +meets all of the requirements above.%mdk + +%mdk-data-line={5204} +\mdline{5204}It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, \mdline{5206}e.g.\mdline{5206} if the server somehow determined that two +\mdline{5207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5207} messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly.%mdk + +%mdk-data-line={5213} +\section{\mdline{5213}14.\hspace*{0.5em}\mdline{5213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5213} RPC}\label{sec-setforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5215} +\noindent\mdline{5215}A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the \mdline{5216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig~RPC}}}\mdline{5216}. The request is defined as:%mdk + +%mdk-data-line={5218} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5219} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~SetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Action~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~VERIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~VERIFY\_AND\_SAVE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~VERIFY\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~~~COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~~~RECONCILE\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~Action~action~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5236} +\noindent\mdline{5236}The server is expected to perform the following checks (in this order) +before performing the required \mdline{5237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{5237}:%mdk + +%mdk-data-line={5239} +\begin{enumerate}%mdk + +%mdk-data-line={5239} +\item{} +%mdk-data-line={5239} +\mdline{5239}If \mdline{5239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5239} does not match any of the devices known to the P4Runtime +server or if \mdline{5240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5240} does not match any of the roles for the device, the +server must return a \mdline{5241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5241} error.%mdk%mdk + +%mdk-data-line={5243} +\item{} +%mdk-data-line={5243} +\mdline{5243}If the client is not the primary for (\mdline{5243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5243}, \mdline{5243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5243}) according to +the \mdline{5244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5244} value, the server must return a \mdline{5244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5244} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5246} +\noindent\mdline{5246}The action is the type of configuration action requested, it can be one of:%mdk + +%mdk-data-line={5248} +\begin{itemize}%mdk + +%mdk-data-line={5248} +\item{} +%mdk-data-line={5248} +\mdline{5248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY}}}\mdline{5248}: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an \mdline{5249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5249} +error if config is not provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5252} +\item{} +%mdk-data-line={5252} +\mdline{5252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5252}: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent \mdline{5254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5254} / \mdline{5254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5254} requests must refer to fields in the new +config. Returns an \mdline{5255}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5255} error if the forwarding config is not +provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5258} +\item{} +%mdk-data-line={5258} +\mdline{5258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_COMMIT}}}\mdline{5258}: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an \mdline{5260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5260} error if the forwarding config is not provided or if the +provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5263} +\item{} +%mdk-data-line={5263} +\mdline{5263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COMMIT}}}\mdline{5263}: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a \mdline{5266}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5266} error if no saved config +is found, \mdline{5267}i.e.\mdline{5267} if no \mdline{5267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5267} action preceded this one. Returns an +\mdline{5268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5268} error if a config is provided with this message.%mdk%mdk + +%mdk-data-line={5270} +\item{} +%mdk-data-line={5270} +\mdline{5270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RECONCILE\_AND\_COMMIT}}}\mdline{5270}: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an \mdline{5276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5276} error. For targets that support this option, an +\mdline{5277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5277} error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5281} +\noindent\mdline{5281}The \mdline{5281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5281} field is a message of type \mdline{5281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5281} that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(\mdline{5283}e.g.\mdline{5283} generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the\mdline{5284}~\mdref{sec-p4-fwd-pipe-config}{Forwarding-Pipeline +Configuration}\mdline{5285} section for details.%mdk + +%mdk-data-line={5287} +\mdline{5287}A P4Runtime server running on a non-programmable device may not +support \mdline{5288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5288} (\mdline{5288}e.g.\mdline{5288} the forwarding-pipeline +config is part of the device\mdline{5289}'\mdline{5289}s software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +\mdline{5291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5291} error.%mdk + +%mdk-data-line={5293} +\section{\mdline{5293}15.\hspace*{0.5em}\mdline{5293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5293} RPC}\label{sec-getforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5295} +\noindent\mdline{5295}The forwarding-pipeline configuration of the target can be retrieved by invoking +the \mdline{5296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig~RPC}}}\mdline{5296}. The request is defined as:%mdk + +%mdk-data-line={5298} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5299} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~ResponseType~\{\\ +~~~~ALL~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~COOKIE\_ONLY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~P{\mdcolor{purple}4}INFO\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DEVICE\_CONFIG\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~ResponseType~response\_type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5311} +\noindent\mdline{5311}The \mdline{5311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5311} uniquely identifies the target P4 device. A \mdline{5311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5311} error is +returned if the \mdline{5312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5312} is not recognized by the P4Runtime server.%mdk + +%mdk-data-line={5314} +\mdline{5314}The \mdline{5314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5314} is used to specify which fields to populate in the response, +its value can be one of:%mdk + +%mdk-data-line={5317} +\begin{itemize}%mdk + +%mdk-data-line={5317} +\item{} +%mdk-data-line={5317} +\mdline{5317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5317}: returns a \mdline{5317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5317} with all fields +set as stored by the target. This is the default behaviour if the +\mdline{5319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5319} field is not set.%mdk%mdk + +%mdk-data-line={5321} +\item{} +%mdk-data-line={5321} +\mdline{5321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COOKIE\_ONLY}}}\mdline{5321}: reply by setting only the \mdline{5321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5321} field in the +\mdline{5322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5322}, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message.%mdk%mdk + +%mdk-data-line={5326} +\item{} +%mdk-data-line={5326} +\mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4INFO\_AND\_COOKIE}}}\mdline{5326}: reply by setting the \mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{5326} and \mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5326} fields.%mdk%mdk + +%mdk-data-line={5328} +\item{} +%mdk-data-line={5328} +\mdline{5328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEVICE\_CONFIG\_AND\_COOKIE}}}\mdline{5328}: reply by setting the \mdline{5328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5328} and +\mdline{5329}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5329} fields.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5331} +\noindent\mdline{5331}The response contains the \mdline{5331}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5331} for the specified device:%mdk + +%mdk-data-line={5333} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5334} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigResponse~\{\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5339} +\noindent\mdline{5339}If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level \mdline{5340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5340} field will be unset in the response. Examples are +(i) a server that only allows configuration via \mdline{5341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5341} +but this RPC hasn\mdline{5342}'\mdline{5342}t been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn\mdline{5343}'\mdline{5343}t yet occurred.%mdk + +%mdk-data-line={5345} +\mdline{5345}Once a forwarding-pipeline config is installed on the device (either via +\mdline{5346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5346} or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +\mdline{5348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.p4\_device\_config}}}\mdline{5348} will be empty / unset in the response, even if +\mdline{5349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5349} in the request was set to \mdline{5349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5349}. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the \mdline{5351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5351} RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +\mdline{5353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5353}, the value of \mdline{5353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.cookie}}}\mdline{5353} will be unset.%mdk + +%mdk-data-line={5355} +\mdline{5355}If a P4Runtime server supports both \mdline{5355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5355} as well as +returning the \mdline{5356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5356}, there should be read-write symmetry between +\mdline{5357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5357} and \mdline{5357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5357} RPCs.%mdk + +%mdk-data-line={5359} +\section{\mdline{5359}16.\hspace*{0.5em}\mdline{5359}P4Runtime Stream Messages}\label{sec-p4runtime-stream-messages}%mdk%mdk + +%mdk-data-line={5361} +\subsection{\mdline{5361}16.1.\hspace*{0.5em}\mdline{5361}Packet I/O}\label{sec-packet-i_o}%mdk%mdk + +%mdk-data-line={5363} +\noindent\mdline{5363}P4Runtime supports controller packet-in and packet-out by means of \mdline{5363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5363} +and \mdline{5364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5364} stream messages, respectively.%mdk + +%mdk-data-line={5366} +\mdline{5366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5366} messages are sent by the P4Runtime server to the client. Conversely, +\mdline{5367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5367} messages are sent by the client to the server. Any \mdline{5367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5367} +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a \mdline{5370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5370} message with the \mdline{5370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5370} field set to +report the error to the client. See the section on\mdline{5371}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{5372} for more information on \mdline{5372}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5372}.%mdk + +%mdk-data-line={5374} +\mdline{5374}As introduced in the\mdline{5374}~\mdref{sec-controller-packet-meta}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\mdline{5374} +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with \mdline{5376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5376}. The expected metadata is described +in the P4Info using the \mdline{5377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5377} messages.%mdk + +%mdk-data-line={5379} +\mdline{5379}Both \mdline{5379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5379} and \mdline{5379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5379} stream messages share the same fields and are +defined as follows:%mdk + +%mdk-data-line={5382} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5383} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Packet~sent~from~the~controller~to~the~switch.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketOut~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~Packet~sent~from~the~switch~to~the~controller.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketIn~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~PacketMetadata~\{\\ +~~{\mdcolor{darkgreen}//~This~refers~to~Metadata.id~coming~from~P4Info~ControllerPacketMetadata.}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~metadata\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5402} +\begin{itemize}%mdk + +%mdk-data-line={5402} +\item{} +%mdk-data-line={5402} +\mdline{5402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}payload}}}\mdline{5402} is used to carry the full packet content, including the headers.%mdk%mdk + +%mdk-data-line={5404} +\item{} +%mdk-data-line={5404} +\mdline{5404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5404} is a repeated field of \mdline{5404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{5404} messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +\mdline{5407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5407}. Indeed, when a P4Runtime client (or server) +generates a \mdline{5408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5408} (or \mdline{5408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5408}) message, it needs to populate the +\mdline{5409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5409} field with as many values as in \mdline{5409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{5409} +for the packet-out (or packet-in) case. Each \mdline{5410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata.value}}}\mdline{5410} is a +binary string and must conform to the\mdline{5411}~\mdref{sec-bytestrings}{Bytestrings}\mdline{5411} +requirements based on the corresponding P4Info +\mdline{5413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{5413} specification. If the \mdline{5413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5413} field +does not match the P4Info specification, the server must drop the \mdline{5414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5414} +message and may generate a \mdline{5415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5415} message with the \mdline{5415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5415} +field set to report the error to the client which issued the \mdline{5416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5416}. See +the section on\mdline{5417}~\mdref{sec-stream-error-reporting}{Stream Error Reporting}\mdline{5417} for more +information on \mdline{5418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5418}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5420} +\subsection{\mdline{5420}16.2.\hspace*{0.5em}\mdline{5420}Client Arbitration Update}\label{sec-client-arbitration-update}%mdk%mdk + +%mdk-data-line={5422} +\noindent\mdline{5422}P4Runtime\mdline{5422}'\mdline{5422}s client arbitration mechanism ensures that only the current primary +can modify state on the switch, and that the \mdline{5423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5423} is monotonically +increasing. For example, the switch must finish all previous write operations +before before selecting a different primary, and must only accept write requests +from the current primary.%mdk + +%mdk-data-line={5428} +\mdline{5428}As explained earlier in this document, the controller uses the \mdline{5428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5428} +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via \mdline{5430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5430} RPC), +it needs to start a controller session and become a \mdline{5431}\textquotedblleft{}primary\textquotedblright{}\mdline{5431}. To do so, the +controller first opens a bidirectional stream channel to the server via +\mdline{5433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5433} for each device and sends a \mdline{5433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5433} message. The +controller populates the \mdline{5434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5434} field in this message using +its \mdline{5435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5435} and \mdline{5435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5435} and the \mdline{5435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5435} of the device, as explained +in detail in the\mdline{5436}~\mdref{sec-client-arbitration-and-controller-replication}{Client Arbitration and Controller +Replication}\mdline{5437} +section. For any given \mdline{5438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role)}}}\mdline{5438}, the P4Runtime server keeps track +of the highest \mdline{5439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5439} that it has ever received. If a controller\mdline{5439}'\mdline{5439}s +\mdline{5440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5440} is equal to the highest \mdline{5440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5440} that the server has ever +received, that controller is the primary. All other controllers are backups. +Note that it is possible that all controllers are backups, and that there is no +primary. There can be at most one primary, because for any given +\mdline{5444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role)}}}\mdline{5444}, each connected controller has a unique \mdline{5444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5444}.%mdk + +%mdk-data-line={5446} +\mdline{5446}This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest \mdline{5447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5447} after such a restart. +However, across a\mdline{5448}~\mdref{sec-restarts}{full restart}\mdline{5448}, the \mdline{5448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5448} must be +reset. In fact, a full restart is the only way to reset the \mdline{5449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5449}.%mdk + +%mdk-data-line={5451} +\mdline{5451}The \mdline{5451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5451} message is defined as follows:%mdk + +%mdk-data-line={5453} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5454} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MasterArbitrationUpdate~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~The~role~for~which~the~primary~client~is~being~arbitrated.~For~use-cases}\\ +~~{\mdcolor{darkgreen}//~where~multiple~roles~are~not~needed,~the~controller~can~leave~this~unset,}\\ +~~{\mdcolor{darkgreen}//~implying~default~role~and~full~pipeline~access.}\\ +~~Role~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~The~stream~RPC~with~the~highest~election\_id~is~the~primary.~The~'primary'}\\ +~~{\mdcolor{darkgreen}//~controller~instance~populates~this~with~its~latest~election\_id.~Switch}\\ +~~{\mdcolor{darkgreen}//~populates~with~the~highest~election~ID~it~has~received~from~all~connected}\\ +~~{\mdcolor{darkgreen}//~controllers.}\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Switch~populates~this~with~OK~for~the~client~that~is~the~primary,~and}\\ +~~{\mdcolor{darkgreen}//~with~an~error~status~for~all~other~connected~clients~(at~every~primary}\\ +~~{\mdcolor{darkgreen}//~client~change).~The~controller~does~not~populate~this~field.}\\ +~~.google.{\bfseries{\mdcolor{navy}rpc}}.Status~status~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Role~\{\\ +~~{\mdcolor{darkgreen}//~Uniquely~identifies~this~role.}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Describes~the~role~configuration,~i.e.~what~operations,~P4~entities,}\\ +~~{\mdcolor{darkgreen}//~behaviors,~etc.~are~in~the~scope~of~a~given~role.~If~config~is~not~set}\\ +~~{\mdcolor{darkgreen}//~(default~case),~it~implies~all~P4~objects~and~control~behaviors~are~in}\\ +~~{\mdcolor{darkgreen}//~scope,~i.e.~full~pipeline~access.~The~format~of~this~message~is}\\ +~~{\mdcolor{darkgreen}//~out-of-scope~of~P4Runtime.}\\ +~~.google.protobuf.Any~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5483} +\noindent\mdline{5483}Note that the \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5483} field in the \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5483} message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a \mdline{5485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5485} message back to the controller, in which +it populates the \mdline{5486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5486} message using the \mdline{5486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5486}, +\mdline{5487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5487}, and \mdline{5487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5487} it previously received from the controller. The server +also populates the \mdline{5488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5488} field in the \mdline{5488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5488} according to +the rules in an\mdline{5489}~\mdref{sec-arbitration-updates}{earlier section}\mdline{5489}.%mdk + +%mdk-data-line={5491} +\mdline{5491}The sender need not specify an \mdline{5491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5491}. If the \mdline{5491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5491} is not +specified, the sender\mdline{5492}'\mdline{5492}s \mdline{5492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5492} is considered lower than any +\mdline{5493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5493}, and the sender will thus never become primary. This way, a +controller can choose to be a backup controller, in order to avoid +\mdline{5495}\textquotedblleft{}flapping\textquotedblright{}\mdline{5495} (if a backup controller connects to the switch shortly before the +actual primary controller, therefore becoming primary temporarily).%mdk + +%mdk-data-line={5499} +\subsection{\mdline{5499}16.3.\hspace*{0.5em}\mdline{5499}Digest Messages}\label{sec-digest-messages}%mdk%mdk + +%mdk-data-line={5501} +\noindent\mdline{5501}See the\mdline{5501}~\mdref{sec-digestentry}{DigestEntry}\mdline{5501} section.%mdk + +%mdk-data-line={5503} +\subsection{\mdline{5503}16.4.\hspace*{0.5em}\mdline{5503}Table Idle Timeout Notification}\label{sec-table-idle-timeout-notification}%mdk%mdk + +%mdk-data-line={5505} +\noindent\mdline{5505}When a table supports idle timeout (as per the P4Info message), the primary +client can specify a TTL value for each entry in the table (see +\mdline{5507}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{5507} section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an \mdline{5509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5509} message on the +\mdline{5510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5510} bidirectional stream to the primary client. The primary client +can then take the action of its choice, most likely remove the idle entry.%mdk + +%mdk-data-line={5513} +\mdline{5513}The \mdline{5513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5513} Protobuf message has the following fields:%mdk + +%mdk-data-line={5515} +\begin{itemize}%mdk + +%mdk-data-line={5515} +\item{} +%mdk-data-line={5515} +\mdline{5515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}timestamp}}}\mdline{5515}: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server\mdline{5516}'\mdline{5516}s local clock.%mdk%mdk + +%mdk-data-line={5518} +\item{} +%mdk-data-line={5518} +\mdline{5518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5518}: a repeated field of entries which have expired. Each individual +entry is identified by a single \mdline{5519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5519} message. For each \mdline{5519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5519}, +the \mdline{5520}\emph{key}\mdline{5520} fields (\mdline{5520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{5520}, \mdline{5520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{5520} and \mdline{5520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{5520}) must be set, along with +the \mdline{5521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{5521} field, the \mdline{5521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5521} field, and the +\mdline{5522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{5522} field. Other fields may be set by the server but should be +ignored by the client.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5525} +\noindent\mdline{5525}Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +\mdline{5527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5527} message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an \mdline{5532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5532} +message with an empty \mdline{5533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5533} repeated field.%mdk + +%mdk-data-line={5535} +\mdline{5535}After generating an idle notification, the P4Runtime server must \mdline{5535}\textquotedblleft{}reset\textquotedblright{}\mdline{5535} the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the primary client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle.%mdk + +%mdk-data-line={5542} +\mdline{5542}Here is a reasonable pseudo-code implementation for idle timeout for table +entries:%mdk + +%mdk-data-line={5545} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5546} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutStream~stream;\\ +\\ +scanning\_interval~=~{\mdcolor{purple}10}ms;\\ +\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~{\mdcolor{darkgreen}//~iterate~over~all~tables~which~support~idle~timeout}\\ +~~{\bfseries{\mdcolor{navy}for}}~(table~in~tables)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(!table.idle\_timeout\_supported)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~{\mdcolor{darkgreen}//~we~coalesce~all~idle~notifications~for~the~same~table~in~one}\\ +~~~~{\mdcolor{darkgreen}//~message}\\ +~~~~IdleTimeoutNotification~msg;\\ +~~~~{\mdcolor{darkgreen}//~read~time\_since\_last\_hit~from~device}\\ +~~~~entries~=~device.load\_table\_entries\_from\_hw(table);\\ +~~~~{\bfseries{\mdcolor{navy}for}}~(entry~in~entries)~\{\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.idle\_timeout~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~TTL}\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.time\_since\_last\_hit~\textless{}~entry.idle\_timeout)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~~~msg.table\_entry\_add(entry);\\ +~~~~~~entry.reset\_time\_since\_last\_hit();\\ +~~~~\}\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(msg.table\_entry\_size()~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~notifications}\\ +~~~~msg.set\_timestamp(now());\\ +~~~~stream.write(msg);\\ +~~\}\\ +~~sleep(scanning\_interval);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5573} +\subsection{\mdline{5573}16.5.\hspace*{0.5em}\mdline{5573}Architecture-Specific Notifications}\label{sec-architecture-specific-notifications}%mdk%mdk + +%mdk-data-line={5575} +\noindent\mdline{5575}P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on \mdline{5576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5576}, by including an \mdline{5576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5576} Protobuf field\mdline{5576}~[\mdcite{protoany}{31}]\mdline{5576} +named \mdline{5577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5577} in both \mdline{5577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5577} and \mdline{5577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5577}. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the\mdline{5579}~\mdref{sec-digestentry}{PSA \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}} +extern}\mdline{5580}. See section on\mdline{5580}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{5581} for more information.%mdk + +%mdk-data-line={5583} +\subsection{\mdline{5583}16.6.\hspace*{0.5em}\mdline{5583}Stream Error Reporting}\label{sec-stream-error-reporting}%mdk%mdk + +%mdk-data-line={5585} +\noindent\mdline{5585}The P4Runtime server can asynchronously report errors which occur when +processing \mdline{5586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5586} messages, using the \mdline{5586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5586} message field (of +type \mdline{5587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5587}) in \mdline{5587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5587}. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature.%mdk + +%mdk-data-line={5591} +\mdline{5591}The \mdline{5591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5591} message has the following fields:%mdk + +%mdk-data-line={5593} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5593} +\item\mdline{5593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5593}, which must be set to the appropriate canonical error code +\mdline{5594}[\mdcite{grpcstatuscodes}{34}]\mdline{5594}.%mdk + +%mdk-data-line={5595} +\item\mdline{5595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{5595}, an optional developer-facing error message describing the error.%mdk + +%mdk-data-line={5596} +\item\mdline{5596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5596} and \mdline{5596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5596}, which are optional and can be used by vendors to provide +additional details on the error. \mdline{5597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5597} is a numeric error code drawn from a +vendor\mdline{5598}'\mdline{5598}s chosen error \mdline{5598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5598}.%mdk + +%mdk-data-line={5599} +\item\mdline{5599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5599}, which is a Protobuf \mdline{5599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5599} used to help the client identify which +\mdline{5600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5600} triggered the error. The server is required to set the +appropriate field in the \mdline{5601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5601} so that the client can identify which type +of stream message is responsible for the error (\mdline{5602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5602}, +\mdline{5603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_list\_ack}}}\mdline{5603} or \mdline{5603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5603}), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid \mdline{5605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5605} message from the +client, the \mdline{5606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5606} field (of type \mdline{5606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError)}}}\mdline{5606} should be set in +the \mdline{5607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5607} \mdline{5607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5607}, and the server may additionally set the \mdline{5607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5607} +field in the \mdline{5608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError}}}\mdline{5608} sub-message (by copying it from the invalid +\mdline{5609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5609} message received on the stream channel) so that the client can +know exactly what packet-out triggered the error.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5612} +\noindent\mdline{5612}The appropriate canonical error code\mdline{5612}~[\mdcite{grpcstatuscodes}{34}]\mdline{5612} should be used when +populating the \mdline{5613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5613} field. For example:%mdk + +%mdk-data-line={5615} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5615} +\item\mdline{5615}if a controller is not allowed to send a \mdline{5615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5615} message under its +current role definition, the code should be set to \mdline{5616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5616}.%mdk + +%mdk-data-line={5617} +\item\mdline{5617}if the \mdline{5617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5617} repeated field in \mdline{5617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5617} does not match the P4Info +definition, the code should be set to \mdline{5618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5618}. It may be useful +for the server to set the \mdline{5619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5619} field in this case, so that the client +can find out which set of metadata fields triggered the error.%mdk + +%mdk-data-line={5621} +\item\mdline{5621}if the \mdline{5621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{5621} field in \mdline{5621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{5621} does not match any \mdline{5621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{5621} entry +in P4Info, the code should be set to \mdline{5622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5622}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5624} +\noindent\mdline{5624}The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, \mdline{5625}e.g.\mdline{5625} because of a +burst of \mdline{5626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5626} messages.%mdk + +%mdk-data-line={5628} +\mdline{5628}Note that client arbitration errors are never reported using the \mdline{5628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5628} +message. Invalid \mdline{5629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5629} messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section\mdline{5631}~\mdref{sec-arbitration-updates}{5.3}\mdline{5631}.%mdk + +%mdk-data-line={5633} +\subsubsection{\mdline{5633}16.6.1.\hspace*{0.5em}\mdline{5633}Examples of \mdline{5633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5633} Messages}\label{sec-examples-of-streamerror-messages}%mdk%mdk + +%mdk-data-line={5635} +\begin{itemize}%mdk + +%mdk-data-line={5635} +\item{} +%mdk-data-line={5635} +\mdline{5635}\textbf{Malformed packet-out metadata.}\mdline{5635} If the server receives a \mdline{5635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5635} +message with a \mdline{5636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5636} field with id 7 which is not included in the P4Info +\mdline{5637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5637} message for \mdline{5637}\textquotedblleft{}packet\_out\textquotedblright{}\mdline{5637}, the server may send the +following \mdline{5638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5638} back to the client:%mdk + +%mdk-data-line={5639} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5640} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Unknown~metadata~field~id~7.}{\mdcolor{maroon}"}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~copied~from~the~PacketOut~message~received~from~the~client}\\ +~~~packet\_out~\{\\ +~~~~~payload:~...\\ +~~~~~metadata~\{\\ +~~~~~~~id:~{\mdcolor{purple}7}\\ +~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}I\_should\_not\_be\_here}{\mdcolor{maroon}"}\\ +~~~~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~~\}\\ +~~~~~{\mdcolor{darkgreen}\#~more~metadata}\\ +~~~\}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={5658} +\item{} +%mdk-data-line={5658} +\mdline{5658}\textbf{Packet-out which exceeds the MTU.}\mdline{5658} If the server receives a \mdline{5658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5658} +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following \mdline{5661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5661}:%mdk + +%mdk-data-line={5662} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5663} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Packet~exceeds~the~MTU~for~port.}{\mdcolor{maroon}"}\\ +~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendor1}{\mdcolor{maroon}"}\\ +~code:~{\mdcolor{purple}123}~~{\mdcolor{darkgreen}\#~MTU\_EXCEEDED}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~we~do~not~set~the~packet\_out~field~as~it~does~not~provide~any}\\ +~~~{\mdcolor{darkgreen}\#~extra~information~to~the~client}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5675} +\section{\mdline{5675}17.\hspace*{0.5em}\mdline{5675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5675} RPC}\label{sec-capabilities-rpc}%mdk%mdk + +%mdk-data-line={5677} +\noindent\mdline{5677}The \mdline{5677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5677} RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the \mdline{5679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesRequest}}}\mdline{5679} message is empty and the \mdline{5679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5679} +message only includes the \mdline{5680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_api\_version}}}\mdline{5680} string field. This field must +be set to the full semantic version string\mdline{5681}~[\mdcite{semver}{27}]\mdline{5681} corresponding to the +version of the P4Runtime API implemented by the server, \mdline{5682}e.g.\mdline{5682} \mdline{5682}\textquotedblleft{}1.1.0-rc.1\textquotedblright{}\mdline{5682}.%mdk + +%mdk-data-line={5684} +\mdline{5684}Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three\mdline{5685}~\mdref{sec-batch-atomicity}{atomicity +modes}\mdline{5686} for \mdline{5686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5686} batches, two of them being +optional. In the future we may decide to leverage the \mdline{5687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5687} +message to enable the server to report to the client which subset of these +atomicity modes is supported.%mdk + +%mdk-data-line={5691} +\mdline{5691}The semantic version string included in \mdline{5691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5691} can be used by +the client to determine which exact feature set is implemented by the server, +since\mdline{5693}~\mdref{sec-p4runtime-versioning}{minor releases}\mdline{5693} may introduce new +functionality. However, because the \mdline{5694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5694} RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (\mdline{5696}i.e.\mdline{5696} an \mdline{5696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5696} error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0).%mdk + +%mdk-data-line={5700} +\section{\mdline{5700}18.\hspace*{0.5em}\mdline{5700}Portability Considerations}\label{sec-portability-considerations}%mdk%mdk + +%mdk-data-line={5702} +\subsection{\mdline{5702}18.1.\hspace*{0.5em}\mdline{5702}PSA Metadata Translation}\label{sec-psa-metadata-translation}%mdk%mdk + +%mdk-data-line={5704} +\noindent\mdline{5704}The \mdline{5704}\emph{Portable Switch Architecture}\mdline{5704} (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +\mdline{5708}[\mdcite{psatranslation}{24}]\mdline{5708}. For such metadata, a translation between the controller\mdline{5708}'\mdline{5708}s +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the \mdline{5712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5712} annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture.%mdk + +%mdk-data-line={5716} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={5717} +\noindent\mdline{5717}\includegraphics[keepaspectratio=true,height=7cm]{build/psa-metadata-translation}{}\mdline{5717}%mdk + +%mdk-data-line={5718} +\mdhr{}%mdk + +%mdk-data-line={5719} +\noindent\mdline{5719}\mdcaption{\textbf{Figure~\mdcaptionlabel{8}.}~\mdcaptiontext{P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdcenter}\label{fig-psa-metadata-translation}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={5723} +\noindent\mdline{5723}Figure\mdline{5723}~\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}}\mdline{5723} illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller\mdline{5729}'\mdline{5729}s 32 bit port +numbers to a target\mdline{5730}'\mdline{5730}s 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch.%mdk + +%mdk-data-line={5734} +\subsubsection{\mdline{5734}18.1.1.\hspace*{0.5em}\mdline{5734}Translation of Port Numbers}\label{sec-translation-of-port-numbers}%mdk%mdk + +%mdk-data-line={5736} +\noindent\mdline{5736}In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller\mdline{5737}'\mdline{5737}s space and the PSA device\mdline{5737}'\mdline{5737}s space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +\mdline{5741}\mdref{sec-user-defined-types}{user-defined P4 types}\mdline{5741}, namely \mdline{5741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5741} and +\mdline{5742}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5742}, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in \mdline{5745}\emph{psa.p4}\mdline{5745} for +the PSA device in Switch 1.%mdk + +%mdk-data-line={5748} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5749} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_t;\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortIdInHeader\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~PortIdInHeader\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5755} +\noindent\mdline{5755}The first argument to the \mdline{5755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5755} annotation is a URI that +indicates to the P4Runtime server which numerical mapping\mdline{5756} \mdline{5756}\textemdash{}\mdline{5756} provided by the +out-of-band switch configuration mechanism\mdline{5757} \mdline{5757}\textemdash{}\mdline{5757} to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports).%mdk + +%mdk-data-line={5761} +\mdline{5761}An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows:%mdk + +%mdk-data-line={5767} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5768} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}enum}}~SdnPort~\{\\ +~~SDN\_PORT\_UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +\\ +~~{\mdcolor{darkgreen}//~SDN~ports~are~numbered~starting~from~1.}\\ +~~SDN\_PORT\_MIN~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\\ +~~{\mdcolor{darkgreen}//~The~maximum~value~of~an~SDN~port~(physical~or~logical).}\\ +~~SDN\_PORT\_MAX~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffeff};\\ +\\ +~~{\mdcolor{darkgreen}//~Reserved~SDN~port~numbers~(0xfffffff0~-~0xffffffff)}\\ +\\ +~~SDN\_PORT\_RECIRCULATE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffa};\\ +~~SDN\_PORT\_CPU~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffd};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5784} +\noindent\mdline{5784}The switch config will map \mdline{5784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_RECIRCULATE}}}\mdline{5784} and \mdline{5784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_CPU}}}\mdline{5784} \mdline{5784}\textemdash{}\mdline{5784} as well +as any SDN port number corresponding to a \mdline{5785}\textquotedblleft{}regular\textquotedblright{}\mdline{5785} front-panel port\mdline{5785} \mdline{5785}\textemdash{}\mdline{5785} to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation.%mdk + +%mdk-data-line={5789} +\mdline{5789}The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs.%mdk + +%mdk-data-line={5792} +\subsubsection{\mdline{5792}18.1.2.\hspace*{0.5em}\mdline{5792}Translation of Packet-IO Header Fields}\label{sec-translation-of-packet-io-header-fields}%mdk%mdk + +%mdk-data-line={5794} +\noindent\mdline{5794}Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:.%mdk + +%mdk-data-line={5797} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5798} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~PortIdInHeader\_t~egress\_port;\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~PortIdInHeader\_t~ingress\_port;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5809} +\noindent\mdline{5809}The header-level annotation \mdline{5809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5809} is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (\mdline{5813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5813}) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI\mdline{5817} \mdline{5817}\textemdash{}\mdline{5817} first argument to the \mdline{5817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5817} +annotation). Any subsequent reference to the \mdline{5818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5818} field in the +data plane will use the translated value. \mdline{5819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5819} is used in the +header definition instead of \mdline{5820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5820} to guarantee byte-aligned headers in +case this is required by the target.%mdk + +%mdk-data-line={5823} +\mdline{5823}A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target\mdline{5825}'\mdline{5825}s PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the \mdline{5827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ingress\_port}}}\mdline{5827} field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller.%mdk + +%mdk-data-line={5833} +\subsubsection{\mdline{5833}18.1.3.\hspace*{0.5em}\mdline{5833}Translation of Match Fields}\label{sec-translation-of-match-fields}%mdk%mdk + +%mdk-data-line={5835} +\noindent\mdline{5835}Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table\mdline{5836}'\mdline{5836}s match key as shown in the example below:%mdk + +%mdk-data-line={5838} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5839} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~istd.ingress\_port:~exact;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~ingress~port}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5849} +\noindent\mdline{5849}Table \mdline{5849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5849} has an exact match on PSA standard metadata ingress port +(\mdline{5850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}istd.ingress\_port}}}\mdline{5850}). Since the field is of type \mdline{5850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5850}, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in \mdline{5853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5853} from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table \mdline{5858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5858} is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values.%mdk + +%mdk-data-line={5862} +\mdline{5862}Note that it may be infeasible to translate the value-mask pair for ternary +matches: \mdline{5863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5863}, \mdline{5863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5863} or \mdline{5863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5863} match kinds. The P4Runtime server may +require that for these match kinds the port match be either \mdline{5864}\emph{de facto}\mdline{5864} \mdline{5864}\textquotedblleft{}exact\textquotedblright{}\mdline{5864} +(0xffffffff mask for \mdline{5865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5865}, prefix-length of 32 for \mdline{5865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5865}, or same low and +high bounds for \mdline{5866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5866}) or \mdline{5866}\textquotedblleft{}don't care\textquotedblright{}\mdline{5866}.%mdk + +%mdk-data-line={5868} +\subsubsection{\mdline{5868}18.1.4.\hspace*{0.5em}\mdline{5868}Translation of Action Parameters}\label{sec-translation-of-action-parameters}%mdk%mdk + +%mdk-data-line={5870} +\noindent\mdline{5870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5870} type parameters can be part of a P4 action definition as shown in the +example below:%mdk + +%mdk-data-line={5873} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5874} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.h.f:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~a;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5888} +\noindent\mdline{5888}The controller may write entries in table \mdline{5888}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5888} with action \mdline{5888}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5888} to set the egress +port as shown in the P4 code above. The action parameter \mdline{5889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5889} is of type +\mdline{5890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5890}, which leads to a 32-bit bitwidth for \mdline{5890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5890} being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device.%mdk + +%mdk-data-line={5896} +\subsubsection{\mdline{5896}18.1.5.\hspace*{0.5em}\mdline{5896}Port Translation for PSA Extern APIs}\label{sec-port-translation-for-psa-extern-apis}%mdk%mdk + +%mdk-data-line={5898} +\noindent\mdline{5898}The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The \mdline{5903}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{5903} +field is of type \mdline{5904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{5904} to carry the SDN representation of the port being +watched. The P4Runtime server will translate the given watch port into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device.%mdk + +%mdk-data-line={5909} +\mdline{5909}The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type \mdline{5911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5911} to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane.%mdk + +%mdk-data-line={5915} +\subsubsection{\mdline{5915}18.1.6.\hspace*{0.5em}\mdline{5915}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}\label{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}%mdk%mdk + +%mdk-data-line={5917} +\noindent\mdline{5917}P4Runtime supports using a translated value (\mdline{5917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5917} or any other translated +type for which the underlying built-in type is \mdline{5918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5918}) as an index to a +register, indirect counter, or indirect meter.%mdk + +%mdk-data-line={5921} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5922} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~counter~entry~type~}{\mdcolor{darkgreen}*/},~PortId\_t~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~index~type~}{\mdcolor{darkgreen}*/}\textgreater{}(\\ +~~{\mdcolor{purple}32}w1024,~PSA\_CounterType\_t.PACKETS)~counter;\\ +{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +~~counter.count(p);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5930} +\noindent\mdline{5930}This P4 Counter declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={5933} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5934} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counters~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x12000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}counter}{\mdcolor{maroon}"}\\ +~~\}\\ +~~spec~\{\\ +~~~~unit:~PACKETS\\ +~~\}\\ +~~index\_type\_name~\{\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5948} +\noindent\mdline{5948}The controller may read and write counter values from indexed counter \mdline{5948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter}}}\mdline{5948} +using SDN port numbers as indices, and not device-specific port numbers. The +\mdline{5950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{5950} field in the P4Info message is a signal to the P4Runtime +server that translation is required.%mdk + +%mdk-data-line={5953} +\section{\mdline{5953}19.\hspace*{0.5em}\mdline{5953}P4Runtime Versioning}\label{sec-p4runtime-versioning}%mdk%mdk + +%mdk-data-line={5955} +\noindent\mdline{5955}P4Runtime follows the Google guidelines for versioning cloud APIs +\mdline{5956}[\mdcite{apiversioning}{6}]\mdline{5956}. We use a \mdline{5956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR.MINOR.PATCH}}}\mdline{5956} style version number scheme and +we increment the:%mdk + +%mdk-data-line={5959} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5959} +\item\mdline{5959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5959} version when we make incompatible API changes,%mdk + +%mdk-data-line={5960} +\item\mdline{5960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MINOR}}}\mdline{5960} version when we add functionality in a backwards-compatible manner,%mdk + +%mdk-data-line={5961} +\item\mdline{5961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PATCH}}}\mdline{5961} version when we make backwards-compatible bug fixes.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5963} +\noindent\mdline{5963}The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is \mdline{5965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1}}}\mdline{5965} and the package +name for P4Info is \mdline{5966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1}}}\mdline{5966}. Even though \mdline{5966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5966} and \mdline{5966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5966} are two +different Protobuf packages, \mdline{5967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5967} depends on \mdline{5967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5967} and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence.%mdk + +%mdk-data-line={5971} +\mdline{5971}As recommended in\mdline{5971}~[\mdcite{apiversioning}{6}]\mdline{5971}, we may consider using pre-GA release +suffixes (such as \mdline{5972}\emph{alpha}\mdline{5972} or \mdline{5972}\emph{beta}\mdline{5972}) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1).%mdk + +%mdk-data-line={5976} +\mdline{5976}Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner.\mdline{5977}~[\mdcite{apiversioningbackwardscompatibility}{7}]\mdline{5977} describes +what constitute a backwards-compatible change. We expect \mdline{5978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5978} version bumps +to be a \mdline{5979}\textbf{rare}\mdline{5979} event.%mdk + +%mdk-data-line={5981} +\mdline{5981}Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor\mdline{5986} \mdline{5986}+ patch version numbers in future releases.%mdk + +%mdk-data-line={5988} +\mdline{5988}All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository\mdline{5989}~[\mdcite{p4runtimerepo}{15}]\mdline{5989} and the version label follows +semantic versioning rules\mdline{5990}~[\mdcite{semver}{27}]\mdline{5990}.%mdk + +%mdk-data-line={5992} +\section{\mdline{5992}20.\hspace*{0.5em}\mdline{5992}Extending P4Runtime for non-PSA Architectures}\label{sec-extending-p4runtime}%mdk%mdk + +%mdk-data-line={5994} +\noindent\mdline{5994}P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place.%mdk + +%mdk-data-line={6002} +\mdline{6002}When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names:%mdk + +%mdk-data-line={6006} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6006} +\item\mdline{6006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/config/\textless{}major~version\textgreater{}/p4info.proto}}}\mdline{6006}%mdk + +%mdk-data-line={6007} +\item\mdline{6007}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/\textless{}major~version\textgreater{}/p4runtime.proto}}}\mdline{6007}%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6009} +\noindent\mdline{6009}We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they \mdline{6010}\textquotedblleft{}extend\textquotedblright{}\mdline{6010}.%mdk + +%mdk-data-line={6012} +\mdline{6012}For the remainder of this section, we will refer to these two files as +\mdline{6013}\emph{p4info-ext}\mdline{6013} and \mdline{6013}\emph{p4runtime-ext}\mdline{6013} respectively.%mdk + +%mdk-data-line={6015} +\subsection{\mdline{6015}20.1.\hspace*{0.5em}\mdline{6015}Extending P4Runtime for Architecture-Specific Externs}\label{sec-extending-p4runtime-for-architecture-specific-externs}%mdk%mdk + +%mdk-data-line={6017} +\noindent\mdline{6017}Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both \mdline{6018}\emph{p4info-ext}\mdline{6018} and +\mdline{6019}\emph{p4runtime-ext}\mdline{6019}. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example:%mdk + +%mdk-data-line={6023} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6024} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~T~must~be~a~bit\textless{}W\textgreater{}~type,~it~indicates~the~width~of~each~counter~cell}\\ +{\bfseries{\mdcolor{navy}extern}}~MyNewPacketCounter\textless{}T\textgreater{}~\{\\ +~~counter({\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~size);\\ +~~increment({\bfseries{\mdcolor{navy}in}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~index);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6031} +\subsubsection{\mdline{6031}20.1.1.\hspace*{0.5em}\mdline{6031}Extending the P4Info message}\label{sec-extending-the-p4info-message}%mdk%mdk + +%mdk-data-line={6033} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6033} +\item\mdline{6033}Id prefixes \mdline{6033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0x81}}}\mdline{6033} through \mdline{6033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfe}}}\mdline{6033} are reserved for architecture-specific +externs. It is recommended that \mdline{6034}\emph{p4info-ext}\mdline{6034} include a \mdline{6034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Ids}}}\mdline{6034} message based +on the one in p4info.proto that the P4 compiler can refer to when\mdline{6035}~\mdref{sec-id-allocation}{assigning +IDs}\mdline{6036} to each extern instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6038} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6039} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~P{\mdcolor{purple}4}Ids~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Prefix~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~MY\_NEW\_PACKET\_COUNTER~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0x81};\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6047} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6047} +\item\mdline{6047}\emph{p4info-ext}\mdline{6047} should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +\mdline{6051}\mdref{sec-p4info-extern}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ExternInstance}}}}\mdline{6051} message as the \mdline{6051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{6051} +field, which is of type \mdline{6052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6052}~[\mdcite{protoany}{31}]\mdline{6052}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6054} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6055} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\mdcolor{darkgreen}//~corresponds~to~the~T~type~parameter~in~the~P4~extern~definition}\\ +~~p4.config.v1.P{\mdcolor{purple}4}DataTypeSpec~type\_spec~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~constructor~argument}\\ +~~{\bfseries{\mdcolor{navy}int64}}~size~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6063} +\subsubsection{\mdline{6063}20.1.2.\hspace*{0.5em}\mdline{6063}Extending the P4Runtime Service}\label{sec-extending-the-p4runtime-service}%mdk%mdk + +%mdk-data-line={6065} +\noindent\mdline{6065}Just like \mdline{6065}\emph{p4info-ext}\mdline{6065}, \mdline{6065}\emph{p4runtime-ext}\mdline{6065} should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an\mdline{6070}~\mdref{sec-extern-entry}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\mdline{6070} message generated by the +P4Runtime client.%mdk + +%mdk-data-line={6073} +\mdline{6073}Here is a possible Protobuf message for our \mdline{6073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyNewPacketCounter}}}\mdline{6073} P4 extern:%mdk + +%mdk-data-line={6074} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6075} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~This~message~enables~reading~/~writing~data~to~the~counter~at~the~provided}\\ +{\mdcolor{darkgreen}//~index}\\ +{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~p4.v1.P{\mdcolor{purple}4}Data~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6083} +\noindent\mdline{6083}P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an \mdline{6084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6084} Protobuf field\mdline{6084}~[\mdcite{protoany}{31}]\mdline{6084} named \mdline{6084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6084} +in both \mdline{6085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{6085} and +\mdline{6086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{6086}. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in \mdline{6088}\emph{p4runtime-ext}\mdline{6088} and embed instances of these messages in +\mdline{6089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{6089} and \mdline{6089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{6089} as appropriate.%mdk + +%mdk-data-line={6091} +\subsection{\mdline{6091}20.2.\hspace*{0.5em}\mdline{6091}Architecture-Specific Table Extensions}\label{sec-architecture-specific-table-extensions}%mdk%mdk + +%mdk-data-line={6093} +\subsubsection{\mdline{6093}20.2.1.\hspace*{0.5em}\mdline{6093}New Match Types}\label{sec-new-match-types}%mdk%mdk + +%mdk-data-line={6095} +\noindent\mdline{6095}An architecture may introduce new table match types\mdline{6095}~[\mdcite{p4matchtypes}{12}]\mdline{6095}. P4Runtime +accounts for this by providing the following hooks:%mdk + +%mdk-data-line={6098} +\begin{itemize}%mdk + +%mdk-data-line={6098} +\item{} +%mdk-data-line={6098} +\mdline{6098}The \mdline{6098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{6098} field in \mdline{6098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{6098} (p4info.proto) is a \mdline{6098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6098} +which can be either one of the default match types (\mdline{6099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{6099}, \mdline{6099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{6099}, \mdline{6099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{6099}, +\mdline{6100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{6100}, or \mdline{6100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6100}) or an architecture-specific match type encoded as a +string.%mdk%mdk + +%mdk-data-line={6103} +\item{} +%mdk-data-line={6103} +\mdline{6103}The \mdline{6103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{6103} field in \mdline{6103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6103} (p4runtime.proto) is a +\mdline{6104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6104} which includes an \mdline{6104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6104} Protobuf message\mdline{6104}~[\mdcite{protoany}{31}]\mdline{6104} field +(\mdline{6105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6105}). \mdline{6105}\emph{p4info-ext}\mdline{6105} should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in \mdline{6108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6108} as the +\mdline{6109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6109} field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6112} +\subsubsection{\mdline{6112}20.2.2.\hspace*{0.5em}\mdline{6112}New Table Properties}\label{sec-new-table-properties}%mdk%mdk + +%mdk-data-line={6114} +\noindent\mdline{6114}An architecture may introduce additional table properties +\mdline{6115}[\mdcite{p4tableproperties}{30}]\mdline{6115}. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +\mdline{6117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Table}}}\mdline{6117} message includes the \mdline{6117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{6117} \mdline{6117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6117} Protobuf +field\mdline{6118}~[\mdcite{protoany}{31}]\mdline{6118}. At the moment, there is not any mechanism to extend the +\mdline{6119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.TableEntry}}}\mdline{6119} message based on the value of architecture-specific table +properties, but we may include on in future versions of the API.%mdk + +%mdk-data-line={6122} +\section{\mdline{6122}21.\hspace*{0.5em}\mdline{6122}Known Limitations of Current P4Runtime Version}\label{sec-known-limitations-of-current-p4runtime-version}%mdk%mdk + +%mdk-data-line={6124} +\begin{itemize}%mdk + +%mdk-data-line={6124} +\item{} +%mdk-data-line={6124} +\mdline{6124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6124}, action \mdline{6124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6124}, and controller packet metadata fields only +support unsigned bitstrings, \mdline{6125}i.e.\mdline{6125} values of one of the following types (not +the more general \mdline{6126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{6126}):%mdk + +%mdk-data-line={6127} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6127} +\item\mdline{6127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6127}%mdk + +%mdk-data-line={6128} +\item\mdline{6128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6128}. Note that as far as the \mdline{6128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Info}}}\mdline{6128} message contents and +thus controller software is concerned, such fields of type \mdline{6129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6129} +will be indistinguishable from those that have been declared with +type \mdline{6131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6131}. P4Runtime server software will automatically +perform any conversion needed between the type \mdline{6132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6132} values in +P4Runtime messages and the data plane representation.%mdk + +%mdk-data-line={6134} +\item\mdline{6134}an \mdline{6134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{6134} with underlying type \mdline{6134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6134}%mdk + +%mdk-data-line={6135} +\item\mdline{6135}a \mdline{6135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6135} or \mdline{6135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6135} with an underlying type that is one of the above (or +in general a \mdline{6136}\textquotedblleft{}chain\textquotedblright{}\mdline{6136} of \mdline{6136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6136} and/or \mdline{6136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6136} that eventually ends with +one of the types above)%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6139} +\item{} +%mdk-data-line={6139} +\mdline{6139}Support for PSA Random \mdline{6139}\&\mdline{6139} Timestamp externs is postponed to a future minor +version update.%mdk%mdk + +%mdk-data-line={6142} +\item{} +%mdk-data-line={6142} +\mdline{6142}P4Info does not include information about which of a table\mdline{6142}'\mdline{6142}s actions execute +which direct resource(s).%mdk%mdk + +%mdk-data-line={6145} +\item{} +%mdk-data-line={6145} +\mdline{6145}The default action for indirect match tables is restricted to a \mdline{6145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\\ +NoAction}}}\mdline{6146} known at compile-time.%mdk%mdk + +%mdk-data-line={6148} +\item{} +%mdk-data-line={6148} +\mdline{6148}There is no mechanism for changing the value of the \mdline{6148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{6148} +table property at runtime.%mdk%mdk + +%mdk-data-line={6151} +\item{} +%mdk-data-line={6151} +\mdline{6151}There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor\mdline{6152} \mdline{6152}+ +patch version numbers.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6155} +\section{\mdline{6155}A.\hspace*{0.5em}\mdline{6155}Appendix}\label{sec-appendix}%mdk%mdk + +%mdk-data-line={6157} +\subsection{\mdline{6157}A.1.\hspace*{0.5em}\mdline{6157}Revision History}\label{sec-revision-history}%mdk%mdk + +%mdk-data-line={6159} +\subsubsection{\mdline{6159}A.1.1.\hspace*{0.5em}\mdline{6159}Changes in v1.3.0}\label{sec-changes-in-v130}%mdk%mdk + +%mdk-data-line={6161} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6161} +\item\mdline{6161}Add IANA assigned TCP port, 9559, to P4Runtime server discussion.%mdk + +%mdk-data-line={6162} +\item\mdline{6162}Move \mdline{6162}\textquotedblleft{}Security considerations\textquotedblright{}\mdline{6162} section to P4Runtime server discussion.%mdk + +%mdk-data-line={6163} +\item\mdline{6163}Deprecate \mdline{6163}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{6163} field (int32) in favor of \mdline{6163}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{6163} (bytes). This allows +using the watch port feature with the \mdline{6164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_translation}}}\mdline{6164} feature.%mdk + +%mdk-data-line={6165} +\item\mdline{6165}Replace master, slave, master arbitration with more inclusive language: +primary, backup, and client arbitration%mdk + +%mdk-data-line={6167} +\item\mdline{6167}Clarify that source locations for annotations are optional in the P4Info +message.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6170} +\subsubsection{\mdline{6170}A.1.2.\hspace*{0.5em}\mdline{6170}Changes in v1.2.0}\label{sec-changes-in-v120}%mdk%mdk + +%mdk-data-line={6172} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6172} +\item\mdline{6172}Add new \mdline{6172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6172} match kind. At the moment, \mdline{6172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6172} is only supported by +the v1model architecture\mdline{6173}~[\mdcite{v1model}{38}]\mdline{6173}, and not by PSA. It will eventually be +included in the core P4 language.%mdk + +%mdk-data-line={6175} +\item\mdline{6175}Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists.%mdk + +%mdk-data-line={6177} +\item\mdline{6177}Add a new \mdline{6177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6177} field of type \mdline{6177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{6177} to \mdline{6177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{6177}. This is more +flexible than the now deprecated \mdline{6178}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{6178} field.%mdk + +%mdk-data-line={6179} +\item\mdline{6179}Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +\mdline{6181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6181} annotation.%mdk + +%mdk-data-line={6182} +\item\mdline{6182}Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature.%mdk + +%mdk-data-line={6184} +\item\mdline{6184}Support using \mdline{6184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{6184} as the controller type in the \mdline{6184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6184} +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type.%mdk + +%mdk-data-line={6187} +\item\mdline{6187}Add optional P4 source locations to both structured and unstructured +annotations.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6190} +\subsubsection{\mdline{6190}A.1.3.\hspace*{0.5em}\mdline{6190}Changes in v1.1.0}\label{sec-changes-in-v110}%mdk%mdk + +%mdk-data-line={6192} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6192} +\item\mdline{6192}Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously.%mdk + +%mdk-data-line={6198} +\item\mdline{6198}Add \mdline{6198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{6198} field to stream messages sent by the server.%mdk + +%mdk-data-line={6199} +\item\mdline{6199}Add \mdline{6199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6199} RPC to query the P4Runtime API version implemented by the +server.%mdk + +%mdk-data-line={6201} +\item\mdline{6201}Support wildcard reads for multicast groups and clone sessions.%mdk + +%mdk-data-line={6202} +\item\mdline{6202}Support for modifying direct resources of const tables.%mdk + +%mdk-data-line={6203} +\item\mdline{6203}Support P4 user-defined types for Packet IO metadata fields.%mdk + +%mdk-data-line={6204} +\item\mdline{6204}Clarify consistency requirements for \mdline{6204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6204} and \mdline{6204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{6204} RPCs.%mdk + +%mdk-data-line={6205} +\item\mdline{6205}Add Appendix providing implementation advice for avoiding common pitfalls: + +%mdk-data-line={6206} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6206} +\item\mdline{6206}advice on setting gRPC Metadata Maximum Size%mdk + +%mdk-data-line={6207} +\item\mdline{6207}advice on setting gRPC Server Maximum Receive Message Size%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6208} +\item\mdline{6208}Clarify limitations on supported types for \mdline{6208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6208}, action \mdline{6208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6208}, and +Packet IO metadata fields.%mdk + +%mdk-data-line={6210} +\item\mdline{6210}Clarify that reading entire forwarding state with empty \mdline{6210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{6210} is not +supported.%mdk + +%mdk-data-line={6212} +\item\mdline{6212}Document that \mdline{6212}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6212} need only be supported when applied to +type declarations in P4.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6215} +\subsection{\mdline{6215}A.2.\hspace*{0.5em}\mdline{6215}P4 Annotations}\label{sec-p4-annotations}%mdk%mdk + +%mdk-data-line={6217} +\noindent\mdline{6217}Table\mdline{6217}~\mdref{tab-p4-annotations}{\mdcaptionlabel{7}}\mdline{6217} lists P4\mdline{6217}\mdsub{16}\mdline{6217} annotations introduced primarily for +the purpose of adding features for the P4Runtime API.%mdk + +%mdk-data-line={6220} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{6222} Annotation}}&\multicolumn{1}{|c|}{{\bfseries\mdline{6222} Description}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{6224} \mdline{6224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{6224}}&\multicolumn{1}{|l|}{\mdline{6224} See section\mdline{6224}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6224}}\\ +\multicolumn{1}{|l}{\mdline{6225} \mdline{6225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{6225}}&\multicolumn{1}{|l|}{\mdline{6225} See section\mdline{6225}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{6225}}\\ +\multicolumn{1}{|l}{\mdline{6226} \mdline{6226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{6226}}&\multicolumn{1}{|l|}{\mdline{6226} See section\mdline{6226}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6226}}\\ +\multicolumn{1}{|l}{\mdline{6227} \mdline{6227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6227}}&\multicolumn{1}{|l|}{\mdline{6227} See section\mdline{6227}~\mdref{sec-id-allocation}{6.3}\mdline{6227}}\\ +\multicolumn{1}{|l}{\mdline{6228} \mdline{6228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{6228}}&\multicolumn{1}{|l|}{\mdline{6228} See sections\mdline{6228}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{6228},\mdline{6228}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{6228}}\\ +\multicolumn{1}{|l}{\mdline{6229} \mdline{6229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{6229}}&\multicolumn{1}{|l|}{\mdline{6229} See section\mdline{6229}~\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1}\mdline{6229}}\\ +\multicolumn{1}{|l}{\mdline{6230} \mdline{6230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6230}}&\multicolumn{1}{|l|}{\mdline{6230} See sections\mdline{6230}~\mdref{sec-user-defined-types}{8.5.6}\mdline{6230},\mdline{6230}~\mdref{sec-translation-of-port-numbers}{18.1.1}\mdline{6230}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={6232} +\mdhr{}%mdk + +%mdk-data-line={6233} +\noindent\mdline{6233}\mdcaption{\textbf{Table~\mdcaptionlabel{7}.}~\mdcaptiontext{P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-annotations}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={6236} +\subsection{\mdline{6236}A.3.\hspace*{0.5em}\mdline{6236}A More Complex Value Set Example}\label{sec-value-set-example}%mdk%mdk + +%mdk-data-line={6238} +\noindent\mdline{6238}This section includes a more complex Value Set example, with multiple matches of +different kinds.%mdk + +%mdk-data-line={6241} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6242} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6251} +\noindent\mdline{6251}This P4 Value Set declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={6254} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6255} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6282} +\noindent\mdline{6282}A P4Runtime client can set the membership for this Value Set with \mdline{6282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6282} +messages similar to this one:%mdk + +%mdk-data-line={6285} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6286} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xac}~\}\\ +~~~~~~\}\\ +~~~~~~{\mdcolor{darkgreen}\#~match~for~field\_id~2~is~missing~=\textgreater{}~don't~care~match}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xdc}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~~~ternary~\{~value:~{\mdcolor{purple}0x88}~mask:~{\mdcolor{purple}8}f~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6320} +\subsection{\mdline{6320}A.4.\hspace*{0.5em}\mdline{6320}Guidelines for Implementations}\label{sec-guidelines-for-implementations}%mdk%mdk + +%mdk-data-line={6322} +\noindent\mdline{6322}This section contains practical advice for implementing P4Runtime clients and +servers.%mdk + +%mdk-data-line={6325} +\subsubsection{\mdline{6325}A.4.1.\hspace*{0.5em}\mdline{6325}gRPC Metadata Maximum Size}\label{sec-grpc-metadata-maximum-size}%mdk%mdk + +%mdk-data-line={6327} +\noindent\mdline{6327}In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the \mdline{6328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6328} gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the \mdline{6329}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6329} P4Runtime RPC. The \mdline{6329}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6329} RPC +returns an individual error for every item in a batch (see Section +\mdline{6331}\mdref{sec-write-rpc}{12}\mdline{6331}), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +\mdline{6333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{6333} error, without any of the individual errors.%mdk + +%mdk-data-line={6335} +\mdline{6335}To fix this problem, one can set the \mdline{6335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6335} option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it\mdline{6337}'\mdline{6337}s +limit, as only the receiving side\mdline{6338}'\mdline{6338}s limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every \mdline{6340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{6340}, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +\mdline{6342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}8192~+~MAX\_UPDATES\_PER\_WRITE~*~100}}}\mdline{6342} bytes of metadata.%mdk + +%mdk-data-line={6344} +\mdline{6344}For example, in C++, one can create a client channel as follows:%mdk + +%mdk-data-line={6345} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6346} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}~=~{\mdcolor{purple}100};\\ +::{\mdcolor{navy}grpc::}ChannelArguments~arguments;\\ +arguments{\bfseries{\mdcolor{navy}.}}SetInt({\mdcolor{teal}GRPC\_ARG\_MAX\_METADATA\_SIZE},~{\mdcolor{purple}8192}~+~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}*{\mdcolor{purple}100});\\ +{\bfseries{\mdcolor{navy}return}}~{\mdcolor{navy}grpc::}CreateCustomChannel(address,~credentials,~arguments);}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6352} +\subsubsection{\mdline{6352}A.4.2.\hspace*{0.5em}\mdline{6352}gRPC Server Maximum Receive Message Size}\label{sec-grpc-server-maximum-receive-message-size}%mdk%mdk + +%mdk-data-line={6354} +\noindent\mdline{6354}At the time of writing, the default maximum receive message size in gRPC is 4MB +\mdline{6355}\textemdash{}\mdline{6355} while the default maximum send message size is unlimited. This can be a +problem for the \mdline{6356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{6356} RPC, since for some targets the +binary \mdline{6357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6357} can exceed 4MB, in which case by default the P4Runtime +server would return an \mdline{6358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6358} error. To a lesser extent, this may +affect the \mdline{6359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6359} RPC as well, in case of extremely large batches.%mdk + +%mdk-data-line={6361} +\mdline{6361}To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of \mdline{6363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6363} for their target(s). This can be done by +setting the \mdline{6364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_receive\_message\_length}}}\mdline{6364} when building the gRPC server.%mdk + +%mdk-data-line={6366} +\mdline{6366}For example, in C++, one can set the maximum receive message size as follows:%mdk + +%mdk-data-line={6367} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6368} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE}~=~{\mdcolor{purple}128}~*~{\mdcolor{purple}1024}~*~{\mdcolor{purple}1024};~~{\mdcolor{darkgreen}//~128MB}\\ +::{\mdcolor{navy}grpc::}ServerBuilder~server\_builder;\\ +builder{\bfseries{\mdcolor{navy}.}}AddListeningPort({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});\\ +builder{\bfseries{\mdcolor{navy}.}}RegisterService({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});~~{\mdcolor{darkgreen}//~register~P4Runtime~service}\\ +builder{\bfseries{\mdcolor{navy}.}}SetMaxReceiveMessageSize({\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE});\\ +builder{\bfseries{\mdcolor{navy}.}}BuildAndStart();}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6376} +\noindent\mdline{6376}On the client side, we recommend that P4Runtime clients do not use \mdline{6376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6376} +batches larger than the default maximum receive message size (4MB)\mdline{6377} \mdline{6377}\textemdash{}\mdline{6377} in case +the server did not deem necessary to increase the default value\mdline{6378} \mdline{6378}\textemdash{}\mdline{6378}, unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB).%mdk + +%mdk-data-line={6383;build/P4Runtime-Spec-bib.bbl.mdk:1} +%mdk-data-line={6383;build/P4Runtime-Spec-bib.bbl.mdk:2} +\mdsetrefname{References}%mdk +{\mdbibindent{0}%mdk +\begin{thebibliography}{39}%mdk +\label{sec-bibliography}%mdk + +%mdk-data-line={references.bib:68} +\bibitem{p4spec}\mdbibitemlabel{{}[1]}\textquotedblleft{}$P4_{16}$ 1.2.1 Specification.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html}}.\label{p4spec}%mdk%mdk + +%mdk-data-line={references.bib:134} +\bibitem{rfc2698}\mdbibitemlabel{{}[2]}\textquotedblleft{}A Two Rate Three Color Marker.\textquotedblright{} \href{https://tools.ietf.org/html/rfc2698}{{\ttfamily https://\hspace{0pt}tools.\hspace{0pt}ietf.\hspace{0pt}org/\hspace{0pt}html/\hspace{0pt}rfc2698}}.\label{rfc2698}%mdk%mdk + +%mdk-data-line={references.bib:32} +\bibitem{p4complextypes}\mdbibitemlabel{{}[3]}\textquotedblleft{}Complex Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-p4-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}p4-\hspace{0pt}type}}.\label{p4complextypes}%mdk%mdk + +%mdk-data-line={references.bib:37} +\bibitem{protodefaults}\mdbibitemlabel{{}[4]}\textquotedblleft{}Default Values for Protobuf 3 ($proto3$) Fields.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23default}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}default}}.\label{protodefaults}%mdk%mdk + +%mdk-data-line={references.bib:78} +\bibitem{p4enums}\mdbibitemlabel{{}[5]}\textquotedblleft{}Enums in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-enum-types}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}enum-\hspace{0pt}types}}.\label{p4enums}%mdk%mdk + +%mdk-data-line={references.bib:119} +\bibitem{apiversioning}\mdbibitemlabel{{}[6]}\textquotedblleft{}Google Cloud APIs Versioning.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning}}.\label{apiversioning}%mdk%mdk + +%mdk-data-line={references.bib:124} +\bibitem{apiversioningbackwardscompatibility}\mdbibitemlabel{{}[7]}\textquotedblleft{}Google Cloud APIs Versioning - Backwards-Compatibility.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning\%23backwards_compatibility}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning\#\hspace{0pt}backwards\_\hspace{0pt}compatibility}}.\label{apiversioningbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:149} +\bibitem{grpcauth}\mdbibitemlabel{{}[8]}\textquotedblleft{}gRPC Authentication.\textquotedblright{} \href{https://grpc.io/docs/guides/auth.html}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}guides/\hspace{0pt}auth.\hspace{0pt}html}}.\label{grpcauth}%mdk%mdk + +%mdk-data-line={references.bib:7} +\bibitem{grpc}\mdbibitemlabel{{}[9]}\textquotedblleft{}gRPC Main Site.\textquotedblright{} \href{https://grpc.io}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io}}.\label{grpc}%mdk%mdk + +%mdk-data-line={references.bib:144} +\bibitem{grpcstreamc}\mdbibitemlabel{{}[10]}\textquotedblleft{}gRPC Streaming RPCs in C++.\textquotedblright{} \href{https://grpc.io/docs/tutorials/basic/c.html\%23streaming-rpcs}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}tutorials/\hspace{0pt}basic/\hspace{0pt}c.\hspace{0pt}html\#\hspace{0pt}streaming-\hspace{0pt}rpcs}}.\label{grpcstreamc}%mdk%mdk + +%mdk-data-line={references.bib:114} +\bibitem{p4newtypes}\mdbibitemlabel{{}[11]}\textquotedblleft{}Introducing New Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-newtype}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}newtype}}.\label{p4newtypes}%mdk%mdk + +%mdk-data-line={references.bib:139} +\bibitem{p4matchtypes}\mdbibitemlabel{{}[12]}\textquotedblleft{}Match Types in P4.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-match-kind-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}match-\hspace{0pt}kind-\hspace{0pt}type}}.\label{p4matchtypes}%mdk%mdk + +%mdk-data-line={references.bib:194} +\bibitem{p4annotations}\mdbibitemlabel{{}[13]}\textquotedblleft{}P4 Annotations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-annotations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}annotations}}.\label{p4annotations}%mdk%mdk + +%mdk-data-line={references.bib:174} +\bibitem{p4concurrency}\mdbibitemlabel{{}[14]}\textquotedblleft{}P4 Concurrency Model.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-concurrency}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}concurrency}}.\label{p4concurrency}%mdk%mdk + +%mdk-data-line={references.bib:1} +\bibitem{p4runtimerepo}\mdbibitemlabel{{}[15]}\textquotedblleft{}p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.\textquotedblright{} \href{https://github.com/p4lang/p4runtime}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4runtime}}.\label{p4runtimerepo}%mdk%mdk + +%mdk-data-line={references.bib:42} +\bibitem{pirepo}\mdbibitemlabel{{}[16]}\textquotedblleft{}p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.\textquotedblright{} \href{https://github.com/p4lang/PI}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}PI}}.\label{pirepo}%mdk%mdk + +%mdk-data-line={references.bib:109} +\bibitem{p4apiwgcharter}\mdbibitemlabel{{}[17]}\textquotedblleft{}P4.org API Working Group Charter.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4_API_WG_charter.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4\_\hspace{0pt}API\_\hspace{0pt}WG\_\hspace{0pt}charter.\hspace{0pt}html}}.\label{p4apiwgcharter}%mdk%mdk + +%mdk-data-line={references.bib:154} +\bibitem{p4actionannotations}\mdbibitemlabel{{}[18]}\textquotedblleft{}P4 Standard Annotations on Table Actions.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-action-anno}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}action-\hspace{0pt}anno}}.\label{p4actionannotations}%mdk%mdk + +%mdk-data-line={references.bib:73} +\bibitem{psa}\mdbibitemlabel{{}[19]}\textquotedblleft{}Portable Switch Architecture Specification (v1.1.0).\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html}}.\label{psa}%mdk%mdk + +%mdk-data-line={references.bib:189} +\bibitem{protooneofbackwardscompatibility}\mdbibitemlabel{{}[20]}\textquotedblleft{}Protobuf OneOf Backwards-Compatibility Issues.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23backwards-compatibility-issues}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}backwards-\hspace{0pt}compatibility-\hspace{0pt}issues}}.\label{protooneofbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:12} +\bibitem{proto}\mdbibitemlabel{{}[21]}\textquotedblleft{}Protocol Buffers Main Site.\textquotedblright{} \href{https://developers.google.com/protocol-buffers}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers}}.\label{proto}%mdk%mdk + +%mdk-data-line={references.bib:159} +\bibitem{psaactionselector}\mdbibitemlabel{{}[22]}\textquotedblleft{}PSA Action Selector.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-action-selector}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}action-\hspace{0pt}selector}}.\label{psaactionselector}%mdk%mdk + +%mdk-data-line={references.bib:169} +\bibitem{psaatomicityofcontrolplaneops}\mdbibitemlabel{{}[23]}\textquotedblleft{}PSA Atomicity of Control Plane Operations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-atomicity-of-control-plane-api-operations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}atomicity-\hspace{0pt}of-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}api-\hspace{0pt}operations}}.\label{psaatomicityofcontrolplaneops}%mdk%mdk + +%mdk-data-line={references.bib:179} +\bibitem{psatranslation}\mdbibitemlabel{{}[24]}\textquotedblleft{}PSA Data Plane vs Control Plane Types.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-data-plane-vs-control-plane-values}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}data-\hspace{0pt}plane-\hspace{0pt}vs-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}values}}.\label{psatranslation}%mdk%mdk + +%mdk-data-line={references.bib:164} +\bibitem{psaemptygroupactionappendix}\mdbibitemlabel{{}[25]}\textquotedblleft{}PSA Empty Group Action Appendix.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23appendix-empty-action-selector-groups}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}appendix-\hspace{0pt}empty-\hspace{0pt}action-\hspace{0pt}selector-\hspace{0pt}groups}}.\label{psaemptygroupactionappendix}%mdk%mdk + +%mdk-data-line={references.bib:58} +\bibitem{p4selectexpr}\mdbibitemlabel{{}[26]}\textquotedblleft{}Select Expressions in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-select}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}select}}.\label{p4selectexpr}%mdk%mdk + +%mdk-data-line={references.bib:129} +\bibitem{semver}\mdbibitemlabel{{}[27]}\textquotedblleft{}Semantic Versioning.\textquotedblright{} \href{https://semver.org/}{{\ttfamily https://\hspace{0pt}semver.\hspace{0pt}org/\hspace{0pt}}}.\label{semver}%mdk%mdk + +%mdk-data-line={references.bib:98} +\bibitem{protostatus}\mdbibitemlabel{{}[28]}\textquotedblleft{}Status.proto:the Protobuf Status Message.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}src/\hspace{0pt}proto/\hspace{0pt}grpc/\hspace{0pt}status/\hspace{0pt}status.\hspace{0pt}proto}}.\label{protostatus}%mdk%mdk + +%mdk-data-line={references.bib:63} +\bibitem{p4revisions110}\mdbibitemlabel{{}[29]}\textquotedblleft{}Summary of Changes Made in $P4_{16}$ Version 1.1.0.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-summary-of-changes-made-in-version-110}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}summary-\hspace{0pt}of-\hspace{0pt}changes-\hspace{0pt}made-\hspace{0pt}in-\hspace{0pt}version-\hspace{0pt}110}}.\label{p4revisions110}%mdk%mdk + +%mdk-data-line={references.bib:48} +\bibitem{p4tableproperties}\mdbibitemlabel{{}[30]}\textquotedblleft{}Table Properties in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-props}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}props}}.\label{p4tableproperties}%mdk%mdk + +%mdk-data-line={references.bib:83} +\bibitem{protoany}\mdbibitemlabel{{}[31]}\textquotedblleft{}The Any Protobuf Message.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23any}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}any}}.\label{protoany}%mdk%mdk + +%mdk-data-line={references.bib:88} +\bibitem{grpcstatus}\mdbibitemlabel{{}[32]}\textquotedblleft{}The gRPC $Status$ Class.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/status.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}impl/\hspace{0pt}codegen/\hspace{0pt}status.\hspace{0pt}h}}.\label{grpcstatus}%mdk%mdk + +%mdk-data-line={references.bib:104} +\bibitem{grpcerrordetails}\mdbibitemlabel{{}[33]}\textquotedblleft{}The gRPC C++ Error Details Library.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/support/error_details.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}support/\hspace{0pt}error\_\hspace{0pt}details.\hspace{0pt}h}}.\label{grpcerrordetails}%mdk%mdk + +%mdk-data-line={references.bib:93} +\bibitem{grpcstatuscodes}\mdbibitemlabel{{}[34]}\textquotedblleft{}The gRPC Canonical Status Codes.\textquotedblright{} \href{https://developers.google.com/maps-booking/reference/grpc-api/status_codes}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}maps-\hspace{0pt}booking/\hspace{0pt}reference/\hspace{0pt}grpc-\hspace{0pt}api/\hspace{0pt}status\_\hspace{0pt}codes}}.\label{grpcstatuscodes}%mdk%mdk + +%mdk-data-line={references.bib:22} +\bibitem{openconfig}\mdbibitemlabel{{}[35]}\textquotedblleft{}The OpenConfig Project.\textquotedblright{} \href{http://openconfig.net}{{\ttfamily http://\hspace{0pt}openconfig.\hspace{0pt}net}}.\label{openconfig}%mdk%mdk + +%mdk-data-line={references.bib:184} +\bibitem{protomessagedifferencer}\mdbibitemlabel{{}[36]}\textquotedblleft{}The Protobuf MessageDifferencer in the C++ API.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.util.message_differencer}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}reference/\hspace{0pt}cpp/\hspace{0pt}google.\hspace{0pt}protobuf.\hspace{0pt}util.\hspace{0pt}message\_\hspace{0pt}differencer}}.\label{protomessagedifferencer}%mdk%mdk + +%mdk-data-line={references.bib:27} +\bibitem{stratum}\mdbibitemlabel{{}[37]}\textquotedblleft{}The Stratum Project.\textquotedblright{} \href{https://stratumproject.org/}{{\ttfamily https://\hspace{0pt}stratumproject.\hspace{0pt}org/\hspace{0pt}}}.\label{stratum}%mdk%mdk + +%mdk-data-line={references.bib:199} +\bibitem{v1model}\mdbibitemlabel{{}[38]}\textquotedblleft{}v1model Architecture Definition.\textquotedblright{} \href{https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4c/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}p4include/\hspace{0pt}v1model.\hspace{0pt}p4}}.\label{v1model}%mdk%mdk + +%mdk-data-line={references.bib:53} +\bibitem{p4valuesets}\mdbibitemlabel{{}[39]}\textquotedblleft{}Value Sets in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-value-set}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}value-\hspace{0pt}set}}.\label{p4valuesets}%mdk%mdk +\par%mdk +\end{thebibliography}}%mdk%mdk +}%mdk + + +\end{document} diff --git a/spec/v1.4.0-rc.2/ellipse.sty b/spec/v1.4.0-rc.2/ellipse.sty new file mode 100644 index 00000000..7c0ecb3e --- /dev/null +++ b/spec/v1.4.0-rc.2/ellipse.sty @@ -0,0 +1,318 @@ +%% +%% This is file `ellipse.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ellipse.dtx (with options: `package') +%% +%% Copyright (C) 2015 +%% Daan Leijen +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". +%% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{ellipse} + [2004/11/05 v1.0 .dtx ellipse file] +\RequirePackage{pict2e} + +\providecommand*\pIIe@csedef[1]{\expandafter\edef\csname #1\endcsname} +\newcommand*\pIIe@ellip@csqrt[3]{% + \@ovxx=#1\relax + \ifdim\@ovxx<\z@\@ovxx-\@ovxx\fi + \@ovyy=#2\relax + \ifdim\@ovyy<\z@\@ovyy-\@ovyy\fi + \edef\pIIe@csname{@csqrt(\number\@ovxx,\number\@ovyy)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@ellip@csqrt@% + \pIIe@csedef{\pIIe@csname}{\the\dimen@}% + #3\dimen@ + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} +\newcommand*\pIIe@ellip@csqrt@{% + \@ovdx\@ovxx + \advance\@ovdx by \@ovyy + \dimen@0.7071067\@ovdx + \ifdim\dimen@<\@ovyy\dimen@\@ovyy\fi + \ifdim\dimen@<\@ovxx\dimen@\@ovxx\fi + \ifdim\@ovdx<128\p@ + \edef\@tempa{\strip@pt\@ovxx}% + \@ovxx\@tempa\@ovxx + \edef\@tempa{\strip@pt\@ovyy}% + \@ovyy\@tempa\@ovyy + \advance\@ovxx by \@ovyy + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \fi +} + +\newcommand*\pIIe@atan@{% + \@tempdima\dimen@ + \@tempdimb\@tempdima + \ifdim\@tempdimb<\z@\@tempdimb-\@tempdimb\fi + \dimen@0.0663\@tempdimb + \advance\dimen@ 0.2447pt\relax + \advance\@tempdimb -1pt\relax + \edef\@tempa{\strip@pt\@tempdimb}% + \dimen@\@tempa\dimen@ + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \dimen@-\dimen@ + \advance\dimen@ 0.7853\@tempdima +} + +\newcommand*\pIIe@atantwo[3]{% + \edef\pIIe@csname{@atan2(\number\dimexpr#1\relax,\number\dimexpr#2\relax)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@atantwo@{#1}{#2}{#3}% + \pIIe@csedef{\pIIe@csname}{\the\dimexpr#3\relax}% + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} + +\newcommand*\pIIe@atantwo@[3]{% + \@tempdima\dimexpr#2\relax + \@tempdimb\dimexpr#1\relax + \ifdim\@tempdima=\z@\relax + \ifdim\@tempdimb>\z@\relax\dimen@90\p@ + \else\ifdim\@tempdimb<\z@\relax\dimen@-90\p@ + \else\dimen@0\p@ + \fi\fi + \else + \@tempdimd\z@ + \ifdim\@tempdima<\z@\relax + \ifdim\@tempdimb<\z@\relax\@tempdimd-180\p@ + \else\@tempdimd180\p@ + \fi + \fi + \dimen@\dimexpr1pt * \@tempdimb/\@tempdima\relax + \@tempdimc\dimen@ + \ifdim\@tempdimc<\z@\relax\@tempdimc-\@tempdimc\fi + \ifdim\@tempdimc>\p@\relax + \dimen@\dimexpr1pt * \@tempdima/\@tempdimb\relax + \ifdim\dimen@<\z@\relax\def\@tempsign{-}\else\def\@tempsign{}\fi + \pIIe@atan@ + \dimen@-\dimen@ + \advance\dimen@ by \@tempsign1.5707pt\relax + \else + \pIIe@atan@ + \fi + \dimen@57.29578\dimen@ + \advance\dimen@ by \@tempdimd + \fi + #3\dimen@% +} + +\newcommand*\pIIe@noneto[2]{} +\newcommand*\pIIe@ellip@sincost@[2]{% + \CalculateSin{#1}% + \CalculateCos{#1}% + \@tempdima\UseSin{#1}\p@ + \@tempdimb\UseCos{#1}\p@ + \ifdim\@tempdima=\p@\relax + \pIIe@csedef{@ellipsin#2}{1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else\ifdim\@tempdima=-\p@\relax + \pIIe@csedef{@ellipsin#2}{-1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else + \@tempdimc\@ellipratio\dimexpr1pt * \@tempdima/\@tempdimb\relax + %\typeout{ i#2=\the\@tempdimc, sin(#1)=\the\@tempdima}% + \pIIe@ellip@csqrt{\p@}{\@tempdimc}\@tempdimd + \ifdim\@tempdimb<\z@\relax\@tempdimd-\@tempdimd\fi + \pIIe@csedef{@ellipsin#2}{\strip@pt\dimexpr1pt * \@tempdimc/\@tempdimd\relax}% + \pIIe@csedef{@ellipcos#2}{\strip@pt\dimexpr1pt * \p@/\@tempdimd\relax}% + \fi\fi +} + +\newcommand*\pIIe@ellip@sincost[2]{% + %\typeout{ calc sin cos: angles (#1,#2), radii: (\the\@ovro,\the\@ovri)}% + \edef\@ellipratio{\strip@pt\dimexpr1pt * \@ovro/\@ovri\relax}% + \pIIe@ellip@sincost@{#1}{one}% + \pIIe@ellip@sincost@{#2}{two}% + %\typeout{ sincos(a=#1)=(\@ellipsinone,\@ellipcosone), sincos(a=#2)=(\@ellipsintwo,\@ellipcostwo), }% +} +\newcommand*\pIIe@omega[3]{% + \@tempdima\csname @ellipcos#3\endcsname\@ovro + \advance\@tempdima by #1\relax + \@tempdimb\csname @ellipsin#3\endcsname\@ovri + \advance\@tempdimb by #2\relax +} + +\newcommand*\pIIe@omegai[1]{% + \@tempdimc\csname @ellipsin#1\endcsname\@ovro + \@tempdimc-\@tempdimc + \@tempdimd\csname @ellipcos#1\endcsname\@ovri +} + +\newcommand*\pIIe@ellip@kappa{% + \@ovyy\@ellipsinone\p@ + \@ovxx\@ellipcosone\p@ + \@tempdima\@ellipcostwo\@ovyy + \@tempdima-\@tempdima + \advance\@tempdima by \@ellipsintwo\@ovxx + \@tempdimb\@ellipcostwo\@ovxx + \advance\@tempdimb by \@ellipsintwo\@ovyy + \ifdim\@tempdima=\z@\relax + \edef\@ellipkappa{0}% + \else + \dimen@\dimexpr1pt - \@tempdimb\relax + \dimen@\dimexpr1pt * \dimen@/\@tempdima\relax + \pIIe@ellip@csqrt{2\p@}{1.73205\dimen@}{\dimen@}% + \advance\dimen@ by -\p@ + \divide\dimen@ by 3% + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \edef\@ellipkappa{\strip@pt\dimen@}% + \fi + %\typeout{ calculated kappa: \@ellipkappa}% +} + +\newcommand*\pIIe@elliparc@[5]{% + %\typeout{elliparc: #1, center: (#2, #3), radius (\the\@ovro, \the\@ovri),angle (#4, #5)}% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \pIIe@ellip@sincost{#4}{#5}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@t[5]{% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \CalculateSin{#4}\CalculateCos{#4}% + \edef\@ellipsinone{\UseSin{#4}}% + \edef\@ellipcosone{\UseCos{#4}}% + \CalculateSin{#5}\CalculateCos{#5}% + \edef\@ellipsintwo{\UseSin{#5}}% + \edef\@ellipcostwo{\UseCos{#5}}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@draw[2]{% + \pIIe@ellip@kappa% + \pIIe@omega{#1}{#2}{one}% + %\typeout{ point one: (\the\@tempdima,\the\@tempdimb)}% + \@ellip@startto\@tempdima\@tempdimb + \pIIe@omegai{one}% + \advance\@tempdima by \@ellipkappa\@tempdimc + \advance\@tempdimb by \@ellipkappa\@tempdimd + \pIIe@add@nums\@tempdima\@tempdimb + %\typeout{ control one: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@omega{#1}{#2}{two}% + \pIIe@omegai{two}% + \@tempdimc\@ellipkappa\@tempdimc + \@tempdimd\@ellipkappa\@tempdimd + \@tempdimc-\@tempdimc + \@tempdimd-\@tempdimd + \advance\@tempdimc by \@tempdima + \advance\@tempdimd by \@tempdimb + \pIIe@add@nums\@tempdimc\@tempdimd + %\typeout{ control two: (\the\@tempdimc,\the\@tempdimd)}% + \pIIe@add@CP\@tempdima\@tempdimb + %\typeout{ point two: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@addtoGraph\pIIe@curveto@op +} +\newcommand*\pIIe@elliparc[7][0]{% + \@ovro #4\relax + \@ovri #5\relax + \iffalse%dim\@ovro=\@ovri + \pIIe@arc[#1]{#2}{#3}{#4}{#6}{#7} + \else + \ifdim \@ovro<\z@ \pIIe@badcircarg\else + \ifdim \@ovri<\z@ \pIIe@badcircarg\else + \@arclen #7\p@ \advance\@arclen -#6\p@ + \ifdim \@arclen<\z@ \def\@tempsign{-}\else\def\@tempsign{}\fi + \ifdim \@tempsign\@arclen>720\p@ + \PackageWarning {ellipse}{The arc angle is reduced to -720..720}% + \@whiledim \@tempsign\@arclen>720\p@ \do {\advance\@arclen-\@tempsign360\p@}% + \@tempdima #6\p@ \advance\@tempdima \@arclen + \edef\@angleend{\strip@pt\@tempdima}% + \pIIe@@elliparc{#1}{#2}{#3}{#6}{\@angleend}% + \else + \pIIe@@elliparc{#1}{#2}{#3}{#6}{#7}% + \fi + \fi + \fi + \fi +} +\newcommand*\pIIe@@elliparc[5]{% + \begingroup + \ifdim \@tempsign\@arclen>90\p@ + \divide\@arclen 2% + \@tempdima #4\p@\advance\@tempdima by \@arclen + \edef\@anglemid{\strip@pt\@tempdima}% + \def\@tempa{\pIIe@@elliparc{#1}{#2}{#3}{#4}}% + \expandafter\@tempa\expandafter{\@anglemid}% + \def\@tempa{\pIIe@@elliparc{2}{#2}{#3}}% + \expandafter\@tempa\expandafter{\@anglemid}{#5}% + \else + \pIIe@elliparc@{#1}{#2}{#3}{#4}{#5}% + \fi + \endgroup +}% + +\newcommand*\pIIeelliparc[7][0]{% + \@killglue + \pIIe@elliparc[#1]{#2\unitlength}{#3\unitlength}{#4\unitlength}{#5\unitlength}{#6}{#7}% + \ignorespaces% +} +\ifx\undefined\elliparc\else + \PackageWarning{ellipse}{\protect\elliparc\space is redefined}% +\fi +\let\elliparc\pIIeelliparc + +\newcommand*\pIIeearc + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\newcommand*\pIIe@earc@[3][0,360]{\pIIe@earc@@(#1){#2}{#3}} +\def\pIIe@earc@@(#1,#2)#3#4{% + \if@tempswa + \pIIe@moveto\z@\z@ + \pIIe@elliparc{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@closepath\pIIe@fillGraph + \else + \pIIe@elliparc[1]{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@strokeGraph + \fi} +\ifx\undefined\earc\else + \PackageWarning{ellipse}{\protect\earc\space is redefined}% +\fi +\let\earc\pIIeearc + +\newcommand*\pIIeellipse + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\let\ellipse\pIIeellipse + +\endinput +%% +%% End of file `ellipse.sty'. diff --git a/spec/v1.4.0-rc.2/embedded-plus-single-remote-controller.png b/spec/v1.4.0-rc.2/embedded-plus-single-remote-controller.png new file mode 100644 index 00000000..2e0f1803 Binary files /dev/null and b/spec/v1.4.0-rc.2/embedded-plus-single-remote-controller.png differ diff --git a/spec/v1.4.0-rc.2/embedded-plus-single-remote-controller.svg b/spec/v1.4.0-rc.2/embedded-plus-single-remote-controller.svg new file mode 100644 index 00000000..9fe2ce9c --- /dev/null +++ b/spec/v1.4.0-rc.2/embedded-plus-single-remote-controller.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0-rc.2/embedded-plus-two-remote-controllers.png b/spec/v1.4.0-rc.2/embedded-plus-two-remote-controllers.png new file mode 100644 index 00000000..b6dc04fc Binary files /dev/null and b/spec/v1.4.0-rc.2/embedded-plus-two-remote-controllers.png differ diff --git a/spec/v1.4.0-rc.2/embedded-plus-two-remote-controllers.svg b/spec/v1.4.0-rc.2/embedded-plus-two-remote-controllers.svg new file mode 100644 index 00000000..0f97ba38 --- /dev/null +++ b/spec/v1.4.0-rc.2/embedded-plus-two-remote-controllers.svg @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + + + Entities + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0-rc.2/embedded-plus-two-remote-ha-controllers.png b/spec/v1.4.0-rc.2/embedded-plus-two-remote-ha-controllers.png new file mode 100644 index 00000000..392f8963 Binary files /dev/null and b/spec/v1.4.0-rc.2/embedded-plus-two-remote-ha-controllers.png differ diff --git a/spec/v1.4.0-rc.2/embedded-plus-two-remote-ha-controllers.svg b/spec/v1.4.0-rc.2/embedded-plus-two-remote-ha-controllers.svg new file mode 100644 index 00000000..97ab6fc3 --- /dev/null +++ b/spec/v1.4.0-rc.2/embedded-plus-two-remote-ha-controllers.svg @@ -0,0 +1,511 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + Primary (Active) + + + + + + Backup (Standby) + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0-rc.2/error-report.png b/spec/v1.4.0-rc.2/error-report.png new file mode 100644 index 00000000..766cb77f Binary files /dev/null and b/spec/v1.4.0-rc.2/error-report.png differ diff --git a/spec/v1.4.0-rc.2/error-report.svg b/spec/v1.4.0-rc.2/error-report.svg new file mode 100644 index 00000000..a2709a72 --- /dev/null +++ b/spec/v1.4.0-rc.2/error-report.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StatusCode error_code_; // canonical error codestring error_message_;string binary_error_details_; // serialized google.rpc.Status + + + + + + + + + + + + + google.rpc.Status + + + + + + int32 error_code; // canonical error codestring message;repeated Any details; // P4Error + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + + + p4.Error + + + + + + p4.Error + + + + + + + + + + + + + + + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + grpc::Status + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0-rc.2/longbox.sty b/spec/v1.4.0-rc.2/longbox.sty new file mode 100644 index 00000000..cab48934 --- /dev/null +++ b/spec/v1.4.0-rc.2/longbox.sty @@ -0,0 +1,853 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longbox}[2015/12/01, Daan Leijen, Provides basic longbox that can break over pages] +\RequirePackage{options} + +\@ifclassloaded{beamer}{% + \newcommand\lb@savefootnotes{}% + \newcommand\lb@restorefootnotes{}% +}% +{\RequirePackage{footnote}% + \newcommand\lb@savefootnotes{\savenotes}% + \newcommand\lb@restorefootnotes{\spewnotes}% +} + + +% -------------------------------------------------------- +% Debugging +% -------------------------------------------------------- + +\newcommand*\lb@debug[1]{% + \ontoggle{lb@debug}{\typeout{longbox debug: #1}}% +} +\newcommand*\lb@typeout[1]{% + \ontoggle{lb@verbose}{\typeout{longbox: #1}}% +} +\newcommand*\lb@warncannotsplit{% + \PackageWarning{longbox}{Cannot split box; it seems you are using a non-splittable contents}% +} +\newcommand*\lb@warnbadsplit[1]{% + \PackageWarning{longbox}{Bad split (underful vbox by \the#1)}% +} + + +% -------------------------------------------------------- +% Utilities for LaTeX internals +% -------------------------------------------------------- + +% Suppress the indentation on the following paragraph +\providecommand\nofirstindent{\@afterindentfalse\@afterheading} + +% Suppress the paragraph skip on the following paragraph +\providecommand\nofirstparskip{\addvskip{-\parskip}} + +% In contrast to addvspace, addvskip is not suppressed in a minipage +\providecommand\addvskip[1]{% + \ifvmode + \ifdim\lastskip=\z@ + \vskip #1\relax + \else + \@tempskipb#1\relax\@xaddvskip + \fi + \else\@noitemerr\fi +} + + +% Skip to 0.3\baselineskip multiple taking prevdepth into account. +\newskip\lb@prevdepth +\newcommand\lb@skiptobaseline{% + \global\lb@prevdepth=-\@m\p@\relax + \ifvmode + \ifdim\lastskip=\z@\relax + \ifdim\prevdepth=-\@m\p@\else + \dimen@\prevdepth + % Calculate the modulus of the previous depth with 0.3|\baselineskip| in |\dimen@|. + \@tempcnta\prevdepth + \@tempskipa=0.3\baselineskip\relax + \@tempcntb=\@tempskipa\relax + \divide \@tempcnta by \@tempcntb + \dimen@\prevdepth + \advance\dimen@ -\@tempcnta\@tempskipa + % Skip back by that amount, and then skip by 0.3|\baselineskip|. + \vskip -\dimen@ + \vskip \@tempskipa\relax + \global\lb@prevdepth=\@tempskipa\relax + \fi + \fi + \fi +} + +% unvbox a box, and return a vbox with a given background color +% \unvcolorbox{}{} +\newcommand\unvcolorbox[2]{% + \ifoptionblank{#1}{\vbox{\unvbox#2}}{% + \lb@debug{vcolorbox: #1}% + \vbox{\offinterlineskip + \hbox to \z@{\vbox to \z@{\optioncolor{#1}\hrule\@width\wd#2\@height\ht#2\@depth\dp#2\vss}\hss}% + \unvbox#2% + }% + }% +} + +% create a vbox with a given background color +\newcommand\vcolorbox[2]{% + \eifblank{#1}{\vbox{#2}}{% + \setbox\z@=\vbox{#2}\relax + \unvcolorbox{#1}{\z@}% + }% +}% + +% -------------------------------------------------------- +% The following macros come from mdframed +% -------------------------------------------------------- + +% Determine the amount of free space left on the current page +\newlength\lb@freevspace +\newcommand*\lb@setfreevspace@page{% + \lb@debug{ determine free space}% + \bgroup\@nobreakfalse\addpenalty\z@\egroup% + \penalty\@M\relax\vskip 2\baselineskip\relax% + \penalty9999\relax\vskip -2\baselineskip\relax% + \penalty9999% + \ifdim\pagegoal=\maxdimen\relax% + \lb@freevspace=\vsize% + \else + \lb@freevspace=\dimexpr\pagegoal-\pagetotal-\parskip\relax% + \fi + \lb@debug{free space: \the\lb@freevspace, in page: \the\textheight, vsize=\the\vsize}% +} + +\newcommand*\lb@shiftdim[2]{% + %\letoption{#1}\lb@list + \expandafter\lb@setheadtail@#1,\relax + \eifblank{\lb@head}{}{\option@invoke{/longbox/@breakat-previous}{\lb@head}}% + #2\option{/longbox/@breakat-previous}% + \eifblank{\lb@tail}{}{\let#1\lb@tail}% push back tail +} +\def\lb@comma{,}% +\def\lb@setheadtail@#1,#2\relax{% + \def\lb@head{#1}% + \def\lb@tail{#2}% adds commas! +} + +\newcommand*\lb@setfreevspace{% + \eifblank{\lb@breakat}{\lb@setfreevspace@page}{% + \def\lb@eject{\par}%no eject + \lb@extrasplit=\z@\relax% + \lb@shiftdim{\lb@breakat}\lb@freevspace + \ifdim\lb@freevspace>\z@\else\lb@setfreevspace@page\fi + }% +} + + +% Suppress overfull-underfull vbox messages +\newcommand*\lb@ignorevbadness{% + \edef\lb@currentvbadness{\the\vbadness}% + \edef\lb@currentvfuzz{\the\vfuzz}% + \vbadness=\@M\relax% + \vfuzz=\maxdimen\relax% + \afterassignment\lb@restorevbadness +} +\newcommand*\lb@restorevbadness{% + \vbadness=\lb@currentvbadness\relax + \vfuzz=\lb@currentvfuzz\relax +} + + +% -------------------------------------------------------- +% The 'long vbox' (lvbox) environment collects long material +% into a long \vbox, instead of a \hbox like a lrbox in latex. +% The collected box can contain any box, minipage, lrbox, fbox etc, +% but not outer-par material like a figure. Footnotes can be +% dealt with useing lb@savefootnotes. +% +% The material is typeset in a \vbox according to a given width. +% inside the environment, the boolean 'inlvbox' is true. +% +% \begin{lvbox}{}{} +% -------------------------------------------------------- + +\newif\ifinlvbox +\newcommand\lvbox[4]{% + \setbox#1\vbox\bgroup + \begingroup + \inlvboxtrue + % reset defaults + \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\par\@@par + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + % set margin and linewidth + \leftmargin=#2\relax\rightmargin=#4\relax + \@totalleftmargin=\leftmargin% + %\leftskip=#2\relax\rightskip=#4\relax\@rightskip=#4\relax + \linewidth=#3\relax + % set primitive tex margins + \leftskip=\@totalleftmargin% + \rightskip=\rightmargin% + \@rightskip=\rightmargin% + \hsize=\dimexpr\@totalleftmargin+\linewidth+\rightmargin\relax + \columnwidth\hsize + \textwidth\hsize + \nofirstindent + %\nofirstparskip +} +\def\endlvbox{\endgroup\egroup} + + + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + + +\newsavebox\lb@headbox +\newsavebox\lb@savebox +\newsavebox\lb@mainbox + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@setbaseline[1]{% + %\typeout{ set baseline, \the\dp#1,\the\ht#1}% + \ifcase\lb@baseline% + \relax%bottom + \or%middle + \setbox#1=\vbox{\hbox{\lower \dimexpr(\dp#1 + \ht#1)/2 - \dp#1\relax\vbox{\unvbox#1}}}% + \or%top + \setbox#1=\vtop{\unvbox#1}% + \fi + %\typeout{ .new dim: \the\dp#1, \the\ht#1}% +} + + +\@ifundefined{define@key}{}% + {\define@key{longbox}{options}{\options{#1}\option{/longbox/adjust-options}}}% + +\newcommand*\lb@render@breakbox{% + %\typeout{render breakbox entry (in output routine), height=\the\bb@height}% + \bb@restorekeys{longbox}% + \lb@skiptop=\ifbb@isfirst\option{/longbox/skip-top}\else\option{/longbox/skip-break-top}\fi\relax + \lb@skipbottom=\ifbb@islast\option{/longbox/skip-bottom}\else\option{/longbox/skip-break-bottom}\fi\relax + \lb@skipbreaktop=\ifbb@isfirst 0pt\else\option{/longbox/skip-break-top}\fi + \lb@skipbreakbottom=\ifbb@islast 0pt\else\option{/longbox/skip-break-bottom}\fi + %\typeout{ render: skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom, break-top=\the\dimexpr\option{/longbox/skip-bottom}}% + \options{% + /longbox/@part-height=\bb@height + \lb@skipbreaktop + \lb@skipbreakbottom, + /longbox/@part-width=\option{/longbox/width} + \option{/longbox/skip-left} + \option{/longbox/skip-right},%\bb@width, + /longbox/@part-depth=0pt, + /longbox/@part-needtop=\ifbb@isfirst true\else false\fi, + /longbox/@part-needbottom=\ifbb@islast true\else false\fi, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-depth=\option{/longbox/@part-depth}, + }% + %\typeout{breakbox: width=\expandafter\the\option{/longbox/width}, \the\bb@width, \the\dimexpr\option{/longbox/@part-width}}% + \vbox{% + \kern -\lb@skipbreaktop% todo: move to breakbox? + \option{/longbox/render}% + \kern -\lb@skipbreakbottom + }% +} + +\newcommand*\lb@render@vbox[1]{% + \lb@debug{render vbox entry}% + \lb@restoreoptions + \lb@skiptop=\dimexpr\iftoggle{/longbox/@part-needtop}{\option{/longbox/skip-top}}{\option{/longbox/skip-break-top}}\relax + \lb@skipbottom=\dimexpr\iftoggle{/longbox/@part-needbottom}{\option{/longbox/skip-bottom}}{\option{/longbox/skip-break-bottom}}\relax + %\typeout{ skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom}% + % add top skip while maintaining the baseline. + \ifdim\lb@skiptop=\z@\relax\else + \setbox\z@=\vtop{\unvcopy#1}% + \dimen@=\ht\z@ + \setbox#1=\vbox{\offinterlineskip + \hrule width \z@ height \dimexpr\dimen@ + \lb@skiptop\relax depth -\dimen@ + \unvbox#1% + }% + \fi + % add bottom skip while maintaining the baseline. + \ifdim\lb@skipbottom=\z@\relax\else + \dimen@=\dp#1% + \setbox#1=\vbox{\offinterlineskip\unvbox#1\hrule width \z@ height -\dimen@ depth \dimexpr\dimen@ + \lb@skipbottom\relax}% + \fi + \lb@setbaseline{#1}% + \options{% + /longbox/@part-height=\dimexpr\ht#1 + \dp#1\relax, + /longbox/@part-width=\dimexpr\wd#1 + \option{/longbox/skip-left} + \option{/longbox/skip-right}\relax, + /longbox/@part-depth=\dp#1, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-depth=\option{/longbox/@part-depth} - \lb@skipbottom, + }% + %\typeout{ longbox: height=\the\dimexpr\option{/longbox/@content-box-height}, outer height=\the\dimexpr\option{/longbox/@part-height}\relax}% + % lower the box depending on vertical alignment + \ifcase\option{/longbox/vertical-align/@ord}\relax + \@tempdima\z@ + \or + %bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%middle + \@tempdima\dimexpr0.5\option{/longbox/@part-height} - \option{/longbox/@part-depth}\relax + \or%top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%text-bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%text-top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%super + \@tempdima=-0.9ex% + \or%sub + \@tempdima=0.7ex% + \else + \@tempdima\z@ + \fi + \advance\@tempdima by -\option{/longbox/raise}% + \option@invoke{/longbox/@lower}{\@tempdima}% + \noindent\hbox{\lower \@tempdima\vbox{\offinterlineskip + \hbox to \z@{% + \vbox to \z@{% + \hbox{\lower \option{/longbox/@part-height}\vbox{\offinterlineskip{\option{/longbox/render}}}}% + \vss}% + \hss + }% + \hbox{% + \ifdim\option{/longbox/skip-left}=\z@\else\hskip\option{/longbox/skip-left}\fi + \box#1% + \ifdim\option{/longbox/skip-right}=\z@\else\hskip\option{/longbox/skip-right}\fi + %$\box#1% + }% + }}% +} + +\newcommand*\lb@single@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} +\newcommand*\lb@first@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@middle@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@last@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand*\lb@env@start{% + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore +} + +\newcount\lb@usevbox +\newlength\lb@width +\newlength\lb@height +\newlength\lb@skiptop +\newlength\lb@skipright +\newlength\lb@skipbottom +\newlength\lb@skipleft +\newlength\lb@skipbreaktop +\newlength\lb@skipbreakbottom +\newlength\lb@outerwidth +\newlength\lb@extrasplit +\newcount\lb@textalign +\newcount\lb@baseline +\newtoggle{lb@baselineskip}% +\newtoggle{lb@breakable}% +\newtoggle{lb@debug}% +\newtoggle{lb@verbose}% +\def\lb@breakat{}% +\def\lb@halign{}% +\def\lb@eject{}% +\def\lb@insertafter{} +\def\lb@insertbefore{} + +\newcommand*\lb@peekoptions[1]{% + % process options inside a group and just set necessary parameters + % this way, nested boxes don't influence each other's parameters + \begingroup + \options{#1}% + \option{/longbox/adjust-options}% + \protected@edef\lb@temp{\endgroup + \lb@width=\the\dimexpr\option{/longbox/width}\relax + \lb@height=\the\dimexpr\option{/longbox/height}\relax + \lb@textalign=\the\numexpr\option{/longbox/text-align/@ord}\relax + \lb@baseline=\the\numexpr\option{/longbox/baseline/@ord}\relax + \lb@skiptop=\the\dimexpr\option{/longbox/skip-top}\relax + \lb@skipright=\the\dimexpr\option{/longbox/skip-right}\relax + \lb@skipbottom=\the\dimexpr\option{/longbox/skip-bottom}\relax + \lb@skipleft=\the\dimexpr\option{/longbox/skip-left}\relax + \lb@skipbreaktop=\the\dimexpr\option{/longbox/skip-break-top}\relax + \lb@skipbreakbottom=\the\dimexpr\option{/longbox/skip-break-bottom}\relax + \lb@usevbox=\iftoggle{/longbox/use-vbox}{1}{0}\relax + \lb@outerwidth=\the\dimexpr\option{/longbox/outer-width}\relax + \lb@extrasplit=\the\dimexpr\option{/longbox/split-minimum}\relax + \def\noexpand\lb@insertafter{\option{/longbox/insert-after}}% + \def\noexpand\lb@insertbefore{\option{/longbox/insert-before}}% + \def\noexpand\lb@breakat{\option{/longbox/breakat}}% + \def\noexpand\lb@halign{\option{/longbox/height-align}}% + \def\noexpand\lb@eject{\option{/longbox/eject}}% + \noexpand\csname toggle\iftoggle{/longbox/baseline-skip}{true}{false}\endcsname{lb@baselineskip}% + \noexpand\csname toggle\iftoggle{/longbox/breakable}{true}{false}\endcsname{lb@breakable}% + \noexpand\csname toggle\iftoggle{/longbox/debug}{true}{false}\endcsname{lb@debug}% + \noexpand\csname toggle\iftoggle{/longbox/verbose}{true}{false}\endcsname{lb@verbose}% + }% + \lb@temp +} + +\newenvironment{longbox@env}[2]{% + % save options + \lb@peekoptions{#1,#2}% + % + \ifnum\lb@usevbox=0\relax + \lb@debug{start breakbox}% + \let\bb@render\lb@render@breakbox + \bb@savekeys{longbox}{options={#1,#2,outer-width=\the\lb@outerwidth}}% + \iftoggle{lb@baselineskip}{\typeout{**insert bskip}}{\typeout{**suppress bskip}\vskip 1pt}% + \begin{breakbox}% + \ifdim\lb@skiptop=\z@\relax\else\vspace{\lb@skiptop}\fi% + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \begin{bb@margins}{\lb@skipleft}{\dimen@}% + \else + \lb@debug{start vbox}% + \def\lb@restoreoptions{\options{#1,#2}\option{/longbox/adjust-options}}% + \lb@savefootnotes + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \lb@debug{ width=\the\lb@width, linewidth=\the\linewidth, skipleft=\the\lb@skipleft, right=\the\lb@skipright, total right=\the\dimen@}% + \iftoggle{lb@baselineskip}{\lb@skiptobaseline}{\lb@prevdepth=-\@m pt}% + \lvbox{\lb@mainbox}{0pt}{\lb@width}{0pt}%{\lb@skipleft}{\lb@width}{\lb@skipright}% + \prevdepth=\lb@prevdepth + \fi + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore + \begingroup +}{% + \par\unskip + \endgroup + \lb@insertafter + %\ifdim\lb@skipbottom=\z@\relax\else\vskip\lb@skipbottom\fi% + \ifnum\lb@usevbox=0\relax + \end{bb@margins}% + \ifdim\lb@skipbottom=\z@\relax\else\hrule width \z@ height \lb@skipbottom\fi%\vspace{\lb@skipbottom}\fi% + \iftoggle{lb@baselineskip}{}{\vskip 1sp}% + \end{breakbox}% + \lb@debug{end breakbox}% + \else + \ontoggle{lb@baselineskip}{\lb@skiptobaseline}% + \endlvbox% + \lb@debug{initial lvbox: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@processbox + %\setbox\lb@mainbox=\hbox{\lower \lb@skipbottom\vbox{\offinterlineskip\unvbox\lb@mainbox}}% + \lb@restorefootnotes + \lb@debug{end vbox}% + \fi +} + +\newcommand\longbox@cmd[3]{% + \begingroup + %\options{/options/collectunknown,/longbox/scoped,#2}% set scoped options first + %\option{/longbox/scoped/@adjust-options}% + \lb@peekoptions{#1,#2}% + \leavevmode + %\setbox\lb@mainbox=\hbox{% + % \begingroup + % #3% + % \endgroup + %}% + \setbox\lb@mainbox=\hbox{% + \begingroup + \ifcase\lb@textalign\relax + %default=left + \or%left + \or\hss%center + \or\hss%right + \else%justify + \fi + \lb@insertbefore + #3% + \lb@insertafter + \ifnum\lb@textalign<3\relax\hss\fi% default,left,center + \endgroup + }% + \options{#1,#2}% + \ifdim\option{/longbox/width}=-1sp\relax + \options{/longbox/width=\wd\lb@mainbox}%set to natural width + \fi + \option{/longbox/adjust-options}% + % make it a vbox + \setbox\lb@mainbox=\vbox{\offinterlineskip% + \hbox to \option{/longbox/width}{% + \unhbox\lb@mainbox + }% + }% + \def\lb@restoreoptions{}% + \letoption{/longbox/height-align}\lb@halign + \lb@height=\option{/longbox/height}\relax + \lb@baseline=\option{/longbox/baseline/@ord}\relax + \lb@processbox + \endgroup +} + +\newcommand\lb@processbox{% + \ifdim\lb@height<0pt\relax + \lb@setbaseline{\lb@mainbox}% + \else + \lb@restrictheight + \fi + \lb@typesetbox +} + +\newcommand\lb@typesetbox{% + \ifinlvbox + \iftoggle{lb@breakable}{% + %\lb@debug{disable breakable due to nesting of long-boxes}% + \togglefalse{lb@breakable}% + }{}% + \fi + \ifhmode\lb@single@{\lb@mainbox}\else\lb@typeset\fi +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@restrictheight{% + \lb@typeout{restrict height to \the\lb@height}% + \lb@splitheight=\lb@height% + %lb@debug{before height split: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + %split failed.. do nothing + \lb@debug{could not restrict height}% + \else + % store splitted off content in the mainbox (and discard the rest) + \setbox\lb@mainbox\vbox{\unvbox\lb@headbox}% + \lb@debug{restricted height to \the\ht\lb@mainbox}% + \fi + % set baseline + \lb@setbaseline{\lb@mainbox}% + % height align + %\letoption{/longbox/height-align}\lb@halign + \eifstrequal{\lb@halign}{bottom}% + {\setbox\lb@mainbox=\vbox{\hbox{\vbox to \lb@splitheight{\vss\unvbox\lb@mainbox}}}}% + {\eifstrequal{\lb@halign}{middle}% + {\dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\hbox{% + \lower \dimexpr0.5\dimen@ + \dp\lb@mainbox\relax% + \vbox to \lb@splitheight{\vss\unvbox\lb@mainbox\vss}}}}% + {% default is top + \dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\vtop to \lb@splitheight{\box\lb@mainbox\vss}}% + }% + }% +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newlength\lb@neededvspace +\newcommand\lb@typeset[1][0pt]{% + \iftoggle{lb@breakable}{% + \lb@setfreevspace + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skiptop+\lb@skipbottom\relax}% + \lb@debug{needed: \the\lb@neededvspace, available: \the\lb@freevspace}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@single@{\lb@mainbox}% + \else + \lb@typeout{longbox needs splitting}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skiptop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \ifdim\dimexpr\lb@freevspace + #1\relax<\textheight\relax % test if we were at a fresh page.. (and prevent infinite recursion) + \lb@debug{failed to split the box, inserting a page break}% + \hrule \@height\z@ \@width\hsize + \lb@eject% + \lb@typeset[\textheight]% try again, but pass \textheight to guard against infinite recursion + \else + % on a fresh page we should not fail anymore.. just output as is.. + % lb@warncannotsplit + \lb@single@{\lb@mainbox}% + \fi + \else + % first part success + \lb@typeout{first part splitted}% + \lb@first@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest + \fi + \fi + }{%\else + \lb@debug{unbreakable box}% + \lb@single@{\lb@mainbox}% always directly output an unbreakable box + }% +} + +\newcommand\lb@typesetrest{% + \lb@setfreevspace% + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skipbottom+\lb@skipbreaktop\relax}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@typeout{output last part of box}% + \lb@last@{\lb@mainbox}% + \else + \lb@debug{split box further}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skipbreaktop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \lb@typeout{failed to split box!}% + \lb@last@{\lb@mainbox}% + \else + % middle part success + \lb@typeout{output middle part of box}% + \lb@middle@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest% continue the iteration... + \fi + \fi +} + +% -------------------------------------------------------- +% Split a long vbox over multiple pages. +% This code is based on similar code in the mdframed package +% -------------------------------------------------------- + +\newlength\lb@splitheight +\newlength\lb@insurance % tiny extra space to ensure our box will really fit +\setlength\lb@insurance{1pt} + +% expects split target height in lb@splitheight, and splits off the start of lb@mainbox to lb@headbox +\newcommand\lb@splitbox{% + \ifdim\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax>\lb@splitheight\relax + % the main box is larger than our target split height.. + \ifdim\lb@extrasplit>\lb@splitheight\relax + % not enough space to bother + \lb@typeout{not enough space on page for a split}% + \setbox\lb@headbox=\vbox{}% empty head + \else + % try a split; lower the split height a bit so we are sure to fit + \advance\lb@splitheight -\lb@insurance\relax + \lb@debug{split: \the\lb@splitheight, from \the\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax}% + \setbox\lb@savebox=\vbox{\unvcopy\lb@mainbox}% save original + \lb@trysplit{\lb@splitheight}% + \ifdim\dimexpr\ht\lb@headbox + \dp\lb@headbox>\lb@splitheight\relax + % too big, bad split. Try other splits.. iterate N times with 1 or 5pt less before giving up + \dimen@=\lb@splitheight\relax + \@tempcnta=\z@\relax + \loop + \ifdim\dimexpr\ht\lb@headbox+\dp\lb@headbox\relax>\lb@splitheight\relax + \ifnum\@tempcnta<50% + \advance\dimen@ by -\p@\relax% try a slightly smaller height.. + \else + \advance\dimen@ by -5\p@\relax% try larger increase after 50pt.. + \fi + \advance\@tempcnta by \@ne\relax + \lb@ignorevbadness + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \lb@trysplit{\dimen@}% + \ifdim\lb@extrasplit<\dimen@\relax\else\lb@splitstop\fi % don't try to split too small + \ifnum\@tempcnta<100\relax\else\lb@splitstop\fi % and not more than N attempts + \repeat% + \ifnum\@tempcnta<100\relax + \dimen@=\dimexpr\lb@splitheight - \ht\lb@headbox - \dp\lb@headbox\relax + \ifdim\dimen@>\option{/longbox/split-badness}\relax + \lb@warnbadsplit{\dimen@}% + \fi + \fi + \fi + \fi + \else + % mainbox fits in our target lb@splitheight + \setbox\lb@headbox=\vbox{\unvbox\lb@mainbox}% + \setbox\lb@mainbox=\vbox{}% + \fi +} + +\newcommand\lb@splitstop{% + \lb@typeout{cannot find a good split}% + \let\iterate\relax + \lb@warncannotsplit + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \setbox\lb@headbox=\vbox{}% empty head + \@tempcnta=\@M\relax +} + +\newcommand\lb@trysplit[1]{% try to split at given height + \lb@typeout{try to split at: \the\dimexpr #1\relax}% + \lb@ignorevbadness + \setbox\lb@headbox=\vsplit\lb@mainbox to #1\relax% + \setbox\lb@headbox=\vbox{\unvbox\lb@headbox}% + \setbox\lb@mainbox=\vbox{\unvbox\lb@mainbox}% +} + +% -------------------------------------------------------- +% The longbox environment uses options to set its options +% -------------------------------------------------------- + + +% keys and styles that can be set once globally +\options{% + /longbox/.new family, +}% + +\options{/longbox,% + % computed + @part-needtop/.new toggle, + @part-needbottom/.new toggle, + @part-height/.new length, + @part-width/.new length, + @part-depth/.new length, + @content-box-height/.new length, + @content-box-width/.new length, + @content-box-depth/.new length, + @breakat-previous/.new length, + @lower/.new length, + % + debug/.new toggle, + verbose/.new toggle, + render/.new value =\lb@render@fbox, + adjust-options/.new value = {\longbox@adjustoptions}, + eject/.new value = {\protect\vfill\protect\eject}, + use-vbox/.new toggle = true, + split-minimum/.new length = {1.5\baselineskip}, + split-badness/.new length = \baselineskip, + % + height-align/.new choice= {top,middle,bottom}, + baseline/.new choice = {bottom,middle,top}, + text-align/.new choice = {default,left,center,right,justify}, + vertical-align/.new choice = {baseline,bottom,middle,top,text-bottom,text-top,super,sub}, + raise/.new length = {0pt}, + baseline-skip/.new toggle =true, + % + height/.new length = -1sp, + width/.new length = -1sp, + outer-height/.new length= -1sp, + outer-width/.new length = -1sp, + insert-before/.new value= {}, + insert-after/.new value = {}, + breakat/.new value = {}, + breakable/.new toggle = false, + skip/.new style = {skip-top=#1,skip-right=#1,skip-bottom=#1,skip-left=#1}, + skip-top/.new length, + skip-right/.new length, + skip-bottom/.new length, + skip-left/.new length, + skip-break-bottom/.new length, + skip-break-top/.new length, +} + +\newcommand\longbox@adjustoptions{% + %\typeout{ standard longbox adjustoptions}% + \lb@debug{ current width=\the\dimexpr\option{/longbox/width}, outer=\the\dimexpr\option{/longbox/outer-width}, linewidth=\the\linewidth}% + \ontoggle{/longbox/debug}{\option@invoke{/longbox/verbose}{true}}% + % adjust height + \ifdim\option{/longbox/height}=-1sp\relax + \ifdim\option{/longbox/outer-height}=-1sp\else + \option@invoke{/longbox/height}% + {\option{/longbox/outer-height}-\option{/longbox/skip-top}-\option{/longbox/skip-bottom}}% + \fi + \fi + % set width + \ifdim\option{/longbox/width}=-1sp\relax + \ifdim\option{/longbox/outer-width}=-1sp\relax + \option@invoke{/longbox/outer-width}{\linewidth}% + \fi + \dimen@=\dimexpr\option{/longbox/outer-width}-\option{/longbox/skip-left}-\option{/longbox/skip-right}\relax + \ifdim\dimen@<\z@\relax\dimen@=\z@\fi + \option@invoke{/longbox/width}{\dimen@}% + \fi + % use a breakbox whenever we are in external vertical mode and not width or height restricted. + \iftoggle{/longbox/use-vbox}{}{% + \ifinner\toggletrue{/longbox/use-vbox}\else + \ifhmode\toggletrue{/longbox/use-vbox}\else + \ifdim\option{/longbox/height}>-1sp\toggletrue{/longbox/use-vbox}\else + \iftoggle{/longbox/breakable}{}{\toggletrue{/longbox/use-vbox}}% + \ifoptionblank{/longbox/breakat}{}{\toggletrue{/longbox/use-vbox}}% + \fi\fi\fi + }% +} + +\newenvironment{longbox}[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \begin{longbox@env}{/longbox}{#1}% +}{\end{longbox@env}} + +\newcommand\lbox[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \longbox@cmd{/longbox}{#1}% +} + +\newcommand*\lb@render@fbox{% + %\typeout{render defaultbox: bgcolor=\bb@bgcolor, needtop=\iftoggle{/longbox/@part-needtop}{true}{false}}% + \@ovdx=\dimexpr\option{/longbox/@part-width} - 2\fboxrule\relax% + \@ovdy=\dimexpr\option{/longbox/@part-height}\relax% + \iftoggle{/longbox/@part-needbottom}% + {\@tempdima=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdima=\dimexpr\fboxrule + \bb@stickout\relax + \advance\bb@height by \@tempdima + \advance\@ovdy by \@tempdima}% + \iftoggle{/longbox/@part-needtop}% + {\@tempdimb=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdimb=\dimexpr\bb@stickout\relax + \advance\bb@height by \@tempdimb + \advance\@ovdy by \@tempdimb}% + % + \hbox{\lower \@tempdima\vbox{% + \vskip -\@tempdimb + \ontoggle{/longbox/@part-needtop}{\lb@debug{toprule wd=\expandafter\the\option{/longbox/width}}\hrule width \option{/longbox/@part-width} height \fboxrule}% + \hbox{% + \vrule width \fboxrule height \@ovdy% + \ifx\bb@bgcolor\@empty + \vrule width \@ovdx height \z@\relax + \else + {\color{\bb@bgcolor}\vrule width \@ovdx height \@ovdy}% + \fi + \vrule width \fboxrule height \@ovdy% + }% + \ontoggle{/longbox/@part-needbottom}{\hrule width \option{/longbox/@part-width} height \fboxrule}% + }}% +} \ No newline at end of file diff --git a/spec/v1.4.0-rc.2/longfbox.sty b/spec/v1.4.0-rc.2/longfbox.sty new file mode 100644 index 00000000..0df01331 --- /dev/null +++ b/spec/v1.4.0-rc.2/longfbox.sty @@ -0,0 +1,1344 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longfbox}[2015/12/01, Daan Leijen, Provides long fbox that can break over pages] + +\RequirePackage{options} +\RequirePackage{longbox} +\RequirePackage{pict2e} +\RequirePackage{ellipse} + +% -------------------------------------------------------- +% Dimension calulations +% -------------------------------------------------------- + +% dimmin/dimmax return minimum or maximum dimension +\providecommand\dim@min[2]{\ifdim#1>#2#2\else #1\fi} +\providecommand\dim@max[2]{\ifdim#1>#2#1\else #2\fi} + +\newcommand*\option@dimmin[2]{\dim@min{\option{#1}}{\option{#2}}} +\newcommand*\option@dimmax[2]{\dim@max{\option{#1}}{\option{#2}}} + + +% -------------------------------------------------------- +% Add a new 'sides' option type +% -------------------------------------------------------- + +\options{ + /handlers/new sides/.new handler = []{ + \ifblank{#2}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#1-top={##1}, #1-right={##2}, #1-bottom={##3}, #1-left={##4}}}}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#2}}}% + \optionsalso{ + #1/.new cmdx = {##1,##2,##3,##4,##5\relax}{,,,,\relax}{% + \ifblank{##2##3##4}{\option{#1/@cmd@sides}{##1}{##1}{##1}{##1}}% + {\ifblank{##3##4}{\option{#1/@cmd@sides}{##1}{##2}{##1}{##2}}% + {\ifblank{##4}{\option{#1/@cmd@sides}{##1}{##2}{##3}{##2}}% + {\option{#1/@cmd@sides}{##1}{##2}{##3}{##4}}% + }% + }% + }, + #1/.type = sides, + }% + },% +} + +\newcommand*\optionlengthlimit[3]{% len, min, max + \letoption{#1}\opt@temp + \ifdim\opt@temp<\dimexpr#2\relax + \option@invoke{#1}{#2}% + \else\ifdim\opt@temp>\dimexpr#3\relax + \option@invoke{#1}{#3}% + \fi\fi +} + +\newcommand*\optionradiuslimit[4]{% r1, r2, min, max + \letoption{#1}\opt@tempa + \letoption{#2}\opt@tempb + \ifdim\opt@tempa<\dimexpr#3\relax\option@invoke{#1}{#3}\fi + \ifdim\opt@tempb<\dimexpr#3\relax\option@invoke{#2}{#3}\fi + \ifdim\dimexpr\opt@tempa + \opt@tempb\relax=\z@\relax\else + \ifdim\dimexpr\opt@tempa+\opt@tempb\relax>\dimexpr#4\relax + \edef\opt@perc{\the\numexpr(\number\dimexpr#4\relax)/% + (\number\dimexpr(\opt@tempa+\opt@tempb)/100\relax)}% + %\typeout{scale:\the\opt@tempa,\the\opt@tempb, by \opt@perc percent to make \the\dimexpr#4\relax}% + \edef\opt@temp{\dimexpr\opt@perc\dimexpr\the\opt@tempa\relax / 100\relax}% + \option@einvoke{#1}{\opt@temp}% + \option@einvoke{#2}{\dimexpr#4 - \opt@temp\relax}% + %\typeout{ scaled to: \the\opt@temp,\the\dimexpr#4 - \opt@temp\relax}% + \fi + \fi +} + + +% \begin{macro}{\trig@atantan} +% \marg{a}\marg{b}\marg{$\alpha$}{dimen$_\mathit{reg}$}\\ +% Assigns $\atan_2(\frac{\sin(\alpha)}{b},\frac{\cos(\alpha)}{a})$ to dimension register \textit{dimen$_\mathit{reg}$}, +% where $a$ and $b$ are dimensions. +% Returns $\alpha$ when $a = b$, or when $a=0$ or $b=0$. +% \begin{macrocode} +\newcommand*\trig@atantan[4]{% + %\typeout{ atantan:(\the#1,\the#2,\the#3, #4)}% + \@tempdima\dimexpr#1\relax + \@tempdimb\dimexpr#2\relax +% \end{macrocode} +% If $a = b$, we have a circle and the result is $\alpha$. +% \begin{macrocode} + \ifdim\@tempdima=\@tempdimb + #4\dimexpr#3\relax + \else\ifdim\@tempdima=\z@ + #4\dimexpr#3\relax + \else\ifdim\@tempdimb=\z@ + #4\dimexpr#3\relax + \else + \edef\trig@temp{\strip@pt\dimexpr#3\relax}% + \CalculateSin{\trig@temp}\CalculateCos{\trig@temp}% + \@tempdimc\dimexpr1\p@ * \dimexpr\UseSin{\trig@temp}\p@\relax/\@tempdimb\relax + \@tempdimd\dimexpr1\p@ * \dimexpr\UseCos{\trig@temp}\p@\relax/\@tempdima\relax + \pIIe@atantwo{\@tempdimc}{\@tempdimd}\dimen@ + \ifdim\dimen@<\z@ + \ifdim\dimexpr#3\relax<\z@\else\advance\dimen@360\p@\fi + \fi + \@tempdima\dimexpr#3 - \dimen@\relax + \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi + \ifdim\@tempdima<360\p@\else\advance\dimen@360\p@\fi + %\typeout{atan: \the\dimexpr#3\relax versus. \the\dimen@ }% + #4\dimen@ + \fi\fi\fi +} +% \end{macrocode} +% \end{macro} + +% rough approximation of the perimeter; +% if |radius-x == radius-y| = 0 (a circle), the approximation is precise. +% otherwise, works best when |angle2-angle1| <= 45 and gets worse from there on. +\newcommand*\ellip@letarcperimeter[5]{% 'radius-x', 'radius-y', 'angle-1', 'angle-2', '\result' + \@tempdima\dimexpr#3\relax + \@tempdimb\dimexpr#4\relax + \@tempdimc\dimexpr\@tempdima - \@tempdimb\relax + \ifdim\@tempdimc<\z@\@tempdimc-\@tempdimc\fi + \ifdim#1=#2\relax% circle? + \edef\@tempa{\strip@pt\@tempdimc}% angle difference delta as factor + \dimen@\@tempa\dimexpr#1\relax% r*delta + \dimen@0.017453\dimen@% (2*pi/360) * r * delta = 2*pi*r * (delta/360) + \else% ellipse: take the distance between the points on the ellipse, works pretty good if delta <= 45, and ok'ish for delta <= 90 + \@ovro\dimexpr#1\relax + \@ovri\dimexpr#2\relax + \edef\fbox@tempa{\strip@pt\@tempdima}% + \edef\fbox@tempb{\strip@pt\@tempdimb}% + \pIIe@ellip@sincost{\fbox@tempa}{\fbox@tempb}% + \@tempdima\@ellipcosone\@ovro + \@tempdimb\@ellipsinone\@ovri + \@tempdimc\@ellipcostwo\@ovro + \@tempdimd\@ellipsintwo\@ovri + \advance\@tempdimc by -\@tempdima% + \advance\@tempdimd by -\@tempdimb% + \pIIe@ellip@csqrt{\@tempdimc}{\@tempdimd}{\dimen@}% + %\typeout{ distance: \the\dimen@, from (x,y)=(\the\@tempdimc,\the\@tempdimd), radii=(\the#1,\the#2), angles=(\the#3,\the#4)}% + \fi + \edef#5{\the\dimen@}% +} + + +% ------------------------------------------------------------------------------ +% Borders using the picture environment +% ------------------------------------------------------------------------------ + +\newcommand*\fbox@border@pict{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \begingroup + \hbox{% + \unitlength\p@ + \begin{picture}(0,0)(0,\optionunit{/fbox/@border-box-height})% bottom-left is origin + % markers + \ontoggle{/fbox/show-markers}{% + \linethickness{\option{/fbox/marker-width}}% + \optioncolor{/fbox/marker-color}% + \fbox@rect{0pt}{0pt}{\option{/fbox/@border-box-width}}{\option{/fbox/@border-box-height}}% + \fbox@rect{\option{/fbox/border-left-width}}{\option{/fbox/border-\fbox@bottom-width}}% + {\option{/fbox/@border-box-width}-\option{/fbox/border-right-width}}% + {\option{/fbox/@border-box-height}-\option{/fbox/border-\fbox@top-width}}%S + }% + %compute corner coordinates + \fbox@border@calccorners + %put down the background color + \fbox@border@colorbackground + \option{/fbox/picture-insert-before}% + %put down the sides + \fbox@border@side{3}{-2}{0}%top + \fbox@border@side{5}{-4}{3}%left + \fbox@border@side{-6}{7}{2}%bottom + \fbox@border@side{-8}{1}{1}%right + \end{picture}% + }% + \endgroup + \fi +} + +\newcommand*\fbox@border@pict@after{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \letoption{/fbox/picture-insert-after}\fbox@insertafter + \eifblank{\fbox@insertafter}{}{% + \begingroup + \hbox{% + \begin{picture}(0,0)(0,0)% bottom-left is origin + \fbox@insertafter + \end{picture}% + }% + \endgroup + }% + \fi +} + +\newcommand*\fbox@border@side[3]{% + \fbox@setoct@angles{#1}% + \edef\fbox@style{\option{/fbox/border-\fbox@side-style}}% + \optioncolor{/fbox/border-\fbox@side-color}% + \option{/fbox/picture-side-insert-before}% + \ifcsdef{fbox@border@pict@\fbox@style}% + {\csuse{fbox@border@pict@\fbox@style}{#1}{#2}{#3}}% + {\PackageWarning{longfbox}{Unknown style "\fbox@style". Using "solid" instead.}% + \fbox@border@pict@solid{#1}{#2}{#3}}% + \option{/fbox/picture-side-insert-after}% +} + +% ------------------------------------------------------------------------------ +% Define standard border styles for the picture environment +% +% a style has the form \fbox@border@pict@ + + + + + + +
+
+
+
P4Runtime Specification
+
version 1.3.0
+
+
+
The P4.org API Working Group
+
2022-03-23
+
+

Abstract. P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.

+ + +

1. Introduction and Scope

+

This document is published by the P4.org API Working Group, which was +chartered [17] to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called P4Runtime. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +https://github.com/p4lang/p4runtime/tree/v1.3.0/proto. +

1.1. P4 Language Version Applicability

+

P4Runtime is designed to be implemented in conjunction with the P416 language +version or later. P414 programs should be translated into P416 to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P416 1.0, but were introduced in P416 1.1.0 [29]. For +this version of P4Runtime, we recommend using P416 1.2.1 [1]. +

1.2. In Scope

+

This specification document defines the semantics of P4Runtime messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime: +

+
    +
  • Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA) [19] externs (e.g. Counters, Meters, Action +Profiles, ). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0. +
  • +
  • Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism. +
  • +
  • Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy. +
  • +
  • Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities. +
  • +
  • Packet I/O to enable streaming packets to & from the control plane. +
  • +
  • Batching support, with different atomicity guarantees. +
  • +
  • In-the-field device-reconfiguration with a new P4 data plane. +
+ +

The following are in the scope of this specification document: +

+
    +
  • Rationale for the P4Runtime design. +
  • +
  • Reference architecture and use-cases for deploying a P4Runtime service. +
  • +
  • Detailed description of the API semantics. +
  • +
  • Requirements for conformant implementations of the API. +
+

1.3. Not In Scope

+

The following are not in scope of P4Runtime: +

+
    +
  • Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +[35]. An open source implementation of these APIs is also in progress +as part of the Stratum project [37]. +
  • +
  • Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures. +
+ +

The following are not in scope of this specification document: +

+
    +
  • Description of the P4 programming language; it is assumed that the reader is +already familiar with P416 [1]. +
  • +
  • Descriptions of gRPC and Protobuf files in general. +
  • +
  • Controller role definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme. +
+

2. Terms and Definitions

+
+
arbitration
+
Refers to the process through which P4Runtime ensures that at any given +time, there is a single primary controller (i.e. a client with write access) +for a given role. Also referred to as “client arbitration”. +
+
client
+
The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +
+
COS
+
Class of Service. +
+
device
+
Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +
+
entity
+
An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +
+
gRPC
+
gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +[9]. +
+
HA
+
High-Availability. Refers to a redundancy architecture. +
+
Instrumentation
+
The part of the P4Runtime server which implements the calls to the device or +target native “SDK” or backend. +
+
IPC
+
Inter-Process Communication. +
+
P4 Blob
+
A more colloquial term for P4 Device Config (Blob = Binary Large Object). +
+
P4 Device Config
+
The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its “program.” +
+
P4Info
+
Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +
+
P4RT
+
Abbreviation for P4Runtime. +
+
Protobuf (Protocol Buffers)
+
The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See [21]. +
+
PSA
+
Portable Switch Architecture [19]; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +
+
RPC
+
Remote Procedure Call. +
+
RTT
+
Round-trip time. +
+
SDN
+
Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network controller. +
+
SDN port
+
A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +
+
server
+
The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +
+
stream
+
Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (StreamChannel), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and client arbitration, among other things. +
+
switch config
+
Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +
+
target
+
The hardware or software entity which “executes” the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with “device”. +
+
URI
+
Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.

3. Reference Architecture

+

Figure 1 represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. P4Runtime only grants write access to a +single primary controller for each read/write entity. A role defines a grouping +of P4 entities. P4Runtime allows for a primary controller for each role, and a +role-based client arbitration scheme ensures only one controller has +write access to each read/write entity, or the pipeline config itself. Any +controller may perform read access to any entity or the pipeline config. Later +sections describe this in detail. For the sake of brevity, the term controller +may refer to one or more controllers. +

+

The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +[15]. It may be compiled via protoc the Protobuf compiler +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server. +

+

Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository [16]. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, e.g. via callbacks, thus reducing the burden of implementing +P4Runtime. +

+

The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard. +

+

The controller can also set the ForwardingPipelineConfig, which amounts to +installing and running the compiled P4 program output, which is included in the +p4_device_config Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +ForwardingPipelineConfig to retrieve the device config and the P4Info. +

+
+

reference-architecture +

+
+ +
Figure 1. P4Runtime Reference Architecture.

3.1. P4Runtime Service Implementation

+

The P4Runtime API is implemented by a program that runs a gRPC server which +binds an implementation of auto-generated P4Runtime Service interface. This +program is called the “P4Runtime server.” The server must listen on TCP port +9559 by default, which is the port that has been allocated by IANA for the +P4Runtime service. Servers should allow users to override the default port +using a configuration file or flag when starting the server. Uses of other +port numbers as the default should be discontinued. +

3.1.1. Security concerns

+

Appropriate measures and security best practices must be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. Mutual TLS (mTLS) may +be used to facilitate the authentication of the client by the server and +vice-versa. +

3.2. Idealized Workflow

+

In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the ForwardingPipelineConfig +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a SetForwardingPipelineConfig +RPC. Metadata in the P4Info describes both the overall program itself +(PkgInfo) as well as all entity instances derived from the P4 program +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise “handle” used in API +calls. +

+

In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible. +

+

In some use cases, it is expected that a controller will store a +collection of multiple P4 “packages”, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the ForwardingPipelineConfig from the target via the +GetForwardingPipelineRequest RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state. +

3.3. P4 as a Behavioral Description Language

+

P4 can be considered a behavioral description of a switching device which may or +may not execute “P4” natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a SetForwardingPipelineRequest to +change its pipeline “program”, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device. +

+

While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API. +

+

In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the PkgInfo +message as well as the embedded doc fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections. +

3.4. Alternative Workflows

+

Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary. +

3.4.1. P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config

+

In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +p4_device_config. The device's configuration might be derived via some other +means to implement the P4 source code's intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane. +

3.4.2. No P4 Source Available, P4Info Available

+

In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are: +

+
    +
  1. +

    The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security. +

  2. +
  3. +

    The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info. +

+ +

As discussed in Section 3.3, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, e.g. documentation. +

3.4.3. Partial P4Info and P4 Source are Available

+

In this situation, a subset of the target's pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code. +

3.4.4. P4Info Role-Based Subsets

+

In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more. +

3.5. P4Runtime State Across Restarts

+

All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade. +

4. Controller Use-cases

+

P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +section. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime's flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex. +

4.1. Single Embedded Controller

+

Figure 2 shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases. +

+

P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC. +

+
+

single-embedded-controller +

+
+ +
Figure 2. Use-Case: Single Embedded Controller

4.2. Single Remote Controller

+

Figure 3 shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections. +

+
+

single-remote-controller +

+
+ +
Figure 3. Use-Case: Single Remote Controller

4.3. Embedded + Single Remote Controller

+

Figure 4 illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller. +

+

For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables. +

+
+

embedded-plus-single-remote-controller +

+
+ +
Figure 4. Use-Case: Embedded Plus Single Remote Controller

4.4. Embedded + Two Remote Controllers

+

Figure 5 illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +e.g. routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership. +

+
+

embedded-plus-two-remote-controllers +

+
+ +
Figure 5. Use-Case: Embedded Plus Two Remote Controllers

4.5. Embedded Controller + Two High-Availability Remote Controllers

+

Figure 6 illustrates a single +embedded controller plus two remote controllers in an active-standby (i.e. +primary-backup) HA (High-Availability) configuration. Controller #1 is the +active controller and is in charge of some entities. If it fails, Controller #2 +takes over and manages the tables formerly owned by Controller #1. The mechanics +of HA architectures are beyond the scope of this document, but the P4Runtime +role-based client arbitration scheme supports it. +

+
+

embedded-plus-two-remote-ha-controllers +

+
+ +
Figure 6. Use-Case: Embedded Plus Two Remote High-Availability Controllers

5. Client Arbitration and Controller Replication

+

The P4Runtime interface allows multiple clients (i.e. controllers) to be +connected to the P4Runtime server running on the device at the same time for the +following reasons: +

+
    +
  1. +

    Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, “roles” (or “realms”) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +primary and the rest are backups. Role definition, i.e. how P4 entities get +assigned to each role, is out-of-scope of this document. +

  2. +
  3. +

    Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby backup controllers. These can already have a connection +open, which can help them become primary more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved. +

+ +

To support multiple controllers, P4Runtime uses the streaming channel (available +via StreamChannel RPC) for session management. The workflow is described as +follows: +

+
    +
  • +

    Each controller instance (e.g. a controller process) can participate in one or +more roles. For each (device_id, role), the controller receives an +election_id. This election_id can be the same for different roles and/or +devices, as long as the tuple (device_id, role, election_id) is +unique. For each (device_id, role) that the controller wishes to +control, it establishes a StreamChannel with the P4Runtime server +responsible for that device, and sends a MasterArbitrationUpdate message +containing that tuple of (device_id, role, election_id) values. The +P4Runtime server selects a primary independently for each (device_id, +role) pair. The primary is the client that has the highest election_id +that the device has ever received for the same (device_id, +role) values. A connection between a controller instance and a device id + which involves a persistent StreamChannel can be referred to as a +P4Runtime client. +

    +

    Note that the P4Runtime server does not assign a role or election_id to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the election_id values used for each +StreamChannel. The P4Runtime server only keeps track of the (device_id, +role, election_id) of each StreamChannel that has sent a successful +MasterArbitrationUpdate message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +WriteRequest message to identify which client is making the WriteRequest, +not only the election_id. This enables controllers to re-use the same +numeric election_id values across different (device_id, role) +pairs. P4Runtime does not require election_id values be reused across such +different (device_id, role) pairs; it allows it. +

  • +
  • +

    To start a controller session, a controller first opens a bidirectional stream +channel to the server via the StreamChannel RPC for each device. This stream +will be used for two purposes: +

    +
      +
    • +

      Session management: As soon as the controller opens the stream +channel, it sends a StreamMessageRequest message to the switch. The +controller populates the MasterArbitrationUpdate field in this message +using its role and election_id, as well as the device_id of the +device. Note that the status field in the MasterArbitrationUpdate is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below. +

    • +
    • +

      Streaming of notifications (e.g. digests) and packet I/O: The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the primary controller can participate in +packet I/O. This feature is explained in more details in the Packet +I/O section. +

    + +

    Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state. +

  • +
  • +

    Note that the stream is opened per device. In case a switching platform has +multiple devices (e.g. multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different primary clients for +different devices. In this case, it is the responsibility of the P4Runtime +server to keep track of the primary for each device (and role). More +specifically, the P4Runtime server will know which stream corresponds to the +primary controller for each pair of (device_id, role) at any point of +time. +

  • +
  • +

    The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered “offline” or +“dead” as soon as its stream channel to the switch is broken. When a primary +channel gets broken: (i) an advisory message is sent to all other controllers +for that device_id and role, as described in the +following section (ii) the P4Runtime server +will be without a primary controller, until a client sends a successful +MasterArbitrationUpdate (as per the rules in a +later section). +

  • +
  • +

    The mechanism via which the controller receives the P4Runtime server details +which includes the device_id, ip and port, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +device_id) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks. +

+ +

gRPC enables the server to identify which client originated each message in the +StreamChannel stream. For example, the C++ gRPC library [10] in +synchronous mode enables a server process to cause a function to be called when +a new client creates a StreamChannel stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +StreamChannel is closed normally (or broken, e.g. because a client process +unexpectedly terminated). Thus the server can easily associate all +StreamChannel messages received from the same client, because they are +processed within the context of the same function call. +

+

A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values device_id, role, and election_id in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods [8] that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server. +

5.1. Default Role

+

A controller can omit the role message in MasterArbitrationUpdate. This +implies the “default role”, which corresponds to “full pipeline access”. +This also implies that a default role has a role_id of "" (default). +If using a default role, all RPCs from the controller (e.g. Write) must +leave the role unset. +

5.2. Role Config

+

The role.config field in the MasterArbitrationUpdate message sent by the +controller describes the role configuration, i.e. which operations are in the +scope of a given role. In particular, the definition of a role may include the +following: +

+
    +
  • A list of P4 entities for which the controller may issue Write updates and +receive notification messages (e.g. DigestList and +IdleTimeoutNotification). +
  • +
  • Whether the controller is able to receive PacketIn messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketIn messages should be sent to the controller. +
  • +
  • Whether the controller is able to send PacketOut messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketOut messages are allowed to be sent by the controller. +
+ +

An unset role.config implies “full pipeline access” (similar to the default +role explained above). In order to support different role definition schemes, +role.config is defined as an Any Protobuf message [31]. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion. +

+

It is the job of the P4Runtime server to remember the role.config for every +device_id and role pair. +

5.3. Rules for Handling MasterArbitrationUpdate Messages Received from Controllers

+
    +
  1. +

    If the MasterArbitrationUpdate message is received for the first time on +this particular channel (i.e. for a newly connected controller): +

    +
      +
    1. +

      If device_id does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +NOT_FOUND error. +

    2. +
    3. +

      If the election_id is set and is already used by another controller for +the same (device_id, role), the P4Runtime server shall terminate +the stream by returning an INVALID_ARGUMENT error. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the number of open streams for the given (device_id, role) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a RESOURCE_EXHAUSTED error. +

    8. +
    9. +

      Otherwise, the controller is added to a list of connected controllers for +the given (device_id, role) and the server remembers the +controllers device_id, role and election_id for this gRPC +channel. See below for the rules to determine if this controller becomes +a primary or backup, and what notifications are sent as a consequence. +

    +
  2. +
  3. +

    Otherwise, if the MasterArbitrationUpdate message is received from an +already connected controller: +

    +
      +
    1. +

      If the device_id does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. +

    2. +
    3. +

      If the role does not match the current role assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. If the controller wishes to change its role, +it must close the current stream channel and open a new one. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the election_id is set and is already used by another controller +(excluding the controller making the request) for the same +(device_id, role), the P4Runtime server shall terminate the stream +by returning an INVALID_ARGUMENT error. +

    8. +
    9. +

      Otherwise, the server updates the election_id it has stored for this +controller. This change might cause a change in the primary client (this +controller might become primary, or the controller might have downgraded +itself to a backup, see below), as well as notifications being sent to +one or more controllers. +

    +
+ +

If the MasterArbitrationUpdate is accepted by either of the two steps above +(cases 1.5. and 2.5. above), then the server determines if there are changes in +the primary client. Let election_id_past be the highest election ID the server +has ever seen for the given device_id and role (including the one of the +current primary if there is one). +

+
    +
  1. +

    If election_id is greater than or equal to election_id_past, then the +controller becomes, or stays, primary. The server updates the role +configuration to role.config for the given role. Furthermore: +

    +
      +
    1. +

      If there was no primary for this device_id and role before and +there are no Write requests still processing from a previous primary, +then the server immediately sends an advisory notification to all +controllers for this device_id and role. See the +following section for the format of the +advisory message. +

    2. +
    3. +

      If there was a previous primary, including this controller, or Write +requests in flight, then the server carries out the following steps +(in this order): +

      +
        +
      1. +

        The server stops accepting Write requests from the previous primary +(if there is one). At this point, the server will reject all Write +requests with PERMISSION_DENIED. +

      2. +
      3. +

        The server notifies all controllers other than the new primary client +of the change by sending the advisory notification described in +the following section. +

      4. +
      5. +

        The server will finish processing any Write requests that have +already started. If there are errors, they are reported as usual to +the previous primary. If the previous primary has already +disconnected, any possible errors are dropped and not reported. +

      6. +
      7. +

        The server now accepts the current controller as the new primary, +thus accepting Write requests from this controller. The server +updates the highest election ID (i.e. election_id_past) it has seen +for this device_id and role to election_id. +

      8. +
      9. +

        The server notifies the new primary by sending the advisory message +described in the following section. +

      +
    +
  2. +
  3. +

    Otherwise, the controller becomes a backup. If the controller was previously +a primary (and downgraded itself), then an advisory message is sent to all +controllers for this device_id and role. Otherwise, the advisory +message is only sent to the controller that sent the initial +MasterArbitrationUpdate. See the +following section for the format of the +advisory message. +

+

5.4. Client Arbitration Notifications

+

For any given device_id and role, any time a new primary is chosen, a +primary downgrades its status to a backup, a primary disconnects, or the +role.config is updated by the primary, all controllers for that +(device_id, role) are informed of this by sending a +StreamMessageResponse. The MasterArbitrationUpdate is populated as follows: +

+
    +
  • +

    device_id and role as given. +

  • +
  • +

    role.config is set to the role configuration the server received most +recently in a MasterArbitrationUpdate from a primary. +

  • +
  • +

    election_id is populated as follows: +

    +
      +
    • +

      If there has not been any primary at all, the election_id is left unset. +

    • +
    • +

      Otherwise, election_id is set to the highest election ID that the server +has seen for this device_id and role (which is the election_id of +the current primary if there is any). +

    +
  • +
  • +

    status is set differently based on whether the notification is sent to the +primary or a backup controller: +

    +
      +
    • +

      If there is a primary: +

      +
        +
      • +

        For the primary, status is OK (with status.code set to +google.rpc.OK). +

      • +
      • +

        For all backup controllers, status is set to non-OK (with +status.code set to google.rpc.ALREADY_EXISTS). +

      +
    • +
    • +

      Otherwise, if there is no primary currently, for all backup controllers, +status is set to non-OK (with status.code set to +google.rpc.NOT_FOUND). +

    +
+ +

Note that on primary client changes with outstanding Write request, some +notifications might be delayed, see the +previous section for details. +

6. The P4Info Message

+

The purpose of P4Info was described under +Reference Architecture. +Here we describe the various +components. +

6.1. Common Messages

+

These messages appear nested within many other messages. +

6.1.1. Documentation Message

+

Documentation is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers. +

+
+
+
message Documentation {
+  // A brief description of something, e.g. one sentence
+  string brief = 1;
+  // A more verbose description of something.
+  // Multiline is accepted. Markup format (if any) is TBD.
+  string description = 2;
+}

6.1.2. Preamble Message

+

The preamble serves as the “descriptor” for each entity and contains the unique +instance ID, name, alias, annotations and documentation. +

+
+
+
message Preamble {
+  // ids share the same number-space; e.g. table ids cannot overlap with counter
+  // ids. Even though this is irrelevant to this proto definition, the ids are
+  // allocated in such a way that it is possible based on an id to deduce the
+  // resource type (e.g. table, action, counter, ...). This means that code
+  // using these ids can detect if the wrong resource type is used
+  // somewhere. This also means that ids of different types can be mixed
+  // (e.g. direct resource list for a table) without ambiguity. Note that id 0
+  // is reserved and means "invalid id".
+  uint32 id = 1;
+  // fully qualified name of the P4 object, e.g. c1.c2.ipv4_lpm
+  string name = 2;
+  // an alias (alternative name) for the P4 object, probably shorter than its
+  // fully qualified name. The only constraint is for it to be unique with
+  // respect to other P4 objects of the same type. By default, the compiler uses
+  // the shortest suffix of the name that uniquely identifies the object. For
+  // example if the P4 program contains two tables with names s.c1.t and s.c2.t,
+  // the default aliases will respectively be c1.t and c2.t. In the future, the
+  // P4 programmer may also be able to override the default alias for any P4
+  // object (TBD).
+  string alias = 3;
+  repeated string annotations = 4;
+  // Optional. If present, the location of `annotations[i]` is given by
+ // `annotation_locations[i]`.
+  repeated SourceLocation annotation_locations = 7;
+  // Documentation of the entity
+  Documentation doc = 5;
+  repeated StructuredAnnotation structured_annotations = 6;
+}

6.1.3. Annotating P4 Entities with Documentation

+

P4 entities may be annotated using the following annotations: +

+
+
+
@brief(string...)
+@description(string...)
+

Attaching either or both of these annotations to an entity will generate a +P4Info Documentation Message, which in turn will +appear in the Preamble Message for the entity. +

+

The P4 compiler should not emit annotation messages in the P4Info for these +specific cases; instead, it should generate the Documentation messages as +described. +

+

The following example shows documentation annotations for a table entity: +

+
+
+
@brief("Match IPv4 addresses to next-hop MAC and port")
+@description("Match IPv4 addresses to next-hop MAC and port. \
+Uses LPM match type.")
+table my_ipv4_lkup {
+  ...
+}

6.1.4. Structured Annotations

+

P4 supports both unstructured and structured annotations [13]. +Unstructured annotations of the form MyAnno1 or MyAnno2(body-content) can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +MyAnno3[] or MyAnno4[kvList|expressionList] have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this. +

+

The annotations described up to this point, e.g. @brief(), have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as repeated string annotations fields in the various messages. +Similarly, structured annotations are represented in repeated +StructuredAnnotation structured_annotations fields which are siblings to the +unstructured annotations. The structured_annotations contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations. +

+

The structured annotation messages are defined in p4types.proto. +

+
+
+
message KeyValuePair {
+  string key = 1;
+  Expression value = 2;
+}
+
+message KeyValuePairList {
+  repeated KeyValuePair kv_pairs = 1;
+}
+
+message Expression {
+  oneof value {
+    string string_value = 1;
+    int64 int64_value = 2;
+    bool bool_value = 3;
+  }
+}
+
+message ExpressionList {
+  repeated Expression expressions = 1;
+}
+
+message StructuredAnnotation {
+  string name = 1;
+  oneof body {
+    ExpressionList expression_list = 2;
+    KeyValuePairList kv_pair_list = 3;
+  }
+  // Optional. Location of the '@' symbol of this annotation in the source code.
+  SourceLocation source_location = 4;
+}
+

The StructuredAnnotation message can represent either a KeyValuePairList +or an ExpressionList. +

+

The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The p4c +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don't match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler may print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions. +

+

The following invariants hold: +

+
    +
  1. +

    For any P4 entity, there are no two StructuredAnnotations that have the +same name. +

  2. +
  3. +

    Within a KeyValuePairList, there are no two KeyValuePairs that have the +same key. +

+
6.1.4.1. Structured Annotation Examples
+

We omit the source_location field in the following examples. +

+

Empty Expression List +

+
+
+
@Empty[]
+table t {
+    ...
+}
+

The generated P4Info will contain the following. +

+
+
+
structured_annotations {
+  name: "Empty"
+}
+

Mixed Expression List +

+
+
+
#define TEXT_CONST "hello"
+#define NUM_CONST 6
+@MixedExprList[1,TEXT_CONST,true,1==2,5+NUM_CONST]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedExprList"
+  expression_list {
+    expressions {
+      int64_value: 1
+    }
+    expressions {
+      string_value: "hello"
+    }
+    expressions {
+      bool_value: true
+    }
+    expressions {
+      bool_value: false
+    }
+    expressions {
+      int64_value: 11
+    }
+  }
+}
+

kvList of Mixed Expressions +

+
+
+
@MixedKV[label="text", my_bool=true, int_val=2*3]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedKV"
+  kv_pair_list {
+    kv_pairs {
+      key: "label"
+      value {
+        string_value: "text"
+      }
+    }
+    kv_pairs {
+      key: "my_bool"
+      value {
+        bool_value: true
+      }
+    }
+    kv_pairs {
+      key: "int_val"
+      value {
+        int64_value: 6
+      }
+    }
+  }
+}

6.1.5. SourceLocation Message

+

A source location describes a location within a .p4-source file. The +SourceLocation message is defined in p4types.proto as follows: +

+
+
+
// Location of code relative to a given source file.
+message SourceLocation {
+  // Path to the source file (absolute or relative to the working directory).
+  string file = 1;
+  // Line and column numbers within the source file, 1-based.
+  int32 line = 2;
+  int32 column = 3;
+}
+

We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations. +

+

The SourceLocation message associated with an annotation holds the location of +the @ symbol introducing the annotation in the P4 source code; the message can +be found in the following place: +

+
    +
  • +

    For unstructured annotations, every message containing a field +repeated string annotations also contains a field +repeated SourceLocation annotation_locations. The field must either be empty + or match the size of annotations. In the latter case, the i-th member of +annotation_locations is the source location of the i-th member of +annotations. +

  • +
  • +

    For structured annotations, every StructuredAnnotation message contains +an optional field SourceLocation source_location holding its source +location, if present. +

+

6.2. PkgInfo Message

+

The PkgInfo message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. PkgInfo can be extracted +and used to facilitate “browsing” of available P4 programs from a +library. Although all fields are technically “optional,” every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included. +

+
+
+
// Can be used to manage multiple P4 packages.
+message PkgInfo {
+  // a definitive name for this configuration, e.g. switch.p4_v1.0
+  string name = 1;
+  // configuration version, free-format string
+  string version = 2;
+  // brief and detailed descriptions
+  Documentation doc = 3;
+  // Miscellaneous metadata, free-form; a way to extend PkgInfo
+  repeated string annotations = 4;
+  // the target architecture, e.g. "psa"
+  string arch = 5;
+  // organization which produced the configuration, e.g. "p4.org"
+  string organization = 6;
+  // contact info for support,e.g. "tech-support@acme.org"
+  string contact = 7;
+  // url for more information, e.g. "http://support.p4.org/ref/p4/switch.p4_v1.0"
+  string url = 8;
+  // Miscellaneous metadata, structured; a way to extend PkgInfo
+  repeated StructuredAnnotation structured_annotations = 9;
+}

6.2.1. Annotating P4 code with PkgInfo

+

A P4 progam's PkgInfo may be declared using one or more of the following +annotations, attached to the main block only: +

+
+
+
@pkginfo(key=value)
+@pkginfo(key=value[,key=value,...])
+@brief("A brief description")
+@description("A longer\
+description")
+@custom_annotation(...)
+@another_custom_annotation(...)
+

Above we see several different types of annotations: +

+
    +
  • +

    @pkginfo - This is used to populate a specific field within the PkgInfo +message. Multiple @pkginfo annotations are allowed. For compactness, +multiple key-value pairs can appear in a single @pkginfo annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The keys must be from +among the message fields inside PkgInfo, for example, name, version, +etc. Each key-value pair assigns a value to the corresponding field inside the +single PkgInfo message for the program's P4Info. One exception is that the +Documentation field of PkgInfo must be expressed as individual +@description and @brief annotations, see next bullets. The key arch will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself. +

  • +
  • +

    @brief - This will populate the PkgInfo.doc.brief message field. +

  • +
  • +

    @description - This will populate the PkgInfo.doc.description message +field +

  • +
  • +

    @<anything else> - This will create a PkgInfo.annotation entry +

+ +

Declaring one or more of these annotations on main will +generate a single corresponding PkgInfo message in the P4Info as described in +PkgInfo Message. +

+

The following example shows @pkginfo annotations using a mixture of single and +multiple key-value pairs. It also shows @brief and @description annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the PkgInfo message. The custom annotations will +be appended to the PkgInfo.annotations list. +

+
+
+
@pkginfo(name="switch.p4",version="2")
+@pkginfo(organization="p4.org")
+@pkginfo(contact="info@p4.org")
+@pkginfo(url="www.p4.org")
+@brief("L2/L3 switch")
+@description("L2/L3 switch.\
+Built for data-center profile.")
+@my_annotation1(...) // Not well-known, this will appear in PkgInfo annotations
+@my_annotation2(...) // Not well-known, this will appear in PkgInfo annotations
+PSA_Switch(IgPipeline, PacketReplicationEngine(), EgPipeline,
+           BufferingQueueingEngine()) main;

6.3. ID Allocation for P4Info Objects

+

P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(e.g. table, action, counter, ). The most significant 8 bits of the ID +encodes the object type (as per Table 1). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (p4.config.v1.P4Ids.Prefix). These values must +be used (e.g. by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table 2 shows the ID +layout. +

+
+ + + + + + + + + + + + + + + + + + + + + +
8-bit prefix value P4 object type
0x00 Reserved (unspecified)
0x01 Action
0x02 Table
0x03 Value-set
0x04 Controller header (header type with @controller_header annotation)
0x050x0f Reserved (for future P4 built-in objects)
0x10 Reserved (start of PSA extern types)
0x11 PSA Action profiles / selectors
0x12 PSA Counter
0x13 PSA Direct counter
0x14 PSA Meter
0x15 PSA Direct meter
0x16 PSA Register
0x17 PSA Digest
0x180x7f Reserved (for future PSA extern types)
0x80 Reserved (start of vendor-specific extern types)
0x810xfe Vendor-specific extern types
0xff Reserved (max prefix value)
+
+ +
Table 1. Mapping of P4Info object type to 8-bit ID prefix value
+
+ + + + +
MSB bit 31 .. bit 24 bit 23 .. bit 0 LSB
Object type prefix Generated suffix (e.g. by the compiler)
+
+ +
Table 2. Format of P4Info object IDs
+

It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with @id (see Table +3). The compiler must honor the @id annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (i.e. if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same @id value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct. +

+
+ + + + + + + + + + +
P4 declaration(s) Compiler-allocated ID(s)
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) table tA... Error(same ID suffixes for 2 objects of the same type)
@id(0x12ab34) table tB...
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) action act1... 0x0112ab34
+
+ +
Table 3. Example of statically-assigned P4Info object IDs
+

The @id annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively). +

6.4. P4Info Objects

6.4.1. Table

+

Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this table. +

  • +
  • +

    match_fields, a repeated field of type MatchField representing the data to +be used to construct the lookup key matched in this table. Each MatchField +message is defined with the following fields: +

    +
      +
    • +

      id, the uint32 identifier of this MatchField, unique in the scope of +this table. No rules are prescribed on the way MatchField IDs should be +allocated, as long as two MatchField of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the @id annotation, or let the compiler +choose them. +

    • +
    • +

      name, the string representing the name of this MatchField. +

    • +
    • +

      annotations, a repeated field of strings, each one representing a P4 +annotation associated to this match field. +

    • +
    • +

      bitwidth, an int32 value set to the size in bits of this match field. +

    • +
    • +

      match, a oneof describing the match behavior for this field; it can be +either: +

      +
        +
      • match_type, an enum field of type MatchType, which includes all +possible PSA match kinds. +
      • +
      • other_match_type, a string field which can be used to encode any +architecture-specific match type. +
      +
    • +
    • +

      doc, a Documentation message describing this match field. +

    • +
    • +

      type_name, which indicates whether the match field has a user-defined +type; this is useful for +translation. +

    +
  • +
  • +

    action_refs, a repeated ActionRef field representing the set of possible +actions for this table. The ActionRef message is used to reference an action +specified in the same P4Info message and it includes the following fields: +

    +
      +
    • id, the uint32 identifier of the action. +
    • +
    • scope, an enum value which can take one of three values: + TABLE_AND_DEFAULT, TABLE_ONLY and DEFAULT_ONLY. The scope of the + action is determined by the use of the P4 standard annotations + @tableonly and @defaultonly [18]. TABLE_ONLY + (@tableonly annotation) means that the action can only appear within + the table, and never as the default action. DEFAULT_ONLY + (@defaultonly annotation) means that the action can only be used as the + default action. TABLE_AND_DEFAULT is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action. +
    • +
    • annotations, a repeated string field, each one representing a P4 +annotation associated to the action reference in this table. +
    +
  • +
  • +

    const_default_action_id, if this table has a constant default action, this +field will carry the uint32 identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action's +arguments. +

  • +
  • +

    implementation_id, the uint32 identifier of the “implementation” of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (e.g. a PSA ActionProfile or ActionSelector +instance). The table is then referred to as an indirect match table. +

  • +
  • +

    direct_resource_ids, repeated uint32 identifiers for all the direct +resources attached to this table, such as DirectMeter and DirectCounter +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2. +

  • +
  • +

    size, an int64 describing the desired number of table entries that the +target should support for the table. See the “Size” subsection within the +“Table Properties” section of the P416 language specification for details +[30]. +

  • +
  • +

    idle_timeout_behavior, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +Idle-Timeout section). Value can be any of the +IdleTimeoutBehavior enum: +

    +
      +
    • NO_TIMEOUT (default value), which means that idle timeout is not +supported for this table. +
    • +
    • NOTIFY_CONTROL, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +Table Idle Timeout Notifications). +
    +
  • +
  • +

    is_const_table, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime. +

  • +
  • +

    other_properties, an Any Protobuf message [31] to embed +architecture-specific table properties [30] which are not part +of the core P4 language or of the PSA architecture. +

+

6.4.2. Action

+

Action messages are used to specify all possible actions of all match-action +tables. +

+

The Action message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this action +

  • +
  • +

    params, a repeated field of Param messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each Param message contains the +following fields: +

    +
      +
    • id, the uint32 identifier of this parameter. No rules are prescribed +on the way Param IDs should be allocated, as long as two Param of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the @id +annotation, or let the compiler choose them. +
    • +
    • name, the string representing the name of this parameter. +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this parameter. +
    • +
    • bitwidth, an int32 value set to the size in bits of this parameter. +
    • +
    • doc, which describes this parameter using a Documentation message. +
    • +
    • type_name, which indicates whether the action parameter has a +user-defined type; this is useful for +translation. +
    +
+

6.4.3. ActionProfile

+

ActionProfile messages are used to specify all available instances of Action +Profile and Action Selector PSA externs. +

+

PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile member, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime. +

+

PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into groups. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime. +

+

While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same ActionProfile message to describe both. +

+

The ActionProfile message includes the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Action +Profile or Selector. +

  • +
  • +

    table_ids, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector. +

  • +
  • +

    with_selector, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern. +

  • +
  • +

    size, an int64 representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups. +

  • +
  • +

    max_group_size, an int32 which is 0 for an Action Profile, or, for an +Action Selector, represents the maximum sum of all member weights within any +given selector group. The max_group_size must be no larger than size. PSA +programs can use the @max_group_size annotation to provide this value for +Action Selectors. If the annotation is omitted, the P4Info field will default +to 0. +

+

6.4.4. Counter & DirectCounter

+

Counter and DirectCounter messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is: +

+
    +
  • +

    Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index. +

  • +
  • +

    Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table. +

+ +

Both Counter and DirectCounter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this counter +extern instance. +

  • +
  • +

    spec, a message of of type CounterSpec used to describe the compile-time +configuration of this counter. Currently, the CounterSpec message is used to +carry only the counter unit, which can be any of the CounterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES: byte counter. +
    • +
    • PACKETS: packet counter. +
    • +
    • BOTH: combination of both byte and packet counter. +
    +
+ +

For indexed counters, the Counter message contains also a size field, an +int64 representing the maximum number of independent values that can be held +by this counter array. Conversely, the DirectCounter message contains a +direct_table_id field that carries the unit32 identifier of the table to +which this direct counter is attached. +

+

For indexed counters, the Counter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.5. Meter & DirectMeter

+

Meter and DirectMeter messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is: +

+
    +
  • +

    Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +e.g. to set the rate threshold. +

  • +
  • +

    Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table. +

+ +

Both Meter and DirectMeter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this meter +extern instance. +

  • +
  • +

    spec, a message of type MeterSpec used to describe the capabilities of +this meter extern instance. Currently, the MeterSpec message is used to +carry only the meter unit, which can be any of the MeterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES, which signifies that this meter can be configured with rates +expressed in bytes/second. +
    • +
    • PACKETS, for rates expressed in packets/second. +
    +
+ +

For indexed meters, the Meter message contains also a size field, an int64 +representing the maximum number of independent cells that can be held by this +meter. Conversely, the DirectMeter message contains a direct_table_id field +that carries the uint32 identifier of the table to which this direct meter is +attached. +

+

For indexed meters, the Meter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.6. ControllerPacketMetadata

+

ControllerPacketMetadata messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server. +

+

When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet. +

+

Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +@controller_header("packet_in") and @controller_header("packet_out"), +respectively. ControllerPacketMetadata messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages). +

+

A P4Info message can contain at most two ControllerPacketMetadata messages, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message where preamble.name is set to "packet_in" +and "packet_out" for packet-in and packet-out metadata, respectively. +

  • +
  • +

    metadata, a repeated field of type Metadata, where each Metadata message +includes the following fields: +

    +
      +
    • id, a uint32 identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two Metadata of the +same ControllerPacketMetadata message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the @id annotation, or let the compiler choose them. +
    • +
    • name, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below). +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this metadata. +
    • +
    • bitwidth, an int32 representing the size in bits of this metadata. +
    • +
    • type_name, which indicates whether the metadata field has a +user-defined type; this is useful for +translation. +
    +
+ +

As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding ControllerPacketMetadata +messages. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  bit<9> egress_port; /* suggested port where the packet
+                         should be sent */
+  bit<8> queue_id;    /* suggested queue ID */
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  bit<9> ingress_port; /* data plane port ID where
+                          the original packet was received */
+  bit<1> is_clone;     /* 1 if this is a clone of the
+                          original packet */
+}
+
+
+
controller_packet_metadata {
+  preamble {
+    id: 2868916615
+    name: "packet_out"
+    annotations: "@controller_header(\"packet_out\")"
+  }
+  metadata {
+    id: 1
+    name: "egress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "queue_id"
+    bitwidth: 8
+  }
+}
+
+controller_packet_metadata {
+  preamble {
+    id: 2868941301
+    name: "packet_in"
+    annotations: "@controller_header(\"packet_in\")"
+  }
+  metadata {
+    id: 1
+    name: "ingress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "is_clone"
+    bitwidth: 1
+  }
+}
+

Note that the use of @controller_header is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages. +

6.4.7. ValueSet

+

ValueSet messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P416 +specification [39]. +

+

The ValueSet message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Value +Set. +

  • +
  • +

    match, a repeated field of MatchField messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the match_fields repeated field in the +Table message. +

  • +
  • +

    size, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +value_set constructor call. +

+ +

According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of bit<W>, +tuple, or struct [26]. The rest of this section looks at all 3 of +these cases and gives an example ValueSet message when appropriate. +

+
    +
  1. +

    If the type parameter is bit<W>, match will include exactly one +MatchField message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used): +

    +
      +
    • id: set to 1 +
    • +
    • bitwidth: set to the value of W +
    • +
    • match_type: set to EXACT +
    +
+ +
+
+
@id(1) value_set<bit<8> >(4) pvs;
+select (hdr.f8) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    bitwidth: 8
+    match_type: EXACT
+  }
+  size: 4
+}
+
    +
  1. +

    If the type parameter is a tuple, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program. +

  2. +
  3. +

    If the type parameter is a struct, this version of P4Runtime requires that +all the fields of the struct be of type bit<W> (where W can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +match field will include one MatchField message for each field in the +struct, with the following fields: +

    +
      +
    • id: must be unique with respect to the other match entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +@id annotation, or let the compiler choose them. +
    • +
    • name: set to the name of the corresponding struct field. +
    • +
    • annotations: set to the list of P4 annotations associated with the struct +field, except for the @match annotation, if present (see the match field +below). +
    • +
    • bitwidth: set to the value of W for the corresponding struct field. +
    • +
    • type_name, which indicates whether the struct field has a user-defined +type; this is useful for +translation. +
    • +
    • match: by default match_type is set to EXACT; the P4 programmer can +specify a different match type by using the @match annotation +[26]. +
    • +
    • doc: documentation associated with the struct field. +
    +
+ +
+
+
struct match_t {
+  @id(1) bit<8> f8;
+  @id(2) @match(ternary) bit<16> f16;
+  @id(3) @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

In the above example, the @id annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs. +

+

Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a user-defined +type that resolves to a bit<W>, or a struct where +one or more fields is a user-defined type that +resolves to a bit<W>. For each MatchField that corresponds to a user-defined +type, the type_name field must be set to the appropriate value (i.e. the name +of the type). +

6.4.8. Register

+

Register messages are used to specify all possible instances of Register PSA +externs. +

+

Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime. +

+

The Register message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this register +instance. +

  • +
  • +

    type_spec, which specifies the data type stored by this register, expressed +using a P4DataTypeSpec message (see section on Representation of Arbitrary +P4 Types). +

  • +
  • +

    size, an int32 value representing the total number of independent register +cells available. +

  • +
  • +

    index_type_name, which indicates whether the register index has a +user-defined type. This is useful for +translation. The underlying built-in type +must be a fixed-width unsigned bitstring (bit<W>). +

+

6.4.9. Digest

+

Digest messages are used to specify all possible instances of Packet Digest +PSA externs. +

+

A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages. +

+

The Digest message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this digest +instance. +

  • +
  • +

    type_spec, which specifies the data type of an individual digest +notification using a P4DataTypeSpec message (see section on Representation +of Arbitrary P4 Types). +

+

6.4.10. Extern

+

Extern messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one Extern message instance in P4Info. The Extern message defines +the following fields: +

+
    +
  • +

    extern_type_id, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the reserved +range [0x81, 0xfe]. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture. +

  • +
  • +

    extern_type_name, which specifies the fully-qualified P4 name of the extern +type. +

  • +
  • +

    instances, a repeated field of ExternInstance Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +ExternInstance in turn defines the following fields: +

    +
      +
    • preamble, a Preamble message with the ID, name, and alias of this digest +instance. +
    • +
    • info, an Any Protobuf message [31] which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for info should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on Extending +P4Runtime for non-PSA Architectures for more +information. +
    +
+ +

If the P4 program does not include any instance of a given extern type, the +Extern message instance for that type should be omitted from the P4Info. +

6.5. Support for Arbitrary P4 Types with P4TypeInfo

+

See section on Representation of Arbitrary P4 +Types. +

7. P4 Forwarding-Pipeline Configuration

+

The ForwardingPipelineConfig captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the “Device Configuration” and sometimes also referred to as +the “P4 Blob”. It is defined as: +

+
+
+
message ForwardingPipelineConfig {
+  config.P4Info p4info = 1;
+  bytes p4_device_config = 2;
+  message Cookie {
+    uint64 cookie = 1;
+  }
+  Cookie cookie = 3;
+}
+

The p4info field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic. +

+

The p4_device_config is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new ForwardingPipelineConfig on that target. +

+

The cookie field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a GetForwardingPipelineConfig RPC. +When writing the config via a SetForwardingPipelineConfig RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present. +

8. General Principles for Message Formatting

8.1. Set / Unset Protobuf Field

+

In Protobuf version 3 (proto3), the default value for a message field is +“unset” [4]. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +CounterEntry message, an “unset” index field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the index message field is +set, a single entry will be read. +

+

Let's look at the counter example in more details. Based on this specification +document, the C++ server code which processes CounterEntry messages may look +like this: +

+
+
+
auto *counter_entry = ...
+if (counter_entry->has_index()) {
+  auto index = counter_entry->index().index();
+  read_one_entry(counter_entry->id(), index);
+} else {
+  read_all_entries(counter_entry->id());
+}
+
    +
  1. +

    Reading a single counter entry at index 0 in the counter array with id +<id>: +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
      +entry.mutable_index();
      +// The above line sets the index field; it is equivalent to:
      +// auto *index = entry.mutable_index();
      +// index->set_index(0);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
      +index {}
    • +
    • Expected behavior: Counter entry at index 0 is read. Notice that the +index subfield is missing under the index field message of +CounterEntry in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages. +
    +
  2. +
  3. +

    Reading all counter entries by leaving the index field unset +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
    • +
    • Expected behavior: All counter entries for the provided counter +instance are read. Notice that the index message field is unset (default +value) and is therefore omitted from the textual representation of the +message. +
    +
+

8.2. Read-Write Symmetry

+

The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example: +

+
+
+
intended_value = value
+
+status = server.write(intended_value, p4_entity)
+observed_value = server.read(p4_entity)
+
+assert(intended_value == observed_value)
+

To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If Read RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol's complexities to the client implementations. +

+

In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the match fields in a TableEntry message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +MessageDifferencer class [36] included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance. +

8.3. Zero as Reserved Value

+

p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a uint32. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a WriteRequest or a SetForwardingPipelineConfigRequest. +

8.4. Bytestrings

+

P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (bit<W>) or signed (int<W>), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +bytes Protobuf type. The correct bitwidth as per the P4 program of +each integer variable exposed through P4Runtime is specified in the P4Info +message. +

+

The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals: +

+
    +
  • +

    It ensures that a properly encoded binary string's integer value conforms +to the P4Info-specified bitwidth. +

  • +
  • +

    It supports read-write symmetry. +

  • +
  • +

    It helps facilitate non-disruptive P4 program updates. +

+ +

In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type bit<W> and/or int<W>. +

+

Note that this representation does not make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range. +

+

In the P4Runtime API version 1.0 (including minor version revisions), values +of table key fields, action parameters, and fields in packet-in and packet-out +headers between a device and the controller (see 6.4.6), +may not be of type int<W>. The rules for encoding signed values thus only +apply to messages of type P4Data (see 8.5.3). +

+

For a value of type bit<W>, the fewest number of bits required to represent +the integer value $V > 0$ is the smallest integer $A$ such that $V \leq 2^A -1$. +

+

For a value of type int<W>, the fewest number of bits required to represent +the integer value $V \neq 0$ in 2's complement form is the smallest integer $A$ +such that $-2^{A-1} \leq V \leq 2^{A-1} - 1$. +

+

As a special case, define that the value $V=0$ requires at least $A=1$ bit to +represent, regardless of whether it is signed or unsigned. +

+

The shortest possible binary string for an integer $V$ that needs $A$ bits to +represent it is computed as: +

+
+
+
minimum_string_size = floor((A + 7) / 8)
+

Binary strings with the byte length computed as minimum_string_size promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies. +

+

Any additional bits in the bytes sent for an unsigned integer value (type +bit<W>) must be 0. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with 0. +

+

Any additional bits in the bytes sent for a signed integer value (type int<W>) +must be copies of the sign bit, i.e. 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with copies of the +sign bit, i.e. 0 for non-negative values, or 0xff for negative values. In 2's +complement representation, this is called “sign extension”, and leaves the +numeric value represented unchanged. +

+

Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value. +

+

For a received bitstring expected to fit within a bit<W> type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring's width is W bits or less. +

+

For a received bitstring expected to fit within an int<W> type, the value it +represents is in range if, after “undoing sign extension”, the remaining bit +string's width is W bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other. +

+

If the string's byte length is zero, the server always rejects the string. +

+

When the server rejects a binary string due to any of the previous criteria, +it returns an OUT_OF_RANGE error. +

+

For all binary strings, P4Runtime uses big-endian (i.e. network) byte-order. +For signed integer values (int<W> P4 type), P4Runtime uses the same two's +complement bitwise representation as P4. Table 4 +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above. +

+
+ + + + + + + + + + + + + + + + + +
P4 type Integer value P4Runtime binary string Read-write symmetry
bit<8> 99 (0x63) \x63 yes
bit<16> 99 (0x63) \x00\x63 no
bit<16> 99 (0x63) \x63 yes
bit<16> 12388 (0x3064) \x30\x64 yes
bit<16> 12388 (0x3064) \x00\x30\x64 no
bit<12> 99 (0x63) \x00\x63 no
bit<12> 99 (0x63) \x63 yes
bit<12> 99 (0x63) \x00\x00\x63 no
int<8> 99 (0x63) \x63 yes
int<8> -99 (-0x63) \x9d yes
int<8> -99 (-0x63) \xff\x9d no
int<12> -739 (-0x2e3) \xfd\x1d yes
int<16> 0 (0x0) \x00\x00 no
int<16> 0 (0x0) \x00 yes
+
+ +
Table 4. Examples of Valid Bytestring Encoding
+

Table 5 shows some examples of invalid +P4Runtime binary strings: +

+
+ + + + + + + + + + + + +
P4 type P4Runtime binary string
bit<8> \x01\x63
bit<8> empty string
bit<16> \x01\x00\x63
bit<12> \x10\x63
bit<12> \x01\x00\x63
bit<12> \x00\x40\x63
int<8> \x00\x9d
int<12> \x8d\x1d
int<16> empty string
+
+ +
Table 5. Examples of Invalid Bytestring Encoding
+

As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from bit<8> to bit<9>, a server +running the bit<9> version of the P4 program will accept requests from +clients that remain on the bit<8> P4Runtime version. +

+

Despite the server's binary string flexibility for P4 program update support, +the client and server must both remain aware of the +read-write symmetry +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values. +

+

Representation of variable-length integer values (varbit<W> P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the dynamic-length of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an OUT_OF_RANGE error code otherwise. +

8.5. Representation of Arbitrary P4 Types

8.5.1. Problem Statement

+

The P416 language includes more complex types than just binary strings +[3]. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table 6 shows the different +P416 types and how they are allowed to be used, as per the P416 +specification. +

+
+ + + + + + + + + + + + + + + + + + + +
Container type
Element type header header_union struct or tuple
bit<W> allowed error allowed
int<W> allowed error allowed
varbit<W> allowed error allowed
int error error error
void error error error
error error error allowed
match_kind error error error
bool error error allowed
enum allowed1 error allowed
header error allowed allowed
header stack error error allowed
header_union error error allowed
struct error error allowed
tuple error error allowed
+
+ +
Table 6. P4 Type Usage
+

For example, the following P416 objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects. +

+
+
+
Digest<tuple<bit<4>, bit<8> > >() digest_complex;
+digest_complex.pack({ hdr.ipv4.version, hdr.ipv4.protocol });
+// ...
+header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

One solution would be to use only binary string (bytes type) in +p4runtime.proto and to define a custom serialization format for complex P416 +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P416 types. +

8.5.2. P4 Type Specifications in p4info.proto

+

In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type ip_t, which is a header union with 2 possible headers: +ipv4 with type ipv4_t and ipv6 with type ipv6_t. Similarly, they need to +know the field layout for both of these header types. +

+

To achieve this we introduce 2 main Protobuf messages: P4TypeInfo and +P4DataTypeSpec. +

+

P4TypeInfo is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P416 program. These +named types are struct, header, header_union, enum and +serializable_enum; for each of these we have a type specification message, +respectively P4StructTypeSpec, P4HeaderTypeSpec, P4HeaderUnionTypeSpec, +P4EnumTypeSpec and P4SerializableEnumTypeSpec. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. P4TypeInfo also includes the list of parser errors for the program, as +a P4ErrorTypeSpec message. +

+

P4DataTypeSpec is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each P4DataTypeSpec message corresponds to a compile-time type in the +original P416 program (e.g. the type parameter of an extern). This +compile-time type is represented as a Protobuf oneof, which can be: +

+
    +
  • +

    a string representing the name of the type in case of a named type (struct, +header, header_union, enum, serializable_enum or user-defined “new” +type), +

  • +
  • +

    an empty Protobuf message for bool and error, or +

  • +
  • +

    a Protobuf message for other anonymous types (bit<W>, int<W>, varbit<W>, +tuple or stack). The “binary string” types (bit<W>, int<W>, and +varbit<W>) are grouped together in the P4BitstringLikeTypeSpec message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf bytes +type). +

+ +

For all P416 compound types (tuple, struct, header, and header_union), +the order of members in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P416 declaration. The same goes for the order of members of an enum +(serializable or not) or members of error. +

8.5.3. P4Data in p4runtime.proto

+

P4Runtime uses the P4Data message to represent values of arbitrary types. The +P4Runtime client must generate correct P4Data messages based on the type +specification information included in P4Info. The P4Data message was designed +to introduce little overhead compared to using binary strings in the most common +case (P416 bit<W> type). +

+

Just like its P4Info counterpart - P4DataTypeSpec -, P4Data uses a Protobuf +oneof to represent all possible values. +

+

We define a canonical representation for P4Data messages therefore +guaranteeing read-write symmetry by introducing the following requirements: +

+
    +
  • +

    The order of members in P4StructLike and the order of bitstrings in +P4Header must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P416 type +declaration. +

  • +
  • +

    An invalid header is represented by a P4Header message where the is_valid +field is false and the bitstrings repeated field is empty. +

  • +
  • +

    An invalid header union (i.e. all headers in the union are invalid) is +represented by a P4HeaderUnion message where the valid_header_name is the +empty string (default value for the field) and the valid_header is unset. +

  • +
  • +

    The order of entries in P4HeaderStack and P4HeaderUnionStack is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the entries field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding P4HeaderStackTypeSpec or +P4HeaderUnionStackTypeSpec message. +

+

8.5.4. Example

+

Let's look at the Register example again: +

+
+
+
header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

Here's the corresponding entry in the P4Info message: +

+
+
+
registers {
+  preamble {
+    id: 369119267
+    name: "register_ip"
+    alias: "register_ip"
+  }
+  type_spec {
+    header_union {
+      name: "ip_t"
+    }
+  }
+  size: 128
+}
+type_info {
+  headers {
+    key: "ipv4_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  headers {
+    key: "ipv6_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  header_unions {
+    key: "ip_t"
+    value {
+      members {
+        name: "ipv4"
+        header {
+          name: "ipv4_t"
+        }
+      }
+      members {
+        name: "ipv6"
+        header {
+          name: "ipv6_t"
+        }
+      }
+    }
+  }
+}
+

Here's a p4.WriteRequest to set the value of register_ip[12]: +

+
+
+
update {
+  type: INSERT
+  entity {
+    register_entry {
+      register_id: 369119267
+      index {
+        index: 12
+      }
+      data {
+        header_union {
+          valid_header_name: "ipv4"
+          valid_header {
+            is_valid: true
+            bitstrings: "\x04"
+            bitstrings: # ...
+          }
+        }
+      }
+    }
+  }
+}

8.5.5. enum, serializable enum and error

+

P416 supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or “unsafe” enum) +[5]. For enum types with no underlying type as well as error +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in P4Data to represent enum and +error values. +

+

Serializable enum types have an underlying fixed-width unsigned integer +representation (bit<W>). All named enum members must be assigned an integer +value by the P4 programmer, but not all valid numeric values for the +underlying type need to have a corresponding name. P4TypeInfo includes the +mapping between entry name and entry value. When providing serializable enum +values through P4Data, one must use the assigned integer value (enum_value +bytestring field). P4Runtime does not provide a way for the client to use the +name even when the enum member has one instead of the value, as it makes +it easier for the server to respect the read-write +symmetry principle. +

8.5.6. User-defined types

+

P416 enables programmers to introduce new types [11]. While similar +to typedef, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +translation. When introducing a new type, the +declaration can be annotated with @p4runtime_translation to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for port numbers, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. The @p4runtime_translation annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (bit<W>). The type exposed to the control plane (referred to as the +controller_type) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a URI (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the controller_type of the values exposed to the control plane. The +controller_type can be either bit<W> where W is any positive integer, or +string, or a positive integer W which has the same meaning as bit<W>. +Specifying just an integer is deprecated. +

+

It is recommended that the URI includes at least the P4 architecture name and +the type name. +

+

A @p4runtime_translation annotation need not have any effect if it is used to +annotate anything in a P4 program other than a type declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect. +

+

User-defined types are specified using the P4NewTypeSpec message, which has +the following fields: +

+
    +
  • +

    representation, a Protobuf oneof specifying how values of this type are +exchanged between client and server; it can be either: +

    +
      +
    • +

      original_type, if and only if no @p4runtime_translation annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 type declaration is itself a +user-defined type, original_type is obtained by “walking” the chain of +type declarations recursively until a built-in type (e.g. bit<W>) is +found. +

    • +
    • +

      translated_type, if and only if the P4 type declaration was annotated +with @p4runtime_translation. It is of type P4NewTypeTranslation, +which itself has two fields uri and either sdn_string or +sdn_bitwidth , which map to the two input parameters to the +annotation. +

    +
  • +
  • +

    annotations, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration. +

+ +

For example, an architecture in this case PSA may introduce a new type +for port numbers: +

+
+
+
// Controller refers to ports as a string, e.g. "eth0".
+@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+// Controller refers to ports as a 32-bit integer, e.g. 0xffffffff.
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+// Same as above.
+@p4runtime_translation("p4.org/psa/v1/PortId_32_t", 32)
+type bit<9> PortId_32_t;
+

In this case, the P4Info message would include the following P4TypeInfo +messages: +

+
+
+
type_info {
+  new_types {
+    key: "PortId_String_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_String_t"
+        sdn_string: {}
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_Bit32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_Bit32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+

Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (e.g. through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over @p4runtime_translation to enable users +to overwrite annotations included as part of the P4 architecture definition. +

8.5.7. Trade-off for v1.x Releases

+

For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +bytes with P4Data in the p4.v1.FieldMatch message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +bytes to provide action parameter values and controller metadata +values. However P4Data is used whenever appropriate for PSA externs and we +encourage the use of P4Data in architecture-specific extensions. +

+

In order to support translation for action +parameters and match fields, we include a type_name field in +p4.config.v1.MatchField, p4.config.v1.Action.Param and +p4.config.v1.ControllerPacketMetadata.Metadata. In addition, the bitwidth +field for all of these message types must abide by the following rule when +type_name names a translated user-defined type: +

+
    +
  • +

    If the controller_type is a fixed-width unsigned bitstring, the bitwidth +field must be set to the bitwidth of the controller_type. This information +is redundant with the one included in the P4TypeInfo entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent. +

  • +
  • +

    Otherwise (i.e., if the controller_type is a string), the bitwidth must +be “unset”, which, in Protobuf version 3, is the same as setting the field to +0. +

+ +

For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types: +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+@name(".t")
+table t {
+  key = {
+    meta.port1: exact;  // meta.port1 has type PortId_String_t
+    meta.port2: exact;  // meta.port2 has type PortId_Bit32_t
+  }
+  actions = {
+    drop;
+  }
+}
+

This table would have the following representation in the generated P4Info +message: +

+
+
+
tables {
+  preamble {
+    id: 34728461
+    name: "t"
+    alias: "t"
+  }
+  match_fields {
+    id: 1
+    name: "meta.port1"
+    # notice that bitwidth is unset
+    match_type: EXACT
+    type_name {
+      name: "PortId_String_t"
+    }
+  }
+  match_fields {
+    id: 2
+    name: "meta.port2"
+    bitwidth: 32
+    match_type: EXACT
+    type_name {
+      name: "PortId_Bit32_t"
+    }
+  }
+  # ...
+}

9. P4 Entity Messages

+

P4Runtime covers P4 entities that are either part of the P416 language, or +defined as PSA externs. The sections below describe the messages for each +supported entity. +

9.1. TableEntry

+

The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action's +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification. +

+

P4Runtime supports inserting, modifying, deleting and reading table entries with +the TableEntry entity, which has the following fields: +

+
    +
  • +

    table_id, which identifies the table instance; the table_id is determined +by the P4Info message. +

  • +
  • +

    match, a repeated field of FieldMatch messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration. +

  • +
  • +

    action, which indicates which of the table's actions to execute in case of +match and with which argument values. +

  • +
  • +

    priority, a 32-bit integer used to order entries when the table's match key +includes an optional, ternary or range match. +

  • +
  • +

    controller_metadata, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +metadata field. +

  • +
  • +

    metadata, an arbitrary bytes value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. +

  • +
  • +

    meter_config, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    counter_data, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    meter_counter_data, which is used to read and write the per-color counter +values for the direct meter entry attached to this table entry, if any. +See Direct resources section for more information. +

  • +
  • +

    is_default_action, a boolean flag which indicates whether the table entry is +the default entry for the table. See Default entry +section for more information. +

  • +
  • +

    idle_timeout_ns and time_since_last_hit, which are two fields used to +implement idle-timeout support for the table, if applicable. See +Idle-timeout section for more information. +

+ +

The priority field must be set to a non-zero value if the match key includes a +ternary match (i.e. in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an OPTIONAL, TERNARY or +RANGE match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches. +

+

The match and priority fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for MODIFY and DELETE updates. When deleting +an entry, these key fields (along with is_default_action) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a keyless +table (the table has an empty match key), the server must reject all attempts to +INSERT a match entry and return an INVALID_ARGUMENT error. +

+

The number of match entries that a table should support is indicated in P4Info +(size field of Table message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P416 specification for the +size property [30]. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +RESOURCE_EXHAUSTED when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached. +

9.1.1. Match Format

+

The bytes fields in the FieldMatch message follow the format described in +Bytestrings. +

+

For “don't care” matches, the P4Runtime client must omit the field's entire +FieldMatch entry when building the match repeated field of the TableEntry +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for “don't care” matches, which is needed +to ensure read-write symmetry. For PSA match types, +a “don't care” match for a specific match key field is defined as follows: +

+
    +
  • +

    For a TERNARY match, it is logically equivalent to a mask of zeros. +

  • +
  • +

    For a OPTIONAL match, it is logically equivalent to a wildcard match. +

  • +
  • +

    For an LPM match, it is logically equivalent to a prefix_len of zero. +

  • +
  • +

    For a RANGE match, it is logically equivalent to a range which includes all +possible values for the field. +

+ +

Note that there is no “don't care” value for EXACT matches and therefore exact +match fields can never be omitted from the TableEntry message. +

+

The following example shows a P4Runtime message that treats a TERNARY field +as a “don't care” match. The P4 program defines table t with TERNARY +and EXACT fields in its match key: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: ternary;
+    istd.ingress_port: exact;
+  }
+  actions = {
+    drop;
+  }
+}
+

In this P4Runtime request, the client omits the table's TERNARY field +from the repeated match field to indicate a “don't care” match. As shown +below, the match specifies only the EXACT field given by field_id: 2. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 33554439  # Table t's ID.
+    match {
+      # field_id 1 is not present to use the don't care ternary value.
+      field_id: 2
+      exact {
+        value: "\x20"
+      }
+    }
+    action {
+      # Action selection goes here.
+    }
+  }
+}
+

For every member of the TableEntry repeated match field, field_id must be +a valid id for the table, as per the P4Info, and one of the fields in +field_match_type must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an INVALID_ARGUMENT error code. +

+
    +
  • EXACT match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.exact().value()))
+
    +
  • LPM match + +
      +
    • The binary string encoding of the value (when present) must conform to the +Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • “Don't care” bits must be 0 in value. +
+ +
+
+
assert(BytestringValid(match.lpm().value()))
+
+pLen = match.lpm().prefix_len()
+assert(pLen > 0)
+
+trailing_zeros = countTrailingZeros(match.lpm().value())
+assert(trailing_zeros >= field_bits - pLen)
+
    +
  • TERNARY match + +
      +
    • The binary string encoding of the value (when present) and mask (when +present) must conform to the Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • Masked bits must be 0 in value. This constraint taken together +with the Bytestrings requirements means that the +value's binary string is never longer than the mask's binary string. +When the value's string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask. +
+ +
+
+
assert(BytestringValid(match.ternary().value()))
+assert(BytestringValid(match.ternary().mask()))
+assert(match.ternary().value().size() <= match.ternary().mask().size());
+
+value = parseInteger(match.ternary().value())
+mask = parseInteger(match.ternary().mask())
+
+assert(mask != 0)
+
+assert(value & mask == value)
+
    +
  • RANGE match + +
      +
    • The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the Bytestrings +requirements. +
    • +
    • Low bound must be less than or equal to the high bound. +
    • +
    • “Don't care” match must be omitted. +
+ +
+
+
assert(BytestringValid(match.range().low()))
+assert(BytestringValid(match.range().high()))
+
+low = parseInteger(match.range().low())
+high = parseInteger(match.range().high())
+
+assert(low <= high)
+
+assert(low != min_field_value || high != max_field_value)
+
    +
  • OPTIONAL match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.optional().value()))

9.1.2. Action Specification

+

The TableEntry action field must be set for every INSERT update but may be +left unset for MODIFY updates, in which case the action specification for the +table entry will not be modified (if a MODIFY update has an unset action field +and does not modify any direct resource attached to the table then the MODIFY +update is a no-op). Based on the implementation property value of the P4 table, +the oneof in the TableAction message will either be: +

+
    +
  • +

    an Action specification for direct tables (with no P4 implementation +property) +

  • +
  • +

    an action profile member id for indirect tables for which the implementation +property is an action profile with no selector. +

  • +
  • +

    an action profile member id or group id for indirect tables for which the +implementation property is an action profile with selector. +

  • +
  • +

    an ActionProfileActionSet specification for indirect tables for +which the implementation property is an action profile with +selector. This usage is described in One Shot Action Selector +Programming +

+ +

If the oneof does not match the table description in the P4Info (e.g. the +oneof is action_profile_member_id for a direct table), the server must +return an INVALID_ARGUMENT error code. +

+

The Action Protobuf message has the following fields: +

+
    +
  • +

    action_id, which identifies the action instance; the action_id is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an INVALID_ARGUMENT error +code. If the client uses a valid action_id for the table but does not +respect the action scope specified in P4Info (e.g. tries to set a TABLE_ONLY +action as the default action), the server must return a PERMISSION_DENIED +error code. +

  • +
  • +

    params: a repeated Protobuf field of action parameter values, each encoded +as a Param message. For each parameter, param_id must be valid for the +action (as per the P4Info) and value must follow the format described in +Bytestrings. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an INVALID_ARGUMENT error code +if a parameter id is missing, if an extra parameter id not found in the +P4Info was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +Bytestrings format. +

+ +

For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a NOT_FOUND error code. +

9.1.3. Default Entry

+

According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer or defaults to NoAction +(which is a no-op) otherwise and assuming it is not declared as const, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow INSERT and DELETE updates on the default entry and the +P4Runtime server must return an INVALID_ARGUMENT error code if the client +attempts one. +

+

The default entry is identified by setting the is_default_action boolean field +to true. When this flag is set to true, the repeated match field must be empty +and the priority field must be set to zero, otherwise the P4Runtime server +must return an INVALID_ARGUMENT error code. When performing a MODIFY update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its controller_metadata and metadata value as well as the +configurations for its direct resources will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a PERMISSION_DENIED +error code if the client attempts to modify it. +

+

Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to direct resources. +

+

In this P4Runtime release, we have decided to restrict the default entry for +indirect tables tables with an ActionProfile or ActionSelector +implementation property to a constant NoAction action entry, with the +hope that it would simplify the implementation of the P4Runtime service. +

9.1.4. Constant Tables

+

Constant tables are defined as tables whose match entries are immutable. They +are identified by the is_const_table flag in P4Info. +

+

The only write updates which are allowed for constant tables are MODIFY +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +PERMISSION_DENIED error. Just like any table entry MODIFY request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a PERMISSION_DENIED error. +

+

The contents of const tables can be queried by the client through a +ReadRequest. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: table_id, match, action, +is_default_action, and priority (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the priority field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P416 does not support assigning explicit priorities to static +entries. When a priority value is required (e.g. for tables including RANGE, +TERNARY or OPTIONAL matches), it is inferred based on the order in which +entries appear in the table declaration. +

9.1.5. Wildcard Reads

+

When performing a ReadRequest, the P4Runtime client can select all entries +from one or all tables on the target and use several of the TableEntry fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as priority and “unset” for message fields such as match. The following +fields may be used to select and filter results: +

+
    +
  • table_id: If default (0), entries from all tables including constant +tables will be selected and no other filter can be used. Otherwise only +the specified table will be considered. +
  • +
  • match: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned. +
  • +
  • action: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an action_id (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id. +
  • +
  • priority: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value. +
  • +
  • controller_metadata: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +controller_metadata value. +
  • +
  • metadata: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided metadata value. +
  • +
  • is_default_action: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered. +
  • +
  • role: If default (unset), all table entries will be considered. Otherwise, +table entries will be filtered based on the provided role value. +
+ +

For example, in order to read all entries from all tables from device 3, the +client can use the following ReadRequest message. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0
+    priority: 0
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following ReadRequest +message: +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+    priority: 11
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

The canonical representation of “don't care” matches, combined with the ability +to do a wildcard read on all table entries by leaving the match field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single “don't care” entry or to do a wildcard +read. If a table has no fields with match kind EXACT, it is possible via +P4Runtime to add an entry that is “don't care” for all fields (i.e. has an empty +match field) but is not the default entry (i.e. is_default_action is +false). When reading this entry from the table, there is no way to read only +that entry from the table, because it would require providing an unset match +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single LPM match: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: lpm;
+  }
+  actions = {
+    drop; fwd;
+  }
+}
+

The following WriteRequest message can be used to add 2 entries: +

+
+
+
device_id: 3
+entities {
+  table_entry { # don't care entry
+    table_id: 0x0212ab34
+    # ...
+  }
+  table entry {
+    table_id: 0x0212ab34
+    match {
+      field_id: 1
+      lpm {
+        value: 0x0a000000
+        prefix_len: 8
+      }
+    # ...
+  }
+}
+

The first entry is a “don't care” entry, while the second one matches all +10.0.0.0/8 addresses. The second entry has higher priority than the first one. +

+

The following ReadRequest message will return all entries in the table, not +just the “don't care” entry. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+  }
+}
+

This issue also exists for tables with TERNARY, RANGE, and OPTIONAL +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the “don't care” entry will be returned to the +client. If the client uses distinct priority values for all entries which is +strongly recommended to achieve deterministic behavior , +then there is no ambiguity because the wildcard read will actually return a +single entry (the “don't care” entry) as long as the priority field is set to +the correct value. +

9.1.6. Direct Resources

+

In addition to the DirectCounterEntry and DirectMeterEntry entities, +P4Runtime support reading and writing direct resources as part of the +TableEntry message. This is convenient for two reasons: +

+
    +
  • +

    A table entry and its direct resources can be read with a single entity when +doing a Read RPC call +

  • +
  • +

    The initial configuration for an entry's direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can “hit” the table entry without +executing the appropriate meter entry. +

+ +

Once the table entry has been inserted, the P4Runtime client is free to use the +DirectCounterEntry and DirectMeterEntry messages for read and write +operations on DirectCounter and DirectMeter instances. For example, it is +usually more convenient as well as more efficient to use DirectCounterEntry to +query a counter entry value rather than use TableEntry, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry. +

+

The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does not need to be “executed” in +every action bound to the table. It is an error to provide a direct resource +configuration in a TableEntry message when programming an action that does not +execute the direct resource, and the server must return an INVALID_ARGUMENT +error code. +

+

We leverage Protobuf's ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the TableEntry message. The list below describes how +the server must handle the meter_config, counter_data and +meter_counter_data fields for read and write requests, based on whether the +fields are set or not. We do not cover error cases in the list, i.e. we assume +that we are dealing with a table which is assigned a direct counter / a direct +meter, and that the action being used for the table entry “executes” the direct +resource appropriately. +

+
    +
  • +

    meter_config field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets). +
      • +
      • if set: The initial configuration for the meter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The meter entry's configuration is reset to the default +(meter returns GREEN for all packets). +
      • +
      • if set: The value provided by the client is used to re-configure +the meter entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the meter entry's +configuration (meter_config is unset in the response). +
      • +
      • if set: If the meter entry's configuration is the default +configuration, meter_config is unset in the response. Otherwise, the +response includes the meter entry's configuration that was written by +the client earlier. This respects the “read-write symmetry” principle. +
    +
  • +
  • +

    counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for the counter entry is the default +(0). +
      • +
      • if set: The initial value for the counter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The counter entry's value is not changed. +
      • +
      • if set: The value provided by the client is written to the counter +entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the counter entry's value +(counter_data is unset in the response). +
      • +
      • if set: The response includes the counter entry's value read from +the target. +
    +
  • +
  • +

    meter_counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for all 3 counter entries is the +default (0). +
      • +
      • if set: The initial value for all 3 counter entries is the +default (0). Sub-field, if any, can only have zero (0) as its value. +INVALID_ARGUMENT error is returned for any non-zero sub-field value. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: All the 3 counter entries are unchanged. +
      • +
      • if set: All the 3 counters are reset to 0. Sub-field, if any, can +only have zero (0) as its value. INVALID_ARGUMENT error is returned +for any non-zero sub-field value. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include counter values +(meter_counter_data is unset in the response). +
      • +
      • if set: The response includes all the 3 counter values read from +the target. +
    +
+ +

In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +meter_config field unset when inserting or modifying a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the TableEntry message +(i.e. the meter_config field must be set to match the existing configuration). +

9.1.7. Idle-timeout

+

P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not “hit” (i.e. not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification using the +IdleTimeoutNotification message to the primary client, which can then take +action, such as remove the idle table entry. +

+

Two fields of the TableEntry Protobuf message are used to implement idle +timeout: +

+
    +
  • +

    idle_timeout_ns: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, i.e. no +IdleTimeoutNotification message will ever be generated for this entry. When +a client reads a TableEntry, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry. +

  • +
  • +

    time_since_last_hit: a Protobuf message with a single field (elapsed_ns) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The time_since_last_hit field must be unset for a +TableEntry write. When reading a table entry, time_since_last_hit must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0. +

+ +

These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an INVALID_ARGUMENT error code if at least one of these +conditions is met: +

+
    +
  • idle_timeout_ns is set to a non-zero value, or +
  • +
  • time_since_last_hit is set +
+ +

The target should do its best to approximate the idle_timeout_ns value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the TableEntry write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for time_since_last_hit. +

+

P4Runtime does not support idle timeout for default entries. When the +is_default_action flag is set in a TableEntry message, idle_timeout_ns +must be set to 0 (default) and time_since_last_hit must be unset. If the +server receives a TableEntry message which violates this, it must return an +INVALID_ARGUMENT error. +

+

For more information about idle timeout, in particular regarding +IdleTimeoutNotification, please refer to the Table idle timeout +notifications section. +

9.2. ActionProfileMember & ActionProfileGroup

+

P4Runtime defines an API for programming a PSA ActionProfile extern using +ActionProfileMember messages. A PSA ActionSelector extern can be programmed +using both ActionProfileMember and ActionProfileGroup messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table t for L3 routing, implemented with an action +selector as. +

+
+
+
ActionSelector(HashAlgorithm.crc32,
+               /*size = */ 32w1024,
+               /*output_width = */ 32w10) as;
+
+action set_nhop(PortId_t p, EthAddr smac, EthAddr dmac) {
+  istd.egress_port = p;
+  hdr.ethernet.smac = smac;
+  hdr.ethernet.dmac = dmac;
+}
+
+table t {
+  key = {
+    hdr.ipv4.dip: lpm;  // LPM on destination IP address
+  }
+  actions = {
+    set_nhop;
+  }
+  implementation = as;
+}
+

When programming table t in the example above, a P4Runtime client should +specify the TableAction in the TableEntry to be a reference to either an +action profile member or group. The reference is a non-zero uint32 identifier +that uniquely identifies a member or group programmed in the action selector +as. +

+

If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata. +

+

If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata. +

9.2.1. Action Profile Member Programming

+

Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a uint32 identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the actions +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the actions attributes of the +tables must have an identical list of P4 actions. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector. +

+

An ActionProfileMember entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info. +

  • +
  • +

    member_id is the non-zero uint32 identifier of the action profile member +entry being updated. +

  • +
  • +

    action is the specification of the P4 action instance bound to the action +profile member entry. +

+ +

An action profile member may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an ALREADY_EXISTS error +code. The action specification must be provided, or the server must return +INVALID_ARGUMENT. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return RESOURCE_EXHAUSTED. +
  • +
  • MODIFY: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return NOT_FOUND, +and the action specification must be provided, or the server must return +INVALID_ARGUMENT. +
  • +
  • DELETE: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a NOT_FOUND error code. The member +must not be part of an action profile group, or the server must return +FAILED_PRECONDITION. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return FAILED_PRECONDITION. action_profile_id and member_id are the only +fields that are considered when performing a DELETE and every other field +will be ignored. +
+ +

When reading, an ActionProfileMember message with action_profile_id and +member_id equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with action_profile_id equal to the id of +an existing ActionProfile or ActionSelector object, and a member_id equal to +0, will read all members of that specified object. +

9.2.2. Action Profile Group Programming

+

Action profile groups are entries in an ActionSelector and are referenced by a +uint32 identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type. +

+

Within a single ActionSelector object, the uint32 values used to identify its +members are in a separate ‘scope’ from the uint32 values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5. +

+

There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it. +

+

An ActionProfileGroup entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionSelector +extern instance, as defined in P4Info. +

  • +
  • +

    group_id is the non-zero uint32 identifier of the action profile group +entry being updated. +

  • +
  • +

    members is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields: +

    +
      +
    • member_id for looking up the member table in the selector. +
    • +
    • weight specifying the probability of the member's selection at +runtime. 0 is not a valid weight value and the server must return +INVALID_ARGUMENT if the client attempts to use it. +
    • +
    • watch_port is the controller-defined port that the member's +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +9.2.4 for notes on the behavior if all members in +a group are excluded for this reason. If watch_port is empty, then the +member is always included in the selection, regardless of the status of +any port of the device. The value must be empty or the SDN port of an +existing port on the device, otherwise the server must return +INVALID_ARGUMENT. +
    +
  • +
  • +

    max_size is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +MODIFY update. See the subsection below for the rules on setting +max_size. +

+ +

An action profile group may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new group entry bound to a set of existing action profile +members. The group_id must be different from ids of already programmed +groups for that selector, or the server must return an ALREADY_EXISTS error +code. All members specified in the group must exist in the selector, or the +server must return NOT_FOUND. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target. +
  • +
  • MODIFY: Modify the member set specification of an existing group entry. An +entry with the group_id must exist, or the server must return +NOT_FOUND. All members specified in the group entry must exist in the +selector, or the server must return NOT_FOUND. The value of max_size must +be identical to the value used when inserting the group, otherwise an +INVALID_ARGUMENT error is returned. +
  • +
  • DELETE: Delete the group entry and deallocate the group_id. The group must +not be referenced in the table action of any table entry, or the server must +return a FAILED_PRECONDITION error code. If the group_id is invalid, the +server must return NOT_FOUND. action_profile_id and group_id are the +only fields that are considered when performing a DELETE and every other +field will be ignored. +
+ +

When setting the group membership with INSERT or MODIFY, the members +repeated field must not include duplicates, i.e. members with the same +member_id. The weight field is used instead to logically “repeat” the member +inside the group. +

+

It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation “stores” the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made. +

+

When reading, an ActionProfileGroup message with action_profile_id and +group_id equal to 0 will read all groups of all ActionSelector objects. A +message with action_profile_id equal to the id of an existing ActionSelector +object, and a group_id equal to 0, will read all groups of that one specified +object. +

9.2.2.1. Rules on Setting max_size
+

The valid values for max_size depend on the static max_group_size included +in the P4Info message: +

+
    +
  • +

    If max_group_size is greater than 0, then max_size must be greater than 0, +and less than or equal to max_group_size. We assume that the target can +support selector groups for which the sum of all member weights is up to +max_group_size, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If max_size is greater than max_group_size, the server +must return INVALID_ARGUMENT. +

  • +
  • +

    Otherwise (i.e. if max_group_size is 0), the P4Runtime client can set +max_size to any value greater than or equal to 0. +

    +
      +
    • +

      A max_size of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (INSERT or MODIFY), the target must return a +RESOURCE_EXHAUSTED error. +

    • +
    • +

      If max_size is greater than 0 and the value is not supported by the +target, the server must return a RESOURCE_EXHAUSTED error at +group-creation time. +

    +
+

9.2.3. One Shot Action Selector Programming

+

P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids. +

+

One shots are programmed by choosing the ActionProfileActionSet message as the +TableAction. The ActionProfileActionSet message consists of a set of +ActionProfileAction messages, which in turn have the following fields: +

+
    +
  • +

    action is one of the actions specified by the table that is being +programmed. +

  • +
  • +

    weight specifying the probability of the action's selection at runtime. 0 is +not a valid weight value and the server must return INVALID_ARGUMENT if +the client attempts to use it. The sum of all weights across all +ActionProfileAction messages for that ActionProfileActionSet message must +not exceed the max_group_size specificed in the P4Info (if greater than 0), +or the server must return INVALID_ARGUMENT. +

  • +
  • +

    watch_port is the controller-defined port that the action's liveness depends +on. At runtime, the action must be excluded from selection if the watch port +is down. See Section 9.2.2 for more details +on the watch_port field, which also apply for one shot action selector +programming. +

+ +

Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics. +

+

To preserve read-write symmetry, an implementation must answer ReadRequests +with the original one shot messages. It may not return a desugared version of +the one shot message. +

+

For example, consider the action selector table defined +here. This table could be programmed +with the following one shot update: +

+
+
+
table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action {
+    action_profile_action_set {
+      action_profile_actions {
+        action { /* set nexthop 1 */ }
+        weight: 1
+        watch_port: "\x01"
+      }
+      action_profile_actions {
+        action { /* set nexthop 2 */ }
+        weight: 2
+        watch_port: "\x02"
+      }
+      action_profile_actions {
+        action { /* set nexthop 3 */ }
+        weight: 3
+        watch_port: "\x03"
+      }
+    }
+  }
+}
+

Which would be equivalent to the following updates, where GROUP_ID, +MEMBER_ID_1, MEMBER_ID_2, and MEMBER_ID_3 are unused ids: +

+
+
+
action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_1
+  action { /* set nexthop 1 */ }
+}
+action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_2
+  action { /* set nexthop 2 */ }
+}
+action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_3
+  action {  /* set nexthop 3 */ }
+}
+action_profile_group {
+  action_profile_id: 0x11ab12cd
+  group_id: GROUP_ID
+  members {
+    member_id: MEMBER_ID_1
+    weight: 1
+    watch_port: "\x01"
+  }
+  members {
+    member_id: MEMBER_ID_2
+    weight: 2
+    watch_port: "\x02"
+  }
+  members {
+    member_id: MEMBER_ID_3
+    weight: 3
+    watch_port: "\x03"
+  }
+}
+table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action { action_profile_group_id: GROUP_ID }
+}
+

Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure correct ordering between the dependent +updates. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct WriteRequest batches are required. +

+

It is possible to include several ActionProfileAction messages with the same +exact action specification in one ActionProfileActionSet message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the weight field. Note that to preserve read-write symmetry, the server +must not coalesce multiple ActionProfileAction messages with the same action +specification into one. +

+

All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with ActionProfileMember and +ActionProfileGroup messages. Programming some entries with one shots, and +other entries with ActionProfileMember and ActionProfileGroup messages is +not allowed, and the server must return the error code INVALID_ARGUMENT in +that case. +

+

A P4Runtime server must support the one shot style of programming tables with +an action selector implementation. Support for the ActionProfileMember and +ActionProfileGroup style is optional. If ActionProfileMember and +ActionProfileGroup are not supported by a server, it must return an +UNIMPLEMENTED error for every ActionProfileMember or ActionProfileGroup +message that it receives. +

9.2.4. Constraints on action selector programming

+

The PSA specification states that the following features are optional in +action selector implementations [22]: +

+
    +
  1. Support for non-empty groups where in the same group, different members are +bound to different actions. +
  2. +
  3. Predictable data plane behavior when a matched table entry points to an empty +group. +
+ +

For 1., if a client tries to INSERT or MODIFY a group with members bound to +different actions, the server should return UNIMPLEMENTED if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return UNIMPLEMENTED (modifying the action parameter values must be +supported, however). +

+

PSA 1.1 introduces the psa_empty_group_action table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. psa_empty_group_action is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of psa_empty_group_action at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +NoAction. Even when psa_empty_group_action is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of psa_empty_group_action mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming. +

+

The PSA specification includes a discussion on how to implement +psa_empty_group_action in software in the P4Runtime server +[25]. +

+

If a P4Runtime implementation does support psa_empty_group_action, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down. +

+

If a P4Runtime implementation does not support psa_empty_group_action, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down. +

9.3. CounterEntry & DirectCounterEntry

+

PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The CounterData +P4Runtime message can be used for all three types of PSA counters PACKETS, +BYTES and PACKETS_AND_BYTES and consists of the following fields: +

+
    +
  • byte_count is an int64, corresponding to the number of octets. +
  • +
  • packet_count is an int64, corresponding to the number of packets. +
+ +
+
+
message CounterData {
+  int64 byte_count = 1;
+  int64 packet_count = 2;
+}
+

P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of byte_count and packet_count fields, which +is equivalent to specifying the counter type PACKETS_AND_BYTES. Counters may +be defined as direct or indirect (indexed) instances. +

9.3.1. DirectCounterEntry

+

A direct counter is a direct resource associated with a TableEntry (see +Direct Resources). The counter_data field of the +TableEntry message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +DirectCounterEntry message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed. +

+
+
+
message DirectCounterEntry {
+  TableEntry table_entry = 1;
+  CounterData data = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectCounterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match TableEntry.match of the table entry +to which this direct counter entry is associated. If a matching TableEntry +is not found, the server returns the error code NOT_FOUND. +

  • +
  • +

    data is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified. +

+ +

Specifying DirectCounterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read the contents of a +DirectCounter: +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the counter value in the counter_data field of the TableEntry message +(see Direct resources). +

  • +
  • +

    Explicitly request the counter value by including the DirectCounterEntry in +the ReadRequest. The table_entry.match field must match the TableEntry +whose counter is being read. If no such entry is found, the server returns the +error code NOT_FOUND. +

+

9.3.2. CounterEntry

+

An indirect or indexed counter is not associated with a specific TableEntry +and may be updated independently of any action. It may be read or written using +the P4Runtime CounterEntry message whose fields are defined as follows: +

+
    +
  • +

    counter_id is a uint32, the unique identifier for the counter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +the counter array. +

  • +
  • +

    data is a Protobuf message of type CounterData, which represents the +counter value. +

+ +
+
+
message CounterEntry {
+  uint32 counter_id = 1;
+  Index index = 2;
+  CounterData data = 3;
+}
+

The CounterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the counter entries in the +array have default value 0. +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect counter instance whose unique id is counter_id +and array index is specified by index. The counter value is set to the value +specified by the client in the data field. Note that the counter value is +not modified if this Protobuf field is not set. If index is omitted all +counter values in the array will be set to the value provided by the +client. The server must return INVALID_ARGUMENT for a negative index value +and OUT_OF_RANGE if the index value exceeds the size of the counter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a ReadRequest by including a CounterEntry +entity for each of the instances, specifying the counter_id and +index. Wildcard reads are also supported as follows. +

+
    +
  • +

    If the counter_id field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id counter_id. +

+

9.4. MeterEntry & DirectMeterEntry

+

Meters are an advanced mechanism for keeping statistics, involving stateful +“marking” and usually “throttling” of packets based on configured rates of +traffic. The PSA metering function is based on the Two Rate Three Color Marker +(trTCM) defined in RFC 2698 [2]. The trTCM meters an arbitrary packet +stream using two configured rates the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes and +“marks” its packets as GREEN, YELLOW or RED based on the observed rate. +

+

MeterEntry & DirectMeterEntry have an additional field counter_data that +may hold per color counter data for targets that support it, and that must +always be unset for targets that do not support it. If set in a request and +unsupported by a target, an UNIMPLEMENTED error code should be returned. +These counters provide a granular list of the counters applicable to the +possible meter colors GREEN, YELLOW and RED. The counter associated with a +specific color is incremented when a packet is “marked” with that color. The +primary purpose of the color counters is for debugging purposes. +

+

A meter may be configured as a direct or indirect instance, similar to a +counter. The MeterConfig P4Runtime message represents meter configuration. +

+
+
+
message MeterConfig {
+  int64 cir = 1;  // Committed Information Rate
+  int64 cburst = 2;  // Committed Burst Size
+  int64 pir = 3;  // Peak Information Rate
+  int64 pburst = 4;  // Peak Burst Size
+}

9.4.1. DirectMeterEntry

+

A direct meter is a direct resource associated with a TableEntry (see Direct +resources). The meter_config field of the TableEntry +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +DirectMeterEntry message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed. +

+
+
+
message DirectMeterEntry {
+  TableEntry table_entry = 1;
+  MeterConfig config = 2;
+  MeterCounterData counter_data = 3;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectMeterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match the match key of the TableEntry +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching TableEntry is not found, +the server returns the error code NOT_FOUND. +

  • +
  • +

    config is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets). +

  • +
  • +

    counter_data is used to set the per color counter values to the default +value of (0), which is essentially clearing the counters. If the field is +unset, the counter values are left untouched. If the field is set, targets +supporting these counters should reset all the color counters to (0), if any +of the sub-fields are set to a non-zero value, then an INVALID_ARGUMENT +error should be returned. +

+ +

Specifying DirectMeterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read a DirectMeter config. +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the meter config in the meter_config field of the TableEntry +message (see Direct resources). +

  • +
  • +

    Explicitly request the meter configuration by including the DirectMeterEntry +in the ReadRequest. The table_entry.match field must match the +TableEntry whose meter config is being read. If no such entry is found, the +server returns the error code NOT_FOUND. Read responses also include the +per color counter data for the meter entry, if supported and specified in +the request message. +

+

9.4.2. MeterEntry

+

An indirect or indexed meter is not associated with a specific TableEntry and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime MeterEntry message whose fields are defined as +follows: +

+
    +
  • +

    meter_id is a uint32, the unique identifier for the meter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +a meter array. +

  • +
  • +

    config is a Protobuf message of type MeterConfig, which represents the +meter configuration. +

  • +
  • +

    counter_data is a Protobuf message of type MeterCounterData, which +represents the per color counter values associated with the corresponding +meter. +

+ +
+
+
message MeterEntry {
+  uint32 meter_id = 1;
+  Index index = 2;
+  MeterConfig config = 3;
+  MeterCounterData counter_data = 4;
+}
+

The MeterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the meter entries in the +array have a default configuration (GREEN for all packets). +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect meter instance whose unique id is meter_id and +array index is specified by index. The meter is reconfigured using the +config field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the index field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if config is unset). The server must return INVALID_ARGUMENT for a +negative index value and OUT_OF_RANGE if the index value exceeds the size of +the meter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a ReadRequest by including a MeterEntry entity for each +of the instances, specifying the meter_id and index. Wildcard reads are also +supported as follows: +

+
    +
  • +

    If the meter_id field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id meter_id. +

+

9.4.3. MeterCounterData

+

The MeterCounterData P4Runtime message represents the per color counters +associated with a meter entry. Whenever a meter is executed and returns +a color, the corresponding color counter GREEN, YELLOW or RED is updated. +

+

As seen above, these counters can be associated with a DirectMeterEntry or +MeterEntry. Targets not capable of supporting these counters should return +UNIMPLEMENTED if a MeterCounterData field was set in a read or write +request. +

+
+
+
message MeterCounterData {
+  CounterData green = 1;
+  CounterData yellow = 2;
+  CounterData red = 3;
+}

9.5. PacketReplicationEngineEntry

+

The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets. +

9.5.1. MulticastGroupEntry

+

Multicasting is achieved in PSA programs by setting the multicast_group +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the MulticastGroupEntry API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example. +

+
+
+
control arp_multicast(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ethernet.isValid() &&
+        hdr.ethernet.eth_type == ETH_TYPE_ARP) {
+      smeta.multicast_group = (MulticastGroup_t) 1;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    multicast_group_entry {
+      multicast_group_id: 1
+      replicas { egress_port: 5 instance: 1 }
+      replicas { egress_port: 12 instance: 2 }
+      replicas { egress_port: 18 instance: 3 }
+      replicas { egress_port: 24 instance: 4 }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +PSA Metadata Translation section. +

+

The egress packets may be distinguished for further processing in the egress +using the instance metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 multicast_group metadata is set to a value that is not +programmed in the PRE, then the packet is dropped. +

+

A multicast group may be inserted, modified or deleted as per the following +semantics. +

+
    +
  • INSERT: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The multicast_group_id field is a uint32 and must be greater +than 0 (see explanation below), or the +P4Runtime server must return an INVALID_ARGUMENT error. The replica +instance ID is also a uint32, and its value may not exceed the maximum +allowed by the target for the EgressInstance_t type (0 is allowed), or the +server must return an INVALID_ARGUMENT error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of both egress_port and instance, or the server +must return INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify the set of replicas for a given multicast group entry, +indexed by the given multicast_group_id. Same restrictions as INSERT apply +here. +
  • +
  • DELETE: Delete the multicast group indexed by the given +multicast_group_id. The replicas need not be provided for this +operation. Any packets with their multicast_group metadata in the data plane +set to the deleted multicast_group_id will be dropped. +
+ +

When reading a multicast group, only multicast_group_id is considered. All +other fields in MulticastGroupEntry are ignored. To perform a wildcard +Read on all configured multicast group entries, the multicast_group_id field +must be set to 0, its default value. +

9.5.1.1. Valid Values for multicast_group_id
+

The PSA specification states that the valid data plane values for multicast +group ids (MulticastGroup_t) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target [24]. This means that, in the absence of +translation, the client must set the multicast_group_id field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special wildcard value which is used to read all the multicast groups +configured in the target, the multicast_group_id field must never be set to 0 +when performing a Write RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value. +

9.5.2. CloneSessionEntry

+

PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +clone_session_id identifier and a boolean flag clone in the packet +metadata. The clone_session_id serves as a handle to the clone attributes, +namely a set replicas of (egress port, instance) pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +CloneSessionEntry API. +

+

The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the clone_low_ttl control block is applied in the ingress +pipeline to create an ingress-to-egress clone. +

+
+
+
control clone_low_ttl(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ipv4.isValid() &&
+        hdr.ipv4.ttl <= LOW_TTL_THRESHOLD) {
+      smeta.clone_session_id = 10w100;
+      smeta.clone = true;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    clone_session_entry {
+      session_id: 100
+      replicas { egress_port: 0xfffffffd instance: 1 } # to CPU
+      class_of_service: 2
+      packet_length_bytes: 4096
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type CloneSessionId_t [24]). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes. +

+

The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port 0xfffffffd; see +Translation of Port Numbers). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port. +

+

If the clone_session_id data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created. +

+

A clone session may be inserted, modified or deleted as per the following +semantics: +

+
    +
  • INSERT: Add a new clone session entry bound to a set of egress ports and +replica IDs. The session_id is a uint32 and must be greater than 0 (see +explanation below), or the P4Runtime +server must return an INVALID_ARGUMENT error. The replica instance ID is +also a uint32, and its value may not exceed the maximum allowed by the +target for the EgressInstance_t type (0 is allowed), or the server must also +return an INVALID_ARGUMENT error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (class_of_service field). This value must be a valid +value for the PSA ClassOfService_t type, which supports runtime translation +by default [24], or the server must return +INVALID_ARGUMENT. See PSA Metadata +Translation for more information. The +packet_length_bytes field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +packet_length_bytes field is 0 (default), no truncation on the clone will be +performed. +
  • +
  • MODIFY: Modify the attributes of a given clone session entry, indexed by the +given clone_session_id. Same restrictions as INSERT apply here. +
  • +
  • DELETE: Delete the clone session indexed by the given +clone_session_id. Other fields need not be provided for this operation. Any +packet with their clone_session_id metadata in the data plane set to the +deleted session_id will no longer be cloned. +
+ +

When reading a clone session, only session_id is considered. All other fields +in CloneSessionEntry are ignored. To perform a wildcard Read on all +configured clone session entries, the session_id field must be set to 0, its +default value. The session_id field can never be equal to 0 in a Write +RPC. If it does, the server must return an INVALID_ARGUMENT error. +

9.5.2.1. Valid Values for session_id
+

The PSA specification states that the valid data plane values for clone +session ids (CloneSessionId_t) range from 0 to the maximum value supported by +the target [24]. Note that unlike for multicast group +ids, 0 is a valid data plane value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special wildcard value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a session_id +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is not enabled, we effectively +“lose” one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (e.g. because the target supports a very +limited number of clone sessions), one can enable translation on +CloneSessionId_t and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id. +

9.6. ValueSetEntry

+

Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the parse_trill_types state. +

+
+
+
state parse_l2 {
+  @id(1) value_set<ETH_TYPE_BITWIDTH>(MAX_TRILL_TYPES) trill_types;
+  extract(hdr.ethernet);
+  select (hdr.ethernet.eth_type) {
+    ETH_TYPE_IPV4: parse_ipv4;
+    ETH_TYPE_IPV6: parse_ipv6;
+    trill_types:   parse_trill_types;
+    _:             reject;
+  }
+}
+

The corresponding entry in the P4Info for this Value Set is: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "trill_types"
+  }
+  match {
+    id: 1
+    bitwidth: <ETH_TYPE_BITWIDTH>
+    match_type: EXACT
+  }
+  size: <MAX_TRILL_TYPES>
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0x22f3 }
+      }
+      match {
+        field_id: 1
+        exact { value: 0x893b }
+      }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the parse_trill_types state. +

+

A ValueSetEntry entity update message has the following fields: +

+
    +
  • +

    value_set_id is the uint32 identifier of the Value Set instance, as +defined in P4Info. +

  • +
  • +

    members is a repeated field of type ValueSetMember. When “selecting” +against a Value Set, every member will be considered and if at least one +“matches”, the corresponding parser transition will be taken. Each +ValueSetMember contains a repeated field of FieldMatch messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a ValueSetMember if and only if +it matches all its FieldMatch messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. FieldMatch messages in a ValueSetEntry follow +the same rules as in a TableEntry. +

+ +

A ValueSetEntry may only be modified. If the update type is INSERT or +DELETE, the server must return an INVALID_ARGUMENT error. If the update type +is MODIFY, the server writes the members given in the repeated field to the +Value Set entry indexed by the given value_set_id. The maximum number of +matches must not exceed the maximum size given by the size field in P4Info of +the Value Set, otherwise the server must return a RESOURCE_EXHAUSTED error. To +empty a Value Set (i.e. restore it to its initial state), the P4Runtime client +can perform a MODIFY update with an empty members repeated field. +

+

To facilitate read-write symmetry, the server must +return an ALREADY_EXISTS error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set. +

+

See Appendix A.3 for a more complex Value Set example. +

9.7. RegisterEntry

+

The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The RegisterEntry P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations. +

+

RegisterEntry has the following fields: +

+
    +
  • +

    register_id, which identifies the PSA Register extern instance which is +being accessed by the client; the register_id is specified by the P4Info +message. +

  • +
  • +

    index, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the RegisterEntry message +used for the request. When an index is provided , the server must validate +its value, and return INVALID_ARGUMENT for a negative index or +OUT_OF_RANGE if the index exceeds the size of the register array. +

  • +
  • +

    data: the data to be written to the array (if RegisterEntry is part of a +WriteRequest message) or the data read from the array (if RegisterEntry is +part of a ReadResponse message). The data field is a P4Data message and +must match the format described by the type_spec field of the corresponding +Register entry in the P4Info, or the server must return an INVALID_ARGUMENT +error. +

+

9.8. DigestEntry

+

A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly. +

+

The DigestEntry P4Runtime entity is used to configure how the device must +generate digest messages. The DigestEntry Protobuf message is not used to +carry digest data, which is done on the StreamChannel bidirectional stream +using the DigestList (digest data sent by the target to the client) and +DigestListAck (digest data acknowledgments sent by the client to the target) +Protobuf messages. +

+

In this section, we refer to the data learned by a single data plane call to +Digest<T>::pack as a “digest message” and we use “digest list” to designate +the list of digest messages bundled by the P4Runtime service in a single +DigestList stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are “duplicate” if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are “distinct” +if they are not duplicate. +

+

DigestEntry has the following fields: +

+
    +
  • +

    digest_id, which identifies the PSA Digest extern instance which emitted the +data; the digest_id is determined by the P4Info message. +

  • +
  • +

    config, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +digest_id; these parameters are: +

    +
      +
    • max_timeout_ns: the maximum server buffering delay in nanoseconds for an +outstanding digest message. +
    • +
    • max_list_size: the maximum digest list size in number of digest +messages sent by the server to the client as a single DigestList +Protobuf message. +
    • +
    • ack_timeout_ns: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data. +
    +
+ +

Here is the significance of the different Update types for DigestEntry: +

+
    +
  • INSERT: Enable server generation of DigestList messages for given digest +instance and use provided configuration parameters. +
  • +
  • MODIFY: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance. +
  • +
  • DELETE: Disable server generation of DigestList messages for given digest +instance. +
+ +

A server should buffer digest messages until either: +

+
    +
  • max_timeout_ns time has passed since the first digest message was added to +the empty buffer, or +
  • +
  • max_list_size distinct digest messages have been received from the +data plane and added to the buffer +
+ +

At which point the server should, with best effort, generate a DigestList +stream message with the buffer contents and send it to the primary client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software. +

+

To avoid sending duplicate digest messages across different DigestList +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the primary client indicates that it has received the +digest list and acted on it. The server must keep a “cache” containing the set +of all digest messages that have been sent, but not acknowledged yet by the +primary client, up-to ack_timeout_ns in the past. The server must delete all +cache entries for a given digest list when they are at least ack_timeout_ns +old or when a matching DigestListAck message (i.e. with the same digest_id +and list_id fields as the DigestList message) is received. +

+

The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged DigestList messages. +

+

When max_timeout_ns is set to 0 and / or max_list_size is set to 1, the +server should, with best effort, generate a DigestList message for every +digest message generated by the data plane which is not already in the cache. If +ack_timeout_ns is set to 0, the cache must always be an empty set. If +max_list_size is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +max_timeout_ns configuration parameter. +

+

The P4Runtime server may empty the digest message cache in case of a client +status change. +

+

Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server: +

+
+
+
DigestStream stream;
+DigestCache cache;
+DigestBuffer buffers;
+
+// sends digest list when it is ready
+send_buffer(Id digest_id) {
+  buffer = buffers[digest_id];
+  stream.write(DigestList(buffer));
+  cache.merge(buffer);  // updates cache with new digest list
+  buffer.clear();
+}
+
+// callback which handles data plane digest messages from device
+handle_dataplane_digest(Digest msg) {
+  digest_id = msg.digest_id();
+  buffer = buffers[digest_id];
+  if (msg in cache OR msg in buffer) return;
+  buffer.enqueue(msg);
+  if (buffer.length() < max_list_size(digest_id)) return;
+  send_buffer(digest_id);
+}
+
+// callback which handles ack messages received on the stream
+handle_stream_ack(DigestListAck ack) {
+  // clear all cache entries matching the tuple (digest_id, list_id)
+  cache.erase( (ack.digest_id(), ack.list_id() )
+}
+
+// loop to enforce timeouts
+while (true) {
+  now = now();
+  // check for buffers that need to be sent
+  for ((digest_id, buffer) in buffers) {
+    if (now - buffer.first_enq_time() >= max_timeout_ns(digest_id))
+      send_buffer(buffer_id);
+  }
+  // check for expired entries in cache
+  for ((digest_id, list_id, sent_time) in cache) {
+    if (now - sent_time >= ack_timeout_ns(digest_id))
+      cache.erase( (digest_id, list_id) );
+  }
+  sleep(X);
+}

9.9. ExternEntry

+

This is used to support a P4 extern entity that is not part of PSA. It is +defined as: +

+
+
+
message ExternEntry {
+  uint32 extern_type_id = 1;
+  uint32 extern_id = 2;
+  google.protobuf.Any entry = 3;
+}
+

Each ExternEntry entity maps to an Extern message in the +P4Info and an ExternInstance message within that +message. The extern_type_id field must be equal to the one in +ExternEntry. The extern_id field must be equal to the ID included in the +preamble of the corresponding ExternInstance message. +

+

entry itself is embedded as an Any Protobuf message [31] to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on Extending P4Runtime for non-PSA +Architectures for more information. +

10. Error Reporting Messages

+

P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case. +

+

gRPC uses grpc::Status [32] to represent the status returned by an +RPC. It has 3 attributes: +

+
+
+
StatusCode code_;
+grpc::string error_message_;
+grpc::string binary_error_details_;
+

The code_ represents a canonical error [34] and describes the +overall RPC status. The error_message_ is a developer-facing error message, +which should be in English. The binary_error_details_ carries a serialized +google.rpc.Status message [28] message, which has 3 fields: +

+
+
+
int32 code = 1;  // see code.proto
+string message = 2;
+repeated google.protobuf.Any details = 3;
+

The code and message fields must be the same as code_ and error_message_ +fields from grpc::Status above. The details field is a list that consists of +p4.Error messages that carry error details for individual elements inside +batch-request RPCs (e.g. Write and Read). p4.Error includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices [34]. +

+

Figure 7 illustrates how these messages fit together. +

+
+

error-report +

+
+ +
Figure 7. P4Runtime Error Report Message Format
+

gRPC provides utility functions ExtractErrorDetails() and SetErrorDetails() +[33] to easily convert between grpc::Status and +google.rpc.Status. +

+

Please see sections on individual P4Runtime RPCs for details on how +grpc::Status is populated for reporting errors. +

+

Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on Stream Error +Reporting for more information. +

11. Atomicity of Individual Write and Read Operations

+

Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane apply +operation, and every single Write operation on a table that inserts, deletes, +or modifies one table entry, the apply operation should behave as if that +Write operation has not yet occurred, or as if the Write operation is +complete. The P4 program should never behave as if the Write operation is +partially complete. These guarantees also apply to extern instances: Read and +Write operations on extern entities must execute atomically relative to extern +data plane methods. +

+

The atomicity guarantees provided by P4Runtime for individual Read and Write +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification [23]. +

+

The P416 language introduces an @atomic annotation [14], to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the @atomic annotation for Write +operations, as well as non-wildcard Read operations, +relative to data plane execution. Consider the following P4 example written for +PSA: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024) r1;
+
+  apply {
+    // ...
+    @atomic {
+        Value_t v = r1.read((Index_t)1);
+        v = v + 1;
+        r1.write((Index_t)1, v);
+    }
+  }
+}
+

If a P4Runtime server is processing messages which write to Register r1 at +index 1, these writes must not happen between the data plane read and +write. +

+

Now let's consider the following example: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024, (Value_t)0 /* initial value */) r1;
+
+  apply {
+    @atomic {
+        r1.write((Index_t)1, (Value_t)100);
+        r1.write((Index_t)2, (Value_t)100);
+    }
+    @atomic {
+        r1.write((Index_t)1, (Value_t)200);
+        r1.write((Index_t)2, (Value_t)200);
+    }
+  }
+}
+

If a P4Runtime client issues a wildcard Read on Register r1, there is no +guarantee that r1[1] == r1[2] in the response, as the read for r1[1] may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for r1[2] may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read r1[1] and r1[2] separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +ReadRequest message) of individual read requests. Similar to a batch +ReadRequest, a wildcard read of a register can execute the reads of the +register array elements (r1[1], r1[2], ) in an arbitrary order relative +to each other. +

+

If the @atomic annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program. +

12. Write RPC

+

The Write RPC updates one or more P4 entities on the target. The request is +defined as follows: +

+
+
+
message WriteRequest {
+  uint64 device_id = 1;
+  string role = 6;
+  Uint128 election_id = 3;
+  repeated Update updates = 4;
+  enum Atomicity {
+    CONTINUE_ON_ERROR = 0;
+    ROLLBACK_ON_ERROR = 1;
+    DATAPLANE_ATOMIC = 2;
+  }
+  Atomicity atomicity = 5;
+}
+

The device_id uniquely identifies the target P4 device. The role and +election_id define the client role and election-id as described in the +Primary-Backup Arbitration and Controller +Replication +section. The server is expected to perform the following checks (in this order) +before processing the updates list: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the primary for (device_id, role) according to +the election_id value, the server must return a PERMISSION_DENIED error. +

  4. +
  5. +

    If the Write is attempted before a ForwardingPipelineConfig has been set, +the server must return a FAILED_PRECONDITION error. +

+ +

The updates field is a list of P4 entity updates to be applied. Each update is +defined as: +

+
+
+
message Update {
+  enum Type {
+    UNSPECIFIED = 0;
+    INSERT = 1;
+    MODIFY = 2;
+    DELETE = 3;
+  }
+  Type type = 1;
+  Entity entity = 2;
+}
+

This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a logical table (e.g. +CounterEntry) or an actual table (e.g. TableEntry) in the P4 data +plane. Each entity in the container is uniquely identified by its key. Please +refer to the P4 Entity Messages section for details on +what parts of the entity specification make up the key for each P4 entity. +

+

An update can be one of the following types: +

+
    +
  • +

    INSERT: Inserts the given P4 entity in the entity container. +The entity field always specifies the full state of the P4 entity. +If the entity already exists, an ALREADY_EXISTS error is returned, and +the existing entity remains unchanged. If the entity is malformed, an +INVALID_ARGUMENT error is usually returned (unless a more specific error +code applies [34]). If the entity cannot be inserted because the +container is already full, a RESOURCE_EXHAUSTED error is returned. +

  • +
  • +

    MODIFY: Modifies the P4 entity to its new specified state. This uses +assign or full-snapshot semantics, i.e. the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an INVALID_ARGUMENT error is usually returned (unless a +more specific error code applies [34]). If the entity does not +exist, a NOT_FOUND error is returned. +

  • +
  • +

    DELETE: Deletes the specified P4 entity. If the entity does not exist, a +NOT_FOUND error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored. +

+ +

If an update is not allowed under the given controller role, the server must +return a PERMISSION_DENIED error for this update. +

12.1. Batching and Ordering of Updates

+

P4Runtime supports batching of Write operations. The list of updates in a +WriteRequest is referred to as a batch. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of TableEntry entities). +

+

The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +WriteRequests can also be processed interleaved and/or in parallel. +However, the processing of requests must be strictly serializable. That +is, given a history $S$ of WriteRequests including the responses to those +requests, there must exist an order $L$ for all updates in $S$, such that: +

+
    +
  1. All updates from the same write request must appear as a contiguous +subsequence in $L$, but the order within that subsequence can be arbitrary. +
  2. +
  3. For two updates $u_1$ and $u_2$, if the write request containing $u_1$ +completed before the write request of $u_2$ was sent, then $u_1$ must appear +before $u_2$ in $L$. +
  4. +
  5. Executing all updates in $L$ sequentially must yield the same response for +every update as in $S$. +
  6. +
  7. The observable state of the switch after $S$ (e.g., through the Read RPC) +is identical to the one obtained by sequentially executing $L$. +
+ +

The Write RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the Write RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (e.g. inserting an ActionProfileMember +followed by pointing a TableEntry to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding Write RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate Write calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each Write call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one. +

12.2. Batch Atomicity

+

A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the Atomicity +enum. A P4Runtime server is required to support only the modes marked as +Required below: +

+
    +
  • +

    Required: CONTINUE_ON_ERROR: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that see each of +these intermediate stages. +

  • +
  • +

    Optional: ROLLBACK_ON_ERROR: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is all-or-none, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that see each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure. +

    +

    If a P4Runtime server does not support this option at all, an +UNIMPLEMENTED error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (e.g. it is +more straightforward to implement batches that contain only INSERT +operations, vs. those that contain DELETE operations), an +UNIMPLEMENTED error is returned when the batch cannot be executed +in a data plane-atomic way. +

  • +
  • +

    Optional: DATAPLANE_ATOMIC: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +transaction. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane's table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table. +

    +

    If a P4Runtime server does not support this option at all, an UNIMPLEMENTED +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an UNIMPLEMENTED error is returned when the batch +cannot be executed in a data plane-atomic way. +

+ +

There is no expectation that a given client must always use the same Atomicity +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use DATAPLANE_ATOMIC at one time and default behavior +(CONTINUE_ON_ERROR) at other times. +

12.3. Error Reporting

+

Please see section Error Reporting Messages for +information on error reporting messages and guidelines. P4Runtime server will +populate grpc::Status as follows: +

+
    +
  1. +

    If all batch updates succeeded, set grpc::Status::code_ to OK and do not +populate any other field. +

  2. +
  3. +

    If an error is encountered before even trying to attempt individual batch +updates, set grpc::Status::code_ that best describes that RPC-wide +error. For example, use UNAVAILABLE if the P4Runtime service is not yet +ready to handle requests. Set error_message_ to describe the issue. Do not +set error_details in this case. +

  4. +
  5. +

    Otherwise, if one or more updates in the batch (WriteRequest.updates) +failed, set grpc::Status::code_ to UNKNOWN. For example, one update in +the batch may fail with RESOURCE_EXHAUSTED and another with +INVALID_ARGUMENT. A p4.Error message is used to capture the status of +each and every update in the batch. The number of p4.Error messages packed +into google.rpc.Status.details field should therefore always match the +number of updates in the WriteRequest, and the order of +p4.Error messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +p4.Error should set the code to OK and omit other fields. +

+ +
+
+
# Example of a grpc::Status returned for a Write RPC with a batch of 3 updates.
+# The first and third updates encountered an error, while the second update
+# succeeded.
+code_ = 2  # UNKNOWN
+error_message_ = "Write failure."
+binary_error_details {
+  code: 2  # UNKNOWN
+  message: "Write failure."
+  details {
+    canonical_code: 8  # RESOURCE_EXHAUSTED
+    message: "Table is full."
+    space: "targetX-psa-vendorY"
+    code: 500  # ERR_TABLE_FULL
+  }
+  details {
+    canonical_code: 0  # OK
+  }
+  details {
+    canonical_code: 6  # ALREADY_EXISTS
+    message: "Entity already exists."
+    space: "targetX-psa-vendorY"
+    code: 600  # ERR_ENTITY_ALREADY_EXISTS
+  }
+}

13. Read RPC

+

The Read RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as: +

+
+
+
message ReadRequest {
+  uint64 device_id = 1;
+  string role = 3;
+  repeated Entity entities = 2;
+}
+

The device_id uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +NOT_FOUND error. +If the Read is attempted before ForwardingPipelineConfig has been set, the +server must return a FAILED_PRECONDITION error. +The role field acts as a filter, restricting the reported entities based on +the role to which the entity belongs. +The entities repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server. +

+

Since ReadRequests do not mutate any state on the switch, they do not +require an election_id, and they do not require the presence of an open +StreamChannel between the server and client. +

+

The Read response consists of a sequence of messages (a gRPC stream) with +each message defined as: +

+
+
+
message ReadResponse {
+  repeated Entity entities = 1;
+}
+

The entities repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the Finish() method on the stream object +[10]). +

13.1. Nomenclature

+
+
request
+
An element of the p4.ReadRequest.entities repeated field. +
+
batch
+
Refers to the p4.ReadRequest.entities repeated field.
+

Each request acts as a query filter for that entity type. If a request fully +specifies the entity key, the Read operation should retrieve a single P4 +entity. Please refer to the P4 Entity Messages section +for details on what parts of the entity specification make up the entity key. +

13.2. Wildcard Reads

+

P4Runtime allows wildcard read of P4 entities. A request may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the P4 Entity Messages section for details on +what parts of the entity can be wildcarded in a given request. +

+

For example, in a request of type CounterEntry: +

+
    +
  • A default counter_id (0) implies a request to read all counter-entries for +all indirect counters. +
  • +
  • A particular (non-default) counter_id in conjunction with index unset +implies a request to read all counter-entries for the given indirect counter +ID. +
+ +

To read the entire forwarding state for a given device, the P4Runtime client can +generate the following ReadRequest: +

+
+
+
device_id: <ID>
+entities {
+  extern_entry { }  # read all extern instances for all supported extern types
+  table_entry { }  # read all table entries for all tables
+  action_profile_member { }  # read all members for all action profiles
+  action_profile_group { }  # read all groups for all action profiles
+  ...
+}
+

The entity oneof field in the Entity message must always be set, or the +server must return an INVALID_ARGUMENT error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty Entity message in the ReadRequest. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the entity oneof [20]. +

13.3. Batch Processing

+

A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type request +appears only once in the batch. +

+

A P4Runtime server will process the batch as follows: +

+
    +
  1. +

    Lock state (preventing new writes) and validate each request in the batch: +

    +
      +
    1. +

      If it is a valid request, perform the read; +

      +
        +
      1. If the read was successful, return the entities read in +ReadResponse stream. +
      2. +
      3. If the read failed (exception / critical-error), prepare a p4.Error +with code set to INTERNAL. +
      +
    2. +
    3. +

      If the request is invalid (invalid-argument, not-supported, etc.), +prepare a p4.Error with relevant canonical code to capture the error. +

    +
  2. +
  3. +

    Unlock the state (allowing new writes); +

  4. +
  5. +

    Close the ReadResponse stream and return a grpc::Status as follows: +

    +
      +
    1. +

      If no errors were encountered, set code to OK and do not populate any +other field. +

    2. +
    3. +

      Otherwise, the overall code should be set to UNKNOWN. See section +Error Reporting Messages for information +on error reporting messages and guidelines. Assemble a list of p4.Error +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +google.rpc.Status.details field. This behavior also matches Write +RPC. +

    +
+

13.3.1. Example

+

If a client asked to read {a,b,c,d} and b and d requests didn't +validate, the server will return entities corresponding to a and c, followed +by a status {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} in the +details field. +

+

The P4Runtime server is not required to perform any optimization (e.g. merge two +requests in the batch if one is a subset of other). As a result of this, it +is possible for the ReadResponse to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging. +

+

There is no requirement that each request in the batch will correspond to one +ReadResponse message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit. +

+

A P4Runtime server must be prepared to handle multiple concurrent Read RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (e.g. in a single-threaded architecture), it may choose to serialize +Read RPC processing. +

13.4. Parallelism of Read and Write Requests

+

A P4Runtime server may be implemented to serve at most one +ReadRequest or WriteRequest message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so. +

+

For example, imagine a client that wanted to use WriteRequest +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +WriteRequest messages with only a few updates to an ActionSelector +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +WriteRequest batch currently being processed, but it will not +complete for a significant amount of time. +

+

The restrictions on which a client may rely are: +

+
    +
  • The processing of any two WriteRequest messages W1 and W2 must +result in the same state as if one of them was completed before the +other began. +
  • +
  • For any WriteRequest W and any ReadRequest R, R must +return results consistent with a state where W has completed +processing, or W has not yet begun processing. +
+ +

For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a WriteRequest message it acquired a write lock for each stateful +object affected by the WriteRequest, and before starting the +processing of a ReadRequest message it acquired a read lock for each +stateful object accessed by the ReadRequest, such an implementation +meets all of the requirements above. +

+

It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, e.g. if the server somehow determined that two +WriteRequest messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly. +

14. SetForwardingPipelineConfig RPC

+

A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the SetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message SetForwardingPipelineConfigRequest {
+  enum Action {
+    UNSPECIFIED = 0;
+    VERIFY = 1;
+    VERIFY_AND_SAVE = 2;
+    VERIFY_AND_COMMIT = 3;
+    COMMIT = 4;
+    RECONCILE_AND_COMMIT = 5;
+  }
+  uint64 device_id = 1;
+  string role = 6;
+  Uint128 election_id = 3;
+  Action action = 4;
+  ForwardingPipelineConfig config = 5;
+}
+

The server is expected to perform the following checks (in this order) +before performing the required action: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the primary for (device_id, role) according to +the election_id value, the server must return a PERMISSION_DENIED error. +

+ +

The action is the type of configuration action requested, it can be one of: +

+
    +
  • +

    VERIFY: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an INVALID_ARGUMENT +error if config is not provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_SAVE: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent Read / Write requests must refer to fields in the new +config. Returns an INVALID_ARGUMENT error if the forwarding config is not +provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_COMMIT: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an INVALID_ARGUMENT error if the forwarding config is not provided or if the +provided config cannot be realized. +

  • +
  • +

    COMMIT: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a NOT_FOUND error if no saved config +is found, i.e. if no VERIFY_AND_SAVE action preceded this one. Returns an +INVALID_ARGUMENT error if a config is provided with this message. +

  • +
  • +

    RECONCILE_AND_COMMIT: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an UNIMPLEMENTED error. For targets that support this option, an +INVALID_ARGUMENT error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target. +

+ +

The config field is a message of type ForwardingPipelineConfig that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(e.g. generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the Forwarding-Pipeline +Configuration section for details. +

+

A P4Runtime server running on a non-programmable device may not +support SetForwardingPipelineConfig (e.g. the forwarding-pipeline +config is part of the device's software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +UNIMPLEMENTED error. +

15. GetForwardingPipelineConfig RPC

+

The forwarding-pipeline configuration of the target can be retrieved by invoking +the GetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message GetForwardingPipelineConfigRequest {
+  enum ResponseType {
+    ALL = 0;
+    COOKIE_ONLY = 1;
+    P4INFO_AND_COOKIE = 2;
+    DEVICE_CONFIG_AND_COOKIE = 3;
+  }
+  uint64 device_id = 1;
+  ResponseType response_type = 2;
+}
+

The device_id uniquely identifies the target P4 device. A NOT_FOUND error is +returned if the device_id is not recognized by the P4Runtime server. +

+

The response_type is used to specify which fields to populate in the response, +its value can be one of: +

+
    +
  • +

    ALL: returns a ForwardingPipelineConfig with all fields +set as stored by the target. This is the default behaviour if the +response_type field is not set. +

  • +
  • +

    COOKIE_ONLY: reply by setting only the cookie field in the +ForwardingPipelineConfig, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message. +

  • +
  • +

    P4INFO_AND_COOKIE: reply by setting the p4info and cookie fields. +

  • +
  • +

    DEVICE_CONFIG_AND_COOKIE: reply by setting the p4_device_config and +cookie fields. +

+ +

The response contains the ForwardingPipelineConfig for the specified device: +

+
+
+
message GetForwardingPipelineConfigResponse {
+  ForwardingPipelineConfig config = 1;
+}
+

If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level config field will be unset in the response. Examples are +(i) a server that only allows configuration via SetForwardingPipelineConfig +but this RPC hasn't been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn't yet occurred. +

+

Once a forwarding-pipeline config is installed on the device (either via +SetForwardingPipelineConfig or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +config.p4_device_config will be empty / unset in the response, even if +response_type in the request was set to ALL. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the SetForwardingPipelineConfig RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +SetForwardingPipelineConfig, the value of config.cookie will be unset. +

+

If a P4Runtime server supports both SetForwardingPipelineConfig as well as +returning the p4_device_config, there should be read-write symmetry between +SetForwardingPipelineConfig and GetForwardingPipelineConfig RPCs. +

16. P4Runtime Stream Messages

16.1. Packet I/O

+

P4Runtime supports controller packet-in and packet-out by means of PacketIn +and PacketOut stream messages, respectively. +

+

PacketIn messages are sent by the P4Runtime server to the client. Conversely, +PacketOut messages are sent by the client to the server. Any PacketOut +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a StreamMessageResponse message with the error field set to +report the error to the client. See the section on Stream Error +Reporting for more information on error. +

+

As introduced in the ControllerPacketMetadata +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with @controller_header. The expected metadata is described +in the P4Info using the ControllerPacketMetadata messages. +

+

Both PacketIn and PacketOut stream messages share the same fields and are +defined as follows: +

+
+
+
// Packet sent from the controller to the switch.
+message PacketOut {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+// Packet sent from the switch to the controller.
+message PacketIn {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+message PacketMetadata {
+  // This refers to Metadata.id coming from P4Info ControllerPacketMetadata.
+  uint32 metadata_id = 1;
+  bytes value = 2;
+}
+
    +
  • +

    payload is used to carry the full packet content, including the headers. +

  • +
  • +

    metadata is a repeated field of PacketMetadata messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +ControllerPacketMetadata. Indeed, when a P4Runtime client (or server) +generates a PacketOut (or PacketIn) message, it needs to populate the +metadata field with as many values as in ControllerPacketMetadata.metadata +for the packet-out (or packet-in) case. Each PacketMetadata.value is a +binary string and must conform to the Bytestrings +requirements based on the corresponding P4Info +ControllerPacketMetadata.metadata specification. If the metadata field +does not match the P4Info specification, the server must drop the PacketOut +message and may generate a StreamMessageResponse message with the error +field set to report the error to the client which issued the PacketOut. See +the section on Stream Error Reporting for more +information on error. +

+

16.2. Client Arbitration Update

+

P4Runtime's client arbitration mechanism ensures that only the current primary +can modify state on the switch, and that the election_id is monotonically +increasing. For example, the switch must finish all previous write operations +before before selecting a different primary, and must only accept write requests +from the current primary. +

+

As explained earlier in this document, the controller uses the StreamChannel +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via Write RPC), +it needs to start a controller session and become a “primary”. To do so, the +controller first opens a bidirectional stream channel to the server via +StreamChannel for each device and sends a StreamMessageRequest message. The +controller populates the MasterArbitrationUpdate field in this message using +its role and election_id and the device_id of the device, as explained +in detail in the Client Arbitration and Controller +Replication +section. For any given (device_id, role), the P4Runtime server keeps track +of the highest election_id that it has ever received. If a controller's +election_id is equal to the highest election_id that the server has ever +received, that controller is the primary. All other controllers are backups. +Note that it is possible that all controllers are backups, and that there is no +primary. There can be at most one primary, because for any given +(device_id, role), each connected controller has a unique election_id. +

+

This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest election_id after such a restart. +However, across a full restart, the election_id must be +reset. In fact, a full restart is the only way to reset the election_id. +

+

The MasterArbitrationUpdate message is defined as follows: +

+
+
+
message MasterArbitrationUpdate {
+  uint64 device_id = 1;
+  // The role for which the primary client is being arbitrated. For use-cases
+  // where multiple roles are not needed, the controller can leave this unset,
+  // implying default role and full pipeline access.
+  Role role = 2;
+  // The stream RPC with the highest election_id is the primary. The 'primary'
+  // controller instance populates this with its latest election_id. Switch
+  // populates with the highest election ID it has received from all connected
+  // controllers.
+  Uint128 election_id = 3;
+  // Switch populates this with OK for the client that is the primary, and
+  // with an error status for all other connected clients (at every primary
+  // client change). The controller does not populate this field.
+  .google.rpc.Status status = 4;
+}
+
+message Role {
+  // Uniquely identifies this role.
+  string name = 3;
+  // Describes the role configuration, i.e. what operations, P4 entities,
+  // behaviors, etc. are in the scope of a given role. If config is not set
+  // (default case), it implies all P4 objects and control behaviors are in
+  // scope, i.e. full pipeline access. The format of this message is
+  // out-of-scope of P4Runtime.
+  .google.protobuf.Any config = 2;
+}
+

Note that the status field in the MasterArbitrationUpdate message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a StreamMessageResponse message back to the controller, in which +it populates the MasterArbitrationUpdate message using the device_id, +role, and election_id it previously received from the controller. The server +also populates the status field in the MasterArbitrationUpdate according to +the rules in an earlier section. +

+

The sender need not specify an election_id. If the election_id is not +specified, the sender's election_id is considered lower than any +election_id, and the sender will thus never become primary. This way, a +controller can choose to be a backup controller, in order to avoid +“flapping” (if a backup controller connects to the switch shortly before the +actual primary controller, therefore becoming primary temporarily). +

16.3. Digest Messages

+

See the DigestEntry section. +

16.4. Table Idle Timeout Notification

+

When a table supports idle timeout (as per the P4Info message), the primary +client can specify a TTL value for each entry in the table (see +Idle-timeout section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an IdleTimeoutNotification message on the +StreamChannel bidirectional stream to the primary client. The primary client +can then take the action of its choice, most likely remove the idle entry. +

+

The IdleTimeoutNotification Protobuf message has the following fields: +

+
    +
  • +

    timestamp: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server's local clock. +

  • +
  • +

    table_entry: a repeated field of entries which have expired. Each individual +entry is identified by a single TableEntry message. For each TableEntry, +the key fields (table_id, match and priority) must be set, along with +the controller_metadata field, the metadata field, and the +idle_timeout_ns field. Other fields may be set by the server but should be +ignored by the client. +

+ +

Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +IdleTimeoutNotification message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an IdleTimeoutNotification +message with an empty table_entry repeated field. +

+

After generating an idle notification, the P4Runtime server must “reset” the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the primary client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle. +

+

Here is a reasonable pseudo-code implementation for idle timeout for table +entries: +

+
+
+
IdleTimeoutStream stream;
+
+scanning_interval = 10ms;
+
+while (true) {
+  // iterate over all tables which support idle timeout
+  for (table in tables) {
+    if (!table.idle_timeout_supported) continue;
+    // we coalesce all idle notifications for the same table in one
+    // message
+    IdleTimeoutNotification msg;
+    // read time_since_last_hit from device
+    entries = device.load_table_entries_from_hw(table);
+    for (entry in entries) {
+      if (entry.idle_timeout == 0) continue;  // no TTL
+      if (entry.time_since_last_hit < entry.idle_timeout) continue;
+      msg.table_entry_add(entry);
+      entry.reset_time_since_last_hit();
+    }
+    if (msg.table_entry_size() == 0) continue;  // no notifications
+    msg.set_timestamp(now());
+    stream.write(msg);
+  }
+  sleep(scanning_interval);
+}

16.5. Architecture-Specific Notifications

+

P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on StreamChannel, by including an Any Protobuf field [31] +named other in both StreamMessageRequest and StreamMessageResponse. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the PSA Digest +extern. See section on Extending P4Runtime for non-PSA +Architectures for more information. +

16.6. Stream Error Reporting

+

The P4Runtime server can asynchronously report errors which occur when +processing StreamMessageRequest messages, using the error message field (of +type StreamError) in StreamMessageResponse. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature. +

+

The StreamError message has the following fields: +

+
    +
  • canonical_code, which must be set to the appropriate canonical error code +[34]. +
  • +
  • message, an optional developer-facing error message describing the error. +
  • +
  • space and code, which are optional and can be used by vendors to provide +additional details on the error. code is a numeric error code drawn from a +vendor's chosen error space. +
  • +
  • details, which is a Protobuf oneof used to help the client identify which +StreamMessageRequest triggered the error. The server is required to set the +appropriate field in the oneof so that the client can identify which type +of stream message is responsible for the error (packet_out, +digest_list_ack or other), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid PacketOut message from the +client, the packet_out field (of type PacketOutError) should be set in +the details oneof, and the server may additionally set the packet_out +field in the PacketOutError sub-message (by copying it from the invalid +PacketOut message received on the stream channel) so that the client can +know exactly what packet-out triggered the error. +
+ +

The appropriate canonical error code [34] should be used when +populating the canonical_code field. For example: +

+
    +
  • if a controller is not allowed to send a PacketOut message under its +current role definition, the code should be set to PERMISSION_DENIED. +
  • +
  • if the metadata repeated field in PacketOut does not match the P4Info +definition, the code should be set to INVALID_ARGUMENT. It may be useful +for the server to set the packet_out field in this case, so that the client +can find out which set of metadata fields triggered the error. +
  • +
  • if the digest_id field in DigestListAck does not match any Digest entry +in P4Info, the code should be set to INVALID_ARGUMENT. +
+ +

The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, e.g. because of a +burst of PacketIn messages. +

+

Note that client arbitration errors are never reported using the StreamError +message. Invalid MasterArbitrationUpdate messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section 5.3. +

16.6.1. Examples of StreamError Messages

+
    +
  • +

    Malformed packet-out metadata. If the server receives a PacketOut +message with a metadata field with id 7 which is not included in the P4Info +ControllerPacketMetadata message for “packet_out”, the server may send the +following StreamMessageResponse back to the client: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Unknown metadata field id 7."
    + packet_out {
    +   # copied from the PacketOut message received from the client
    +   packet_out {
    +     payload: ...
    +     metadata {
    +       id: 7
    +       name: "I_should_not_be_here"
    +       bitwidth: 32
    +     }
    +     # more metadata
    +   }
    + }
    +}
  • +
  • +

    Packet-out which exceeds the MTU. If the server receives a PacketOut +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following StreamMessageResponse: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Packet exceeds the MTU for port."
    + space: "targetX-psa-vendor1"
    + code: 123  # MTU_EXCEEDED
    + packet_out {
    +   # we do not set the packet_out field as it does not provide any
    +   # extra information to the client
    + }
    +}
+

17. Capabilities RPC

+

The Capabilities RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the CapabilitiesRequest message is empty and the CapabilitiesResponse +message only includes the p4runtime_api_version string field. This field must +be set to the full semantic version string [27] corresponding to the +version of the P4Runtime API implemented by the server, e.g. “1.1.0-rc.1”. +

+

Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three atomicity +modes for WriteRequest batches, two of them being +optional. In the future we may decide to leverage the CapabilitiesResponse +message to enable the server to report to the client which subset of these +atomicity modes is supported. +

+

The semantic version string included in CapabilitiesResponse can be used by +the client to determine which exact feature set is implemented by the server, +since minor releases may introduce new +functionality. However, because the Capabilities RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (i.e. an UNIMPLEMENTED error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0). +

18. Portability Considerations

18.1. PSA Metadata Translation

+

The Portable Switch Architecture (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +[24]. For such metadata, a translation between the controller's +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the @p4runtime_translation annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture. +

+
+

psa-metadata-translation +

+
+ +
Figure 8. P4Runtime Metadata Translation for the Portable Switch Architecture
+

Figure 8 illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller's 32 bit port +numbers to a target's 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch. +

18.1.1. Translation of Port Numbers

+

In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller's space and the PSA device's space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +user-defined P4 types, namely PortId_t and +PortIdInHeader_t, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in psa.p4 for +the PSA device in Switch 1. +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type bit<9> PortId_t;
+@p4runtime_translation("p4.org/psa/v1/PortIdInHeader_t", 32)
+type bit<32> PortIdInHeader_t;
+

The first argument to the @p4runtime_translation annotation is a URI that +indicates to the P4Runtime server which numerical mapping provided by the +out-of-band switch configuration mechanism to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports). +

+

An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows: +

+
+
+
enum SdnPort {
+  SDN_PORT_UNSPECIFIED = 0;
+
+  // SDN ports are numbered starting from 1.
+  SDN_PORT_MIN = 1;
+
+  // The maximum value of an SDN port (physical or logical).
+  SDN_PORT_MAX = 0xfffffeff;
+
+  // Reserved SDN port numbers (0xfffffff0 - 0xffffffff)
+
+  SDN_PORT_RECIRCULATE = 0xfffffffa;
+  SDN_PORT_CPU = 0xfffffffd;
+}
+

The switch config will map SDN_PORT_RECIRCULATE and SDN_PORT_CPU as well +as any SDN port number corresponding to a “regular” front-panel port to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation. +

+

The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs. +

18.1.2. Translation of Packet-IO Header Fields

+

Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  PortIdInHeader_t egress_port;
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  PortIdInHeader_t ingress_port;
+}
+

The header-level annotation @controller_header is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (egress_port) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI first argument to the @p4runtime_translation +annotation). Any subsequent reference to the egress_port field in the +data plane will use the translated value. PortIdInHeader_t is used in the +header definition instead of PortId_t to guarantee byte-aligned headers in +case this is required by the target. +

+

A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target's PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the ingress_port field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller. +

18.1.3. Translation of Match Fields

+

Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table's match key as shown in the example below: +

+
+
+
table t {
+  key = {
+    istd.ingress_port: exact;  // PSA standard metadata ingress port
+  }
+  actions = {
+    drop;
+  }
+}
+

Table t has an exact match on PSA standard metadata ingress port +(istd.ingress_port). Since the field is of type PortId_t, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in t from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table t is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values. +

+

Note that it may be infeasible to translate the value-mask pair for ternary +matches: LPM, TERNARY or RANGE match kinds. The P4Runtime server may +require that for these match kinds the port match be either de facto “exact” +(0xffffffff mask for TERNARY, prefix-length of 32 for LPM, or same low and +high bounds for RANGE) or “don't care”. +

18.1.4. Translation of Action Parameters

+

PortId_t type parameters can be part of a P4 action definition as shown in the +example below: +

+
+
+
action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+}
+
+table t {
+  key = {
+    hdr.h.f: exact;
+  }
+  actions = {
+    a;
+  }
+}
+

The controller may write entries in table t with action a to set the egress +port as shown in the P4 code above. The action parameter p is of type +PortId_t, which leads to a 32-bit bitwidth for p being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device. +

18.1.5. Port Translation for PSA Extern APIs

+

The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch_port +field is of type bytes to carry the SDN representation of the port being +watched. The P4Runtime server will translate the given watch port into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device. +

+

The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type uint32 to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane. +

18.1.6. Using Port as an Index to a Register, Indirect Counter or Indirect Meter

+

P4Runtime supports using a translated value (PortId_t or any other translated +type for which the underlying built-in type is bit<W>) as an index to a +register, indirect counter, or indirect meter. +

+
+
+
Counter<bit<32> /* counter entry type */, PortId_t /* index type */>(
+  32w1024, PSA_CounterType_t.PACKETS) counter;
+action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+  counter.count(p);
+}
+

This P4 Counter declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
counters {
+  preamble {
+    id: 0x12000001
+    name: "counter"
+  }
+  spec {
+    unit: PACKETS
+  }
+  index_type_name {
+    name: "PortId_t"
+  }
+}
+

The controller may read and write counter values from indexed counter counter +using SDN port numbers as indices, and not device-specific port numbers. The +index_type_name field in the P4Info message is a signal to the P4Runtime +server that translation is required. +

19. P4Runtime Versioning

+

P4Runtime follows the Google guidelines for versioning cloud APIs +[6]. We use a MAJOR.MINOR.PATCH style version number scheme and +we increment the: +

+
    +
  • MAJOR version when we make incompatible API changes, +
  • +
  • MINOR version when we add functionality in a backwards-compatible manner, +
  • +
  • PATCH version when we make backwards-compatible bug fixes. +
+ +

The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is p4.v1 and the package +name for P4Info is p4.config.v1. Even though p4 and p4.config are two +different Protobuf packages, p4 depends on p4.config and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence. +

+

As recommended in [6], we may consider using pre-GA release +suffixes (such as alpha or beta) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1). +

+

Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner. [7] describes +what constitute a backwards-compatible change. We expect MAJOR version bumps +to be a rare event. +

+

Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor + patch version numbers in future releases. +

+

All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository [15] and the version label follows +semantic versioning rules [27]. +

20. Extending P4Runtime for non-PSA Architectures

+

P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place. +

+

When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names: +

+
    +
  • p4/[organization]/arch/config/<major version>/p4info.proto +
  • +
  • p4/[organization]/arch/<major version>/p4runtime.proto +
+ +

We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they “extend”. +

+

For the remainder of this section, we will refer to these two files as +p4info-ext and p4runtime-ext respectively. +

20.1. Extending P4Runtime for Architecture-Specific Externs

+

Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both p4info-ext and +p4runtime-ext. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example: +

+
+
+
// T must be a bit<W> type, it indicates the width of each counter cell
+extern MyNewPacketCounter<T> {
+  counter(bit<32> size);
+  increment(in bit<32> index);
+}

20.1.1. Extending the P4Info message

+
    +
  • Id prefixes 0x81 through 0xfe are reserved for architecture-specific +externs. It is recommended that p4info-ext include a P4Ids message based +on the one in p4info.proto that the P4 compiler can refer to when assigning +IDs to each extern instance. +
+ +
+
+
message P4Ids {
+  enum Prefix {
+    UNSPECIFIED = 0;
+    MY_NEW_PACKET_COUNTER = 0x81;
+  }
+}
+
    +
  • p4info-ext should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +p4.config.v1.ExternInstance message as the info +field, which is of type Any [31]. +
+ +
+
+
message MyNewPacketCounter {
+  // corresponds to the T type parameter in the P4 extern definition
+  p4.config.v1.P4DataTypeSpec type_spec = 1;
+  // constructor argument
+  int64 size = 2;
+}

20.1.2. Extending the P4Runtime Service

+

Just like p4info-ext, p4runtime-ext should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an ExternEntry message generated by the +P4Runtime client. +

+

Here is a possible Protobuf message for our MyNewPacketCounter P4 extern: +

+
+
+
// This message enables reading / writing data to the counter at the provided
+// index
+message MyNewPacketCounter {
+  int64 index = 1;
+  p4.v1.P4Data data = 2;
+}
+

P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an Any Protobuf field [31] named other +in both p4.v1.StreamMessageRequest and +p4.v1.StreamMessageResponse. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in p4runtime-ext and embed instances of these messages in +p4.v1.StreamMessageRequest and p4.v1.StreamMessageResponse as appropriate. +

20.2. Architecture-Specific Table Extensions

20.2.1. New Match Types

+

An architecture may introduce new table match types [12]. P4Runtime +accounts for this by providing the following hooks: +

+
    +
  • +

    The match field in p4.config.v1.MatchField (p4info.proto) is a oneof +which can be either one of the default match types (EXACT, LPM, TERNARY, +RANGE, or OPTIONAL) or an architecture-specific match type encoded as a +string. +

  • +
  • +

    The field_match_type field in p4.v1.FieldMatch (p4runtime.proto) is a +oneof which includes an Any Protobuf message [31] field +(other). p4info-ext should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in p4.v1.FieldMatch as the +other field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info. +

+

20.2.2. New Table Properties

+

An architecture may introduce additional table properties +[30]. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +p4.config.v1.Table message includes the other_properties Any Protobuf +field [31]. At the moment, there is not any mechanism to extend the +p4.v1.TableEntry message based on the value of architecture-specific table +properties, but we may include on in future versions of the API. +

21. Known Limitations of Current P4Runtime Version

+
    +
  • +

    FieldMatch, action Param, and controller packet metadata fields only +support unsigned bitstrings, i.e. values of one of the following types (not +the more general P4Data): +

    +
      +
    • bit<W> +
    • +
    • bool. Note that as far as the P4Info message contents and +thus controller software is concerned, such fields of type bool +will be indistinguishable from those that have been declared with +type bit<1>. P4Runtime server software will automatically +perform any conversion needed between the type bit<1> values in +P4Runtime messages and the data plane representation. +
    • +
    • an enum with underlying type bit<W> +
    • +
    • a type or typedef with an underlying type that is one of the above (or +in general a “chain” of type and/or typedef that eventually ends with +one of the types above) +
    +
  • +
  • +

    Support for PSA Random & Timestamp externs is postponed to a future minor +version update. +

  • +
  • +

    P4Info does not include information about which of a table's actions execute +which direct resource(s). +

  • +
  • +

    The default action for indirect match tables is restricted to a const +NoAction known at compile-time. +

  • +
  • +

    There is no mechanism for changing the value of the psa_empty_group_action +table property at runtime. +

  • +
  • +

    There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor + +patch version numbers. +

+

A. Appendix

A.1. Revision History

A.1.1. Changes in v1.3.0

+
    +
  • Add IANA assigned TCP port, 9559, to P4Runtime server discussion. +
  • +
  • Move “Security considerations” section to P4Runtime server discussion. +
  • +
  • Deprecate watch field (int32) in favor of watch_port (bytes). This allows +using the watch port feature with the p4runtime_translation feature. +
  • +
  • Replace master, slave, master arbitration with more inclusive language: +primary, backup, and client arbitration +
  • +
  • Clarify that source locations for annotations are optional in the P4Info +message. +
+

A.1.2. Changes in v1.2.0

+
    +
  • Add new OPTIONAL match kind. At the moment, OPTIONAL is only supported by +the v1model architecture [38], and not by PSA. It will eventually be +included in the core P4 language. +
  • +
  • Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists. +
  • +
  • Add a new metadata field of type bytes to TableEntry. This is more +flexible than the now deprecated controller_metadata field. +
  • +
  • Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +@id annotation. +
  • +
  • Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature. +
  • +
  • Support using string as the controller type in the @p4runtime_translation +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type. +
  • +
  • Add optional P4 source locations to both structured and unstructured +annotations. +
+

A.1.3. Changes in v1.1.0

+
    +
  • Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously. +
  • +
  • Add error field to stream messages sent by the server. +
  • +
  • Add Capabilities RPC to query the P4Runtime API version implemented by the +server. +
  • +
  • Support wildcard reads for multicast groups and clone sessions. +
  • +
  • Support for modifying direct resources of const tables. +
  • +
  • Support P4 user-defined types for Packet IO metadata fields. +
  • +
  • Clarify consistency requirements for Write and Read RPCs. +
  • +
  • Add Appendix providing implementation advice for avoiding common pitfalls: + +
      +
    • advice on setting gRPC Metadata Maximum Size +
    • +
    • advice on setting gRPC Server Maximum Receive Message Size +
  • +
  • Clarify limitations on supported types for FieldMatch, action Param, and +Packet IO metadata fields. +
  • +
  • Clarify that reading entire forwarding state with empty entity is not +supported. +
  • +
  • Document that @p4runtime_translation need only be supported when applied to +type declarations in P4. +
+

A.2. P4 Annotations

+

Table 7 lists P416 annotations introduced primarily for +the purpose of adding features for the P4Runtime API. +

+
+ + + + + + + + + + +
Annotation Description
@brief See section 6.1.3
@controller_header See section 6.4.6
@description See section 6.1.3
@id See section 6.3
@max_group_size See sections 6.4.3, 9.2.2
@pkginfo See section 6.2.1
@p4runtime_translation See sections 8.5.6, 18.1.1
+
+ +
Table 7. P4 annotations introduced by P4Runtime

A.3. A More Complex Value Set Example

+

This section includes a more complex Value Set example, with multiple matches of +different kinds. +

+
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+

This P4 Value Set declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

A P4Runtime client can set the membership for this Value Set with WriteRequest +messages similar to this one: +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xac }
+      }
+      # match for field_id 2 is missing => don't care match
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xdc }
+      }
+      match {
+        field_id: 2
+        ternary { value: 0x88 mask: 8f }
+      }
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+  }
+}

A.4. Guidelines for Implementations

+

This section contains practical advice for implementing P4Runtime clients and +servers. +

A.4.1. gRPC Metadata Maximum Size

+

In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the grpc.max_metadata_size gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the Write P4Runtime RPC. The Write RPC +returns an individual error for every item in a batch (see Section +12), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +RESOURCE_EXHAUSTED error, without any of the individual errors. +

+

To fix this problem, one can set the grpc.max_metadata_size option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it's +limit, as only the receiving side's limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every p4.Error, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +8192 + MAX_UPDATES_PER_WRITE * 100 bytes of metadata. +

+

For example, in C++, one can create a client channel as follows: +

+
+
+
const int MAX_UPDATES_PER_WRITE = 100;
+::grpc::ChannelArguments arguments;
+arguments.SetInt(GRPC_ARG_MAX_METADATA_SIZE, 8192 + MAX_UPDATES_PER_WRITE*100);
+return grpc::CreateCustomChannel(address, credentials, arguments);

A.4.2. gRPC Server Maximum Receive Message Size

+

At the time of writing, the default maximum receive message size in gRPC is 4MB + while the default maximum send message size is unlimited. This can be a +problem for the SetForwardingPipelineConfig RPC, since for some targets the +binary p4_device_config can exceed 4MB, in which case by default the P4Runtime +server would return an INVALID_ARGUMENT error. To a lesser extent, this may +affect the Write RPC as well, in case of extremely large batches. +

+

To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of p4_device_config for their target(s). This can be done by +setting the grpc.max_receive_message_length when building the gRPC server. +

+

For example, in C++, one can set the maximum receive message size as follows: +

+
+
+
const int MAX_RECEIVE_MESSAGE_SIZE = 128 * 1024 * 1024;  // 128MB
+::grpc::ServerBuilder server_builder;
+builder.AddListeningPort(/*...*/);
+builder.RegisterService(/*...*/);  // register P4Runtime service
+builder.SetMaxReceiveMessageSize(MAX_RECEIVE_MESSAGE_SIZE);
+builder.BuildAndStart();
+

On the client side, we recommend that P4Runtime clients do not use Write +batches larger than the default maximum receive message size (4MB) in case +the server did not deem necessary to increase the default value , unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB). +

+

References

+
+ +
[2]“A Two Rate Three Color Marker.” https://​tools.​ietf.​org/​html/​rfc2698.
+ + + + +
[7]“Google Cloud APIs Versioning - Backwards-Compatibility.” https://​cloud.​google.​com/​apis/​design/​versioning#​backwards_​compatibility.
+ +
[9]“gRPC Main Site.” https://​grpc.​io.
+ + + + + +
[15]“p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” https://​github.​com/​p4lang/​p4runtime.
+
[16]“p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.” https://​github.​com/​p4lang/​PI.
+ + +
[19]“Portable Switch Architecture Specification (v1.1.0).” https://​p4.​org/​p4-​spec/​docs/​PSA-​v1.​1.​0.​html.
+ + + + + + + +
[27]“Semantic Versioning.” https://​semver.​org/​.
+ + + + + + + +
[35]“The OpenConfig Project.” http://​openconfig.​net.
+ +
[37]“The Stratum Project.” https://​stratumproject.​org/​.
+ +
+
+
+ +
+

1.an enum type used as a field in a header must specify a +underlying type and representation for enum elements. +

+ + + diff --git a/spec/v1.4.0-rc.4/P4Runtime-Spec.log b/spec/v1.4.0-rc.4/P4Runtime-Spec.log new file mode 100644 index 00000000..62266a18 --- /dev/null +++ b/spec/v1.4.0-rc.4/P4Runtime-Spec.log @@ -0,0 +1,14758 @@ +This is XeTeX, Version 3.14159265-2.6-0.99992 (TeX Live 2015/Debian) (preloaded format=xelatex 2018.8.17) 23 MAR 2022 20:43 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**build/P4Runtime-Spec.tex +(./build/P4Runtime-Spec.tex +LaTeX2e <2016/02/01> +Babel <3.9q> and hyphenation patterns for 81 language(s) loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2014/09/29 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo +File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@section=\count80 +\c@subsection=\count81 +\c@subsubsection=\count82 +\c@paragraph=\count83 +\c@subparagraph=\count84 +\c@figure=\count85 +\c@table=\count86 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) (build/madoko2.sty (/usr/share/texlive/texmf-dist/tex/latex/colortbl/colortbl.sty +Package: colortbl 2012/02/13 v1.0a Color table columns (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty +Package: array 2014/10/28 v2.4c Tabular extension package (FMi) +\col@sep=\dimen103 +\extrarowheight=\dimen104 +\NC@list=\toks14 +\extratabsurround=\skip43 +\backup@length=\skip44 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty +Package: color 2016/01/03 v1.1b Standard LaTeX Color (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package color Info: Driver file: xetex.def on input line 143. +(/usr/share/texlive/texmf-dist/tex/xelatex/xetex-def/xetex.def +File: xetex.def 2015/09/11 v4.06 LaTeX color/graphics driver for XeTeX (TeX Live/RRM/JK) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +))) +\everycr=\toks15 +\minrowclearance=\skip45 +) (/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: xetex.def on input line 225. +LaTeX Info: Redefining \color on input line 702. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) (build/options.sty +Package: options 2015/03/01, Daan Leijen, Provides convenient path-value (or key-value) options +(/usr/share/texlive/texmf-dist/tex/latex/etoolbox/etoolbox.sty +Package: etoolbox 2015/08/02 v2.2a e-TeX tools for LaTeX (JAW) +\etb@tempcnta=\count87 +) +\opt@nesting=\count88 +\opt@idx=\count89 +\opt@choiceord=\count90 +) (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty +Package: iftex 2013/04/04 v0.2 Provides if(tex) conditional for PDFTeX, XeTeX, and LuaTeX +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2014/10/28 v1.0g Enhanced LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks16 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2016/01/03 v1.0q Standard LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2016/01/03 v1.10 sin cos tan (DPC) +) (/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg +File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live +) +Package graphics Info: Driver file: xetex.def on input line 95. +) +\Gin@req@height=\dimen105 +\Gin@req@width=\dimen106 +) (build/longfbox.sty +Package: longfbox 2015/12/01, Daan Leijen, Provides long fbox that can break over pages +(build/longbox.sty +Package: longbox 2015/12/01, Daan Leijen, Provides basic longbox that can break over pages +(/usr/share/texlive/texmf-dist/tex/latex/mdwtools/footnote.sty +Package: footnote 1997/01/28 1.13 Save footnotes around boxes +\fn@notes=\box26 +\fn@width=\dimen107 +) +\lb@prevdepth=\skip46 +\lb@freevspace=\skip47 +\lb@headbox=\box27 +\lb@savebox=\box28 +\lb@mainbox=\box29 +\lb@usevbox=\count91 +\lb@width=\skip48 +\lb@height=\skip49 +\lb@skiptop=\skip50 +\lb@skipright=\skip51 +\lb@skipbottom=\skip52 +\lb@skipleft=\skip53 +\lb@skipbreaktop=\skip54 +\lb@skipbreakbottom=\skip55 +\lb@outerwidth=\skip56 +\lb@extrasplit=\skip57 +\lb@textalign=\count92 +\lb@baseline=\count93 +\lb@neededvspace=\skip58 +\lb@splitheight=\skip59 +\lb@insurance=\skip60 +\/longbox/@part-height=\skip61 +\/longbox/@part-width=\skip62 +\/longbox/@part-depth=\skip63 +\/longbox/@content-box-height=\skip64 +\/longbox/@content-box-width=\skip65 +\/longbox/@content-box-depth=\skip66 +\/longbox/@breakat-previous=\skip67 +\/longbox/@lower=\skip68 +\/longbox/split-minimum=\skip69 +\/longbox/split-badness=\skip70 +\/longbox/raise=\skip71 +\/longbox/height=\skip72 +\/longbox/width=\skip73 +\/longbox/outer-height=\skip74 +\/longbox/outer-width=\skip75 +\/longbox/skip-top=\skip76 +\/longbox/skip-right=\skip77 +\/longbox/skip-bottom=\skip78 +\/longbox/skip-left=\skip79 +\/longbox/skip-break-bottom=\skip80 +\/longbox/skip-break-top=\skip81 +) (/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.sty +Package: pict2e 2016/02/05 v0.3b Improved picture commands (HjG,RN,JT) +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.cfg +File: pict2e.cfg 2016/02/05 v0.1u pict2e configuration for teTeX/TeXLive +) +Package pict2e Info: Driver file: xetex.def on input line 119. +Package pict2e Info: Driver file for pict2e: p2e-xetex.def on input line 121. +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/p2e-xetex.def +File: p2e-xetex.def 2016/02/05 v0.1u Driver-dependant file (RN,HjG,JT) +) +\pIIe@GRAPH=\toks17 +\@arclen=\dimen108 +\@arcrad=\dimen109 +\@tempdimd=\dimen110 +) (build/ellipse.sty +Package: ellipse 2004/11/05 v1.0 .dtx ellipse file +) +\fbox@oct=\count94 +\fbox@quad=\count95 +\fbox@diaq=\count96 +\fbox@sign=\count97 +\fbox@anglestart=\skip82 +\fbox@angleend=\skip83 +\fbox@dash=\skip84 +\fbox@dashskip=\skip85 +\fbox@anglecur=\skip86 +\fbox@dashangle=\skip87 +\fbox@dashskipangle=\skip88 +\fbox@delta=\skip89 +\fbox@from=\skip90 +\fbox@to=\skip91 +\/fbox/padding-top=\skip92 +\/fbox/padding-right=\skip93 +\/fbox/padding-bottom=\skip94 +\/fbox/padding-left=\skip95 +\/fbox/padding-break-top=\skip96 +\/fbox/padding-break-bottom=\skip97 +\/fbox/margin-top=\skip98 +\/fbox/margin-right=\skip99 +\/fbox/margin-bottom=\skip100 +\/fbox/margin-left=\skip101 +\/fbox/margin-break-top=\skip102 +\/fbox/margin-break-bottom=\skip103 +\/fbox/border-top-width=\skip104 +\/fbox/border-right-width=\skip105 +\/fbox/border-bottom-width=\skip106 +\/fbox/border-left-width=\skip107 +\/fbox/border-break-top-width=\skip108 +\/fbox/border-break-bottom-width=\skip109 +\/fbox/@lower=\skip110 +\/fbox/@padding-box-height=\skip111 +\/fbox/@padding-box-depth=\skip112 +\/fbox/@padding-box-width=\skip113 +\/fbox/@border-box-width=\skip114 +\/fbox/@border-box-height=\skip115 +\/fbox/@border-box-depth=\skip116 +\/fbox/@border-top-left-radius-x=\skip117 +\/fbox/@border-top-right-radius-x=\skip118 +\/fbox/@border-bottom-left-radius-x=\skip119 +\/fbox/@border-bottom-right-radius-x=\skip120 +\/fbox/@border-top-left-radius-y=\skip121 +\/fbox/@border-top-right-radius-y=\skip122 +\/fbox/@border-bottom-left-radius-y=\skip123 +\/fbox/@border-bottom-right-radius-y=\skip124 +\/fbox/@border-top-left-ix=\skip125 +\/fbox/@border-top-left-iy=\skip126 +\/fbox/@border-top-right-ix=\skip127 +\/fbox/@border-top-right-iy=\skip128 +\/fbox/@border-bottom-left-ix=\skip129 +\/fbox/@border-bottom-left-iy=\skip130 +\/fbox/@border-bottom-right-ix=\skip131 +\/fbox/@border-bottom-right-iy=\skip132 +\/fbox/@border-top-left-phi=\skip133 +\/fbox/@border-top-right-phi=\skip134 +\/fbox/@border-bottom-left-phi=\skip135 +\/fbox/@border-bottom-right-phi=\skip136 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2016/03/03 v2.15a AMS math features +\@mathmargin=\skip137 +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2000/06/29 v2.01 AMS text +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen111 +)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen112 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 1999/12/14 v2.01 operator names +) +\inf@bad=\count98 +LaTeX Info: Redefining \frac on input line 199. +\uproot@=\count99 +\leftroot@=\count100 +LaTeX Info: Redefining \overline on input line 297. +\classnum@=\count101 +\DOTSCASE@=\count102 +LaTeX Info: Redefining \ldots on input line 394. +LaTeX Info: Redefining \dots on input line 397. +LaTeX Info: Redefining \cdots on input line 518. +\Mathstrutbox@=\box30 +\strutbox@=\box31 +\big@size=\dimen113 +LaTeX Font Info: Redeclaring font encoding OML on input line 630. +LaTeX Font Info: Redeclaring font encoding OMS on input line 631. +\macc@depth=\count103 +\c@MaxMatrixCols=\count104 +\dotsspace@=\muskip10 +\c@parentequation=\count105 +\dspbrk@lvl=\count106 +\tag@help=\toks19 +\row@=\count107 +\column@=\count108 +\maxfields@=\count109 +\andhelp@=\toks20 +\eqnshift@=\dimen114 +\alignsep@=\dimen115 +\tagshift@=\dimen116 +\tagwidth@=\dimen117 +\totwidth@=\dimen118 +\lineht@=\dimen119 +\@envbody=\toks21 +\multlinegap=\skip138 +\multlinetaggap=\skip139 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2735. +LaTeX Info: Redefining \] on input line 2736. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +) (/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/stmaryrd.sty +Package: stmaryrd 1994/03/03 St Mary's Road symbol package +\symstmry=\mathgroup6 +LaTeX Font Info: Overwriting symbol font `stmry' in version `bold' +(Font) U/stmry/m/n --> U/stmry/b/n on input line 89. +) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty +Package: textcomp 2005/09/27 v1.99g Standard LaTeX package +Package textcomp Info: Sub-encoding information: +(textcomp) 5 = only ISO-Adobe without \textcurrency +(textcomp) 4 = 5 + \texteuro +(textcomp) 3 = 4 + \textohm +(textcomp) 2 = 3 + \textestimated + \textcurrency +(textcomp) 1 = TS1 - \textcircled - \t +(textcomp) 0 = TS1 (full) +(textcomp) Font families with sub-encoding setting implement +(textcomp) only a restricted character set as indicated. +(textcomp) Family '?' is the default used for unknown fonts. +(textcomp) See the documentation for details. +Package textcomp Info: Setting ? sub-encoding to TS1/1 on input line 79. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +) +LaTeX Info: Redefining \oldstylenums on input line 334. +Package textcomp Info: Setting cmr sub-encoding to TS1/0 on input line 349. +Package textcomp Info: Setting cmss sub-encoding to TS1/0 on input line 350. +Package textcomp Info: Setting cmtt sub-encoding to TS1/0 on input line 351. +Package textcomp Info: Setting cmvtt sub-encoding to TS1/0 on input line 352. +Package textcomp Info: Setting cmbr sub-encoding to TS1/0 on input line 353. +Package textcomp Info: Setting cmtl sub-encoding to TS1/0 on input line 354. +Package textcomp Info: Setting ccr sub-encoding to TS1/0 on input line 355. +Package textcomp Info: Setting ptm sub-encoding to TS1/4 on input line 356. +Package textcomp Info: Setting pcr sub-encoding to TS1/4 on input line 357. +Package textcomp Info: Setting phv sub-encoding to TS1/4 on input line 358. +Package textcomp Info: Setting ppl sub-encoding to TS1/3 on input line 359. +Package textcomp Info: Setting pag sub-encoding to TS1/4 on input line 360. +Package textcomp Info: Setting pbk sub-encoding to TS1/4 on input line 361. +Package textcomp Info: Setting pnc sub-encoding to TS1/4 on input line 362. +Package textcomp Info: Setting pzc sub-encoding to TS1/4 on input line 363. +Package textcomp Info: Setting bch sub-encoding to TS1/4 on input line 364. +Package textcomp Info: Setting put sub-encoding to TS1/5 on input line 365. +Package textcomp Info: Setting uag sub-encoding to TS1/5 on input line 366. +Package textcomp Info: Setting ugq sub-encoding to TS1/5 on input line 367. +Package textcomp Info: Setting ul8 sub-encoding to TS1/4 on input line 368. +Package textcomp Info: Setting ul9 sub-encoding to TS1/4 on input line 369. +Package textcomp Info: Setting augie sub-encoding to TS1/5 on input line 370. +Package textcomp Info: Setting dayrom sub-encoding to TS1/3 on input line 371. +Package textcomp Info: Setting dayroms sub-encoding to TS1/3 on input line 372. +Package textcomp Info: Setting pxr sub-encoding to TS1/0 on input line 373. +Package textcomp Info: Setting pxss sub-encoding to TS1/0 on input line 374. +Package textcomp Info: Setting pxtt sub-encoding to TS1/0 on input line 375. +Package textcomp Info: Setting txr sub-encoding to TS1/0 on input line 376. +Package textcomp Info: Setting txss sub-encoding to TS1/0 on input line 377. +Package textcomp Info: Setting txtt sub-encoding to TS1/0 on input line 378. +Package textcomp Info: Setting lmr sub-encoding to TS1/0 on input line 379. +Package textcomp Info: Setting lmdh sub-encoding to TS1/0 on input line 380. +Package textcomp Info: Setting lmss sub-encoding to TS1/0 on input line 381. +Package textcomp Info: Setting lmssq sub-encoding to TS1/0 on input line 382. +Package textcomp Info: Setting lmvtt sub-encoding to TS1/0 on input line 383. +Package textcomp Info: Setting lmtt sub-encoding to TS1/0 on input line 384. +Package textcomp Info: Setting qhv sub-encoding to TS1/0 on input line 385. +Package textcomp Info: Setting qag sub-encoding to TS1/0 on input line 386. +Package textcomp Info: Setting qbk sub-encoding to TS1/0 on input line 387. +Package textcomp Info: Setting qcr sub-encoding to TS1/0 on input line 388. +Package textcomp Info: Setting qcs sub-encoding to TS1/0 on input line 389. +Package textcomp Info: Setting qpl sub-encoding to TS1/0 on input line 390. +Package textcomp Info: Setting qtm sub-encoding to TS1/0 on input line 391. +Package textcomp Info: Setting qzc sub-encoding to TS1/0 on input line 392. +Package textcomp Info: Setting qhvc sub-encoding to TS1/0 on input line 393. +Package textcomp Info: Setting futs sub-encoding to TS1/4 on input line 394. +Package textcomp Info: Setting futx sub-encoding to TS1/4 on input line 395. +Package textcomp Info: Setting futj sub-encoding to TS1/4 on input line 396. +Package textcomp Info: Setting hlh sub-encoding to TS1/3 on input line 397. +Package textcomp Info: Setting hls sub-encoding to TS1/3 on input line 398. +Package textcomp Info: Setting hlst sub-encoding to TS1/3 on input line 399. +Package textcomp Info: Setting hlct sub-encoding to TS1/5 on input line 400. +Package textcomp Info: Setting hlx sub-encoding to TS1/5 on input line 401. +Package textcomp Info: Setting hlce sub-encoding to TS1/5 on input line 402. +Package textcomp Info: Setting hlcn sub-encoding to TS1/5 on input line 403. +Package textcomp Info: Setting hlcw sub-encoding to TS1/5 on input line 404. +Package textcomp Info: Setting hlcf sub-encoding to TS1/5 on input line 405. +Package textcomp Info: Setting pplx sub-encoding to TS1/3 on input line 406. +Package textcomp Info: Setting pplj sub-encoding to TS1/3 on input line 407. +Package textcomp Info: Setting ptmx sub-encoding to TS1/4 on input line 408. +Package textcomp Info: Setting ptmj sub-encoding to TS1/4 on input line 409. +) (/usr/share/texlive/texmf-dist/tex/latex/psnfss/pifont.sty +Package: pifont 2005/04/12 PSNFSS-v9.2a Pi font support (SPQR) +LaTeX Font Info: Try loading font information for U+pzd on input line 63. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upzd.fd +File: upzd.fd 2001/06/04 font definitions for U/pzd. +) +LaTeX Font Info: Try loading font information for U+psy on input line 64. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upsy.fd +File: upsy.fd 2001/06/04 font definitions for U/psy. +)) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2012/11/06 v6.83m Hypertext links for LaTeX +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO) +Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO) +Package hobsub Info: Skipping package `infwarerr' (already loaded). +Package hobsub Info: Skipping package `ltxcmds' (already loaded). +Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO) +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is not detected. +Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) +Package etexcmds Info: Could not find \expanded. +(etexcmds) That can mean that you are not using pdfTeX 1.50 or +(etexcmds) that some package has redefined \expanded. +(etexcmds) In the latter case, load this package earlier. +Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) +Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO) +Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: pdfTeX >= 1.30 not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode not found. +Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO) +Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO) +Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO) +Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO) +Package: xcolor-patch 2011/01/30 xcolor patch +Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO) +Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO) +Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO) +Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2011/03/04 v1.3 Hooks for auxiliary files (HO) +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) +) +\@linkdim=\dimen120 +\Hy@linkcounter=\count110 +\Hy@pagecounter=\count111 +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count112 +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Hyper figures OFF on input line 4443. +Package hyperref Info: Link nesting OFF on input line 4448. +Package hyperref Info: Hyper index ON on input line 4451. +Package hyperref Info: Plain pages OFF on input line 4458. +Package hyperref Info: Backreferencing OFF on input line 4463. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4688. +\c@Hy@tempcnt=\count113 +(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip11 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 5041. +\XeTeXLinkMargin=\dimen121 +\Fld@menulength=\count114 +\Field@Width=\dimen122 +\Fld@charsize=\dimen123 +Package hyperref Info: Hyper figures OFF on input line 6295. +Package hyperref Info: Link nesting OFF on input line 6300. +Package hyperref Info: Hyper index ON on input line 6303. +Package hyperref Info: backreferencing OFF on input line 6310. +Package hyperref Info: Link coloring OFF on input line 6315. +Package hyperref Info: Link coloring with OCG OFF on input line 6320. +Package hyperref Info: PDF/A mode OFF on input line 6325. +LaTeX Info: Redefining \ref on input line 6365. +LaTeX Info: Redefining \pageref on input line 6369. +\Hy@abspage=\count115 +\c@Item=\count116 +\c@Hfootnote=\count117 +) + +Package hyperref Message: Driver (autodetected): hxetex. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hxetex.def +File: hxetex.def 2012/11/06 v6.83m Hyperref driver for XeTeX +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def +File: puenc.def 2012/11/06 v6.83m Hyperref: PDF Unicode definition (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/stringenc.sty +Package: stringenc 2011/12/02 v1.10 Convert strings between diff. encodings (HO) +) +\pdfm@box=\box32 +\c@Hy@AnnotLevel=\count118 +\HyField@AnnotCount=\count119 +\Fld@listcount=\count120 +\c@bookmark@seq@number=\count121 +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO) +Package rerunfilecheck Info: Feature \pdfmdfivesum is not available +(rerunfilecheck) (e.g. pdfTeX or LuaTeX with package `pdftexcmds'). +(rerunfilecheck) Therefore file contents cannot be checked efficiently +(rerunfilecheck) and the loading of the package is aborted. +) +\Hy@SectionHShift=\skip140 +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bookmark.sty +Package: bookmark 2011/12/02 v1.24 PDF bookmarks (HO) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bkm-dvipdfm.def +File: bkm-dvipdfm.def 2011/12/02 v1.24 bookmark driver for dvipdfm (HO) +\BKM@id=\count122 +)) (/usr/share/texlive/texmf-dist/tex/latex/booktabs/booktabs.sty +Package: booktabs 2005/04/14 v1.61803 publication quality tables +\heavyrulewidth=\dimen124 +\lightrulewidth=\dimen125 +\cmidrulewidth=\dimen126 +\belowrulesep=\dimen127 +\belowbottomsep=\dimen128 +\aboverulesep=\dimen129 +\abovetopsep=\dimen130 +\cmidrulesep=\dimen131 +\cmidrulekern=\dimen132 +\defaultaddspace=\dimen133 +\@cmidla=\count123 +\@cmidlb=\count124 +\@aboverulesep=\dimen134 +\@belowrulesep=\dimen135 +\@thisruleclass=\count125 +\@lastruleclass=\count126 +\@thisrulewidth=\dimen136 +) (/usr/share/texlive/texmf-dist/tex/latex/tools/longtable.sty +Package: longtable 2014/10/28 v4.11 Multi-page Table package (DPC) +\LTleft=\skip141 +\LTright=\skip142 +\LTpre=\skip143 +\LTpost=\skip144 +\LTchunksize=\count127 +\LTcapwidth=\dimen137 +\LT@head=\box33 +\LT@firsthead=\box34 +\LT@foot=\box35 +\LT@lastfoot=\box36 +\LT@cols=\count128 +\LT@rows=\count129 +\c@LT@tables=\count130 +\c@LT@chunks=\count131 +\LT@p@ftn=\toks23 +) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Package: anyfontsize 2007/11/22 anyfontsize.sty by pts +) (/usr/share/texlive/texmf-dist/tex/latex/enumitem/enumitem.sty +Package: enumitem 2011/09/28 v3.5.2 Customized lists +\labelindent=\skip145 +\enit@outerparindent=\dimen138 +\enit@toks=\toks24 +\enit@inbox=\box37 +\enitdp@description=\count132 +) (/usr/share/texlive/texmf-dist/tex/latex/wrapfig/wrapfig.sty +\wrapoverhang=\dimen139 +\WF@size=\dimen140 +\c@WF@wrappedlines=\count133 +\WF@box=\box38 +\WF@everypar=\toks25 +Package: wrapfig 2003/01/31 v 3.6 +) (/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.sty (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty +Package: expl3 2016/01/19 v6377 L3 programming layer (loader) +(/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3-code.tex +Package: expl3 2016/01/19 v6377 L3 programming layer (code) +L3 Module: l3bootstrap 2016/01/01 v6339 L3 Bootstrap code +L3 Module: l3names 2015/12/21 v6328 L3 Namespace for primitives +L3 Module: l3basics 2015/11/22 v6315 L3 Basic definitions +L3 Module: l3expan 2015/09/10 v5983 L3 Argument expansion +L3 Module: l3tl 2015/09/29 v6121 L3 Token lists +L3 Module: l3str 2016/01/03 v6357 L3 Strings +L3 Module: l3seq 2015/08/05 v5777 L3 Sequences and stacks +L3 Module: l3int 2016/01/05 v6366 L3 Integers +\c_max_int=\count134 +\l_tmpa_int=\count135 +\l_tmpb_int=\count136 +\g_tmpa_int=\count137 +\g_tmpb_int=\count138 +L3 Module: l3quark 2015/08/17 v5855 L3 Quarks +L3 Module: l3prg 2015/11/01 v6216 L3 Control structures +\g__prg_map_int=\count139 +L3 Module: l3clist 2015/09/02 v5901 L3 Comma separated lists +L3 Module: l3token 2015/11/11 v6249 L3 Experimental token manipulation +L3 Module: l3prop 2016/01/05 v6366 L3 Property lists +L3 Module: l3msg 2015/09/28 v6113 L3 Messages +L3 Module: l3file 2015/12/03 v6317 L3 File and I/O operations +\l_iow_line_count_int=\count140 +\l__iow_target_count_int=\count141 +\l__iow_current_line_int=\count142 +\l__iow_current_word_int=\count143 +\l__iow_current_indentation_int=\count144 +L3 Module: l3skip 2016/01/05 v6366 L3 Dimensions and skips +\c_zero_dim=\dimen141 +\c_max_dim=\dimen142 +\l_tmpa_dim=\dimen143 +\l_tmpb_dim=\dimen144 +\g_tmpa_dim=\dimen145 +\g_tmpb_dim=\dimen146 +\c_zero_skip=\skip146 +\c_max_skip=\skip147 +\l_tmpa_skip=\skip148 +\l_tmpb_skip=\skip149 +\g_tmpa_skip=\skip150 +\g_tmpb_skip=\skip151 +\c_zero_muskip=\muskip12 +\c_max_muskip=\muskip13 +\l_tmpa_muskip=\muskip14 +\l_tmpb_muskip=\muskip15 +\g_tmpa_muskip=\muskip16 +\g_tmpb_muskip=\muskip17 +L3 Module: l3keys 2015/11/17 v6284 L3 Key-value interfaces +\g__keyval_level_int=\count145 +\l_keys_choice_int=\count146 +L3 Module: l3fp 2015/08/25 v5890 L3 Floating points +\c__fp_leading_shift_int=\count147 +\c__fp_middle_shift_int=\count148 +\c__fp_trailing_shift_int=\count149 +\c__fp_big_leading_shift_int=\count150 +\c__fp_big_middle_shift_int=\count151 +\c__fp_big_trailing_shift_int=\count152 +\c__fp_Bigg_leading_shift_int=\count153 +\c__fp_Bigg_middle_shift_int=\count154 +\c__fp_Bigg_trailing_shift_int=\count155 +L3 Module: l3box 2015/08/09 v5822 L3 Experimental boxes +\c_empty_box=\box39 +\l_tmpa_box=\box40 +\l_tmpb_box=\box41 +\g_tmpa_box=\box42 +\g_tmpb_box=\box43 +L3 Module: l3coffins 2015/08/06 v5789 L3 Coffin code layer +\l__coffin_internal_box=\box44 +\l__coffin_internal_dim=\dimen147 +\l__coffin_offset_x_dim=\dimen148 +\l__coffin_offset_y_dim=\dimen149 +\l__coffin_x_dim=\dimen150 +\l__coffin_y_dim=\dimen151 +\l__coffin_x_prime_dim=\dimen152 +\l__coffin_y_prime_dim=\dimen153 +\c_empty_coffin=\box45 +\l__coffin_aligned_coffin=\box46 +\l__coffin_aligned_internal_coffin=\box47 +\l_tmpa_coffin=\box48 +\l_tmpb_coffin=\box49 +\l__coffin_display_coffin=\box50 +\l__coffin_display_coord_coffin=\box51 +\l__coffin_display_pole_coffin=\box52 +\l__coffin_display_offset_dim=\dimen154 +\l__coffin_display_x_dim=\dimen155 +\l__coffin_display_y_dim=\dimen156 +L3 Module: l3color 2014/08/23 v5354 L3 Experimental color support +L3 Module: l3sys 2015/09/25 v6087 L3 Experimental system/runtime functions +L3 Module: l3candidates 2016/01/14 v6376 L3 Experimental additions to l3kernel +\l__box_top_dim=\dimen157 +\l__box_bottom_dim=\dimen158 +\l__box_left_dim=\dimen159 +\l__box_right_dim=\dimen160 +\l__box_top_new_dim=\dimen161 +\l__box_bottom_new_dim=\dimen162 +\l__box_left_new_dim=\dimen163 +\l__box_right_new_dim=\dimen164 +\l__box_internal_box=\box53 +\l__coffin_bounding_shift_dim=\dimen165 +\l__coffin_left_corner_dim=\dimen166 +\l__coffin_right_corner_dim=\dimen167 +\l__coffin_bottom_corner_dim=\dimen168 +\l__coffin_top_corner_dim=\dimen169 +\l__coffin_scaled_total_height_dim=\dimen170 +\l__coffin_scaled_width_dim=\dimen171 +L3 Module: l3luatex 2015/11/11 v6250 L3 Experimental LuaTeX-specific functions +) (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def +File: l3xdvidpfmx.def 2015/11/11 v6250 L3 Experimental driver: xdvipdfmx +)) (/usr/share/texlive/texmf-dist/tex/latex/l3packages/xparse/xparse.sty +Package: xparse 2016/01/19 v6377 L3 Experimental document command parser +\l__xparse_current_arg_int=\count156 +\l__xparse_m_args_int=\count157 +\l__xparse_mandatory_args_int=\count158 +\l__xparse_processor_int=\count159 +\l__xparse_v_nesting_int=\count160 +) +Package: fontspec 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec-xetex.sty +Package: fontspec-xetex 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +\l_fontspec_script_int=\count161 +\l_fontspec_language_int=\count162 +\l_fontspec_strnum_int=\count163 +\l__fontspec_tmpa_dim=\dimen172 +\l__fontspec_tmpb_dim=\dimen173 +\l__fontspec_tmpc_dim=\dimen174 +\g__file_internal_ior=\read1 +(/usr/share/texlive/texmf-dist/tex/latex/base/fontenc.sty +Package: fontenc 2005/09/27 v1.99g Standard LaTeX package +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1enc.def +File: eu1enc.def 2010/05/27 v0.1h Experimental Unicode font encodings +) +LaTeX Font Info: Try loading font information for EU1+lmr on input line 105. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmr.fd +File: eu1lmr.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) (/usr/share/texlive/texmf-dist/tex/xelatex/xunicode/xunicode.sty +File: xunicode.sty 2011/09/09 v0.981 provides access to latin accents and many other characters in Unicode lower plane +(/usr/share/texmf/tex/latex/tipa/t3enc.def +File: t3enc.def 2001/12/31 T3 encoding +LaTeX Font Info: Try loading font information for EU1+lmss on input line 357. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmss.fd +File: eu1lmss.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) +\tipaTiiicode=\count164 +\tipasavetokens=\toks26 +\tipachecktokens=\toks27 +) +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \__fontspec_post_arg:w with sig. 'mmO{}' on line 353. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \fontspec with sig. 'om' on line 355. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmainfont with sig. 'om' on line 365. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setsansfont with sig. 'om' on line 375. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmonofont with sig. 'om' on line 385. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathrm with sig. 'om' on line 399. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setboldmathrm with sig. 'om' on line 407. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathsf with sig. 'om' on line 415. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathtt with sig. 'om' on line 423. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfamily with sig. 'mom' on line 437. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontface with sig. 'mom' on line 453. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \defaultfontfeatures with sig. 't+om' on line 467. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \addfontfeatures with sig. 'm' on line 529. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfeature with sig. 'mm' on line 540. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newAATfeature with sig. 'mmmm' on line 548. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newopentypefeature with sig. 'mmm' on line 556. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeature with sig. 'mm' on line 577. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeatureoption with sig. 'mmm' on line 586. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontscript with sig. 'mm' on line 590. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontlanguage with sig. 'mm' on line 594. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \DeclareFontsExtensions with sig. 'm' on line 599. +................................................. +\l__fontspec_tmp_int=\count165 +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.cfg) +LaTeX Info: Redefining \itshape on input line 2705. +LaTeX Info: Redefining \slshape on input line 2710. +LaTeX Info: Redefining \scshape on input line 2715. +LaTeX Info: Redefining \upshape on input line 2720. +\l__fontspec_em_int=\count166 +\l__fontspec_emdef_int=\count167 +LaTeX Info: Redefining \em on input line 2736. +LaTeX Info: Redefining \emph on input line 2742. +LaTeX Info: Redefining \- on input line 2746. +................................................. +. LaTeX info: "xparse/redefine-command" +. +. Redefining command \oldstylenums with sig. 'm' on line 2841. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \liningnums with sig. 'm' on line 2845. +................................................. +)) +Package hyperref Info: Option `colorlinks' set `true' on input line 87. +\px=\skip152 +\c@md@targetcount=\count168 +\mdcompactskip=\skip153 +\mdcompacttopsep=\skip154 +\dim@rem=\skip155 +\dim@ch=\skip156 +\md@height=\skip157 +\dim@marginbottom=\skip158 +\dim@paddingbottom=\skip159 +\md@interaction=\count169 +\mddefinitionsskip=\skip160 +\md@captionlen=\skip161 +\mdtoclevel=\count170 +\c@mdtoclevelbold=\count171 +\c@mdtocleveldots=\count172 +\mdtocskip=\skip162 +\mdpreskip=\skip163 +\presp=\skip164 +LaTeX Font Info: Try loading font information for EU1+lmtt on input line 801. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmtt.fd +File: eu1lmtt.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +\md@postskip=\skip165 +\ppresp=\skip166 +\md@thmcaption=\box54 +\md@defaultcolwidth=\skip167 +\mdtabularskip=\skip168 +\mdbibindentunit=\skip169 +\c@md@authorcount=\count173 +\c@mdx@authorcount=\count174 +\c@@mdTargetCount=\count175 +\@snippetBox=\box55 +\@snippetWidth=\skip170 +\@snippetHeight=\skip171 +\@snippetDepth=\skip172 +\c@snippets=\count176 +) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty +Package: geometry 2010/09/12 v5.6 Page Geometry +\Gm@cnth=\count177 +\Gm@cntv=\count178 +\c@Gm@tempcnt=\count179 +\Gm@bindingoffset=\dimen175 +\Gm@wd@mp=\dimen176 +\Gm@odd@mp=\dimen177 +\Gm@even@mp=\dimen178 +\Gm@layoutwidth=\dimen179 +\Gm@layoutheight=\dimen180 +\Gm@layouthoffset=\dimen181 +\Gm@layoutvoffset=\dimen182 +\Gm@dimlist=\toks28 +) (/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +\fancy@headwidth=\skip173 +\f@ncyO@elh=\skip174 +\f@ncyO@erh=\skip175 +\f@ncyO@olh=\skip176 +\f@ncyO@orh=\skip177 +\f@ncyO@elf=\skip178 +\f@ncyO@erf=\skip179 +\f@ncyO@olf=\skip180 +\f@ncyO@orf=\skip181 +) (build/P4Runtime-Spec.aux + +LaTeX Warning: Label `sec-example' multiply defined. + +) +\openout1 = `P4Runtime-Spec.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for TS1+cmr on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1cmr.fd +File: ts1cmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions +) +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for EU1/lmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T3/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for T3+cmr on input line 14. +(/usr/share/texmf/tex/latex/tipa/t3cmr.fd +File: t3cmr.fd 2001/12/31 TIPA font definitions +) +LaTeX Font Info: ... okay on input line 14. +\AtBeginShipoutBox=\box56 +Package hyperref Info: Link coloring ON on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2012/10/27 v2.43 Cross-referencing by name of section +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO) +) +\c@section@level=\count180 +) +LaTeX Info: Redefining \ref on input line 14. +LaTeX Info: Redefining \pageref on input line 14. +LaTeX Info: Redefining \nameref on input line 14. +................................................. +. fontspec info: "setup-math" +. +. Adjusting the maths setup (use [no-math] to avoid this). +................................................. +\symlegacymaths=\mathgroup7 +LaTeX Font Info: Overwriting symbol font `legacymaths' in version `bold' +(Font) OT1/cmr/m/n --> OT1/cmr/bx/n on input line 14. +LaTeX Font Info: Redeclaring math accent \acute on input line 14. +LaTeX Font Info: Redeclaring math accent \grave on input line 14. +LaTeX Font Info: Redeclaring math accent \ddot on input line 14. +LaTeX Font Info: Redeclaring math accent \tilde on input line 14. +LaTeX Font Info: Redeclaring math accent \bar on input line 14. +LaTeX Font Info: Redeclaring math accent \breve on input line 14. +LaTeX Font Info: Redeclaring math accent \check on input line 14. +LaTeX Font Info: Redeclaring math accent \hat on input line 14. +LaTeX Font Info: Redeclaring math accent \dot on input line 14. +LaTeX Font Info: Redeclaring math accent \mathring on input line 14. +LaTeX Font Info: Redeclaring math symbol \Gamma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Delta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Theta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Lambda on input line 14. +LaTeX Font Info: Redeclaring math symbol \Xi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Pi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Sigma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Upsilon on input line 14. +LaTeX Font Info: Redeclaring math symbol \Phi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Psi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Omega on input line 14. +LaTeX Font Info: Redeclaring math symbol \mathdollar on input line 14. +LaTeX Font Info: Redeclaring symbol font `operators' on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `normal' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/cmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `bold' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/cmr/bx/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) EU1/lmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/cmr/m/it --> EU1/lmr/m/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/cmr/bx/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/cmss/m/n --> EU1/lmss/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/cmtt/m/n --> EU1/lmtt/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) EU1/lmr/m/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' +(Font) OT1/cmr/bx/it --> EU1/lmr/bx/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/cmss/bx/n --> EU1/lmss/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/cmtt/m/n --> EU1/lmtt/bx/n on input line 14. +*geometry* driver: auto-detecting +*geometry* detected driver: xetex +*geometry* verbose mode - [ preamble ] result: +* driver: xetex +* paper: +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: +* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt) +* v-part:(T,H,B)=(72.26999pt, 632.3625pt, 90.3375pt) +* \paperwidth=614.295pt +* \paperheight=794.96999pt +* \textwidth=469.75502pt +* \textheight=632.3625pt +* \oddsidemargin=0.0pt +* \evensidemargin=0.0pt +* \topmargin=-37.0pt +* \headheight=30.0pt +* \headsep=25.0pt +* \topskip=11.0pt +* \footskip=30.0pt +* \marginparwidth=59.0pt +* \marginparsep=10.0pt +* \columnsep=10.0pt +* \skip\footins=10.0pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +resolve font stack: UtopiaStd-Regular + +\g__fontspec_family_UtopiaStd-Regular_int=\count181 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'UtopiaStd-Regular(0)' created for font 'UtopiaStd-Regular' with +. options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;" +. - 'small caps' (m/sc) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;+smcp;" +................................................. + +resolved font stack 'UtopiaStd-Regular' to: UtopiaStd-Regular +LaTeX Font Info: Try loading font information for U+msa on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Try loading font information for U+msb on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Try loading font information for U+stmry on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/Ustmry.fd) + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/bx/n' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 35. + +resolve font stack: LuxiMono + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +\g__fontspec_family_LuxiMono_int=\count182 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'LuxiMono(0)' created for font 'LuxiMono' with options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: <->"LuxiMono/OT:" +. - 'small caps' (m/sc) with NFSS spec.: +................................................. + +resolved font stack 'LuxiMono' to: LuxiMono +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/se-ascii-print.def +File: se-ascii-print.def 2011/12/02 v1.10 stringenc: Printable ASCII characters +) [1 + +] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[2] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <10.95> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 309. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Font Warning: Font shape `EU1/LuxiMono(0)/bx/n' undefined +(Font) using `EU1/LuxiMono(0)/m/n' instead on input line 309. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[3] [4] + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/m/it' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 519. + +[5] [6] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[7] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/reference-architecture.png Graphic file (type QTm) + [8] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[9] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[10] +File: build/single-embedded-controller.png Graphic file (type QTm) + [11] +File: build/single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-controllers.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-ha-controllers.png Graphic file (type QTm) + [12] [13] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[14] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[15] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <12> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 1530. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1530. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1530. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[16] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[17] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (65.03293pt too wide) in paragraph at lines 1798--1801 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For all backup controllers, \EU1/LuxiMono(0)/bx/n/8.2125 status \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set to non-OK (with \EU1/LuxiMono(0)/bx/n/8.2125 status.code \EU1/UtopiaStd-Regular(0)/m/it/10.95 set to \EU1/LuxiMono(0)/bx/n/8.2125 google.rpc.ALREADY_EXISTS\EU1/UtopiaStd-Regular(0)/m/it/10.95 ). + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[18] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1835. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1835. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1859. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1859. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[19] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1904. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1904. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[20] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[21] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[22] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2187. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2187. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[23] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1057) in paragraph at lines 2237--2241 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For structured annotations, every \EU1/LuxiMono(0)/bx/n/8.2125 StructuredAnnotation \EU1/UtopiaStd-Regular(0)/m/it/10.95 message contains an optional field + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2244. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2244. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[24] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[25] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[26] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (12.45624pt too wide) in paragraph at lines 2475--2488 + [] + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2511. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2511. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[27] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[28] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2702. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2702. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2762. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2762. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[29] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2836. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2836. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[30] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2917. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2917. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.59204pt too wide) in paragraph at lines 2971--2973 +[]\EU1/LuxiMono(0)/bx/n/8.2125 BYTES\EU1/UtopiaStd-Regular(0)/m/it/10.95 , which signifies that this meter can be configured with rates expressed in bytes/second. + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2996. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2996. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[31] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (18.74199pt too wide) in paragraph at lines 3013--3020 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 carrying P4 standard annotations \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_in") \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_out")\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[32] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[33] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3155. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3155. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[34] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[35] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3383. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3383. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3430. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3430. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[36] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3468. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3468. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[37] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[38] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[39] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[40] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[41] [42] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1629) in paragraph at lines 4072--4074 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For example, the following P4$[]$ objects involve complex types that need to be exposed in + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[43] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1454) in paragraph at lines 4120--4129 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 ification for all the named types in the P4$[]$ program. These named types are \EU1/LuxiMono(0)/bx/n/8.2125 struct\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 header\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + + +Underfull \hbox (badness 1831) in paragraph at lines 4120--4129 +\EU1/LuxiMono(0)/bx/n/8.2125 header_union\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 enum \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 serializable_enum\EU1/UtopiaStd-Regular(0)/m/it/10.95 ; for each of these we have a type specification mes- + [] + + +Underfull \hbox (badness 1845) in paragraph at lines 4120--4129 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 sage, respectively \EU1/LuxiMono(0)/bx/n/8.2125 P4StructTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnionTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4EnumTypeSpec \EU1/UtopiaStd-Regular(0)/m/it/10.95 and + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (33.06564pt too wide) in paragraph at lines 4155--4162 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 “binary string” types (\EU1/LuxiMono(0)/bx/n/8.2125 bit\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 int\EU1/UtopiaStd-Regular(0)/m/it/10.95 , and \EU1/LuxiMono(0)/bx/n/8.2125 varbit\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) are grouped together in the \EU1/LuxiMono(0)/bx/n/8.2125 P4BitstringLikeTypeSpec + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[44] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4172. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4172. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.46094pt too wide) in paragraph at lines 4209--4212 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 An invalid header union (i.e. all headers in the union are invalid) is represented by a \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnion + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[45] [46] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4346. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4346. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[47] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (24.68944pt too wide) in paragraph at lines 4434--4440 +[]\EU1/LuxiMono(0)/bx/n/8.2125 translated_type\EU1/UtopiaStd-Regular(0)/m/it/10.95 , if and only if the P4 \EU1/LuxiMono(0)/bx/n/8.2125 type \EU1/UtopiaStd-Regular(0)/m/it/10.95 declaration was annotated with \EU1/LuxiMono(0)/bx/n/8.2125 @p4runtime_translation\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[48] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[49] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (32.59732pt too wide) in paragraph at lines 4542--4548 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 in \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.MatchField\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.Action.Param \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.ControllerPacketMetadata.Metadata\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[50] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4649. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4649. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[51] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[52] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[53] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[54] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.53593pt too wide) in paragraph at lines 5112--5115 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 If the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 does not match the table description in the P4Info (e.g. the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 is \EU1/LuxiMono(0)/bx/n/8.2125 action_profile_member_id + [] + +[55] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[56] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[57] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[58] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[59] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[60] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[61] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5749. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5749. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[62] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[63] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[64] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (9.29865pt too wide) in paragraph at lines 6033--6035 + []\EU1/lmr/bx/n/10.95 9.2.2.1.| Rules on Setting \EU1/LuxiMono(0)/bx/n/8.2125 max_size[] \EU1/UtopiaStd-Regular(0)/m/it/10.95 The valid values for \EU1/LuxiMono(0)/bx/n/8.2125 max_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 depend on the static \EU1/LuxiMono(0)/bx/n/8.2125 max_group_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[65] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[66] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[67] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[68] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6321. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6321. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6361. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6361. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1331) in paragraph at lines 6364--6371 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 A direct counter is a direct resource associated with a \EU1/LuxiMono(0)/bx/n/8.2125 TableEntry \EU1/UtopiaStd-Regular(0)/m/it/10.95 (see [][]Direct Resources[][]). The + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[69] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6438. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6438. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[70] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6531. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6531. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6572. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6572. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[71] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6662. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6662. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[72] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6766. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6766. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6794. + +[73] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6804. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6804. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[74] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6928. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6928. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[75] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.93839pt too wide) in paragraph at lines 7039--7041 +[]\EU1/LuxiMono(0)/bx/n/8.2125 MODIFY\EU1/UtopiaStd-Regular(0)/m/it/10.95 : Modify the attributes of a given clone session entry, indexed by the given \EU1/LuxiMono(0)/bx/n/8.2125 clone_session_id\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[76] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7077. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7077. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[77] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[78] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7213. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7213. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7257. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7257. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[79] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[80] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7455. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7455. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[81] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/error-report.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[82] +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <14.4> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 7579. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7579. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7579. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: Hyper reference `wildcard-reads' on page 83 undefined on input line 7601. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[83] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7681. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7681. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[84] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[85] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[86] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (34.34796pt too wide) in paragraph at lines 7965--7970 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If an error is encountered before even trying to attempt individual batch updates, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +[87] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.66206pt too wide) in paragraph at lines 7974--7985 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 Otherwise, if one or more updates in the batch (\EU1/LuxiMono(0)/bx/n/8.2125 WriteRequest.updates\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) failed, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8021. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8021. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[88] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[89] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.4752pt too wide) in paragraph at lines 8256--8260 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 responding to \EU1/LuxiMono(0)/bx/n/8.2125 a \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 c\EU1/UtopiaStd-Regular(0)/m/it/10.95 , followed by a status \EU1/LuxiMono(0)/bx/n/8.2125 {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[90] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8342. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8342. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[91] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[92] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8465. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8465. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[93] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 8563--8566 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If a P4Runtime server supports both \EU1/LuxiMono(0)/bx/n/8.2125 SetForwardingPipelineConfig \EU1/UtopiaStd-Regular(0)/m/it/10.95 as well as returning the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[94] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[95] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[96] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[97] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[98] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8932. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8932. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[99] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 9000. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 9000. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/psa-metadata-translation.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[100] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[101] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[102] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[103] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[104] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[105] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 9510--9517 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 p4info-ext should include a Protobuf message definition for every extern type that can + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[106] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 4036) in paragraph at lines 9565--9572 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 P4Runtime also supports streaming arbitrary Protobuf messages between the server and the + [] + + +Underfull \hbox (badness 1629) in paragraph at lines 9565--9572 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 client, by including an \EU1/LuxiMono(0)/bx/n/8.2125 Any \EU1/UtopiaStd-Regular(0)/m/it/10.95 Protobuf field [[][]31[][]] named \EU1/LuxiMono(0)/bx/n/8.2125 other \EU1/UtopiaStd-Regular(0)/m/it/10.95 in both \EU1/LuxiMono(0)/bx/n/8.2125 p4.v1.StreamMessageRequest + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[107] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[108] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1997) in paragraph at lines 9826--9828 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 Table [][]7[][] lists P4$[]$ annotations introduced primarily for the purpose of adding features for the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[109] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[110] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.61781pt too wide) in paragraph at lines 9973--9980 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 In gRPC, the status of a RPC request is sent as metadata, whose size is limited by the \EU1/LuxiMono(0)/bx/n/8.2125 grpc.max_metadata_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[111] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 10000) in paragraph at lines 10064--10065 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Complex Types in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- p4- + [] + +[112] +Underfull \hbox (badness 4001) in paragraph at lines 10076--10077 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Google Cloud APIs Versioning - Backwards-Compatibility.” [][]\EU1/lmtt/m/n/10.95 https:// cloud. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10085--10086 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “gRPC Streaming RPCs in C++.” [][]\EU1/lmtt/m/n/10.95 https:// grpc. io/ docs/ tutorials/ basic/ c. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10097--10098 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “P4 Concurrency Model.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10100--10101 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10115--10116 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Protobuf OneOf Backwards-Compatibility Issues.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10121--10122 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Action Selector.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# sec- action- + [] + + +Underfull \hbox (badness 2409) in paragraph at lines 10130--10131 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Empty Group Action Appendix.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# + [] + +[113] +Underfull \hbox (badness 10000) in paragraph at lines 10133--10134 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Select Expressions in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 1668) in paragraph at lines 10148--10149 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Any Protobuf Message.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ protocol- buffers/ docs/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10154--10155 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC C++ Error Details Library.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ grpc/ grpc/ blob/ master/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10157--10158 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC Canonical Status Codes.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ maps- booking/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10163--10164 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Protobuf MessageDifferencer in the C++ API.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10169--10170 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “v1model Architecture Definition.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ p4lang/ p4c/ blob/ master/ + [] + +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 10178. +[114] +Package atveryend Info: Empty hook `AfterLastShipout' on input line 10178. +(build/P4Runtime-Spec.aux) +Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 10178. +Package atveryend Info: Empty hook `AtEndAfterFileList' on input line 10178. + +LaTeX Font Warning: Some font shapes were not available, defaults substituted. + + +LaTeX Warning: There were undefined references. + + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 27553 strings out of 493638 + 517940 string characters out of 6146796 + 565041 words of memory out of 5000000 + 30655 multiletter control sequences out of 15000+600000 + 14633 words of font info for 98 fonts, out of 8000000 for 9000 + 1328 hyphenation exceptions out of 8191 + 48i,19n,81p,10429b,790s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on build/P4Runtime-Spec.pdf (114 pages). diff --git a/spec/v1.4.0-rc.4/P4Runtime-Spec.pdf b/spec/v1.4.0-rc.4/P4Runtime-Spec.pdf new file mode 100644 index 00000000..25e15240 Binary files /dev/null and b/spec/v1.4.0-rc.4/P4Runtime-Spec.pdf differ diff --git a/spec/v1.4.0-rc.4/P4Runtime-Spec.tex b/spec/v1.4.0-rc.4/P4Runtime-Spec.tex new file mode 100644 index 00000000..251c97d2 --- /dev/null +++ b/spec/v1.4.0-rc.4/P4Runtime-Spec.tex @@ -0,0 +1,10178 @@ +\documentclass[11pt]{article} +% generated by Madoko, version 1.1.4 +%mdk-data-line={1} + + +\usepackage[heading-base={2},section-num={False},bib-label={hide},fontspec={True}]{madoko2} +\usepackage[top=1in, bottom=1.25in, left=1in, right=1in]{geometry} +\usepackage{fancyhdr} +%mdk-data-line={11} + + \setlength{\headheight}{30pt} + \setlength{\emergencystretch}{2em} + +\begin{document} + + + +{\mdfontfamily{UtopiaStd-Regular} +%mdk-data-line={203} +\mdxtitleblockstart{} +%mdk-data-line={203} +\mdxtitle{{\sffamily{\bfseries\mdline{203}P4Runtime Specification}}}%mdk + +%mdk-data-line={206} +\mdxtitlenote{{\sffamily{\bfseries\mdline{206}version 1.3.0}}}%mdk +\mdxauthorstart{} +%mdk-data-line={211} +\mdxauthorname{\mdline{211}The P4.org API Working Group}%mdk +\mdxauthorend +%mdk-data-line={220} +\mdxtitlefooter{{\sffamily{\bfseries\mdline{220}2022-03-23}}}%mdk +\mdtitleauthorrunning{}{}\mdxtitleblockend%mdk + +%mdk-data-line={205} +\begin{abstract}%mdk + +%mdk-data-line={206} +\noindent\mdline{206}P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.%mdk +%mdk +\end{abstract}%mdk +\mdline{214} +\begin{mdtoc}%mdk + +\section*{Contents}\label{sec-contents}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-introduction-and-scope}{\mdref{sec-introduction-and-scope}{1.\hspace*{0.5em}Introduction and Scope}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-language-version-applicability}{\mdref{sec-p4-language-version-applicability}{1.1.\hspace*{0.5em}P4 Language Version Applicability}}%mdk + +\mdtocitemx{sec-in-scope}{\mdref{sec-in-scope}{1.2.\hspace*{0.5em}In Scope}}%mdk + +\mdtocitemx{sec-not-in-scope}{\mdref{sec-not-in-scope}{1.3.\hspace*{0.5em}Not In Scope}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-terms-and-definitions}{\mdref{sec-terms-and-definitions}{2.\hspace*{0.5em}Terms and Definitions}}%mdk + +\mdtocitemx{sec-reference-architecture}{\mdref{sec-reference-architecture}{3.\hspace*{0.5em}Reference Architecture}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-service-implementation}{\mdref{sec-p4runtime-service-implementation}{3.1.\hspace*{0.5em}P4Runtime Service Implementation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-security-concerns}{\mdref{sec-security-concerns}{3.1.1.\hspace*{0.5em}Security concerns}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-idealized-workflow}{\mdref{sec-idealized-workflow}{3.2.\hspace*{0.5em}Idealized Workflow}}%mdk + +\mdtocitemx{sec-p4-as-behavioral-description-language}{\mdref{sec-p4-as-behavioral-description-language}{3.3.\hspace*{0.5em}P4 as a Behavioral Description Language}}%mdk + +\mdtocitemx{sec-alternative-workflows}{\mdref{sec-alternative-workflows}{3.4.\hspace*{0.5em}Alternative Workflows}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{\mdref{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{3.4.1.\hspace*{0.5em}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}}%mdk + +\mdtocitemx{sec-no-p4-source-available-p4info-available}{\mdref{sec-no-p4-source-available-p4info-available}{3.4.2.\hspace*{0.5em}No P4 Source Available, P4Info Available}}%mdk + +\mdtocitemx{sec-partial-p4info-and-p4-source-are-available}{\mdref{sec-partial-p4info-and-p4-source-are-available}{3.4.3.\hspace*{0.5em}Partial P4Info and P4 Source are Available}}%mdk + +\mdtocitemx{sec-p4info-role-based-subsets}{\mdref{sec-p4info-role-based-subsets}{3.4.4.\hspace*{0.5em}P4Info Role-Based Subsets}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-restarts}{\mdref{sec-restarts}{3.5.\hspace*{0.5em}P4Runtime State Across Restarts}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-controller-use-cases}{\mdref{sec-controller-use-cases}{4.\hspace*{0.5em}Controller Use-cases}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-single-embedded-controller}{\mdref{sec-single-embedded-controller}{4.1.\hspace*{0.5em}Single Embedded Controller}}%mdk + +\mdtocitemx{sec-single-remote-controller}{\mdref{sec-single-remote-controller}{4.2.\hspace*{0.5em}Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-single-remote-controller}{\mdref{sec-embedded-single-remote-controller}{4.3.\hspace*{0.5em}Embedded + Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-two-remote-controllers}{\mdref{sec-embedded-two-remote-controllers}{4.4.\hspace*{0.5em}Embedded + Two Remote Controllers}}%mdk + +\mdtocitemx{sec-embedded-controller-two-high-availability-remote-controllers}{\mdref{sec-embedded-controller-two-high-availability-remote-controllers}{4.5.\hspace*{0.5em}Embedded Controller + Two High-Availability Remote Controllers}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-client-arbitration-and-controller-replication}{\mdref{sec-client-arbitration-and-controller-replication}{5.\hspace*{0.5em}Client Arbitration and Controller Replication}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-default-role}{\mdref{sec-default-role}{5.1.\hspace*{0.5em}Default Role}}%mdk + +\mdtocitemx{sec-arbitration-role-config}{\mdref{sec-arbitration-role-config}{5.2.\hspace*{0.5em}Role Config}}%mdk + +\mdtocitemx{sec-arbitration-updates}{\mdref{sec-arbitration-updates}{5.3.\hspace*{0.5em}Rules for Handling \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}} Messages Received from Controllers}}%mdk + +\mdtocitemx{sec-arbitration-notification}{\mdref{sec-arbitration-notification}{5.4.\hspace*{0.5em}Client Arbitration Notifications}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-the-p4info-message}{\mdref{sec-the-p4info-message}{6.\hspace*{0.5em}The P4Info Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-common-messages}{\mdref{sec-common-messages}{6.1.\hspace*{0.5em}Common Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-documentation-message}{\mdref{sec-documentation-message}{6.1.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}} Message}}%mdk + +\mdtocitemx{sec-preamble-message}{\mdref{sec-preamble-message}{6.1.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}} Message}}%mdk + +\mdtocitemx{sec-annotating-p4-entities-with-documentation}{\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3.\hspace*{0.5em}Annotating P4 Entities with \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}}%mdk + +\mdtocitemx{sec-structured-annotations}{\mdref{sec-structured-annotations}{6.1.4.\hspace*{0.5em}Structured Annotations}}%mdk + +\mdtocitemx{sec-sourcelocation-message}{\mdref{sec-sourcelocation-message}{6.1.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}} Message}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-pkginfo-message}{\mdref{sec-pkginfo-message}{6.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}} Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-annotating-p4-code-with-pkginfo}{\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1.\hspace*{0.5em}Annotating P4 code with PkgInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-id-allocation}{\mdref{sec-id-allocation}{6.3.\hspace*{0.5em}ID Allocation for P4Info Objects}}%mdk + +\mdtocitemx{sec-p4info-objects}{\mdref{sec-p4info-objects}{6.4.\hspace*{0.5em}P4Info Objects}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table}{\mdref{sec-table}{6.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}}%mdk + +\mdtocitemx{sec-action}{\mdref{sec-action}{6.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}}%mdk + +\mdtocitemx{sec-p4info-action-profile}{\mdref{sec-p4info-action-profile}{6.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}}%mdk + +\mdtocitemx{sec-counter-directcounter}{\mdref{sec-counter-directcounter}{6.4.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}}%mdk + +\mdtocitemx{sec-meter-directmeter}{\mdref{sec-meter-directmeter}{6.4.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}}%mdk + +\mdtocitemx{sec-controller-packet-meta}{\mdref{sec-controller-packet-meta}{6.4.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}}%mdk + +\mdtocitemx{sec-valueset}{\mdref{sec-valueset}{6.4.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}}%mdk + +\mdtocitemx{sec-register}{\mdref{sec-register}{6.4.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}}%mdk + +\mdtocitemx{sec-digest}{\mdref{sec-digest}{6.4.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}}%mdk + +\mdtocitemx{sec-p4info-extern}{\mdref{sec-p4info-extern}{6.4.10.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{\mdref{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{6.5.\hspace*{0.5em}Support for Arbitrary P4 Types with P4TypeInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-fwd-pipe-config}{\mdref{sec-p4-fwd-pipe-config}{7.\hspace*{0.5em}P4 Forwarding-Pipeline Configuration}}%mdk + +\mdtocitemx{sec-general-principles-for-message-formatting}{\mdref{sec-general-principles-for-message-formatting}{8.\hspace*{0.5em}General Principles for Message Formatting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-set-unset-protobuf-field}{\mdref{sec-set-unset-protobuf-field}{8.1.\hspace*{0.5em}Set / Unset Protobuf Field}}%mdk + +\mdtocitemx{sec-read-write-symmetry}{\mdref{sec-read-write-symmetry}{8.2.\hspace*{0.5em}Read-Write Symmetry}}%mdk + +\mdtocitemx{sec-zero-as-reserved-value}{\mdref{sec-zero-as-reserved-value}{8.3.\hspace*{0.5em}Zero as Reserved Value}}%mdk + +\mdtocitemx{sec-bytestrings}{\mdref{sec-bytestrings}{8.4.\hspace*{0.5em}Bytestrings}}%mdk + +\mdtocitemx{sec-representation-of-arbitrary-p4-types}{\mdref{sec-representation-of-arbitrary-p4-types}{8.5.\hspace*{0.5em}Representation of Arbitrary P4 Types}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-problem-statement}{\mdref{sec-problem-statement}{8.5.1.\hspace*{0.5em}Problem Statement}}%mdk + +\mdtocitemx{sec-p4-type-specifications-in-p4infoproto}{\mdref{sec-p4-type-specifications-in-p4infoproto}{8.5.2.\hspace*{0.5em}P4 Type Specifications in p4info.proto}}%mdk + +\mdtocitemx{sec-p4data-in-p4runtime-proto}{\mdref{sec-p4data-in-p4runtime-proto}{8.5.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}} in p4runtime.proto}}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{8.5.4.\hspace*{0.5em}Example}}%mdk + +\mdtocitemx{sec-enum-serializable-enum-and-error}{\mdref{sec-enum-serializable-enum-and-error}{8.5.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}, serializable \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}}%mdk + +\mdtocitemx{sec-user-defined-types}{\mdref{sec-user-defined-types}{8.5.6.\hspace*{0.5em}User-defined types}}%mdk + +\mdtocitemx{sec-trade-off-for-v1x-releases}{\mdref{sec-trade-off-for-v1x-releases}{8.5.7.\hspace*{0.5em}Trade-off for v1.x Releases}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-entity-msgs}{\mdref{sec-p4-entity-msgs}{9.\hspace*{0.5em}P4 Entity Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table-entry}{\mdref{sec-table-entry}{9.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-match-format}{\mdref{sec-match-format}{9.1.1.\hspace*{0.5em}Match Format}}%mdk + +\mdtocitemx{sec-action-specification}{\mdref{sec-action-specification}{9.1.2.\hspace*{0.5em}Action Specification}}%mdk + +\mdtocitemx{sec-default-entry}{\mdref{sec-default-entry}{9.1.3.\hspace*{0.5em}Default Entry}}%mdk + +\mdtocitemx{sec-constant-tables}{\mdref{sec-constant-tables}{9.1.4.\hspace*{0.5em}Constant Tables}}%mdk + +\mdtocitemx{sec-table-wildcard-reads}{\mdref{sec-table-wildcard-reads}{9.1.5.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-direct-resources}{\mdref{sec-direct-resources}{9.1.6.\hspace*{0.5em}Direct Resources}}%mdk + +\mdtocitemx{sec-idle-timeout}{\mdref{sec-idle-timeout}{9.1.7.\hspace*{0.5em}Idle-timeout}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-and-group}{\mdref{sec-action-profile-member-and-group}{9.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-programming}{\mdref{sec-action-profile-member-programming}{9.2.1.\hspace*{0.5em}Action Profile Member Programming}}%mdk + +\mdtocitemx{sec-action-profile-group-programming}{\mdref{sec-action-profile-group-programming}{9.2.2.\hspace*{0.5em}Action Profile Group Programming}}%mdk + +\mdtocitemx{sec-oneshot}{\mdref{sec-oneshot}{9.2.3.\hspace*{0.5em}One Shot Action Selector Programming}}%mdk + +\mdtocitemx{action-selector-constraints}{\mdref{action-selector-constraints}{9.2.4.\hspace*{0.5em}Constraints on action selector programming}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-counterentry-directcounterentry}{\mdref{sec-counterentry-directcounterentry}{9.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directcounterentry}{\mdref{sec-directcounterentry}{9.3.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\mdtocitemx{sec-counterentry}{\mdref{sec-counterentry}{9.3.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-meterentry-directmeterentry}{\mdref{sec-meterentry-directmeterentry}{9.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directmeterentry}{\mdref{sec-directmeterentry}{9.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\mdtocitemx{sec-meterentry}{\mdref{sec-meterentry}{9.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}}%mdk + +\mdtocitemx{sec-metercounterdata}{\mdref{sec-metercounterdata}{9.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-packetreplicationengineentry}{\mdref{sec-packetreplicationengineentry}{9.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-multicastgroupentry}{\mdref{sec-multicastgroupentry}{9.5.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}}%mdk + +\mdtocitemx{sec-clonesessionentry}{\mdref{sec-clonesessionentry}{9.5.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-valuesetentry}{\mdref{sec-valuesetentry}{9.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}}%mdk + +\mdtocitemx{sec-registerentry}{\mdref{sec-registerentry}{9.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}}%mdk + +\mdtocitemx{sec-digestentry}{\mdref{sec-digestentry}{9.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}}%mdk + +\mdtocitemx{sec-extern-entry}{\mdref{sec-extern-entry}{9.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-error-reporting-messages}{\mdref{sec-error-reporting-messages}{10.\hspace*{0.5em}Error Reporting Messages}}%mdk + +\mdtocitemx{sec-atomicity-of-individual-write-and-read-operations}{\mdref{sec-atomicity-of-individual-write-and-read-operations}{11.\hspace*{0.5em}Atomicity of Individual \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} Operations}}%mdk + +\mdtocitemx{sec-write-rpc}{\mdref{sec-write-rpc}{12.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-batching-and-ordering-of-updates}{\mdref{sec-batching-and-ordering-of-updates}{12.1.\hspace*{0.5em}Batching and Ordering of Updates}}%mdk + +\mdtocitemx{sec-batch-atomicity}{\mdref{sec-batch-atomicity}{12.2.\hspace*{0.5em}Batch Atomicity}}%mdk + +\mdtocitemx{sec-error-reporting}{\mdref{sec-error-reporting}{12.3.\hspace*{0.5em}Error Reporting}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-read-rpc}{\mdref{sec-read-rpc}{13.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-nomenclature}{\mdref{sec-nomenclature}{13.1.\hspace*{0.5em}Nomenclature}}%mdk + +\mdtocitemx{sec-wildcard-reads}{\mdref{sec-wildcard-reads}{13.2.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-batch-processing}{\mdref{sec-batch-processing}{13.3.\hspace*{0.5em}Batch Processing}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{13.3.1.\hspace*{0.5em}Example}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-parallelism-of-read-and-write-requests}{\mdref{sec-parallelism-of-read-and-write-requests}{13.4.\hspace*{0.5em}Parallelism of Read and Write Requests}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-setforwardingpipelineconfig-rpc}{\mdref{sec-setforwardingpipelineconfig-rpc}{14.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-getforwardingpipelineconfig-rpc}{\mdref{sec-getforwardingpipelineconfig-rpc}{15.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-p4runtime-stream-messages}{\mdref{sec-p4runtime-stream-messages}{16.\hspace*{0.5em}P4Runtime Stream Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-packet-i_o}{\mdref{sec-packet-i_o}{16.1.\hspace*{0.5em}Packet I/O}}%mdk + +\mdtocitemx{sec-client-arbitration-update}{\mdref{sec-client-arbitration-update}{16.2.\hspace*{0.5em}Client Arbitration Update}}%mdk + +\mdtocitemx{sec-digest-messages}{\mdref{sec-digest-messages}{16.3.\hspace*{0.5em}Digest Messages}}%mdk + +\mdtocitemx{sec-table-idle-timeout-notification}{\mdref{sec-table-idle-timeout-notification}{16.4.\hspace*{0.5em}Table Idle Timeout Notification}}%mdk + +\mdtocitemx{sec-architecture-specific-notifications}{\mdref{sec-architecture-specific-notifications}{16.5.\hspace*{0.5em}Architecture-Specific Notifications}}%mdk + +\mdtocitemx{sec-stream-error-reporting}{\mdref{sec-stream-error-reporting}{16.6.\hspace*{0.5em}Stream Error Reporting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-examples-of-streamerror-messages}{\mdref{sec-examples-of-streamerror-messages}{16.6.1.\hspace*{0.5em}Examples of \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}} Messages}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-capabilities-rpc}{\mdref{sec-capabilities-rpc}{17.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}} RPC}}%mdk + +\mdtocitemx{sec-portability-considerations}{\mdref{sec-portability-considerations}{18.\hspace*{0.5em}Portability Considerations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-psa-metadata-translation}{\mdref{sec-psa-metadata-translation}{18.1.\hspace*{0.5em}PSA Metadata Translation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-translation-of-port-numbers}{\mdref{sec-translation-of-port-numbers}{18.1.1.\hspace*{0.5em}Translation of Port Numbers}}%mdk + +\mdtocitemx{sec-translation-of-packet-io-header-fields}{\mdref{sec-translation-of-packet-io-header-fields}{18.1.2.\hspace*{0.5em}Translation of Packet-IO Header Fields}}%mdk + +\mdtocitemx{sec-translation-of-match-fields}{\mdref{sec-translation-of-match-fields}{18.1.3.\hspace*{0.5em}Translation of Match Fields}}%mdk + +\mdtocitemx{sec-translation-of-action-parameters}{\mdref{sec-translation-of-action-parameters}{18.1.4.\hspace*{0.5em}Translation of Action Parameters}}%mdk + +\mdtocitemx{sec-port-translation-for-psa-extern-apis}{\mdref{sec-port-translation-for-psa-extern-apis}{18.1.5.\hspace*{0.5em}Port Translation for PSA Extern APIs}}%mdk + +\mdtocitemx{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{\mdref{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{18.1.6.\hspace*{0.5em}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-versioning}{\mdref{sec-p4runtime-versioning}{19.\hspace*{0.5em}P4Runtime Versioning}}%mdk + +\mdtocitemx{sec-extending-p4runtime}{\mdref{sec-extending-p4runtime}{20.\hspace*{0.5em}Extending P4Runtime for non-PSA Architectures}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-p4runtime-for-architecture-specific-externs}{\mdref{sec-extending-p4runtime-for-architecture-specific-externs}{20.1.\hspace*{0.5em}Extending P4Runtime for Architecture-Specific Externs}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-the-p4info-message}{\mdref{sec-extending-the-p4info-message}{20.1.1.\hspace*{0.5em}Extending the P4Info message}}%mdk + +\mdtocitemx{sec-extending-the-p4runtime-service}{\mdref{sec-extending-the-p4runtime-service}{20.1.2.\hspace*{0.5em}Extending the P4Runtime Service}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-architecture-specific-table-extensions}{\mdref{sec-architecture-specific-table-extensions}{20.2.\hspace*{0.5em}Architecture-Specific Table Extensions}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-new-match-types}{\mdref{sec-new-match-types}{20.2.1.\hspace*{0.5em}New Match Types}}%mdk + +\mdtocitemx{sec-new-table-properties}{\mdref{sec-new-table-properties}{20.2.2.\hspace*{0.5em}New Table Properties}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-known-limitations-of-current-p4runtime-version}{\mdref{sec-known-limitations-of-current-p4runtime-version}{21.\hspace*{0.5em}Known Limitations of Current P4Runtime Version}}%mdk + +\mdtocitemx{sec-appendix}{\mdref{sec-appendix}{A.\hspace*{0.5em}Appendix}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-revision-history}{\mdref{sec-revision-history}{A.1.\hspace*{0.5em}Revision History}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-changes-in-v130}{\mdref{sec-changes-in-v130}{A.1.1.\hspace*{0.5em}Changes in v1.3.0}}%mdk + +\mdtocitemx{sec-changes-in-v120}{\mdref{sec-changes-in-v120}{A.1.2.\hspace*{0.5em}Changes in v1.2.0}}%mdk + +\mdtocitemx{sec-changes-in-v110}{\mdref{sec-changes-in-v110}{A.1.3.\hspace*{0.5em}Changes in v1.1.0}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-annotations}{\mdref{sec-p4-annotations}{A.2.\hspace*{0.5em}P4 Annotations}}%mdk + +\mdtocitemx{sec-value-set-example}{\mdref{sec-value-set-example}{A.3.\hspace*{0.5em}A More Complex Value Set Example}}%mdk + +\mdtocitemx{sec-guidelines-for-implementations}{\mdref{sec-guidelines-for-implementations}{A.4.\hspace*{0.5em}Guidelines for Implementations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-grpc-metadata-maximum-size}{\mdref{sec-grpc-metadata-maximum-size}{A.4.1.\hspace*{0.5em}gRPC Metadata Maximum Size}}%mdk + +\mdtocitemx{sec-grpc-server-maximum-receive-message-size}{\mdref{sec-grpc-server-maximum-receive-message-size}{A.4.2.\hspace*{0.5em}gRPC Server Maximum Receive Message Size}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-bibliography}{\mdref{sec-bibliography}{References}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{215} +\begin{mdtoc}%mdk + +\section*{Figures}\label{sec-figures}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{fig-reference-architecture}{\mdref{fig-reference-architecture}{\mdcaptionlabel{1}. P4Runtime Reference Architecture.}}%mdk + +\mdtocitemx{fig-single-embedded-controller}{\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}. Use-Case: Single Embedded Controller}}%mdk + +\mdtocitemx{fig-single-remote-controller}{\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}. Use-Case: Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-single-remote-controller}{\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}. Use-Case: Embedded Plus Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-controllers}{\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}. Use-Case: Embedded Plus Two Remote Controllers}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-ha-controllers}{\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}. Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk + +\mdtocitemx{fig-error-report}{\mdref{fig-error-report}{\mdcaptionlabel{7}. P4Runtime Error Report Message Format}}%mdk + +\mdtocitemx{fig-psa-metadata-translation}{\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}. P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{216} +\begin{mdtoc}%mdk + +\section*{Tables}\label{sec-tables}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{tab-mapping-p4-obj-ids}{\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}. Mapping of P4Info object type to 8-bit ID prefix value}}%mdk + +\mdtocitemx{tab-format-p4-obj-ids}{\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}. Format of P4Info object IDs}}%mdk + +\mdtocitemx{tab-exmpl-p4-obj-ids}{\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}. Example of statically-assigned P4Info object IDs}}%mdk + +\mdtocitemx{tab-valid-bytestring-encoding}{\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}. Examples of Valid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-invalid-bytestring-encoding}{\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}. Examples of Invalid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-p4-type-usage}{\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}. P4 Type Usage}}%mdk + +\mdtocitemx{tab-p4-annotations}{\mdref{tab-p4-annotations}{\mdcaptionlabel{7}. P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk + +%mdk-data-line={218} +\section{\mdline{218}1.\hspace*{0.5em}\mdline{218}Introduction and Scope}\label{sec-introduction-and-scope}%mdk%mdk + +%mdk-data-line={220} +\noindent\mdline{220}This document is published by the \mdline{220}\emph{P4.org API Working Group}\mdline{220}, which was +chartered\mdline{221}~[\mdcite{p4apiwgcharter}{17}]\mdline{221} to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called \mdline{223}\emph{P4Runtime}\mdline{223}. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +\mdline{226}\href{https://github.com/p4lang/p4runtime/tree/v1.3.0/proto}{https://github.com/p4lang/p4runtime/tree/v1.3.0/proto}\mdline{226}.%mdk + +%mdk-data-line={228} +\subsection{\mdline{228}1.1.\hspace*{0.5em}\mdline{228}P4 Language Version Applicability}\label{sec-p4-language-version-applicability}%mdk%mdk + +%mdk-data-line={230} +\noindent\mdline{230}P4Runtime is designed to be implemented in conjunction with the P4\mdline{230}\mdsub{16}\mdline{230} language +version or later. P4\mdline{231}\mdsub{14}\mdline{231} programs should be translated into P4\mdline{231}\mdsub{16}\mdline{231} to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P4\mdline{233}\mdsub{16}\mdline{233} 1.0, but were introduced in P4\mdline{233}\mdsub{16}\mdline{233} 1.1.0\mdline{233}~[\mdcite{p4revisions110}{29}]\mdline{233}. For +this version of P4Runtime, we recommend using P4\mdline{234}\mdsub{16}\mdline{234} 1.2.1\mdline{234}~[\mdcite{p4spec}{1}]\mdline{234}.%mdk + +%mdk-data-line={236} +\subsection{\mdline{236}1.2.\hspace*{0.5em}\mdline{236}In Scope}\label{sec-in-scope}%mdk%mdk + +%mdk-data-line={238} +\noindent\mdline{238}This specification document defines the \mdline{238}\emph{semantics}\mdline{238} of \mdline{238}\emph{P4Runtime}\mdline{238} messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime:%mdk + +%mdk-data-line={242} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={242} +\item\mdline{242}Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA)\mdline{243}~[\mdcite{psa}{19}]\mdline{243} externs (\mdline{243}e.g.\mdline{243} Counters, Meters, Action +Profiles, \mdline{244}\dots{}\mdline{244}). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0.%mdk + +%mdk-data-line={246} +\item\mdline{246}Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism.%mdk + +%mdk-data-line={248} +\item\mdline{248}Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy.%mdk + +%mdk-data-line={251} +\item\mdline{251}Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities.%mdk + +%mdk-data-line={253} +\item\mdline{253}Packet I/O to enable streaming packets to \mdline{253}\&\mdline{253} from the control plane.%mdk + +%mdk-data-line={254} +\item\mdline{254}Batching support, with different atomicity guarantees.%mdk + +%mdk-data-line={255} +\item\mdline{255}In-the-field device-reconfiguration with a new P4 data plane.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={257} +\noindent\mdline{257}The following are in the scope of this specification document:%mdk + +%mdk-data-line={259} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={259} +\item\mdline{259}Rationale for the P4Runtime design.%mdk + +%mdk-data-line={260} +\item\mdline{260}Reference architecture and use-cases for deploying a P4Runtime service.%mdk + +%mdk-data-line={261} +\item\mdline{261}Detailed description of the API semantics.%mdk + +%mdk-data-line={262} +\item\mdline{262}Requirements for conformant implementations of the API.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={264} +\subsection{\mdline{264}1.3.\hspace*{0.5em}\mdline{264}Not In Scope}\label{sec-not-in-scope}%mdk%mdk + +%mdk-data-line={266} +\noindent\mdline{266}The following are not in scope of P4Runtime:%mdk + +%mdk-data-line={268} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={268} +\item\mdline{268}Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +\mdline{273}[\mdcite{openconfig}{35}]\mdline{273}. An open source implementation of these APIs is also in progress +as part of the Stratum project\mdline{274}~[\mdcite{stratum}{37}]\mdline{274}.%mdk + +%mdk-data-line={275} +\item\mdline{275}Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={280} +\noindent\mdline{280}The following are not in scope of this specification document:%mdk + +%mdk-data-line={282} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={282} +\item\mdline{282}Description of the P4 programming language; it is assumed that the reader is +already familiar with P4\mdline{283}\mdsub{16}\mdline{283}~[\mdcite{p4spec}{1}]\mdline{283}.%mdk + +%mdk-data-line={284} +\item\mdline{284}Descriptions of gRPC and Protobuf files in general.%mdk + +%mdk-data-line={285} +\item\mdline{285}Controller\mdline{285}~\mdref{sec-arbitration-role-config}{role}\mdline{285} definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={289} +\section{\mdline{289}2.\hspace*{0.5em}\mdline{289}Terms and Definitions}\label{sec-terms-and-definitions}%mdk%mdk + +%mdk-data-line={291} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries arbitration}}%mdk + +%mdk-data-line={291} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{291}Refers to the process through which P4Runtime ensures that at any given +time, there is a single primary controller (\mdline{292}i.e.\mdline{292} a client with write access) +for a given role. Also referred to as \mdline{293}\textquotedblleft{}client arbitration\textquotedblright{}\mdline{293}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries client}}%mdk + +%mdk-data-line={295} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{295}The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries COS}}%mdk + +%mdk-data-line={299} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{299}Class of Service. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries device}}%mdk + +%mdk-data-line={301} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{301}Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries entity}}%mdk + +%mdk-data-line={305} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{305}An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries gRPC}}%mdk + +%mdk-data-line={308} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{308}gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +\mdline{309}[\mdcite{grpc}{9}]\mdline{309}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries HA}}%mdk + +%mdk-data-line={311} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{311}High-Availability. Refers to a redundancy architecture. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Instrumentation}}%mdk + +%mdk-data-line={313} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{313}The part of the P4Runtime server which implements the calls to the device or +target native \mdline{314}\textquotedblleft{}SDK\textquotedblright{}\mdline{314} or backend. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries IPC}}%mdk + +%mdk-data-line={316} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{316}Inter-Process Communication. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Blob}}%mdk + +%mdk-data-line={318} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{318}A more colloquial term for P4 Device Config (Blob = Binary Large Object). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Device Config}}%mdk + +%mdk-data-line={320} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{320}The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its \mdline{322}\textquotedblleft{}program.\textquotedblright{}\mdline{322} +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4Info}}%mdk + +%mdk-data-line={324} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{324}Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4RT}}%mdk + +%mdk-data-line={328} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{328}Abbreviation for P4Runtime. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Protobuf (Protocol Buffers)}}%mdk + +%mdk-data-line={330} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{330}The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See\mdline{331}~[\mdcite{proto}{21}]\mdline{331}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries PSA}}%mdk + +%mdk-data-line={333} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{333}Portable Switch Architecture\mdline{333}~[\mdcite{psa}{19}]\mdline{333}; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RPC}}%mdk + +%mdk-data-line={337} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{337}Remote Procedure Call. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RTT}}%mdk + +%mdk-data-line={339} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{339}Round-trip time. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN}}%mdk + +%mdk-data-line={341} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{341}Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network \mdline{346}\emph{controller}\mdline{346}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN port}}%mdk + +%mdk-data-line={348} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{348}A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries server}}%mdk + +%mdk-data-line={352} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{352}The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries stream}}%mdk + +%mdk-data-line={356} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{356}Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (\mdline{357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{357}), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and client arbitration, among other things. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries switch config}}%mdk + +%mdk-data-line={361} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{361}Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries target}}%mdk + +%mdk-data-line={366} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{366}The hardware or software entity which \mdline{366}\textquotedblleft{}executes\textquotedblright{}\mdline{366} the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with \mdline{367}\textquotedblleft{}device\textquotedblright{}\mdline{367}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries URI}}%mdk + +%mdk-data-line={369} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{369}Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={373} +\section{\mdline{373}3.\hspace*{0.5em}\mdline{373}Reference Architecture}\label{sec-reference-architecture}%mdk%mdk + +%mdk-data-line={375} +\noindent\mdline{375}Figure\mdline{375}~\mdref{fig-reference-architecture}{\mdcaptionlabel{1}}\mdline{375} represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. P4Runtime only grants write access to a +single primary controller for each read/write entity. A role defines a grouping +of P4 entities. P4Runtime allows for a primary controller for each role, and a +role-based client arbitration scheme ensures only one controller has +write access to each read/write entity, or the pipeline config itself. Any +controller may perform read access to any entity or the pipeline config. Later +sections describe this in detail. For the sake of brevity, the term controller +may refer to one or more controllers.%mdk + +%mdk-data-line={386} +\mdline{386}The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +\mdline{389}[\mdcite{p4runtimerepo}{15}]\mdline{389}. It may be compiled via protoc\mdline{389} \mdline{389}\textemdash{}\mdline{389} the Protobuf compiler\mdline{389} \mdline{389}\textemdash{}\mdline{389} +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server.%mdk + +%mdk-data-line={394} +\mdline{394}Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository\mdline{395}~[\mdcite{pirepo}{16}]\mdline{395}. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, \mdline{397}e.g.\mdline{397} via callbacks, thus reducing the burden of implementing +P4Runtime.%mdk + +%mdk-data-line={400} +\mdline{400}The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard.%mdk + +%mdk-data-line={404} +\mdline{404}The controller can also set the \mdline{404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{404}, which amounts to +installing and running the compiled P4 program output, which is included in the +\mdline{406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{406} Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +\mdline{408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{408} to retrieve the device config and the P4Info.%mdk + +%mdk-data-line={411} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={412} +\noindent\mdline{412}\includegraphics[keepaspectratio=true,height=7cm]{build/reference-architecture}{}\mdline{412}%mdk + +%mdk-data-line={413} +\mdhr{}%mdk + +%mdk-data-line={414} +\noindent\mdline{414}\mdcaption{\textbf{Figure~\mdcaptionlabel{1}.}~\mdcaptiontext{P4Runtime Reference Architecture.}}%mdk +%mdk +\end{mdcenter}\label{fig-reference-architecture}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={418} +\subsection{\mdline{418}3.1.\hspace*{0.5em}\mdline{418}P4Runtime Service Implementation}\label{sec-p4runtime-service-implementation}%mdk%mdk + +%mdk-data-line={420} +\noindent\mdline{420}The P4Runtime API is implemented by a program that runs a gRPC server which +binds an implementation of auto-generated P4Runtime Service interface. This +program is called the \mdline{422}\textquotedblleft{}P4Runtime server.\textquotedblright{}\mdline{422} The server must listen on TCP port +9559 by default, which is the port that has been allocated by IANA for the +P4Runtime service. Servers should allow users to override the default port +using a configuration file or flag when starting the server. Uses of other +port numbers as the default should be discontinued.%mdk + +%mdk-data-line={428} +\subsubsection{\mdline{428}3.1.1.\hspace*{0.5em}\mdline{428}Security concerns}\label{sec-security-concerns}%mdk%mdk + +%mdk-data-line={430} +\noindent\mdline{430}Appropriate measures and security best practices must be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. Mutual TLS (mTLS) may +be used to facilitate the authentication of the client by the server and +vice-versa.%mdk + +%mdk-data-line={439} +\subsection{\mdline{439}3.2.\hspace*{0.5em}\mdline{439}Idealized Workflow}\label{sec-idealized-workflow}%mdk%mdk + +%mdk-data-line={441} +\noindent\mdline{441}In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the \mdline{442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{442} +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a \mdline{444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{444} +RPC. Metadata in the P4Info describes both the overall program itself +(\mdline{446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{446}) as well as all entity instances derived from the P4 program\mdline{446} \mdline{446}\textemdash{}\mdline{446} +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise \mdline{448}\textquotedblleft{}handle\textquotedblright{}\mdline{448} used in API +calls.%mdk + +%mdk-data-line={451} +\mdline{451}In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible.%mdk + +%mdk-data-line={457} +\mdline{457}In some use cases, it is expected that a controller will store a +collection of multiple P4 \mdline{458}\textquotedblleft{}packages\textquotedblright{}\mdline{458}, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the \mdline{460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{460} from the target via the +\mdline{461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineRequest}}}\mdline{461} RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state.%mdk + +%mdk-data-line={465} +\subsection{\mdline{465}3.3.\hspace*{0.5em}\mdline{465}P4 as a Behavioral Description Language}\label{sec-p4-as-behavioral-description-language}%mdk%mdk + +%mdk-data-line={467} +\noindent\mdline{467}P4 can be considered a behavioral description of a switching device which may or +may not execute \mdline{468}\textquotedblleft{}P4\textquotedblright{}\mdline{468} natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a \mdline{470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineRequest}}}\mdline{470} to +change its pipeline \mdline{471}\textquotedblleft{}program\textquotedblright{}\mdline{471}, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device.%mdk + +%mdk-data-line={477} +\mdline{477}While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API.%mdk + +%mdk-data-line={486} +\mdline{486}In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the \mdline{487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{487} +message as well as the embedded \mdline{488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{488} fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections.%mdk + +%mdk-data-line={492} +\subsection{\mdline{492}3.4.\hspace*{0.5em}\mdline{492}Alternative Workflows}\label{sec-alternative-workflows}%mdk%mdk + +%mdk-data-line={494} +\noindent\mdline{494}Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary.%mdk + +%mdk-data-line={498} +\subsubsection{\mdline{498}3.4.1.\hspace*{0.5em}\mdline{498}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}\label{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}%mdk%mdk + +%mdk-data-line={500} +\noindent\mdline{500}In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +\mdline{502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{502}. The device\mdline{502}'\mdline{502}s configuration might be derived via some other +means to implement the P4 source code\mdline{503}'\mdline{503}s intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane.%mdk + +%mdk-data-line={507} +\subsubsection{\mdline{507}3.4.2.\hspace*{0.5em}\mdline{507}No P4 Source Available, P4Info Available}\label{sec-no-p4-source-available-p4info-available}%mdk%mdk + +%mdk-data-line={509} +\noindent\mdline{509}In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are:%mdk + +%mdk-data-line={512} +\begin{enumerate}%mdk + +%mdk-data-line={512} +\item{} +%mdk-data-line={512} +\mdline{512}The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security.%mdk%mdk + +%mdk-data-line={515} +\item{} +%mdk-data-line={515} +\mdline{515}The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={518} +\noindent\mdline{518}As discussed in Section\mdline{518}~\mdref{sec-p4-as-behavioral-description-language}{3.3}\mdline{518}, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, \mdline{521}e.g.\mdline{521} documentation.%mdk + +%mdk-data-line={523} +\subsubsection{\mdline{523}3.4.3.\hspace*{0.5em}\mdline{523}Partial P4Info and P4 Source are Available}\label{sec-partial-p4info-and-p4-source-are-available}%mdk%mdk + +%mdk-data-line={525} +\noindent\mdline{525}In this situation, a subset of the target\mdline{525}'\mdline{525}s pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code.%mdk + +%mdk-data-line={532} +\subsubsection{\mdline{532}3.4.4.\hspace*{0.5em}\mdline{532}P4Info Role-Based Subsets}\label{sec-p4info-role-based-subsets}%mdk%mdk + +%mdk-data-line={534} +\noindent\mdline{534}In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more.%mdk + +%mdk-data-line={538} +\subsection{\mdline{538}3.5.\hspace*{0.5em}\mdline{538}P4Runtime State Across Restarts}\label{sec-restarts}%mdk%mdk + +%mdk-data-line={540} +\noindent\mdline{540}All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade.%mdk + +%mdk-data-line={546} +\section{\mdline{546}4.\hspace*{0.5em}\mdline{546}Controller Use-cases}\label{sec-controller-use-cases}%mdk%mdk + +%mdk-data-line={548} +\noindent\mdline{548}P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +\mdline{550}\mdref{sec-client-arbitration-and-controller-replication}{section}\mdline{550}. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime\mdline{552}'\mdline{552}s flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex.%mdk + +%mdk-data-line={555} +\subsection{\mdline{555}4.1.\hspace*{0.5em}\mdline{555}Single Embedded Controller}\label{sec-single-embedded-controller}%mdk%mdk + +%mdk-data-line={557} +\noindent\mdline{557}Figure\mdline{557}~\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}}\mdline{557} shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases.%mdk + +%mdk-data-line={562} +\mdline{562}P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC.%mdk + +%mdk-data-line={567} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={568} +\noindent\mdline{568}\includegraphics[keepaspectratio=true,height=6cm]{build/single-embedded-controller}{}\mdline{568}%mdk + +%mdk-data-line={569} +\mdhr{}%mdk + +%mdk-data-line={570} +\noindent\mdline{570}\mdcaption{\textbf{Figure~\mdcaptionlabel{2}.}~\mdcaptiontext{Use-Case: Single Embedded Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-embedded-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={574} +\subsection{\mdline{574}4.2.\hspace*{0.5em}\mdline{574}Single Remote Controller}\label{sec-single-remote-controller}%mdk%mdk + +%mdk-data-line={576} +\noindent\mdline{576}Figure\mdline{576}~\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}}\mdline{576} shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections.%mdk + +%mdk-data-line={581} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={582} +\noindent\mdline{582}\includegraphics[keepaspectratio=true,height=7cm]{build/single-remote-controller}{}\mdline{582}%mdk + +%mdk-data-line={583} +\mdhr{}%mdk + +%mdk-data-line={584} +\noindent\mdline{584}\mdcaption{\textbf{Figure~\mdcaptionlabel{3}.}~\mdcaptiontext{Use-Case: Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={588} +\subsection{\mdline{588}4.3.\hspace*{0.5em}\mdline{588}Embedded\mdline{588} \mdline{588}+ Single Remote Controller}\label{sec-embedded-single-remote-controller}%mdk%mdk + +%mdk-data-line={590} +\noindent\mdline{590}Figure\mdline{590}~\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}}\mdline{590} illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller.%mdk + +%mdk-data-line={597} +\mdline{597}For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables.%mdk + +%mdk-data-line={601} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={602} +\noindent\mdline{602}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-single-remote-controller}{}\mdline{602}%mdk + +%mdk-data-line={603} +\mdhr{}%mdk + +%mdk-data-line={604} +\noindent\mdline{604}\mdcaption{\textbf{Figure~\mdcaptionlabel{4}.}~\mdcaptiontext{Use-Case: Embedded Plus Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={609} +\subsection{\mdline{609}4.4.\hspace*{0.5em}\mdline{609}Embedded\mdline{609} \mdline{609}+ Two Remote Controllers}\label{sec-embedded-two-remote-controllers}%mdk%mdk + +%mdk-data-line={611} +\noindent\mdline{611}Figure\mdline{611}~\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}}\mdline{611} illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +\mdline{614}e.g.\mdline{614} routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership.%mdk + +%mdk-data-line={617} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={618} +\noindent\mdline{618}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-controllers}{}\mdline{618}%mdk + +%mdk-data-line={619} +\mdhr{}%mdk + +%mdk-data-line={620} +\noindent\mdline{620}\mdcaption{\textbf{Figure~\mdcaptionlabel{5}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={625} +\subsection{\mdline{625}4.5.\hspace*{0.5em}\mdline{625}Embedded Controller\mdline{625} \mdline{625}+ Two High-Availability Remote Controllers}\label{sec-embedded-controller-two-high-availability-remote-controllers}%mdk%mdk + +%mdk-data-line={627} +\noindent\mdline{627}Figure\mdline{627}~\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}}\mdline{627} illustrates a single +embedded controller plus two remote controllers in an active-standby (\mdline{628}i.e.\mdline{628} +primary-backup) HA (High-Availability) configuration. Controller \mdline{629}\#\mdline{629}1 is the +active controller and is in charge of some entities. If it fails, Controller \mdline{630}\#\mdline{630}2 +takes over and manages the tables formerly owned by Controller \mdline{631}\#\mdline{631}1. The mechanics +of HA architectures are beyond the scope of this document, but the P4Runtime +role-based client arbitration scheme supports it.%mdk + +%mdk-data-line={635} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={636} +\noindent\mdline{636}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-ha-controllers}{}\mdline{636}%mdk + +%mdk-data-line={637} +\mdhr{}%mdk + +%mdk-data-line={638} +\noindent\mdline{638}\mdcaption{\textbf{Figure~\mdcaptionlabel{6}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-ha-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={643} +\section{\mdline{643}5.\hspace*{0.5em}\mdline{643}Client Arbitration and Controller Replication}\label{sec-client-arbitration-and-controller-replication}%mdk%mdk + +%mdk-data-line={646} +\noindent\mdline{646}The P4Runtime interface allows multiple clients (\mdline{646}i.e.\mdline{646} controllers) to be +connected to the P4Runtime server running on the device at the same time for the +following reasons:%mdk + +%mdk-data-line={650} +\begin{enumerate}%mdk + +%mdk-data-line={650} +\item{} +%mdk-data-line={650} +\mdline{650}Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, \mdline{651}\textquotedblleft{}roles\textquotedblright{}\mdline{651} (or \mdline{651}\textquotedblleft{}realms\textquotedblright{}\mdline{651}) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +primary and the rest are backups. Role definition, \mdline{654}i.e.\mdline{654} how P4 entities get +assigned to each role, is \mdline{655}\textbf{out-of-scope}\mdline{655} of this document.%mdk%mdk + +%mdk-data-line={657} +\item{} +%mdk-data-line={657} +\mdline{657}Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby backup controllers. These can already have a connection +open, which can help them become primary more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={663} +\noindent\mdline{663}To support multiple controllers, P4Runtime uses the streaming channel (available +via \mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{664} RPC) for session management. The workflow is described as +follows:%mdk + +%mdk-data-line={667} +\begin{itemize}%mdk + +%mdk-data-line={667} +\item{} +%mdk-data-line={667} +\mdline{667}Each controller instance (\mdline{667}e.g.\mdline{667} a controller process) can participate in one or +more roles. For each (\mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{668}, \mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{668}), the controller receives an +\mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{669}. This \mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{669} can be the same for different roles and/or +devices, as long as the tuple (\mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{670}, \mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{670}, \mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{670}) is +unique. For each (\mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{671}, \mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{671}) that the controller wishes to +control, it establishes a \mdline{672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{672} with the P4Runtime server +responsible for that device, and sends a \mdline{673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{673} message +containing that tuple of (\mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{674}, \mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{674}, \mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{674}) values. The +P4Runtime server selects a primary independently for each (\mdline{675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{675}, +\mdline{676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{676}) pair. The primary is the client that has the highest \mdline{676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{676} +that the device has ever received for the same (\mdline{677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{677}, +\mdline{678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{678}) values. A connection between a controller instance and a device id +\mdline{679}\textemdash{}\mdline{679} which involves a persistent \mdline{679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{679} \mdline{679}\textemdash{}\mdline{679} can be referred to as a +P4Runtime client.%mdk + +%mdk-data-line={682} +\mdline{682}Note that the P4Runtime server does not assign a \mdline{682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{682} or \mdline{682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{682} to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the \mdline{684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{684} values used for each +\mdline{685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{685}. The P4Runtime server only keeps track of the (\mdline{685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{685}, +\mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{686}, \mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{686}) of each \mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{686} that has sent a successful +\mdline{687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{687} message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +\mdline{689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{689} message to identify which client is making the \mdline{689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{689}, +not only the \mdline{690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{690}. This enables controllers to re-use the same +numeric \mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{691} values across different (\mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{691}, \mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{691}) +pairs. P4Runtime does not require \mdline{692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{692} values be reused across such +different (\mdline{693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{693}, \mdline{693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{693}) pairs; it allows it.%mdk%mdk + +%mdk-data-line={695} +\item{} +%mdk-data-line={695} +\mdline{695}To start a controller session, a controller first opens a bidirectional stream +channel to the server via the \mdline{696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{696} RPC for each device. This stream +will be used for two purposes:%mdk + +%mdk-data-line={699} +\begin{itemize}%mdk + +%mdk-data-line={699} +\item{} +%mdk-data-line={699} +\mdline{699}\textbf{Session management:}\mdline{699} As soon as the controller opens the stream +channel, it sends a \mdline{700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{700} message to the switch. The +controller populates the \mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{701} field in this message +using its \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{702} and \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{702}, as well as the \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{702} of the +device. Note that the \mdline{703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{703} field in the \mdline{703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{703} is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below.%mdk%mdk + +%mdk-data-line={707} +\item{} +%mdk-data-line={707} +\mdline{707}\textbf{Streaming of notifications (e.g. digests) and packet I/O:}\mdline{707} The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the primary controller can participate in +packet I/O. This feature is explained in more details in the\mdline{711}~\mdref{sec-packet-i_o}{Packet +I/O}\mdline{712} section.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={714} +\mdline{714}Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state.%mdk%mdk + +%mdk-data-line={717} +\item{} +%mdk-data-line={717} +\mdline{717}Note that the stream is opened per device. In case a switching platform has +multiple devices (\mdline{718}e.g.\mdline{718} multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different primary clients for +different devices. In this case, it is the responsibility of the P4Runtime +server to keep track of the primary for each device (and role). More +specifically, the P4Runtime server will know which stream corresponds to the +primary controller for each pair of (\mdline{723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{723}, \mdline{723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{723}) at any point of +time.%mdk%mdk + +%mdk-data-line={726} +\item{} +%mdk-data-line={726} +\mdline{726}The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered \mdline{727}\textquotedblleft{}offline\textquotedblright{}\mdline{727} or +\mdline{728}\textquotedblleft{}dead\textquotedblright{}\mdline{728} as soon as its stream channel to the switch is broken. When a primary +channel gets broken: (i) an advisory message is sent to all other controllers +for that \mdline{730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{730} and \mdline{730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{730}, as described in the +\mdline{731}\mdref{sec-arbitration-notification}{following section}\mdline{731} (ii) the P4Runtime server +will be without a primary controller, until a client sends a successful +\mdline{733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{733} (as per the rules in a +\mdline{734}\mdref{sec-arbitration-updates}{later section}\mdline{734}).%mdk%mdk + +%mdk-data-line={736} +\item{} +%mdk-data-line={736} +\mdline{736}The mechanism via which the controller receives the P4Runtime server details +which includes the \mdline{737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{737}, \mdline{737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip}}}\mdline{737} and \mdline{737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{737}, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +\mdline{741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{741}) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={746} +\noindent\mdline{746}gRPC enables the server to identify which client originated each message in the +\mdline{747}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{747} stream. For example, the C++ gRPC library\mdline{747}~[\mdcite{grpcstreamc}{10}]\mdline{747} in +synchronous mode enables a server process to cause a function to be called when +a new client creates a \mdline{749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{749} stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +\mdline{751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{751} is closed normally (or broken, \mdline{751}e.g.\mdline{751} because a client process +unexpectedly terminated). Thus the server can easily associate all +\mdline{753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{753} messages received from the same client, because they are +processed within the context of the same function call.%mdk + +%mdk-data-line={756} +\mdline{756}A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values \mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{761}, \mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{761}, and \mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{761} in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods\mdline{763}~[\mdcite{grpcauth}{8}]\mdline{763} that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server.%mdk + +%mdk-data-line={767} +\subsection{\mdline{767}5.1.\hspace*{0.5em}\mdline{767}Default Role}\label{sec-default-role}%mdk%mdk + +%mdk-data-line={769} +\noindent\mdline{769}A controller can omit the role message in \mdline{769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{769}. This +implies the \mdline{770}\textquotedblleft{}default role\textquotedblright{}\mdline{770}, which corresponds to \mdline{770}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{770}. +This also implies that a default role has a \mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{771} of \mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}""}}}\mdline{771} (default). +If using a default role, all RPCs from the controller (\mdline{772}e.g.\mdline{772} \mdline{772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{772}) must +leave the \mdline{773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{773} unset.%mdk + +%mdk-data-line={775} +\subsection{\mdline{775}5.2.\hspace*{0.5em}\mdline{775}Role Config}\label{sec-arbitration-role-config}%mdk%mdk + +%mdk-data-line={777} +\noindent\mdline{777}The \mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{777} field in the \mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{777} message sent by the +controller describes the role configuration, \mdline{778}i.e.\mdline{778} which operations are in the +scope of a given role. In particular, the definition of a role may include the +following:%mdk + +%mdk-data-line={782} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={782} +\item\mdline{782}A list of P4 entities for which the controller may issue \mdline{782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{782} updates and +receive notification messages (\mdline{783}e.g.\mdline{783} \mdline{783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{783} and +\mdline{784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{784}).%mdk + +%mdk-data-line={785} +\item\mdline{785}Whether the controller is able to receive \mdline{785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{785} messages, along with a +filtering mechanism based on the values of the \mdline{786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{786} fields to +select which \mdline{787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{787} messages should be sent to the controller.%mdk + +%mdk-data-line={788} +\item\mdline{788}Whether the controller is able to send \mdline{788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{788} messages, along with a +filtering mechanism based on the values of the \mdline{789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{789} fields to +select which \mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{790} messages are allowed to be sent by the controller.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={792} +\noindent\mdline{792}An unset \mdline{792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{792} implies \mdline{792}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{792} (similar to the default +role explained above). In order to support different role definition schemes, +\mdline{794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{794} is defined as an \mdline{794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{794} Protobuf message\mdline{794}~[\mdcite{protoany}{31}]\mdline{794}. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion.%mdk + +%mdk-data-line={799} +\mdline{799}It is the job of the P4Runtime server to remember the \mdline{799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{799} for every +\mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{800} and \mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{800} pair.%mdk + +%mdk-data-line={802} +\subsection{\mdline{802}5.3.\hspace*{0.5em}\mdline{802}Rules for Handling \mdline{802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{802} Messages Received from Controllers}\label{sec-arbitration-updates}%mdk%mdk + +%mdk-data-line={804} +\begin{enumerate}%mdk + +%mdk-data-line={804} +\item{} +%mdk-data-line={804} +\mdline{804}If the \mdline{804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{804} message is received for the first time on +this particular channel (\mdline{805}i.e.\mdline{805} for a newly connected controller):%mdk + +%mdk-data-line={807} +\begin{enumerate}%mdk + +%mdk-data-line={807} +\item{} +%mdk-data-line={807} +\mdline{807}If \mdline{807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{807} does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +\mdline{809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{809} error.%mdk%mdk + +%mdk-data-line={811} +\item{} +%mdk-data-line={811} +\mdline{811}If the \mdline{811}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{811} is set and is already used by another controller for +the same (\mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{812}, \mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{812}), the P4Runtime server shall terminate +the stream by returning an \mdline{813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{813} error.%mdk%mdk + +%mdk-data-line={815} +\item{} +%mdk-data-line={815} +\mdline{815}If \mdline{815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{815} does not match the \mdline{815}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{815} scheme previously +agreed upon, the server must return an \mdline{816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{816} error.%mdk%mdk + +%mdk-data-line={818} +\item{} +%mdk-data-line={818} +\mdline{818}If the number of open streams for the given (\mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{818}, \mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{818}) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a \mdline{820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{820} error.%mdk%mdk + +%mdk-data-line={822} +\item{} +%mdk-data-line={822} +\mdline{822}Otherwise, the controller is added to a list of connected controllers for +the given (\mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{823}, \mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{823}) and the server remembers the +controllers \mdline{824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{824}, \mdline{824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{824} and \mdline{824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{824} for this gRPC +channel. See below for the rules to determine if this controller becomes +a primary or backup, and what notifications are sent as a consequence.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={828} +\item{} +%mdk-data-line={828} +\mdline{828}Otherwise, if the \mdline{828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{828} message is received from an +already connected controller:%mdk + +%mdk-data-line={831} +\begin{enumerate}%mdk + +%mdk-data-line={831} +\item{} +%mdk-data-line={831} +\mdline{831}If the \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{831} does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{833} error.%mdk%mdk + +%mdk-data-line={835} +\item{} +%mdk-data-line={835} +\mdline{835}If the \mdline{835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{835} does not match the current \mdline{835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{835} assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{837} error. If the controller wishes to change its role, +it must close the current stream channel and open a new one.%mdk%mdk + +%mdk-data-line={840} +\item{} +%mdk-data-line={840} +\mdline{840}If \mdline{840}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{840} does not match the \mdline{840}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{840} scheme previously +agreed upon, the server must return an \mdline{841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{841} error.%mdk%mdk + +%mdk-data-line={843} +\item{} +%mdk-data-line={843} +\mdline{843}If the \mdline{843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{843} is set and is already used by another controller +(excluding the controller making the request) for the same +(\mdline{845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{845}, \mdline{845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{845}), the P4Runtime server shall terminate the stream +by returning an \mdline{846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{846} error.%mdk%mdk + +%mdk-data-line={848} +\item{} +%mdk-data-line={848} +\mdline{848}Otherwise, the server updates the \mdline{848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{848} it has stored for this +controller. This change might cause a change in the primary client (this +controller might become primary, or the controller might have downgraded +itself to a backup, see below), as well as notifications being sent to +one or more controllers.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={854} +\noindent\mdline{854}If the \mdline{854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{854} is accepted by either of the two steps above +(cases 1.5. and 2.5. above), then the server determines if there are changes in +the primary client. Let \mdline{856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{856} be the highest election ID the server +has ever seen for the given \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{857} and \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{857} (including the one of the +current primary if there is one).%mdk + +%mdk-data-line={860} +\begin{enumerate}%mdk + +%mdk-data-line={860} +\item{} +%mdk-data-line={860} +\mdline{860}If \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{860} is greater than or equal to \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{860}, then the +controller becomes, or stays, primary. The server updates the role +configuration to \mdline{862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{862} for the given \mdline{862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{862}. Furthermore:%mdk + +%mdk-data-line={864} +\begin{enumerate}%mdk + +%mdk-data-line={864} +\item{} +%mdk-data-line={864} +\mdline{864}If there was no primary for this \mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{864} and \mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{864} before and +there are no \mdline{865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{865} requests still processing from a previous primary, +then the server immediately sends an advisory notification to all +controllers for this \mdline{867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{867} and \mdline{867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{867}. See the +\mdline{868}\mdref{sec-arbitration-notification}{following section}\mdline{868} for the format of the +advisory message.%mdk%mdk + +%mdk-data-line={871} +\item{} +%mdk-data-line={871} +\mdline{871}If there was a previous primary, including this controller, or \mdline{871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{871} +requests in flight, then the server carries out the following steps +(in this order):%mdk + +%mdk-data-line={875} +\begin{enumerate}%mdk + +%mdk-data-line={875} +\item{} +%mdk-data-line={875} +\mdline{875}The server stops accepting \mdline{875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{875} requests from the previous primary +(if there is one). At this point, the server will reject all \mdline{876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{876} +requests with \mdline{877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{877}.%mdk%mdk + +%mdk-data-line={879} +\item{} +%mdk-data-line={879} +\mdline{879}The server notifies all controllers other than the new primary client +of the change by sending the advisory notification described in +the\mdline{881}~\mdref{sec-arbitration-notification}{following section}\mdline{881}.%mdk%mdk + +%mdk-data-line={883} +\item{} +%mdk-data-line={883} +\mdline{883}The server will finish processing any \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{883} requests that have +already started. If there are errors, they are reported as usual to +the previous primary. If the previous primary has already +disconnected, any possible errors are dropped and not reported.%mdk%mdk + +%mdk-data-line={888} +\item{} +%mdk-data-line={888} +\mdline{888}The server now accepts the current controller as the new primary, +thus accepting \mdline{889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{889} requests from this controller. The server +updates the highest election ID (\mdline{890}i.e.\mdline{890} \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{890}) it has seen +for this \mdline{891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{891} and \mdline{891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{891} to \mdline{891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{891}.%mdk%mdk + +%mdk-data-line={893} +\item{} +%mdk-data-line={893} +\mdline{893}The server notifies the new primary by sending the advisory message +described in the\mdline{894}~\mdref{sec-arbitration-notification}{following section}\mdline{894}.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={896} +\item{} +%mdk-data-line={896} +\mdline{896}Otherwise, the controller becomes a backup. If the controller was previously +a primary (and downgraded itself), then an advisory message is sent to all +controllers for this \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{898} and \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{898}. Otherwise, the advisory +message is only sent to the controller that sent the initial +\mdline{900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{900}. See the +\mdline{901}\mdref{sec-arbitration-notification}{following section}\mdline{901} for the format of the +advisory message.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={904} +\subsection{\mdline{904}5.4.\hspace*{0.5em}\mdline{904}Client Arbitration Notifications}\label{sec-arbitration-notification}%mdk%mdk + +%mdk-data-line={906} +\noindent\mdline{906}For any given \mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{906} and \mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{906}, any time a new primary is chosen, a +primary downgrades its status to a backup, a primary disconnects, or the +\mdline{908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{908} is updated by the primary, all controllers for that +(\mdline{909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{909}, \mdline{909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{909}) are informed of this by sending a +\mdline{910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{910}. The \mdline{910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{910} is populated as follows:%mdk + +%mdk-data-line={912} +\begin{itemize}%mdk + +%mdk-data-line={912} +\item{} +%mdk-data-line={912} +\mdline{912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{912} and \mdline{912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{912} as given.%mdk%mdk + +%mdk-data-line={914} +\item{} +%mdk-data-line={914} +\mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{914} is set to the role configuration the server received most +recently in a \mdline{915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{915} from a primary.%mdk%mdk + +%mdk-data-line={917} +\item{} +%mdk-data-line={917} +\mdline{917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{917} is populated as follows:%mdk + +%mdk-data-line={919} +\begin{itemize}%mdk + +%mdk-data-line={919} +\item{} +%mdk-data-line={919} +\mdline{919}If there has not been any primary at all, the election\mdline{919}\_\mdline{919}id is left unset.%mdk%mdk + +%mdk-data-line={921} +\item{} +%mdk-data-line={921} +\mdline{921}Otherwise, \mdline{921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{921} is set to the highest election ID that the server +has seen for this \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{922} and \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{922} (which is the \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{922} of +the current primary if there is any).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={925} +\item{} +%mdk-data-line={925} +\mdline{925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{925} is set differently based on whether the notification is sent to the +primary or a backup controller:%mdk + +%mdk-data-line={928} +\begin{itemize}%mdk + +%mdk-data-line={928} +\item{} +%mdk-data-line={928} +\mdline{928}If there is a primary:%mdk + +%mdk-data-line={930} +\begin{itemize}%mdk + +%mdk-data-line={930} +\item{} +%mdk-data-line={930} +\mdline{930}For the primary, \mdline{930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{930} is OK (with \mdline{930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{930} set to +\mdline{931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.OK}}}\mdline{931}).%mdk%mdk + +%mdk-data-line={933} +\item{} +%mdk-data-line={933} +\mdline{933}For all backup controllers, \mdline{933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{933} is set to non-OK (with +\mdline{934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{934} set to \mdline{934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.ALREADY\_EXISTS}}}\mdline{934}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={936} +\item{} +%mdk-data-line={936} +\mdline{936}Otherwise, if there is no primary currently, for all backup controllers, +\mdline{937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{937} is set to non-OK (with \mdline{937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{937} set to +\mdline{938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.NOT\_FOUND}}}\mdline{938}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={940} +\noindent\mdline{940}Note that on primary client changes with outstanding \mdline{940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{940} request, some +notifications might be delayed, see the +\mdline{942}\mdref{sec-arbitration-updates}{previous section}\mdline{942} for details.%mdk + +%mdk-data-line={944} +\section{\mdline{944}6.\hspace*{0.5em}\mdline{944}The P4Info Message}\label{sec-the-p4info-message}%mdk%mdk + +%mdk-data-line={946} +\noindent\mdline{946}The purpose of P4Info was described under +\mdline{947}\mdref{sec-reference-architecture}{Reference Architecture}\mdline{947}. +Here we describe the various +components.%mdk + +%mdk-data-line={951} +\subsection{\mdline{951}6.1.\hspace*{0.5em}\mdline{951}Common Messages}\label{sec-common-messages}%mdk%mdk + +%mdk-data-line={953} +\noindent\mdline{953}These messages appear nested within many other messages.%mdk + +%mdk-data-line={955} +\subsubsection{\mdline{955}6.1.1.\hspace*{0.5em}\mdline{955}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{955} Message}\label{sec-documentation-message}%mdk%mdk + +%mdk-data-line={957} +\noindent\mdline{957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{957} is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers.%mdk + +%mdk-data-line={961} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={962} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Documentation~\{\\ +~~{\mdcolor{darkgreen}//~A~brief~description~of~something,~e.g.~one~sentence}\\ +~~{\bfseries{\mdcolor{navy}string}}~brief~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~A~more~verbose~description~of~something.}\\ +~~{\mdcolor{darkgreen}//~Multiline~is~accepted.~Markup~format~(if~any)~is~TBD.}\\ +~~{\bfseries{\mdcolor{navy}string}}~description~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={971} +\subsubsection{\mdline{971}6.1.2.\hspace*{0.5em}\mdline{971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{971} Message}\label{sec-preamble-message}%mdk%mdk + +%mdk-data-line={973} +\noindent\mdline{973}The preamble serves as the \mdline{973}\textquotedblleft{}descriptor\textquotedblright{}\mdline{973} for each entity and contains the unique +instance ID, name, alias, annotations and documentation.%mdk + +%mdk-data-line={976} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={977} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Preamble~\{\\ +~~{\mdcolor{darkgreen}//~ids~share~the~same~number-space;~e.g.~table~ids~cannot~overlap~with~counter}\\ +~~{\mdcolor{darkgreen}//~ids.~Even~though~this~is~irrelevant~to~this~proto~definition,~the~ids~are}\\ +~~{\mdcolor{darkgreen}//~allocated~in~such~a~way~that~it~is~possible~based~on~an~id~to~deduce~the}\\ +~~{\mdcolor{darkgreen}//~resource~type~(e.g.~table,~action,~counter,~...).~This~means~that~code}\\ +~~{\mdcolor{darkgreen}//~using~these~ids~can~detect~if~the~wrong~resource~type~is~used}\\ +~~{\mdcolor{darkgreen}//~somewhere.~This~also~means~that~ids~of~different~types~can~be~mixed}\\ +~~{\mdcolor{darkgreen}//~(e.g.~direct~resource~list~for~a~table)~without~ambiguity.~Note~that~id~0}\\ +~~{\mdcolor{darkgreen}//~is~reserved~and~means~"invalid~id".}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name~of~the~P4~object,~e.g.~c1.c2.ipv4\_lpm}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~an~alias~(alternative~name)~for~the~P4~object,~probably~shorter~than~its}\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name.~The~only~constraint~is~for~it~to~be~unique~with}\\ +~~{\mdcolor{darkgreen}//~respect~to~other~P4~objects~of~the~same~type.~By~default,~the~compiler~uses}\\ +~~{\mdcolor{darkgreen}//~the~shortest~suffix~of~the~name~that~uniquely~identifies~the~object.~For}\\ +~~{\mdcolor{darkgreen}//~example~if~the~P4~program~contains~two~tables~with~names~s.c1.t~and~s.c2.t,}\\ +~~{\mdcolor{darkgreen}//~the~default~aliases~will~respectively~be~c1.t~and~c2.t.~In~the~future,~the}\\ +~~{\mdcolor{darkgreen}//~P4~programmer~may~also~be~able~to~override~the~default~alias~for~any~P4}\\ +~~{\mdcolor{darkgreen}//~object~(TBD).}\\ +~~{\bfseries{\mdcolor{navy}string}}~alias~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~Optional.~If~present,~the~location~of~`annotations{}[i]`~is~given~by}\\ +~{\mdcolor{darkgreen}//~`annotation\_locations{}[i]`.}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~SourceLocation~annotation\_locations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~Documentation~of~the~entity}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1008} +\subsubsection{\mdline{1008}6.1.3.\hspace*{0.5em}\mdline{1008}Annotating P4 Entities with \mdline{1008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}\label{sec-annotating-p4-entities-with-documentation}%mdk%mdk + +%mdk-data-line={1010} +\noindent\mdline{1010}P4 entities may be annotated using the following annotations:%mdk + +%mdk-data-line={1012} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1013} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}(string...)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}(string...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1017} +\noindent\mdline{1017}Attaching either or both of these annotations to an entity will generate a +P4Info\mdline{1018}~\mdref{sec-documentation-message}{Documentation Message}\mdline{1018}, which in turn will +appear in the\mdline{1019}~\mdref{sec-preamble-message}{Preamble Message}\mdline{1019} for the entity.%mdk + +%mdk-data-line={1021} +\mdline{1021}The P4 compiler should not emit \mdline{1021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation}}}\mdline{1021} messages in the P4Info for these +specific cases; instead, it should generate the \mdline{1022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1022} messages as +described.%mdk + +%mdk-data-line={1025} +\mdline{1025}The following example shows documentation annotations for a \mdline{1025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table}}}\mdline{1025} entity:%mdk + +%mdk-data-line={1027} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1028} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port.~\textbackslash{}}\\ +Uses~LPM~match~{\bfseries{\mdcolor{navy}type}}.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}table~my\_ipv4\_lkup~\{}\\ +{\mdcolor{maroon}~~...}\\ +{\mdcolor{maroon}\}}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1036} +\subsubsection{\mdline{1036}6.1.4.\hspace*{0.5em}\mdline{1036}Structured Annotations}\label{sec-structured-annotations}%mdk%mdk + +%mdk-data-line={1038} +\noindent\mdline{1038}P4 supports both unstructured and structured annotations\mdline{1038}~[\mdcite{p4annotations}{13}]\mdline{1038}. +Unstructured annotations of the form \mdline{1039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno1}}}\mdline{1039} or \mdline{1039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno2(body-content)}}}\mdline{1039} can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +\mdline{1042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno3{}[]}}}\mdline{1042} or \mdline{1042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno4{}[kvList\textbar{}expressionList]}}}\mdline{1042} have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this.%mdk + +%mdk-data-line={1047} +\mdline{1047}The annotations described up to this point, \mdline{1047}e.g.\mdline{1047} \mdline{1047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief()}}}\mdline{1047}, have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as \mdline{1049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1049} fields in the various \mdline{1049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{1049}s. +Similarly, structured annotations are represented in \mdline{1050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated\\ +StructuredAnnotation~structured\_annotations}}}\mdline{1051} fields which are siblings to the +unstructured \mdline{1052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1052}. The \mdline{1052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations}}}\mdline{1052} contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations.%mdk + +%mdk-data-line={1057} +\mdline{1057}The structured annotation messages are defined in p4types.proto.%mdk + +%mdk-data-line={1059} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1060} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~KeyValuePair~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~key~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Expression~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~KeyValuePairList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~KeyValuePair~kv\_pairs~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Expression~\{\\ +~~{\bfseries{\mdcolor{navy}oneof}}~value~\{\\ +~~~~{\bfseries{\mdcolor{navy}string}}~string\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~{\bfseries{\mdcolor{navy}int64}}~int64\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~{\bfseries{\mdcolor{navy}bool}}~bool\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~ExpressionList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Expression~expressions~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~StructuredAnnotation~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}oneof}}~body~\{\\ +~~~~ExpressionList~expression\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~KeyValuePairList~kv\_pair\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~Optional.~Location~of~the~'@'~symbol~of~this~annotation~in~the~source~code.}\\ +~~SourceLocation~source\_location~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1092} +\noindent\mdline{1092}The \mdline{1092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1092} message can represent either a \mdline{1092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1092} +or an \mdline{1093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExpressionList}}}\mdline{1093}.%mdk + +%mdk-data-line={1095} +\mdline{1095}The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The \mdline{1096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{1096} +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don\mdline{1098}'\mdline{1098}t match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler \mdline{1100}\emph{may}\mdline{1100} print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions.%mdk + +%mdk-data-line={1104} +\mdline{1104}The following invariants hold:%mdk + +%mdk-data-line={1106} +\begin{enumerate}%mdk + +%mdk-data-line={1106} +\item{} +%mdk-data-line={1106} +\mdline{1106}For any P4 entity, there are no two \mdline{1106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1106}s that have the +same name.%mdk%mdk + +%mdk-data-line={1109} +\item{} +%mdk-data-line={1109} +\mdline{1109}Within a \mdline{1109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1109}, there are no two \mdline{1109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePair}}}\mdline{1109}s that have the +same \mdline{1110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key.}}}\mdline{1110}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1112} +\paragraph{\mdline{1112}6.1.4.1.\hspace*{0.5em}\mdline{1112}Structured Annotation Examples}\label{sec-structured-annotation-examples}%mdk%mdk + +%mdk-data-line={1114} +\noindent\mdline{1114}We omit the \mdline{1114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}source\_location}}}\mdline{1114} field in the following examples.%mdk + +%mdk-data-line={1116} +\mdline{1116}\textbf{Empty Expression List}\mdline{1116}%mdk + +%mdk-data-line={1118} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1119} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}Empty}{\mdcolor{maroon}{}[]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1125} +\noindent\mdline{1125}The generated P4Info will contain the following.%mdk + +%mdk-data-line={1127} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1128} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}Empty}{\mdcolor{maroon}"}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1133} +\noindent\mdline{1133}\textbf{Mixed Expression List}\mdline{1133}%mdk + +%mdk-data-line={1135} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1136} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~TEXT\_CONST~"hello"}\\ +{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~NUM\_CONST~6}\\ +{\mdcolor{gray}@}{\mdcolor{gray}MixedExprList}{\mdcolor{maroon}{}[1,TEXT\_CONST,true,1==2,5+NUM\_CONST]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1144} +\noindent\mdline{1144}The generated P4Info will contain:%mdk + +%mdk-data-line={1146} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1147} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedExprList}{\mdcolor{maroon}"}\\ +~~expression\_list~\{\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}1}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}hello}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~true\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~false\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}11}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1169} +\noindent\mdline{1169}\textbf{kvList of Mixed Expressions}\mdline{1169}%mdk + +%mdk-data-line={1171} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1172} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}MixedKV}{\mdcolor{maroon}{}[label="text",~my\_bool=true,~int\_val=2*3]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1178} +\noindent\mdline{1178}The generated P4Info will contain:%mdk + +%mdk-data-line={1180} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1181} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedKV}{\mdcolor{maroon}"}\\ +~~kv\_pair\_list~\{\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}label}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}text}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}my\_bool}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~bool\_value:~true\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}int\_val}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~int64\_value:~{\mdcolor{purple}6}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1206} +\subsubsection{\mdline{1206}6.1.5.\hspace*{0.5em}\mdline{1206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1206} Message}\label{sec-sourcelocation-message}%mdk%mdk + +%mdk-data-line={1208} +\noindent\mdline{1208}A source location describes a location within a \mdline{1208}\emph{.p4}\mdline{1208}-source file. The +\mdline{1209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1209} message is defined in p4types.proto as follows:%mdk + +%mdk-data-line={1211} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1212} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Location~of~code~relative~to~a~given~source~file.}\\ +{\bfseries{\mdcolor{navy}message}}~SourceLocation~\{\\ +~~{\mdcolor{darkgreen}//~Path~to~the~source~file~(absolute~or~relative~to~the~working~directory).}\\ +~~{\bfseries{\mdcolor{navy}string}}~file~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Line~and~column~numbers~within~the~source~file,~1-based.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~line~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}int32}}~column~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1222} +\noindent\mdline{1222}We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations.%mdk + +%mdk-data-line={1227} +\mdline{1227}The \mdline{1227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1227} message associated with an annotation holds the location of +the \mdline{1228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@}}}\mdline{1228} symbol introducing the annotation in the P4 source code; the message can +be found in the following place:%mdk + +%mdk-data-line={1231} +\begin{itemize}%mdk + +%mdk-data-line={1231} +\item{} +%mdk-data-line={1231} +\mdline{1231}For \mdline{1231}\textbf{unstructured annotations}\mdline{1231}, every message containing a field +\mdline{1232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1232} also contains a field +\mdline{1233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~SourceLocation~annotation\_locations}}}\mdline{1233}. The field must either be empty + or match the size of \mdline{1234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1234}. In the latter case, the i-th member of +\mdline{1235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation\_locations}}}\mdline{1235} is the source location of the i-th member of +\mdline{1236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1236}.%mdk%mdk + +%mdk-data-line={1238} +\item{} +%mdk-data-line={1238} +\mdline{1238}For \mdline{1238}\textbf{structured annotations}\mdline{1238}, every \mdline{1238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1238} message contains +an optional field \mdline{1239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation~source\_location}}}\mdline{1239} holding its source +location, if present.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1243} +\subsection{\mdline{1243}6.2.\hspace*{0.5em}\mdline{1243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1243} Message}\label{sec-pkginfo-message}%mdk%mdk + +%mdk-data-line={1245} +\noindent\mdline{1245}The \mdline{1245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1245} message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. \mdline{1246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1246} can be extracted +and used to facilitate \mdline{1247}\textquotedblleft{}browsing\textquotedblright{}\mdline{1247} of available P4 programs from a +library. Although all fields are technically \mdline{1248}\textquotedblleft{}optional,\textquotedblright{}\mdline{1248} every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included.%mdk + +%mdk-data-line={1252} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1253} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Can~be~used~to~manage~multiple~P4~packages.}\\ +{\bfseries{\mdcolor{navy}message}}~PkgInfo~\{\\ +~~{\mdcolor{darkgreen}//~a~definitive~name~for~this~configuration,~e.g.~switch.p4\_v1.0}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~configuration~version,~free-format~string}\\ +~~{\bfseries{\mdcolor{navy}string}}~version~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~brief~and~detailed~descriptions}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~free-form;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~the~target~architecture,~e.g.~"psa"}\\ +~~{\bfseries{\mdcolor{navy}string}}~arch~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\mdcolor{darkgreen}//~organization~which~produced~the~configuration,~e.g.~"p4.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~organization~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~{\mdcolor{darkgreen}//~contact~info~for~support,e.g.~"tech-support@acme.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~contact~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~url~for~more~information,~e.g.~"http://support.p4.org/ref/p4/switch.p4\_v1.0"}\\ +~~{\bfseries{\mdcolor{navy}string}}~url~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}8};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~structured;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}9};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1276} +\subsubsection{\mdline{1276}6.2.1.\hspace*{0.5em}\mdline{1276}Annotating P4 code with PkgInfo}\label{sec-annotating-p4-code-with-pkginfo}%mdk%mdk + +%mdk-data-line={1278} +\noindent\mdline{1278}A P4 progam\mdline{1278}'\mdline{1278}s \mdline{1278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1278} may be declared using one or more of the following +annotations, attached to the \mdline{1279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1279} block only:%mdk + +%mdk-data-line={1281} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1282} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value{}[,key=value,...])}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("A~brief~description")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("A~longer\textbackslash{}}\\ +description{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@custom\_annotation(...)}\\ +{\mdcolor{maroon}@another\_custom\_annotation(...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1291} +\noindent\mdline{1291}Above we see several different types of annotations:%mdk + +%mdk-data-line={1293} +\begin{itemize}%mdk + +%mdk-data-line={1293} +\item{} +%mdk-data-line={1293} +\mdline{1293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1293} \mdline{1293}- This is used to populate a specific field within the \mdline{1293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1293} +message. Multiple \mdline{1294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1294} annotations are allowed. For compactness, +multiple key-value pairs can appear in a single \mdline{1295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1295} annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The \mdline{1297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{1297}s must be from +among the message fields inside \mdline{1298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1298}, for example, \mdline{1298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1298}, \mdline{1298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}version}}}\mdline{1298}, +etc. Each key-value pair assigns a value to the corresponding field inside the +single \mdline{1300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1300} message for the program\mdline{1300}'\mdline{1300}s P4Info. One exception is that the +\mdline{1301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1301} field of \mdline{1301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1301} must be expressed as individual +\mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1302} and \mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1302} annotations, see next bullets. The key \mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}arch}}}\mdline{1302} will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself.%mdk%mdk + +%mdk-data-line={1306} +\item{} +%mdk-data-line={1306} +\mdline{1306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1306} \mdline{1306}- This will populate the \mdline{1306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.brief}}}\mdline{1306} message field.%mdk%mdk + +%mdk-data-line={1308} +\item{} +%mdk-data-line={1308} +\mdline{1308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1308} \mdline{1308}- This will populate the \mdline{1308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.description}}}\mdline{1308} message +field%mdk%mdk + +%mdk-data-line={1311} +\item{} +%mdk-data-line={1311} +\mdline{1311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@\textless{}anything~else\textgreater{}}}}\mdline{1311} \mdline{1311}- This will create a \mdline{1311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotation}}}\mdline{1311} entry%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1313} +\noindent\mdline{1313}Declaring one or more of these annotations on \mdline{1313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1313} will +generate a single corresponding \mdline{1314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1314} message in the P4Info as described in +\mdline{1315}\mdref{sec-pkginfo-message}{PkgInfo Message}\mdline{1315}.%mdk + +%mdk-data-line={1317} +\mdline{1317}The following example shows \mdline{1317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1317} annotations using a mixture of single and +multiple key-value pairs. It also shows \mdline{1318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1318} and \mdline{1318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1318} annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the \mdline{1320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1320} message. The custom annotations will +be appended to the \mdline{1321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotations}}}\mdline{1321} list.%mdk + +%mdk-data-line={1323} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1324} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(name="switch.p4",version="2")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(organization="p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(contact="info@p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(url="www.p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("L2/L3~switch")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("L2/L3~switch.\textbackslash{}}\\ +Built~for~data-center~profile.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@my\_annotation1(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}@my\_annotation2(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}PSA\_Switch(IgPipeline,~PacketReplicationEngine(),~EgPipeline,}\\ +{\mdcolor{maroon}~~~~~~~~~~~BufferingQueueingEngine())~main;}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1337} +\subsection{\mdline{1337}6.3.\hspace*{0.5em}\mdline{1337}ID Allocation for P4Info Objects}\label{sec-id-allocation}%mdk%mdk + +%mdk-data-line={1339} +\noindent\mdline{1339}P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(\mdline{1343}e.g.\mdline{1343} table, action, counter, \mdline{1343}\dots{}\mdline{1343}). The most significant 8 bits of the ID +encodes the object type (as per Table\mdline{1344}~\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}}\mdline{1344}). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (\mdline{1346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.P4Ids.Prefix}}}\mdline{1346}). These values must +be used (\mdline{1347}e.g.\mdline{1347} by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table\mdline{1349}~\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}}\mdline{1349} shows the ID +layout.%mdk + +%mdk-data-line={1352} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1354} 8-bit prefix value}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1354} P4 object type}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{1356} 0x00}&\multicolumn{1}{|l|}{\mdline{1356} Reserved (unspecified)}\\ +\multicolumn{1}{|l}{\mdline{1357} 0x01}&\multicolumn{1}{|l|}{\mdline{1357} Action}\\ +\multicolumn{1}{|l}{\mdline{1358} 0x02}&\multicolumn{1}{|l|}{\mdline{1358} Table}\\ +\multicolumn{1}{|l}{\mdline{1359} 0x03}&\multicolumn{1}{|l|}{\mdline{1359} Value-set}\\ +\multicolumn{1}{|l}{\mdline{1360} 0x04}&\multicolumn{1}{|l|}{\mdline{1360} Controller header (header type with \mdline{1360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1360} annotation)}\\ +\multicolumn{1}{|l}{\mdline{1361} 0x05\mdline{1361}\dots{}\mdline{1361}0x0f}&\multicolumn{1}{|l|}{\mdline{1361} Reserved (for future P4 built-in objects)}\\ +\multicolumn{1}{|l}{\mdline{1362} 0x10}&\multicolumn{1}{|l|}{\mdline{1362} Reserved (start of PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1363} 0x11}&\multicolumn{1}{|l|}{\mdline{1363} PSA Action profiles / selectors}\\ +\multicolumn{1}{|l}{\mdline{1364} 0x12}&\multicolumn{1}{|l|}{\mdline{1364} PSA Counter}\\ +\multicolumn{1}{|l}{\mdline{1365} 0x13}&\multicolumn{1}{|l|}{\mdline{1365} PSA Direct counter}\\ +\multicolumn{1}{|l}{\mdline{1366} 0x14}&\multicolumn{1}{|l|}{\mdline{1366} PSA Meter}\\ +\multicolumn{1}{|l}{\mdline{1367} 0x15}&\multicolumn{1}{|l|}{\mdline{1367} PSA Direct meter}\\ +\multicolumn{1}{|l}{\mdline{1368} 0x16}&\multicolumn{1}{|l|}{\mdline{1368} PSA Register}\\ +\multicolumn{1}{|l}{\mdline{1369} 0x17}&\multicolumn{1}{|l|}{\mdline{1369} PSA Digest}\\ +\multicolumn{1}{|l}{\mdline{1370} 0x18\mdline{1370}\dots{}\mdline{1370}0x7f}&\multicolumn{1}{|l|}{\mdline{1370} Reserved (for future PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1371} 0x80}&\multicolumn{1}{|l|}{\mdline{1371} Reserved (start of vendor-specific extern types)}\\ +\multicolumn{1}{|l}{\mdline{1372} 0x81\mdline{1372}\dots{}\mdline{1372}0xfe}&\multicolumn{1}{|l|}{\mdline{1372} Vendor-specific extern types}\\ +\multicolumn{1}{|l}{\mdline{1373} 0xff}&\multicolumn{1}{|l|}{\mdline{1373} Reserved (max prefix value)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1375} +\mdhr{}%mdk + +%mdk-data-line={1376} +\noindent\mdline{1376}\mdcaption{\textbf{Table~\mdcaptionlabel{1}.}~\mdcaptiontext{Mapping of P4Info object type to 8-bit ID prefix value}}%mdk +%mdk +\end{mdcenter}\label{tab-mapping-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1379} +\begin{table}[h!]%mdk +\begin{mdblock}{text-align=center,breakable=true}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{cc}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1381} MSB bit 31 \mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}.. bit 24}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1381} bit 23 \mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}.. bit 0 LSB}}\\ + +\midrule +\multicolumn{1}{|c}{\mdline{1383} Object type prefix}&\multicolumn{1}{|c|}{\mdline{1383} Generated suffix (\mdline{1383}e.g.\mdline{1383} by the compiler)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1385} +\mdhr{}%mdk + +%mdk-data-line={1386} +\noindent\mdline{1386}\mdcaption{\textbf{Table~\mdcaptionlabel{2}.}~\mdcaptiontext{Format of P4Info object IDs}}%mdk%mdk +\end{mdblock}\label{tab-format-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1390} +\mdline{1390}It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with \mdline{1391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1391} (see Table +\mdline{1392}\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}}\mdline{1392}). The compiler must honor the \mdline{1392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1392} annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (\mdline{1394}i.e.\mdline{1394} if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same \mdline{1396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1396} value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct.%mdk + +%mdk-data-line={1405} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth-7cm)/1}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{\mdinline{width=7cm}{{\bfseries\mdline{1407} P4 declaration(s)}}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1407} Compiler-allocated ID(s)}}\\ + +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1409} \mdline{1409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1409}}}&\multicolumn{1}{|l|}{\mdline{1409} 0x0212ab34}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1411} \mdline{1411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1411}}}&\multicolumn{1}{|l|}{\mdline{1411} \mdline{1411}\textbf{Error}\mdline{1411}(same ID suffixes for 2 objects of the same type)}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1412} \mdline{1412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tB...}}}\mdline{1412}}}&\multicolumn{1}{|l|}{\mdline{1412}}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1414} \mdline{1414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1414}}}&\multicolumn{1}{|l|}{\mdline{1414} 0x0212ab34}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1415} \mdline{1415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~action~act1...}}}\mdline{1415}}}&\multicolumn{1}{|l|}{\mdline{1415} 0x0112ab34}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1417} +\mdhr{}%mdk + +%mdk-data-line={1418} +\noindent\mdline{1418}\mdcaption{\textbf{Table~\mdcaptionlabel{3}.}~\mdcaptiontext{Example of statically-assigned P4Info object IDs}}%mdk +%mdk +\end{mdcenter}\label{tab-exmpl-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1421} +\mdline{1421}The \mdline{1421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1421} annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively).%mdk + +%mdk-data-line={1427} +\subsection{\mdline{1427}6.4.\hspace*{0.5em}\mdline{1427}P4Info Objects}\label{sec-p4info-objects}%mdk%mdk + +%mdk-data-line={1429} +\subsubsection{\mdline{1429}6.4.1.\hspace*{0.5em}\mdline{1429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}\label{sec-table}%mdk%mdk + +%mdk-data-line={1431} +\noindent\mdline{1431}Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields:%mdk + +%mdk-data-line={1434} +\begin{itemize}%mdk + +%mdk-data-line={1434} +\item{} +%mdk-data-line={1434} +\mdline{1434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1434}, a \mdline{1434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1434} message with the ID, name, and alias of this table.%mdk%mdk + +%mdk-data-line={1436} +\item{} +%mdk-data-line={1436} +\mdline{1436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1436}, a repeated field of type \mdline{1436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1436} representing the data to +be used to construct the lookup key matched in this table. Each \mdline{1437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1437} +message is defined with the following fields:%mdk + +%mdk-data-line={1440} +\begin{itemize}%mdk + +%mdk-data-line={1440} +\item{} +%mdk-data-line={1440} +\mdline{1440}id, the \mdline{1440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1440} identifier of this \mdline{1440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1440}, unique in the scope of +this table. No rules are prescribed on the way \mdline{1441}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1441} IDs should be +allocated, as long as two \mdline{1442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1442} of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the \mdline{1446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1446} annotation, or let the compiler +choose them.%mdk%mdk + +%mdk-data-line={1449} +\item{} +%mdk-data-line={1449} +\mdline{1449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1449}, the string representing the name of this \mdline{1449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1449}.%mdk%mdk + +%mdk-data-line={1451} +\item{} +%mdk-data-line={1451} +\mdline{1451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1451}, a repeated field of strings, each one representing a P4 +annotation associated to this match field.%mdk%mdk + +%mdk-data-line={1454} +\item{} +%mdk-data-line={1454} +\mdline{1454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1454}, an \mdline{1454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1454} value set to the size in bits of this match field.%mdk%mdk + +%mdk-data-line={1456} +\item{} +%mdk-data-line={1456} +\mdline{1456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1456}, a \mdline{1456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{1456} describing the match behavior for this field; it can be +either:%mdk + +%mdk-data-line={1458} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1458} +\item\mdline{1458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1458}, an enum field of type \mdline{1458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchType}}}\mdline{1458}, which includes all +possible PSA match kinds.%mdk + +%mdk-data-line={1460} +\item\mdline{1460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_match\_type}}}\mdline{1460}, a string field which can be used to encode any +architecture-specific match type.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1463} +\item{} +%mdk-data-line={1463} +\mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1463}, a \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1463} message describing this match field.%mdk%mdk + +%mdk-data-line={1465} +\item{} +%mdk-data-line={1465} +\mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1465}, which indicates whether the match field has a\mdline{1465}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1466}; this is useful for +\mdline{1467}\mdref{sec-psa-metadata-translation}{translation}\mdline{1467}.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1469} +\item{} +%mdk-data-line={1469} +\mdline{1469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_refs}}}\mdline{1469}, a repeated \mdline{1469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1469} field representing the set of possible +actions for this table. The \mdline{1470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1470} message is used to reference an action +specified in the same P4Info message and it includes the following fields:%mdk + +%mdk-data-line={1472} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1472} +\item\mdline{1472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1472}, the \mdline{1472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1472} identifier of the action.%mdk + +%mdk-data-line={1473} +\item\mdline{1473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1473}, an enum value which can take one of three values: + \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1474}, \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1474} and \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1474}. The \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1474} of the + action is determined by the use of the P4 standard annotations + \mdline{1476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1476} and \mdline{1476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1476}~[\mdcite{p4actionannotations}{18}]\mdline{1476}. \mdline{1476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1476} + (\mdline{1477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1477} annotation) means that the action can only appear within + the table, and never as the default action. \mdline{1478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1478} + (\mdline{1479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1479} annotation) means that the action can only be used as the + default action. \mdline{1480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1480} is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action.%mdk + +%mdk-data-line={1483} +\item\mdline{1483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1483}, a repeated string field, each one representing a P4 +annotation associated to the action \mdline{1484}\emph{reference}\mdline{1484} in this table.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1486} +\item{} +%mdk-data-line={1486} +\mdline{1486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\_default\_action\_id}}}\mdline{1486}, if this table has a constant default action, this +field will carry the \mdline{1487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1487} identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action\mdline{1490}'\mdline{1490}s +arguments.%mdk%mdk + +%mdk-data-line={1493} +\item{} +%mdk-data-line={1493} +\mdline{1493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation\_id}}}\mdline{1493}, the \mdline{1493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1493} identifier of the \mdline{1493}\textquotedblleft{}implementation\textquotedblright{}\mdline{1493} of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (\mdline{1496}e.g.\mdline{1496} a PSA \mdline{1496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1496} or \mdline{1496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{1496} +instance). The table is then referred to as an indirect match table.%mdk%mdk + +%mdk-data-line={1499} +\item{} +%mdk-data-line={1499} +\mdline{1499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_resource\_ids}}}\mdline{1499}, repeated \mdline{1499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1499} identifiers for all the direct +resources attached to this table, such as \mdline{1500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1500} and \mdline{1500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1500} +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2.%mdk%mdk + +%mdk-data-line={1506} +\item{} +%mdk-data-line={1506} +\mdline{1506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1506}, an \mdline{1506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1506} describing the desired number of table entries that the +target should support for the table. See the \mdline{1507}\textquotedblleft{}Size\textquotedblright{}\mdline{1507} subsection within the +\mdline{1508}\textquotedblleft{}Table Properties\textquotedblright{}\mdline{1508} section of the P4\mdline{1508}\mdsub{16}\mdline{1508} language specification for details +\mdline{1509}[\mdcite{p4tableproperties}{30}]\mdline{1509}.%mdk%mdk + +%mdk-data-line={1511} +\item{} +%mdk-data-line={1511} +\mdline{1511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_behavior}}}\mdline{1511}, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +\mdline{1513}\mdref{sec-idle-timeout}{Idle-Timeout}\mdline{1513} section). Value can be any of the +\mdline{1514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutBehavior}}}\mdline{1514} enum:%mdk + +%mdk-data-line={1515} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1515} +\item\mdline{1515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NO\_TIMEOUT}}}\mdline{1515} (default value), which means that idle timeout is not +supported for this table.%mdk + +%mdk-data-line={1517} +\item\mdline{1517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOTIFY\_CONTROL}}}\mdline{1517}, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +\mdline{1519}\mdref{sec-table-idle-timeout-notification}{Table Idle Timeout Notifications}\mdline{1519}).%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1521} +\item{} +%mdk-data-line={1521} +\mdline{1521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{1521}, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime.%mdk%mdk + +%mdk-data-line={1524} +\item{} +%mdk-data-line={1524} +\mdline{1524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{1524}, an \mdline{1524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1524} Protobuf message\mdline{1524}~[\mdcite{protoany}{31}]\mdline{1524} to embed +architecture-specific table properties\mdline{1525}~[\mdcite{p4tableproperties}{30}]\mdline{1525} which are not part +of the core P4 language or of the PSA architecture.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1528} +\subsubsection{\mdline{1528}6.4.2.\hspace*{0.5em}\mdline{1528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}\label{sec-action}%mdk%mdk + +%mdk-data-line={1530} +\noindent\mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1530} messages are used to specify all possible actions of all match-action +tables.%mdk + +%mdk-data-line={1533} +\mdline{1533}The \mdline{1533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1533} message defines the following fields:%mdk + +%mdk-data-line={1535} +\begin{itemize}%mdk + +%mdk-data-line={1535} +\item{} +%mdk-data-line={1535} +\mdline{1535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1535}, a \mdline{1535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1535} message with the ID, name, and alias of this action%mdk%mdk + +%mdk-data-line={1537} +\item{} +%mdk-data-line={1537} +\mdline{1537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{1537}, a repeated field of \mdline{1537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1537} messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each \mdline{1539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1539} message contains the +following fields:%mdk + +%mdk-data-line={1541} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1541} +\item\mdline{1541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1541}, the \mdline{1541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1541} identifier of this parameter. No rules are prescribed +on the way \mdline{1542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1542} IDs should be allocated, as long as two \mdline{1542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1542} of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the \mdline{1546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1546} +annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1548} +\item\mdline{1548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1548}, the string representing the name of this parameter.%mdk + +%mdk-data-line={1549} +\item\mdline{1549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1549}, a repeated field of strings, each one representing a P4 +annotation associated to this parameter.%mdk + +%mdk-data-line={1551} +\item\mdline{1551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1551}, an \mdline{1551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1551} value set to the size in bits of this parameter.%mdk + +%mdk-data-line={1552} +\item\mdline{1552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1552}, which describes this parameter using a \mdline{1552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1552} message.%mdk + +%mdk-data-line={1553} +\item\mdline{1553}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1553}, which indicates whether the action parameter has a +\mdline{1554}\mdref{sec-user-defined-types}{user-defined type}\mdline{1554}; this is useful for +\mdline{1555}\mdref{sec-psa-metadata-translation}{translation}\mdline{1555}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1557} +\subsubsection{\mdline{1557}6.4.3.\hspace*{0.5em}\mdline{1557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}\label{sec-p4info-action-profile}%mdk%mdk + +%mdk-data-line={1559} +\noindent\mdline{1559}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1559} messages are used to specify all available instances of Action +Profile and Action Selector PSA externs.%mdk + +%mdk-data-line={1562} +\mdline{1562}PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile \mdline{1566}\emph{member}\mdline{1566}, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime.%mdk + +%mdk-data-line={1570} +\mdline{1570}PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into \mdline{1571}\emph{groups}\mdline{1571}. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime.%mdk + +%mdk-data-line={1580} +\mdline{1580}While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same \mdline{1581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1581} message to describe both.%mdk + +%mdk-data-line={1583} +\mdline{1583}The \mdline{1583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1583} message includes the following fields:%mdk + +%mdk-data-line={1585} +\begin{itemize}%mdk + +%mdk-data-line={1585} +\item{} +%mdk-data-line={1585} +\mdline{1585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1585}, a \mdline{1585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1585} message with the ID, name, and alias of this Action +Profile or Selector.%mdk%mdk + +%mdk-data-line={1588} +\item{} +%mdk-data-line={1588} +\mdline{1588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_ids}}}\mdline{1588}, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector.%mdk%mdk + +%mdk-data-line={1591} +\item{} +%mdk-data-line={1591} +\mdline{1591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}with\_selector}}}\mdline{1591}, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern.%mdk%mdk + +%mdk-data-line={1594} +\item{} +%mdk-data-line={1594} +\mdline{1594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1594}, an \mdline{1594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1594} representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups.%mdk%mdk + +%mdk-data-line={1598} +\item{} +%mdk-data-line={1598} +\mdline{1598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1598}, an \mdline{1598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1598} which is 0 for an Action Profile, or, for an +Action Selector, represents the maximum sum of all member weights within any +given selector group. The \mdline{1600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1600} must be no larger than \mdline{1600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1600}. PSA +programs can use the \mdline{1601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{1601} annotation to provide this value for +Action Selectors. If the annotation is omitted, the P4Info field will default +to 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1605} +\subsubsection{\mdline{1605}6.4.4.\hspace*{0.5em}\mdline{1605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1605} \mdline{1605}\&\mdline{1605} \mdline{1605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}\label{sec-counter-directcounter}%mdk%mdk + +%mdk-data-line={1607} +\noindent\mdline{1607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1607} and \mdline{1607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1607} messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is:%mdk + +%mdk-data-line={1613} +\begin{itemize}%mdk + +%mdk-data-line={1613} +\item{} +%mdk-data-line={1613} +\mdline{1613}Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index.%mdk%mdk + +%mdk-data-line={1617} +\item{} +%mdk-data-line={1617} +\mdline{1617}Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1620} +\noindent\mdline{1620}Both \mdline{1620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1620} and \mdline{1620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1620} messages share the following fields:%mdk + +%mdk-data-line={1622} +\begin{itemize}%mdk + +%mdk-data-line={1622} +\item{} +%mdk-data-line={1622} +\mdline{1622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1622}, a \mdline{1622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1622} message with the ID, name, and alias of this counter +extern instance.%mdk%mdk + +%mdk-data-line={1625} +\item{} +%mdk-data-line={1625} +\mdline{1625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1625}, a message of of type \mdline{1625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1625} used to describe the compile-time +configuration of this counter. Currently, the \mdline{1626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1626} message is used to +carry only the counter unit, which can be any of the \mdline{1627}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec.Unit}}}\mdline{1627} enum +values:%mdk + +%mdk-data-line={1629} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1629} +\item\mdline{1629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1629}: reserved value.%mdk + +%mdk-data-line={1630} +\item\mdline{1630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1630}: byte counter.%mdk + +%mdk-data-line={1631} +\item\mdline{1631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1631}: packet counter.%mdk + +%mdk-data-line={1632} +\item\mdline{1632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BOTH}}}\mdline{1632}: combination of both byte and packet counter.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1634} +\noindent\mdline{1634}For indexed counters, the \mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1634} message contains also a \mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1634} field, an +\mdline{1635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1635} representing the maximum number of independent values that can be held +by this counter array. Conversely, the \mdline{1636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1636} message contains a +\mdline{1637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1637} field that carries the \mdline{1637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}unit32}}}\mdline{1637} identifier of the table to +which this direct counter is attached.%mdk + +%mdk-data-line={1640} +\mdline{1640}For indexed counters, the \mdline{1640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1640} message contains also an \mdline{1640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1640} +field, which indicates whether the index has a\mdline{1641}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1642}. This is useful for +\mdline{1643}\mdref{sec-psa-metadata-translation}{translation}\mdline{1643}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1644}).%mdk + +%mdk-data-line={1646} +\subsubsection{\mdline{1646}6.4.5.\hspace*{0.5em}\mdline{1646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1646} \mdline{1646}\&\mdline{1646} \mdline{1646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}\label{sec-meter-directmeter}%mdk%mdk + +%mdk-data-line={1648} +\noindent\mdline{1648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1648} and \mdline{1648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1648} messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is:%mdk + +%mdk-data-line={1654} +\begin{itemize}%mdk + +%mdk-data-line={1654} +\item{} +%mdk-data-line={1654} +\mdline{1654}Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +\mdline{1656}e.g.\mdline{1656} to set the rate threshold.%mdk%mdk + +%mdk-data-line={1658} +\item{} +%mdk-data-line={1658} +\mdline{1658}Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1661} +\noindent\mdline{1661}Both \mdline{1661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1661} and \mdline{1661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1661} messages share the following fields:%mdk + +%mdk-data-line={1663} +\begin{itemize}%mdk + +%mdk-data-line={1663} +\item{} +%mdk-data-line={1663} +\mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1663}, a \mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1663} message with the ID, name, and alias of this meter +extern instance.%mdk%mdk + +%mdk-data-line={1666} +\item{} +%mdk-data-line={1666} +\mdline{1666}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1666}, a message of type \mdline{1666}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1666} used to describe the capabilities of +this meter extern instance. Currently, the \mdline{1667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1667} message is used to +carry only the meter unit, which can be any of the \mdline{1668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Unit}}}\mdline{1668} enum +values:%mdk + +%mdk-data-line={1670} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1670} +\item\mdline{1670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1670}: reserved value.%mdk + +%mdk-data-line={1671} +\item\mdline{1671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1671}, which signifies that this meter can be configured with rates +expressed in bytes/second.%mdk + +%mdk-data-line={1673} +\item\mdline{1673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1673}, for rates expressed in packets/second.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1675} +\noindent\mdline{1675}For indexed meters, the \mdline{1675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1675} message contains also a \mdline{1675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1675} field, an \mdline{1675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1675} +representing the maximum number of independent cells that can be held by this +meter. Conversely, the \mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1677} message contains a \mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1677} field +that carries the \mdline{1678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1678} identifier of the table to which this direct meter is +attached.%mdk + +%mdk-data-line={1681} +\mdline{1681}For indexed meters, the \mdline{1681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1681} message contains also an \mdline{1681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1681} +field, which indicates whether the index has a\mdline{1682}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1683}. This is useful for +\mdline{1684}\mdref{sec-psa-metadata-translation}{translation}\mdline{1684}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1685}).%mdk + +%mdk-data-line={1687} +\subsubsection{\mdline{1687}6.4.6.\hspace*{0.5em}\mdline{1687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\label{sec-controller-packet-meta}%mdk%mdk + +%mdk-data-line={1689} +\noindent\mdline{1689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1689} messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server.%mdk + +%mdk-data-line={1695} +\mdline{1695}When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet.%mdk + +%mdk-data-line={1701} +\mdline{1701}Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +\mdline{1703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_in")}}}\mdline{1703} and \mdline{1703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_out")}}}\mdline{1703}, +respectively. \mdline{1704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1704} messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages).%mdk + +%mdk-data-line={1709} +\mdline{1709}A P4Info message can contain at most two \mdline{1709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata~messages}}}\mdline{1709}, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields:%mdk + +%mdk-data-line={1713} +\begin{itemize}%mdk + +%mdk-data-line={1713} +\item{} +%mdk-data-line={1713} +\mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1713}, a \mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1713} message where \mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble.name}}}\mdline{1713} is set to \mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_in"}}}\mdline{1713} +and \mdline{1714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_out"}}}\mdline{1714} for packet-in and packet-out metadata, respectively.%mdk%mdk + +%mdk-data-line={1716} +\item{} +%mdk-data-line={1716} +\mdline{1716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{1716}, a repeated field of type \mdline{1716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1716}, where each \mdline{1716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1716} message +includes the following fields:%mdk + +%mdk-data-line={1718} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1718} +\item\mdline{1718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1718}, a \mdline{1718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1718} identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two \mdline{1719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1719} of the +same \mdline{1720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1720} message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the \mdline{1724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1724} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1725} +\item\mdline{1725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1725}, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below).%mdk + +%mdk-data-line={1729} +\item\mdline{1729}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1729}, a repeated field of strings, each one representing a P4 +annotation associated to this metadata.%mdk + +%mdk-data-line={1731} +\item\mdline{1731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1731}, an \mdline{1731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1731} representing the size in bits of this metadata.%mdk + +%mdk-data-line={1732} +\item\mdline{1732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1732}, which indicates whether the metadata field has a +\mdline{1733}\mdref{sec-user-defined-types}{user-defined type}\mdline{1733}; this is useful for +\mdline{1734}\mdref{sec-psa-metadata-translation}{translation}\mdline{1734}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1736} +\noindent\mdline{1736}As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding \mdline{1737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1737} +messages.%mdk + +%mdk-data-line={1740} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1741} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~egress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~port~where~the~packet}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~should~be~sent~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~queue\_id;~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~queue~ID~}{\mdcolor{darkgreen}*/}\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~ingress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~data~plane~port~ID~where}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~the~original~packet~was~received~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}1}\textgreater{}~is\_clone;~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~1~if~this~is~a~clone~of~the}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~original~packet~}{\mdcolor{darkgreen}*/}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1756} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1757} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868916615}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_out}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_out}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}egress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}queue\_id}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~\}\\ +\}\\ +\\ +controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868941301}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_in}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_in}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ingress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}is\_clone}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}1}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1794} +\noindent\mdline{1794}Note that the use of \mdline{1794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1794} is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages.%mdk + +%mdk-data-line={1800} +\subsubsection{\mdline{1800}6.4.7.\hspace*{0.5em}\mdline{1800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}\label{sec-valueset}%mdk%mdk + +%mdk-data-line={1802} +\noindent\mdline{1802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1802} messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P4\mdline{1805}\mdsub{16}\mdline{1805} +specification\mdline{1806}~[\mdcite{p4valuesets}{39}]\mdline{1806}.%mdk + +%mdk-data-line={1808} +\mdline{1808}The \mdline{1808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1808} message defines the following fields:%mdk + +%mdk-data-line={1810} +\begin{itemize}%mdk + +%mdk-data-line={1810} +\item{} +%mdk-data-line={1810} +\mdline{1810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1810}, a \mdline{1810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1810} message with the ID, name, and alias of this Value +Set.%mdk%mdk + +%mdk-data-line={1813} +\item{} +%mdk-data-line={1813} +\mdline{1813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1813}, a repeated field of \mdline{1813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1813} messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the \mdline{1816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1816} repeated field in the +\mdline{1817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{1817} message.%mdk%mdk + +%mdk-data-line={1819} +\item{} +%mdk-data-line={1819} +\mdline{1819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1819}, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +\mdline{1821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set}}}\mdline{1821} constructor call.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1823} +\noindent\mdline{1823}According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of \mdline{1826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1826}, +\mdline{1827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1827}, or \mdline{1827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1827}~[\mdcite{p4selectexpr}{26}]\mdline{1827}. The rest of this section looks at all 3 of +these cases and gives an example \mdline{1828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1828} message when appropriate.%mdk + +%mdk-data-line={1830} +\begin{enumerate}%mdk + +%mdk-data-line={1830} +\item{} +%mdk-data-line={1830} +\mdline{1830}If the type parameter is \mdline{1830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1830}, \mdline{1830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1830} will include exactly one +\mdline{1831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1831} message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used):%mdk + +%mdk-data-line={1834} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1834} +\item\mdline{1834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1834}: set to 1%mdk + +%mdk-data-line={1835} +\item\mdline{1835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1835}: set to the value of \mdline{1835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1835}%mdk + +%mdk-data-line={1836} +\item\mdline{1836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1836}: set to \mdline{1836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1836}%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1838} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1839} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}bit\textless{}8\textgreater{}~\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(hdr.f8)~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1842} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1843} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1857} +\begin{enumerate}[,start=2]%mdk + +%mdk-data-line={1857} +\item{} +%mdk-data-line={1857} +\mdline{1857}If the type parameter is a \mdline{1857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1857}, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program.%mdk%mdk + +%mdk-data-line={1862} +\item{} +%mdk-data-line={1862} +\mdline{1862}If the type parameter is a \mdline{1862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1862}, this version of P4Runtime requires that +all the fields of the struct be of type \mdline{1863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1863} (where \mdline{1863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1863} can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +\mdline{1866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1866} field will include one \mdline{1866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1866} message for each field in the +struct, with the following fields:%mdk + +%mdk-data-line={1869} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1869} +\item\mdline{1869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1869}: must be unique with respect to the other \mdline{1869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1869} entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +\mdline{1873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1873} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1874} +\item\mdline{1874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1874}: set to the name of the corresponding struct field.%mdk + +%mdk-data-line={1875} +\item\mdline{1875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1875}: set to the list of P4 annotations associated with the struct +field, except for the \mdline{1876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1876} annotation, if present (see the \mdline{1876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1876} field +below).%mdk + +%mdk-data-line={1878} +\item\mdline{1878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1878}: set to the value of \mdline{1878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1878} for the corresponding struct field.%mdk + +%mdk-data-line={1879} +\item\mdline{1879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1879}, which indicates whether the struct field has a\mdline{1879}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1880}; this is useful for +\mdline{1881}\mdref{sec-psa-metadata-translation}{translation}\mdline{1881}.%mdk + +%mdk-data-line={1882} +\item\mdline{1882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1882}: by default \mdline{1882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1882} is set to \mdline{1882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1882}; the P4 programmer can +specify a different match type by using the \mdline{1883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1883} annotation +\mdline{1884}[\mdcite{p4selectexpr}{26}]\mdline{1884}.%mdk + +%mdk-data-line={1885} +\item\mdline{1885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1885}: documentation associated with the struct field.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1887} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1888} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~bit\textless{}8\textgreater{}~f8;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(2)~@match(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(3)~@match(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1896} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1897} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1924} +\noindent\mdline{1924}In the above example, the \mdline{1924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1924} annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs.%mdk + +%mdk-data-line={1927} +\mdline{1927}Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a\mdline{1928}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1929} that resolves to a \mdline{1929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1929}, or a \mdline{1929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1929} where +one or more fields is a\mdline{1930}~\mdref{sec-user-defined-types}{user-defined type}\mdline{1930} that +resolves to a \mdline{1931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1931}. For each \mdline{1931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1931} that corresponds to a user-defined +type, the \mdline{1932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1932} field must be set to the appropriate value (\mdline{1932}i.e.\mdline{1932} the name +of the type).%mdk + +%mdk-data-line={1935} +\subsubsection{\mdline{1935}6.4.8.\hspace*{0.5em}\mdline{1935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}\label{sec-register}%mdk%mdk + +%mdk-data-line={1937} +\noindent\mdline{1937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1937} messages are used to specify all possible instances of Register PSA +externs.%mdk + +%mdk-data-line={1940} +\mdline{1940}Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime.%mdk + +%mdk-data-line={1944} +\mdline{1944}The \mdline{1944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1944} message defines the following fields:%mdk + +%mdk-data-line={1946} +\begin{itemize}%mdk + +%mdk-data-line={1946} +\item{} +%mdk-data-line={1946} +\mdline{1946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1946}, a \mdline{1946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1946} message with the ID, name, and alias of this register +instance.%mdk%mdk + +%mdk-data-line={1949} +\item{} +%mdk-data-line={1949} +\mdline{1949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1949}, which specifies the data type stored by this register, expressed +using a \mdline{1950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1950} message (see section on\mdline{1950}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary +P4 Types}\mdline{1951}).%mdk%mdk + +%mdk-data-line={1953} +\item{} +%mdk-data-line={1953} +\mdline{1953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1953}, an \mdline{1953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1953} value representing the total number of independent register +cells available.%mdk%mdk + +%mdk-data-line={1956} +\item{} +%mdk-data-line={1956} +\mdline{1956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1956}, which indicates whether the register index has a +\mdline{1957}\mdref{sec-user-defined-types}{user-defined type}\mdline{1957}. This is useful for +\mdline{1958}\mdref{sec-psa-metadata-translation}{translation}\mdline{1958}. The underlying built-in type +must be a fixed-width unsigned bitstring (\mdline{1959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1959}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1961} +\subsubsection{\mdline{1961}6.4.9.\hspace*{0.5em}\mdline{1961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}\label{sec-digest}%mdk%mdk + +%mdk-data-line={1963} +\noindent\mdline{1963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1963} messages are used to specify all possible instances of Packet Digest +PSA externs.%mdk + +%mdk-data-line={1966} +\mdline{1966}A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages.%mdk + +%mdk-data-line={1975} +\mdline{1975}The \mdline{1975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1975} message defines the following fields:%mdk + +%mdk-data-line={1977} +\begin{itemize}%mdk + +%mdk-data-line={1977} +\item{} +%mdk-data-line={1977} +\mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1977}, a \mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1977} message with the ID, name, and alias of this digest +instance.%mdk%mdk + +%mdk-data-line={1980} +\item{} +%mdk-data-line={1980} +\mdline{1980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1980}, which specifies the data type of an individual digest +notification using a \mdline{1981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1981} message (see section on\mdline{1981}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation +of Arbitrary P4 Types}\mdline{1982}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1984} +\subsubsection{\mdline{1984}6.4.10.\hspace*{0.5em}\mdline{1984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}\label{sec-p4info-extern}%mdk%mdk + +%mdk-data-line={1986} +\noindent\mdline{1986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1986} messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one \mdline{1989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1989} message instance in P4Info. The \mdline{1989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1989} message defines +the following fields:%mdk + +%mdk-data-line={1992} +\begin{itemize}%mdk + +%mdk-data-line={1992} +\item{} +%mdk-data-line={1992} +\mdline{1992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{1992}, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the\mdline{1993}~\mdref{sec-id-allocation}{reserved +range}\mdline{1994} \mdline{1994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{}[0x81,~0xfe]}}}\mdline{1994}. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture.%mdk%mdk + +%mdk-data-line={1999} +\item{} +%mdk-data-line={1999} +\mdline{1999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_name}}}\mdline{1999}, which specifies the fully-qualified P4 name of the extern +type.%mdk%mdk + +%mdk-data-line={2002} +\item{} +%mdk-data-line={2002} +\mdline{2002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instances}}}\mdline{2002}, a repeated field of \mdline{2002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{2002} Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +\mdline{2004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{2004} in turn defines the following fields:%mdk + +%mdk-data-line={2006} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2006} +\item\mdline{2006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{2006}, a \mdline{2006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{2006} message with the ID, name, and alias of this digest +instance.%mdk + +%mdk-data-line={2008} +\item\mdline{2008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{2008}, an \mdline{2008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{2008} Protobuf message\mdline{2008}~[\mdcite{protoany}{31}]\mdline{2008} which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for \mdline{2010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{2010} should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on\mdline{2012}~\mdref{sec-extending-p4runtime}{Extending +P4Runtime for non-PSA Architectures}\mdline{2013} for more +information.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2016} +\noindent\mdline{2016}If the P4 program does not include any instance of a given extern type, the +\mdline{2017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2017} message instance for that type should be omitted from the P4Info.%mdk + +%mdk-data-line={2019} +\subsection{\mdline{2019}6.5.\hspace*{0.5em}\mdline{2019}Support for Arbitrary P4 Types with P4TypeInfo}\label{sec-support-for-arbitrary-p4-types-with-p4typeinfo}%mdk%mdk + +%mdk-data-line={2021} +\noindent\mdline{2021}See section on\mdline{2021}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary P4 +Types}\mdline{2022}.%mdk + +%mdk-data-line={2024} +\section{\mdline{2024}7.\hspace*{0.5em}\mdline{2024}P4 Forwarding-Pipeline Configuration}\label{sec-p4-fwd-pipe-config}%mdk%mdk + +%mdk-data-line={2026} +\noindent\mdline{2026}The \mdline{2026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2026} captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the \mdline{2028}\textquotedblleft{}Device Configuration\textquotedblright{}\mdline{2028} and sometimes also referred to as +the \mdline{2029}\textquotedblleft{}P4 Blob\textquotedblright{}\mdline{2029}. It is defined as:%mdk + +%mdk-data-line={2031} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2032} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ForwardingPipelineConfig~\{\\ +~~config.P{\mdcolor{purple}4}Info~p4info~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~p4\_device\_config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}message}}~Cookie~\{\\ +~~~~{\bfseries{\mdcolor{navy}uint64}}~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~\}\\ +~~Cookie~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2042} +\noindent\mdline{2042}The \mdline{2042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{2042} field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic.%mdk + +%mdk-data-line={2045} +\mdline{2045}The \mdline{2045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{2045} is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new \mdline{2047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2047} on that target.%mdk + +%mdk-data-line={2049} +\mdline{2049}The \mdline{2049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{2049} field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a \mdline{2054}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{2054} RPC. +When writing the config via a \mdline{2055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{2055} RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present.%mdk + +%mdk-data-line={2059} +\section{\mdline{2059}8.\hspace*{0.5em}\mdline{2059}General Principles for Message Formatting}\label{sec-general-principles-for-message-formatting}%mdk%mdk + +%mdk-data-line={2061} +\subsection{\mdline{2061}8.1.\hspace*{0.5em}\mdline{2061}Set / Unset Protobuf Field}\label{sec-set-unset-protobuf-field}%mdk%mdk + +%mdk-data-line={2063} +\noindent\mdline{2063}In Protobuf version 3 (\mdline{2063}\emph{proto3}\mdline{2063}), the default value for a message field is +\mdline{2064}\textquotedblleft{}unset\textquotedblright{}\mdline{2064}~[\mdcite{protodefaults}{4}]\mdline{2064}. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +\mdline{2069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2069} message, an \mdline{2069}\textquotedblleft{}unset\textquotedblright{}\mdline{2069} \mdline{2069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2069} field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the \mdline{2071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2071} message field is +set, a single entry will be read.%mdk + +%mdk-data-line={2074} +\mdline{2074}Let\mdline{2074}'\mdline{2074}s look at the counter example in more details. Based on this specification +document, the C++ server code which processes \mdline{2075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2075} messages may look +like this:%mdk + +%mdk-data-line={2077} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2078} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}auto}}~*counter\_entry~=~...\\ +{\bfseries{\mdcolor{navy}if}}~(counter\_entry-\textgreater{}has\_index())~\{\\ +~~{\bfseries{\mdcolor{navy}auto}}~index~=~counter\_entry-\textgreater{}index().index();\\ +~~read\_one\_entry(counter\_entry-\textgreater{}id(),~index);\\ +\}~{\bfseries{\mdcolor{navy}else}}~\{\\ +~~read\_all\_entries(counter\_entry-\textgreater{}id());\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2087} +\begin{enumerate}%mdk + +%mdk-data-line={2087} +\item{} +%mdk-data-line={2087} +\mdline{2087}Reading a single counter entry at index 0 in the counter array with id +\mdline{2088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textless{}id\textgreater{}}}}\mdline{2088}:%mdk + +%mdk-data-line={2089} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2089} +\item\mdline{2089}Here is the C++ client code: + +%mdk-data-line={2090} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2091} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});\\ +entry.mutable\_index();\\ +{\mdcolor{darkgreen}//~The~above~line~sets~the~index~field;~it~is~equivalent~to:}\\ +{\mdcolor{darkgreen}//~auto~*index~=~entry.mutable\_index();}\\ +{\mdcolor{darkgreen}//~index-\textgreater{}set\_index(0);}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2098} +\item\mdline{2098}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2099} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2100} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}\\ +index~\{\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2103} +\item\mdline{2103}\textbf{Expected behavior}\mdline{2103}: Counter entry at index 0 is read. Notice that the +\mdline{2104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2104} subfield is missing under the \mdline{2104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2104} field message of +\mdline{2105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2105} in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2110} +\item{} +%mdk-data-line={2110} +\mdline{2110}Reading all counter entries by leaving the \mdline{2110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2110} field unset%mdk + +%mdk-data-line={2111} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2111} +\item\mdline{2111}Here is the C++ client code: + +%mdk-data-line={2112} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2113} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2116} +\item\mdline{2116}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2117} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2118} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2120} +\item\mdline{2120}\textbf{Expected behavior}\mdline{2120}: All counter entries for the provided counter +instance are read. Notice that the \mdline{2121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2121} message field is unset (default +value) and is therefore omitted from the textual representation of the +message.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={2125} +\subsection{\mdline{2125}8.2.\hspace*{0.5em}\mdline{2125}Read-Write Symmetry}\label{sec-read-write-symmetry}%mdk%mdk + +%mdk-data-line={2127} +\noindent\mdline{2127}The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example:%mdk + +%mdk-data-line={2133} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2134} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}intended\_value~=~value\\ +\\ +status~=~server.write(intended\_value,~p4\_entity)\\ +observed\_value~=~server.read(p4\_entity)\\ +\\ +assert(intended\_value~==~observed\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2142} +\noindent\mdline{2142}To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If \mdline{2146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{2146} RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol\mdline{2149}'\mdline{2149}s complexities to the client implementations.%mdk + +%mdk-data-line={2151} +\mdline{2151}In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the \mdline{2154}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2154} fields in a \mdline{2154}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2154} message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +\mdline{2157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MessageDifferencer}}}\mdline{2157} class\mdline{2157}~[\mdcite{protomessagedifferencer}{36}]\mdline{2157} included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance.%mdk + +%mdk-data-line={2162} +\subsection{\mdline{2162}8.3.\hspace*{0.5em}\mdline{2162}Zero as Reserved Value}\label{sec-zero-as-reserved-value}%mdk%mdk + +%mdk-data-line={2164} +\noindent\mdline{2164}p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a \mdline{2165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{2165}. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a \mdline{2168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{2168} or a \mdline{2168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfigRequest}}}\mdline{2168}.%mdk + +%mdk-data-line={2170} +\subsection{\mdline{2170}8.4.\hspace*{0.5em}\mdline{2170}Bytestrings}\label{sec-bytestrings}%mdk%mdk + +%mdk-data-line={2172} +\noindent\mdline{2172}P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (\mdline{2174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2174}) or signed (\mdline{2174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2174}), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +\mdline{2177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2177} Protobuf type. The correct bitwidth\mdline{2177} \mdline{2177}\textemdash{}\mdline{2177} as per the P4 program\mdline{2177} \mdline{2177}\textemdash{}\mdline{2177} of +each integer variable exposed through P4Runtime is specified in the P4Info +message.%mdk + +%mdk-data-line={2181} +\mdline{2181}The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals:%mdk + +%mdk-data-line={2184} +\begin{itemize}%mdk + +%mdk-data-line={2184} +\item{} +%mdk-data-line={2184} +\mdline{2184}It ensures that a properly encoded binary string\mdline{2184}'\mdline{2184}s integer value conforms +to the P4Info-specified bitwidth.%mdk%mdk + +%mdk-data-line={2187} +\item{} +%mdk-data-line={2187} +\mdline{2187}It supports\mdline{2187}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2187}.%mdk%mdk + +%mdk-data-line={2189} +\item{} +%mdk-data-line={2189} +\mdline{2189}It helps facilitate non-disruptive P4 program updates.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2191} +\noindent\mdline{2191}In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type \mdline{2196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2196} and/or \mdline{2196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2196}.%mdk + +%mdk-data-line={2198} +\mdline{2198}Note that this representation does \mdline{2198}\emph{not}\mdline{2198} make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range.%mdk + +%mdk-data-line={2207} +\mdline{2207}In the P4Runtime API version 1.0 (including minor version revisions), values +of table key fields, action parameters, and fields in packet-in and packet-out +headers between a device and the controller (see\mdline{2209}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{2209}), +may not be of type \mdline{2210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2210}. The rules for encoding signed values thus only +apply to messages of type \mdline{2211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2211} (see\mdline{2211}~\mdref{sec-p4data-in-p4runtime-proto}{8.5.3}\mdline{2211}).%mdk + +%mdk-data-line={2213} +\mdline{2213}For a value of type \mdline{2213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2213}, the fewest number of bits required to represent +the integer value \mdline{2214}$V > 0$\mdline{2214} is the smallest integer \mdline{2214}$A$\mdline{2214} such that \mdline{2214}$V \leq 2^A -1$\mdline{2215}.%mdk + +%mdk-data-line={2217} +\mdline{2217}For a value of type \mdline{2217}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2217}, the fewest number of bits required to represent +the integer value \mdline{2218}$V \neq 0$\mdline{2218} in 2\mdline{2218}'\mdline{2218}s complement form is the smallest integer \mdline{2218}$A$\mdline{2218} +such that \mdline{2219}$-2^{A-1} \leq V \leq 2^{A-1} - 1$\mdline{2219}.%mdk + +%mdk-data-line={2221} +\mdline{2221}As a special case, define that the value \mdline{2221}$V=0$\mdline{2221} requires at least \mdline{2221}$A=1$\mdline{2221} bit to +represent, regardless of whether it is signed or unsigned.%mdk + +%mdk-data-line={2224} +\mdline{2224}The shortest possible binary string for an integer \mdline{2224}$V$\mdline{2224} that needs \mdline{2224}$A$\mdline{2224} bits to +represent it is computed as:%mdk + +%mdk-data-line={2226} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2227} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size~=~floor(({\mdcolor{teal}A}~+~{\mdcolor{purple}7})~/~{\mdcolor{purple}8})}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2230} +\noindent\mdline{2230}Binary strings with the byte length computed as \mdline{2230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2230} promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies.%mdk + +%mdk-data-line={2234} +\mdline{2234}Any additional bits in the bytes sent for an unsigned integer value (type +\mdline{2235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2235}) must be 0. If additional bytes are transmitted above the +\mdline{2236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2236} minimum required, they must be filled with 0.%mdk + +%mdk-data-line={2238} +\mdline{2238}Any additional bits in the bytes sent for a signed integer value (type \mdline{2238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2238}) +must be copies of the sign bit, \mdline{2239}i.e.\mdline{2239} 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +\mdline{2241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2241} minimum required, they must be filled with copies of the +sign bit, \mdline{2242}i.e.\mdline{2242} 0 for non-negative values, or 0xff for negative values. In 2\mdline{2242}'\mdline{2242}s +complement representation, this is called \mdline{2243}\textquotedblleft{}sign extension\textquotedblright{}\mdline{2243}, and leaves the +numeric value represented unchanged.%mdk + +%mdk-data-line={2246} +\mdline{2246}Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value.%mdk + +%mdk-data-line={2252} +\mdline{2252}For a received bitstring expected to fit within a \mdline{2252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2252} type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring\mdline{2254}'\mdline{2254}s width is \mdline{2254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2254} bits or less.%mdk + +%mdk-data-line={2256} +\mdline{2256}For a received bitstring expected to fit within an \mdline{2256}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2256} type, the value it +represents is in range if, after \mdline{2257}\textquotedblleft{}undoing sign extension\textquotedblright{}\mdline{2257}, the remaining bit +string\mdline{2258}'\mdline{2258}s width is \mdline{2258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2258} bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other.%mdk + +%mdk-data-line={2264} +\mdline{2264}If the string\mdline{2264}'\mdline{2264}s byte length is zero, the server always rejects the string.%mdk + +%mdk-data-line={2266} +\mdline{2266}When the server rejects a binary string due to any of the previous criteria, +it returns an \mdline{2267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2267} error.%mdk + +%mdk-data-line={2269} +\mdline{2269}For all binary strings, P4Runtime uses big-endian (\mdline{2269}i.e.\mdline{2269} network) byte-order. +For signed integer values (\mdline{2270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2270} P4 type), P4Runtime uses the same two\mdline{2270}'\mdline{2270}s +complement bitwise representation as P4. Table\mdline{2271}~\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}}\mdline{2271} +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above.%mdk + +%mdk-data-line={2275} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2277} P4 type}}&\multicolumn{1}{|c}{{\bfseries\mdline{2277} Integer value}}&\multicolumn{1}{|c}{{\bfseries\mdline{2277} P4Runtime binary string}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2277} Read-write symmetry}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2279} \mdline{2279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2279}}&\multicolumn{1}{|l}{\mdline{2279} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2279} \mdline{2279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2279}}&\multicolumn{1}{|l|}{\mdline{2279} yes}\\ +\multicolumn{1}{|l}{\mdline{2280} \mdline{2280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2280}}&\multicolumn{1}{|l}{\mdline{2280} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2280} \mdline{2280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2280}}&\multicolumn{1}{|l|}{\mdline{2280} no}\\ +\multicolumn{1}{|l}{\mdline{2281} \mdline{2281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2281}}&\multicolumn{1}{|l}{\mdline{2281} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2281} \mdline{2281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2281}}&\multicolumn{1}{|l|}{\mdline{2281} yes}\\ +\multicolumn{1}{|l}{\mdline{2282} \mdline{2282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2282}}&\multicolumn{1}{|l}{\mdline{2282} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2282} \mdline{2282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x30\textbackslash{}x64}}}\mdline{2282}}&\multicolumn{1}{|l|}{\mdline{2282} yes}\\ +\multicolumn{1}{|l}{\mdline{2283} \mdline{2283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2283}}&\multicolumn{1}{|l}{\mdline{2283} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2283} \mdline{2283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x30\textbackslash{}x64}}}\mdline{2283}}&\multicolumn{1}{|l|}{\mdline{2283} no}\\ +\multicolumn{1}{|l}{\mdline{2284} \mdline{2284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2284}}&\multicolumn{1}{|l}{\mdline{2284} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2284} \mdline{2284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2284}}&\multicolumn{1}{|l|}{\mdline{2284} no}\\ +\multicolumn{1}{|l}{\mdline{2285} \mdline{2285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2285}}&\multicolumn{1}{|l}{\mdline{2285} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2285} \mdline{2285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2285}}&\multicolumn{1}{|l|}{\mdline{2285} yes}\\ +\multicolumn{1}{|l}{\mdline{2286} \mdline{2286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2286}}&\multicolumn{1}{|l}{\mdline{2286} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2286} \mdline{2286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00\textbackslash{}x63}}}\mdline{2286}}&\multicolumn{1}{|l|}{\mdline{2286} no}\\ +\multicolumn{1}{|l}{\mdline{2287} \mdline{2287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2287}}&\multicolumn{1}{|l}{\mdline{2287} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2287} \mdline{2287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2287}}&\multicolumn{1}{|l|}{\mdline{2287} yes}\\ +\multicolumn{1}{|l}{\mdline{2288} \mdline{2288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2288}}&\multicolumn{1}{|l}{\mdline{2288} \mdline{2288}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2288} \mdline{2288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x9d}}}\mdline{2288}}&\multicolumn{1}{|l|}{\mdline{2288} yes}\\ +\multicolumn{1}{|l}{\mdline{2289} \mdline{2289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2289}}&\multicolumn{1}{|l}{\mdline{2289} \mdline{2289}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2289} \mdline{2289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xff\textbackslash{}x9d}}}\mdline{2289}}&\multicolumn{1}{|l|}{\mdline{2289} no}\\ +\multicolumn{1}{|l}{\mdline{2290} \mdline{2290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2290}}&\multicolumn{1}{|l}{\mdline{2290} \mdline{2290}-739 (-0x2e3)}&\multicolumn{1}{|l}{\mdline{2290} \mdline{2290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xfd\textbackslash{}x1d}}}\mdline{2290}}&\multicolumn{1}{|l|}{\mdline{2290} yes}\\ +\multicolumn{1}{|l}{\mdline{2291} \mdline{2291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2291}}&\multicolumn{1}{|l}{\mdline{2291} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2291} \mdline{2291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00}}}\mdline{2291}}&\multicolumn{1}{|l|}{\mdline{2291} no}\\ +\multicolumn{1}{|l}{\mdline{2292} \mdline{2292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2292}}&\multicolumn{1}{|l}{\mdline{2292} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2292} \mdline{2292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00}}}\mdline{2292}}&\multicolumn{1}{|l|}{\mdline{2292} yes}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2294} +\mdhr{}%mdk + +%mdk-data-line={2295} +\noindent\mdline{2295}\mdcaption{\textbf{Table~\mdcaptionlabel{4}.}~\mdcaptiontext{Examples of Valid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-valid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2297} +\mdline{2297}Table\mdline{2297}~\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}}\mdline{2297} shows some examples of invalid +P4Runtime binary strings:%mdk + +%mdk-data-line={2300} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2302} P4 type}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2302} P4Runtime binary string}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2304} \mdline{2304}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2304}}&\multicolumn{1}{|l|}{\mdline{2304} \mdline{2304}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x63}}}\mdline{2304}}\\ +\multicolumn{1}{|l}{\mdline{2305} \mdline{2305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2305}}&\multicolumn{1}{|l|}{\mdline{2305} \mdline{2305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2305}}\\ +\multicolumn{1}{|l}{\mdline{2306} \mdline{2306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2306}}&\multicolumn{1}{|l|}{\mdline{2306} \mdline{2306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2306}}\\ +\multicolumn{1}{|l}{\mdline{2307} \mdline{2307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2307}}&\multicolumn{1}{|l|}{\mdline{2307} \mdline{2307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x10\textbackslash{}x63}}}\mdline{2307}}\\ +\multicolumn{1}{|l}{\mdline{2308} \mdline{2308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2308}}&\multicolumn{1}{|l|}{\mdline{2308} \mdline{2308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2308}}\\ +\multicolumn{1}{|l}{\mdline{2309} \mdline{2309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2309}}&\multicolumn{1}{|l|}{\mdline{2309} \mdline{2309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x40\textbackslash{}x63}}}\mdline{2309}}\\ +\multicolumn{1}{|l}{\mdline{2310} \mdline{2310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2310}}&\multicolumn{1}{|l|}{\mdline{2310} \mdline{2310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x9d}}}\mdline{2310}}\\ +\multicolumn{1}{|l}{\mdline{2311} \mdline{2311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2311}}&\multicolumn{1}{|l|}{\mdline{2311} \mdline{2311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x8d\textbackslash{}x1d}}}\mdline{2311}}\\ +\multicolumn{1}{|l}{\mdline{2312} \mdline{2312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2312}}&\multicolumn{1}{|l|}{\mdline{2312} \mdline{2312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2312}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2314} +\mdhr{}%mdk + +%mdk-data-line={2315} +\noindent\mdline{2315}\mdcaption{\textbf{Table~\mdcaptionlabel{5}.}~\mdcaptiontext{Examples of Invalid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-invalid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2317} +\mdline{2317}As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from \mdline{2322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2322} to \mdline{2322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2322}, a server +running the \mdline{2323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2323} version of the P4 program will accept requests from +clients that remain on the \mdline{2324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2324} P4Runtime version.%mdk + +%mdk-data-line={2326} +\mdline{2326}Despite the server\mdline{2326}'\mdline{2326}s binary string flexibility for P4 program update support, +the client and server must both remain aware of the +\mdline{2328}\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2328} +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values.%mdk + +%mdk-data-line={2333} +\mdline{2333}Representation of variable-length integer values (\mdline{2333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2333} P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the \mdline{2335}\emph{dynamic-length}\mdline{2335} of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an \mdline{2338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2338} error code otherwise.%mdk + +%mdk-data-line={2340} +\subsection{\mdline{2340}8.5.\hspace*{0.5em}\mdline{2340}Representation of Arbitrary P4 Types}\label{sec-representation-of-arbitrary-p4-types}%mdk%mdk + +%mdk-data-line={2342} +\subsubsection{\mdline{2342}8.5.1.\hspace*{0.5em}\mdline{2342}Problem Statement}\label{sec-problem-statement}%mdk%mdk + +%mdk-data-line={2344} +\noindent\mdline{2344}The P4\mdline{2344}\mdsub{16}\mdline{2344} language includes more complex types than just binary strings +\mdline{2345}[\mdcite{p4complextypes}{3}]\mdline{2345}. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table\mdline{2348}~\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}}\mdline{2348} shows the different +P4\mdline{2349}\mdsub{16}\mdline{2349} types and how they are allowed to be used, as per the P4\mdline{2349}\mdsub{16}\mdline{2349} +specification.%mdk + +%mdk-data-line={2352} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|l}{{\bfseries\mdline{2354}}}&\multicolumn{3}{|c|}{{\bfseries\mdline{2354} Container type}}\\ +\cmidrule{2-2}\cmidrule{3-3}\cmidrule{4-4} +\multicolumn{1}{|l}{{\bfseries\mdline{2356} Element type}}&\multicolumn{1}{|l}{{\bfseries\mdline{2356} header}}&\multicolumn{1}{|l}{{\bfseries\mdline{2356} header\mdline{2356}\_\mdline{2356}union}}&\multicolumn{1}{|l|}{{\bfseries\mdline{2356} struct or tuple}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2358} \mdline{2358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2358}}&\multicolumn{1}{|l}{\mdline{2358} allowed}&\multicolumn{1}{|l}{\mdline{2358} error}&\multicolumn{1}{|l|}{\mdline{2358} allowed}\\ +\multicolumn{1}{|l}{\mdline{2359} \mdline{2359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2359}}&\multicolumn{1}{|l}{\mdline{2359} allowed}&\multicolumn{1}{|l}{\mdline{2359} error}&\multicolumn{1}{|l|}{\mdline{2359} allowed}\\ +\multicolumn{1}{|l}{\mdline{2360} \mdline{2360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2360}}&\multicolumn{1}{|l}{\mdline{2360} allowed}&\multicolumn{1}{|l}{\mdline{2360} error}&\multicolumn{1}{|l|}{\mdline{2360} allowed}\\ +\multicolumn{1}{|l}{\mdline{2361} \mdline{2361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int}}}\mdline{2361}}&\multicolumn{1}{|l}{\mdline{2361} error}&\multicolumn{1}{|l}{\mdline{2361} error}&\multicolumn{1}{|l|}{\mdline{2361} error}\\ +\multicolumn{1}{|l}{\mdline{2362} \mdline{2362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}void}}}\mdline{2362}}&\multicolumn{1}{|l}{\mdline{2362} error}&\multicolumn{1}{|l}{\mdline{2362} error}&\multicolumn{1}{|l|}{\mdline{2362} error}\\ +\multicolumn{1}{|l}{\mdline{2363} \mdline{2363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2363}}&\multicolumn{1}{|l}{\mdline{2363} error}&\multicolumn{1}{|l}{\mdline{2363} error}&\multicolumn{1}{|l|}{\mdline{2363} allowed}\\ +\multicolumn{1}{|l}{\mdline{2364} \mdline{2364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_kind}}}\mdline{2364}}&\multicolumn{1}{|l}{\mdline{2364} error}&\multicolumn{1}{|l}{\mdline{2364} error}&\multicolumn{1}{|l|}{\mdline{2364} error}\\ +\multicolumn{1}{|l}{\mdline{2365} \mdline{2365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2365}}&\multicolumn{1}{|l}{\mdline{2365} error}&\multicolumn{1}{|l}{\mdline{2365} error}&\multicolumn{1}{|l|}{\mdline{2365} allowed}\\ +\multicolumn{1}{|l}{\mdline{2366} \mdline{2366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2366}}&\multicolumn{1}{|l}{\mdline{2366} allowed\mdline{2366}\mdfootnote{1}{%mdk-data-line={2376} +%mdk-data-line={2376} +\noindent\mdline{2376}an \mdline{2376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2376} type used as a field in a \mdline{2376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2376} must specify a +underlying type and representation for \mdline{2377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2377} elements.%mdk +\label{fn-enum_header}%mdk%mdk +}\mdline{2366}}&\multicolumn{1}{|l}{\mdline{2366} error}&\multicolumn{1}{|l|}{\mdline{2366} allowed}\\ +\multicolumn{1}{|l}{\mdline{2367} \mdline{2367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2367}}&\multicolumn{1}{|l}{\mdline{2367} error}&\multicolumn{1}{|l}{\mdline{2367} allowed}&\multicolumn{1}{|l|}{\mdline{2367} allowed}\\ +\multicolumn{1}{|l}{\mdline{2368} header stack}&\multicolumn{1}{|l}{\mdline{2368} error}&\multicolumn{1}{|l}{\mdline{2368} error}&\multicolumn{1}{|l|}{\mdline{2368} allowed}\\ +\multicolumn{1}{|l}{\mdline{2369} \mdline{2369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2369}}&\multicolumn{1}{|l}{\mdline{2369} error}&\multicolumn{1}{|l}{\mdline{2369} error}&\multicolumn{1}{|l|}{\mdline{2369} allowed}\\ +\multicolumn{1}{|l}{\mdline{2370} \mdline{2370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2370}}&\multicolumn{1}{|l}{\mdline{2370} error}&\multicolumn{1}{|l}{\mdline{2370} error}&\multicolumn{1}{|l|}{\mdline{2370} allowed}\\ +\multicolumn{1}{|l}{\mdline{2371} \mdline{2371}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2371}}&\multicolumn{1}{|l}{\mdline{2371} error}&\multicolumn{1}{|l}{\mdline{2371} error}&\multicolumn{1}{|l|}{\mdline{2371} allowed}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2373} +\mdhr{}%mdk + +%mdk-data-line={2374} +\noindent\mdline{2374}\mdcaption{\textbf{Table~\mdcaptionlabel{6}.}~\mdcaptiontext{P4 Type Usage}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-type-usage}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2379} +\mdline{2379}For example, the following P4\mdline{2379}\mdsub{16}\mdline{2379} objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects.%mdk + +%mdk-data-line={2382} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2383} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}{\bfseries{\mdcolor{navy}tuple}}\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}4}\textgreater{},~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~\textgreater{}~\textgreater{}()~digest\_complex;\\ +digest\_complex.pack(\{~hdr.ipv4.version,~hdr.ipv4.protocol~\});\\ +{\mdcolor{darkgreen}//~...}\\ +{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2393} +\noindent\mdline{2393}One solution would be to use only binary string (\mdline{2393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2393} type) in +p4runtime.proto and to define a custom serialization format for complex P4\mdline{2394}\mdsub{16}\mdline{2394} +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P4\mdline{2401}\mdsub{16}\mdline{2401} types.%mdk + +%mdk-data-line={2403} +\subsubsection{\mdline{2403}8.5.2.\hspace*{0.5em}\mdline{2403}P4 Type Specifications in p4info.proto}\label{sec-p4-type-specifications-in-p4infoproto}%mdk%mdk + +%mdk-data-line={2405} +\noindent\mdline{2405}In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type \mdline{2409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip\_t}}}\mdline{2409}, which is a header union with 2 possible headers: +\mdline{2410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4}}}\mdline{2410} with type \mdline{2410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4\_t}}}\mdline{2410} and \mdline{2410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6}}}\mdline{2410} with type \mdline{2410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6\_t}}}\mdline{2410}. Similarly, they need to +know the field layout for both of these header types.%mdk + +%mdk-data-line={2413} +\mdline{2413}To achieve this we introduce 2 main Protobuf messages: \mdline{2413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2413} and +\mdline{2414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2414}.%mdk + +%mdk-data-line={2416} +\mdline{2416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2416} is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P4\mdline{2417}\mdsub{16}\mdline{2417} program. These +named types are \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2418}, \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2418}, \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2418}, \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2418} and +\mdline{2419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2419}; for each of these we have a type specification message, +respectively \mdline{2420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructTypeSpec}}}\mdline{2420}, \mdline{2420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderTypeSpec}}}\mdline{2420}, \mdline{2420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionTypeSpec}}}\mdline{2420}, +\mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4EnumTypeSpec}}}\mdline{2421} and \mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4SerializableEnumTypeSpec}}}\mdline{2421}. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. \mdline{2423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2423} also includes the list of parser errors for the program, as +a \mdline{2424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4ErrorTypeSpec}}}\mdline{2424} message.%mdk + +%mdk-data-line={2426} +\mdline{2426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2426} is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each \mdline{2428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2428} message corresponds to a compile-time type in the +original P4\mdline{2429}\mdsub{16}\mdline{2429} program (\mdline{2429}e.g.\mdline{2429} the type parameter of an extern). This +compile-time type is represented as a Protobuf \mdline{2430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2430}, which can be:%mdk + +%mdk-data-line={2432} +\begin{itemize}%mdk + +%mdk-data-line={2432} +\item{} +%mdk-data-line={2432} +\mdline{2432}a string representing the name of the type in case of a named type (\mdline{2432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2432}, +\mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2433} or user-defined \mdline{2433}\textquotedblleft{}new\textquotedblright{}\mdline{2433} +\mdline{2434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2434}),%mdk%mdk + +%mdk-data-line={2436} +\item{} +%mdk-data-line={2436} +\mdline{2436}an empty Protobuf message for \mdline{2436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2436} and \mdline{2436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2436}, or%mdk%mdk + +%mdk-data-line={2438} +\item{} +%mdk-data-line={2438} +\mdline{2438}a Protobuf message for other anonymous types (\mdline{2438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2438}, \mdline{2438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2438}, \mdline{2438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2438}, +\mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2439} or stack). The \mdline{2439}\textquotedblleft{}binary string\textquotedblright{}\mdline{2439} types (\mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2439}, \mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2439}, and +\mdline{2440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2440}) are grouped together in the \mdline{2440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4BitstringLikeTypeSpec}}}\mdline{2440} message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf \mdline{2442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2442} +type).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2445} +\noindent\mdline{2445}For all P4\mdline{2445}\mdsub{16}\mdline{2445} compound types (\mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2445}, \mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2445}, \mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2445}, and \mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2445}), +the order of \mdline{2446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2446} in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P4\mdline{2448}\mdsub{16}\mdline{2448} declaration. The same goes for the order of members of an \mdline{2448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2448} +(serializable or not) or members of \mdline{2449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2449}.%mdk + +%mdk-data-line={2451} +\subsubsection{\mdline{2451}8.5.3.\hspace*{0.5em}\mdline{2451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2451} in p4runtime.proto}\label{sec-p4data-in-p4runtime-proto}%mdk%mdk + +%mdk-data-line={2453} +\noindent\mdline{2453}P4Runtime uses the \mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2453} message to represent values of arbitrary types. The +P4Runtime client must generate correct \mdline{2454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2454} messages based on the type +specification information included in P4Info. The \mdline{2455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2455} message was designed +to introduce little overhead compared to using binary strings in the most common +case (P4\mdline{2457}\mdsub{16}\mdline{2457} \mdline{2457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2457} type).%mdk + +%mdk-data-line={2459} +\mdline{2459}Just like its P4Info counterpart\mdline{2459} \mdline{2459}- \mdline{2459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2459} \mdline{2459}-, \mdline{2459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2459} uses a Protobuf +\mdline{2460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2460} to represent all possible values.%mdk + +%mdk-data-line={2462} +\mdline{2462}We define a canonical representation for \mdline{2462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2462} messages\mdline{2462} \mdline{2462}\textemdash{}\mdline{2462} therefore +guaranteeing read-write symmetry\mdline{2463} \mdline{2463}\textemdash{}\mdline{2463} by introducing the following requirements:%mdk + +%mdk-data-line={2465} +\begin{itemize}%mdk + +%mdk-data-line={2465} +\item{} +%mdk-data-line={2465} +\mdline{2465}The order of \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2465} in \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructLike}}}\mdline{2465} and the order of \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2465} in +\mdline{2466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2466} must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P4\mdline{2467}\mdsub{16}\mdline{2467} type +declaration.%mdk%mdk + +%mdk-data-line={2470} +\item{} +%mdk-data-line={2470} +\mdline{2470}An invalid header is represented by a \mdline{2470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2470} message where the \mdline{2470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_valid}}}\mdline{2470} +field is false and the \mdline{2471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2471} repeated field is empty.%mdk%mdk + +%mdk-data-line={2473} +\item{} +%mdk-data-line={2473} +\mdline{2473}An invalid header union (\mdline{2473}i.e.\mdline{2473} all headers in the union are invalid) is +represented by a \mdline{2474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnion}}}\mdline{2474} message where the \mdline{2474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header\_name}}}\mdline{2474} is the +empty string (default value for the field) and the \mdline{2475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header}}}\mdline{2475} is unset.%mdk%mdk + +%mdk-data-line={2477} +\item{} +%mdk-data-line={2477} +\mdline{2477}The order of \mdline{2477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2477} in \mdline{2477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStack}}}\mdline{2477} and \mdline{2477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStack}}}\mdline{2477} is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the \mdline{2479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2479} field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding \mdline{2481}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStackTypeSpec}}}\mdline{2481} or +\mdline{2482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStackTypeSpec}}}\mdline{2482} message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2484} +\subsubsection{\mdline{2484}8.5.4.\hspace*{0.5em}\mdline{2484}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={2486} +\noindent\mdline{2486}Let\mdline{2486}'\mdline{2486}s look at the Register example again:%mdk + +%mdk-data-line={2488} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2489} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2496} +\noindent\mdline{2496}Here\mdline{2496}'\mdline{2496}s the corresponding entry in the P4Info message:%mdk + +%mdk-data-line={2498} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2499} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}registers~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}369119267}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~\}\\ +~~type\_spec~\{\\ +~~~~header\_union~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~size:~{\mdcolor{purple}128}\\ +\}\\ +type\_info~\{\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~header\_unions~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2555} +\noindent\mdline{2555}Here\mdline{2555}'\mdline{2555}s a \mdline{2555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.WriteRequest}}}\mdline{2555} to set the value of \mdline{2555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_ip{}[12]}}}\mdline{2555}:%mdk + +%mdk-data-line={2557} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2558} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}update~\{\\ +~~type:~INSERT\\ +~~entity~\{\\ +~~~~register\_entry~\{\\ +~~~~~~register\_id:~{\mdcolor{purple}369119267}\\ +~~~~~~index~\{\\ +~~~~~~~~index:~{\mdcolor{purple}12}\\ +~~~~~~\}\\ +~~~~~~data~\{\\ +~~~~~~~~header\_union~\{\\ +~~~~~~~~~~valid\_header\_name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~~~valid\_header~\{\\ +~~~~~~~~~~~~is\_valid:~true\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x04}{\mdcolor{maroon}"}\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{darkgreen}\#~...}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2581} +\subsubsection{\mdline{2581}8.5.5.\hspace*{0.5em}\mdline{2581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2581}, serializable \mdline{2581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2581} and \mdline{2581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}\label{sec-enum-serializable-enum-and-error}%mdk%mdk + +%mdk-data-line={2583} +\noindent\mdline{2583}P4\mdline{2583}\mdsub{16}\mdline{2583} supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or \mdline{2584}\textquotedblleft{}unsafe\textquotedblright{}\mdline{2584} enum) +\mdline{2585}[\mdcite{p4enums}{5}]\mdline{2585}. For \mdline{2585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2585} types with no underlying type\mdline{2585} \mdline{2585}\textemdash{}\mdline{2585} as well as \mdline{2585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2585} \mdline{2585}\textemdash{}\mdline{2585} +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in \mdline{2588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2588} to represent \mdline{2588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2588} and +\mdline{2589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2589} values.%mdk + +%mdk-data-line={2591} +\mdline{2591}Serializable \mdline{2591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2591} types have an underlying fixed-width unsigned integer +representation (\mdline{2592}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2592}). All named enum members must be assigned an integer +value by the P4 programmer, but \mdline{2593}\emph{not all}\mdline{2593} valid numeric values for the +underlying type need to have a corresponding name. \mdline{2594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2594} includes the +mapping between entry name and entry value. When providing serializable enum +values through \mdline{2596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2596}, one must use the assigned integer value (\mdline{2596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum\_value}}}\mdline{2596} +bytestring field). P4Runtime does not provide a way for the client to use the +name\mdline{2598} \mdline{2598}\textemdash{}\mdline{2598} even when the enum member has one\mdline{2598} \mdline{2598}\textemdash{}\mdline{2598} instead of the value, as it makes +it easier for the server to respect the\mdline{2599}~\mdref{sec-read-write-symmetry}{read-write +symmetry}\mdline{2600} principle.%mdk + +%mdk-data-line={2602} +\subsubsection{\mdline{2602}8.5.6.\hspace*{0.5em}\mdline{2602}User-defined types}\label{sec-user-defined-types}%mdk%mdk + +%mdk-data-line={2604} +\noindent\mdline{2604}P4\mdline{2604}\mdsub{16}\mdline{2604} enables programmers to introduce new types\mdline{2604}~[\mdcite{p4newtypes}{11}]\mdline{2604}. While similar +to \mdline{2605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{2605}, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +\mdline{2608}\mdref{sec-psa-metadata-translation}{translation}\mdline{2608}. When introducing a new type, the +declaration can be annotated with \mdline{2609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2609} to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for\mdline{2611}~\mdref{sec-translation-of-port-numbers}{port numbers}\mdline{2611}, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. \mdline{2614}\textbf{The \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}} annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}})}\mdline{2616}. The type exposed to the control plane (referred to as the +\mdline{2617}\emph{controller\_type}\mdline{2617}) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a \mdline{2619}\emph{URI}\mdline{2619} (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the \mdline{2621}\emph{controller\_type}\mdline{2621} of the values exposed to the control plane. The +\mdline{2622}\emph{controller\_type}\mdline{2622} can be either \mdline{2622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2622} where \mdline{2622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2622} is any positive integer, or +\mdline{2623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{2623}, or a positive integer \mdline{2623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2623} which has the same meaning as \mdline{2623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2623}. +Specifying just an integer is deprecated.%mdk + +%mdk-data-line={2626} +\mdline{2626}It is recommended that the URI includes at least the P4 architecture name and +the type name.%mdk + +%mdk-data-line={2629} +\mdline{2629}A \mdline{2629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2629} annotation need not have any effect if it is used to +annotate anything in a P4 program other than a \mdline{2630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2630} declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect.%mdk + +%mdk-data-line={2634} +\mdline{2634}User-defined types are specified using the \mdline{2634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{2634} message, which has +the following fields:%mdk + +%mdk-data-line={2637} +\begin{itemize}%mdk + +%mdk-data-line={2637} +\item{} +%mdk-data-line={2637} +\mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}representation}}}\mdline{2637}, a Protobuf \mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2637} specifying how values of this type are +exchanged between client and server; it can be either:%mdk + +%mdk-data-line={2640} +\begin{itemize}%mdk + +%mdk-data-line={2640} +\item{} +%mdk-data-line={2640} +\mdline{2640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2640}, if and only if no \mdline{2640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2640} annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 \mdline{2642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2642} declaration is itself a +user-defined type, \mdline{2643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2643} is obtained by \mdline{2643}\textquotedblleft{}walking\textquotedblright{}\mdline{2643} the chain of +\mdline{2644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2644} declarations recursively until a built-in type (\mdline{2644}e.g.\mdline{2644} \mdline{2644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2644}) is +found.%mdk%mdk + +%mdk-data-line={2647} +\item{} +%mdk-data-line={2647} +\mdline{2647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}translated\_type}}}\mdline{2647}, if and only if the P4 \mdline{2647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2647} declaration was annotated +with \mdline{2648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2648}. It is of type \mdline{2648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeTranslation}}}\mdline{2648}, +which itself has two fields\mdline{2649} \mdline{2649}\textemdash{}\mdline{2649} \mdline{2649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uri}}}\mdline{2649} and either \mdline{2649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_string}}}\mdline{2649} or +\mdline{2650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_bitwidth}}}\mdline{2650} \mdline{2650}\textemdash{}\mdline{2650}, which map to the two input parameters to the +annotation.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2653} +\item{} +%mdk-data-line={2653} +\mdline{2653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{2653}, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2656} +\noindent\mdline{2656}For example, an architecture\mdline{2656} \mdline{2656}\textemdash{}\mdline{2656} in this case PSA\mdline{2656} \mdline{2656}\textemdash{}\mdline{2656} may introduce a new type +for port numbers:%mdk + +%mdk-data-line={2658} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2659} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~string,~e.g.~"eth0".}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~32-bit~integer,~e.g.~0xffffffff.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{darkgreen}//~Same~as~above.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_32\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_32\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2672} +\noindent\mdline{2672}In this case, the P4Info message would include the following \mdline{2672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2672} +messages:%mdk + +%mdk-data-line={2675} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2676} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_string:~\{\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2713} +\noindent\mdline{2713}Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (\mdline{2714}e.g.\mdline{2714} through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over \mdline{2716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2716} to enable users +to overwrite annotations included as part of the P4 architecture definition.%mdk + +%mdk-data-line={2719} +\subsubsection{\mdline{2719}8.5.7.\hspace*{0.5em}\mdline{2719}Trade-off for v1.x Releases}\label{sec-trade-off-for-v1x-releases}%mdk%mdk + +%mdk-data-line={2721} +\noindent\mdline{2721}For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +\mdline{2722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2722} with \mdline{2722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2722} in the \mdline{2722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{2722} message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +\mdline{2725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2725} to provide action parameter values and controller metadata +values. However \mdline{2726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2726} is used whenever appropriate for PSA externs and we +encourage the use of \mdline{2727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2727} in architecture-specific extensions.%mdk + +%mdk-data-line={2729} +\mdline{2729}In order to support\mdline{2729}~\mdref{sec-psa-metadata-translation}{translation}\mdline{2729} for action +parameters and match fields, we include a \mdline{2730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2730} field in +\mdline{2731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{2731}, \mdline{2731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Action.Param}}}\mdline{2731} and +\mdline{2732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ControllerPacketMetadata.Metadata}}}\mdline{2732}. In addition, the \mdline{2732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2732} +field for all of these message types must abide by the following rule when +\mdline{2734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2734} names a translated user-defined type:%mdk + +%mdk-data-line={2736} +\begin{itemize}%mdk + +%mdk-data-line={2736} +\item{} +%mdk-data-line={2736} +\mdline{2736}If the \mdline{2736}\emph{controller\_type}\mdline{2736} is a fixed-width unsigned bitstring, the \mdline{2736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2736} +field must be set to the bitwidth of the \mdline{2737}\emph{controller\_type}\mdline{2737}. This information +is redundant with the one included in the \mdline{2738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2738} entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent.%mdk%mdk + +%mdk-data-line={2744} +\item{} +%mdk-data-line={2744} +\mdline{2744}Otherwise (\mdline{2744}i.e.\mdline{2744}, if the \mdline{2744}\emph{controller\_type}\mdline{2744} is a string), the \mdline{2744}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2744} must +be \mdline{2745}\textquotedblleft{}unset\textquotedblright{}\mdline{2745}, which, in Protobuf version 3, is the same as setting the field to +0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2748} +\noindent\mdline{2748}For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types:%mdk + +%mdk-data-line={2750} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2751} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{navy}@}{\mdcolor{navy}name}{\mdcolor{maroon}(".t")}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~meta.port1:~exact;~~{\mdcolor{darkgreen}//~meta.port1~has~type~PortId\_String\_t}\\ +~~~~meta.port2:~exact;~~{\mdcolor{darkgreen}//~meta.port2~has~type~PortId\_Bit32\_t}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2769} +\noindent\mdline{2769}This table would have the following representation in the generated P4Info +message:%mdk + +%mdk-data-line={2771} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2772} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tables~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}34728461}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port1}{\mdcolor{maroon}"}\\ +~~~~{\mdcolor{darkgreen}\#~notice~that~bitwidth~is~unset}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port2}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~{\mdcolor{darkgreen}\#~...}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2800} +\section{\mdline{2800}9.\hspace*{0.5em}\mdline{2800}P4 Entity Messages}\label{sec-p4-entity-msgs}%mdk%mdk + +%mdk-data-line={2802} +\noindent\mdline{2802}P4Runtime covers P4 entities that are either part of the P4\mdline{2802}\mdsub{16}\mdline{2802} language, or +defined as PSA externs. The sections below describe the messages for each +supported entity.%mdk + +%mdk-data-line={2806} +\subsection{\mdline{2806}9.1.\hspace*{0.5em}\mdline{2806}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}\label{sec-table-entry}%mdk%mdk + +%mdk-data-line={2808} +\noindent\mdline{2808}The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action\mdline{2810}'\mdline{2810}s +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification.%mdk + +%mdk-data-line={2816} +\mdline{2816}P4Runtime supports inserting, modifying, deleting and reading table entries with +the \mdline{2817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2817} entity, which has the following fields:%mdk + +%mdk-data-line={2819} +\begin{itemize}%mdk + +%mdk-data-line={2819} +\item{} +%mdk-data-line={2819} +\mdline{2819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2819}, which identifies the table instance; the \mdline{2819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2819} is determined +by the P4Info message.%mdk%mdk + +%mdk-data-line={2822} +\item{} +%mdk-data-line={2822} +\mdline{2822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2822}, a repeated field of \mdline{2822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2822} messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration.%mdk%mdk + +%mdk-data-line={2826} +\item{} +%mdk-data-line={2826} +\mdline{2826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2826}, which indicates which of the table\mdline{2826}'\mdline{2826}s actions to execute in case of +match and with which argument values.%mdk%mdk + +%mdk-data-line={2829} +\item{} +%mdk-data-line={2829} +\mdline{2829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2829}, a 32-bit integer used to order entries when the table\mdline{2829}'\mdline{2829}s match key +includes an optional, ternary or range match.%mdk%mdk + +%mdk-data-line={2832} +\item{} +%mdk-data-line={2832} +\mdline{2832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2832}, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +\mdline{2836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{2836} field.%mdk%mdk + +%mdk-data-line={2838} +\item{} +%mdk-data-line={2838} +\mdline{2838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{2838}, an arbitrary \mdline{2838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2838} value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry.%mdk%mdk + +%mdk-data-line={2843} +\item{} +%mdk-data-line={2843} +\mdline{2843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2843}, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See\mdline{2844}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2845} section for more information.%mdk%mdk + +%mdk-data-line={2847} +\item{} +%mdk-data-line={2847} +\mdline{2847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2847}, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See\mdline{2848}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2849} section for more information.%mdk%mdk + +%mdk-data-line={2851} +\item{} +%mdk-data-line={2851} +\mdline{2851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{2851}, which is used to read and write the per-color counter +values for the direct meter entry attached to this table entry, if any. +See\mdline{2853}~\mdref{sec-direct-resources}{Direct resources}\mdline{2853} section for more information.%mdk%mdk + +%mdk-data-line={2855} +\item{} +%mdk-data-line={2855} +\mdline{2855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2855}, a boolean flag which indicates whether the table entry is +the default entry for the table. See\mdline{2856}~\mdref{sec-default-entry}{Default entry}\mdline{2856} +section for more information.%mdk%mdk + +%mdk-data-line={2859} +\item{} +%mdk-data-line={2859} +\mdline{2859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2859} and \mdline{2859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2859}, which are two fields used to +implement idle-timeout support for the table, if applicable. See +\mdline{2861}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{2861} section for more information.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2863} +\noindent\mdline{2863}The \mdline{2863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2863} field must be set to a non-zero value if the match key includes a +ternary match (\mdline{2864}i.e.\mdline{2864} in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an \mdline{2865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{2865}, \mdline{2865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2865} or +\mdline{2866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2866} match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches.%mdk + +%mdk-data-line={2875} +\mdline{2875}The \mdline{2875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2875} and \mdline{2875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2875} fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for \mdline{2877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2877} and \mdline{2877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{2877} updates. When deleting +an entry, these key fields (along with \mdline{2878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2878}) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a \mdline{2880}\emph{keyless}\mdline{2880} +table (the table has an empty match key), the server must reject all attempts to +\mdline{2882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2882} a match entry and return an \mdline{2882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2882} error.%mdk + +%mdk-data-line={2884} +\mdline{2884}The number of match entries that a table \mdline{2884}\emph{should}\mdline{2884} support is indicated in P4Info +(\mdline{2885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2885} field of \mdline{2885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{2885} message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P4\mdline{2886}\mdsub{16}\mdline{2886} specification for the +\mdline{2887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2887} property\mdline{2887}~[\mdcite{p4tableproperties}{30}]\mdline{2887}. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +\mdline{2891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{2891} when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached.%mdk + +%mdk-data-line={2896} +\subsubsection{\mdline{2896}9.1.1.\hspace*{0.5em}\mdline{2896}Match Format}\label{sec-match-format}%mdk%mdk + +%mdk-data-line={2898} +\noindent\mdline{2898}The bytes fields in the \mdline{2898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2898} message follow the format described in +\mdline{2899}\mdref{sec-bytestrings}{Bytestrings}\mdline{2899}.%mdk + +%mdk-data-line={2901} +\mdline{2901}For \mdline{2901}\textquotedblleft{}don't care\textquotedblright{}\mdline{2901} matches, the P4Runtime client must omit the field\mdline{2901}'\mdline{2901}s entire +\mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2902} entry when building the \mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2902} repeated field of the \mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2902} +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for \mdline{2904}\textquotedblleft{}don't care\textquotedblright{}\mdline{2904} matches, which is needed +to ensure\mdline{2905}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2905}. For PSA match types, +a \mdline{2906}\textquotedblleft{}don't care\textquotedblright{}\mdline{2906} match for a specific match key field is defined as follows:%mdk + +%mdk-data-line={2908} +\begin{itemize}%mdk + +%mdk-data-line={2908} +\item{} +%mdk-data-line={2908} +\mdline{2908}For a \mdline{2908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2908} match, it is logically equivalent to a mask of zeros.%mdk%mdk + +%mdk-data-line={2910} +\item{} +%mdk-data-line={2910} +\mdline{2910}For a \mdline{2910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{2910} match, it is logically equivalent to a wildcard match.%mdk%mdk + +%mdk-data-line={2912} +\item{} +%mdk-data-line={2912} +\mdline{2912}For an \mdline{2912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2912} match, it is logically equivalent to a prefix\mdline{2912}\_\mdline{2912}len of zero.%mdk%mdk + +%mdk-data-line={2914} +\item{} +%mdk-data-line={2914} +\mdline{2914}For a \mdline{2914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2914} match, it is logically equivalent to a range which includes all +possible values for the field.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2917} +\noindent\mdline{2917}Note that there is no \mdline{2917}\textquotedblleft{}don't care\textquotedblright{}\mdline{2917} value for \mdline{2917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2917} matches and therefore exact +match fields can never be omitted from the \mdline{2918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2918} message.%mdk + +%mdk-data-line={2920} +\mdline{2920}The following example shows a P4Runtime message that treats a \mdline{2920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2920} field +as a \mdline{2921}\textquotedblleft{}don't care\textquotedblright{}\mdline{2921} match. The P4 program defines table \mdline{2921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{2921} with \mdline{2921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2921} +and \mdline{2922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2922} fields in its match key:%mdk + +%mdk-data-line={2924} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2925} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~ternary;\\ +~~~~istd.ingress\_port:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2936} +\noindent\mdline{2936}In this P4Runtime request, the client omits the table\mdline{2936}'\mdline{2936}s \mdline{2936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2936} field +from the repeated \mdline{2937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2937} field to indicate a \mdline{2937}\textquotedblleft{}don't care\textquotedblright{}\mdline{2937} match. As shown +below, the \mdline{2938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2938} specifies only the \mdline{2938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2938} field given by \mdline{2938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id:~2}}}\mdline{2938}.%mdk + +%mdk-data-line={2940} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2941} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}33554439}~~{\mdcolor{darkgreen}\#~Table~t's~ID.}\\ +~~~~match~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~field\_id~1~is~not~present~to~use~the~don't~care~ternary~value.}\\ +~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~exact~\{\\ +~~~~~~~~value:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x20}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~action~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~Action~selection~goes~here.}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2959} +\noindent\mdline{2959}For every member of the \mdline{2959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2959} repeated \mdline{2959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2959} field, \mdline{2959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id}}}\mdline{2959} must be +a valid id for the table, as per the P4Info, and one of the fields in +\mdline{2961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{2961} must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an \mdline{2963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2963} error code.%mdk + +%mdk-data-line={2965} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2965} +\item\mdline{2965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2965} match + +%mdk-data-line={2966} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2966} +\item\mdline{2966}The binary string encoding of the value must conform to the +\mdline{2967}\mdref{sec-bytestrings}{Bytestrings}\mdline{2967} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2969} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2970} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.exact().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2973} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2973} +\item\mdline{2973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2973} match + +%mdk-data-line={2974} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2974} +\item\mdline{2974}The binary string encoding of the value (when present) must conform to the +\mdline{2975}\mdref{sec-bytestrings}{Bytestrings}\mdline{2975} requirements.%mdk + +%mdk-data-line={2976} +\item\mdline{2976}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2976} match must be omitted.%mdk + +%mdk-data-line={2977} +\item\mdline{2977}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2977} bits must be 0 in value.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2979} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2980} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.lpm().value()))\\ +\\ +pLen~=~match.lpm().prefix\_len()\\ +assert(pLen~\textgreater{}~0)\\ +\\ +trailing\_zeros~=~countTrailingZeros(match.lpm().value())\\ +assert(trailing\_zeros~\textgreater{}=~field\_bits~-~pLen)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2989} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2989} +\item\mdline{2989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2989} match + +%mdk-data-line={2990} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2990} +\item\mdline{2990}The binary string encoding of the value (when present) and mask (when +present) must conform to the\mdline{2991}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2991} requirements.%mdk + +%mdk-data-line={2992} +\item\mdline{2992}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2992} match must be omitted.%mdk + +%mdk-data-line={2993} +\item\mdline{2993}Masked bits must be 0 in value. This constraint taken together +with the\mdline{2994}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2994} requirements means that the +value\mdline{2995}'\mdline{2995}s binary string is never longer than the mask\mdline{2995}'\mdline{2995}s binary string. +When the value\mdline{2996}'\mdline{2996}s string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3000} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3001} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.ternary().value()))\\ +assert(BytestringValid(match.ternary().mask()))\\ +assert(match.ternary().value().size()~\textless{}=~match.ternary().mask().size());\\ +\\ +value~=~parseInteger(match.ternary().value())\\ +mask~=~parseInteger(match.ternary().mask())\\ +\\ +assert(mask~!=~0)\\ +\\ +assert(value~\&~mask~==~value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3013} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3013} +\item\mdline{3013}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3013} match + +%mdk-data-line={3014} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3014} +\item\mdline{3014}The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the\mdline{3015}~\mdref{sec-bytestrings}{Bytestrings}\mdline{3015} +requirements.%mdk + +%mdk-data-line={3017} +\item\mdline{3017}Low bound must be less than or equal to the high bound.%mdk + +%mdk-data-line={3018} +\item\mdline{3018}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3018} match must be omitted.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3020} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3021} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.range().low()))\\ +assert(BytestringValid(match.range().high()))\\ +\\ +low~=~parseInteger(match.range().low())\\ +high~=~parseInteger(match.range().high())\\ +\\ +assert(low~\textless{}=~high)\\ +\\ +assert(low~!=~min\_field\_value~\textbar{}\textbar{}~high~!=~max\_field\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3032} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3032} +\item\mdline{3032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3032} match + +%mdk-data-line={3033} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3033} +\item\mdline{3033}The binary string encoding of the value must conform to the +\mdline{3034}\mdref{sec-bytestrings}{Bytestrings}\mdline{3034} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3036} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3037} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.optional().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3040} +\subsubsection{\mdline{3040}9.1.2.\hspace*{0.5em}\mdline{3040}Action Specification}\label{sec-action-specification}%mdk%mdk + +%mdk-data-line={3042} +\noindent\mdline{3042}The \mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3042} \mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3042} field must be set for every \mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3042} update but may be +left unset for \mdline{3043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3043} updates, in which case the action specification for the +table entry will not be modified (if a \mdline{3044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3044} update has an unset action field +and does not modify any direct resource attached to the table then the \mdline{3045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3045} +update is a no-op). Based on the implementation property value of the P4 table, +the \mdline{3047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3047} in the \mdline{3047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3047} message will either be:%mdk + +%mdk-data-line={3049} +\begin{itemize}%mdk + +%mdk-data-line={3049} +\item{} +%mdk-data-line={3049} +\mdline{3049}an \mdline{3049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3049} specification for direct tables (with no P4 \mdline{3049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3049} +property)%mdk%mdk + +%mdk-data-line={3052} +\item{} +%mdk-data-line={3052} +\mdline{3052}an action profile member id for indirect tables for which the \mdline{3052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3052} +property is an action profile with no selector.%mdk%mdk + +%mdk-data-line={3055} +\item{} +%mdk-data-line={3055} +\mdline{3055}an action profile member id or group id for indirect tables for which the +\mdline{3056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3056} property is an action profile with selector.%mdk%mdk + +%mdk-data-line={3058} +\item{} +%mdk-data-line={3058} +\mdline{3058}an \mdline{3058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3058} specification for indirect tables for +which the \mdline{3059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3059} property is an action profile with +selector. This usage is described in\mdline{3060}~\mdref{sec-oneshot}{One Shot Action Selector +Programming}\mdline{3061}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3063} +\noindent\mdline{3063}If the \mdline{3063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3063} does not match the table description in the P4Info (\mdline{3063}e.g.\mdline{3063} the +\mdline{3064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3064} is \mdline{3064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member\_id}}}\mdline{3064} for a direct table), the server must +return an \mdline{3065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3065} error code.%mdk + +%mdk-data-line={3067} +\mdline{3067}The \mdline{3067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3067} Protobuf message has the following fields:%mdk + +%mdk-data-line={3069} +\begin{itemize}%mdk + +%mdk-data-line={3069} +\item{} +%mdk-data-line={3069} +\mdline{3069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3069}, which identifies the action instance; the \mdline{3069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3069} is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an \mdline{3071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3071} error +code. If the client uses a valid \mdline{3072}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3072} for the table but does not +respect the action scope specified in P4Info (\mdline{3073}e.g.\mdline{3073} tries to set a \mdline{3073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{3073} +action as the default action), the server must return a \mdline{3074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3074} +error code.%mdk%mdk + +%mdk-data-line={3077} +\item{} +%mdk-data-line={3077} +\mdline{3077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{3077}: a repeated Protobuf field of action parameter values, each encoded +as a \mdline{3078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{3078} message. For each parameter, \mdline{3078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}param\_id}}}\mdline{3078} must be valid for the +action (as per the P4Info) and value must follow the format described in +\mdline{3080}\mdref{sec-bytestrings}{Bytestrings}\mdline{3080}. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3082} error code +if a parameter id is missing, if an extra parameter\mdline{3083} \mdline{3083}\textemdash{}\mdline{3083} id not found in the +P4Info\mdline{3084} \mdline{3084}\textemdash{}\mdline{3084} was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +\mdline{3086}\mdref{sec-bytestrings}{Bytestrings}\mdline{3086} format.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3088} +\noindent\mdline{3088}For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a \mdline{3090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3090} error code.%mdk + +%mdk-data-line={3092} +\subsubsection{\mdline{3092}9.1.3.\hspace*{0.5em}\mdline{3092}Default Entry}\label{sec-default-entry}%mdk%mdk + +%mdk-data-line={3094} +\noindent\mdline{3094}According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer\mdline{3095} \mdline{3095}\textemdash{}\mdline{3095} or defaults to \mdline{3095}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3095} +(which is a no-op) otherwise\mdline{3096} \mdline{3096}\textemdash{}\mdline{3096} and assuming it is not declared as \mdline{3096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3096}, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow \mdline{3098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3098} and \mdline{3098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3098} updates on the default entry and the +P4Runtime server must return an \mdline{3099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3099} error code if the client +attempts one.%mdk + +%mdk-data-line={3102} +\mdline{3102}The default entry is identified by setting the \mdline{3102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3102} boolean field +to true. When this flag is set to true, the repeated \mdline{3103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3103} field must be empty +and the \mdline{3104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3104} field must be set to zero, otherwise the P4Runtime server +must return an \mdline{3105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3105} error code. When performing a \mdline{3105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3105} update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its \mdline{3109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3109} and \mdline{3109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3109} value as well as the +configurations for its\mdline{3110}~\mdref{sec-direct-resources}{direct resources}\mdline{3110} will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a \mdline{3112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3112} +error code if the client attempts to modify it.%mdk + +%mdk-data-line={3115} +\mdline{3115}Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to\mdline{3116}~\mdref{sec-direct-resources}{direct resources}\mdline{3116}.%mdk + +%mdk-data-line={3118} +\mdline{3118}In this P4Runtime release, we have decided to restrict the default entry for +indirect tables\mdline{3119} \mdline{3119}\textemdash{}\mdline{3119} tables with an ActionProfile or ActionSelector +\mdline{3120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3120} property\mdline{3120} \mdline{3120}\textemdash{}\mdline{3120} to a constant \mdline{3120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3120} action entry, with the +hope that it would simplify the implementation of the P4Runtime service.%mdk + +%mdk-data-line={3123} +\subsubsection{\mdline{3123}9.1.4.\hspace*{0.5em}\mdline{3123}Constant Tables}\label{sec-constant-tables}%mdk%mdk + +%mdk-data-line={3125} +\noindent\mdline{3125}Constant tables are defined as tables whose match entries are immutable. They +are identified by the \mdline{3126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3126} flag in P4Info.%mdk + +%mdk-data-line={3128} +\mdline{3128}The only write updates which are allowed for constant tables are \mdline{3128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3128} +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +\mdline{3132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3132} error. Just like any table entry \mdline{3132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3132} request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a \mdline{3136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3136} error.%mdk + +%mdk-data-line={3138} +\mdline{3138}The contents of const tables can be queried by the client through a +\mdline{3139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3139}. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: \mdline{3140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3140}, \mdline{3140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3140}, \mdline{3140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3140}, +\mdline{3141}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3141}, and \mdline{3141}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3141} (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the \mdline{3144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3144} field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P4\mdline{3146}\mdsub{16}\mdline{3146} does not support assigning explicit priorities to static +entries. When a priority value is required (\mdline{3147}e.g.\mdline{3147} for tables including \mdline{3147}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3147}, +\mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3148} or \mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3148} matches), it is inferred based on the order in which +entries appear in the table declaration.%mdk + +%mdk-data-line={3151} +\subsubsection{\mdline{3151}9.1.5.\hspace*{0.5em}\mdline{3151}Wildcard Reads}\label{sec-table-wildcard-reads}%mdk%mdk + +%mdk-data-line={3153} +\noindent\mdline{3153}When performing a \mdline{3153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3153}, the P4Runtime client can select all entries +from one or all tables on the target and use several of the \mdline{3154}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3154} fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as \mdline{3158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3158} and \mdline{3158}\textquotedblleft{}unset\textquotedblright{}\mdline{3158} for message fields such as \mdline{3158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3158}. The following +fields may be used to select and filter results:%mdk + +%mdk-data-line={3161} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3161} +\item\mdline{3161}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3161}: If default (0), entries from all tables\mdline{3161} \mdline{3161}\textemdash{}\mdline{3161} including constant +tables\mdline{3162} \mdline{3162}\textemdash{}\mdline{3162} will be selected and no other filter can be used. Otherwise only +the specified table will be considered.%mdk + +%mdk-data-line={3164} +\item\mdline{3164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3164}: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned.%mdk + +%mdk-data-line={3168} +\item\mdline{3168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3168}: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an \mdline{3169}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3169} (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id.%mdk + +%mdk-data-line={3175} +\item\mdline{3175}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3175}: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value.%mdk + +%mdk-data-line={3178} +\item\mdline{3178}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3178}: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +\mdline{3180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3180} value.%mdk + +%mdk-data-line={3181} +\item\mdline{3181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3181}: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided \mdline{3183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3183} value.%mdk + +%mdk-data-line={3184} +\item\mdline{3184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3184}: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered.%mdk + +%mdk-data-line={3187} +\item\mdline{3187}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{3187}: If default (unset), all table entries will be considered. Otherwise, +table entries will be filtered based on the provided role value.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3190} +\noindent\mdline{3190}For example, in order to read all entries from all tables from device 3, the +client can use the following \mdline{3191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3191} message.%mdk + +%mdk-data-line={3193} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3194} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0}\\ +~~~~priority:~{\mdcolor{purple}0}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3205} +\noindent\mdline{3205}In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following \mdline{3206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3206} +message:%mdk + +%mdk-data-line={3209} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3210} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~priority:~{\mdcolor{purple}11}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3221} +\noindent\mdline{3221}The canonical representation of \mdline{3221}\textquotedblleft{}don't care\textquotedblright{}\mdline{3221} matches, combined with the ability +to do a wildcard read on all table entries by leaving the \mdline{3222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3222} field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single \mdline{3224}\textquotedblleft{}don't care\textquotedblright{}\mdline{3224} entry or to do a wildcard +read. If a table has no fields with match kind \mdline{3225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3225}, it is possible via +P4Runtime to add an entry that is \mdline{3226}\textquotedblleft{}don't care\textquotedblright{}\mdline{3226} for all fields (\mdline{3226}i.e.\mdline{3226} has an empty +\mdline{3227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3227} field) but is not the default entry (\mdline{3227}i.e.\mdline{3227} \mdline{3227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3227} is +false). When reading this entry from the table, there is no way to read \mdline{3228}\emph{only}\mdline{3228} +that entry from the table, because it would require providing an unset \mdline{3229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3229} +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single \mdline{3232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{3232} match:%mdk + +%mdk-data-line={3234} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3235} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;~fwd;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3245} +\noindent\mdline{3245}The following \mdline{3245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3245} message can be used to add 2 entries:%mdk + +%mdk-data-line={3246} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3247} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{~{\mdcolor{darkgreen}\#~don't~care~entry}\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +~~table~entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~match~\{\\ +~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~lpm~\{\\ +~~~~~~~~value:~{\mdcolor{purple}0x0a000000}\\ +~~~~~~~~prefix\_len:~{\mdcolor{purple}8}\\ +~~~~~~\}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3266} +\noindent\mdline{3266}The first entry is a \mdline{3266}\textquotedblleft{}don't care\textquotedblright{}\mdline{3266} entry, while the second one matches all +\mdline{3267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}10.0.0.0/8}}}\mdline{3267} addresses. The second entry has higher priority than the first one.%mdk + +%mdk-data-line={3269} +\mdline{3269}The following \mdline{3269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3269} message will return \mdline{3269}\emph{all}\mdline{3269} entries in the table, not +just the \mdline{3270}\textquotedblleft{}don't care\textquotedblright{}\mdline{3270} entry.%mdk + +%mdk-data-line={3271} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3272} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3280} +\noindent\mdline{3280}This issue also exists for tables with \mdline{3280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3280}, \mdline{3280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3280}, and \mdline{3280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3280} +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the \mdline{3283}\textquotedblleft{}don't care\textquotedblright{}\mdline{3283} entry will be returned to the +client. If the client uses distinct priority values for all entries\mdline{3284} \mdline{3284}\textemdash{}\mdline{3284} which is +strongly recommended to achieve\mdline{3285}~\mdref{sec-table-entry}{deterministic behavior}\mdline{3285} \mdline{3285}\textemdash{}\mdline{3285}, +then there is no ambiguity because the wildcard read will actually return a +single entry (the \mdline{3287}\textquotedblleft{}don't care\textquotedblright{}\mdline{3287} entry) as long as the \mdline{3287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3287} field is set to +the correct value.%mdk + +%mdk-data-line={3290} +\subsubsection{\mdline{3290}9.1.6.\hspace*{0.5em}\mdline{3290}Direct Resources}\label{sec-direct-resources}%mdk%mdk + +%mdk-data-line={3292} +\noindent\mdline{3292}In addition to the \mdline{3292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3292} and \mdline{3292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3292} entities, +P4Runtime support reading and writing direct resources as part of the +\mdline{3294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3294} message. This is convenient for two reasons:%mdk + +%mdk-data-line={3296} +\begin{itemize}%mdk + +%mdk-data-line={3296} +\item{} +%mdk-data-line={3296} +\mdline{3296}A table entry and its direct resources can be read with a single entity when +doing a \mdline{3297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{3297} RPC call%mdk%mdk + +%mdk-data-line={3299} +\item{} +%mdk-data-line={3299} +\mdline{3299}The initial configuration for an entry\mdline{3299}'\mdline{3299}s direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can \mdline{3304}\textquotedblleft{}hit\textquotedblright{}\mdline{3304} the table entry without +executing the appropriate meter entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3307} +\noindent\mdline{3307}Once the table entry has been inserted, the P4Runtime client is free to use the +\mdline{3308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3308} and \mdline{3308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3308} messages for read and write +operations on \mdline{3309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3309} and \mdline{3309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3309} instances. For example, it is +usually more convenient as well as more efficient to use \mdline{3310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3310} to +query a counter entry value rather than use \mdline{3311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3311}, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry.%mdk + +%mdk-data-line={3315} +\mdline{3315}The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does \mdline{3316}\emph{not}\mdline{3316} need to be \mdline{3316}\textquotedblleft{}executed\textquotedblright{}\mdline{3316} in +every action bound to the table. It is an error to provide a direct resource +configuration in a \mdline{3318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3318} message when programming an action that does not +execute the direct resource, and the server must return an \mdline{3319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3319} +error code.%mdk + +%mdk-data-line={3322} +\mdline{3322}We leverage Protobuf\mdline{3322}'\mdline{3322}s ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the \mdline{3324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3324} message. The list below describes how +the server must handle the \mdline{3325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3325}, \mdline{3325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3325} and +\mdline{3326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3326} fields for read and write requests, based on whether the +fields are set or not. We do not cover error cases in the list, \mdline{3327}i.e.\mdline{3327} we assume +that we are dealing with a table which is assigned a direct counter / a direct +meter, and that the action being used for the table entry \mdline{3329}\textquotedblleft{}executes\textquotedblright{}\mdline{3329} the direct +resource appropriately.%mdk + +%mdk-data-line={3332} +\begin{itemize}%mdk + +%mdk-data-line={3332} +\item{} +%mdk-data-line={3332} +\mdline{3332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3332} field%mdk + +%mdk-data-line={3333} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3333} +\item\mdline{3333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3333} + +%mdk-data-line={3334} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3334} +\item\mdline{3334}if \mdline{3334}\textbf{unset}\mdline{3334}: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets).%mdk + +%mdk-data-line={3336} +\item\mdline{3336}if \mdline{3336}\textbf{set}\mdline{3336}: The initial configuration for the meter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3338} +\item\mdline{3338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3338} + +%mdk-data-line={3339} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3339} +\item\mdline{3339}if \mdline{3339}\textbf{unset}\mdline{3339}: The meter entry\mdline{3339}'\mdline{3339}s configuration is reset to the default +(meter returns GREEN for all packets).%mdk + +%mdk-data-line={3341} +\item\mdline{3341}if \mdline{3341}\textbf{set}\mdline{3341}: The value provided by the client is used to re-configure +the meter entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3343} +\item\mdline{3343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3343} + +%mdk-data-line={3344} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3344} +\item\mdline{3344}if \mdline{3344}\textbf{unset}\mdline{3344}: The response does not include the meter entry\mdline{3344}'\mdline{3344}s +configuration (\mdline{3345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3345} is unset in the response).%mdk + +%mdk-data-line={3346} +\item\mdline{3346}if \mdline{3346}\textbf{set}\mdline{3346}: If the meter entry\mdline{3346}'\mdline{3346}s configuration is the default +configuration, \mdline{3347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3347} is unset in the response. Otherwise, the +response includes the meter entry\mdline{3348}'\mdline{3348}s configuration that was written by +the client earlier. This respects the \mdline{3349}\textquotedblleft{}read-write symmetry\textquotedblright{}\mdline{3349} principle.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3351} +\item{} +%mdk-data-line={3351} +\mdline{3351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3351} field%mdk + +%mdk-data-line={3352} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3352} +\item\mdline{3352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3352} + +%mdk-data-line={3353} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3353} +\item\mdline{3353}if \mdline{3353}\textbf{unset}\mdline{3353}: The initial value for the counter entry is the default +(0).%mdk + +%mdk-data-line={3355} +\item\mdline{3355}if \mdline{3355}\textbf{set}\mdline{3355}: The initial value for the counter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3357} +\item\mdline{3357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3357} + +%mdk-data-line={3358} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3358} +\item\mdline{3358}if \mdline{3358}\textbf{unset}\mdline{3358}: The counter entry\mdline{3358}'\mdline{3358}s value is not changed.%mdk + +%mdk-data-line={3359} +\item\mdline{3359}if \mdline{3359}\textbf{set}\mdline{3359}: The value provided by the client is written to the counter +entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3361} +\item\mdline{3361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3361} + +%mdk-data-line={3362} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3362} +\item\mdline{3362}if \mdline{3362}\textbf{unset}\mdline{3362}: The response does not include the counter entry\mdline{3362}'\mdline{3362}s value +(\mdline{3363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3363} is unset in the response).%mdk + +%mdk-data-line={3364} +\item\mdline{3364}if \mdline{3364}\textbf{set}\mdline{3364}: The response includes the counter entry\mdline{3364}'\mdline{3364}s value read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3367} +\item{} +%mdk-data-line={3367} +\mdline{3367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3367} field%mdk + +%mdk-data-line={3368} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3368} +\item\mdline{3368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3368} + +%mdk-data-line={3369} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3369} +\item\mdline{3369}if \mdline{3369}\textbf{unset}\mdline{3369}: The initial value for all 3 counter entries is the +default (0).%mdk + +%mdk-data-line={3371} +\item\mdline{3371}if \mdline{3371}\textbf{set}\mdline{3371}: The initial value for all 3 counter entries is the +default (0). Sub-field, if any, can only have zero (0) as its value. +\mdline{3373}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3373} error is returned for any non-zero sub-field value.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3374} +\item\mdline{3374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3374} + +%mdk-data-line={3375} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3375} +\item\mdline{3375}if \mdline{3375}\textbf{unset}\mdline{3375}: All the 3 counter entries are unchanged.%mdk + +%mdk-data-line={3376} +\item\mdline{3376}if \mdline{3376}\textbf{set}\mdline{3376}: All the 3 counters are reset to 0. Sub-field, if any, can +only have zero (0) as its value. \mdline{3377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3377} error is returned +for any non-zero sub-field value.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3379} +\item\mdline{3379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3379} + +%mdk-data-line={3380} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3380} +\item\mdline{3380}if \mdline{3380}\textbf{unset}\mdline{3380}: The response does not include counter values +(\mdline{3381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3381} is unset in the response).%mdk + +%mdk-data-line={3382} +\item\mdline{3382}if \mdline{3382}\textbf{set}\mdline{3382}: The response includes all the 3 counter values read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3385} +\noindent\mdline{3385}In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +\mdline{3387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3387} field unset when inserting \mdline{3387}\textbf{or modifying}\mdline{3387} a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the \mdline{3389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3389} message +(\mdline{3390}i.e.\mdline{3390} the \mdline{3390}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3390} field must be set to match the existing configuration).%mdk + +%mdk-data-line={3392} +\subsubsection{\mdline{3392}9.1.7.\hspace*{0.5em}\mdline{3392}Idle-timeout}\label{sec-idle-timeout}%mdk%mdk + +%mdk-data-line={3394} +\noindent\mdline{3394}P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not \mdline{3396}\textquotedblleft{}hit\textquotedblright{}\mdline{3396} (\mdline{3396}i.e.\mdline{3396} not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification\mdline{3398} \mdline{3398}\textemdash{}\mdline{3398} using the +\mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3399} message\mdline{3399} \mdline{3399}\textemdash{}\mdline{3399} to the primary client, which can then take +action, such as remove the idle table entry.%mdk + +%mdk-data-line={3402} +\mdline{3402}Two fields of the \mdline{3402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3402} Protobuf message are used to implement idle +timeout:%mdk + +%mdk-data-line={3405} +\begin{itemize}%mdk + +%mdk-data-line={3405} +\item{} +%mdk-data-line={3405} +\mdline{3405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3405}: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, \mdline{3406}i.e.\mdline{3406} no +\mdline{3407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3407} message will ever be generated for this entry. When +a client reads a \mdline{3408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3408}, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry.%mdk%mdk + +%mdk-data-line={3412} +\item{} +%mdk-data-line={3412} +\mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3412}: a Protobuf message with a single field (\mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{3412}) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The \mdline{3414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3414} field must be unset for a +\mdline{3415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3415} write. When reading a table entry, \mdline{3415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3415} must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3420} +\noindent\mdline{3420}These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an \mdline{3422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3422} error code if at least one of these +conditions is met:%mdk + +%mdk-data-line={3425} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3425} +\item\mdline{3425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3425} is set to a non-zero value, or%mdk + +%mdk-data-line={3426} +\item\mdline{3426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3426} is set%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3428} +\noindent\mdline{3428}The target should do its best to approximate the \mdline{3428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3428} value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the \mdline{3431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3431} write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for \mdline{3433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3433}.%mdk + +%mdk-data-line={3435} +\mdline{3435}P4Runtime does not support idle timeout for default entries. When the +\mdline{3436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3436} flag is set in a \mdline{3436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3436} message, \mdline{3436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3436} +must be set to 0 (default) and \mdline{3437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3437} must be unset. If the +server receives a \mdline{3438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3438} message which violates this, it must return an +\mdline{3439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3439} error.%mdk + +%mdk-data-line={3441} +\mdline{3441}For more information about idle timeout, in particular regarding +\mdline{3442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3442}, please refer to the\mdline{3442}~\mdref{sec-table-idle-timeout-notification}{Table idle timeout +notifications}\mdline{3443} section.%mdk + +%mdk-data-line={3445} +\subsection{\mdline{3445}9.2.\hspace*{0.5em}\mdline{3445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3445} \mdline{3445}\&\mdline{3445} \mdline{3445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}\label{sec-action-profile-member-and-group}%mdk%mdk + +%mdk-data-line={3447} +\noindent\mdline{3447}P4Runtime defines an API for programming a PSA ActionProfile extern using +\mdline{3448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3448} messages. A PSA ActionSelector extern can be programmed +using both \mdline{3449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3449} and \mdline{3449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3449} messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table \mdline{3453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3453} for L3 routing, implemented with an action +selector \mdline{3454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3454}.%mdk + +%mdk-data-line={3456} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3457} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector(HashAlgorithm.crc32,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}size~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w1024,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}output\_width~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w10)~as;\\ +\\ +{\bfseries{\mdcolor{navy}action}}~set\_nhop(PortId\_t~p,~EthAddr~smac,~EthAddr~dmac)~\{\\ +~~istd.egress\_port~=~p;\\ +~~hdr.ethernet.smac~=~smac;\\ +~~hdr.ethernet.dmac~=~dmac;\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;~~{\mdcolor{darkgreen}//~LPM~on~destination~IP~address}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~set\_nhop;\\ +~~\}\\ +~~implementation~=~as;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3478} +\noindent\mdline{3478}When programming table \mdline{3478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3478} in the example above, a P4Runtime client should +specify the \mdline{3479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3479} in the \mdline{3479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3479} to be a reference to either an +action profile member or group. The reference is a non-zero \mdline{3480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3480} identifier +that uniquely identifies a member or group programmed in the action selector +\mdline{3482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3482}.%mdk + +%mdk-data-line={3484} +\mdline{3484}If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata.%mdk + +%mdk-data-line={3489} +\mdline{3489}If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata.%mdk + +%mdk-data-line={3500} +\subsubsection{\mdline{3500}9.2.1.\hspace*{0.5em}\mdline{3500}Action Profile Member Programming}\label{sec-action-profile-member-programming}%mdk%mdk + +%mdk-data-line={3502} +\noindent\mdline{3502}Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a \mdline{3503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3503} identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the \mdline{3505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3505} +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the \mdline{3507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3507} attributes of the +tables \mdline{3508}\emph{must have an identical list of P4 actions}\mdline{3508}. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector.%mdk + +%mdk-data-line={3512} +\mdline{3512}An \mdline{3512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3512} entity update message has the following fields:%mdk + +%mdk-data-line={3514} +\begin{itemize}%mdk + +%mdk-data-line={3514} +\item{} +%mdk-data-line={3514} +\mdline{3514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3514} is the \mdline{3514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3514} identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3517} +\item{} +%mdk-data-line={3517} +\mdline{3517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3517} is the non-zero \mdline{3517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3517} identifier of the action profile member +entry being updated.%mdk%mdk + +%mdk-data-line={3520} +\item{} +%mdk-data-line={3520} +\mdline{3520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3520} is the specification of the P4 action instance bound to the action +profile member entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3523} +\noindent\mdline{3523}An action profile member may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3526} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3526} +\item\mdline{3526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3526}: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an \mdline{3528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3528} error +code. The action specification must be provided, or the server must return +\mdline{3530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3530}. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return \mdline{3532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3532}.%mdk + +%mdk-data-line={3533} +\item\mdline{3533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3533}: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return \mdline{3534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3534}, +and the action specification must be provided, or the server must return +\mdline{3536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3536}.%mdk + +%mdk-data-line={3537} +\item\mdline{3537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3537}: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a \mdline{3538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3538} error code. The member +must not be part of an action profile group, or the server must return +\mdline{3540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3540}. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return \mdline{3543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3543}. \mdline{3543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3543} and \mdline{3543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3543} are the only +fields that are considered when performing a \mdline{3544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3544} and every other field +will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3547} +\noindent\mdline{3547}When reading, an \mdline{3547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3547} message with \mdline{3547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3547} and +\mdline{3548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3548} equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with \mdline{3549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3549} equal to the id of +an existing ActionProfile or ActionSelector object, and a \mdline{3550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3550} equal to +0, will read all members of that specified object.%mdk + +%mdk-data-line={3553} +\subsubsection{\mdline{3553}9.2.2.\hspace*{0.5em}\mdline{3553}Action Profile Group Programming}\label{sec-action-profile-group-programming}%mdk%mdk + +%mdk-data-line={3555} +\noindent\mdline{3555}Action profile groups are entries in an ActionSelector and are referenced by a +\mdline{3556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3556} identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type.%mdk + +%mdk-data-line={3560} +\mdline{3560}Within a single ActionSelector object, the \mdline{3560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3560} values used to identify its +members are in a separate \mdline{3561}\textquoteleft{}scope\textquoteright{}\mdline{3561} from the \mdline{3561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3561} values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5.%mdk + +%mdk-data-line={3565} +\mdline{3565}There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it.%mdk + +%mdk-data-line={3571} +\mdline{3571}An \mdline{3571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3571} entity update message has the following fields:%mdk + +%mdk-data-line={3573} +\begin{itemize}%mdk + +%mdk-data-line={3573} +\item{} +%mdk-data-line={3573} +\mdline{3573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3573} is the \mdline{3573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3573} identifier of the PSA ActionSelector +extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3576} +\item{} +%mdk-data-line={3576} +\mdline{3576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3576} is the non-zero \mdline{3576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3576} identifier of the action profile group +entry being updated.%mdk%mdk + +%mdk-data-line={3579} +\item{} +%mdk-data-line={3579} +\mdline{3579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3579} is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields:%mdk + +%mdk-data-line={3582} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3582} +\item\mdline{3582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3582} for looking up the member table in the selector.%mdk + +%mdk-data-line={3583} +\item\mdline{3583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3583} specifying the probability of the member\mdline{3583}'\mdline{3583}s selection at +runtime. 0 is not a valid \mdline{3584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3584} value and the server must return +\mdline{3585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3585} if the client attempts to use it.%mdk + +%mdk-data-line={3586} +\item\mdline{3586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3586} is the controller-defined port that the member\mdline{3586}'\mdline{3586}s +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +\mdline{3589}\mdref{action-selector-constraints}{9.2.4}\mdline{3589} for notes on the behavior if all members in +a group are excluded for this reason. If \mdline{3590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3590} is empty, then the +member is always included in the selection, regardless of the status of +any port of the device. The value must be empty or the SDN port of an +existing port on the device, otherwise the server must return +\mdline{3594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3594}.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3596} +\item{} +%mdk-data-line={3596} +\mdline{3596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3596} is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +\mdline{3598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3598} update. See the subsection below for the\mdline{3598}~\mdref{sec-max-size-rules}{rules on setting +\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\mdline{3599}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3601} +\noindent\mdline{3601}An action profile group may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3604} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3604} +\item\mdline{3604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3604}: Add a new group entry bound to a set of existing action profile +members. \mdline{3605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}The~group\_id}}}\mdline{3605} must be different from ids of already programmed +groups for that selector, or the server must return an \mdline{3606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3606} error +code. All members specified in the group must exist in the selector, or the +server must return \mdline{3608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3608}. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target.%mdk + +%mdk-data-line={3610} +\item\mdline{3610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3610}: Modify the member set specification of an existing group entry. An +entry with the \mdline{3611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3611} must exist, or the server must return +\mdline{3612}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3612}. All members specified in the group entry must exist in the +selector, or the server must return \mdline{3613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3613}. The value of \mdline{3613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3613} must +be identical to the value used when inserting the group, otherwise an +\mdline{3615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3615} error is returned.%mdk + +%mdk-data-line={3616} +\item\mdline{3616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3616}: Delete the group entry and deallocate the \mdline{3616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3616}. The group must +not be referenced in the table action of any table entry, or the server must +return a \mdline{3618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3618} error code. If the \mdline{3618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3618} is invalid, the +server must return \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3619}. \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3619} and \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3619} are the +only fields that are considered when performing a \mdline{3620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3620} and every other +field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3623} +\noindent\mdline{3623}When setting the group membership with \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3623} or \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3623}, the \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3623} +repeated field must not include duplicates, \mdline{3624}i.e.\mdline{3624} members with the same +\mdline{3625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3625}. The \mdline{3625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3625} field is used instead to logically \mdline{3625}\textquotedblleft{}repeat\textquotedblright{}\mdline{3625} the member +inside the group.%mdk + +%mdk-data-line={3628} +\mdline{3628}It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation \mdline{3629}\textquotedblleft{}stores\textquotedblright{}\mdline{3629} the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made.%mdk + +%mdk-data-line={3633} +\mdline{3633}When reading, an \mdline{3633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3633} message with \mdline{3633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3633} and +\mdline{3634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3634} equal to 0 will read all groups of all ActionSelector objects. A +message with \mdline{3635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3635} equal to the id of an existing ActionSelector +object, and a \mdline{3636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3636} equal to 0, will read all groups of that one specified +object.%mdk + +%mdk-data-line={3639} +\paragraph{\mdline{3639}9.2.2.1.\hspace*{0.5em}\mdline{3639}Rules on Setting \mdline{3639}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\label{sec-max-size-rules}%mdk%mdk + +%mdk-data-line={3641} +\noindent\mdline{3641}The valid values for \mdline{3641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3641} depend on the static \mdline{3641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3641} included +in the P4Info message:%mdk + +%mdk-data-line={3644} +\begin{itemize}%mdk + +%mdk-data-line={3644} +\item{} +%mdk-data-line={3644} +\mdline{3644}If \mdline{3644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3644} is greater than 0, then \mdline{3644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3644} must be greater than 0, +and less than or equal to \mdline{3645}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3645}. We assume that the target can +support selector groups for which the sum of all member weights is up to +\mdline{3647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3647}, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If \mdline{3648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3648} is greater than \mdline{3648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3648}, the server +must return \mdline{3649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3649}.%mdk%mdk + +%mdk-data-line={3651} +\item{} +%mdk-data-line={3651} +\mdline{3651}Otherwise (\mdline{3651}i.e.\mdline{3651} if \mdline{3651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3651} is 0), the P4Runtime client can set +\mdline{3652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3652} to any value greater than or equal to 0.%mdk + +%mdk-data-line={3654} +\begin{itemize}%mdk + +%mdk-data-line={3654} +\item{} +%mdk-data-line={3654} +\mdline{3654}A \mdline{3654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3654} of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (\mdline{3657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3657} or \mdline{3657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3657}), the target must return a +\mdline{3658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3658} error.%mdk%mdk + +%mdk-data-line={3660} +\item{} +%mdk-data-line={3660} +\mdline{3660}If \mdline{3660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3660} is greater than 0 and the value is not supported by the +target, the server must return a \mdline{3661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3661} error at +group-creation time.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3664} +\subsubsection{\mdline{3664}9.2.3.\hspace*{0.5em}\mdline{3664}One Shot Action Selector Programming}\label{sec-oneshot}%mdk%mdk + +%mdk-data-line={3666} +\noindent\mdline{3666}P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids.%mdk + +%mdk-data-line={3672} +\mdline{3672}One shots are programmed by choosing the \mdline{3672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3672} message as the +\mdline{3673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3673}. The \mdline{3673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3673} message consists of a set of +\mdline{3674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3674} messages, which in turn have the following fields:%mdk + +%mdk-data-line={3676} +\begin{itemize}%mdk + +%mdk-data-line={3676} +\item{} +%mdk-data-line={3676} +\mdline{3676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3676} is one of the actions specified by the table that is being +programmed.%mdk%mdk + +%mdk-data-line={3679} +\item{} +%mdk-data-line={3679} +\mdline{3679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3679} specifying the probability of the action\mdline{3679}'\mdline{3679}s selection at runtime. 0 is +not a valid \mdline{3680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3680} value and the server must return \mdline{3680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3680} if +the client attempts to use it. The sum of all weights across all +\mdline{3682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3682} messages for that \mdline{3682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3682} message must +not exceed the \mdline{3683}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3683} specificed in the P4Info (if greater than 0), +or the server must return \mdline{3684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3684}.%mdk%mdk + +%mdk-data-line={3686} +\item{} +%mdk-data-line={3686} +\mdline{3686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3686} is the controller-defined port that the action\mdline{3686}'\mdline{3686}s liveness depends +on. At runtime, the action must be excluded from selection if the watch port +is down. See Section\mdline{3688}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{3688} for more details +on the \mdline{3689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3689} field, which also apply for one shot action selector +programming.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3693} +\noindent\mdline{3693}Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics.%mdk + +%mdk-data-line={3698} +\mdline{3698}To preserve read-write symmetry, an implementation must answer \mdline{3698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3698}s +with the original one shot messages. It may not return a desugared version of +the one shot message.%mdk + +%mdk-data-line={3702} +\mdline{3702}For example, consider the action selector table defined +\mdline{3703}\mdref{sec-action-profile-member-and-group}{here}\mdline{3703}. This table could be programmed +with the following one shot update:%mdk + +%mdk-data-line={3706} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3707} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{\\ +~~~~action\_profile\_action\_set~\{\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}1}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x01}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}2}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x02}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}3}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x03}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3732} +\noindent\mdline{3732}Which would be equivalent to the following updates, where \mdline{3732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GROUP\_ID}}}\mdline{3732}, +\mdline{3733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_1}}}\mdline{3733}, \mdline{3733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_2}}}\mdline{3733}, and \mdline{3733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_3}}}\mdline{3733} are unused ids:%mdk + +%mdk-data-line={3735} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3736} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_1\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_2\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_3\\ +~~action~\{~~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +\}\\ +action\_profile\_group~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~group\_id:~GROUP\_ID\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_1\\ +~~~~weight:~{\mdcolor{purple}1}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x01}{\mdcolor{maroon}"}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_2\\ +~~~~weight:~{\mdcolor{purple}2}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x02}{\mdcolor{maroon}"}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_3\\ +~~~~weight:~{\mdcolor{purple}3}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x03}{\mdcolor{maroon}"}\\ +~~\}\\ +\}\\ +table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{~action\_profile\_group\_id:~GROUP\_ID~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3777} +\noindent\mdline{3777}Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure\mdline{3778}~\mdref{sec-batching-and-ordering-of-updates}{correct ordering between the dependent +updates}\mdline{3779}. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct \mdline{3781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3781} batches are required.%mdk + +%mdk-data-line={3783} +\mdline{3783}It is possible to include several \mdline{3783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3783} messages with the same +exact \mdline{3784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3784} specification in one \mdline{3784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3784} message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the \mdline{3786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3786} field. Note that to preserve read-write symmetry, the server +must not coalesce multiple \mdline{3787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3787} messages with the same \mdline{3787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3787} +specification into one.%mdk + +%mdk-data-line={3790} +\mdline{3790}All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with \mdline{3791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3791} and +\mdline{3792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3792} messages. Programming some entries with one shots, and +other entries with \mdline{3793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3793} and \mdline{3793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3793} messages is +not allowed, and the server must return the error code \mdline{3794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3794} in +that case.%mdk + +%mdk-data-line={3797} +\mdline{3797}A P4Runtime server \mdline{3797}\emph{must}\mdline{3797} support the one shot style of programming tables with +an action selector implementation. Support for the \mdline{3798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3798} and +\mdline{3799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3799} style is \mdline{3799}\emph{optional}\mdline{3799}. If \mdline{3799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3799} and +\mdline{3800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3800} are not supported by a server, it must return an +\mdline{3801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3801} error for every \mdline{3801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3801} or \mdline{3801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3801} +message that it receives.%mdk + +%mdk-data-line={3804} +\subsubsection{\mdline{3804}9.2.4.\hspace*{0.5em}\mdline{3804}Constraints on action selector programming}\label{action-selector-constraints}%mdk%mdk + +%mdk-data-line={3806} +\noindent\mdline{3806}The PSA specification states that the following features are \mdline{3806}\emph{optional}\mdline{3806} in +action selector implementations\mdline{3807}~[\mdcite{psaactionselector}{22}]\mdline{3807}:%mdk + +%mdk-data-line={3809} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3809} +\item\mdline{3809}Support for non-empty groups where in the same group, different members are +bound to different actions.%mdk + +%mdk-data-line={3811} +\item\mdline{3811}Predictable data plane behavior when a matched table entry points to an empty +group.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={3814} +\noindent\mdline{3814}For 1., if a client tries to \mdline{3814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3814} or \mdline{3814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3814} a group with members bound to +different actions, the server should return \mdline{3815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3815} if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return \mdline{3821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3821} (modifying the action parameter values must be +supported, however).%mdk + +%mdk-data-line={3824} +\mdline{3824}PSA 1.1 introduces the \mdline{3824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3824} table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. \mdline{3828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3828} is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of \mdline{3831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3831} at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +\mdline{3833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3833}. Even when \mdline{3833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3833} is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of \mdline{3837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3837} mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming.%mdk + +%mdk-data-line={3842} +\mdline{3842}The PSA specification includes a discussion on how to implement +\mdline{3843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3843} in software in the P4Runtime server +\mdline{3844}[\mdcite{psaemptygroupactionappendix}{25}]\mdline{3844}.%mdk + +%mdk-data-line={3846} +\mdline{3846}If a P4Runtime implementation does support \mdline{3846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3846}, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down.%mdk + +%mdk-data-line={3850} +\mdline{3850}If a P4Runtime implementation does not support \mdline{3850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3850}, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down.%mdk + +%mdk-data-line={3856} +\subsection{\mdline{3856}9.3.\hspace*{0.5em}\mdline{3856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3856} \mdline{3856}\&\mdline{3856} \mdline{3856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-counterentry-directcounterentry}%mdk%mdk + +%mdk-data-line={3858} +\noindent\mdline{3858}PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The \mdline{3860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3860} +P4Runtime message can be used for all three types of PSA counters\mdline{3861} \mdline{3861}\textemdash{}\mdline{3861} \mdline{3861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{3861}, +\mdline{3862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{3862} and \mdline{3862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3862} \mdline{3862}\textemdash{}\mdline{3862} and consists of the following fields:%mdk + +%mdk-data-line={3864} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3864} +\item\mdline{3864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3864} is an \mdline{3864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3864}, corresponding to the number of octets.%mdk + +%mdk-data-line={3865} +\item\mdline{3865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3865} is an \mdline{3865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3865}, corresponding to the number of packets.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3867} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3868} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterData~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~byte\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}int64}}~packet\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3874} +\noindent\mdline{3874}P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of \mdline{3875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3875} and \mdline{3875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3875} fields, which +is equivalent to specifying the counter type \mdline{3876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3876}. Counters may +be defined as direct or indirect (indexed) instances.%mdk + +%mdk-data-line={3879} +\subsubsection{\mdline{3879}9.3.1.\hspace*{0.5em}\mdline{3879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-directcounterentry}%mdk%mdk + +%mdk-data-line={3881} +\noindent\mdline{3881}A direct counter is a direct resource associated with a \mdline{3881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3881} (see +\mdline{3882}\mdref{sec-direct-resources}{Direct Resources}\mdline{3882}). The \mdline{3882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3882} field of the +\mdline{3883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3883} message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +\mdline{3886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3886} message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed.%mdk + +%mdk-data-line={3889} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3890} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectCounterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3896} +\noindent\mdline{3896}A \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3896} may only include an \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3896} message of type \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3896} with a +\mdline{3897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3897}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3899} +\begin{itemize}%mdk + +%mdk-data-line={3899} +\item{} +%mdk-data-line={3899} +\mdline{3899}the \mdline{3899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3899} field must match \mdline{3899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry.match}}}\mdline{3899} of the table entry +to which this direct counter entry is associated. If a matching \mdline{3900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3900} +is not found, the server returns the error code \mdline{3901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3901}.%mdk%mdk + +%mdk-data-line={3903} +\item{} +%mdk-data-line={3903} +\mdline{3903}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3903} is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3907} +\noindent\mdline{3907}Specifying \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3907} in an \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3907} message of type \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3907} or +\mdline{3908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3908} is not allowed, and the server must return the error code +\mdline{3909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3909} in that case.%mdk + +%mdk-data-line={3911} +\mdline{3911}A client may use \mdline{3911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3911} in two ways to read the contents of a +\mdline{3912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3912}:%mdk + +%mdk-data-line={3914} +\begin{itemize}%mdk + +%mdk-data-line={3914} +\item{} +%mdk-data-line={3914} +\mdline{3914}As a direct resource associated with a table entry, request the server to +return the counter value in the \mdline{3915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3915} field of the \mdline{3915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3915} message +(see\mdline{3916}~\mdref{sec-direct-resources}{Direct resources}\mdline{3916}).%mdk%mdk + +%mdk-data-line={3918} +\item{} +%mdk-data-line={3918} +\mdline{3918}Explicitly request the counter value by including the \mdline{3918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3918} in +the \mdline{3919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3919}. The \mdline{3919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3919} field must match the \mdline{3919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3919} +whose counter is being read. If no such entry is found, the server returns the +error code \mdline{3921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3921}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3923} +\subsubsection{\mdline{3923}9.3.2.\hspace*{0.5em}\mdline{3923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}\label{sec-counterentry}%mdk%mdk + +%mdk-data-line={3925} +\noindent\mdline{3925}An indirect or indexed counter is not associated with a specific \mdline{3925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3925} +and may be updated independently of any action. It may be read or written using +the P4Runtime \mdline{3927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3927} message whose fields are defined as follows:%mdk + +%mdk-data-line={3929} +\begin{itemize}%mdk + +%mdk-data-line={3929} +\item{} +%mdk-data-line={3929} +\mdline{3929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3929} is a \mdline{3929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3929}, the unique identifier for the counter.%mdk%mdk + +%mdk-data-line={3931} +\item{} +%mdk-data-line={3931} +\mdline{3931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3931} is a Protobuf message that encapsulates an \mdline{3931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3931}, used to index into +the counter array.%mdk%mdk + +%mdk-data-line={3934} +\item{} +%mdk-data-line={3934} +\mdline{3934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3934} is a Protobuf message of type \mdline{3934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3934}, which represents the +counter value.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3937} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3938} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~counter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3945} +\noindent\mdline{3945}The \mdline{3945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3945} can only be used in a \mdline{3945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3945} with the \mdline{3945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3945} update +type. The P4Runtime server must return an \mdline{3946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3946} error code for +update types \mdline{3947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3947} and \mdline{3947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3947}. By default all the counter entries in the +array have default value 0.%mdk + +%mdk-data-line={3950} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3950} +\item\mdline{3950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3950}: Server returns the error code \mdline{3950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3950}.%mdk + +%mdk-data-line={3951} +\item\mdline{3951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3951}: Modify an indirect counter instance whose unique id is \mdline{3951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3951} +and array index is specified by \mdline{3952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3952}. The counter value is set to the value +specified by the client in the \mdline{3953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3953} field. Note that the counter value is +not modified if this Protobuf field is not set. If \mdline{3954}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3954} is omitted all +counter values in the array will be set to the value provided by the +client. The server must return \mdline{3956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3956} for a negative index value +and \mdline{3957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3957} if the index value exceeds the size of the counter array.%mdk + +%mdk-data-line={3958} +\item\mdline{3958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3958}: Server returns the error code \mdline{3958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3958}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3960} +\noindent\mdline{3960}A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a \mdline{3961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3961} by including a \mdline{3961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3961} +entity for each of the instances, specifying the \mdline{3962}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3962} and +\mdline{3963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3963}. Wildcard reads are also supported as follows.%mdk + +%mdk-data-line={3965} +\begin{itemize}%mdk + +%mdk-data-line={3965} +\item{} +%mdk-data-line={3965} +\mdline{3965}If the \mdline{3965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3965} field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the \mdline{3966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3966}.%mdk%mdk + +%mdk-data-line={3968} +\item{} +%mdk-data-line={3968} +\mdline{3968}If the \mdline{3968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3968} field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id \mdline{3969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3969}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3971} +\subsection{\mdline{3971}9.4.\hspace*{0.5em}\mdline{3971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3971} \mdline{3971}\&\mdline{3971} \mdline{3971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-meterentry-directmeterentry}%mdk%mdk + +%mdk-data-line={3973} +\noindent\mdline{3973}Meters are an advanced mechanism for keeping statistics, involving stateful +\mdline{3974}\textquotedblleft{}marking\textquotedblright{}\mdline{3974} and usually \mdline{3974}\textquotedblleft{}throttling\textquotedblright{}\mdline{3974} of packets based on configured rates of +traffic. The PSA metering function is based on the \mdline{3975}\emph{Two Rate Three Color Marker}\mdline{3975} +(trTCM) defined in RFC 2698\mdline{3976}~[\mdcite{rfc2698}{2}]\mdline{3976}. The trTCM meters an arbitrary packet +stream using two configured rates\mdline{3977} \mdline{3977}\textemdash{}\mdline{3977} the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes\mdline{3978} \mdline{3978}\textemdash{}\mdline{3978} and +\mdline{3979}\textquotedblleft{}marks\textquotedblright{}\mdline{3979} its packets as GREEN, YELLOW or RED based on the observed rate.%mdk + +%mdk-data-line={3981} +\mdline{3981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3981} \mdline{3981}\&\mdline{3981} \mdline{3981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3981} have an additional field \mdline{3981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3981} that +may hold per color counter data for targets that support it, and that must +always be unset for targets that do not support it. If set in a request and +unsupported by a target, an \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3984} error code should be returned. +These counters provide a granular list of the counters applicable to the +possible meter colors GREEN, YELLOW and RED. The counter associated with a +specific color is incremented when a packet is \mdline{3987}\textquotedblleft{}marked\textquotedblright{}\mdline{3987} with that color. The +primary purpose of the color counters is for debugging purposes.%mdk + +%mdk-data-line={3990} +\mdline{3990}A meter may be configured as a direct or indirect instance, similar to a +counter. The \mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{3991} P4Runtime message represents meter configuration.%mdk + +%mdk-data-line={3993} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3994} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterConfig~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~cir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~Committed~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~cburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};~~{\mdcolor{darkgreen}//~Committed~Burst~Size}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};~~{\mdcolor{darkgreen}//~Peak~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};~~{\mdcolor{darkgreen}//~Peak~Burst~Size}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4002} +\subsubsection{\mdline{4002}9.4.1.\hspace*{0.5em}\mdline{4002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-directmeterentry}%mdk%mdk + +%mdk-data-line={4004} +\noindent\mdline{4004}A direct meter is a direct resource associated with a \mdline{4004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4004} (see\mdline{4004}~\mdref{sec-direct-resources}{Direct +resources}\mdline{4005}). The \mdline{4005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{4005} field of the \mdline{4005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4005} +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +\mdline{4009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4009} message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed.%mdk + +%mdk-data-line={4012} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4013} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectMeterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterCounterData~counter\_data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4020} +\noindent\mdline{4020}A \mdline{4020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4020} may only include an \mdline{4020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4020} message of type \mdline{4020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4020} with a +\mdline{4021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4021}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={4023} +\begin{itemize}%mdk + +%mdk-data-line={4023} +\item{} +%mdk-data-line={4023} +\mdline{4023}the \mdline{4023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4023} field must match the match key of the \mdline{4023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4023} +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching \mdline{4025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4025} is not found, +the server returns the error code \mdline{4026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4026}.%mdk%mdk + +%mdk-data-line={4028} +\item{} +%mdk-data-line={4028} +\mdline{4028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4028} is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets).%mdk%mdk + +%mdk-data-line={4032} +\item{} +%mdk-data-line={4032} +\mdline{4032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4032} is used to set the per color counter values to the default +value of (0), which is essentially clearing the counters. If the field is +unset, the counter values are left untouched. If the field is set, targets +supporting these counters should reset all the color counters to (0), if any +of the sub-fields are set to a non-zero value, then an \mdline{4036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4036} +error should be returned.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4039} +\noindent\mdline{4039}Specifying \mdline{4039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4039} in an \mdline{4039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4039} message of type \mdline{4039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4039} or +\mdline{4040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4040} is not allowed, and the server must return the error code +\mdline{4041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4041} in that case.%mdk + +%mdk-data-line={4043} +\mdline{4043}A client may use \mdline{4043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4043} in two ways to read a \mdline{4043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{4043} config.%mdk + +%mdk-data-line={4045} +\begin{itemize}%mdk + +%mdk-data-line={4045} +\item{} +%mdk-data-line={4045} +\mdline{4045}As a direct resource associated with a table entry, request the server to +return the meter config in the \mdline{4046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{4046} field of the \mdline{4046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4046} +message (see\mdline{4047}~\mdref{sec-direct-resources}{Direct resources}\mdline{4047}).%mdk%mdk + +%mdk-data-line={4049} +\item{} +%mdk-data-line={4049} +\mdline{4049}Explicitly request the meter configuration by including the \mdline{4049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4049} +in the \mdline{4050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4050}. The \mdline{4050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4050} field must match the +\mdline{4051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4051} whose meter config is being read. If no such entry is found, the +server returns the error code \mdline{4052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4052}. Read responses also include the +per color counter data for the meter entry, if supported and specified in +the request message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4056} +\subsubsection{\mdline{4056}9.4.2.\hspace*{0.5em}\mdline{4056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}\label{sec-meterentry}%mdk%mdk + +%mdk-data-line={4058} +\noindent\mdline{4058}An indirect or indexed meter is not associated with a specific \mdline{4058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4058} and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime \mdline{4060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4060} message whose fields are defined as +follows:%mdk + +%mdk-data-line={4063} +\begin{itemize}%mdk + +%mdk-data-line={4063} +\item{} +%mdk-data-line={4063} +\mdline{4063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4063} is a \mdline{4063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4063}, the unique identifier for the meter.%mdk%mdk + +%mdk-data-line={4065} +\item{} +%mdk-data-line={4065} +\mdline{4065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4065} is a Protobuf message that encapsulates an \mdline{4065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4065}, used to index into +a meter array.%mdk%mdk + +%mdk-data-line={4068} +\item{} +%mdk-data-line={4068} +\mdline{4068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4068} is a Protobuf message of type \mdline{4068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{4068}, which represents the +meter configuration.%mdk%mdk + +%mdk-data-line={4071} +\item{} +%mdk-data-line={4071} +\mdline{4071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4071} is a Protobuf message of type \mdline{4071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4071}, which +represents the per color counter values associated with the corresponding +meter.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4075} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4076} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~meter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~MeterCounterData~counter\_data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4084} +\noindent\mdline{4084}The \mdline{4084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4084} can only be used in a \mdline{4084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4084} with the \mdline{4084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4084} update +type. The P4Runtime server must return an \mdline{4085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4085} error code for +update types \mdline{4086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4086} and \mdline{4086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4086}. By default all the meter entries in the +array have a default configuration (GREEN for all packets).%mdk + +%mdk-data-line={4089} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4089} +\item\mdline{4089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4089}: Server returns the error code \mdline{4089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4089}.%mdk + +%mdk-data-line={4090} +\item\mdline{4090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4090}: Modify an indirect meter instance whose unique id is \mdline{4090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4090} and +array index is specified by \mdline{4091}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4091}. The meter is reconfigured using the +\mdline{4092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4092} field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the \mdline{4094}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4094} field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if \mdline{4096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4096} is unset). The server must return \mdline{4096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4096} for a +negative index value and \mdline{4097}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4097} if the index value exceeds the size of +the meter array.%mdk + +%mdk-data-line={4099} +\item\mdline{4099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4099}: Server returns the error code \mdline{4099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4099}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4101} +\noindent\mdline{4101}A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a \mdline{4102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4102} by including a \mdline{4102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4102} entity for each +of the instances, specifying the \mdline{4103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4103} and \mdline{4103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4103}. Wildcard reads are also +supported as follows:%mdk + +%mdk-data-line={4106} +\begin{itemize}%mdk + +%mdk-data-line={4106} +\item{} +%mdk-data-line={4106} +\mdline{4106}If the \mdline{4106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4106} field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the \mdline{4107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4107}.%mdk%mdk + +%mdk-data-line={4109} +\item{} +%mdk-data-line={4109} +\mdline{4109}If the \mdline{4109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4109} field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id \mdline{4110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4110}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4112} +\subsubsection{\mdline{4112}9.4.3.\hspace*{0.5em}\mdline{4112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}}\label{sec-metercounterdata}%mdk%mdk + +%mdk-data-line={4114} +\noindent\mdline{4114}The \mdline{4114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4114} P4Runtime message represents the per color counters +associated with a meter entry. Whenever a meter is executed and returns +a color, the corresponding color counter GREEN, YELLOW or RED is updated.%mdk + +%mdk-data-line={4118} +\mdline{4118}As seen above, these counters can be associated with a \mdline{4118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4118} or +\mdline{4119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4119}. Targets not capable of supporting these counters should return +\mdline{4120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4120} if a \mdline{4120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4120} field was set in a read or write +request.%mdk + +%mdk-data-line={4123} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4124} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterCounterData~\{\\ +~~CounterData~green~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~yellow~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~red~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4132} +\subsection{\mdline{4132}9.5.\hspace*{0.5em}\mdline{4132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}\label{sec-packetreplicationengineentry}%mdk%mdk + +%mdk-data-line={4134} +\noindent\mdline{4134}The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets.%mdk + +%mdk-data-line={4140} +\subsubsection{\mdline{4140}9.5.1.\hspace*{0.5em}\mdline{4140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}\label{sec-multicastgroupentry}%mdk%mdk + +%mdk-data-line={4142} +\noindent\mdline{4142}Multicasting is achieved in PSA programs by setting the \mdline{4142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4142} +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the \mdline{4145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4145} API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example.%mdk + +%mdk-data-line={4150} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4151} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~arp\_multicast({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ethernet.isValid()~\&\&\\ +~~~~~~~~hdr.ethernet.eth\_type~==~ETH\_TYPE\_ARP)~\{\\ +~~~~~~smeta.multicast\_group~=~(MulticastGroup\_t)~{\mdcolor{purple}1};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4161} +\noindent\mdline{4161}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4164} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4165} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~multicast\_group\_entry~\{\\ +~~~~~~multicast\_group\_id:~{\mdcolor{purple}1}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}5}~instance:~{\mdcolor{purple}1}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}12}~instance:~{\mdcolor{purple}2}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}18}~instance:~{\mdcolor{purple}3}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}24}~instance:~{\mdcolor{purple}4}~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4179} +\noindent\mdline{4179}As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +\mdline{4184}\mdref{sec-translation-of-port-numbers}{PSA Metadata Translation}\mdline{4184} section.%mdk + +%mdk-data-line={4186} +\mdline{4186}The egress packets may be distinguished for further processing in the egress +using the \mdline{4187}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4187} metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 \mdline{4189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4189} metadata is set to a value that is not +programmed in the PRE, then the packet is dropped.%mdk + +%mdk-data-line={4192} +\mdline{4192}A multicast group may be inserted, modified or deleted as per the following +semantics.%mdk + +%mdk-data-line={4195} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4195} +\item\mdline{4195}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4195}: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The \mdline{4196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4196} field is a \mdline{4196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4196} and must be greater +than 0 (see explanation\mdline{4197}~\mdref{sec-valid-values-for-mg-id}{below}\mdline{4197}), or the +P4Runtime server must return an \mdline{4198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4198} error. The replica +\mdline{4199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4199} ID is also a \mdline{4199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4199}, and its value may not exceed the maximum +allowed by the target for the \mdline{4200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4200} type (0 is allowed), or the +server must return an \mdline{4201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4201} error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of \mdline{4203}\emph{both}\mdline{4203} \mdline{4203}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{4203} and \mdline{4203}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4203}, or the server +must return \mdline{4204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4204}.%mdk + +%mdk-data-line={4205} +\item\mdline{4205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4205}: Modify the set of replicas for a given multicast group entry, +indexed by the given \mdline{4206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4206}. Same restrictions as \mdline{4206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4206} apply +here.%mdk + +%mdk-data-line={4208} +\item\mdline{4208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4208}: Delete the multicast group indexed by the given +\mdline{4209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4209}. The replicas need not be provided for this +operation. Any packets with their \mdline{4210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4210} metadata in the data plane +set to the deleted \mdline{4211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4211} will be dropped.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4213} +\noindent\mdline{4213}When reading a multicast group, only \mdline{4213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4213} is considered. All +other fields in \mdline{4214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4214} are ignored. To perform a \mdline{4214}\emph{wildcard}\mdline{4214} +\mdline{4215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4215} on all configured multicast group entries, the \mdline{4215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4215} field +must be set to 0, its default value.%mdk + +%mdk-data-line={4218} +\paragraph{\mdline{4218}9.5.1.1.\hspace*{0.5em}\mdline{4218}Valid Values for \mdline{4218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}}\label{sec-valid-values-for-mg-id}%mdk%mdk + +%mdk-data-line={4220} +\noindent\mdline{4220}The PSA specification states that the valid \mdline{4220}\emph{data plane}\mdline{4220} values for multicast +group ids (\mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroup\_t}}}\mdline{4221}) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target\mdline{4223}~[\mdcite{psatranslation}{24}]\mdline{4223}. This means that, in the absence of +translation, the client must set the \mdline{4224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4224} field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special \mdline{4226}\emph{wildcard}\mdline{4226} value which is used to read all the multicast groups +configured in the target, the \mdline{4227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4227} field must never be set to 0 +when performing a \mdline{4228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4228} RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value.%mdk + +%mdk-data-line={4233} +\subsubsection{\mdline{4233}9.5.2.\hspace*{0.5em}\mdline{4233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}\label{sec-clonesessionentry}%mdk%mdk + +%mdk-data-line={4235} +\noindent\mdline{4235}PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +\mdline{4239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4239} identifier and a boolean flag \mdline{4239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone}}}\mdline{4239} in the packet +metadata. The \mdline{4240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4240} serves as a handle to the clone attributes, +namely a set \mdline{4241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}replicas}}}\mdline{4241} of \mdline{4241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(egress~port,~instance)}}}\mdline{4241} pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +\mdline{4244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4244} API.%mdk + +%mdk-data-line={4246} +\mdline{4246}The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the \mdline{4249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_low\_ttl}}}\mdline{4249} control block is applied in the ingress +pipeline to create an ingress-to-egress clone.%mdk + +%mdk-data-line={4252} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4253} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~clone\_low\_ttl({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ipv4.isValid()~\&\&\\ +~~~~~~~~hdr.ipv4.ttl~\textless{}=~LOW\_TTL\_THRESHOLD)~\{\\ +~~~~~~smeta.clone\_session\_id~=~{\mdcolor{purple}10}w100;\\ +~~~~~~smeta.clone~=~{\bfseries{\mdcolor{navy}true}};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4265} +\noindent\mdline{4265}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4268} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4269} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~clone\_session\_entry~\{\\ +~~~~~~session\_id:~{\mdcolor{purple}100}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}0xfffffffd}~instance:~{\mdcolor{purple}1}~\}~{\mdcolor{darkgreen}\#~to~CPU}\\ +~~~~~~class\_of\_service:~{\mdcolor{purple}2}\\ +~~~~~~packet\_length\_bytes:~{\mdcolor{purple}4096}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4282} +\noindent\mdline{4282}As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type \mdline{4286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4286}~[\mdcite{psatranslation}{24}]\mdline{4286}). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes.%mdk + +%mdk-data-line={4291} +\mdline{4291}The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port \mdline{4292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfffffffd}}}\mdline{4292}; see +\mdline{4293}\mdref{sec-translation-of-port-numbers}{Translation of Port Numbers}\mdline{4293}). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port.%mdk + +%mdk-data-line={4296} +\mdline{4296}If the \mdline{4296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4296} data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created.%mdk + +%mdk-data-line={4299} +\mdline{4299}A clone session may be inserted, modified or deleted as per the following +semantics:%mdk + +%mdk-data-line={4302} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4302} +\item\mdline{4302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4302}: Add a new clone session entry bound to a set of egress ports and +replica IDs. The \mdline{4303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4303} is a \mdline{4303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4303} and must be greater than 0 (see +explanation\mdline{4304}~\mdref{sec-valid-values-for-session-id}{below}\mdline{4304}), or the P4Runtime +server must return an \mdline{4305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4305} error. The replica \mdline{4305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4305} ID is +also a \mdline{4306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4306}, and its value may not exceed the maximum allowed by the +target for the \mdline{4307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4307} type (0 is allowed), or the server must also +return an \mdline{4308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4308} error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (\mdline{4311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}class\_of\_service}}}\mdline{4311} field). This value must be a valid +value for the PSA \mdline{4312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ClassOfService\_t}}}\mdline{4312} type, which supports runtime translation +by default\mdline{4313}~[\mdcite{psatranslation}{24}]\mdline{4313}, or the server must return +\mdline{4314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4314}. See\mdline{4314}~\mdref{sec-translation-of-port-numbers}{PSA Metadata +Translation}\mdline{4315} for more information. The +\mdline{4316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4316} field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +\mdline{4318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4318} field is 0 (default), no truncation on the clone will be +performed.%mdk + +%mdk-data-line={4320} +\item\mdline{4320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4320}: Modify the attributes of a given clone session entry, indexed by the +given \mdline{4321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4321}. Same restrictions as \mdline{4321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4321} apply here.%mdk + +%mdk-data-line={4322} +\item\mdline{4322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4322}: Delete the clone session indexed by the given +\mdline{4323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4323}. Other fields need not be provided for this operation. Any +packet with their \mdline{4324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4324} metadata in the data plane set to the +deleted \mdline{4325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4325} will no longer be cloned.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4327} +\noindent\mdline{4327}When reading a clone session, only \mdline{4327}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4327} is considered. All other fields +in \mdline{4328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4328} are ignored. To perform a \mdline{4328}\emph{wildcard}\mdline{4328} \mdline{4328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4328} on all +configured clone session entries, the \mdline{4329}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4329} field must be set to 0, its +default value. The \mdline{4330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4330} field can never be equal to 0 in a \mdline{4330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4330} +RPC. If it does, the server must return an \mdline{4331}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4331} error.%mdk + +%mdk-data-line={4333} +\paragraph{\mdline{4333}9.5.2.1.\hspace*{0.5em}\mdline{4333}Valid Values for \mdline{4333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}}\label{sec-valid-values-for-session-id}%mdk%mdk + +%mdk-data-line={4335} +\noindent\mdline{4335}The PSA specification states that the valid \mdline{4335}\emph{data plane}\mdline{4335} values for clone +session ids (\mdline{4336}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4336}) range from 0 to the maximum value supported by +the target\mdline{4337}~[\mdcite{psatranslation}{24}]\mdline{4337}. Note that unlike for\mdline{4337}~\mdref{sec-valid-values-for-mg-id}{multicast group +ids}\mdline{4338}, 0 is a valid \mdline{4338}\emph{data plane}\mdline{4338} value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special \mdline{4340}\emph{wildcard}\mdline{4340} value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a \mdline{4341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4341} +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is \mdline{4343}\emph{not}\mdline{4343} enabled, we effectively +\mdline{4344}\textquotedblleft{}lose\textquotedblright{}\mdline{4344} one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (\mdline{4345}e.g.\mdline{4345} because the target supports a very +limited number of clone sessions), one can enable translation on +\mdline{4347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4347} and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id.%mdk + +%mdk-data-line={4350} +\subsection{\mdline{4350}9.6.\hspace*{0.5em}\mdline{4350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}\label{sec-valuesetentry}%mdk%mdk + +%mdk-data-line={4352} +\noindent\mdline{4352}Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the \mdline{4356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4356} state.%mdk + +%mdk-data-line={4358} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4359} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}state}}~parse\_l2~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}(MAX\_TRILL\_TYPES)~trill\_types;}\\ +~~extract(hdr.ethernet);\\ +~~{\bfseries{\mdcolor{navy}select}}~(hdr.ethernet.eth\_type)~\{\\ +~~~~ETH\_TYPE\_IPV4:~parse\_ipv4;\\ +~~~~ETH\_TYPE\_IPV6:~parse\_ipv6;\\ +~~~~trill\_types:~~~parse\_trill\_types;\\ +~~~~\_:~~~~~~~~~~~~~reject;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4371} +\noindent\mdline{4371}The corresponding entry in the P4Info for this Value Set is:%mdk + +%mdk-data-line={4373} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4374} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}trill\_types}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~\textless{}MAX\_TRILL\_TYPES\textgreater{}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4388} +\noindent\mdline{4388}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4391} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4392} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x22f3}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x893b}~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4410} +\noindent\mdline{4410}As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the \mdline{4412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4412} state.%mdk + +%mdk-data-line={4414} +\mdline{4414}A \mdline{4414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4414} entity update message has the following fields:%mdk + +%mdk-data-line={4416} +\begin{itemize}%mdk + +%mdk-data-line={4416} +\item{} +%mdk-data-line={4416} +\mdline{4416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4416} is the \mdline{4416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4416} identifier of the Value Set instance, as +defined in P4Info.%mdk%mdk + +%mdk-data-line={4419} +\item{} +%mdk-data-line={4419} +\mdline{4419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4419} is a repeated field of type \mdline{4419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4419}. When \mdline{4419}\textquotedblleft{}selecting\textquotedblright{}\mdline{4419} +against a Value Set, every member will be considered and if at least one +\mdline{4421}\textquotedblleft{}matches\textquotedblright{}\mdline{4421}, the corresponding parser transition will be taken. Each +\mdline{4422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4422} contains a repeated field of \mdline{4422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4422} messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a \mdline{4424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4424} if and only if +it matches all its \mdline{4425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4425} messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. \mdline{4427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4427} messages in a \mdline{4427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4427} follow +the\mdline{4428}~\mdref{sec-match-format}{same rules}\mdline{4428} as in a \mdline{4428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4428}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4430} +\noindent\mdline{4430}A \mdline{4430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4430} may only be modified. If the update type is \mdline{4430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4430} or +\mdline{4431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4431}, the server must return an \mdline{4431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4431} error. If the update type +is \mdline{4432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4432}, the server writes the members given in the repeated field to the +Value Set entry indexed by the given \mdline{4433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4433}. The maximum number of +matches must not exceed the maximum size given by the \mdline{4434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{4434} field in P4Info of +the Value Set, otherwise the server must return a \mdline{4435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4435} error. To +empty a Value Set (\mdline{4436}i.e.\mdline{4436} restore it to its initial state), the P4Runtime client +can perform a \mdline{4437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4437} update with an empty \mdline{4437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4437} repeated field.%mdk + +%mdk-data-line={4439} +\mdline{4439}To facilitate\mdline{4439}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{4439}, the server must +return an \mdline{4440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4440} error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set.%mdk + +%mdk-data-line={4446} +\mdline{4446}See Appendix\mdline{4446}~\mdref{sec-value-set-example}{A.3}\mdline{4446} for a more complex Value Set example.%mdk + +%mdk-data-line={4448} +\subsection{\mdline{4448}9.7.\hspace*{0.5em}\mdline{4448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}\label{sec-registerentry}%mdk%mdk + +%mdk-data-line={4450} +\noindent\mdline{4450}The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The \mdline{4451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4451} P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations.%mdk + +%mdk-data-line={4455} +\mdline{4455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4455} has the following fields:%mdk + +%mdk-data-line={4457} +\begin{itemize}%mdk + +%mdk-data-line={4457} +\item{} +%mdk-data-line={4457} +\mdline{4457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4457}, which identifies the PSA Register extern instance which is +being accessed by the client; the \mdline{4458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4458} is specified by the P4Info +message.%mdk%mdk + +%mdk-data-line={4461} +\item{} +%mdk-data-line={4461} +\mdline{4461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4461}, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4463} message +used for the request. When an \mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4464} is provided , the server must validate +its value, and return \mdline{4465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4465} for a negative index or +\mdline{4466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4466} if the index exceeds the size of the register array.%mdk%mdk + +%mdk-data-line={4468} +\item{} +%mdk-data-line={4468} +\mdline{4468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4468}: the data to be written to the array (if \mdline{4468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4468} is part of a +\mdline{4469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4469} message) or the data read from the array (if \mdline{4469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4469} is +part of a \mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4470} message). The \mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4470} field is a \mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{4470} message and +must match the format described by the \mdline{4471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{4471} field of the corresponding +Register entry in the P4Info, or the server must return an \mdline{4472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4472} +error.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4475} +\subsection{\mdline{4475}9.8.\hspace*{0.5em}\mdline{4475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}\label{sec-digestentry}%mdk%mdk + +%mdk-data-line={4477} +\noindent\mdline{4477}A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly.%mdk + +%mdk-data-line={4482} +\mdline{4482}The \mdline{4482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4482} P4Runtime entity is used to \mdline{4482}\textbf{configure}\mdline{4482} how the device must +generate digest messages. The \mdline{4483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4483} Protobuf message is not used to +carry digest data, which is done on the \mdline{4484}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4484} bidirectional stream +using the \mdline{4485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4485} (digest data sent by the target to the client) and +\mdline{4486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4486} (digest data acknowledgments sent by the client to the target) +Protobuf messages.%mdk + +%mdk-data-line={4489} +\mdline{4489}In this section, we refer to the data learned by a single data plane call to +\mdline{4490}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}T\textgreater{}::pack}}}\mdline{4490} as a \mdline{4490}\textquotedblleft{}digest message\textquotedblright{}\mdline{4490} and we use \mdline{4490}\textquotedblleft{}digest list\textquotedblright{}\mdline{4490} to designate +the list of digest messages bundled by the P4Runtime service in a single +\mdline{4492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4492} stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are \mdline{4494}\textquotedblleft{}duplicate\textquotedblright{}\mdline{4494} if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are \mdline{4495}\textquotedblleft{}distinct\textquotedblright{}\mdline{4495} +if they are not duplicate.%mdk + +%mdk-data-line={4498} +\mdline{4498}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4498} has the following fields:%mdk + +%mdk-data-line={4500} +\begin{itemize}%mdk + +%mdk-data-line={4500} +\item{} +%mdk-data-line={4500} +\mdline{4500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4500}, which identifies the PSA Digest extern instance which emitted the +data; the \mdline{4501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4501} is determined by the P4Info message.%mdk%mdk + +%mdk-data-line={4503} +\item{} +%mdk-data-line={4503} +\mdline{4503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4503}, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +\mdline{4505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4505}; these parameters are:%mdk + +%mdk-data-line={4507} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4507} +\item\mdline{4507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4507}: the maximum server buffering delay in nanoseconds for an +outstanding digest message.%mdk + +%mdk-data-line={4509} +\item\mdline{4509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4509}: the maximum digest list size\mdline{4509} \mdline{4509}\textemdash{}\mdline{4509} in number of digest +messages\mdline{4510} \mdline{4510}\textemdash{}\mdline{4510} sent by the server to the client as a single \mdline{4510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4510} +Protobuf message.%mdk + +%mdk-data-line={4512} +\item\mdline{4512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4512}: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4516} +\noindent\mdline{4516}Here is the significance of the different \mdline{4516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4516} types for \mdline{4516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4516}:%mdk + +%mdk-data-line={4518} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4518} +\item\mdline{4518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4518}: Enable server generation of \mdline{4518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4518} messages for given digest +instance and use provided configuration parameters.%mdk + +%mdk-data-line={4520} +\item\mdline{4520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4520}: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance.%mdk + +%mdk-data-line={4522} +\item\mdline{4522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4522}: Disable server generation of \mdline{4522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4522} messages for given digest +instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4525} +\noindent\mdline{4525}A server should buffer digest messages until either:%mdk + +%mdk-data-line={4527} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4527} +\item\mdline{4527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4527} time has passed since the first digest message was added to +the empty buffer, or%mdk + +%mdk-data-line={4529} +\item\mdline{4529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4529} \mdline{4529}\emph{distinct}\mdline{4529} digest messages have been received from the +data plane and added to the buffer%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4532} +\noindent\mdline{4532}At which point the server should, with best effort, generate a \mdline{4532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4532} +stream message with the buffer contents and send it to the primary client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software.%mdk + +%mdk-data-line={4538} +\mdline{4538}To avoid sending duplicate digest messages across different \mdline{4538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4538} +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the primary client indicates that it has received the +digest list and acted on it. The server must keep a \mdline{4541}\textquotedblleft{}cache\textquotedblright{}\mdline{4541} containing the set +of all digest messages that have been sent, but not acknowledged yet by the +primary client, up-to \mdline{4543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4543} in the past. The server must delete all +cache entries for a given digest list when they are at least \mdline{4544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4544} +old or when a matching \mdline{4545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4545} message (\mdline{4545}i.e.\mdline{4545} with the same \mdline{4545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4545} +and \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}list\_id}}}\mdline{4546} fields as the \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4546} message) is received.%mdk + +%mdk-data-line={4548} +\mdline{4548}The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged \mdline{4553}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4553} messages.%mdk + +%mdk-data-line={4555} +\mdline{4555}When \mdline{4555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4555} is set to 0 and / or \mdline{4555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4555} is set to 1, the +server should, with best effort, generate a \mdline{4556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4556} message for every +digest message generated by the data plane which is not already in the cache. If +\mdline{4558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4558} is set to 0, the cache must always be an empty set. If +\mdline{4559}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4559} is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +\mdline{4561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4561} configuration parameter.%mdk + +%mdk-data-line={4563} +\mdline{4563}The P4Runtime server may empty the digest message cache in case of a client +status change.%mdk + +%mdk-data-line={4566} +\mdline{4566}Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server:%mdk + +%mdk-data-line={4569} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4570} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestStream~stream;\\ +DigestCache~cache;\\ +DigestBuffer~buffers;\\ +\\ +{\mdcolor{darkgreen}//~sends~digest~list~when~it~is~ready}\\ +send\_buffer(Id~digest\_id)~\{\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~stream.write(DigestList(buffer));\\ +~~cache.merge(buffer);~~{\mdcolor{darkgreen}//~updates~cache~with~new~digest~list}\\ +~~buffer.clear();\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~data~plane~digest~messages~from~device}\\ +handle\_dataplane\_digest(Digest~msg)~\{\\ +~~digest\_id~=~msg.digest\_id();\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~{\bfseries{\mdcolor{navy}if}}~(msg~in~cache~{\mdcolor{teal}OR}~msg~in~buffer)~{\bfseries{\mdcolor{navy}return}};\\ +~~buffer.enqueue(msg);\\ +~~{\bfseries{\mdcolor{navy}if}}~(buffer.length()~\textless{}~max\_list\_size(digest\_id))~{\bfseries{\mdcolor{navy}return}};\\ +~~send\_buffer(digest\_id);\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~ack~messages~received~on~the~stream}\\ +handle\_stream\_ack(DigestListAck~ack)~\{\\ +~~{\mdcolor{darkgreen}//~clear~all~cache~entries~matching~the~tuple~(digest\_id,~list\_id)}\\ +~~cache.erase(~(ack.digest\_id(),~ack.list\_id()~)\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~loop~to~enforce~timeouts}\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~now~=~now();\\ +~~{\mdcolor{darkgreen}//~check~for~buffers~that~need~to~be~sent}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~buffer)~in~buffers)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~buffer.first\_enq\_time()~\textgreater{}=~max\_timeout\_ns(digest\_id))\\ +~~~~~~send\_buffer(buffer\_id);\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~check~for~expired~entries~in~cache}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~list\_id,~sent\_time)~in~cache)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~sent\_time~\textgreater{}=~ack\_timeout\_ns(digest\_id))\\ +~~~~~~cache.erase(~(digest\_id,~list\_id)~);\\ +~~\}\\ +~~sleep({\mdcolor{teal}X});\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4615} +\subsection{\mdline{4615}9.9.\hspace*{0.5em}\mdline{4615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\label{sec-extern-entry}%mdk%mdk + +%mdk-data-line={4617} +\noindent\mdline{4617}This is used to support a P4 extern entity that is not part of PSA. It is +defined as:%mdk + +%mdk-data-line={4620} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4621} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ExternEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_type\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~google.protobuf.Any~entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4628} +\noindent\mdline{4628}Each \mdline{4628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4628} entity maps to an \mdline{4628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{4628} message in the +\mdline{4629}\mdref{sec-p4info-extern}{P4Info}\mdline{4629} and an \mdline{4629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4629} message within that +message. The \mdline{4630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{4630} field must be equal to the one in +\mdline{4631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4631}. The \mdline{4631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_id}}}\mdline{4631} field must be equal to the ID included in the +\mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{4632} of the corresponding \mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4632} message.%mdk + +%mdk-data-line={4634} +\mdline{4634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entry}}}\mdline{4634} itself is embedded as an \mdline{4634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{4634} Protobuf message\mdline{4634}~[\mdcite{protoany}{31}]\mdline{4634} to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on\mdline{4638}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{4639} for more information.%mdk + +%mdk-data-line={4641} +\section{\mdline{4641}10.\hspace*{0.5em}\mdline{4641}Error Reporting Messages}\label{sec-error-reporting-messages}%mdk%mdk + +%mdk-data-line={4643} +\noindent\mdline{4643}P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case.%mdk + +%mdk-data-line={4647} +\mdline{4647}gRPC uses \mdline{4647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4647}~[\mdcite{grpcstatus}{32}]\mdline{4647} to represent the status returned by an +RPC. It has 3 attributes:%mdk + +%mdk-data-line={4650} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4651} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StatusCode~code\_;\\ +{\mdcolor{navy}grpc::}string~error\_message\_;\\ +{\mdcolor{navy}grpc::}string~binary\_error\_details\_;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4656} +\noindent\mdline{4656}The \mdline{4656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4656} represents a canonical error\mdline{4656}~[\mdcite{grpcstatuscodes}{34}]\mdline{4656} and describes the +overall RPC status. The \mdline{4657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4657} is a developer-facing error message, +which should be in English. The \mdline{4658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}binary\_error\_details\_}}}\mdline{4658} carries a serialized +\mdline{4659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4659} message\mdline{4659}~[\mdcite{protostatus}{28}]\mdline{4659} message, which has 3 fields:%mdk + +%mdk-data-line={4661} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4662} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}int32}}~code~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~see~code.proto}\\ +{\bfseries{\mdcolor{navy}string}}~{\bfseries{\mdcolor{navy}message}}~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +{\bfseries{\mdcolor{navy}repeated}}~google.protobuf.Any~details~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4667} +\noindent\mdline{4667}The code and message fields must be the same as \mdline{4667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4667} and \mdline{4667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4667} +fields from \mdline{4668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4668} above. The \mdline{4668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{4668} field is a list that consists of +\mdline{4669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4669} messages that carry error details for individual elements inside +batch-request RPCs (\mdline{4670}e.g.\mdline{4670} \mdline{4670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4670} and \mdline{4670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4670}). \mdline{4670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4670} includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices\mdline{4674}~[\mdcite{grpcstatuscodes}{34}]\mdline{4674}.%mdk + +%mdk-data-line={4676} +\mdline{4676}Figure\mdline{4676}~\mdref{fig-error-report}{\mdcaptionlabel{7}}\mdline{4676} illustrates how these messages fit together.%mdk + +%mdk-data-line={4678} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={4679} +\noindent\mdline{4679}\includegraphics[keepaspectratio=true,width=\dimwidth{0.70}]{build/error-report}{}\mdline{4679}%mdk + +%mdk-data-line={4680} +\mdhr{}%mdk + +%mdk-data-line={4681} +\noindent\mdline{4681}\mdcaption{\textbf{Figure~\mdcaptionlabel{7}.}~\mdcaptiontext{P4Runtime Error Report Message Format}}%mdk +%mdk +\end{mdcenter}\label{fig-error-report}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={4683} +\noindent\mdline{4683}gRPC provides utility functions \mdline{4683}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExtractErrorDetails()}}}\mdline{4683} and \mdline{4683}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetErrorDetails()}}}\mdline{4683} +\mdline{4684}[\mdcite{grpcerrordetails}{33}]\mdline{4684} to easily convert between \mdline{4684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4684} and +\mdline{4685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4685}.%mdk + +%mdk-data-line={4687} +\mdline{4687}Please see sections on individual P4Runtime RPCs for details on how +\mdline{4688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4688} is populated for reporting errors.%mdk + +%mdk-data-line={4690} +\mdline{4690}Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on\mdline{4693}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{4694} for more information.%mdk + +%mdk-data-line={4696} +\section{\mdline{4696}11.\hspace*{0.5em}\mdline{4696}Atomicity of Individual \mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4696} and \mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4696} Operations}\label{sec-atomicity-of-individual-write-and-read-operations}%mdk%mdk + +%mdk-data-line={4698} +\noindent\mdline{4698}Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane \mdline{4699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4699} +operation, and every single \mdline{4700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4700} operation on a table that inserts, deletes, +or modifies one table entry, the \mdline{4701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4701} operation should behave as if that +\mdline{4702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4702} operation has not yet occurred, or as if the \mdline{4702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4702} operation is +complete. The P4 program should never behave as if the \mdline{4703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4703} operation is +partially complete. These guarantees also apply to extern instances: \mdline{4704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4704} and +\mdline{4705}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4705} operations on extern entities must execute atomically relative to extern +data plane methods.%mdk + +%mdk-data-line={4708} +\mdline{4708}The atomicity guarantees provided by P4Runtime for individual \mdline{4708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4708} and \mdline{4708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4708} +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification\mdline{4710}~[\mdcite{psaatomicityofcontrolplaneops}{23}]\mdline{4710}.%mdk + +%mdk-data-line={4712} +\mdline{4712}The P4\mdline{4712}\mdsub{16}\mdline{4712} language introduces an \mdline{4712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4712} annotation\mdline{4712}~[\mdcite{p4concurrency}{14}]\mdline{4712}, to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the \mdline{4714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4714} annotation for \mdline{4714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4714} +operations, as well as\mdline{4715}~\mdref{wildcard-reads}{non-wildcard \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} operations}\mdline{4715}, +relative to data plane execution. Consider the following P4 example written for +PSA:%mdk + +%mdk-data-line={4719} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4720} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024)~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\mdcolor{darkgreen}//~...}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~Value\_t~v~=~r1.read((Index\_t){\mdcolor{purple}1});\\ +~~~~~~~~v~=~v~+~{\mdcolor{purple}1};\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~v);\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4736} +\noindent\mdline{4736}If a P4Runtime server is processing messages which write to Register \mdline{4736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4736} at +index \mdline{4737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}1}}}\mdline{4737}, these writes must not happen between the data plane \mdline{4737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}read}}}\mdline{4737} and +\mdline{4738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}write}}}\mdline{4738}.%mdk + +%mdk-data-line={4740} +\mdline{4740}Now let\mdline{4740}'\mdline{4740}s consider the following example:%mdk + +%mdk-data-line={4742} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4743} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024,~(Value\_t){\mdcolor{purple}0}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~initial~value~}{\mdcolor{darkgreen}*/})~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}100});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}100});\\ +~~~~\}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}200});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}200});\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4761} +\noindent\mdline{4761}If a P4Runtime client issues a \mdline{4761}\emph{wildcard}\mdline{4761} \mdline{4761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4761} on Register \mdline{4761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4761}, there is no +guarantee that \mdline{4762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]~==~r1{}[2]}}}\mdline{4762} in the response, as the read for \mdline{4762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4762} may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for \mdline{4764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4764} may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read \mdline{4766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4766} and \mdline{4766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4766} separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +\mdline{4769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4769} message) of individual read requests. Similar to a batch +\mdline{4770}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4770}, a wildcard read of a register can execute the reads of the +register array elements (\mdline{4771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4771}, \mdline{4771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4771}, \mdline{4771}\dots{}\mdline{4771}) in an arbitrary order relative +to each other.%mdk + +%mdk-data-line={4774} +\mdline{4774}If the \mdline{4774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4774} annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program.%mdk + +%mdk-data-line={4778} +\section{\mdline{4778}12.\hspace*{0.5em}\mdline{4778}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4778} RPC}\label{sec-write-rpc}%mdk%mdk + +%mdk-data-line={4780} +\noindent\mdline{4780}The \mdline{4780}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4780} RPC updates one or more P4 entities on the target. The request is +defined as follows:%mdk + +%mdk-data-line={4783} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4784} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~WriteRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Update~updates~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\bfseries{\mdcolor{navy}enum}}~Atomicity~\{\\ +~~~~CONTINUE\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~ROLLBACK\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~DATAPLANE\_ATOMIC~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~\}\\ +~~Atomicity~atomicity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4798} +\noindent\mdline{4798}The \mdline{4798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4798} uniquely identifies the target P4 device. The \mdline{4798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{4798} and +\mdline{4799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4799} define the client role and election-id as described in the +\mdline{4800}\mdref{sec-client-arbitration-and-controller-replication}{Primary-Backup Arbitration and Controller +Replication}\mdline{4801} +section. The server is expected to perform the following checks (in this order) +before processing the \mdline{4803}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}updates}}}\mdline{4803} list:%mdk + +%mdk-data-line={4805} +\begin{enumerate}%mdk + +%mdk-data-line={4805} +\item{} +%mdk-data-line={4805} +\mdline{4805}If \mdline{4805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4805} does not match any of the devices known to the P4Runtime +server or if \mdline{4806}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{4806} does not match any of the roles for the device, the +server must return a \mdline{4807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4807} error.%mdk%mdk + +%mdk-data-line={4809} +\item{} +%mdk-data-line={4809} +\mdline{4809}If the client is not the primary for (\mdline{4809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4809}, \mdline{4809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{4809}) according to +the \mdline{4810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4810} value, the server must return a \mdline{4810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4810} error.%mdk%mdk + +%mdk-data-line={4812} +\item{} +%mdk-data-line={4812} +\mdline{4812}If the \mdline{4812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4812} is attempted before a \mdline{4812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4812} has been set, +the server must return a \mdline{4813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{4813} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4815} +\noindent\mdline{4815}The updates field is a list of P4 entity updates to be applied. Each update is +defined as:%mdk + +%mdk-data-line={4818} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4819} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Update~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Type~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~INSERT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~MODIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DELETE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~Type~type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Entity~entity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4831} +\noindent\mdline{4831}This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a \mdline{4832}\emph{logical}\mdline{4832} table (\mdline{4832}e.g.\mdline{4832} +\mdline{4833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4833}) or an actual table (\mdline{4833}e.g.\mdline{4833} \mdline{4833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4833}) in the P4 data +plane. Each entity in the container is uniquely identified by its \mdline{4834}\emph{key}\mdline{4834}. Please +refer to the\mdline{4835}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4835} section for details on +what parts of the entity specification make up the \mdline{4836}\emph{key}\mdline{4836} for each P4 entity.%mdk + +%mdk-data-line={4838} +\mdline{4838}An update can be one of the following types:%mdk + +%mdk-data-line={4840} +\begin{itemize}%mdk + +%mdk-data-line={4840} +\item{} +%mdk-data-line={4840} +\mdline{4840}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4840}: Inserts the given P4 entity in the entity container. +The \mdline{4841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{4841} field always specifies the full state of the P4 entity. +If the entity already exists, an \mdline{4842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4842} error is returned, and +the existing entity remains unchanged. If the entity is malformed, an +\mdline{4844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4844} error is usually returned (unless a more specific error +code applies\mdline{4845}~[\mdcite{grpcstatuscodes}{34}]\mdline{4845}). If the entity cannot be inserted because the +container is already full, a \mdline{4846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4846} error is returned.%mdk%mdk + +%mdk-data-line={4848} +\item{} +%mdk-data-line={4848} +\mdline{4848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4848}: Modifies the P4 entity to its new specified state. This uses +\mdline{4849}\emph{assign}\mdline{4849} or \mdline{4849}\emph{full-snapshot}\mdline{4849} semantics, \mdline{4849}i.e.\mdline{4849} the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an \mdline{4851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4851} error is usually returned (unless a +more specific error code applies\mdline{4852}~[\mdcite{grpcstatuscodes}{34}]\mdline{4852}). If the entity does not +exist, a \mdline{4853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4853} error is returned.%mdk%mdk + +%mdk-data-line={4855} +\item{} +%mdk-data-line={4855} +\mdline{4855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4855}: Deletes the specified P4 entity. If the entity does not exist, a +\mdline{4856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4856} error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4859} +\noindent\mdline{4859}If an update is not allowed under the given controller role, the server must +return a \mdline{4860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4860} error for this update.%mdk + +%mdk-data-line={4862} +\subsection{\mdline{4862}12.1.\hspace*{0.5em}\mdline{4862}Batching and Ordering of Updates}\label{sec-batching-and-ordering-of-updates}%mdk%mdk + +%mdk-data-line={4864} +\noindent\mdline{4864}P4Runtime supports batching of \mdline{4864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4864} operations. The list of updates in a +\mdline{4865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4865} is referred to as a \mdline{4865}\emph{batch}\mdline{4865}. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of \mdline{4867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4867} entities).%mdk + +%mdk-data-line={4869} +\mdline{4869}The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +\mdline{4871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4871}s can also be processed interleaved and/or in parallel. +However, \mdline{4872}\textbf{the processing of requests must be strictly serializable}\mdline{4872}. That +is, given a history \mdline{4873}$S$\mdline{4873} of \mdline{4873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4873}s including the responses to those +requests, there must exist an order \mdline{4874}$L$\mdline{4874} for all updates in \mdline{4874}$S$\mdline{4874}, such that:%mdk + +%mdk-data-line={4876} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4876} +\item\mdline{4876}All updates from the same write request must appear as a contiguous +subsequence in \mdline{4877}$L$\mdline{4877}, but the order within that subsequence can be arbitrary.%mdk + +%mdk-data-line={4878} +\item\mdline{4878}For two updates \mdline{4878}$u_1$\mdline{4878} and \mdline{4878}$u_2$\mdline{4878}, if the write request containing \mdline{4878}$u_1$\mdline{4878} +completed before the write request of \mdline{4879}$u_2$\mdline{4879} was sent, then \mdline{4879}$u_1$\mdline{4879} must appear +before \mdline{4880}$u_2$\mdline{4880} in \mdline{4880}$L$\mdline{4880}.%mdk + +%mdk-data-line={4881} +\item\mdline{4881}Executing all updates in \mdline{4881}$L$\mdline{4881} sequentially must yield the same response for +every update as in \mdline{4882}$S$\mdline{4882}.%mdk + +%mdk-data-line={4883} +\item\mdline{4883}The observable state of the switch after \mdline{4883}$S$\mdline{4883} (\mdline{4883}e.g.\mdline{4883}, through the \mdline{4883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4883} RPC) +is identical to the one obtained by sequentially executing \mdline{4884}$L$\mdline{4884}.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4886} +\noindent\mdline{4886}The \mdline{4886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4886} RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the \mdline{4887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4887} RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (\mdline{4890}e.g.\mdline{4890} inserting an \mdline{4890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4890} +followed by pointing a \mdline{4891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4891} to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding \mdline{4893}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4893} RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate \mdline{4897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4897} calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each \mdline{4898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4898} call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one.%mdk + +%mdk-data-line={4903} +\subsection{\mdline{4903}12.2.\hspace*{0.5em}\mdline{4903}Batch Atomicity}\label{sec-batch-atomicity}%mdk%mdk + +%mdk-data-line={4905} +\noindent\mdline{4905}A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the \mdline{4906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4906} +enum. A P4Runtime server is required to support only the modes marked as +\mdline{4908}\emph{Required}\mdline{4908} below:%mdk + +%mdk-data-line={4910} +\begin{itemize}%mdk + +%mdk-data-line={4910} +\item{} +%mdk-data-line={4910} +\mdline{4910}\emph{Required}\mdline{4910}: \mdline{4910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4910}: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that \mdline{4914}\emph{see}\mdline{4914} each of +these intermediate stages.%mdk%mdk + +%mdk-data-line={4917} +\item{} +%mdk-data-line={4917} +\mdline{4917}\emph{Optional}\mdline{4917}: \mdline{4917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ROLLBACK\_ON\_ERROR}}}\mdline{4917}: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is \mdline{4921}\emph{all-or-none}\mdline{4921}, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that \mdline{4925}\emph{see}\mdline{4925} each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure.%mdk + +%mdk-data-line={4930} +\mdline{4930}If a P4Runtime server does not support this option at all, an +\mdline{4931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4931} error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (\mdline{4932}e.g.\mdline{4932} it is +more straightforward to implement batches that contain only \mdline{4933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4933} +operations, vs. those that contain \mdline{4934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4934} operations), an +\mdline{4935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4935} error is returned when the batch cannot be executed +in a data plane-atomic way.%mdk%mdk + +%mdk-data-line={4938} +\item{} +%mdk-data-line={4938} +\mdline{4938}\emph{Optional}\mdline{4938}: \mdline{4938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4938}: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +\mdline{4942}\emph{transaction}\mdline{4942}. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane\mdline{4944}'\mdline{4944}s table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table.%mdk + +%mdk-data-line={4951} +\mdline{4951}If a P4Runtime server does not support this option at all, an \mdline{4951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4951} +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an \mdline{4953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4953} error is returned when the batch +cannot be executed in a data plane-atomic way.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4956} +\noindent\mdline{4956}There is no expectation that a given client must always use the same \mdline{4956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4956} +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use \mdline{4959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4959} at one time and default behavior +(\mdline{4960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4960}) at other times.%mdk + +%mdk-data-line={4962} +\subsection{\mdline{4962}12.3.\hspace*{0.5em}\mdline{4962}Error Reporting}\label{sec-error-reporting}%mdk%mdk + +%mdk-data-line={4964} +\noindent\mdline{4964}Please see section\mdline{4964}~\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{4964} for +information on error reporting messages and guidelines. P4Runtime server will +populate \mdline{4966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4966} as follows:%mdk + +%mdk-data-line={4968} +\begin{enumerate}%mdk + +%mdk-data-line={4968} +\item{} +%mdk-data-line={4968} +\mdline{4968}If all batch updates succeeded, set \mdline{4968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4968} to \mdline{4968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4968} and do not +populate any other field.%mdk%mdk + +%mdk-data-line={4971} +\item{} +%mdk-data-line={4971} +\mdline{4971}If an error is encountered before even trying to attempt individual batch +updates, set \mdline{4972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4972} that best describes that RPC-wide +error. For example, use \mdline{4973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNAVAILABLE}}}\mdline{4973} if the P4Runtime service is not yet +ready to handle requests. Set \mdline{4974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4974} to describe the issue. Do not +set \mdline{4975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_details}}}\mdline{4975} in this case.%mdk%mdk + +%mdk-data-line={4977} +\item{} +%mdk-data-line={4977} +\mdline{4977}Otherwise, if one or more updates in the batch (\mdline{4977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest.updates}}}\mdline{4977}) +failed, set \mdline{4978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4978} to \mdline{4978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{4978}. For example, one update in +the batch may fail with \mdline{4979}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4979} and another with +\mdline{4980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4980}. A \mdline{4980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4980} message is used to capture the status of +each and every update in the batch. The number of \mdline{4981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4981} messages packed +into \mdline{4982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{4982} field should therefore always match the +number of updates in the \mdline{4983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4983}, and the order of +\mdline{4984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4984} messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +\mdline{4986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4986} should set the code to \mdline{4986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4986} and omit other fields.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4988} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4989} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}\#~Example~of~a~grpc::Status~returned~for~a~Write~RPC~with~a~batch~of~3~updates.}\\ +{\mdcolor{darkgreen}\#~The~first~and~third~updates~encountered~an~error,~while~the~second~update}\\ +{\mdcolor{darkgreen}\#~succeeded.}\\ +code\_~=~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +error\_message\_~=~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +binary\_error\_details~\{\\ +~~code:~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}8}~~{\mdcolor{darkgreen}\#~RESOURCE\_EXHAUSTED}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Table~is~full.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}500}~~{\mdcolor{darkgreen}\#~ERR\_TABLE\_FULL}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}0}~~{\mdcolor{darkgreen}\#~OK}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}6}~~{\mdcolor{darkgreen}\#~ALREADY\_EXISTS}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Entity~already~exists.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}600}~~{\mdcolor{darkgreen}\#~ERR\_ENTITY\_ALREADY\_EXISTS}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5015} +\section{\mdline{5015}13.\hspace*{0.5em}\mdline{5015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5015} RPC}\label{sec-read-rpc}%mdk%mdk + +%mdk-data-line={5017} +\noindent\mdline{5017}The \mdline{5017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5017} RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as:%mdk + +%mdk-data-line={5020} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5021} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5028} +\noindent\mdline{5028}The \mdline{5028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5028} uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +\mdline{5030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5030} error. +If the \mdline{5031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5031} is attempted before \mdline{5031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5031} has been set, the +server must return a \mdline{5032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{5032} error. +The \mdline{5033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5033} field acts as a filter, restricting the reported entities based on +the role to which the entity belongs. +The \mdline{5035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{5035} repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server.%mdk + +%mdk-data-line={5038} +\mdline{5038}Since \mdline{5038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5038}s do not mutate any state on the switch, they do not +require an \mdline{5039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5039}, and they do not require the presence of an open +\mdline{5040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5040} between the server and client.%mdk + +%mdk-data-line={5042} +\mdline{5042}The \mdline{5042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read~}}}\mdline{5042}response consists of a sequence of messages (a gRPC \mdline{5042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}stream}}}\mdline{5042}) with +each message defined as:%mdk + +%mdk-data-line={5045} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5046} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadResponse~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5051} +\noindent\mdline{5051}The \mdline{5051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{5051} repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the \mdline{5055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Finish()}}}\mdline{5055} method on the stream object +\mdline{5056}[\mdcite{grpcstreamc}{10}]\mdline{5056}).%mdk + +%mdk-data-line={5058} +\subsection{\mdline{5058}13.1.\hspace*{0.5em}\mdline{5058}Nomenclature}\label{sec-nomenclature}%mdk%mdk + +%mdk-data-line={5060} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries request}}%mdk + +%mdk-data-line={5060} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{5060}An element of the \mdline{5060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{5060} repeated field. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries batch}}%mdk + +%mdk-data-line={5062} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{5062}Refers to the \mdline{5062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{5062} repeated field.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={5065} +\noindent\mdline{5065}Each \mdline{5065}\emph{request}\mdline{5065} acts as a query filter for that entity type. If a \mdline{5065}\emph{request}\mdline{5065} fully +specifies the entity key, the \mdline{5066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5066} operation should retrieve a single P4 +entity. Please refer to the\mdline{5067}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{5067} section +for details on what parts of the entity specification make up the entity \mdline{5068}\emph{key}\mdline{5068}.%mdk + +%mdk-data-line={5070} +\subsection{\mdline{5070}13.2.\hspace*{0.5em}\mdline{5070}Wildcard Reads}\label{sec-wildcard-reads}%mdk%mdk + +%mdk-data-line={5072} +\noindent\mdline{5072}P4Runtime allows wildcard read of P4 entities. A \mdline{5072}\emph{request}\mdline{5072} may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the\mdline{5074}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{5074} section for details on +what parts of the entity can be wildcarded in a given \mdline{5075}\emph{request}\mdline{5075}.%mdk + +%mdk-data-line={5077} +\mdline{5077}For example, in a \mdline{5077}\emph{request}\mdline{5077} of type \mdline{5077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{5077}:%mdk + +%mdk-data-line={5079} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5079} +\item\mdline{5079}A default \mdline{5079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{5079} (0) implies a request to read all counter-entries for +all indirect counters.%mdk + +%mdk-data-line={5081} +\item\mdline{5081}A particular (non-default) \mdline{5081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{5081} in conjunction with \mdline{5081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{5081} unset +implies a request to read all counter-entries for the given indirect counter +ID.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5085} +\noindent\mdline{5085}To read the entire forwarding state for a given device, the P4Runtime client can +generate the following \mdline{5086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5086}:%mdk + +%mdk-data-line={5088} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5089} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~\textless{}ID\textgreater{}\\ +entities~\{\\ +~~extern\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~extern~instances~for~all~supported~extern~types}\\ +~~table\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~table~entries~for~all~tables}\\ +~~action\_profile\_member~\{~\}~~{\mdcolor{darkgreen}\#~read~all~members~for~all~action~profiles}\\ +~~action\_profile\_group~\{~\}~~{\mdcolor{darkgreen}\#~read~all~groups~for~all~action~profiles}\\ +~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5099} +\noindent\mdline{5099}The \mdline{5099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5099} oneof field in the \mdline{5099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5099} message must always be set, or the +server must return an \mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5100} error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty \mdline{5102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5102} message in the \mdline{5102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5102}. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the \mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5104} oneof\mdline{5104}~[\mdcite{protooneofbackwardscompatibility}{20}]\mdline{5104}.%mdk + +%mdk-data-line={5106} +\subsection{\mdline{5106}13.3.\hspace*{0.5em}\mdline{5106}Batch Processing}\label{sec-batch-processing}%mdk%mdk + +%mdk-data-line={5108} +\noindent\mdline{5108}A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type \mdline{5109}\emph{request}\mdline{5109} +appears only once in the batch.%mdk + +%mdk-data-line={5112} +\mdline{5112}A P4Runtime server will process the batch as follows:%mdk + +%mdk-data-line={5114} +\begin{enumerate}%mdk + +%mdk-data-line={5114} +\item{} +%mdk-data-line={5114} +\mdline{5114}Lock state (preventing new writes) and validate each \mdline{5114}\emph{request}\mdline{5114} in the batch:%mdk + +%mdk-data-line={5116} +\begin{enumerate}%mdk + +%mdk-data-line={5116} +\item{} +%mdk-data-line={5116} +\mdline{5116}If it is a valid \mdline{5116}\emph{request}\mdline{5116}, perform the read;%mdk + +%mdk-data-line={5118} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5118} +\item\mdline{5118}If the read was successful, return the entities read in +\mdline{5119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5119} stream.%mdk + +%mdk-data-line={5120} +\item\mdline{5120}If the read failed (exception / critical-error), prepare a \mdline{5120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5120} +with code set to \mdline{5121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INTERNAL}}}\mdline{5121}.%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5123} +\item{} +%mdk-data-line={5123} +\mdline{5123}If the \mdline{5123}\emph{request}\mdline{5123} is invalid (invalid-argument, not-supported, etc.), +prepare a \mdline{5124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5124} with relevant canonical code to capture the error.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5126} +\item{} +%mdk-data-line={5126} +\mdline{5126}Unlock the state (allowing new writes);%mdk%mdk + +%mdk-data-line={5128} +\item{} +%mdk-data-line={5128} +\mdline{5128}Close the \mdline{5128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5128} stream and return a \mdline{5128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5128} as follows:%mdk + +%mdk-data-line={5130} +\begin{enumerate}%mdk + +%mdk-data-line={5130} +\item{} +%mdk-data-line={5130} +\mdline{5130}If no errors were encountered, set code to \mdline{5130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{5130} and do not populate any +other field.%mdk%mdk + +%mdk-data-line={5133} +\item{} +%mdk-data-line={5133} +\mdline{5133}Otherwise, the overall code should be set to \mdline{5133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{5133}. See section +\mdline{5134}\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{5134} for information +on error reporting messages and guidelines. Assemble a list of \mdline{5135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5135} +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +\mdline{5139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{5139} field. This behavior also matches \mdline{5139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5139} +RPC.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5142} +\subsubsection{\mdline{5142}13.3.1.\hspace*{0.5em}\mdline{5142}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={5144} +\noindent\mdline{5144}If a client asked to read \mdline{5144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{a,b,c,d\}}}}\mdline{5144} and \mdline{5144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}b}}}\mdline{5144} and \mdline{5144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}d}}}\mdline{5144} \mdline{5144}\emph{requests}\mdline{5144} didn\mdline{5144}'\mdline{5144}t +validate, the server will return entities corresponding to \mdline{5145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5145} and \mdline{5145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}c}}}\mdline{5145}, followed +by a status \mdline{5146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{p4.Error(OK),~p4.Error(xxx),~p4.Error(yyy),~p4.Error(OK)\}}}}\mdline{5146} in the +\mdline{5147}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5147} field.%mdk + +%mdk-data-line={5149} +\mdline{5149}The P4Runtime server is not required to perform any optimization (\mdline{5149}e.g.\mdline{5149} merge two +\mdline{5150}\emph{requests}\mdline{5150} in the \mdline{5150}\emph{batch}\mdline{5150} if one is a subset of other). As a result of this, it +is possible for the \mdline{5151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5151} to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging.%mdk + +%mdk-data-line={5154} +\mdline{5154}There is no requirement that each request in the batch will correspond to one +\mdline{5155}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5155} message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit.%mdk + +%mdk-data-line={5160} +\mdline{5160}A P4Runtime server must be prepared to handle multiple concurrent \mdline{5160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5160} RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (\mdline{5165}e.g.\mdline{5165} in a single-threaded architecture), it may choose to serialize +\mdline{5166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5166} RPC processing.%mdk + +%mdk-data-line={5168} +\subsection{\mdline{5168}13.4.\hspace*{0.5em}\mdline{5168}Parallelism of Read and Write Requests}\label{sec-parallelism-of-read-and-write-requests}%mdk%mdk + +%mdk-data-line={5170} +\noindent\mdline{5170}A P4Runtime server may be implemented to serve at most one +\mdline{5171}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5171} or \mdline{5171}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5171} message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so.%mdk + +%mdk-data-line={5176} +\mdline{5176}For example, imagine a client that wanted to use \mdline{5176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5176} +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +\mdline{5180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5180} messages with only a few updates to an \mdline{5180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{5180} +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +\mdline{5183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5183} batch currently being processed, but it will not +complete for a significant amount of time.%mdk + +%mdk-data-line={5186} +\mdline{5186}The restrictions on which a client may rely are:%mdk + +%mdk-data-line={5188} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5188} +\item\mdline{5188}The processing of any two \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5188} messages \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W1}}}\mdline{5188} and \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W2}}}\mdline{5188} must +result in the same state as if one of them was completed before the +other began.%mdk + +%mdk-data-line={5191} +\item\mdline{5191}For any \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5191} \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5191} and any \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5191} \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5191}, \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5191} must +return results consistent with a state where \mdline{5192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5192} has completed +processing, or \mdline{5193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5193} has not yet begun processing.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5195} +\noindent\mdline{5195}For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a \mdline{5198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5198} message it acquired a write lock for each stateful +object affected by the \mdline{5199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5199}, and before starting the +processing of a \mdline{5200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5200} message it acquired a read lock for each +stateful object accessed by the \mdline{5201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5201}, such an implementation +meets all of the requirements above.%mdk + +%mdk-data-line={5204} +\mdline{5204}It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, \mdline{5206}e.g.\mdline{5206} if the server somehow determined that two +\mdline{5207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5207} messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly.%mdk + +%mdk-data-line={5213} +\section{\mdline{5213}14.\hspace*{0.5em}\mdline{5213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5213} RPC}\label{sec-setforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5215} +\noindent\mdline{5215}A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the \mdline{5216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig~RPC}}}\mdline{5216}. The request is defined as:%mdk + +%mdk-data-line={5218} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5219} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~SetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Action~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~VERIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~VERIFY\_AND\_SAVE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~VERIFY\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~~~COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~~~RECONCILE\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~Action~action~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5236} +\noindent\mdline{5236}The server is expected to perform the following checks (in this order) +before performing the required \mdline{5237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{5237}:%mdk + +%mdk-data-line={5239} +\begin{enumerate}%mdk + +%mdk-data-line={5239} +\item{} +%mdk-data-line={5239} +\mdline{5239}If \mdline{5239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5239} does not match any of the devices known to the P4Runtime +server or if \mdline{5240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5240} does not match any of the roles for the device, the +server must return a \mdline{5241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5241} error.%mdk%mdk + +%mdk-data-line={5243} +\item{} +%mdk-data-line={5243} +\mdline{5243}If the client is not the primary for (\mdline{5243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5243}, \mdline{5243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5243}) according to +the \mdline{5244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5244} value, the server must return a \mdline{5244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5244} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5246} +\noindent\mdline{5246}The action is the type of configuration action requested, it can be one of:%mdk + +%mdk-data-line={5248} +\begin{itemize}%mdk + +%mdk-data-line={5248} +\item{} +%mdk-data-line={5248} +\mdline{5248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY}}}\mdline{5248}: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an \mdline{5249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5249} +error if config is not provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5252} +\item{} +%mdk-data-line={5252} +\mdline{5252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5252}: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent \mdline{5254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5254} / \mdline{5254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5254} requests must refer to fields in the new +config. Returns an \mdline{5255}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5255} error if the forwarding config is not +provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5258} +\item{} +%mdk-data-line={5258} +\mdline{5258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_COMMIT}}}\mdline{5258}: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an \mdline{5260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5260} error if the forwarding config is not provided or if the +provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5263} +\item{} +%mdk-data-line={5263} +\mdline{5263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COMMIT}}}\mdline{5263}: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a \mdline{5266}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5266} error if no saved config +is found, \mdline{5267}i.e.\mdline{5267} if no \mdline{5267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5267} action preceded this one. Returns an +\mdline{5268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5268} error if a config is provided with this message.%mdk%mdk + +%mdk-data-line={5270} +\item{} +%mdk-data-line={5270} +\mdline{5270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RECONCILE\_AND\_COMMIT}}}\mdline{5270}: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an \mdline{5276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5276} error. For targets that support this option, an +\mdline{5277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5277} error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5281} +\noindent\mdline{5281}The \mdline{5281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5281} field is a message of type \mdline{5281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5281} that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(\mdline{5283}e.g.\mdline{5283} generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the\mdline{5284}~\mdref{sec-p4-fwd-pipe-config}{Forwarding-Pipeline +Configuration}\mdline{5285} section for details.%mdk + +%mdk-data-line={5287} +\mdline{5287}A P4Runtime server running on a non-programmable device may not +support \mdline{5288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5288} (\mdline{5288}e.g.\mdline{5288} the forwarding-pipeline +config is part of the device\mdline{5289}'\mdline{5289}s software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +\mdline{5291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5291} error.%mdk + +%mdk-data-line={5293} +\section{\mdline{5293}15.\hspace*{0.5em}\mdline{5293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5293} RPC}\label{sec-getforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5295} +\noindent\mdline{5295}The forwarding-pipeline configuration of the target can be retrieved by invoking +the \mdline{5296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig~RPC}}}\mdline{5296}. The request is defined as:%mdk + +%mdk-data-line={5298} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5299} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~ResponseType~\{\\ +~~~~ALL~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~COOKIE\_ONLY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~P{\mdcolor{purple}4}INFO\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DEVICE\_CONFIG\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~ResponseType~response\_type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5311} +\noindent\mdline{5311}The \mdline{5311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5311} uniquely identifies the target P4 device. A \mdline{5311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5311} error is +returned if the \mdline{5312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5312} is not recognized by the P4Runtime server.%mdk + +%mdk-data-line={5314} +\mdline{5314}The \mdline{5314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5314} is used to specify which fields to populate in the response, +its value can be one of:%mdk + +%mdk-data-line={5317} +\begin{itemize}%mdk + +%mdk-data-line={5317} +\item{} +%mdk-data-line={5317} +\mdline{5317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5317}: returns a \mdline{5317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5317} with all fields +set as stored by the target. This is the default behaviour if the +\mdline{5319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5319} field is not set.%mdk%mdk + +%mdk-data-line={5321} +\item{} +%mdk-data-line={5321} +\mdline{5321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COOKIE\_ONLY}}}\mdline{5321}: reply by setting only the \mdline{5321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5321} field in the +\mdline{5322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5322}, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message.%mdk%mdk + +%mdk-data-line={5326} +\item{} +%mdk-data-line={5326} +\mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4INFO\_AND\_COOKIE}}}\mdline{5326}: reply by setting the \mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{5326} and \mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5326} fields.%mdk%mdk + +%mdk-data-line={5328} +\item{} +%mdk-data-line={5328} +\mdline{5328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEVICE\_CONFIG\_AND\_COOKIE}}}\mdline{5328}: reply by setting the \mdline{5328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5328} and +\mdline{5329}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5329} fields.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5331} +\noindent\mdline{5331}The response contains the \mdline{5331}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5331} for the specified device:%mdk + +%mdk-data-line={5333} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5334} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigResponse~\{\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5339} +\noindent\mdline{5339}If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level \mdline{5340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5340} field will be unset in the response. Examples are +(i) a server that only allows configuration via \mdline{5341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5341} +but this RPC hasn\mdline{5342}'\mdline{5342}t been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn\mdline{5343}'\mdline{5343}t yet occurred.%mdk + +%mdk-data-line={5345} +\mdline{5345}Once a forwarding-pipeline config is installed on the device (either via +\mdline{5346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5346} or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +\mdline{5348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.p4\_device\_config}}}\mdline{5348} will be empty / unset in the response, even if +\mdline{5349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5349} in the request was set to \mdline{5349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5349}. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the \mdline{5351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5351} RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +\mdline{5353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5353}, the value of \mdline{5353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.cookie}}}\mdline{5353} will be unset.%mdk + +%mdk-data-line={5355} +\mdline{5355}If a P4Runtime server supports both \mdline{5355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5355} as well as +returning the \mdline{5356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5356}, there should be read-write symmetry between +\mdline{5357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5357} and \mdline{5357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5357} RPCs.%mdk + +%mdk-data-line={5359} +\section{\mdline{5359}16.\hspace*{0.5em}\mdline{5359}P4Runtime Stream Messages}\label{sec-p4runtime-stream-messages}%mdk%mdk + +%mdk-data-line={5361} +\subsection{\mdline{5361}16.1.\hspace*{0.5em}\mdline{5361}Packet I/O}\label{sec-packet-i_o}%mdk%mdk + +%mdk-data-line={5363} +\noindent\mdline{5363}P4Runtime supports controller packet-in and packet-out by means of \mdline{5363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5363} +and \mdline{5364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5364} stream messages, respectively.%mdk + +%mdk-data-line={5366} +\mdline{5366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5366} messages are sent by the P4Runtime server to the client. Conversely, +\mdline{5367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5367} messages are sent by the client to the server. Any \mdline{5367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5367} +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a \mdline{5370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5370} message with the \mdline{5370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5370} field set to +report the error to the client. See the section on\mdline{5371}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{5372} for more information on \mdline{5372}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5372}.%mdk + +%mdk-data-line={5374} +\mdline{5374}As introduced in the\mdline{5374}~\mdref{sec-controller-packet-meta}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\mdline{5374} +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with \mdline{5376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5376}. The expected metadata is described +in the P4Info using the \mdline{5377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5377} messages.%mdk + +%mdk-data-line={5379} +\mdline{5379}Both \mdline{5379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5379} and \mdline{5379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5379} stream messages share the same fields and are +defined as follows:%mdk + +%mdk-data-line={5382} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5383} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Packet~sent~from~the~controller~to~the~switch.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketOut~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~Packet~sent~from~the~switch~to~the~controller.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketIn~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~PacketMetadata~\{\\ +~~{\mdcolor{darkgreen}//~This~refers~to~Metadata.id~coming~from~P4Info~ControllerPacketMetadata.}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~metadata\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5402} +\begin{itemize}%mdk + +%mdk-data-line={5402} +\item{} +%mdk-data-line={5402} +\mdline{5402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}payload}}}\mdline{5402} is used to carry the full packet content, including the headers.%mdk%mdk + +%mdk-data-line={5404} +\item{} +%mdk-data-line={5404} +\mdline{5404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5404} is a repeated field of \mdline{5404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{5404} messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +\mdline{5407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5407}. Indeed, when a P4Runtime client (or server) +generates a \mdline{5408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5408} (or \mdline{5408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5408}) message, it needs to populate the +\mdline{5409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5409} field with as many values as in \mdline{5409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{5409} +for the packet-out (or packet-in) case. Each \mdline{5410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata.value}}}\mdline{5410} is a +binary string and must conform to the\mdline{5411}~\mdref{sec-bytestrings}{Bytestrings}\mdline{5411} +requirements based on the corresponding P4Info +\mdline{5413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{5413} specification. If the \mdline{5413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5413} field +does not match the P4Info specification, the server must drop the \mdline{5414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5414} +message and may generate a \mdline{5415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5415} message with the \mdline{5415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5415} +field set to report the error to the client which issued the \mdline{5416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5416}. See +the section on\mdline{5417}~\mdref{sec-stream-error-reporting}{Stream Error Reporting}\mdline{5417} for more +information on \mdline{5418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5418}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5420} +\subsection{\mdline{5420}16.2.\hspace*{0.5em}\mdline{5420}Client Arbitration Update}\label{sec-client-arbitration-update}%mdk%mdk + +%mdk-data-line={5422} +\noindent\mdline{5422}P4Runtime\mdline{5422}'\mdline{5422}s client arbitration mechanism ensures that only the current primary +can modify state on the switch, and that the \mdline{5423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5423} is monotonically +increasing. For example, the switch must finish all previous write operations +before before selecting a different primary, and must only accept write requests +from the current primary.%mdk + +%mdk-data-line={5428} +\mdline{5428}As explained earlier in this document, the controller uses the \mdline{5428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5428} +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via \mdline{5430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5430} RPC), +it needs to start a controller session and become a \mdline{5431}\textquotedblleft{}primary\textquotedblright{}\mdline{5431}. To do so, the +controller first opens a bidirectional stream channel to the server via +\mdline{5433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5433} for each device and sends a \mdline{5433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5433} message. The +controller populates the \mdline{5434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5434} field in this message using +its \mdline{5435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5435} and \mdline{5435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5435} and the \mdline{5435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5435} of the device, as explained +in detail in the\mdline{5436}~\mdref{sec-client-arbitration-and-controller-replication}{Client Arbitration and Controller +Replication}\mdline{5437} +section. For any given \mdline{5438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role)}}}\mdline{5438}, the P4Runtime server keeps track +of the highest \mdline{5439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5439} that it has ever received. If a controller\mdline{5439}'\mdline{5439}s +\mdline{5440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5440} is equal to the highest \mdline{5440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5440} that the server has ever +received, that controller is the primary. All other controllers are backups. +Note that it is possible that all controllers are backups, and that there is no +primary. There can be at most one primary, because for any given +\mdline{5444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role)}}}\mdline{5444}, each connected controller has a unique \mdline{5444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5444}.%mdk + +%mdk-data-line={5446} +\mdline{5446}This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest \mdline{5447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5447} after such a restart. +However, across a\mdline{5448}~\mdref{sec-restarts}{full restart}\mdline{5448}, the \mdline{5448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5448} must be +reset. In fact, a full restart is the only way to reset the \mdline{5449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5449}.%mdk + +%mdk-data-line={5451} +\mdline{5451}The \mdline{5451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5451} message is defined as follows:%mdk + +%mdk-data-line={5453} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5454} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MasterArbitrationUpdate~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~The~role~for~which~the~primary~client~is~being~arbitrated.~For~use-cases}\\ +~~{\mdcolor{darkgreen}//~where~multiple~roles~are~not~needed,~the~controller~can~leave~this~unset,}\\ +~~{\mdcolor{darkgreen}//~implying~default~role~and~full~pipeline~access.}\\ +~~Role~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~The~stream~RPC~with~the~highest~election\_id~is~the~primary.~The~'primary'}\\ +~~{\mdcolor{darkgreen}//~controller~instance~populates~this~with~its~latest~election\_id.~Switch}\\ +~~{\mdcolor{darkgreen}//~populates~with~the~highest~election~ID~it~has~received~from~all~connected}\\ +~~{\mdcolor{darkgreen}//~controllers.}\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Switch~populates~this~with~OK~for~the~client~that~is~the~primary,~and}\\ +~~{\mdcolor{darkgreen}//~with~an~error~status~for~all~other~connected~clients~(at~every~primary}\\ +~~{\mdcolor{darkgreen}//~client~change).~The~controller~does~not~populate~this~field.}\\ +~~.google.{\bfseries{\mdcolor{navy}rpc}}.Status~status~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Role~\{\\ +~~{\mdcolor{darkgreen}//~Uniquely~identifies~this~role.}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Describes~the~role~configuration,~i.e.~what~operations,~P4~entities,}\\ +~~{\mdcolor{darkgreen}//~behaviors,~etc.~are~in~the~scope~of~a~given~role.~If~config~is~not~set}\\ +~~{\mdcolor{darkgreen}//~(default~case),~it~implies~all~P4~objects~and~control~behaviors~are~in}\\ +~~{\mdcolor{darkgreen}//~scope,~i.e.~full~pipeline~access.~The~format~of~this~message~is}\\ +~~{\mdcolor{darkgreen}//~out-of-scope~of~P4Runtime.}\\ +~~.google.protobuf.Any~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5483} +\noindent\mdline{5483}Note that the \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5483} field in the \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5483} message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a \mdline{5485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5485} message back to the controller, in which +it populates the \mdline{5486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5486} message using the \mdline{5486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5486}, +\mdline{5487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5487}, and \mdline{5487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5487} it previously received from the controller. The server +also populates the \mdline{5488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5488} field in the \mdline{5488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5488} according to +the rules in an\mdline{5489}~\mdref{sec-arbitration-updates}{earlier section}\mdline{5489}.%mdk + +%mdk-data-line={5491} +\mdline{5491}The sender need not specify an \mdline{5491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5491}. If the \mdline{5491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5491} is not +specified, the sender\mdline{5492}'\mdline{5492}s \mdline{5492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5492} is considered lower than any +\mdline{5493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5493}, and the sender will thus never become primary. This way, a +controller can choose to be a backup controller, in order to avoid +\mdline{5495}\textquotedblleft{}flapping\textquotedblright{}\mdline{5495} (if a backup controller connects to the switch shortly before the +actual primary controller, therefore becoming primary temporarily).%mdk + +%mdk-data-line={5499} +\subsection{\mdline{5499}16.3.\hspace*{0.5em}\mdline{5499}Digest Messages}\label{sec-digest-messages}%mdk%mdk + +%mdk-data-line={5501} +\noindent\mdline{5501}See the\mdline{5501}~\mdref{sec-digestentry}{DigestEntry}\mdline{5501} section.%mdk + +%mdk-data-line={5503} +\subsection{\mdline{5503}16.4.\hspace*{0.5em}\mdline{5503}Table Idle Timeout Notification}\label{sec-table-idle-timeout-notification}%mdk%mdk + +%mdk-data-line={5505} +\noindent\mdline{5505}When a table supports idle timeout (as per the P4Info message), the primary +client can specify a TTL value for each entry in the table (see +\mdline{5507}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{5507} section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an \mdline{5509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5509} message on the +\mdline{5510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5510} bidirectional stream to the primary client. The primary client +can then take the action of its choice, most likely remove the idle entry.%mdk + +%mdk-data-line={5513} +\mdline{5513}The \mdline{5513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5513} Protobuf message has the following fields:%mdk + +%mdk-data-line={5515} +\begin{itemize}%mdk + +%mdk-data-line={5515} +\item{} +%mdk-data-line={5515} +\mdline{5515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}timestamp}}}\mdline{5515}: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server\mdline{5516}'\mdline{5516}s local clock.%mdk%mdk + +%mdk-data-line={5518} +\item{} +%mdk-data-line={5518} +\mdline{5518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5518}: a repeated field of entries which have expired. Each individual +entry is identified by a single \mdline{5519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5519} message. For each \mdline{5519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5519}, +the \mdline{5520}\emph{key}\mdline{5520} fields (\mdline{5520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{5520}, \mdline{5520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{5520} and \mdline{5520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{5520}) must be set, along with +the \mdline{5521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{5521} field, the \mdline{5521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5521} field, and the +\mdline{5522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{5522} field. Other fields may be set by the server but should be +ignored by the client.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5525} +\noindent\mdline{5525}Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +\mdline{5527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5527} message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an \mdline{5532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5532} +message with an empty \mdline{5533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5533} repeated field.%mdk + +%mdk-data-line={5535} +\mdline{5535}After generating an idle notification, the P4Runtime server must \mdline{5535}\textquotedblleft{}reset\textquotedblright{}\mdline{5535} the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the primary client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle.%mdk + +%mdk-data-line={5542} +\mdline{5542}Here is a reasonable pseudo-code implementation for idle timeout for table +entries:%mdk + +%mdk-data-line={5545} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5546} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutStream~stream;\\ +\\ +scanning\_interval~=~{\mdcolor{purple}10}ms;\\ +\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~{\mdcolor{darkgreen}//~iterate~over~all~tables~which~support~idle~timeout}\\ +~~{\bfseries{\mdcolor{navy}for}}~(table~in~tables)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(!table.idle\_timeout\_supported)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~{\mdcolor{darkgreen}//~we~coalesce~all~idle~notifications~for~the~same~table~in~one}\\ +~~~~{\mdcolor{darkgreen}//~message}\\ +~~~~IdleTimeoutNotification~msg;\\ +~~~~{\mdcolor{darkgreen}//~read~time\_since\_last\_hit~from~device}\\ +~~~~entries~=~device.load\_table\_entries\_from\_hw(table);\\ +~~~~{\bfseries{\mdcolor{navy}for}}~(entry~in~entries)~\{\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.idle\_timeout~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~TTL}\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.time\_since\_last\_hit~\textless{}~entry.idle\_timeout)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~~~msg.table\_entry\_add(entry);\\ +~~~~~~entry.reset\_time\_since\_last\_hit();\\ +~~~~\}\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(msg.table\_entry\_size()~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~notifications}\\ +~~~~msg.set\_timestamp(now());\\ +~~~~stream.write(msg);\\ +~~\}\\ +~~sleep(scanning\_interval);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5573} +\subsection{\mdline{5573}16.5.\hspace*{0.5em}\mdline{5573}Architecture-Specific Notifications}\label{sec-architecture-specific-notifications}%mdk%mdk + +%mdk-data-line={5575} +\noindent\mdline{5575}P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on \mdline{5576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5576}, by including an \mdline{5576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5576} Protobuf field\mdline{5576}~[\mdcite{protoany}{31}]\mdline{5576} +named \mdline{5577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5577} in both \mdline{5577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5577} and \mdline{5577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5577}. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the\mdline{5579}~\mdref{sec-digestentry}{PSA \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}} +extern}\mdline{5580}. See section on\mdline{5580}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{5581} for more information.%mdk + +%mdk-data-line={5583} +\subsection{\mdline{5583}16.6.\hspace*{0.5em}\mdline{5583}Stream Error Reporting}\label{sec-stream-error-reporting}%mdk%mdk + +%mdk-data-line={5585} +\noindent\mdline{5585}The P4Runtime server can asynchronously report errors which occur when +processing \mdline{5586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5586} messages, using the \mdline{5586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5586} message field (of +type \mdline{5587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5587}) in \mdline{5587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5587}. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature.%mdk + +%mdk-data-line={5591} +\mdline{5591}The \mdline{5591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5591} message has the following fields:%mdk + +%mdk-data-line={5593} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5593} +\item\mdline{5593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5593}, which must be set to the appropriate canonical error code +\mdline{5594}[\mdcite{grpcstatuscodes}{34}]\mdline{5594}.%mdk + +%mdk-data-line={5595} +\item\mdline{5595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{5595}, an optional developer-facing error message describing the error.%mdk + +%mdk-data-line={5596} +\item\mdline{5596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5596} and \mdline{5596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5596}, which are optional and can be used by vendors to provide +additional details on the error. \mdline{5597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5597} is a numeric error code drawn from a +vendor\mdline{5598}'\mdline{5598}s chosen error \mdline{5598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5598}.%mdk + +%mdk-data-line={5599} +\item\mdline{5599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5599}, which is a Protobuf \mdline{5599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5599} used to help the client identify which +\mdline{5600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5600} triggered the error. The server is required to set the +appropriate field in the \mdline{5601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5601} so that the client can identify which type +of stream message is responsible for the error (\mdline{5602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5602}, +\mdline{5603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_list\_ack}}}\mdline{5603} or \mdline{5603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5603}), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid \mdline{5605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5605} message from the +client, the \mdline{5606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5606} field (of type \mdline{5606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError)}}}\mdline{5606} should be set in +the \mdline{5607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5607} \mdline{5607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5607}, and the server may additionally set the \mdline{5607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5607} +field in the \mdline{5608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError}}}\mdline{5608} sub-message (by copying it from the invalid +\mdline{5609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5609} message received on the stream channel) so that the client can +know exactly what packet-out triggered the error.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5612} +\noindent\mdline{5612}The appropriate canonical error code\mdline{5612}~[\mdcite{grpcstatuscodes}{34}]\mdline{5612} should be used when +populating the \mdline{5613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5613} field. For example:%mdk + +%mdk-data-line={5615} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5615} +\item\mdline{5615}if a controller is not allowed to send a \mdline{5615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5615} message under its +current role definition, the code should be set to \mdline{5616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5616}.%mdk + +%mdk-data-line={5617} +\item\mdline{5617}if the \mdline{5617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5617} repeated field in \mdline{5617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5617} does not match the P4Info +definition, the code should be set to \mdline{5618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5618}. It may be useful +for the server to set the \mdline{5619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5619} field in this case, so that the client +can find out which set of metadata fields triggered the error.%mdk + +%mdk-data-line={5621} +\item\mdline{5621}if the \mdline{5621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{5621} field in \mdline{5621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{5621} does not match any \mdline{5621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{5621} entry +in P4Info, the code should be set to \mdline{5622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5622}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5624} +\noindent\mdline{5624}The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, \mdline{5625}e.g.\mdline{5625} because of a +burst of \mdline{5626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5626} messages.%mdk + +%mdk-data-line={5628} +\mdline{5628}Note that client arbitration errors are never reported using the \mdline{5628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5628} +message. Invalid \mdline{5629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5629} messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section\mdline{5631}~\mdref{sec-arbitration-updates}{5.3}\mdline{5631}.%mdk + +%mdk-data-line={5633} +\subsubsection{\mdline{5633}16.6.1.\hspace*{0.5em}\mdline{5633}Examples of \mdline{5633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5633} Messages}\label{sec-examples-of-streamerror-messages}%mdk%mdk + +%mdk-data-line={5635} +\begin{itemize}%mdk + +%mdk-data-line={5635} +\item{} +%mdk-data-line={5635} +\mdline{5635}\textbf{Malformed packet-out metadata.}\mdline{5635} If the server receives a \mdline{5635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5635} +message with a \mdline{5636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5636} field with id 7 which is not included in the P4Info +\mdline{5637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5637} message for \mdline{5637}\textquotedblleft{}packet\_out\textquotedblright{}\mdline{5637}, the server may send the +following \mdline{5638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5638} back to the client:%mdk + +%mdk-data-line={5639} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5640} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Unknown~metadata~field~id~7.}{\mdcolor{maroon}"}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~copied~from~the~PacketOut~message~received~from~the~client}\\ +~~~packet\_out~\{\\ +~~~~~payload:~...\\ +~~~~~metadata~\{\\ +~~~~~~~id:~{\mdcolor{purple}7}\\ +~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}I\_should\_not\_be\_here}{\mdcolor{maroon}"}\\ +~~~~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~~\}\\ +~~~~~{\mdcolor{darkgreen}\#~more~metadata}\\ +~~~\}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={5658} +\item{} +%mdk-data-line={5658} +\mdline{5658}\textbf{Packet-out which exceeds the MTU.}\mdline{5658} If the server receives a \mdline{5658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5658} +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following \mdline{5661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5661}:%mdk + +%mdk-data-line={5662} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5663} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Packet~exceeds~the~MTU~for~port.}{\mdcolor{maroon}"}\\ +~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendor1}{\mdcolor{maroon}"}\\ +~code:~{\mdcolor{purple}123}~~{\mdcolor{darkgreen}\#~MTU\_EXCEEDED}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~we~do~not~set~the~packet\_out~field~as~it~does~not~provide~any}\\ +~~~{\mdcolor{darkgreen}\#~extra~information~to~the~client}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5675} +\section{\mdline{5675}17.\hspace*{0.5em}\mdline{5675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5675} RPC}\label{sec-capabilities-rpc}%mdk%mdk + +%mdk-data-line={5677} +\noindent\mdline{5677}The \mdline{5677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5677} RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the \mdline{5679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesRequest}}}\mdline{5679} message is empty and the \mdline{5679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5679} +message only includes the \mdline{5680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_api\_version}}}\mdline{5680} string field. This field must +be set to the full semantic version string\mdline{5681}~[\mdcite{semver}{27}]\mdline{5681} corresponding to the +version of the P4Runtime API implemented by the server, \mdline{5682}e.g.\mdline{5682} \mdline{5682}\textquotedblleft{}1.1.0-rc.1\textquotedblright{}\mdline{5682}.%mdk + +%mdk-data-line={5684} +\mdline{5684}Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three\mdline{5685}~\mdref{sec-batch-atomicity}{atomicity +modes}\mdline{5686} for \mdline{5686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5686} batches, two of them being +optional. In the future we may decide to leverage the \mdline{5687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5687} +message to enable the server to report to the client which subset of these +atomicity modes is supported.%mdk + +%mdk-data-line={5691} +\mdline{5691}The semantic version string included in \mdline{5691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5691} can be used by +the client to determine which exact feature set is implemented by the server, +since\mdline{5693}~\mdref{sec-p4runtime-versioning}{minor releases}\mdline{5693} may introduce new +functionality. However, because the \mdline{5694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5694} RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (\mdline{5696}i.e.\mdline{5696} an \mdline{5696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5696} error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0).%mdk + +%mdk-data-line={5700} +\section{\mdline{5700}18.\hspace*{0.5em}\mdline{5700}Portability Considerations}\label{sec-portability-considerations}%mdk%mdk + +%mdk-data-line={5702} +\subsection{\mdline{5702}18.1.\hspace*{0.5em}\mdline{5702}PSA Metadata Translation}\label{sec-psa-metadata-translation}%mdk%mdk + +%mdk-data-line={5704} +\noindent\mdline{5704}The \mdline{5704}\emph{Portable Switch Architecture}\mdline{5704} (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +\mdline{5708}[\mdcite{psatranslation}{24}]\mdline{5708}. For such metadata, a translation between the controller\mdline{5708}'\mdline{5708}s +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the \mdline{5712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5712} annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture.%mdk + +%mdk-data-line={5716} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={5717} +\noindent\mdline{5717}\includegraphics[keepaspectratio=true,height=7cm]{build/psa-metadata-translation}{}\mdline{5717}%mdk + +%mdk-data-line={5718} +\mdhr{}%mdk + +%mdk-data-line={5719} +\noindent\mdline{5719}\mdcaption{\textbf{Figure~\mdcaptionlabel{8}.}~\mdcaptiontext{P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdcenter}\label{fig-psa-metadata-translation}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={5723} +\noindent\mdline{5723}Figure\mdline{5723}~\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}}\mdline{5723} illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller\mdline{5729}'\mdline{5729}s 32 bit port +numbers to a target\mdline{5730}'\mdline{5730}s 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch.%mdk + +%mdk-data-line={5734} +\subsubsection{\mdline{5734}18.1.1.\hspace*{0.5em}\mdline{5734}Translation of Port Numbers}\label{sec-translation-of-port-numbers}%mdk%mdk + +%mdk-data-line={5736} +\noindent\mdline{5736}In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller\mdline{5737}'\mdline{5737}s space and the PSA device\mdline{5737}'\mdline{5737}s space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +\mdline{5741}\mdref{sec-user-defined-types}{user-defined P4 types}\mdline{5741}, namely \mdline{5741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5741} and +\mdline{5742}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5742}, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in \mdline{5745}\emph{psa.p4}\mdline{5745} for +the PSA device in Switch 1.%mdk + +%mdk-data-line={5748} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5749} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_t;\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortIdInHeader\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~PortIdInHeader\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5755} +\noindent\mdline{5755}The first argument to the \mdline{5755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5755} annotation is a URI that +indicates to the P4Runtime server which numerical mapping\mdline{5756} \mdline{5756}\textemdash{}\mdline{5756} provided by the +out-of-band switch configuration mechanism\mdline{5757} \mdline{5757}\textemdash{}\mdline{5757} to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports).%mdk + +%mdk-data-line={5761} +\mdline{5761}An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows:%mdk + +%mdk-data-line={5767} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5768} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}enum}}~SdnPort~\{\\ +~~SDN\_PORT\_UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +\\ +~~{\mdcolor{darkgreen}//~SDN~ports~are~numbered~starting~from~1.}\\ +~~SDN\_PORT\_MIN~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\\ +~~{\mdcolor{darkgreen}//~The~maximum~value~of~an~SDN~port~(physical~or~logical).}\\ +~~SDN\_PORT\_MAX~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffeff};\\ +\\ +~~{\mdcolor{darkgreen}//~Reserved~SDN~port~numbers~(0xfffffff0~-~0xffffffff)}\\ +\\ +~~SDN\_PORT\_RECIRCULATE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffa};\\ +~~SDN\_PORT\_CPU~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffd};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5784} +\noindent\mdline{5784}The switch config will map \mdline{5784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_RECIRCULATE}}}\mdline{5784} and \mdline{5784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_CPU}}}\mdline{5784} \mdline{5784}\textemdash{}\mdline{5784} as well +as any SDN port number corresponding to a \mdline{5785}\textquotedblleft{}regular\textquotedblright{}\mdline{5785} front-panel port\mdline{5785} \mdline{5785}\textemdash{}\mdline{5785} to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation.%mdk + +%mdk-data-line={5789} +\mdline{5789}The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs.%mdk + +%mdk-data-line={5792} +\subsubsection{\mdline{5792}18.1.2.\hspace*{0.5em}\mdline{5792}Translation of Packet-IO Header Fields}\label{sec-translation-of-packet-io-header-fields}%mdk%mdk + +%mdk-data-line={5794} +\noindent\mdline{5794}Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:.%mdk + +%mdk-data-line={5797} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5798} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~PortIdInHeader\_t~egress\_port;\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~PortIdInHeader\_t~ingress\_port;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5809} +\noindent\mdline{5809}The header-level annotation \mdline{5809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5809} is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (\mdline{5813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5813}) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI\mdline{5817} \mdline{5817}\textemdash{}\mdline{5817} first argument to the \mdline{5817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5817} +annotation). Any subsequent reference to the \mdline{5818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5818} field in the +data plane will use the translated value. \mdline{5819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5819} is used in the +header definition instead of \mdline{5820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5820} to guarantee byte-aligned headers in +case this is required by the target.%mdk + +%mdk-data-line={5823} +\mdline{5823}A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target\mdline{5825}'\mdline{5825}s PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the \mdline{5827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ingress\_port}}}\mdline{5827} field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller.%mdk + +%mdk-data-line={5833} +\subsubsection{\mdline{5833}18.1.3.\hspace*{0.5em}\mdline{5833}Translation of Match Fields}\label{sec-translation-of-match-fields}%mdk%mdk + +%mdk-data-line={5835} +\noindent\mdline{5835}Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table\mdline{5836}'\mdline{5836}s match key as shown in the example below:%mdk + +%mdk-data-line={5838} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5839} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~istd.ingress\_port:~exact;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~ingress~port}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5849} +\noindent\mdline{5849}Table \mdline{5849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5849} has an exact match on PSA standard metadata ingress port +(\mdline{5850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}istd.ingress\_port}}}\mdline{5850}). Since the field is of type \mdline{5850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5850}, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in \mdline{5853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5853} from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table \mdline{5858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5858} is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values.%mdk + +%mdk-data-line={5862} +\mdline{5862}Note that it may be infeasible to translate the value-mask pair for ternary +matches: \mdline{5863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5863}, \mdline{5863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5863} or \mdline{5863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5863} match kinds. The P4Runtime server may +require that for these match kinds the port match be either \mdline{5864}\emph{de facto}\mdline{5864} \mdline{5864}\textquotedblleft{}exact\textquotedblright{}\mdline{5864} +(0xffffffff mask for \mdline{5865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5865}, prefix-length of 32 for \mdline{5865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5865}, or same low and +high bounds for \mdline{5866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5866}) or \mdline{5866}\textquotedblleft{}don't care\textquotedblright{}\mdline{5866}.%mdk + +%mdk-data-line={5868} +\subsubsection{\mdline{5868}18.1.4.\hspace*{0.5em}\mdline{5868}Translation of Action Parameters}\label{sec-translation-of-action-parameters}%mdk%mdk + +%mdk-data-line={5870} +\noindent\mdline{5870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5870} type parameters can be part of a P4 action definition as shown in the +example below:%mdk + +%mdk-data-line={5873} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5874} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.h.f:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~a;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5888} +\noindent\mdline{5888}The controller may write entries in table \mdline{5888}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5888} with action \mdline{5888}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5888} to set the egress +port as shown in the P4 code above. The action parameter \mdline{5889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5889} is of type +\mdline{5890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5890}, which leads to a 32-bit bitwidth for \mdline{5890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5890} being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device.%mdk + +%mdk-data-line={5896} +\subsubsection{\mdline{5896}18.1.5.\hspace*{0.5em}\mdline{5896}Port Translation for PSA Extern APIs}\label{sec-port-translation-for-psa-extern-apis}%mdk%mdk + +%mdk-data-line={5898} +\noindent\mdline{5898}The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The \mdline{5903}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{5903} +field is of type \mdline{5904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{5904} to carry the SDN representation of the port being +watched. The P4Runtime server will translate the given watch port into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device.%mdk + +%mdk-data-line={5909} +\mdline{5909}The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type \mdline{5911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5911} to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane.%mdk + +%mdk-data-line={5915} +\subsubsection{\mdline{5915}18.1.6.\hspace*{0.5em}\mdline{5915}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}\label{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}%mdk%mdk + +%mdk-data-line={5917} +\noindent\mdline{5917}P4Runtime supports using a translated value (\mdline{5917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5917} or any other translated +type for which the underlying built-in type is \mdline{5918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5918}) as an index to a +register, indirect counter, or indirect meter.%mdk + +%mdk-data-line={5921} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5922} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~counter~entry~type~}{\mdcolor{darkgreen}*/},~PortId\_t~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~index~type~}{\mdcolor{darkgreen}*/}\textgreater{}(\\ +~~{\mdcolor{purple}32}w1024,~PSA\_CounterType\_t.PACKETS)~counter;\\ +{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +~~counter.count(p);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5930} +\noindent\mdline{5930}This P4 Counter declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={5933} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5934} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counters~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x12000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}counter}{\mdcolor{maroon}"}\\ +~~\}\\ +~~spec~\{\\ +~~~~unit:~PACKETS\\ +~~\}\\ +~~index\_type\_name~\{\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5948} +\noindent\mdline{5948}The controller may read and write counter values from indexed counter \mdline{5948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter}}}\mdline{5948} +using SDN port numbers as indices, and not device-specific port numbers. The +\mdline{5950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{5950} field in the P4Info message is a signal to the P4Runtime +server that translation is required.%mdk + +%mdk-data-line={5953} +\section{\mdline{5953}19.\hspace*{0.5em}\mdline{5953}P4Runtime Versioning}\label{sec-p4runtime-versioning}%mdk%mdk + +%mdk-data-line={5955} +\noindent\mdline{5955}P4Runtime follows the Google guidelines for versioning cloud APIs +\mdline{5956}[\mdcite{apiversioning}{6}]\mdline{5956}. We use a \mdline{5956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR.MINOR.PATCH}}}\mdline{5956} style version number scheme and +we increment the:%mdk + +%mdk-data-line={5959} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5959} +\item\mdline{5959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5959} version when we make incompatible API changes,%mdk + +%mdk-data-line={5960} +\item\mdline{5960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MINOR}}}\mdline{5960} version when we add functionality in a backwards-compatible manner,%mdk + +%mdk-data-line={5961} +\item\mdline{5961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PATCH}}}\mdline{5961} version when we make backwards-compatible bug fixes.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5963} +\noindent\mdline{5963}The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is \mdline{5965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1}}}\mdline{5965} and the package +name for P4Info is \mdline{5966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1}}}\mdline{5966}. Even though \mdline{5966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5966} and \mdline{5966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5966} are two +different Protobuf packages, \mdline{5967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5967} depends on \mdline{5967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5967} and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence.%mdk + +%mdk-data-line={5971} +\mdline{5971}As recommended in\mdline{5971}~[\mdcite{apiversioning}{6}]\mdline{5971}, we may consider using pre-GA release +suffixes (such as \mdline{5972}\emph{alpha}\mdline{5972} or \mdline{5972}\emph{beta}\mdline{5972}) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1).%mdk + +%mdk-data-line={5976} +\mdline{5976}Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner.\mdline{5977}~[\mdcite{apiversioningbackwardscompatibility}{7}]\mdline{5977} describes +what constitute a backwards-compatible change. We expect \mdline{5978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5978} version bumps +to be a \mdline{5979}\textbf{rare}\mdline{5979} event.%mdk + +%mdk-data-line={5981} +\mdline{5981}Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor\mdline{5986} \mdline{5986}+ patch version numbers in future releases.%mdk + +%mdk-data-line={5988} +\mdline{5988}All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository\mdline{5989}~[\mdcite{p4runtimerepo}{15}]\mdline{5989} and the version label follows +semantic versioning rules\mdline{5990}~[\mdcite{semver}{27}]\mdline{5990}.%mdk + +%mdk-data-line={5992} +\section{\mdline{5992}20.\hspace*{0.5em}\mdline{5992}Extending P4Runtime for non-PSA Architectures}\label{sec-extending-p4runtime}%mdk%mdk + +%mdk-data-line={5994} +\noindent\mdline{5994}P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place.%mdk + +%mdk-data-line={6002} +\mdline{6002}When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names:%mdk + +%mdk-data-line={6006} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6006} +\item\mdline{6006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/config/\textless{}major~version\textgreater{}/p4info.proto}}}\mdline{6006}%mdk + +%mdk-data-line={6007} +\item\mdline{6007}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/\textless{}major~version\textgreater{}/p4runtime.proto}}}\mdline{6007}%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6009} +\noindent\mdline{6009}We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they \mdline{6010}\textquotedblleft{}extend\textquotedblright{}\mdline{6010}.%mdk + +%mdk-data-line={6012} +\mdline{6012}For the remainder of this section, we will refer to these two files as +\mdline{6013}\emph{p4info-ext}\mdline{6013} and \mdline{6013}\emph{p4runtime-ext}\mdline{6013} respectively.%mdk + +%mdk-data-line={6015} +\subsection{\mdline{6015}20.1.\hspace*{0.5em}\mdline{6015}Extending P4Runtime for Architecture-Specific Externs}\label{sec-extending-p4runtime-for-architecture-specific-externs}%mdk%mdk + +%mdk-data-line={6017} +\noindent\mdline{6017}Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both \mdline{6018}\emph{p4info-ext}\mdline{6018} and +\mdline{6019}\emph{p4runtime-ext}\mdline{6019}. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example:%mdk + +%mdk-data-line={6023} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6024} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~T~must~be~a~bit\textless{}W\textgreater{}~type,~it~indicates~the~width~of~each~counter~cell}\\ +{\bfseries{\mdcolor{navy}extern}}~MyNewPacketCounter\textless{}T\textgreater{}~\{\\ +~~counter({\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~size);\\ +~~increment({\bfseries{\mdcolor{navy}in}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~index);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6031} +\subsubsection{\mdline{6031}20.1.1.\hspace*{0.5em}\mdline{6031}Extending the P4Info message}\label{sec-extending-the-p4info-message}%mdk%mdk + +%mdk-data-line={6033} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6033} +\item\mdline{6033}Id prefixes \mdline{6033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0x81}}}\mdline{6033} through \mdline{6033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfe}}}\mdline{6033} are reserved for architecture-specific +externs. It is recommended that \mdline{6034}\emph{p4info-ext}\mdline{6034} include a \mdline{6034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Ids}}}\mdline{6034} message based +on the one in p4info.proto that the P4 compiler can refer to when\mdline{6035}~\mdref{sec-id-allocation}{assigning +IDs}\mdline{6036} to each extern instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6038} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6039} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~P{\mdcolor{purple}4}Ids~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Prefix~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~MY\_NEW\_PACKET\_COUNTER~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0x81};\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6047} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6047} +\item\mdline{6047}\emph{p4info-ext}\mdline{6047} should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +\mdline{6051}\mdref{sec-p4info-extern}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ExternInstance}}}}\mdline{6051} message as the \mdline{6051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{6051} +field, which is of type \mdline{6052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6052}~[\mdcite{protoany}{31}]\mdline{6052}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6054} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6055} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\mdcolor{darkgreen}//~corresponds~to~the~T~type~parameter~in~the~P4~extern~definition}\\ +~~p4.config.v1.P{\mdcolor{purple}4}DataTypeSpec~type\_spec~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~constructor~argument}\\ +~~{\bfseries{\mdcolor{navy}int64}}~size~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6063} +\subsubsection{\mdline{6063}20.1.2.\hspace*{0.5em}\mdline{6063}Extending the P4Runtime Service}\label{sec-extending-the-p4runtime-service}%mdk%mdk + +%mdk-data-line={6065} +\noindent\mdline{6065}Just like \mdline{6065}\emph{p4info-ext}\mdline{6065}, \mdline{6065}\emph{p4runtime-ext}\mdline{6065} should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an\mdline{6070}~\mdref{sec-extern-entry}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\mdline{6070} message generated by the +P4Runtime client.%mdk + +%mdk-data-line={6073} +\mdline{6073}Here is a possible Protobuf message for our \mdline{6073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyNewPacketCounter}}}\mdline{6073} P4 extern:%mdk + +%mdk-data-line={6074} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6075} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~This~message~enables~reading~/~writing~data~to~the~counter~at~the~provided}\\ +{\mdcolor{darkgreen}//~index}\\ +{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~p4.v1.P{\mdcolor{purple}4}Data~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6083} +\noindent\mdline{6083}P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an \mdline{6084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6084} Protobuf field\mdline{6084}~[\mdcite{protoany}{31}]\mdline{6084} named \mdline{6084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6084} +in both \mdline{6085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{6085} and +\mdline{6086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{6086}. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in \mdline{6088}\emph{p4runtime-ext}\mdline{6088} and embed instances of these messages in +\mdline{6089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{6089} and \mdline{6089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{6089} as appropriate.%mdk + +%mdk-data-line={6091} +\subsection{\mdline{6091}20.2.\hspace*{0.5em}\mdline{6091}Architecture-Specific Table Extensions}\label{sec-architecture-specific-table-extensions}%mdk%mdk + +%mdk-data-line={6093} +\subsubsection{\mdline{6093}20.2.1.\hspace*{0.5em}\mdline{6093}New Match Types}\label{sec-new-match-types}%mdk%mdk + +%mdk-data-line={6095} +\noindent\mdline{6095}An architecture may introduce new table match types\mdline{6095}~[\mdcite{p4matchtypes}{12}]\mdline{6095}. P4Runtime +accounts for this by providing the following hooks:%mdk + +%mdk-data-line={6098} +\begin{itemize}%mdk + +%mdk-data-line={6098} +\item{} +%mdk-data-line={6098} +\mdline{6098}The \mdline{6098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{6098} field in \mdline{6098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{6098} (p4info.proto) is a \mdline{6098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6098} +which can be either one of the default match types (\mdline{6099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{6099}, \mdline{6099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{6099}, \mdline{6099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{6099}, +\mdline{6100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{6100}, or \mdline{6100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6100}) or an architecture-specific match type encoded as a +string.%mdk%mdk + +%mdk-data-line={6103} +\item{} +%mdk-data-line={6103} +\mdline{6103}The \mdline{6103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{6103} field in \mdline{6103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6103} (p4runtime.proto) is a +\mdline{6104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6104} which includes an \mdline{6104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6104} Protobuf message\mdline{6104}~[\mdcite{protoany}{31}]\mdline{6104} field +(\mdline{6105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6105}). \mdline{6105}\emph{p4info-ext}\mdline{6105} should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in \mdline{6108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6108} as the +\mdline{6109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6109} field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6112} +\subsubsection{\mdline{6112}20.2.2.\hspace*{0.5em}\mdline{6112}New Table Properties}\label{sec-new-table-properties}%mdk%mdk + +%mdk-data-line={6114} +\noindent\mdline{6114}An architecture may introduce additional table properties +\mdline{6115}[\mdcite{p4tableproperties}{30}]\mdline{6115}. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +\mdline{6117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Table}}}\mdline{6117} message includes the \mdline{6117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{6117} \mdline{6117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6117} Protobuf +field\mdline{6118}~[\mdcite{protoany}{31}]\mdline{6118}. At the moment, there is not any mechanism to extend the +\mdline{6119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.TableEntry}}}\mdline{6119} message based on the value of architecture-specific table +properties, but we may include on in future versions of the API.%mdk + +%mdk-data-line={6122} +\section{\mdline{6122}21.\hspace*{0.5em}\mdline{6122}Known Limitations of Current P4Runtime Version}\label{sec-known-limitations-of-current-p4runtime-version}%mdk%mdk + +%mdk-data-line={6124} +\begin{itemize}%mdk + +%mdk-data-line={6124} +\item{} +%mdk-data-line={6124} +\mdline{6124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6124}, action \mdline{6124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6124}, and controller packet metadata fields only +support unsigned bitstrings, \mdline{6125}i.e.\mdline{6125} values of one of the following types (not +the more general \mdline{6126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{6126}):%mdk + +%mdk-data-line={6127} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6127} +\item\mdline{6127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6127}%mdk + +%mdk-data-line={6128} +\item\mdline{6128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6128}. Note that as far as the \mdline{6128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Info}}}\mdline{6128} message contents and +thus controller software is concerned, such fields of type \mdline{6129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6129} +will be indistinguishable from those that have been declared with +type \mdline{6131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6131}. P4Runtime server software will automatically +perform any conversion needed between the type \mdline{6132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6132} values in +P4Runtime messages and the data plane representation.%mdk + +%mdk-data-line={6134} +\item\mdline{6134}an \mdline{6134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{6134} with underlying type \mdline{6134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6134}%mdk + +%mdk-data-line={6135} +\item\mdline{6135}a \mdline{6135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6135} or \mdline{6135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6135} with an underlying type that is one of the above (or +in general a \mdline{6136}\textquotedblleft{}chain\textquotedblright{}\mdline{6136} of \mdline{6136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6136} and/or \mdline{6136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6136} that eventually ends with +one of the types above)%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6139} +\item{} +%mdk-data-line={6139} +\mdline{6139}Support for PSA Random \mdline{6139}\&\mdline{6139} Timestamp externs is postponed to a future minor +version update.%mdk%mdk + +%mdk-data-line={6142} +\item{} +%mdk-data-line={6142} +\mdline{6142}P4Info does not include information about which of a table\mdline{6142}'\mdline{6142}s actions execute +which direct resource(s).%mdk%mdk + +%mdk-data-line={6145} +\item{} +%mdk-data-line={6145} +\mdline{6145}The default action for indirect match tables is restricted to a \mdline{6145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\\ +NoAction}}}\mdline{6146} known at compile-time.%mdk%mdk + +%mdk-data-line={6148} +\item{} +%mdk-data-line={6148} +\mdline{6148}There is no mechanism for changing the value of the \mdline{6148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{6148} +table property at runtime.%mdk%mdk + +%mdk-data-line={6151} +\item{} +%mdk-data-line={6151} +\mdline{6151}There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor\mdline{6152} \mdline{6152}+ +patch version numbers.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6155} +\section{\mdline{6155}A.\hspace*{0.5em}\mdline{6155}Appendix}\label{sec-appendix}%mdk%mdk + +%mdk-data-line={6157} +\subsection{\mdline{6157}A.1.\hspace*{0.5em}\mdline{6157}Revision History}\label{sec-revision-history}%mdk%mdk + +%mdk-data-line={6159} +\subsubsection{\mdline{6159}A.1.1.\hspace*{0.5em}\mdline{6159}Changes in v1.3.0}\label{sec-changes-in-v130}%mdk%mdk + +%mdk-data-line={6161} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6161} +\item\mdline{6161}Add IANA assigned TCP port, 9559, to P4Runtime server discussion.%mdk + +%mdk-data-line={6162} +\item\mdline{6162}Move \mdline{6162}\textquotedblleft{}Security considerations\textquotedblright{}\mdline{6162} section to P4Runtime server discussion.%mdk + +%mdk-data-line={6163} +\item\mdline{6163}Deprecate \mdline{6163}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{6163} field (int32) in favor of \mdline{6163}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{6163} (bytes). This allows +using the watch port feature with the \mdline{6164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_translation}}}\mdline{6164} feature.%mdk + +%mdk-data-line={6165} +\item\mdline{6165}Replace master, slave, master arbitration with more inclusive language: +primary, backup, and client arbitration%mdk + +%mdk-data-line={6167} +\item\mdline{6167}Clarify that source locations for annotations are optional in the P4Info +message.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6170} +\subsubsection{\mdline{6170}A.1.2.\hspace*{0.5em}\mdline{6170}Changes in v1.2.0}\label{sec-changes-in-v120}%mdk%mdk + +%mdk-data-line={6172} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6172} +\item\mdline{6172}Add new \mdline{6172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6172} match kind. At the moment, \mdline{6172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6172} is only supported by +the v1model architecture\mdline{6173}~[\mdcite{v1model}{38}]\mdline{6173}, and not by PSA. It will eventually be +included in the core P4 language.%mdk + +%mdk-data-line={6175} +\item\mdline{6175}Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists.%mdk + +%mdk-data-line={6177} +\item\mdline{6177}Add a new \mdline{6177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6177} field of type \mdline{6177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{6177} to \mdline{6177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{6177}. This is more +flexible than the now deprecated \mdline{6178}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{6178} field.%mdk + +%mdk-data-line={6179} +\item\mdline{6179}Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +\mdline{6181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6181} annotation.%mdk + +%mdk-data-line={6182} +\item\mdline{6182}Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature.%mdk + +%mdk-data-line={6184} +\item\mdline{6184}Support using \mdline{6184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{6184} as the controller type in the \mdline{6184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6184} +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type.%mdk + +%mdk-data-line={6187} +\item\mdline{6187}Add optional P4 source locations to both structured and unstructured +annotations.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6190} +\subsubsection{\mdline{6190}A.1.3.\hspace*{0.5em}\mdline{6190}Changes in v1.1.0}\label{sec-changes-in-v110}%mdk%mdk + +%mdk-data-line={6192} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6192} +\item\mdline{6192}Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously.%mdk + +%mdk-data-line={6198} +\item\mdline{6198}Add \mdline{6198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{6198} field to stream messages sent by the server.%mdk + +%mdk-data-line={6199} +\item\mdline{6199}Add \mdline{6199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6199} RPC to query the P4Runtime API version implemented by the +server.%mdk + +%mdk-data-line={6201} +\item\mdline{6201}Support wildcard reads for multicast groups and clone sessions.%mdk + +%mdk-data-line={6202} +\item\mdline{6202}Support for modifying direct resources of const tables.%mdk + +%mdk-data-line={6203} +\item\mdline{6203}Support P4 user-defined types for Packet IO metadata fields.%mdk + +%mdk-data-line={6204} +\item\mdline{6204}Clarify consistency requirements for \mdline{6204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6204} and \mdline{6204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{6204} RPCs.%mdk + +%mdk-data-line={6205} +\item\mdline{6205}Add Appendix providing implementation advice for avoiding common pitfalls: + +%mdk-data-line={6206} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6206} +\item\mdline{6206}advice on setting gRPC Metadata Maximum Size%mdk + +%mdk-data-line={6207} +\item\mdline{6207}advice on setting gRPC Server Maximum Receive Message Size%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6208} +\item\mdline{6208}Clarify limitations on supported types for \mdline{6208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6208}, action \mdline{6208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6208}, and +Packet IO metadata fields.%mdk + +%mdk-data-line={6210} +\item\mdline{6210}Clarify that reading entire forwarding state with empty \mdline{6210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{6210} is not +supported.%mdk + +%mdk-data-line={6212} +\item\mdline{6212}Document that \mdline{6212}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6212} need only be supported when applied to +type declarations in P4.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6215} +\subsection{\mdline{6215}A.2.\hspace*{0.5em}\mdline{6215}P4 Annotations}\label{sec-p4-annotations}%mdk%mdk + +%mdk-data-line={6217} +\noindent\mdline{6217}Table\mdline{6217}~\mdref{tab-p4-annotations}{\mdcaptionlabel{7}}\mdline{6217} lists P4\mdline{6217}\mdsub{16}\mdline{6217} annotations introduced primarily for +the purpose of adding features for the P4Runtime API.%mdk + +%mdk-data-line={6220} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{6222} Annotation}}&\multicolumn{1}{|c|}{{\bfseries\mdline{6222} Description}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{6224} \mdline{6224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{6224}}&\multicolumn{1}{|l|}{\mdline{6224} See section\mdline{6224}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6224}}\\ +\multicolumn{1}{|l}{\mdline{6225} \mdline{6225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{6225}}&\multicolumn{1}{|l|}{\mdline{6225} See section\mdline{6225}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{6225}}\\ +\multicolumn{1}{|l}{\mdline{6226} \mdline{6226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{6226}}&\multicolumn{1}{|l|}{\mdline{6226} See section\mdline{6226}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6226}}\\ +\multicolumn{1}{|l}{\mdline{6227} \mdline{6227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6227}}&\multicolumn{1}{|l|}{\mdline{6227} See section\mdline{6227}~\mdref{sec-id-allocation}{6.3}\mdline{6227}}\\ +\multicolumn{1}{|l}{\mdline{6228} \mdline{6228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{6228}}&\multicolumn{1}{|l|}{\mdline{6228} See sections\mdline{6228}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{6228},\mdline{6228}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{6228}}\\ +\multicolumn{1}{|l}{\mdline{6229} \mdline{6229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{6229}}&\multicolumn{1}{|l|}{\mdline{6229} See section\mdline{6229}~\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1}\mdline{6229}}\\ +\multicolumn{1}{|l}{\mdline{6230} \mdline{6230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6230}}&\multicolumn{1}{|l|}{\mdline{6230} See sections\mdline{6230}~\mdref{sec-user-defined-types}{8.5.6}\mdline{6230},\mdline{6230}~\mdref{sec-translation-of-port-numbers}{18.1.1}\mdline{6230}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={6232} +\mdhr{}%mdk + +%mdk-data-line={6233} +\noindent\mdline{6233}\mdcaption{\textbf{Table~\mdcaptionlabel{7}.}~\mdcaptiontext{P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-annotations}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={6236} +\subsection{\mdline{6236}A.3.\hspace*{0.5em}\mdline{6236}A More Complex Value Set Example}\label{sec-value-set-example}%mdk%mdk + +%mdk-data-line={6238} +\noindent\mdline{6238}This section includes a more complex Value Set example, with multiple matches of +different kinds.%mdk + +%mdk-data-line={6241} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6242} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6251} +\noindent\mdline{6251}This P4 Value Set declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={6254} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6255} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6282} +\noindent\mdline{6282}A P4Runtime client can set the membership for this Value Set with \mdline{6282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6282} +messages similar to this one:%mdk + +%mdk-data-line={6285} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6286} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xac}~\}\\ +~~~~~~\}\\ +~~~~~~{\mdcolor{darkgreen}\#~match~for~field\_id~2~is~missing~=\textgreater{}~don't~care~match}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xdc}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~~~ternary~\{~value:~{\mdcolor{purple}0x88}~mask:~{\mdcolor{purple}8}f~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6320} +\subsection{\mdline{6320}A.4.\hspace*{0.5em}\mdline{6320}Guidelines for Implementations}\label{sec-guidelines-for-implementations}%mdk%mdk + +%mdk-data-line={6322} +\noindent\mdline{6322}This section contains practical advice for implementing P4Runtime clients and +servers.%mdk + +%mdk-data-line={6325} +\subsubsection{\mdline{6325}A.4.1.\hspace*{0.5em}\mdline{6325}gRPC Metadata Maximum Size}\label{sec-grpc-metadata-maximum-size}%mdk%mdk + +%mdk-data-line={6327} +\noindent\mdline{6327}In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the \mdline{6328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6328} gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the \mdline{6329}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6329} P4Runtime RPC. The \mdline{6329}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6329} RPC +returns an individual error for every item in a batch (see Section +\mdline{6331}\mdref{sec-write-rpc}{12}\mdline{6331}), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +\mdline{6333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{6333} error, without any of the individual errors.%mdk + +%mdk-data-line={6335} +\mdline{6335}To fix this problem, one can set the \mdline{6335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6335} option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it\mdline{6337}'\mdline{6337}s +limit, as only the receiving side\mdline{6338}'\mdline{6338}s limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every \mdline{6340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{6340}, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +\mdline{6342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}8192~+~MAX\_UPDATES\_PER\_WRITE~*~100}}}\mdline{6342} bytes of metadata.%mdk + +%mdk-data-line={6344} +\mdline{6344}For example, in C++, one can create a client channel as follows:%mdk + +%mdk-data-line={6345} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6346} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}~=~{\mdcolor{purple}100};\\ +::{\mdcolor{navy}grpc::}ChannelArguments~arguments;\\ +arguments{\bfseries{\mdcolor{navy}.}}SetInt({\mdcolor{teal}GRPC\_ARG\_MAX\_METADATA\_SIZE},~{\mdcolor{purple}8192}~+~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}*{\mdcolor{purple}100});\\ +{\bfseries{\mdcolor{navy}return}}~{\mdcolor{navy}grpc::}CreateCustomChannel(address,~credentials,~arguments);}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6352} +\subsubsection{\mdline{6352}A.4.2.\hspace*{0.5em}\mdline{6352}gRPC Server Maximum Receive Message Size}\label{sec-grpc-server-maximum-receive-message-size}%mdk%mdk + +%mdk-data-line={6354} +\noindent\mdline{6354}At the time of writing, the default maximum receive message size in gRPC is 4MB +\mdline{6355}\textemdash{}\mdline{6355} while the default maximum send message size is unlimited. This can be a +problem for the \mdline{6356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{6356} RPC, since for some targets the +binary \mdline{6357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6357} can exceed 4MB, in which case by default the P4Runtime +server would return an \mdline{6358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6358} error. To a lesser extent, this may +affect the \mdline{6359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6359} RPC as well, in case of extremely large batches.%mdk + +%mdk-data-line={6361} +\mdline{6361}To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of \mdline{6363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6363} for their target(s). This can be done by +setting the \mdline{6364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_receive\_message\_length}}}\mdline{6364} when building the gRPC server.%mdk + +%mdk-data-line={6366} +\mdline{6366}For example, in C++, one can set the maximum receive message size as follows:%mdk + +%mdk-data-line={6367} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6368} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE}~=~{\mdcolor{purple}128}~*~{\mdcolor{purple}1024}~*~{\mdcolor{purple}1024};~~{\mdcolor{darkgreen}//~128MB}\\ +::{\mdcolor{navy}grpc::}ServerBuilder~server\_builder;\\ +builder{\bfseries{\mdcolor{navy}.}}AddListeningPort({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});\\ +builder{\bfseries{\mdcolor{navy}.}}RegisterService({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});~~{\mdcolor{darkgreen}//~register~P4Runtime~service}\\ +builder{\bfseries{\mdcolor{navy}.}}SetMaxReceiveMessageSize({\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE});\\ +builder{\bfseries{\mdcolor{navy}.}}BuildAndStart();}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6376} +\noindent\mdline{6376}On the client side, we recommend that P4Runtime clients do not use \mdline{6376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6376} +batches larger than the default maximum receive message size (4MB)\mdline{6377} \mdline{6377}\textemdash{}\mdline{6377} in case +the server did not deem necessary to increase the default value\mdline{6378} \mdline{6378}\textemdash{}\mdline{6378}, unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB).%mdk + +%mdk-data-line={6383;build/P4Runtime-Spec-bib.bbl.mdk:1} +%mdk-data-line={6383;build/P4Runtime-Spec-bib.bbl.mdk:2} +\mdsetrefname{References}%mdk +{\mdbibindent{0}%mdk +\begin{thebibliography}{39}%mdk +\label{sec-bibliography}%mdk + +%mdk-data-line={references.bib:68} +\bibitem{p4spec}\mdbibitemlabel{{}[1]}\textquotedblleft{}$P4_{16}$ 1.2.1 Specification.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html}}.\label{p4spec}%mdk%mdk + +%mdk-data-line={references.bib:134} +\bibitem{rfc2698}\mdbibitemlabel{{}[2]}\textquotedblleft{}A Two Rate Three Color Marker.\textquotedblright{} \href{https://tools.ietf.org/html/rfc2698}{{\ttfamily https://\hspace{0pt}tools.\hspace{0pt}ietf.\hspace{0pt}org/\hspace{0pt}html/\hspace{0pt}rfc2698}}.\label{rfc2698}%mdk%mdk + +%mdk-data-line={references.bib:32} +\bibitem{p4complextypes}\mdbibitemlabel{{}[3]}\textquotedblleft{}Complex Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-p4-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}p4-\hspace{0pt}type}}.\label{p4complextypes}%mdk%mdk + +%mdk-data-line={references.bib:37} +\bibitem{protodefaults}\mdbibitemlabel{{}[4]}\textquotedblleft{}Default Values for Protobuf 3 ($proto3$) Fields.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23default}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}default}}.\label{protodefaults}%mdk%mdk + +%mdk-data-line={references.bib:78} +\bibitem{p4enums}\mdbibitemlabel{{}[5]}\textquotedblleft{}Enums in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-enum-types}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}enum-\hspace{0pt}types}}.\label{p4enums}%mdk%mdk + +%mdk-data-line={references.bib:119} +\bibitem{apiversioning}\mdbibitemlabel{{}[6]}\textquotedblleft{}Google Cloud APIs Versioning.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning}}.\label{apiversioning}%mdk%mdk + +%mdk-data-line={references.bib:124} +\bibitem{apiversioningbackwardscompatibility}\mdbibitemlabel{{}[7]}\textquotedblleft{}Google Cloud APIs Versioning - Backwards-Compatibility.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning\%23backwards_compatibility}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning\#\hspace{0pt}backwards\_\hspace{0pt}compatibility}}.\label{apiversioningbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:149} +\bibitem{grpcauth}\mdbibitemlabel{{}[8]}\textquotedblleft{}gRPC Authentication.\textquotedblright{} \href{https://grpc.io/docs/guides/auth.html}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}guides/\hspace{0pt}auth.\hspace{0pt}html}}.\label{grpcauth}%mdk%mdk + +%mdk-data-line={references.bib:7} +\bibitem{grpc}\mdbibitemlabel{{}[9]}\textquotedblleft{}gRPC Main Site.\textquotedblright{} \href{https://grpc.io}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io}}.\label{grpc}%mdk%mdk + +%mdk-data-line={references.bib:144} +\bibitem{grpcstreamc}\mdbibitemlabel{{}[10]}\textquotedblleft{}gRPC Streaming RPCs in C++.\textquotedblright{} \href{https://grpc.io/docs/tutorials/basic/c.html\%23streaming-rpcs}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}tutorials/\hspace{0pt}basic/\hspace{0pt}c.\hspace{0pt}html\#\hspace{0pt}streaming-\hspace{0pt}rpcs}}.\label{grpcstreamc}%mdk%mdk + +%mdk-data-line={references.bib:114} +\bibitem{p4newtypes}\mdbibitemlabel{{}[11]}\textquotedblleft{}Introducing New Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-newtype}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}newtype}}.\label{p4newtypes}%mdk%mdk + +%mdk-data-line={references.bib:139} +\bibitem{p4matchtypes}\mdbibitemlabel{{}[12]}\textquotedblleft{}Match Types in P4.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-match-kind-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}match-\hspace{0pt}kind-\hspace{0pt}type}}.\label{p4matchtypes}%mdk%mdk + +%mdk-data-line={references.bib:194} +\bibitem{p4annotations}\mdbibitemlabel{{}[13]}\textquotedblleft{}P4 Annotations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-annotations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}annotations}}.\label{p4annotations}%mdk%mdk + +%mdk-data-line={references.bib:174} +\bibitem{p4concurrency}\mdbibitemlabel{{}[14]}\textquotedblleft{}P4 Concurrency Model.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-concurrency}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}concurrency}}.\label{p4concurrency}%mdk%mdk + +%mdk-data-line={references.bib:1} +\bibitem{p4runtimerepo}\mdbibitemlabel{{}[15]}\textquotedblleft{}p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.\textquotedblright{} \href{https://github.com/p4lang/p4runtime}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4runtime}}.\label{p4runtimerepo}%mdk%mdk + +%mdk-data-line={references.bib:42} +\bibitem{pirepo}\mdbibitemlabel{{}[16]}\textquotedblleft{}p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.\textquotedblright{} \href{https://github.com/p4lang/PI}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}PI}}.\label{pirepo}%mdk%mdk + +%mdk-data-line={references.bib:109} +\bibitem{p4apiwgcharter}\mdbibitemlabel{{}[17]}\textquotedblleft{}P4.org API Working Group Charter.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4_API_WG_charter.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4\_\hspace{0pt}API\_\hspace{0pt}WG\_\hspace{0pt}charter.\hspace{0pt}html}}.\label{p4apiwgcharter}%mdk%mdk + +%mdk-data-line={references.bib:154} +\bibitem{p4actionannotations}\mdbibitemlabel{{}[18]}\textquotedblleft{}P4 Standard Annotations on Table Actions.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-action-anno}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}action-\hspace{0pt}anno}}.\label{p4actionannotations}%mdk%mdk + +%mdk-data-line={references.bib:73} +\bibitem{psa}\mdbibitemlabel{{}[19]}\textquotedblleft{}Portable Switch Architecture Specification (v1.1.0).\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html}}.\label{psa}%mdk%mdk + +%mdk-data-line={references.bib:189} +\bibitem{protooneofbackwardscompatibility}\mdbibitemlabel{{}[20]}\textquotedblleft{}Protobuf OneOf Backwards-Compatibility Issues.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23backwards-compatibility-issues}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}backwards-\hspace{0pt}compatibility-\hspace{0pt}issues}}.\label{protooneofbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:12} +\bibitem{proto}\mdbibitemlabel{{}[21]}\textquotedblleft{}Protocol Buffers Main Site.\textquotedblright{} \href{https://developers.google.com/protocol-buffers}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers}}.\label{proto}%mdk%mdk + +%mdk-data-line={references.bib:159} +\bibitem{psaactionselector}\mdbibitemlabel{{}[22]}\textquotedblleft{}PSA Action Selector.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-action-selector}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}action-\hspace{0pt}selector}}.\label{psaactionselector}%mdk%mdk + +%mdk-data-line={references.bib:169} +\bibitem{psaatomicityofcontrolplaneops}\mdbibitemlabel{{}[23]}\textquotedblleft{}PSA Atomicity of Control Plane Operations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-atomicity-of-control-plane-api-operations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}atomicity-\hspace{0pt}of-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}api-\hspace{0pt}operations}}.\label{psaatomicityofcontrolplaneops}%mdk%mdk + +%mdk-data-line={references.bib:179} +\bibitem{psatranslation}\mdbibitemlabel{{}[24]}\textquotedblleft{}PSA Data Plane vs Control Plane Types.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-data-plane-vs-control-plane-values}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}data-\hspace{0pt}plane-\hspace{0pt}vs-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}values}}.\label{psatranslation}%mdk%mdk + +%mdk-data-line={references.bib:164} +\bibitem{psaemptygroupactionappendix}\mdbibitemlabel{{}[25]}\textquotedblleft{}PSA Empty Group Action Appendix.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23appendix-empty-action-selector-groups}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}appendix-\hspace{0pt}empty-\hspace{0pt}action-\hspace{0pt}selector-\hspace{0pt}groups}}.\label{psaemptygroupactionappendix}%mdk%mdk + +%mdk-data-line={references.bib:58} +\bibitem{p4selectexpr}\mdbibitemlabel{{}[26]}\textquotedblleft{}Select Expressions in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-select}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}select}}.\label{p4selectexpr}%mdk%mdk + +%mdk-data-line={references.bib:129} +\bibitem{semver}\mdbibitemlabel{{}[27]}\textquotedblleft{}Semantic Versioning.\textquotedblright{} \href{https://semver.org/}{{\ttfamily https://\hspace{0pt}semver.\hspace{0pt}org/\hspace{0pt}}}.\label{semver}%mdk%mdk + +%mdk-data-line={references.bib:98} +\bibitem{protostatus}\mdbibitemlabel{{}[28]}\textquotedblleft{}Status.proto:the Protobuf Status Message.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}src/\hspace{0pt}proto/\hspace{0pt}grpc/\hspace{0pt}status/\hspace{0pt}status.\hspace{0pt}proto}}.\label{protostatus}%mdk%mdk + +%mdk-data-line={references.bib:63} +\bibitem{p4revisions110}\mdbibitemlabel{{}[29]}\textquotedblleft{}Summary of Changes Made in $P4_{16}$ Version 1.1.0.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-summary-of-changes-made-in-version-110}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}summary-\hspace{0pt}of-\hspace{0pt}changes-\hspace{0pt}made-\hspace{0pt}in-\hspace{0pt}version-\hspace{0pt}110}}.\label{p4revisions110}%mdk%mdk + +%mdk-data-line={references.bib:48} +\bibitem{p4tableproperties}\mdbibitemlabel{{}[30]}\textquotedblleft{}Table Properties in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-props}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}props}}.\label{p4tableproperties}%mdk%mdk + +%mdk-data-line={references.bib:83} +\bibitem{protoany}\mdbibitemlabel{{}[31]}\textquotedblleft{}The Any Protobuf Message.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23any}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}any}}.\label{protoany}%mdk%mdk + +%mdk-data-line={references.bib:88} +\bibitem{grpcstatus}\mdbibitemlabel{{}[32]}\textquotedblleft{}The gRPC $Status$ Class.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/status.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}impl/\hspace{0pt}codegen/\hspace{0pt}status.\hspace{0pt}h}}.\label{grpcstatus}%mdk%mdk + +%mdk-data-line={references.bib:104} +\bibitem{grpcerrordetails}\mdbibitemlabel{{}[33]}\textquotedblleft{}The gRPC C++ Error Details Library.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/support/error_details.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}support/\hspace{0pt}error\_\hspace{0pt}details.\hspace{0pt}h}}.\label{grpcerrordetails}%mdk%mdk + +%mdk-data-line={references.bib:93} +\bibitem{grpcstatuscodes}\mdbibitemlabel{{}[34]}\textquotedblleft{}The gRPC Canonical Status Codes.\textquotedblright{} \href{https://developers.google.com/maps-booking/reference/grpc-api/status_codes}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}maps-\hspace{0pt}booking/\hspace{0pt}reference/\hspace{0pt}grpc-\hspace{0pt}api/\hspace{0pt}status\_\hspace{0pt}codes}}.\label{grpcstatuscodes}%mdk%mdk + +%mdk-data-line={references.bib:22} +\bibitem{openconfig}\mdbibitemlabel{{}[35]}\textquotedblleft{}The OpenConfig Project.\textquotedblright{} \href{http://openconfig.net}{{\ttfamily http://\hspace{0pt}openconfig.\hspace{0pt}net}}.\label{openconfig}%mdk%mdk + +%mdk-data-line={references.bib:184} +\bibitem{protomessagedifferencer}\mdbibitemlabel{{}[36]}\textquotedblleft{}The Protobuf MessageDifferencer in the C++ API.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.util.message_differencer}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}reference/\hspace{0pt}cpp/\hspace{0pt}google.\hspace{0pt}protobuf.\hspace{0pt}util.\hspace{0pt}message\_\hspace{0pt}differencer}}.\label{protomessagedifferencer}%mdk%mdk + +%mdk-data-line={references.bib:27} +\bibitem{stratum}\mdbibitemlabel{{}[37]}\textquotedblleft{}The Stratum Project.\textquotedblright{} \href{https://stratumproject.org/}{{\ttfamily https://\hspace{0pt}stratumproject.\hspace{0pt}org/\hspace{0pt}}}.\label{stratum}%mdk%mdk + +%mdk-data-line={references.bib:199} +\bibitem{v1model}\mdbibitemlabel{{}[38]}\textquotedblleft{}v1model Architecture Definition.\textquotedblright{} \href{https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4c/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}p4include/\hspace{0pt}v1model.\hspace{0pt}p4}}.\label{v1model}%mdk%mdk + +%mdk-data-line={references.bib:53} +\bibitem{p4valuesets}\mdbibitemlabel{{}[39]}\textquotedblleft{}Value Sets in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-value-set}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}value-\hspace{0pt}set}}.\label{p4valuesets}%mdk%mdk +\par%mdk +\end{thebibliography}}%mdk%mdk +}%mdk + + +\end{document} diff --git a/spec/v1.4.0-rc.4/ellipse.sty b/spec/v1.4.0-rc.4/ellipse.sty new file mode 100644 index 00000000..7c0ecb3e --- /dev/null +++ b/spec/v1.4.0-rc.4/ellipse.sty @@ -0,0 +1,318 @@ +%% +%% This is file `ellipse.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ellipse.dtx (with options: `package') +%% +%% Copyright (C) 2015 +%% Daan Leijen +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". +%% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{ellipse} + [2004/11/05 v1.0 .dtx ellipse file] +\RequirePackage{pict2e} + +\providecommand*\pIIe@csedef[1]{\expandafter\edef\csname #1\endcsname} +\newcommand*\pIIe@ellip@csqrt[3]{% + \@ovxx=#1\relax + \ifdim\@ovxx<\z@\@ovxx-\@ovxx\fi + \@ovyy=#2\relax + \ifdim\@ovyy<\z@\@ovyy-\@ovyy\fi + \edef\pIIe@csname{@csqrt(\number\@ovxx,\number\@ovyy)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@ellip@csqrt@% + \pIIe@csedef{\pIIe@csname}{\the\dimen@}% + #3\dimen@ + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} +\newcommand*\pIIe@ellip@csqrt@{% + \@ovdx\@ovxx + \advance\@ovdx by \@ovyy + \dimen@0.7071067\@ovdx + \ifdim\dimen@<\@ovyy\dimen@\@ovyy\fi + \ifdim\dimen@<\@ovxx\dimen@\@ovxx\fi + \ifdim\@ovdx<128\p@ + \edef\@tempa{\strip@pt\@ovxx}% + \@ovxx\@tempa\@ovxx + \edef\@tempa{\strip@pt\@ovyy}% + \@ovyy\@tempa\@ovyy + \advance\@ovxx by \@ovyy + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \fi +} + +\newcommand*\pIIe@atan@{% + \@tempdima\dimen@ + \@tempdimb\@tempdima + \ifdim\@tempdimb<\z@\@tempdimb-\@tempdimb\fi + \dimen@0.0663\@tempdimb + \advance\dimen@ 0.2447pt\relax + \advance\@tempdimb -1pt\relax + \edef\@tempa{\strip@pt\@tempdimb}% + \dimen@\@tempa\dimen@ + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \dimen@-\dimen@ + \advance\dimen@ 0.7853\@tempdima +} + +\newcommand*\pIIe@atantwo[3]{% + \edef\pIIe@csname{@atan2(\number\dimexpr#1\relax,\number\dimexpr#2\relax)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@atantwo@{#1}{#2}{#3}% + \pIIe@csedef{\pIIe@csname}{\the\dimexpr#3\relax}% + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} + +\newcommand*\pIIe@atantwo@[3]{% + \@tempdima\dimexpr#2\relax + \@tempdimb\dimexpr#1\relax + \ifdim\@tempdima=\z@\relax + \ifdim\@tempdimb>\z@\relax\dimen@90\p@ + \else\ifdim\@tempdimb<\z@\relax\dimen@-90\p@ + \else\dimen@0\p@ + \fi\fi + \else + \@tempdimd\z@ + \ifdim\@tempdima<\z@\relax + \ifdim\@tempdimb<\z@\relax\@tempdimd-180\p@ + \else\@tempdimd180\p@ + \fi + \fi + \dimen@\dimexpr1pt * \@tempdimb/\@tempdima\relax + \@tempdimc\dimen@ + \ifdim\@tempdimc<\z@\relax\@tempdimc-\@tempdimc\fi + \ifdim\@tempdimc>\p@\relax + \dimen@\dimexpr1pt * \@tempdima/\@tempdimb\relax + \ifdim\dimen@<\z@\relax\def\@tempsign{-}\else\def\@tempsign{}\fi + \pIIe@atan@ + \dimen@-\dimen@ + \advance\dimen@ by \@tempsign1.5707pt\relax + \else + \pIIe@atan@ + \fi + \dimen@57.29578\dimen@ + \advance\dimen@ by \@tempdimd + \fi + #3\dimen@% +} + +\newcommand*\pIIe@noneto[2]{} +\newcommand*\pIIe@ellip@sincost@[2]{% + \CalculateSin{#1}% + \CalculateCos{#1}% + \@tempdima\UseSin{#1}\p@ + \@tempdimb\UseCos{#1}\p@ + \ifdim\@tempdima=\p@\relax + \pIIe@csedef{@ellipsin#2}{1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else\ifdim\@tempdima=-\p@\relax + \pIIe@csedef{@ellipsin#2}{-1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else + \@tempdimc\@ellipratio\dimexpr1pt * \@tempdima/\@tempdimb\relax + %\typeout{ i#2=\the\@tempdimc, sin(#1)=\the\@tempdima}% + \pIIe@ellip@csqrt{\p@}{\@tempdimc}\@tempdimd + \ifdim\@tempdimb<\z@\relax\@tempdimd-\@tempdimd\fi + \pIIe@csedef{@ellipsin#2}{\strip@pt\dimexpr1pt * \@tempdimc/\@tempdimd\relax}% + \pIIe@csedef{@ellipcos#2}{\strip@pt\dimexpr1pt * \p@/\@tempdimd\relax}% + \fi\fi +} + +\newcommand*\pIIe@ellip@sincost[2]{% + %\typeout{ calc sin cos: angles (#1,#2), radii: (\the\@ovro,\the\@ovri)}% + \edef\@ellipratio{\strip@pt\dimexpr1pt * \@ovro/\@ovri\relax}% + \pIIe@ellip@sincost@{#1}{one}% + \pIIe@ellip@sincost@{#2}{two}% + %\typeout{ sincos(a=#1)=(\@ellipsinone,\@ellipcosone), sincos(a=#2)=(\@ellipsintwo,\@ellipcostwo), }% +} +\newcommand*\pIIe@omega[3]{% + \@tempdima\csname @ellipcos#3\endcsname\@ovro + \advance\@tempdima by #1\relax + \@tempdimb\csname @ellipsin#3\endcsname\@ovri + \advance\@tempdimb by #2\relax +} + +\newcommand*\pIIe@omegai[1]{% + \@tempdimc\csname @ellipsin#1\endcsname\@ovro + \@tempdimc-\@tempdimc + \@tempdimd\csname @ellipcos#1\endcsname\@ovri +} + +\newcommand*\pIIe@ellip@kappa{% + \@ovyy\@ellipsinone\p@ + \@ovxx\@ellipcosone\p@ + \@tempdima\@ellipcostwo\@ovyy + \@tempdima-\@tempdima + \advance\@tempdima by \@ellipsintwo\@ovxx + \@tempdimb\@ellipcostwo\@ovxx + \advance\@tempdimb by \@ellipsintwo\@ovyy + \ifdim\@tempdima=\z@\relax + \edef\@ellipkappa{0}% + \else + \dimen@\dimexpr1pt - \@tempdimb\relax + \dimen@\dimexpr1pt * \dimen@/\@tempdima\relax + \pIIe@ellip@csqrt{2\p@}{1.73205\dimen@}{\dimen@}% + \advance\dimen@ by -\p@ + \divide\dimen@ by 3% + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \edef\@ellipkappa{\strip@pt\dimen@}% + \fi + %\typeout{ calculated kappa: \@ellipkappa}% +} + +\newcommand*\pIIe@elliparc@[5]{% + %\typeout{elliparc: #1, center: (#2, #3), radius (\the\@ovro, \the\@ovri),angle (#4, #5)}% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \pIIe@ellip@sincost{#4}{#5}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@t[5]{% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \CalculateSin{#4}\CalculateCos{#4}% + \edef\@ellipsinone{\UseSin{#4}}% + \edef\@ellipcosone{\UseCos{#4}}% + \CalculateSin{#5}\CalculateCos{#5}% + \edef\@ellipsintwo{\UseSin{#5}}% + \edef\@ellipcostwo{\UseCos{#5}}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@draw[2]{% + \pIIe@ellip@kappa% + \pIIe@omega{#1}{#2}{one}% + %\typeout{ point one: (\the\@tempdima,\the\@tempdimb)}% + \@ellip@startto\@tempdima\@tempdimb + \pIIe@omegai{one}% + \advance\@tempdima by \@ellipkappa\@tempdimc + \advance\@tempdimb by \@ellipkappa\@tempdimd + \pIIe@add@nums\@tempdima\@tempdimb + %\typeout{ control one: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@omega{#1}{#2}{two}% + \pIIe@omegai{two}% + \@tempdimc\@ellipkappa\@tempdimc + \@tempdimd\@ellipkappa\@tempdimd + \@tempdimc-\@tempdimc + \@tempdimd-\@tempdimd + \advance\@tempdimc by \@tempdima + \advance\@tempdimd by \@tempdimb + \pIIe@add@nums\@tempdimc\@tempdimd + %\typeout{ control two: (\the\@tempdimc,\the\@tempdimd)}% + \pIIe@add@CP\@tempdima\@tempdimb + %\typeout{ point two: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@addtoGraph\pIIe@curveto@op +} +\newcommand*\pIIe@elliparc[7][0]{% + \@ovro #4\relax + \@ovri #5\relax + \iffalse%dim\@ovro=\@ovri + \pIIe@arc[#1]{#2}{#3}{#4}{#6}{#7} + \else + \ifdim \@ovro<\z@ \pIIe@badcircarg\else + \ifdim \@ovri<\z@ \pIIe@badcircarg\else + \@arclen #7\p@ \advance\@arclen -#6\p@ + \ifdim \@arclen<\z@ \def\@tempsign{-}\else\def\@tempsign{}\fi + \ifdim \@tempsign\@arclen>720\p@ + \PackageWarning {ellipse}{The arc angle is reduced to -720..720}% + \@whiledim \@tempsign\@arclen>720\p@ \do {\advance\@arclen-\@tempsign360\p@}% + \@tempdima #6\p@ \advance\@tempdima \@arclen + \edef\@angleend{\strip@pt\@tempdima}% + \pIIe@@elliparc{#1}{#2}{#3}{#6}{\@angleend}% + \else + \pIIe@@elliparc{#1}{#2}{#3}{#6}{#7}% + \fi + \fi + \fi + \fi +} +\newcommand*\pIIe@@elliparc[5]{% + \begingroup + \ifdim \@tempsign\@arclen>90\p@ + \divide\@arclen 2% + \@tempdima #4\p@\advance\@tempdima by \@arclen + \edef\@anglemid{\strip@pt\@tempdima}% + \def\@tempa{\pIIe@@elliparc{#1}{#2}{#3}{#4}}% + \expandafter\@tempa\expandafter{\@anglemid}% + \def\@tempa{\pIIe@@elliparc{2}{#2}{#3}}% + \expandafter\@tempa\expandafter{\@anglemid}{#5}% + \else + \pIIe@elliparc@{#1}{#2}{#3}{#4}{#5}% + \fi + \endgroup +}% + +\newcommand*\pIIeelliparc[7][0]{% + \@killglue + \pIIe@elliparc[#1]{#2\unitlength}{#3\unitlength}{#4\unitlength}{#5\unitlength}{#6}{#7}% + \ignorespaces% +} +\ifx\undefined\elliparc\else + \PackageWarning{ellipse}{\protect\elliparc\space is redefined}% +\fi +\let\elliparc\pIIeelliparc + +\newcommand*\pIIeearc + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\newcommand*\pIIe@earc@[3][0,360]{\pIIe@earc@@(#1){#2}{#3}} +\def\pIIe@earc@@(#1,#2)#3#4{% + \if@tempswa + \pIIe@moveto\z@\z@ + \pIIe@elliparc{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@closepath\pIIe@fillGraph + \else + \pIIe@elliparc[1]{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@strokeGraph + \fi} +\ifx\undefined\earc\else + \PackageWarning{ellipse}{\protect\earc\space is redefined}% +\fi +\let\earc\pIIeearc + +\newcommand*\pIIeellipse + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\let\ellipse\pIIeellipse + +\endinput +%% +%% End of file `ellipse.sty'. diff --git a/spec/v1.4.0-rc.4/embedded-plus-single-remote-controller.png b/spec/v1.4.0-rc.4/embedded-plus-single-remote-controller.png new file mode 100644 index 00000000..2e0f1803 Binary files /dev/null and b/spec/v1.4.0-rc.4/embedded-plus-single-remote-controller.png differ diff --git a/spec/v1.4.0-rc.4/embedded-plus-single-remote-controller.svg b/spec/v1.4.0-rc.4/embedded-plus-single-remote-controller.svg new file mode 100644 index 00000000..9fe2ce9c --- /dev/null +++ b/spec/v1.4.0-rc.4/embedded-plus-single-remote-controller.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0-rc.4/embedded-plus-two-remote-controllers.png b/spec/v1.4.0-rc.4/embedded-plus-two-remote-controllers.png new file mode 100644 index 00000000..b6dc04fc Binary files /dev/null and b/spec/v1.4.0-rc.4/embedded-plus-two-remote-controllers.png differ diff --git a/spec/v1.4.0-rc.4/embedded-plus-two-remote-controllers.svg b/spec/v1.4.0-rc.4/embedded-plus-two-remote-controllers.svg new file mode 100644 index 00000000..0f97ba38 --- /dev/null +++ b/spec/v1.4.0-rc.4/embedded-plus-two-remote-controllers.svg @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + + + Entities + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0-rc.4/embedded-plus-two-remote-ha-controllers.png b/spec/v1.4.0-rc.4/embedded-plus-two-remote-ha-controllers.png new file mode 100644 index 00000000..392f8963 Binary files /dev/null and b/spec/v1.4.0-rc.4/embedded-plus-two-remote-ha-controllers.png differ diff --git a/spec/v1.4.0-rc.4/embedded-plus-two-remote-ha-controllers.svg b/spec/v1.4.0-rc.4/embedded-plus-two-remote-ha-controllers.svg new file mode 100644 index 00000000..97ab6fc3 --- /dev/null +++ b/spec/v1.4.0-rc.4/embedded-plus-two-remote-ha-controllers.svg @@ -0,0 +1,511 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + Primary (Active) + + + + + + Backup (Standby) + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0-rc.4/error-report.png b/spec/v1.4.0-rc.4/error-report.png new file mode 100644 index 00000000..766cb77f Binary files /dev/null and b/spec/v1.4.0-rc.4/error-report.png differ diff --git a/spec/v1.4.0-rc.4/error-report.svg b/spec/v1.4.0-rc.4/error-report.svg new file mode 100644 index 00000000..a2709a72 --- /dev/null +++ b/spec/v1.4.0-rc.4/error-report.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StatusCode error_code_; // canonical error codestring error_message_;string binary_error_details_; // serialized google.rpc.Status + + + + + + + + + + + + + google.rpc.Status + + + + + + int32 error_code; // canonical error codestring message;repeated Any details; // P4Error + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + + + p4.Error + + + + + + p4.Error + + + + + + + + + + + + + + + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + grpc::Status + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0-rc.4/longbox.sty b/spec/v1.4.0-rc.4/longbox.sty new file mode 100644 index 00000000..cab48934 --- /dev/null +++ b/spec/v1.4.0-rc.4/longbox.sty @@ -0,0 +1,853 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longbox}[2015/12/01, Daan Leijen, Provides basic longbox that can break over pages] +\RequirePackage{options} + +\@ifclassloaded{beamer}{% + \newcommand\lb@savefootnotes{}% + \newcommand\lb@restorefootnotes{}% +}% +{\RequirePackage{footnote}% + \newcommand\lb@savefootnotes{\savenotes}% + \newcommand\lb@restorefootnotes{\spewnotes}% +} + + +% -------------------------------------------------------- +% Debugging +% -------------------------------------------------------- + +\newcommand*\lb@debug[1]{% + \ontoggle{lb@debug}{\typeout{longbox debug: #1}}% +} +\newcommand*\lb@typeout[1]{% + \ontoggle{lb@verbose}{\typeout{longbox: #1}}% +} +\newcommand*\lb@warncannotsplit{% + \PackageWarning{longbox}{Cannot split box; it seems you are using a non-splittable contents}% +} +\newcommand*\lb@warnbadsplit[1]{% + \PackageWarning{longbox}{Bad split (underful vbox by \the#1)}% +} + + +% -------------------------------------------------------- +% Utilities for LaTeX internals +% -------------------------------------------------------- + +% Suppress the indentation on the following paragraph +\providecommand\nofirstindent{\@afterindentfalse\@afterheading} + +% Suppress the paragraph skip on the following paragraph +\providecommand\nofirstparskip{\addvskip{-\parskip}} + +% In contrast to addvspace, addvskip is not suppressed in a minipage +\providecommand\addvskip[1]{% + \ifvmode + \ifdim\lastskip=\z@ + \vskip #1\relax + \else + \@tempskipb#1\relax\@xaddvskip + \fi + \else\@noitemerr\fi +} + + +% Skip to 0.3\baselineskip multiple taking prevdepth into account. +\newskip\lb@prevdepth +\newcommand\lb@skiptobaseline{% + \global\lb@prevdepth=-\@m\p@\relax + \ifvmode + \ifdim\lastskip=\z@\relax + \ifdim\prevdepth=-\@m\p@\else + \dimen@\prevdepth + % Calculate the modulus of the previous depth with 0.3|\baselineskip| in |\dimen@|. + \@tempcnta\prevdepth + \@tempskipa=0.3\baselineskip\relax + \@tempcntb=\@tempskipa\relax + \divide \@tempcnta by \@tempcntb + \dimen@\prevdepth + \advance\dimen@ -\@tempcnta\@tempskipa + % Skip back by that amount, and then skip by 0.3|\baselineskip|. + \vskip -\dimen@ + \vskip \@tempskipa\relax + \global\lb@prevdepth=\@tempskipa\relax + \fi + \fi + \fi +} + +% unvbox a box, and return a vbox with a given background color +% \unvcolorbox{}{} +\newcommand\unvcolorbox[2]{% + \ifoptionblank{#1}{\vbox{\unvbox#2}}{% + \lb@debug{vcolorbox: #1}% + \vbox{\offinterlineskip + \hbox to \z@{\vbox to \z@{\optioncolor{#1}\hrule\@width\wd#2\@height\ht#2\@depth\dp#2\vss}\hss}% + \unvbox#2% + }% + }% +} + +% create a vbox with a given background color +\newcommand\vcolorbox[2]{% + \eifblank{#1}{\vbox{#2}}{% + \setbox\z@=\vbox{#2}\relax + \unvcolorbox{#1}{\z@}% + }% +}% + +% -------------------------------------------------------- +% The following macros come from mdframed +% -------------------------------------------------------- + +% Determine the amount of free space left on the current page +\newlength\lb@freevspace +\newcommand*\lb@setfreevspace@page{% + \lb@debug{ determine free space}% + \bgroup\@nobreakfalse\addpenalty\z@\egroup% + \penalty\@M\relax\vskip 2\baselineskip\relax% + \penalty9999\relax\vskip -2\baselineskip\relax% + \penalty9999% + \ifdim\pagegoal=\maxdimen\relax% + \lb@freevspace=\vsize% + \else + \lb@freevspace=\dimexpr\pagegoal-\pagetotal-\parskip\relax% + \fi + \lb@debug{free space: \the\lb@freevspace, in page: \the\textheight, vsize=\the\vsize}% +} + +\newcommand*\lb@shiftdim[2]{% + %\letoption{#1}\lb@list + \expandafter\lb@setheadtail@#1,\relax + \eifblank{\lb@head}{}{\option@invoke{/longbox/@breakat-previous}{\lb@head}}% + #2\option{/longbox/@breakat-previous}% + \eifblank{\lb@tail}{}{\let#1\lb@tail}% push back tail +} +\def\lb@comma{,}% +\def\lb@setheadtail@#1,#2\relax{% + \def\lb@head{#1}% + \def\lb@tail{#2}% adds commas! +} + +\newcommand*\lb@setfreevspace{% + \eifblank{\lb@breakat}{\lb@setfreevspace@page}{% + \def\lb@eject{\par}%no eject + \lb@extrasplit=\z@\relax% + \lb@shiftdim{\lb@breakat}\lb@freevspace + \ifdim\lb@freevspace>\z@\else\lb@setfreevspace@page\fi + }% +} + + +% Suppress overfull-underfull vbox messages +\newcommand*\lb@ignorevbadness{% + \edef\lb@currentvbadness{\the\vbadness}% + \edef\lb@currentvfuzz{\the\vfuzz}% + \vbadness=\@M\relax% + \vfuzz=\maxdimen\relax% + \afterassignment\lb@restorevbadness +} +\newcommand*\lb@restorevbadness{% + \vbadness=\lb@currentvbadness\relax + \vfuzz=\lb@currentvfuzz\relax +} + + +% -------------------------------------------------------- +% The 'long vbox' (lvbox) environment collects long material +% into a long \vbox, instead of a \hbox like a lrbox in latex. +% The collected box can contain any box, minipage, lrbox, fbox etc, +% but not outer-par material like a figure. Footnotes can be +% dealt with useing lb@savefootnotes. +% +% The material is typeset in a \vbox according to a given width. +% inside the environment, the boolean 'inlvbox' is true. +% +% \begin{lvbox}{}{} +% -------------------------------------------------------- + +\newif\ifinlvbox +\newcommand\lvbox[4]{% + \setbox#1\vbox\bgroup + \begingroup + \inlvboxtrue + % reset defaults + \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\par\@@par + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + % set margin and linewidth + \leftmargin=#2\relax\rightmargin=#4\relax + \@totalleftmargin=\leftmargin% + %\leftskip=#2\relax\rightskip=#4\relax\@rightskip=#4\relax + \linewidth=#3\relax + % set primitive tex margins + \leftskip=\@totalleftmargin% + \rightskip=\rightmargin% + \@rightskip=\rightmargin% + \hsize=\dimexpr\@totalleftmargin+\linewidth+\rightmargin\relax + \columnwidth\hsize + \textwidth\hsize + \nofirstindent + %\nofirstparskip +} +\def\endlvbox{\endgroup\egroup} + + + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + + +\newsavebox\lb@headbox +\newsavebox\lb@savebox +\newsavebox\lb@mainbox + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@setbaseline[1]{% + %\typeout{ set baseline, \the\dp#1,\the\ht#1}% + \ifcase\lb@baseline% + \relax%bottom + \or%middle + \setbox#1=\vbox{\hbox{\lower \dimexpr(\dp#1 + \ht#1)/2 - \dp#1\relax\vbox{\unvbox#1}}}% + \or%top + \setbox#1=\vtop{\unvbox#1}% + \fi + %\typeout{ .new dim: \the\dp#1, \the\ht#1}% +} + + +\@ifundefined{define@key}{}% + {\define@key{longbox}{options}{\options{#1}\option{/longbox/adjust-options}}}% + +\newcommand*\lb@render@breakbox{% + %\typeout{render breakbox entry (in output routine), height=\the\bb@height}% + \bb@restorekeys{longbox}% + \lb@skiptop=\ifbb@isfirst\option{/longbox/skip-top}\else\option{/longbox/skip-break-top}\fi\relax + \lb@skipbottom=\ifbb@islast\option{/longbox/skip-bottom}\else\option{/longbox/skip-break-bottom}\fi\relax + \lb@skipbreaktop=\ifbb@isfirst 0pt\else\option{/longbox/skip-break-top}\fi + \lb@skipbreakbottom=\ifbb@islast 0pt\else\option{/longbox/skip-break-bottom}\fi + %\typeout{ render: skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom, break-top=\the\dimexpr\option{/longbox/skip-bottom}}% + \options{% + /longbox/@part-height=\bb@height + \lb@skipbreaktop + \lb@skipbreakbottom, + /longbox/@part-width=\option{/longbox/width} + \option{/longbox/skip-left} + \option{/longbox/skip-right},%\bb@width, + /longbox/@part-depth=0pt, + /longbox/@part-needtop=\ifbb@isfirst true\else false\fi, + /longbox/@part-needbottom=\ifbb@islast true\else false\fi, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-depth=\option{/longbox/@part-depth}, + }% + %\typeout{breakbox: width=\expandafter\the\option{/longbox/width}, \the\bb@width, \the\dimexpr\option{/longbox/@part-width}}% + \vbox{% + \kern -\lb@skipbreaktop% todo: move to breakbox? + \option{/longbox/render}% + \kern -\lb@skipbreakbottom + }% +} + +\newcommand*\lb@render@vbox[1]{% + \lb@debug{render vbox entry}% + \lb@restoreoptions + \lb@skiptop=\dimexpr\iftoggle{/longbox/@part-needtop}{\option{/longbox/skip-top}}{\option{/longbox/skip-break-top}}\relax + \lb@skipbottom=\dimexpr\iftoggle{/longbox/@part-needbottom}{\option{/longbox/skip-bottom}}{\option{/longbox/skip-break-bottom}}\relax + %\typeout{ skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom}% + % add top skip while maintaining the baseline. + \ifdim\lb@skiptop=\z@\relax\else + \setbox\z@=\vtop{\unvcopy#1}% + \dimen@=\ht\z@ + \setbox#1=\vbox{\offinterlineskip + \hrule width \z@ height \dimexpr\dimen@ + \lb@skiptop\relax depth -\dimen@ + \unvbox#1% + }% + \fi + % add bottom skip while maintaining the baseline. + \ifdim\lb@skipbottom=\z@\relax\else + \dimen@=\dp#1% + \setbox#1=\vbox{\offinterlineskip\unvbox#1\hrule width \z@ height -\dimen@ depth \dimexpr\dimen@ + \lb@skipbottom\relax}% + \fi + \lb@setbaseline{#1}% + \options{% + /longbox/@part-height=\dimexpr\ht#1 + \dp#1\relax, + /longbox/@part-width=\dimexpr\wd#1 + \option{/longbox/skip-left} + \option{/longbox/skip-right}\relax, + /longbox/@part-depth=\dp#1, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-depth=\option{/longbox/@part-depth} - \lb@skipbottom, + }% + %\typeout{ longbox: height=\the\dimexpr\option{/longbox/@content-box-height}, outer height=\the\dimexpr\option{/longbox/@part-height}\relax}% + % lower the box depending on vertical alignment + \ifcase\option{/longbox/vertical-align/@ord}\relax + \@tempdima\z@ + \or + %bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%middle + \@tempdima\dimexpr0.5\option{/longbox/@part-height} - \option{/longbox/@part-depth}\relax + \or%top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%text-bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%text-top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%super + \@tempdima=-0.9ex% + \or%sub + \@tempdima=0.7ex% + \else + \@tempdima\z@ + \fi + \advance\@tempdima by -\option{/longbox/raise}% + \option@invoke{/longbox/@lower}{\@tempdima}% + \noindent\hbox{\lower \@tempdima\vbox{\offinterlineskip + \hbox to \z@{% + \vbox to \z@{% + \hbox{\lower \option{/longbox/@part-height}\vbox{\offinterlineskip{\option{/longbox/render}}}}% + \vss}% + \hss + }% + \hbox{% + \ifdim\option{/longbox/skip-left}=\z@\else\hskip\option{/longbox/skip-left}\fi + \box#1% + \ifdim\option{/longbox/skip-right}=\z@\else\hskip\option{/longbox/skip-right}\fi + %$\box#1% + }% + }}% +} + +\newcommand*\lb@single@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} +\newcommand*\lb@first@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@middle@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@last@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand*\lb@env@start{% + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore +} + +\newcount\lb@usevbox +\newlength\lb@width +\newlength\lb@height +\newlength\lb@skiptop +\newlength\lb@skipright +\newlength\lb@skipbottom +\newlength\lb@skipleft +\newlength\lb@skipbreaktop +\newlength\lb@skipbreakbottom +\newlength\lb@outerwidth +\newlength\lb@extrasplit +\newcount\lb@textalign +\newcount\lb@baseline +\newtoggle{lb@baselineskip}% +\newtoggle{lb@breakable}% +\newtoggle{lb@debug}% +\newtoggle{lb@verbose}% +\def\lb@breakat{}% +\def\lb@halign{}% +\def\lb@eject{}% +\def\lb@insertafter{} +\def\lb@insertbefore{} + +\newcommand*\lb@peekoptions[1]{% + % process options inside a group and just set necessary parameters + % this way, nested boxes don't influence each other's parameters + \begingroup + \options{#1}% + \option{/longbox/adjust-options}% + \protected@edef\lb@temp{\endgroup + \lb@width=\the\dimexpr\option{/longbox/width}\relax + \lb@height=\the\dimexpr\option{/longbox/height}\relax + \lb@textalign=\the\numexpr\option{/longbox/text-align/@ord}\relax + \lb@baseline=\the\numexpr\option{/longbox/baseline/@ord}\relax + \lb@skiptop=\the\dimexpr\option{/longbox/skip-top}\relax + \lb@skipright=\the\dimexpr\option{/longbox/skip-right}\relax + \lb@skipbottom=\the\dimexpr\option{/longbox/skip-bottom}\relax + \lb@skipleft=\the\dimexpr\option{/longbox/skip-left}\relax + \lb@skipbreaktop=\the\dimexpr\option{/longbox/skip-break-top}\relax + \lb@skipbreakbottom=\the\dimexpr\option{/longbox/skip-break-bottom}\relax + \lb@usevbox=\iftoggle{/longbox/use-vbox}{1}{0}\relax + \lb@outerwidth=\the\dimexpr\option{/longbox/outer-width}\relax + \lb@extrasplit=\the\dimexpr\option{/longbox/split-minimum}\relax + \def\noexpand\lb@insertafter{\option{/longbox/insert-after}}% + \def\noexpand\lb@insertbefore{\option{/longbox/insert-before}}% + \def\noexpand\lb@breakat{\option{/longbox/breakat}}% + \def\noexpand\lb@halign{\option{/longbox/height-align}}% + \def\noexpand\lb@eject{\option{/longbox/eject}}% + \noexpand\csname toggle\iftoggle{/longbox/baseline-skip}{true}{false}\endcsname{lb@baselineskip}% + \noexpand\csname toggle\iftoggle{/longbox/breakable}{true}{false}\endcsname{lb@breakable}% + \noexpand\csname toggle\iftoggle{/longbox/debug}{true}{false}\endcsname{lb@debug}% + \noexpand\csname toggle\iftoggle{/longbox/verbose}{true}{false}\endcsname{lb@verbose}% + }% + \lb@temp +} + +\newenvironment{longbox@env}[2]{% + % save options + \lb@peekoptions{#1,#2}% + % + \ifnum\lb@usevbox=0\relax + \lb@debug{start breakbox}% + \let\bb@render\lb@render@breakbox + \bb@savekeys{longbox}{options={#1,#2,outer-width=\the\lb@outerwidth}}% + \iftoggle{lb@baselineskip}{\typeout{**insert bskip}}{\typeout{**suppress bskip}\vskip 1pt}% + \begin{breakbox}% + \ifdim\lb@skiptop=\z@\relax\else\vspace{\lb@skiptop}\fi% + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \begin{bb@margins}{\lb@skipleft}{\dimen@}% + \else + \lb@debug{start vbox}% + \def\lb@restoreoptions{\options{#1,#2}\option{/longbox/adjust-options}}% + \lb@savefootnotes + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \lb@debug{ width=\the\lb@width, linewidth=\the\linewidth, skipleft=\the\lb@skipleft, right=\the\lb@skipright, total right=\the\dimen@}% + \iftoggle{lb@baselineskip}{\lb@skiptobaseline}{\lb@prevdepth=-\@m pt}% + \lvbox{\lb@mainbox}{0pt}{\lb@width}{0pt}%{\lb@skipleft}{\lb@width}{\lb@skipright}% + \prevdepth=\lb@prevdepth + \fi + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore + \begingroup +}{% + \par\unskip + \endgroup + \lb@insertafter + %\ifdim\lb@skipbottom=\z@\relax\else\vskip\lb@skipbottom\fi% + \ifnum\lb@usevbox=0\relax + \end{bb@margins}% + \ifdim\lb@skipbottom=\z@\relax\else\hrule width \z@ height \lb@skipbottom\fi%\vspace{\lb@skipbottom}\fi% + \iftoggle{lb@baselineskip}{}{\vskip 1sp}% + \end{breakbox}% + \lb@debug{end breakbox}% + \else + \ontoggle{lb@baselineskip}{\lb@skiptobaseline}% + \endlvbox% + \lb@debug{initial lvbox: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@processbox + %\setbox\lb@mainbox=\hbox{\lower \lb@skipbottom\vbox{\offinterlineskip\unvbox\lb@mainbox}}% + \lb@restorefootnotes + \lb@debug{end vbox}% + \fi +} + +\newcommand\longbox@cmd[3]{% + \begingroup + %\options{/options/collectunknown,/longbox/scoped,#2}% set scoped options first + %\option{/longbox/scoped/@adjust-options}% + \lb@peekoptions{#1,#2}% + \leavevmode + %\setbox\lb@mainbox=\hbox{% + % \begingroup + % #3% + % \endgroup + %}% + \setbox\lb@mainbox=\hbox{% + \begingroup + \ifcase\lb@textalign\relax + %default=left + \or%left + \or\hss%center + \or\hss%right + \else%justify + \fi + \lb@insertbefore + #3% + \lb@insertafter + \ifnum\lb@textalign<3\relax\hss\fi% default,left,center + \endgroup + }% + \options{#1,#2}% + \ifdim\option{/longbox/width}=-1sp\relax + \options{/longbox/width=\wd\lb@mainbox}%set to natural width + \fi + \option{/longbox/adjust-options}% + % make it a vbox + \setbox\lb@mainbox=\vbox{\offinterlineskip% + \hbox to \option{/longbox/width}{% + \unhbox\lb@mainbox + }% + }% + \def\lb@restoreoptions{}% + \letoption{/longbox/height-align}\lb@halign + \lb@height=\option{/longbox/height}\relax + \lb@baseline=\option{/longbox/baseline/@ord}\relax + \lb@processbox + \endgroup +} + +\newcommand\lb@processbox{% + \ifdim\lb@height<0pt\relax + \lb@setbaseline{\lb@mainbox}% + \else + \lb@restrictheight + \fi + \lb@typesetbox +} + +\newcommand\lb@typesetbox{% + \ifinlvbox + \iftoggle{lb@breakable}{% + %\lb@debug{disable breakable due to nesting of long-boxes}% + \togglefalse{lb@breakable}% + }{}% + \fi + \ifhmode\lb@single@{\lb@mainbox}\else\lb@typeset\fi +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@restrictheight{% + \lb@typeout{restrict height to \the\lb@height}% + \lb@splitheight=\lb@height% + %lb@debug{before height split: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + %split failed.. do nothing + \lb@debug{could not restrict height}% + \else + % store splitted off content in the mainbox (and discard the rest) + \setbox\lb@mainbox\vbox{\unvbox\lb@headbox}% + \lb@debug{restricted height to \the\ht\lb@mainbox}% + \fi + % set baseline + \lb@setbaseline{\lb@mainbox}% + % height align + %\letoption{/longbox/height-align}\lb@halign + \eifstrequal{\lb@halign}{bottom}% + {\setbox\lb@mainbox=\vbox{\hbox{\vbox to \lb@splitheight{\vss\unvbox\lb@mainbox}}}}% + {\eifstrequal{\lb@halign}{middle}% + {\dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\hbox{% + \lower \dimexpr0.5\dimen@ + \dp\lb@mainbox\relax% + \vbox to \lb@splitheight{\vss\unvbox\lb@mainbox\vss}}}}% + {% default is top + \dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\vtop to \lb@splitheight{\box\lb@mainbox\vss}}% + }% + }% +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newlength\lb@neededvspace +\newcommand\lb@typeset[1][0pt]{% + \iftoggle{lb@breakable}{% + \lb@setfreevspace + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skiptop+\lb@skipbottom\relax}% + \lb@debug{needed: \the\lb@neededvspace, available: \the\lb@freevspace}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@single@{\lb@mainbox}% + \else + \lb@typeout{longbox needs splitting}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skiptop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \ifdim\dimexpr\lb@freevspace + #1\relax<\textheight\relax % test if we were at a fresh page.. (and prevent infinite recursion) + \lb@debug{failed to split the box, inserting a page break}% + \hrule \@height\z@ \@width\hsize + \lb@eject% + \lb@typeset[\textheight]% try again, but pass \textheight to guard against infinite recursion + \else + % on a fresh page we should not fail anymore.. just output as is.. + % lb@warncannotsplit + \lb@single@{\lb@mainbox}% + \fi + \else + % first part success + \lb@typeout{first part splitted}% + \lb@first@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest + \fi + \fi + }{%\else + \lb@debug{unbreakable box}% + \lb@single@{\lb@mainbox}% always directly output an unbreakable box + }% +} + +\newcommand\lb@typesetrest{% + \lb@setfreevspace% + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skipbottom+\lb@skipbreaktop\relax}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@typeout{output last part of box}% + \lb@last@{\lb@mainbox}% + \else + \lb@debug{split box further}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skipbreaktop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \lb@typeout{failed to split box!}% + \lb@last@{\lb@mainbox}% + \else + % middle part success + \lb@typeout{output middle part of box}% + \lb@middle@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest% continue the iteration... + \fi + \fi +} + +% -------------------------------------------------------- +% Split a long vbox over multiple pages. +% This code is based on similar code in the mdframed package +% -------------------------------------------------------- + +\newlength\lb@splitheight +\newlength\lb@insurance % tiny extra space to ensure our box will really fit +\setlength\lb@insurance{1pt} + +% expects split target height in lb@splitheight, and splits off the start of lb@mainbox to lb@headbox +\newcommand\lb@splitbox{% + \ifdim\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax>\lb@splitheight\relax + % the main box is larger than our target split height.. + \ifdim\lb@extrasplit>\lb@splitheight\relax + % not enough space to bother + \lb@typeout{not enough space on page for a split}% + \setbox\lb@headbox=\vbox{}% empty head + \else + % try a split; lower the split height a bit so we are sure to fit + \advance\lb@splitheight -\lb@insurance\relax + \lb@debug{split: \the\lb@splitheight, from \the\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax}% + \setbox\lb@savebox=\vbox{\unvcopy\lb@mainbox}% save original + \lb@trysplit{\lb@splitheight}% + \ifdim\dimexpr\ht\lb@headbox + \dp\lb@headbox>\lb@splitheight\relax + % too big, bad split. Try other splits.. iterate N times with 1 or 5pt less before giving up + \dimen@=\lb@splitheight\relax + \@tempcnta=\z@\relax + \loop + \ifdim\dimexpr\ht\lb@headbox+\dp\lb@headbox\relax>\lb@splitheight\relax + \ifnum\@tempcnta<50% + \advance\dimen@ by -\p@\relax% try a slightly smaller height.. + \else + \advance\dimen@ by -5\p@\relax% try larger increase after 50pt.. + \fi + \advance\@tempcnta by \@ne\relax + \lb@ignorevbadness + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \lb@trysplit{\dimen@}% + \ifdim\lb@extrasplit<\dimen@\relax\else\lb@splitstop\fi % don't try to split too small + \ifnum\@tempcnta<100\relax\else\lb@splitstop\fi % and not more than N attempts + \repeat% + \ifnum\@tempcnta<100\relax + \dimen@=\dimexpr\lb@splitheight - \ht\lb@headbox - \dp\lb@headbox\relax + \ifdim\dimen@>\option{/longbox/split-badness}\relax + \lb@warnbadsplit{\dimen@}% + \fi + \fi + \fi + \fi + \else + % mainbox fits in our target lb@splitheight + \setbox\lb@headbox=\vbox{\unvbox\lb@mainbox}% + \setbox\lb@mainbox=\vbox{}% + \fi +} + +\newcommand\lb@splitstop{% + \lb@typeout{cannot find a good split}% + \let\iterate\relax + \lb@warncannotsplit + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \setbox\lb@headbox=\vbox{}% empty head + \@tempcnta=\@M\relax +} + +\newcommand\lb@trysplit[1]{% try to split at given height + \lb@typeout{try to split at: \the\dimexpr #1\relax}% + \lb@ignorevbadness + \setbox\lb@headbox=\vsplit\lb@mainbox to #1\relax% + \setbox\lb@headbox=\vbox{\unvbox\lb@headbox}% + \setbox\lb@mainbox=\vbox{\unvbox\lb@mainbox}% +} + +% -------------------------------------------------------- +% The longbox environment uses options to set its options +% -------------------------------------------------------- + + +% keys and styles that can be set once globally +\options{% + /longbox/.new family, +}% + +\options{/longbox,% + % computed + @part-needtop/.new toggle, + @part-needbottom/.new toggle, + @part-height/.new length, + @part-width/.new length, + @part-depth/.new length, + @content-box-height/.new length, + @content-box-width/.new length, + @content-box-depth/.new length, + @breakat-previous/.new length, + @lower/.new length, + % + debug/.new toggle, + verbose/.new toggle, + render/.new value =\lb@render@fbox, + adjust-options/.new value = {\longbox@adjustoptions}, + eject/.new value = {\protect\vfill\protect\eject}, + use-vbox/.new toggle = true, + split-minimum/.new length = {1.5\baselineskip}, + split-badness/.new length = \baselineskip, + % + height-align/.new choice= {top,middle,bottom}, + baseline/.new choice = {bottom,middle,top}, + text-align/.new choice = {default,left,center,right,justify}, + vertical-align/.new choice = {baseline,bottom,middle,top,text-bottom,text-top,super,sub}, + raise/.new length = {0pt}, + baseline-skip/.new toggle =true, + % + height/.new length = -1sp, + width/.new length = -1sp, + outer-height/.new length= -1sp, + outer-width/.new length = -1sp, + insert-before/.new value= {}, + insert-after/.new value = {}, + breakat/.new value = {}, + breakable/.new toggle = false, + skip/.new style = {skip-top=#1,skip-right=#1,skip-bottom=#1,skip-left=#1}, + skip-top/.new length, + skip-right/.new length, + skip-bottom/.new length, + skip-left/.new length, + skip-break-bottom/.new length, + skip-break-top/.new length, +} + +\newcommand\longbox@adjustoptions{% + %\typeout{ standard longbox adjustoptions}% + \lb@debug{ current width=\the\dimexpr\option{/longbox/width}, outer=\the\dimexpr\option{/longbox/outer-width}, linewidth=\the\linewidth}% + \ontoggle{/longbox/debug}{\option@invoke{/longbox/verbose}{true}}% + % adjust height + \ifdim\option{/longbox/height}=-1sp\relax + \ifdim\option{/longbox/outer-height}=-1sp\else + \option@invoke{/longbox/height}% + {\option{/longbox/outer-height}-\option{/longbox/skip-top}-\option{/longbox/skip-bottom}}% + \fi + \fi + % set width + \ifdim\option{/longbox/width}=-1sp\relax + \ifdim\option{/longbox/outer-width}=-1sp\relax + \option@invoke{/longbox/outer-width}{\linewidth}% + \fi + \dimen@=\dimexpr\option{/longbox/outer-width}-\option{/longbox/skip-left}-\option{/longbox/skip-right}\relax + \ifdim\dimen@<\z@\relax\dimen@=\z@\fi + \option@invoke{/longbox/width}{\dimen@}% + \fi + % use a breakbox whenever we are in external vertical mode and not width or height restricted. + \iftoggle{/longbox/use-vbox}{}{% + \ifinner\toggletrue{/longbox/use-vbox}\else + \ifhmode\toggletrue{/longbox/use-vbox}\else + \ifdim\option{/longbox/height}>-1sp\toggletrue{/longbox/use-vbox}\else + \iftoggle{/longbox/breakable}{}{\toggletrue{/longbox/use-vbox}}% + \ifoptionblank{/longbox/breakat}{}{\toggletrue{/longbox/use-vbox}}% + \fi\fi\fi + }% +} + +\newenvironment{longbox}[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \begin{longbox@env}{/longbox}{#1}% +}{\end{longbox@env}} + +\newcommand\lbox[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \longbox@cmd{/longbox}{#1}% +} + +\newcommand*\lb@render@fbox{% + %\typeout{render defaultbox: bgcolor=\bb@bgcolor, needtop=\iftoggle{/longbox/@part-needtop}{true}{false}}% + \@ovdx=\dimexpr\option{/longbox/@part-width} - 2\fboxrule\relax% + \@ovdy=\dimexpr\option{/longbox/@part-height}\relax% + \iftoggle{/longbox/@part-needbottom}% + {\@tempdima=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdima=\dimexpr\fboxrule + \bb@stickout\relax + \advance\bb@height by \@tempdima + \advance\@ovdy by \@tempdima}% + \iftoggle{/longbox/@part-needtop}% + {\@tempdimb=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdimb=\dimexpr\bb@stickout\relax + \advance\bb@height by \@tempdimb + \advance\@ovdy by \@tempdimb}% + % + \hbox{\lower \@tempdima\vbox{% + \vskip -\@tempdimb + \ontoggle{/longbox/@part-needtop}{\lb@debug{toprule wd=\expandafter\the\option{/longbox/width}}\hrule width \option{/longbox/@part-width} height \fboxrule}% + \hbox{% + \vrule width \fboxrule height \@ovdy% + \ifx\bb@bgcolor\@empty + \vrule width \@ovdx height \z@\relax + \else + {\color{\bb@bgcolor}\vrule width \@ovdx height \@ovdy}% + \fi + \vrule width \fboxrule height \@ovdy% + }% + \ontoggle{/longbox/@part-needbottom}{\hrule width \option{/longbox/@part-width} height \fboxrule}% + }}% +} \ No newline at end of file diff --git a/spec/v1.4.0-rc.4/longfbox.sty b/spec/v1.4.0-rc.4/longfbox.sty new file mode 100644 index 00000000..0df01331 --- /dev/null +++ b/spec/v1.4.0-rc.4/longfbox.sty @@ -0,0 +1,1344 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longfbox}[2015/12/01, Daan Leijen, Provides long fbox that can break over pages] + +\RequirePackage{options} +\RequirePackage{longbox} +\RequirePackage{pict2e} +\RequirePackage{ellipse} + +% -------------------------------------------------------- +% Dimension calulations +% -------------------------------------------------------- + +% dimmin/dimmax return minimum or maximum dimension +\providecommand\dim@min[2]{\ifdim#1>#2#2\else #1\fi} +\providecommand\dim@max[2]{\ifdim#1>#2#1\else #2\fi} + +\newcommand*\option@dimmin[2]{\dim@min{\option{#1}}{\option{#2}}} +\newcommand*\option@dimmax[2]{\dim@max{\option{#1}}{\option{#2}}} + + +% -------------------------------------------------------- +% Add a new 'sides' option type +% -------------------------------------------------------- + +\options{ + /handlers/new sides/.new handler = []{ + \ifblank{#2}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#1-top={##1}, #1-right={##2}, #1-bottom={##3}, #1-left={##4}}}}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#2}}}% + \optionsalso{ + #1/.new cmdx = {##1,##2,##3,##4,##5\relax}{,,,,\relax}{% + \ifblank{##2##3##4}{\option{#1/@cmd@sides}{##1}{##1}{##1}{##1}}% + {\ifblank{##3##4}{\option{#1/@cmd@sides}{##1}{##2}{##1}{##2}}% + {\ifblank{##4}{\option{#1/@cmd@sides}{##1}{##2}{##3}{##2}}% + {\option{#1/@cmd@sides}{##1}{##2}{##3}{##4}}% + }% + }% + }, + #1/.type = sides, + }% + },% +} + +\newcommand*\optionlengthlimit[3]{% len, min, max + \letoption{#1}\opt@temp + \ifdim\opt@temp<\dimexpr#2\relax + \option@invoke{#1}{#2}% + \else\ifdim\opt@temp>\dimexpr#3\relax + \option@invoke{#1}{#3}% + \fi\fi +} + +\newcommand*\optionradiuslimit[4]{% r1, r2, min, max + \letoption{#1}\opt@tempa + \letoption{#2}\opt@tempb + \ifdim\opt@tempa<\dimexpr#3\relax\option@invoke{#1}{#3}\fi + \ifdim\opt@tempb<\dimexpr#3\relax\option@invoke{#2}{#3}\fi + \ifdim\dimexpr\opt@tempa + \opt@tempb\relax=\z@\relax\else + \ifdim\dimexpr\opt@tempa+\opt@tempb\relax>\dimexpr#4\relax + \edef\opt@perc{\the\numexpr(\number\dimexpr#4\relax)/% + (\number\dimexpr(\opt@tempa+\opt@tempb)/100\relax)}% + %\typeout{scale:\the\opt@tempa,\the\opt@tempb, by \opt@perc percent to make \the\dimexpr#4\relax}% + \edef\opt@temp{\dimexpr\opt@perc\dimexpr\the\opt@tempa\relax / 100\relax}% + \option@einvoke{#1}{\opt@temp}% + \option@einvoke{#2}{\dimexpr#4 - \opt@temp\relax}% + %\typeout{ scaled to: \the\opt@temp,\the\dimexpr#4 - \opt@temp\relax}% + \fi + \fi +} + + +% \begin{macro}{\trig@atantan} +% \marg{a}\marg{b}\marg{$\alpha$}{dimen$_\mathit{reg}$}\\ +% Assigns $\atan_2(\frac{\sin(\alpha)}{b},\frac{\cos(\alpha)}{a})$ to dimension register \textit{dimen$_\mathit{reg}$}, +% where $a$ and $b$ are dimensions. +% Returns $\alpha$ when $a = b$, or when $a=0$ or $b=0$. +% \begin{macrocode} +\newcommand*\trig@atantan[4]{% + %\typeout{ atantan:(\the#1,\the#2,\the#3, #4)}% + \@tempdima\dimexpr#1\relax + \@tempdimb\dimexpr#2\relax +% \end{macrocode} +% If $a = b$, we have a circle and the result is $\alpha$. +% \begin{macrocode} + \ifdim\@tempdima=\@tempdimb + #4\dimexpr#3\relax + \else\ifdim\@tempdima=\z@ + #4\dimexpr#3\relax + \else\ifdim\@tempdimb=\z@ + #4\dimexpr#3\relax + \else + \edef\trig@temp{\strip@pt\dimexpr#3\relax}% + \CalculateSin{\trig@temp}\CalculateCos{\trig@temp}% + \@tempdimc\dimexpr1\p@ * \dimexpr\UseSin{\trig@temp}\p@\relax/\@tempdimb\relax + \@tempdimd\dimexpr1\p@ * \dimexpr\UseCos{\trig@temp}\p@\relax/\@tempdima\relax + \pIIe@atantwo{\@tempdimc}{\@tempdimd}\dimen@ + \ifdim\dimen@<\z@ + \ifdim\dimexpr#3\relax<\z@\else\advance\dimen@360\p@\fi + \fi + \@tempdima\dimexpr#3 - \dimen@\relax + \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi + \ifdim\@tempdima<360\p@\else\advance\dimen@360\p@\fi + %\typeout{atan: \the\dimexpr#3\relax versus. \the\dimen@ }% + #4\dimen@ + \fi\fi\fi +} +% \end{macrocode} +% \end{macro} + +% rough approximation of the perimeter; +% if |radius-x == radius-y| = 0 (a circle), the approximation is precise. +% otherwise, works best when |angle2-angle1| <= 45 and gets worse from there on. +\newcommand*\ellip@letarcperimeter[5]{% 'radius-x', 'radius-y', 'angle-1', 'angle-2', '\result' + \@tempdima\dimexpr#3\relax + \@tempdimb\dimexpr#4\relax + \@tempdimc\dimexpr\@tempdima - \@tempdimb\relax + \ifdim\@tempdimc<\z@\@tempdimc-\@tempdimc\fi + \ifdim#1=#2\relax% circle? + \edef\@tempa{\strip@pt\@tempdimc}% angle difference delta as factor + \dimen@\@tempa\dimexpr#1\relax% r*delta + \dimen@0.017453\dimen@% (2*pi/360) * r * delta = 2*pi*r * (delta/360) + \else% ellipse: take the distance between the points on the ellipse, works pretty good if delta <= 45, and ok'ish for delta <= 90 + \@ovro\dimexpr#1\relax + \@ovri\dimexpr#2\relax + \edef\fbox@tempa{\strip@pt\@tempdima}% + \edef\fbox@tempb{\strip@pt\@tempdimb}% + \pIIe@ellip@sincost{\fbox@tempa}{\fbox@tempb}% + \@tempdima\@ellipcosone\@ovro + \@tempdimb\@ellipsinone\@ovri + \@tempdimc\@ellipcostwo\@ovro + \@tempdimd\@ellipsintwo\@ovri + \advance\@tempdimc by -\@tempdima% + \advance\@tempdimd by -\@tempdimb% + \pIIe@ellip@csqrt{\@tempdimc}{\@tempdimd}{\dimen@}% + %\typeout{ distance: \the\dimen@, from (x,y)=(\the\@tempdimc,\the\@tempdimd), radii=(\the#1,\the#2), angles=(\the#3,\the#4)}% + \fi + \edef#5{\the\dimen@}% +} + + +% ------------------------------------------------------------------------------ +% Borders using the picture environment +% ------------------------------------------------------------------------------ + +\newcommand*\fbox@border@pict{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \begingroup + \hbox{% + \unitlength\p@ + \begin{picture}(0,0)(0,\optionunit{/fbox/@border-box-height})% bottom-left is origin + % markers + \ontoggle{/fbox/show-markers}{% + \linethickness{\option{/fbox/marker-width}}% + \optioncolor{/fbox/marker-color}% + \fbox@rect{0pt}{0pt}{\option{/fbox/@border-box-width}}{\option{/fbox/@border-box-height}}% + \fbox@rect{\option{/fbox/border-left-width}}{\option{/fbox/border-\fbox@bottom-width}}% + {\option{/fbox/@border-box-width}-\option{/fbox/border-right-width}}% + {\option{/fbox/@border-box-height}-\option{/fbox/border-\fbox@top-width}}%S + }% + %compute corner coordinates + \fbox@border@calccorners + %put down the background color + \fbox@border@colorbackground + \option{/fbox/picture-insert-before}% + %put down the sides + \fbox@border@side{3}{-2}{0}%top + \fbox@border@side{5}{-4}{3}%left + \fbox@border@side{-6}{7}{2}%bottom + \fbox@border@side{-8}{1}{1}%right + \end{picture}% + }% + \endgroup + \fi +} + +\newcommand*\fbox@border@pict@after{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \letoption{/fbox/picture-insert-after}\fbox@insertafter + \eifblank{\fbox@insertafter}{}{% + \begingroup + \hbox{% + \begin{picture}(0,0)(0,0)% bottom-left is origin + \fbox@insertafter + \end{picture}% + }% + \endgroup + }% + \fi +} + +\newcommand*\fbox@border@side[3]{% + \fbox@setoct@angles{#1}% + \edef\fbox@style{\option{/fbox/border-\fbox@side-style}}% + \optioncolor{/fbox/border-\fbox@side-color}% + \option{/fbox/picture-side-insert-before}% + \ifcsdef{fbox@border@pict@\fbox@style}% + {\csuse{fbox@border@pict@\fbox@style}{#1}{#2}{#3}}% + {\PackageWarning{longfbox}{Unknown style "\fbox@style". Using "solid" instead.}% + \fbox@border@pict@solid{#1}{#2}{#3}}% + \option{/fbox/picture-side-insert-after}% +} + +% ------------------------------------------------------------------------------ +% Define standard border styles for the picture environment +% +% a style has the form \fbox@border@pict@ + + + + + + +
+
+
+
P4Runtime Specification
+
version 1.4.0-dev
+
+
+
The P4.org API Working Group
+
2022-03-23
+
+

Abstract. P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.

+ + +

1. Introduction and Scope

+

This document is published by the P4.org API Working Group, which was +chartered [17] to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called P4Runtime. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +https://github.com/p4lang/p4runtime/tree/main/proto. +

1.1. P4 Language Version Applicability

+

P4Runtime is designed to be implemented in conjunction with the P416 language +version or later. P414 programs should be translated into P416 to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P416 1.0, but were introduced in P416 1.1.0 [29]. For +this version of P4Runtime, we recommend using P416 1.2.1 [1]. +

1.2. In Scope

+

This specification document defines the semantics of P4Runtime messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime: +

+
    +
  • Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA) [19] externs (e.g. Counters, Meters, Action +Profiles, ). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0. +
  • +
  • Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism. +
  • +
  • Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy. +
  • +
  • Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities. +
  • +
  • Packet I/O to enable streaming packets to & from the control plane. +
  • +
  • Batching support, with different atomicity guarantees. +
  • +
  • In-the-field device-reconfiguration with a new P4 data plane. +
+ +

The following are in the scope of this specification document: +

+
    +
  • Rationale for the P4Runtime design. +
  • +
  • Reference architecture and use-cases for deploying a P4Runtime service. +
  • +
  • Detailed description of the API semantics. +
  • +
  • Requirements for conformant implementations of the API. +
+

1.3. Not In Scope

+

The following are not in scope of P4Runtime: +

+
    +
  • Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +[35]. An open source implementation of these APIs is also in progress +as part of the Stratum project [37]. +
  • +
  • Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures. +
+ +

The following are not in scope of this specification document: +

+
    +
  • Description of the P4 programming language; it is assumed that the reader is +already familiar with P416 [1]. +
  • +
  • Descriptions of gRPC and Protobuf files in general. +
  • +
  • Controller role definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme. +
+

2. Terms and Definitions

+
+
arbitration
+
Refers to the process through which P4Runtime ensures that at any given +time, there is a single primary controller (i.e. a client with write access) +for a given role. Also referred to as “client arbitration”. +
+
client
+
The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +
+
COS
+
Class of Service. +
+
device
+
Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +
+
entity
+
An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +
+
gRPC
+
gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +[9]. +
+
HA
+
High-Availability. Refers to a redundancy architecture. +
+
Instrumentation
+
The part of the P4Runtime server which implements the calls to the device or +target native “SDK” or backend. +
+
IPC
+
Inter-Process Communication. +
+
P4 Blob
+
A more colloquial term for P4 Device Config (Blob = Binary Large Object). +
+
P4 Device Config
+
The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its “program.” +
+
P4Info
+
Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +
+
P4RT
+
Abbreviation for P4Runtime. +
+
Protobuf (Protocol Buffers)
+
The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See [21]. +
+
PSA
+
Portable Switch Architecture [19]; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +
+
RPC
+
Remote Procedure Call. +
+
RTT
+
Round-trip time. +
+
SDN
+
Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network controller. +
+
SDN port
+
A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +
+
server
+
The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +
+
stream
+
Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (StreamChannel), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and client arbitration, among other things. +
+
switch config
+
Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +
+
target
+
The hardware or software entity which “executes” the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with “device”. +
+
URI
+
Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.

3. Reference Architecture

+

Figure 1 represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. P4Runtime only grants write access to a +single primary controller for each read/write entity. A role defines a grouping +of P4 entities. P4Runtime allows for a primary controller for each role, and a +role-based client arbitration scheme ensures only one controller has +write access to each read/write entity, or the pipeline config itself. Any +controller may perform read access to any entity or the pipeline config. Later +sections describe this in detail. For the sake of brevity, the term controller +may refer to one or more controllers. +

+

The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +[15]. It may be compiled via protoc the Protobuf compiler +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server. +

+

Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository [16]. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, e.g. via callbacks, thus reducing the burden of implementing +P4Runtime. +

+

The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard. +

+

The controller can also set the ForwardingPipelineConfig, which amounts to +installing and running the compiled P4 program output, which is included in the +p4_device_config Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +ForwardingPipelineConfig to retrieve the device config and the P4Info. +

+
+

reference-architecture +

+
+ +
Figure 1. P4Runtime Reference Architecture.

3.1. P4Runtime Service Implementation

+

The P4Runtime API is implemented by a program that runs a gRPC server which +binds an implementation of auto-generated P4Runtime Service interface. This +program is called the “P4Runtime server.” The server must listen on TCP port +9559 by default, which is the port that has been allocated by IANA for the +P4Runtime service. Servers should allow users to override the default port +using a configuration file or flag when starting the server. Uses of other +port numbers as the default should be discontinued. +

3.1.1. Security concerns

+

Appropriate measures and security best practices must be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. Mutual TLS (mTLS) may +be used to facilitate the authentication of the client by the server and +vice-versa. +

3.2. Idealized Workflow

+

In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the ForwardingPipelineConfig +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a SetForwardingPipelineConfig +RPC. Metadata in the P4Info describes both the overall program itself +(PkgInfo) as well as all entity instances derived from the P4 program +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise “handle” used in API +calls. +

+

In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible. +

+

In some use cases, it is expected that a controller will store a +collection of multiple P4 “packages”, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the ForwardingPipelineConfig from the target via the +GetForwardingPipelineRequest RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state. +

3.3. P4 as a Behavioral Description Language

+

P4 can be considered a behavioral description of a switching device which may or +may not execute “P4” natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a SetForwardingPipelineRequest to +change its pipeline “program”, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device. +

+

While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API. +

+

In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the PkgInfo +message as well as the embedded doc fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections. +

3.4. Alternative Workflows

+

Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary. +

3.4.1. P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config

+

In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +p4_device_config. The device's configuration might be derived via some other +means to implement the P4 source code's intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane. +

3.4.2. No P4 Source Available, P4Info Available

+

In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are: +

+
    +
  1. +

    The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security. +

  2. +
  3. +

    The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info. +

+ +

As discussed in Section 3.3, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, e.g. documentation. +

3.4.3. Partial P4Info and P4 Source are Available

+

In this situation, a subset of the target's pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code. +

3.4.4. P4Info Role-Based Subsets

+

In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more. +

3.5. P4Runtime State Across Restarts

+

All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade. +

4. Controller Use-cases

+

P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +section. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime's flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex. +

4.1. Single Embedded Controller

+

Figure 2 shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases. +

+

P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC. +

+
+

single-embedded-controller +

+
+ +
Figure 2. Use-Case: Single Embedded Controller

4.2. Single Remote Controller

+

Figure 3 shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections. +

+
+

single-remote-controller +

+
+ +
Figure 3. Use-Case: Single Remote Controller

4.3. Embedded + Single Remote Controller

+

Figure 4 illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller. +

+

For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables. +

+
+

embedded-plus-single-remote-controller +

+
+ +
Figure 4. Use-Case: Embedded Plus Single Remote Controller

4.4. Embedded + Two Remote Controllers

+

Figure 5 illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +e.g. routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership. +

+
+

embedded-plus-two-remote-controllers +

+
+ +
Figure 5. Use-Case: Embedded Plus Two Remote Controllers

4.5. Embedded Controller + Two High-Availability Remote Controllers

+

Figure 6 illustrates a single +embedded controller plus two remote controllers in an active-standby (i.e. +primary-backup) HA (High-Availability) configuration. Controller #1 is the +active controller and is in charge of some entities. If it fails, Controller #2 +takes over and manages the tables formerly owned by Controller #1. The mechanics +of HA architectures are beyond the scope of this document, but the P4Runtime +role-based client arbitration scheme supports it. +

+
+

embedded-plus-two-remote-ha-controllers +

+
+ +
Figure 6. Use-Case: Embedded Plus Two Remote High-Availability Controllers

5. Client Arbitration and Controller Replication

+

The P4Runtime interface allows multiple clients (i.e. controllers) to be +connected to the P4Runtime server running on the device at the same time for the +following reasons: +

+
    +
  1. +

    Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, “roles” (or “realms”) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +primary and the rest are backups. Role definition, i.e. how P4 entities get +assigned to each role, is out-of-scope of this document. +

  2. +
  3. +

    Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby backup controllers. These can already have a connection +open, which can help them become primary more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved. +

+ +

To support multiple controllers, P4Runtime uses the streaming channel (available +via StreamChannel RPC) for session management. The workflow is described as +follows: +

+
    +
  • +

    Each controller instance (e.g. a controller process) can participate in one or +more roles. For each (device_id, role), the controller receives an +election_id. This election_id can be the same for different roles and/or +devices, as long as the tuple (device_id, role, election_id) is +unique. For each (device_id, role) that the controller wishes to +control, it establishes a StreamChannel with the P4Runtime server +responsible for that device, and sends a MasterArbitrationUpdate message +containing that tuple of (device_id, role, election_id) values. The +P4Runtime server selects a primary independently for each (device_id, +role) pair. The primary is the client that has the highest election_id +that the device has ever received for the same (device_id, +role) values. A connection between a controller instance and a device id + which involves a persistent StreamChannel can be referred to as a +P4Runtime client. +

    +

    Note that the P4Runtime server does not assign a role or election_id to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the election_id values used for each +StreamChannel. The P4Runtime server only keeps track of the (device_id, +role, election_id) of each StreamChannel that has sent a successful +MasterArbitrationUpdate message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +WriteRequest message to identify which client is making the WriteRequest, +not only the election_id. This enables controllers to re-use the same +numeric election_id values across different (device_id, role) +pairs. P4Runtime does not require election_id values be reused across such +different (device_id, role) pairs; it allows it. +

  • +
  • +

    To start a controller session, a controller first opens a bidirectional stream +channel to the server via the StreamChannel RPC for each device. This stream +will be used for two purposes: +

    +
      +
    • +

      Session management: As soon as the controller opens the stream +channel, it sends a StreamMessageRequest message to the switch. The +controller populates the MasterArbitrationUpdate field in this message +using its role and election_id, as well as the device_id of the +device. Note that the status field in the MasterArbitrationUpdate is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below. +

    • +
    • +

      Streaming of notifications (e.g. digests) and packet I/O: The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the primary controller can participate in +packet I/O. This feature is explained in more details in the Packet +I/O section. +

    + +

    Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state. +

  • +
  • +

    Note that the stream is opened per device. In case a switching platform has +multiple devices (e.g. multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different primary clients for +different devices. In this case, it is the responsibility of the P4Runtime +server to keep track of the primary for each device (and role). More +specifically, the P4Runtime server will know which stream corresponds to the +primary controller for each pair of (device_id, role) at any point of +time. +

  • +
  • +

    The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered “offline” or +“dead” as soon as its stream channel to the switch is broken. When a primary +channel gets broken: (i) an advisory message is sent to all other controllers +for that device_id and role, as described in the +following section (ii) the P4Runtime server +will be without a primary controller, until a client sends a successful +MasterArbitrationUpdate (as per the rules in a +later section). +

  • +
  • +

    The mechanism via which the controller receives the P4Runtime server details +which includes the device_id, ip and port, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +device_id) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks. +

+ +

gRPC enables the server to identify which client originated each message in the +StreamChannel stream. For example, the C++ gRPC library [10] in +synchronous mode enables a server process to cause a function to be called when +a new client creates a StreamChannel stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +StreamChannel is closed normally (or broken, e.g. because a client process +unexpectedly terminated). Thus the server can easily associate all +StreamChannel messages received from the same client, because they are +processed within the context of the same function call. +

+

A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values device_id, role, and election_id in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods [8] that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server. +

5.1. Default Role

+

A controller can omit the role message in MasterArbitrationUpdate. This +implies the “default role”, which corresponds to “full pipeline access”. +This also implies that a default role has a role_id of "" (default). +If using a default role, all RPCs from the controller (e.g. Write) must +leave the role unset. +

5.2. Role Config

+

The role.config field in the MasterArbitrationUpdate message sent by the +controller describes the role configuration, i.e. which operations are in the +scope of a given role. In particular, the definition of a role may include the +following: +

+
    +
  • A list of P4 entities for which the controller may issue Write updates and +receive notification messages (e.g. DigestList and +IdleTimeoutNotification). +
  • +
  • Whether the controller is able to receive PacketIn messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketIn messages should be sent to the controller. +
  • +
  • Whether the controller is able to send PacketOut messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketOut messages are allowed to be sent by the controller. +
+ +

An unset role.config implies “full pipeline access” (similar to the default +role explained above). In order to support different role definition schemes, +role.config is defined as an Any Protobuf message [31]. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion. +

+

It is the job of the P4Runtime server to remember the role.config for every +device_id and role pair. +

5.3. Rules for Handling MasterArbitrationUpdate Messages Received from Controllers

+
    +
  1. +

    If the MasterArbitrationUpdate message is received for the first time on +this particular channel (i.e. for a newly connected controller): +

    +
      +
    1. +

      If device_id does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +NOT_FOUND error. +

    2. +
    3. +

      If the election_id is set and is already used by another controller for +the same (device_id, role), the P4Runtime server shall terminate +the stream by returning an INVALID_ARGUMENT error. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the number of open streams for the given (device_id, role) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a RESOURCE_EXHAUSTED error. +

    8. +
    9. +

      Otherwise, the controller is added to a list of connected controllers for +the given (device_id, role) and the server remembers the +controllers device_id, role and election_id for this gRPC +channel. See below for the rules to determine if this controller becomes +a primary or backup, and what notifications are sent as a consequence. +

    +
  2. +
  3. +

    Otherwise, if the MasterArbitrationUpdate message is received from an +already connected controller: +

    +
      +
    1. +

      If the device_id does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. +

    2. +
    3. +

      If the role does not match the current role assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. If the controller wishes to change its role, +it must close the current stream channel and open a new one. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the election_id is set and is already used by another controller +(excluding the controller making the request) for the same +(device_id, role), the P4Runtime server shall terminate the stream +by returning an INVALID_ARGUMENT error. +

    8. +
    9. +

      Otherwise, the server updates the election_id it has stored for this +controller. This change might cause a change in the primary client (this +controller might become primary, or the controller might have downgraded +itself to a backup, see below), as well as notifications being sent to +one or more controllers. +

    +
+ +

If the MasterArbitrationUpdate is accepted by either of the two steps above +(cases 1.5. and 2.5. above), then the server determines if there are changes in +the primary client. Let election_id_past be the highest election ID the server +has ever seen for the given device_id and role (including the one of the +current primary if there is one). +

+
    +
  1. +

    If election_id is greater than or equal to election_id_past, then the +controller becomes, or stays, primary. The server updates the role +configuration to role.config for the given role. Furthermore: +

    +
      +
    1. +

      If there was no primary for this device_id and role before and +there are no Write requests still processing from a previous primary, +then the server immediately sends an advisory notification to all +controllers for this device_id and role. See the +following section for the format of the +advisory message. +

    2. +
    3. +

      If there was a previous primary, including this controller, or Write +requests in flight, then the server carries out the following steps +(in this order): +

      +
        +
      1. +

        The server stops accepting Write requests from the previous primary +(if there is one). At this point, the server will reject all Write +requests with PERMISSION_DENIED. +

      2. +
      3. +

        The server notifies all controllers other than the new primary client +of the change by sending the advisory notification described in +the following section. +

      4. +
      5. +

        The server will finish processing any Write requests that have +already started. If there are errors, they are reported as usual to +the previous primary. If the previous primary has already +disconnected, any possible errors are dropped and not reported. +

      6. +
      7. +

        The server now accepts the current controller as the new primary, +thus accepting Write requests from this controller. The server +updates the highest election ID (i.e. election_id_past) it has seen +for this device_id and role to election_id. +

      8. +
      9. +

        The server notifies the new primary by sending the advisory message +described in the following section. +

      +
    +
  2. +
  3. +

    Otherwise, the controller becomes a backup. If the controller was previously +a primary (and downgraded itself), then an advisory message is sent to all +controllers for this device_id and role. Otherwise, the advisory +message is only sent to the controller that sent the initial +MasterArbitrationUpdate. See the +following section for the format of the +advisory message. +

+

5.4. Client Arbitration Notifications

+

For any given device_id and role, any time a new primary is chosen, a +primary downgrades its status to a backup, a primary disconnects, or the +role.config is updated by the primary, all controllers for that +(device_id, role) are informed of this by sending a +StreamMessageResponse. The MasterArbitrationUpdate is populated as follows: +

+
    +
  • +

    device_id and role as given. +

  • +
  • +

    role.config is set to the role configuration the server received most +recently in a MasterArbitrationUpdate from a primary. +

  • +
  • +

    election_id is populated as follows: +

    +
      +
    • +

      If there has not been any primary at all, the election_id is left unset. +

    • +
    • +

      Otherwise, election_id is set to the highest election ID that the server +has seen for this device_id and role (which is the election_id of +the current primary if there is any). +

    +
  • +
  • +

    status is set differently based on whether the notification is sent to the +primary or a backup controller: +

    +
      +
    • +

      If there is a primary: +

      +
        +
      • +

        For the primary, status is OK (with status.code set to +google.rpc.OK). +

      • +
      • +

        For all backup controllers, status is set to non-OK (with +status.code set to google.rpc.ALREADY_EXISTS). +

      +
    • +
    • +

      Otherwise, if there is no primary currently, for all backup controllers, +status is set to non-OK (with status.code set to +google.rpc.NOT_FOUND). +

    +
+ +

Note that on primary client changes with outstanding Write request, some +notifications might be delayed, see the +previous section for details. +

6. The P4Info Message

+

The purpose of P4Info was described under +Reference Architecture. +Here we describe the various +components. +

6.1. Common Messages

+

These messages appear nested within many other messages. +

6.1.1. Documentation Message

+

Documentation is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers. +

+
+
+
message Documentation {
+  // A brief description of something, e.g. one sentence
+  string brief = 1;
+  // A more verbose description of something.
+  // Multiline is accepted. Markup format (if any) is TBD.
+  string description = 2;
+}

6.1.2. Preamble Message

+

The preamble serves as the “descriptor” for each entity and contains the unique +instance ID, name, alias, annotations and documentation. +

+
+
+
message Preamble {
+  // ids share the same number-space; e.g. table ids cannot overlap with counter
+  // ids. Even though this is irrelevant to this proto definition, the ids are
+  // allocated in such a way that it is possible based on an id to deduce the
+  // resource type (e.g. table, action, counter, ...). This means that code
+  // using these ids can detect if the wrong resource type is used
+  // somewhere. This also means that ids of different types can be mixed
+  // (e.g. direct resource list for a table) without ambiguity. Note that id 0
+  // is reserved and means "invalid id".
+  uint32 id = 1;
+  // fully qualified name of the P4 object, e.g. c1.c2.ipv4_lpm
+  string name = 2;
+  // an alias (alternative name) for the P4 object, probably shorter than its
+  // fully qualified name. The only constraint is for it to be unique with
+  // respect to other P4 objects of the same type. By default, the compiler uses
+  // the shortest suffix of the name that uniquely identifies the object. For
+  // example if the P4 program contains two tables with names s.c1.t and s.c2.t,
+  // the default aliases will respectively be c1.t and c2.t. In the future, the
+  // P4 programmer may also be able to override the default alias for any P4
+  // object (TBD).
+  string alias = 3;
+  repeated string annotations = 4;
+  // Optional. If present, the location of `annotations[i]` is given by
+ // `annotation_locations[i]`.
+  repeated SourceLocation annotation_locations = 7;
+  // Documentation of the entity
+  Documentation doc = 5;
+  repeated StructuredAnnotation structured_annotations = 6;
+}

6.1.3. Annotating P4 Entities with Documentation

+

P4 entities may be annotated using the following annotations: +

+
+
+
@brief(string...)
+@description(string...)
+

Attaching either or both of these annotations to an entity will generate a +P4Info Documentation Message, which in turn will +appear in the Preamble Message for the entity. +

+

The P4 compiler should not emit annotation messages in the P4Info for these +specific cases; instead, it should generate the Documentation messages as +described. +

+

The following example shows documentation annotations for a table entity: +

+
+
+
@brief("Match IPv4 addresses to next-hop MAC and port")
+@description("Match IPv4 addresses to next-hop MAC and port. \
+Uses LPM match type.")
+table my_ipv4_lkup {
+  ...
+}

6.1.4. Structured Annotations

+

P4 supports both unstructured and structured annotations [13]. +Unstructured annotations of the form MyAnno1 or MyAnno2(body-content) can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +MyAnno3[] or MyAnno4[kvList|expressionList] have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this. +

+

The annotations described up to this point, e.g. @brief(), have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as repeated string annotations fields in the various messages. +Similarly, structured annotations are represented in repeated +StructuredAnnotation structured_annotations fields which are siblings to the +unstructured annotations. The structured_annotations contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations. +

+

The structured annotation messages are defined in p4types.proto. +

+
+
+
message KeyValuePair {
+  string key = 1;
+  Expression value = 2;
+}
+
+message KeyValuePairList {
+  repeated KeyValuePair kv_pairs = 1;
+}
+
+message Expression {
+  oneof value {
+    string string_value = 1;
+    int64 int64_value = 2;
+    bool bool_value = 3;
+  }
+}
+
+message ExpressionList {
+  repeated Expression expressions = 1;
+}
+
+message StructuredAnnotation {
+  string name = 1;
+  oneof body {
+    ExpressionList expression_list = 2;
+    KeyValuePairList kv_pair_list = 3;
+  }
+  // Optional. Location of the '@' symbol of this annotation in the source code.
+  SourceLocation source_location = 4;
+}
+

The StructuredAnnotation message can represent either a KeyValuePairList +or an ExpressionList. +

+

The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The p4c +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don't match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler may print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions. +

+

The following invariants hold: +

+
    +
  1. +

    For any P4 entity, there are no two StructuredAnnotations that have the +same name. +

  2. +
  3. +

    Within a KeyValuePairList, there are no two KeyValuePairs that have the +same key. +

+
6.1.4.1. Structured Annotation Examples
+

We omit the source_location field in the following examples. +

+

Empty Expression List +

+
+
+
@Empty[]
+table t {
+    ...
+}
+

The generated P4Info will contain the following. +

+
+
+
structured_annotations {
+  name: "Empty"
+}
+

Mixed Expression List +

+
+
+
#define TEXT_CONST "hello"
+#define NUM_CONST 6
+@MixedExprList[1,TEXT_CONST,true,1==2,5+NUM_CONST]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedExprList"
+  expression_list {
+    expressions {
+      int64_value: 1
+    }
+    expressions {
+      string_value: "hello"
+    }
+    expressions {
+      bool_value: true
+    }
+    expressions {
+      bool_value: false
+    }
+    expressions {
+      int64_value: 11
+    }
+  }
+}
+

kvList of Mixed Expressions +

+
+
+
@MixedKV[label="text", my_bool=true, int_val=2*3]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedKV"
+  kv_pair_list {
+    kv_pairs {
+      key: "label"
+      value {
+        string_value: "text"
+      }
+    }
+    kv_pairs {
+      key: "my_bool"
+      value {
+        bool_value: true
+      }
+    }
+    kv_pairs {
+      key: "int_val"
+      value {
+        int64_value: 6
+      }
+    }
+  }
+}

6.1.5. SourceLocation Message

+

A source location describes a location within a .p4-source file. The +SourceLocation message is defined in p4types.proto as follows: +

+
+
+
// Location of code relative to a given source file.
+message SourceLocation {
+  // Path to the source file (absolute or relative to the working directory).
+  string file = 1;
+  // Line and column numbers within the source file, 1-based.
+  int32 line = 2;
+  int32 column = 3;
+}
+

We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations. +

+

The SourceLocation message associated with an annotation holds the location of +the @ symbol introducing the annotation in the P4 source code; the message can +be found in the following place: +

+
    +
  • +

    For unstructured annotations, every message containing a field +repeated string annotations also contains a field +repeated SourceLocation annotation_locations. The field must either be empty + or match the size of annotations. In the latter case, the i-th member of +annotation_locations is the source location of the i-th member of +annotations. +

  • +
  • +

    For structured annotations, every StructuredAnnotation message contains +an optional field SourceLocation source_location holding its source +location, if present. +

+

6.2. PkgInfo Message

+

The PkgInfo message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. PkgInfo can be extracted +and used to facilitate “browsing” of available P4 programs from a +library. Although all fields are technically “optional,” every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included. +

+
+
+
// Can be used to manage multiple P4 packages.
+message PkgInfo {
+  // a definitive name for this configuration, e.g. switch.p4_v1.0
+  string name = 1;
+  // configuration version, free-format string
+  string version = 2;
+  // brief and detailed descriptions
+  Documentation doc = 3;
+  // Miscellaneous metadata, free-form; a way to extend PkgInfo
+  repeated string annotations = 4;
+  // the target architecture, e.g. "psa"
+  string arch = 5;
+  // organization which produced the configuration, e.g. "p4.org"
+  string organization = 6;
+  // contact info for support,e.g. "tech-support@acme.org"
+  string contact = 7;
+  // url for more information, e.g. "http://support.p4.org/ref/p4/switch.p4_v1.0"
+  string url = 8;
+  // Miscellaneous metadata, structured; a way to extend PkgInfo
+  repeated StructuredAnnotation structured_annotations = 9;
+}

6.2.1. Annotating P4 code with PkgInfo

+

A P4 progam's PkgInfo may be declared using one or more of the following +annotations, attached to the main block only: +

+
+
+
@pkginfo(key=value)
+@pkginfo(key=value[,key=value,...])
+@brief("A brief description")
+@description("A longer\
+description")
+@custom_annotation(...)
+@another_custom_annotation(...)
+

Above we see several different types of annotations: +

+
    +
  • +

    @pkginfo - This is used to populate a specific field within the PkgInfo +message. Multiple @pkginfo annotations are allowed. For compactness, +multiple key-value pairs can appear in a single @pkginfo annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The keys must be from +among the message fields inside PkgInfo, for example, name, version, +etc. Each key-value pair assigns a value to the corresponding field inside the +single PkgInfo message for the program's P4Info. One exception is that the +Documentation field of PkgInfo must be expressed as individual +@description and @brief annotations, see next bullets. The key arch will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself. +

  • +
  • +

    @brief - This will populate the PkgInfo.doc.brief message field. +

  • +
  • +

    @description - This will populate the PkgInfo.doc.description message +field +

  • +
  • +

    @<anything else> - This will create a PkgInfo.annotation entry +

+ +

Declaring one or more of these annotations on main will +generate a single corresponding PkgInfo message in the P4Info as described in +PkgInfo Message. +

+

The following example shows @pkginfo annotations using a mixture of single and +multiple key-value pairs. It also shows @brief and @description annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the PkgInfo message. The custom annotations will +be appended to the PkgInfo.annotations list. +

+
+
+
@pkginfo(name="switch.p4",version="2")
+@pkginfo(organization="p4.org")
+@pkginfo(contact="info@p4.org")
+@pkginfo(url="www.p4.org")
+@brief("L2/L3 switch")
+@description("L2/L3 switch.\
+Built for data-center profile.")
+@my_annotation1(...) // Not well-known, this will appear in PkgInfo annotations
+@my_annotation2(...) // Not well-known, this will appear in PkgInfo annotations
+PSA_Switch(IgPipeline, PacketReplicationEngine(), EgPipeline,
+           BufferingQueueingEngine()) main;

6.3. ID Allocation for P4Info Objects

+

P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(e.g. table, action, counter, ). The most significant 8 bits of the ID +encodes the object type (as per Table 1). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (p4.config.v1.P4Ids.Prefix). These values must +be used (e.g. by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table 2 shows the ID +layout. +

+
+ + + + + + + + + + + + + + + + + + + + + +
8-bit prefix value P4 object type
0x00 Reserved (unspecified)
0x01 Action
0x02 Table
0x03 Value-set
0x04 Controller header (header type with @controller_header annotation)
0x050x0f Reserved (for future P4 built-in objects)
0x10 Reserved (start of PSA extern types)
0x11 PSA Action profiles / selectors
0x12 PSA Counter
0x13 PSA Direct counter
0x14 PSA Meter
0x15 PSA Direct meter
0x16 PSA Register
0x17 PSA Digest
0x180x7f Reserved (for future PSA extern types)
0x80 Reserved (start of vendor-specific extern types)
0x810xfe Vendor-specific extern types
0xff Reserved (max prefix value)
+
+ +
Table 1. Mapping of P4Info object type to 8-bit ID prefix value
+
+ + + + +
MSB bit 31 .. bit 24 bit 23 .. bit 0 LSB
Object type prefix Generated suffix (e.g. by the compiler)
+
+ +
Table 2. Format of P4Info object IDs
+

It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with @id (see Table +3). The compiler must honor the @id annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (i.e. if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same @id value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct. +

+
+ + + + + + + + + + +
P4 declaration(s) Compiler-allocated ID(s)
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) table tA... Error(same ID suffixes for 2 objects of the same type)
@id(0x12ab34) table tB...
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) action act1... 0x0112ab34
+
+ +
Table 3. Example of statically-assigned P4Info object IDs
+

The @id annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively). +

6.4. P4Info Objects

6.4.1. Table

+

Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this table. +

  • +
  • +

    match_fields, a repeated field of type MatchField representing the data to +be used to construct the lookup key matched in this table. Each MatchField +message is defined with the following fields: +

    +
      +
    • +

      id, the uint32 identifier of this MatchField, unique in the scope of +this table. No rules are prescribed on the way MatchField IDs should be +allocated, as long as two MatchField of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the @id annotation, or let the compiler +choose them. +

    • +
    • +

      name, the string representing the name of this MatchField. +

    • +
    • +

      annotations, a repeated field of strings, each one representing a P4 +annotation associated to this match field. +

    • +
    • +

      bitwidth, an int32 value set to the size in bits of this match field. +

    • +
    • +

      match, a oneof describing the match behavior for this field; it can be +either: +

      +
        +
      • match_type, an enum field of type MatchType, which includes all +possible PSA match kinds. +
      • +
      • other_match_type, a string field which can be used to encode any +architecture-specific match type. +
      +
    • +
    • +

      doc, a Documentation message describing this match field. +

    • +
    • +

      type_name, which indicates whether the match field has a user-defined +type; this is useful for +translation. +

    +
  • +
  • +

    action_refs, a repeated ActionRef field representing the set of possible +actions for this table. The ActionRef message is used to reference an action +specified in the same P4Info message and it includes the following fields: +

    +
      +
    • id, the uint32 identifier of the action. +
    • +
    • scope, an enum value which can take one of three values: + TABLE_AND_DEFAULT, TABLE_ONLY and DEFAULT_ONLY. The scope of the + action is determined by the use of the P4 standard annotations + @tableonly and @defaultonly [18]. TABLE_ONLY + (@tableonly annotation) means that the action can only appear within + the table, and never as the default action. DEFAULT_ONLY + (@defaultonly annotation) means that the action can only be used as the + default action. TABLE_AND_DEFAULT is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action. +
    • +
    • annotations, a repeated string field, each one representing a P4 +annotation associated to the action reference in this table. +
    +
  • +
  • +

    const_default_action_id, if this table has a constant default action, this +field will carry the uint32 identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action's +arguments. +

  • +
  • +

    implementation_id, the uint32 identifier of the “implementation” of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (e.g. a PSA ActionProfile or ActionSelector +instance). The table is then referred to as an indirect match table. +

  • +
  • +

    direct_resource_ids, repeated uint32 identifiers for all the direct +resources attached to this table, such as DirectMeter and DirectCounter +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2. +

  • +
  • +

    size, an int64 describing the desired number of table entries that the +target should support for the table. See the “Size” subsection within the +“Table Properties” section of the P416 language specification for details +[30]. +

  • +
  • +

    idle_timeout_behavior, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +Idle-Timeout section). Value can be any of the +IdleTimeoutBehavior enum: +

    +
      +
    • NO_TIMEOUT (default value), which means that idle timeout is not +supported for this table. +
    • +
    • NOTIFY_CONTROL, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +Table Idle Timeout Notifications). +
    +
  • +
  • +

    is_const_table, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime. +

  • +
  • +

    other_properties, an Any Protobuf message [31] to embed +architecture-specific table properties [30] which are not part +of the core P4 language or of the PSA architecture. +

+

6.4.2. Action

+

Action messages are used to specify all possible actions of all match-action +tables. +

+

The Action message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this action +

  • +
  • +

    params, a repeated field of Param messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each Param message contains the +following fields: +

    +
      +
    • id, the uint32 identifier of this parameter. No rules are prescribed +on the way Param IDs should be allocated, as long as two Param of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the @id +annotation, or let the compiler choose them. +
    • +
    • name, the string representing the name of this parameter. +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this parameter. +
    • +
    • bitwidth, an int32 value set to the size in bits of this parameter. +
    • +
    • doc, which describes this parameter using a Documentation message. +
    • +
    • type_name, which indicates whether the action parameter has a +user-defined type; this is useful for +translation. +
    +
+

6.4.3. ActionProfile

+

ActionProfile messages are used to specify all available instances of Action +Profile and Action Selector PSA externs. +

+

PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile member, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime. +

+

PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into groups. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime. +

+

While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same ActionProfile message to describe both. +

+

The ActionProfile message includes the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Action +Profile or Selector. +

  • +
  • +

    table_ids, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector. +

  • +
  • +

    with_selector, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern. +

  • +
  • +

    size, an int64 representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups. +

  • +
  • +

    max_group_size, an int32 which is 0 for an Action Profile, or, for an +Action Selector, represents the maximum sum of all member weights within any +given selector group. The max_group_size must be no larger than size. PSA +programs can use the @max_group_size annotation to provide this value for +Action Selectors. If the annotation is omitted, the P4Info field will default +to 0. +

+

6.4.4. Counter & DirectCounter

+

Counter and DirectCounter messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is: +

+
    +
  • +

    Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index. +

  • +
  • +

    Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table. +

+ +

Both Counter and DirectCounter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this counter +extern instance. +

  • +
  • +

    spec, a message of of type CounterSpec used to describe the compile-time +configuration of this counter. Currently, the CounterSpec message is used to +carry only the counter unit, which can be any of the CounterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES: byte counter. +
    • +
    • PACKETS: packet counter. +
    • +
    • BOTH: combination of both byte and packet counter. +
    +
+ +

For indexed counters, the Counter message contains also a size field, an +int64 representing the maximum number of independent values that can be held +by this counter array. Conversely, the DirectCounter message contains a +direct_table_id field that carries the unit32 identifier of the table to +which this direct counter is attached. +

+

For indexed counters, the Counter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.5. Meter & DirectMeter

+

Meter and DirectMeter messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is: +

+
    +
  • +

    Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +e.g. to set the rate threshold. +

  • +
  • +

    Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table. +

+ +

Both Meter and DirectMeter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this meter +extern instance. +

  • +
  • +

    spec, a message of type MeterSpec used to describe the capabilities of +this meter extern instance. Currently, the MeterSpec message is used to +carry only the meter unit, which can be any of the MeterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES, which signifies that this meter can be configured with rates +expressed in bytes/second. +
    • +
    • PACKETS, for rates expressed in packets/second. +
    +
+ +

For indexed meters, the Meter message contains also a size field, an int64 +representing the maximum number of independent cells that can be held by this +meter. Conversely, the DirectMeter message contains a direct_table_id field +that carries the uint32 identifier of the table to which this direct meter is +attached. +

+

For indexed meters, the Meter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.6. ControllerPacketMetadata

+

ControllerPacketMetadata messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server. +

+

When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet. +

+

Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +@controller_header("packet_in") and @controller_header("packet_out"), +respectively. ControllerPacketMetadata messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages). +

+

A P4Info message can contain at most two ControllerPacketMetadata messages, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message where preamble.name is set to "packet_in" +and "packet_out" for packet-in and packet-out metadata, respectively. +

  • +
  • +

    metadata, a repeated field of type Metadata, where each Metadata message +includes the following fields: +

    +
      +
    • id, a uint32 identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two Metadata of the +same ControllerPacketMetadata message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the @id annotation, or let the compiler choose them. +
    • +
    • name, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below). +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this metadata. +
    • +
    • bitwidth, an int32 representing the size in bits of this metadata. +
    • +
    • type_name, which indicates whether the metadata field has a +user-defined type; this is useful for +translation. +
    +
+ +

As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding ControllerPacketMetadata +messages. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  bit<9> egress_port; /* suggested port where the packet
+                         should be sent */
+  bit<8> queue_id;    /* suggested queue ID */
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  bit<9> ingress_port; /* data plane port ID where
+                          the original packet was received */
+  bit<1> is_clone;     /* 1 if this is a clone of the
+                          original packet */
+}
+
+
+
controller_packet_metadata {
+  preamble {
+    id: 2868916615
+    name: "packet_out"
+    annotations: "@controller_header(\"packet_out\")"
+  }
+  metadata {
+    id: 1
+    name: "egress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "queue_id"
+    bitwidth: 8
+  }
+}
+
+controller_packet_metadata {
+  preamble {
+    id: 2868941301
+    name: "packet_in"
+    annotations: "@controller_header(\"packet_in\")"
+  }
+  metadata {
+    id: 1
+    name: "ingress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "is_clone"
+    bitwidth: 1
+  }
+}
+

Note that the use of @controller_header is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages. +

6.4.7. ValueSet

+

ValueSet messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P416 +specification [39]. +

+

The ValueSet message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Value +Set. +

  • +
  • +

    match, a repeated field of MatchField messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the match_fields repeated field in the +Table message. +

  • +
  • +

    size, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +value_set constructor call. +

+ +

According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of bit<W>, +tuple, or struct [26]. The rest of this section looks at all 3 of +these cases and gives an example ValueSet message when appropriate. +

+
    +
  1. +

    If the type parameter is bit<W>, match will include exactly one +MatchField message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used): +

    +
      +
    • id: set to 1 +
    • +
    • bitwidth: set to the value of W +
    • +
    • match_type: set to EXACT +
    +
+ +
+
+
@id(1) value_set<bit<8> >(4) pvs;
+select (hdr.f8) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    bitwidth: 8
+    match_type: EXACT
+  }
+  size: 4
+}
+
    +
  1. +

    If the type parameter is a tuple, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program. +

  2. +
  3. +

    If the type parameter is a struct, this version of P4Runtime requires that +all the fields of the struct be of type bit<W> (where W can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +match field will include one MatchField message for each field in the +struct, with the following fields: +

    +
      +
    • id: must be unique with respect to the other match entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +@id annotation, or let the compiler choose them. +
    • +
    • name: set to the name of the corresponding struct field. +
    • +
    • annotations: set to the list of P4 annotations associated with the struct +field, except for the @match annotation, if present (see the match field +below). +
    • +
    • bitwidth: set to the value of W for the corresponding struct field. +
    • +
    • type_name, which indicates whether the struct field has a user-defined +type; this is useful for +translation. +
    • +
    • match: by default match_type is set to EXACT; the P4 programmer can +specify a different match type by using the @match annotation +[26]. +
    • +
    • doc: documentation associated with the struct field. +
    +
+ +
+
+
struct match_t {
+  @id(1) bit<8> f8;
+  @id(2) @match(ternary) bit<16> f16;
+  @id(3) @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

In the above example, the @id annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs. +

+

Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a user-defined +type that resolves to a bit<W>, or a struct where +one or more fields is a user-defined type that +resolves to a bit<W>. For each MatchField that corresponds to a user-defined +type, the type_name field must be set to the appropriate value (i.e. the name +of the type). +

6.4.8. Register

+

Register messages are used to specify all possible instances of Register PSA +externs. +

+

Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime. +

+

The Register message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this register +instance. +

  • +
  • +

    type_spec, which specifies the data type stored by this register, expressed +using a P4DataTypeSpec message (see section on Representation of Arbitrary +P4 Types). +

  • +
  • +

    size, an int32 value representing the total number of independent register +cells available. +

  • +
  • +

    index_type_name, which indicates whether the register index has a +user-defined type. This is useful for +translation. The underlying built-in type +must be a fixed-width unsigned bitstring (bit<W>). +

+

6.4.9. Digest

+

Digest messages are used to specify all possible instances of Packet Digest +PSA externs. +

+

A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages. +

+

The Digest message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this digest +instance. +

  • +
  • +

    type_spec, which specifies the data type of an individual digest +notification using a P4DataTypeSpec message (see section on Representation +of Arbitrary P4 Types). +

+

6.4.10. Extern

+

Extern messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one Extern message instance in P4Info. The Extern message defines +the following fields: +

+
    +
  • +

    extern_type_id, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the reserved +range [0x81, 0xfe]. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture. +

  • +
  • +

    extern_type_name, which specifies the fully-qualified P4 name of the extern +type. +

  • +
  • +

    instances, a repeated field of ExternInstance Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +ExternInstance in turn defines the following fields: +

    +
      +
    • preamble, a Preamble message with the ID, name, and alias of this digest +instance. +
    • +
    • info, an Any Protobuf message [31] which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for info should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on Extending +P4Runtime for non-PSA Architectures for more +information. +
    +
+ +

If the P4 program does not include any instance of a given extern type, the +Extern message instance for that type should be omitted from the P4Info. +

6.5. Support for Arbitrary P4 Types with P4TypeInfo

+

See section on Representation of Arbitrary P4 +Types. +

7. P4 Forwarding-Pipeline Configuration

+

The ForwardingPipelineConfig captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the “Device Configuration” and sometimes also referred to as +the “P4 Blob”. It is defined as: +

+
+
+
message ForwardingPipelineConfig {
+  config.P4Info p4info = 1;
+  bytes p4_device_config = 2;
+  message Cookie {
+    uint64 cookie = 1;
+  }
+  Cookie cookie = 3;
+}
+

The p4info field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic. +

+

The p4_device_config is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new ForwardingPipelineConfig on that target. +

+

The cookie field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a GetForwardingPipelineConfig RPC. +When writing the config via a SetForwardingPipelineConfig RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present. +

8. General Principles for Message Formatting

8.1. Set / Unset Protobuf Field

+

In Protobuf version 3 (proto3), the default value for a message field is +“unset” [4]. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +CounterEntry message, an “unset” index field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the index message field is +set, a single entry will be read. +

+

Let's look at the counter example in more details. Based on this specification +document, the C++ server code which processes CounterEntry messages may look +like this: +

+
+
+
auto *counter_entry = ...
+if (counter_entry->has_index()) {
+  auto index = counter_entry->index().index();
+  read_one_entry(counter_entry->id(), index);
+} else {
+  read_all_entries(counter_entry->id());
+}
+
    +
  1. +

    Reading a single counter entry at index 0 in the counter array with id +<id>: +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
      +entry.mutable_index();
      +// The above line sets the index field; it is equivalent to:
      +// auto *index = entry.mutable_index();
      +// index->set_index(0);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
      +index {}
    • +
    • Expected behavior: Counter entry at index 0 is read. Notice that the +index subfield is missing under the index field message of +CounterEntry in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages. +
    +
  2. +
  3. +

    Reading all counter entries by leaving the index field unset +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
    • +
    • Expected behavior: All counter entries for the provided counter +instance are read. Notice that the index message field is unset (default +value) and is therefore omitted from the textual representation of the +message. +
    +
+

8.2. Read-Write Symmetry

+

The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example: +

+
+
+
intended_value = value
+
+status = server.write(intended_value, p4_entity)
+observed_value = server.read(p4_entity)
+
+assert(intended_value == observed_value)
+

To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If Read RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol's complexities to the client implementations. +

+

In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the match fields in a TableEntry message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +MessageDifferencer class [36] included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance. +

8.3. Zero as Reserved Value

+

p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a uint32. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a WriteRequest or a SetForwardingPipelineConfigRequest. +

8.4. Bytestrings

+

P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (bit<W>) or signed (int<W>), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +bytes Protobuf type. The correct bitwidth as per the P4 program of +each integer variable exposed through P4Runtime is specified in the P4Info +message. +

+

The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals: +

+
    +
  • +

    It ensures that a properly encoded binary string's integer value conforms +to the P4Info-specified bitwidth. +

  • +
  • +

    It supports read-write symmetry. +

  • +
  • +

    It helps facilitate non-disruptive P4 program updates. +

+ +

In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type bit<W> and/or int<W>. +

+

Note that this representation does not make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range. +

+

In the P4Runtime API version 1.0 (including minor version revisions), values +of table key fields, action parameters, and fields in packet-in and packet-out +headers between a device and the controller (see 6.4.6), +may not be of type int<W>. The rules for encoding signed values thus only +apply to messages of type P4Data (see 8.5.3). +

+

For a value of type bit<W>, the fewest number of bits required to represent +the integer value $V > 0$ is the smallest integer $A$ such that $V \leq 2^A -1$. +

+

For a value of type int<W>, the fewest number of bits required to represent +the integer value $V \neq 0$ in 2's complement form is the smallest integer $A$ +such that $-2^{A-1} \leq V \leq 2^{A-1} - 1$. +

+

As a special case, define that the value $V=0$ requires at least $A=1$ bit to +represent, regardless of whether it is signed or unsigned. +

+

The shortest possible binary string for an integer $V$ that needs $A$ bits to +represent it is computed as: +

+
+
+
minimum_string_size = floor((A + 7) / 8)
+

Binary strings with the byte length computed as minimum_string_size promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies. +

+

Any additional bits in the bytes sent for an unsigned integer value (type +bit<W>) must be 0. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with 0. +

+

Any additional bits in the bytes sent for a signed integer value (type int<W>) +must be copies of the sign bit, i.e. 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with copies of the +sign bit, i.e. 0 for non-negative values, or 0xff for negative values. In 2's +complement representation, this is called “sign extension”, and leaves the +numeric value represented unchanged. +

+

Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value. +

+

For a received bitstring expected to fit within a bit<W> type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring's width is W bits or less. +

+

For a received bitstring expected to fit within an int<W> type, the value it +represents is in range if, after “undoing sign extension”, the remaining bit +string's width is W bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other. +

+

If the string's byte length is zero, the server always rejects the string. +

+

When the server rejects a binary string due to any of the previous criteria, +it returns an OUT_OF_RANGE error. +

+

For all binary strings, P4Runtime uses big-endian (i.e. network) byte-order. +For signed integer values (int<W> P4 type), P4Runtime uses the same two's +complement bitwise representation as P4. Table 4 +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above. +

+
+ + + + + + + + + + + + + + + + + +
P4 type Integer value P4Runtime binary string Read-write symmetry
bit<8> 99 (0x63) \x63 yes
bit<16> 99 (0x63) \x00\x63 no
bit<16> 99 (0x63) \x63 yes
bit<16> 12388 (0x3064) \x30\x64 yes
bit<16> 12388 (0x3064) \x00\x30\x64 no
bit<12> 99 (0x63) \x00\x63 no
bit<12> 99 (0x63) \x63 yes
bit<12> 99 (0x63) \x00\x00\x63 no
int<8> 99 (0x63) \x63 yes
int<8> -99 (-0x63) \x9d yes
int<8> -99 (-0x63) \xff\x9d no
int<12> -739 (-0x2e3) \xfd\x1d yes
int<16> 0 (0x0) \x00\x00 no
int<16> 0 (0x0) \x00 yes
+
+ +
Table 4. Examples of Valid Bytestring Encoding
+

Table 5 shows some examples of invalid +P4Runtime binary strings: +

+
+ + + + + + + + + + + + +
P4 type P4Runtime binary string
bit<8> \x01\x63
bit<8> empty string
bit<16> \x01\x00\x63
bit<12> \x10\x63
bit<12> \x01\x00\x63
bit<12> \x00\x40\x63
int<8> \x00\x9d
int<12> \x8d\x1d
int<16> empty string
+
+ +
Table 5. Examples of Invalid Bytestring Encoding
+

As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from bit<8> to bit<9>, a server +running the bit<9> version of the P4 program will accept requests from +clients that remain on the bit<8> P4Runtime version. +

+

Despite the server's binary string flexibility for P4 program update support, +the client and server must both remain aware of the +read-write symmetry +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values. +

+

Representation of variable-length integer values (varbit<W> P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the dynamic-length of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an OUT_OF_RANGE error code otherwise. +

8.5. Representation of Arbitrary P4 Types

8.5.1. Problem Statement

+

The P416 language includes more complex types than just binary strings +[3]. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table 6 shows the different +P416 types and how they are allowed to be used, as per the P416 +specification. +

+
+ + + + + + + + + + + + + + + + + + + +
Container type
Element type header header_union struct or tuple
bit<W> allowed error allowed
int<W> allowed error allowed
varbit<W> allowed error allowed
int error error error
void error error error
error error error allowed
match_kind error error error
bool error error allowed
enum allowed1 error allowed
header error allowed allowed
header stack error error allowed
header_union error error allowed
struct error error allowed
tuple error error allowed
+
+ +
Table 6. P4 Type Usage
+

For example, the following P416 objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects. +

+
+
+
Digest<tuple<bit<4>, bit<8> > >() digest_complex;
+digest_complex.pack({ hdr.ipv4.version, hdr.ipv4.protocol });
+// ...
+header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

One solution would be to use only binary string (bytes type) in +p4runtime.proto and to define a custom serialization format for complex P416 +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P416 types. +

8.5.2. P4 Type Specifications in p4info.proto

+

In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type ip_t, which is a header union with 2 possible headers: +ipv4 with type ipv4_t and ipv6 with type ipv6_t. Similarly, they need to +know the field layout for both of these header types. +

+

To achieve this we introduce 2 main Protobuf messages: P4TypeInfo and +P4DataTypeSpec. +

+

P4TypeInfo is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P416 program. These +named types are struct, header, header_union, enum and +serializable_enum; for each of these we have a type specification message, +respectively P4StructTypeSpec, P4HeaderTypeSpec, P4HeaderUnionTypeSpec, +P4EnumTypeSpec and P4SerializableEnumTypeSpec. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. P4TypeInfo also includes the list of parser errors for the program, as +a P4ErrorTypeSpec message. +

+

P4DataTypeSpec is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each P4DataTypeSpec message corresponds to a compile-time type in the +original P416 program (e.g. the type parameter of an extern). This +compile-time type is represented as a Protobuf oneof, which can be: +

+
    +
  • +

    a string representing the name of the type in case of a named type (struct, +header, header_union, enum, serializable_enum or user-defined “new” +type), +

  • +
  • +

    an empty Protobuf message for bool and error, or +

  • +
  • +

    a Protobuf message for other anonymous types (bit<W>, int<W>, varbit<W>, +tuple or stack). The “binary string” types (bit<W>, int<W>, and +varbit<W>) are grouped together in the P4BitstringLikeTypeSpec message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf bytes +type). +

+ +

For all P416 compound types (tuple, struct, header, and header_union), +the order of members in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P416 declaration. The same goes for the order of members of an enum +(serializable or not) or members of error. +

8.5.3. P4Data in p4runtime.proto

+

P4Runtime uses the P4Data message to represent values of arbitrary types. The +P4Runtime client must generate correct P4Data messages based on the type +specification information included in P4Info. The P4Data message was designed +to introduce little overhead compared to using binary strings in the most common +case (P416 bit<W> type). +

+

Just like its P4Info counterpart - P4DataTypeSpec -, P4Data uses a Protobuf +oneof to represent all possible values. +

+

We define a canonical representation for P4Data messages therefore +guaranteeing read-write symmetry by introducing the following requirements: +

+
    +
  • +

    The order of members in P4StructLike and the order of bitstrings in +P4Header must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P416 type +declaration. +

  • +
  • +

    An invalid header is represented by a P4Header message where the is_valid +field is false and the bitstrings repeated field is empty. +

  • +
  • +

    An invalid header union (i.e. all headers in the union are invalid) is +represented by a P4HeaderUnion message where the valid_header_name is the +empty string (default value for the field) and the valid_header is unset. +

  • +
  • +

    The order of entries in P4HeaderStack and P4HeaderUnionStack is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the entries field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding P4HeaderStackTypeSpec or +P4HeaderUnionStackTypeSpec message. +

+

8.5.4. Example

+

Let's look at the Register example again: +

+
+
+
header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

Here's the corresponding entry in the P4Info message: +

+
+
+
registers {
+  preamble {
+    id: 369119267
+    name: "register_ip"
+    alias: "register_ip"
+  }
+  type_spec {
+    header_union {
+      name: "ip_t"
+    }
+  }
+  size: 128
+}
+type_info {
+  headers {
+    key: "ipv4_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  headers {
+    key: "ipv6_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  header_unions {
+    key: "ip_t"
+    value {
+      members {
+        name: "ipv4"
+        header {
+          name: "ipv4_t"
+        }
+      }
+      members {
+        name: "ipv6"
+        header {
+          name: "ipv6_t"
+        }
+      }
+    }
+  }
+}
+

Here's a p4.WriteRequest to set the value of register_ip[12]: +

+
+
+
update {
+  type: INSERT
+  entity {
+    register_entry {
+      register_id: 369119267
+      index {
+        index: 12
+      }
+      data {
+        header_union {
+          valid_header_name: "ipv4"
+          valid_header {
+            is_valid: true
+            bitstrings: "\x04"
+            bitstrings: # ...
+          }
+        }
+      }
+    }
+  }
+}

8.5.5. enum, serializable enum and error

+

P416 supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or “unsafe” enum) +[5]. For enum types with no underlying type as well as error +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in P4Data to represent enum and +error values. +

+

Serializable enum types have an underlying fixed-width unsigned integer +representation (bit<W>). All named enum members must be assigned an integer +value by the P4 programmer, but not all valid numeric values for the +underlying type need to have a corresponding name. P4TypeInfo includes the +mapping between entry name and entry value. When providing serializable enum +values through P4Data, one must use the assigned integer value (enum_value +bytestring field). P4Runtime does not provide a way for the client to use the +name even when the enum member has one instead of the value, as it makes +it easier for the server to respect the read-write +symmetry principle. +

8.5.6. User-defined types

+

P416 enables programmers to introduce new types [11]. While similar +to typedef, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +translation. When introducing a new type, the +declaration can be annotated with @p4runtime_translation to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for port numbers, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. The @p4runtime_translation annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (bit<W>). The type exposed to the control plane (referred to as the +controller_type) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a URI (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the controller_type of the values exposed to the control plane. The +controller_type can be either bit<W> where W is any positive integer, or +string, or a positive integer W which has the same meaning as bit<W>. +Specifying just an integer is deprecated. +

+

It is recommended that the URI includes at least the P4 architecture name and +the type name. +

+

A @p4runtime_translation annotation need not have any effect if it is used to +annotate anything in a P4 program other than a type declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect. +

+

User-defined types are specified using the P4NewTypeSpec message, which has +the following fields: +

+
    +
  • +

    representation, a Protobuf oneof specifying how values of this type are +exchanged between client and server; it can be either: +

    +
      +
    • +

      original_type, if and only if no @p4runtime_translation annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 type declaration is itself a +user-defined type, original_type is obtained by “walking” the chain of +type declarations recursively until a built-in type (e.g. bit<W>) is +found. +

    • +
    • +

      translated_type, if and only if the P4 type declaration was annotated +with @p4runtime_translation. It is of type P4NewTypeTranslation, +which itself has two fields uri and either sdn_string or +sdn_bitwidth , which map to the two input parameters to the +annotation. +

    +
  • +
  • +

    annotations, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration. +

+ +

For example, an architecture in this case PSA may introduce a new type +for port numbers: +

+
+
+
// Controller refers to ports as a string, e.g. "eth0".
+@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+// Controller refers to ports as a 32-bit integer, e.g. 0xffffffff.
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+// Same as above.
+@p4runtime_translation("p4.org/psa/v1/PortId_32_t", 32)
+type bit<9> PortId_32_t;
+

In this case, the P4Info message would include the following P4TypeInfo +messages: +

+
+
+
type_info {
+  new_types {
+    key: "PortId_String_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_String_t"
+        sdn_string: {}
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_Bit32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_Bit32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+

Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (e.g. through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over @p4runtime_translation to enable users +to overwrite annotations included as part of the P4 architecture definition. +

8.5.7. Trade-off for v1.x Releases

+

For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +bytes with P4Data in the p4.v1.FieldMatch message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +bytes to provide action parameter values and controller metadata +values. However P4Data is used whenever appropriate for PSA externs and we +encourage the use of P4Data in architecture-specific extensions. +

+

In order to support translation for action +parameters and match fields, we include a type_name field in +p4.config.v1.MatchField, p4.config.v1.Action.Param and +p4.config.v1.ControllerPacketMetadata.Metadata. In addition, the bitwidth +field for all of these message types must abide by the following rule when +type_name names a translated user-defined type: +

+
    +
  • +

    If the controller_type is a fixed-width unsigned bitstring, the bitwidth +field must be set to the bitwidth of the controller_type. This information +is redundant with the one included in the P4TypeInfo entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent. +

  • +
  • +

    Otherwise (i.e., if the controller_type is a string), the bitwidth must +be “unset”, which, in Protobuf version 3, is the same as setting the field to +0. +

+ +

For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types: +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+@name(".t")
+table t {
+  key = {
+    meta.port1: exact;  // meta.port1 has type PortId_String_t
+    meta.port2: exact;  // meta.port2 has type PortId_Bit32_t
+  }
+  actions = {
+    drop;
+  }
+}
+

This table would have the following representation in the generated P4Info +message: +

+
+
+
tables {
+  preamble {
+    id: 34728461
+    name: "t"
+    alias: "t"
+  }
+  match_fields {
+    id: 1
+    name: "meta.port1"
+    # notice that bitwidth is unset
+    match_type: EXACT
+    type_name {
+      name: "PortId_String_t"
+    }
+  }
+  match_fields {
+    id: 2
+    name: "meta.port2"
+    bitwidth: 32
+    match_type: EXACT
+    type_name {
+      name: "PortId_Bit32_t"
+    }
+  }
+  # ...
+}

9. P4 Entity Messages

+

P4Runtime covers P4 entities that are either part of the P416 language, or +defined as PSA externs. The sections below describe the messages for each +supported entity. +

9.1. TableEntry

+

The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action's +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification. +

+

P4Runtime supports inserting, modifying, deleting and reading table entries with +the TableEntry entity, which has the following fields: +

+
    +
  • +

    table_id, which identifies the table instance; the table_id is determined +by the P4Info message. +

  • +
  • +

    match, a repeated field of FieldMatch messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration. +

  • +
  • +

    action, which indicates which of the table's actions to execute in case of +match and with which argument values. +

  • +
  • +

    priority, a 32-bit integer used to order entries when the table's match key +includes an optional, ternary or range match. +

  • +
  • +

    controller_metadata, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +metadata field. +

  • +
  • +

    metadata, an arbitrary bytes value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. +

  • +
  • +

    meter_config, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    counter_data, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    meter_counter_data, which is used to read and write the per-color counter +values for the direct meter entry attached to this table entry, if any. +See Direct resources section for more information. +

  • +
  • +

    is_default_action, a boolean flag which indicates whether the table entry is +the default entry for the table. See Default entry +section for more information. +

  • +
  • +

    idle_timeout_ns and time_since_last_hit, which are two fields used to +implement idle-timeout support for the table, if applicable. See +Idle-timeout section for more information. +

+ +

The priority field must be set to a non-zero value if the match key includes a +ternary match (i.e. in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an OPTIONAL, TERNARY or +RANGE match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches. +

+

The match and priority fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for MODIFY and DELETE updates. When deleting +an entry, these key fields (along with is_default_action) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a keyless +table (the table has an empty match key), the server must reject all attempts to +INSERT a match entry and return an INVALID_ARGUMENT error. +

+

The number of match entries that a table should support is indicated in P4Info +(size field of Table message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P416 specification for the +size property [30]. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +RESOURCE_EXHAUSTED when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached. +

9.1.1. Match Format

+

The bytes fields in the FieldMatch message follow the format described in +Bytestrings. +

+

For “don't care” matches, the P4Runtime client must omit the field's entire +FieldMatch entry when building the match repeated field of the TableEntry +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for “don't care” matches, which is needed +to ensure read-write symmetry. For PSA match types, +a “don't care” match for a specific match key field is defined as follows: +

+
    +
  • +

    For a TERNARY match, it is logically equivalent to a mask of zeros. +

  • +
  • +

    For a OPTIONAL match, it is logically equivalent to a wildcard match. +

  • +
  • +

    For an LPM match, it is logically equivalent to a prefix_len of zero. +

  • +
  • +

    For a RANGE match, it is logically equivalent to a range which includes all +possible values for the field. +

+ +

Note that there is no “don't care” value for EXACT matches and therefore exact +match fields can never be omitted from the TableEntry message. +

+

The following example shows a P4Runtime message that treats a TERNARY field +as a “don't care” match. The P4 program defines table t with TERNARY +and EXACT fields in its match key: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: ternary;
+    istd.ingress_port: exact;
+  }
+  actions = {
+    drop;
+  }
+}
+

In this P4Runtime request, the client omits the table's TERNARY field +from the repeated match field to indicate a “don't care” match. As shown +below, the match specifies only the EXACT field given by field_id: 2. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 33554439  # Table t's ID.
+    match {
+      # field_id 1 is not present to use the don't care ternary value.
+      field_id: 2
+      exact {
+        value: "\x20"
+      }
+    }
+    action {
+      # Action selection goes here.
+    }
+  }
+}
+

For every member of the TableEntry repeated match field, field_id must be +a valid id for the table, as per the P4Info, and one of the fields in +field_match_type must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an INVALID_ARGUMENT error code. +

+
    +
  • EXACT match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.exact().value()))
+
    +
  • LPM match + +
      +
    • The binary string encoding of the value (when present) must conform to the +Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • “Don't care” bits must be 0 in value. +
+ +
+
+
assert(BytestringValid(match.lpm().value()))
+
+pLen = match.lpm().prefix_len()
+assert(pLen > 0)
+
+trailing_zeros = countTrailingZeros(match.lpm().value())
+assert(trailing_zeros >= field_bits - pLen)
+
    +
  • TERNARY match + +
      +
    • The binary string encoding of the value (when present) and mask (when +present) must conform to the Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • Masked bits must be 0 in value. This constraint taken together +with the Bytestrings requirements means that the +value's binary string is never longer than the mask's binary string. +When the value's string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask. +
+ +
+
+
assert(BytestringValid(match.ternary().value()))
+assert(BytestringValid(match.ternary().mask()))
+assert(match.ternary().value().size() <= match.ternary().mask().size());
+
+value = parseInteger(match.ternary().value())
+mask = parseInteger(match.ternary().mask())
+
+assert(mask != 0)
+
+assert(value & mask == value)
+
    +
  • RANGE match + +
      +
    • The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the Bytestrings +requirements. +
    • +
    • Low bound must be less than or equal to the high bound. +
    • +
    • “Don't care” match must be omitted. +
+ +
+
+
assert(BytestringValid(match.range().low()))
+assert(BytestringValid(match.range().high()))
+
+low = parseInteger(match.range().low())
+high = parseInteger(match.range().high())
+
+assert(low <= high)
+
+assert(low != min_field_value || high != max_field_value)
+
    +
  • OPTIONAL match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.optional().value()))

9.1.2. Action Specification

+

The TableEntry action field must be set for every INSERT update but may be +left unset for MODIFY updates, in which case the action specification for the +table entry will not be modified (if a MODIFY update has an unset action field +and does not modify any direct resource attached to the table then the MODIFY +update is a no-op). Based on the implementation property value of the P4 table, +the oneof in the TableAction message will either be: +

+
    +
  • +

    an Action specification for direct tables (with no P4 implementation +property) +

  • +
  • +

    an action profile member id for indirect tables for which the implementation +property is an action profile with no selector. +

  • +
  • +

    an action profile member id or group id for indirect tables for which the +implementation property is an action profile with selector. +

  • +
  • +

    an ActionProfileActionSet specification for indirect tables for +which the implementation property is an action profile with +selector. This usage is described in One Shot Action Selector +Programming +

+ +

If the oneof does not match the table description in the P4Info (e.g. the +oneof is action_profile_member_id for a direct table), the server must +return an INVALID_ARGUMENT error code. +

+

The Action Protobuf message has the following fields: +

+
    +
  • +

    action_id, which identifies the action instance; the action_id is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an INVALID_ARGUMENT error +code. If the client uses a valid action_id for the table but does not +respect the action scope specified in P4Info (e.g. tries to set a TABLE_ONLY +action as the default action), the server must return a PERMISSION_DENIED +error code. +

  • +
  • +

    params: a repeated Protobuf field of action parameter values, each encoded +as a Param message. For each parameter, param_id must be valid for the +action (as per the P4Info) and value must follow the format described in +Bytestrings. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an INVALID_ARGUMENT error code +if a parameter id is missing, if an extra parameter id not found in the +P4Info was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +Bytestrings format. +

+ +

For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a NOT_FOUND error code. +

9.1.3. Default Entry

+

According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer or defaults to NoAction +(which is a no-op) otherwise and assuming it is not declared as const, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow INSERT and DELETE updates on the default entry and the +P4Runtime server must return an INVALID_ARGUMENT error code if the client +attempts one. +

+

The default entry is identified by setting the is_default_action boolean field +to true. When this flag is set to true, the repeated match field must be empty +and the priority field must be set to zero, otherwise the P4Runtime server +must return an INVALID_ARGUMENT error code. When performing a MODIFY update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its controller_metadata and metadata value as well as the +configurations for its direct resources will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a PERMISSION_DENIED +error code if the client attempts to modify it. +

+

Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to direct resources. +

+

In this P4Runtime release, we have decided to restrict the default entry for +indirect tables tables with an ActionProfile or ActionSelector +implementation property to a constant NoAction action entry, with the +hope that it would simplify the implementation of the P4Runtime service. +

9.1.4. Constant Tables

+

Constant tables are defined as tables whose match entries are immutable. They +are identified by the is_const_table flag in P4Info. +

+

The only write updates which are allowed for constant tables are MODIFY +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +PERMISSION_DENIED error. Just like any table entry MODIFY request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a PERMISSION_DENIED error. +

+

The contents of const tables can be queried by the client through a +ReadRequest. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: table_id, match, action, +is_default_action, and priority (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the priority field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P416 does not support assigning explicit priorities to static +entries. When a priority value is required (e.g. for tables including RANGE, +TERNARY or OPTIONAL matches), it is inferred based on the order in which +entries appear in the table declaration. +

9.1.5. Wildcard Reads

+

When performing a ReadRequest, the P4Runtime client can select all entries +from one or all tables on the target and use several of the TableEntry fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as priority and “unset” for message fields such as match. The following +fields may be used to select and filter results: +

+
    +
  • table_id: If default (0), entries from all tables including constant +tables will be selected and no other filter can be used. Otherwise only +the specified table will be considered. +
  • +
  • match: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned. +
  • +
  • action: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an action_id (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id. +
  • +
  • priority: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value. +
  • +
  • controller_metadata: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +controller_metadata value. +
  • +
  • metadata: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided metadata value. +
  • +
  • is_default_action: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered. +
  • +
  • role: If default (unset), all table entries will be considered. Otherwise, +table entries will be filtered based on the provided role value. +
+ +

For example, in order to read all entries from all tables from device 3, the +client can use the following ReadRequest message. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0
+    priority: 0
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following ReadRequest +message: +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+    priority: 11
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

The canonical representation of “don't care” matches, combined with the ability +to do a wildcard read on all table entries by leaving the match field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single “don't care” entry or to do a wildcard +read. If a table has no fields with match kind EXACT, it is possible via +P4Runtime to add an entry that is “don't care” for all fields (i.e. has an empty +match field) but is not the default entry (i.e. is_default_action is +false). When reading this entry from the table, there is no way to read only +that entry from the table, because it would require providing an unset match +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single LPM match: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: lpm;
+  }
+  actions = {
+    drop; fwd;
+  }
+}
+

The following WriteRequest message can be used to add 2 entries: +

+
+
+
device_id: 3
+entities {
+  table_entry { # don't care entry
+    table_id: 0x0212ab34
+    # ...
+  }
+  table entry {
+    table_id: 0x0212ab34
+    match {
+      field_id: 1
+      lpm {
+        value: 0x0a000000
+        prefix_len: 8
+      }
+    # ...
+  }
+}
+

The first entry is a “don't care” entry, while the second one matches all +10.0.0.0/8 addresses. The second entry has higher priority than the first one. +

+

The following ReadRequest message will return all entries in the table, not +just the “don't care” entry. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+  }
+}
+

This issue also exists for tables with TERNARY, RANGE, and OPTIONAL +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the “don't care” entry will be returned to the +client. If the client uses distinct priority values for all entries which is +strongly recommended to achieve deterministic behavior , +then there is no ambiguity because the wildcard read will actually return a +single entry (the “don't care” entry) as long as the priority field is set to +the correct value. +

9.1.6. Direct Resources

+

In addition to the DirectCounterEntry and DirectMeterEntry entities, +P4Runtime support reading and writing direct resources as part of the +TableEntry message. This is convenient for two reasons: +

+
    +
  • +

    A table entry and its direct resources can be read with a single entity when +doing a Read RPC call +

  • +
  • +

    The initial configuration for an entry's direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can “hit” the table entry without +executing the appropriate meter entry. +

+ +

Once the table entry has been inserted, the P4Runtime client is free to use the +DirectCounterEntry and DirectMeterEntry messages for read and write +operations on DirectCounter and DirectMeter instances. For example, it is +usually more convenient as well as more efficient to use DirectCounterEntry to +query a counter entry value rather than use TableEntry, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry. +

+

The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does not need to be “executed” in +every action bound to the table. It is an error to provide a direct resource +configuration in a TableEntry message when programming an action that does not +execute the direct resource, and the server must return an INVALID_ARGUMENT +error code. +

+

We leverage Protobuf's ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the TableEntry message. The list below describes how +the server must handle the meter_config, counter_data and +meter_counter_data fields for read and write requests, based on whether the +fields are set or not. We do not cover error cases in the list, i.e. we assume +that we are dealing with a table which is assigned a direct counter / a direct +meter, and that the action being used for the table entry “executes” the direct +resource appropriately. +

+
    +
  • +

    meter_config field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets). +
      • +
      • if set: The initial configuration for the meter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The meter entry's configuration is reset to the default +(meter returns GREEN for all packets). +
      • +
      • if set: The value provided by the client is used to re-configure +the meter entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the meter entry's +configuration (meter_config is unset in the response). +
      • +
      • if set: If the meter entry's configuration is the default +configuration, meter_config is unset in the response. Otherwise, the +response includes the meter entry's configuration that was written by +the client earlier. This respects the “read-write symmetry” principle. +
    +
  • +
  • +

    counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for the counter entry is the default +(0). +
      • +
      • if set: The initial value for the counter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The counter entry's value is not changed. +
      • +
      • if set: The value provided by the client is written to the counter +entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the counter entry's value +(counter_data is unset in the response). +
      • +
      • if set: The response includes the counter entry's value read from +the target. +
    +
  • +
  • +

    meter_counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for all 3 counter entries is the +default (0). +
      • +
      • if set: The initial value for all 3 counter entries is the +default (0). Sub-field, if any, can only have zero (0) as its value. +INVALID_ARGUMENT error is returned for any non-zero sub-field value. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: All the 3 counter entries are unchanged. +
      • +
      • if set: All the 3 counters are reset to 0. Sub-field, if any, can +only have zero (0) as its value. INVALID_ARGUMENT error is returned +for any non-zero sub-field value. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include counter values +(meter_counter_data is unset in the response). +
      • +
      • if set: The response includes all the 3 counter values read from +the target. +
    +
+ +

In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +meter_config field unset when inserting or modifying a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the TableEntry message +(i.e. the meter_config field must be set to match the existing configuration). +

9.1.7. Idle-timeout

+

P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not “hit” (i.e. not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification using the +IdleTimeoutNotification message to the primary client, which can then take +action, such as remove the idle table entry. +

+

Two fields of the TableEntry Protobuf message are used to implement idle +timeout: +

+
    +
  • +

    idle_timeout_ns: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, i.e. no +IdleTimeoutNotification message will ever be generated for this entry. When +a client reads a TableEntry, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry. +

  • +
  • +

    time_since_last_hit: a Protobuf message with a single field (elapsed_ns) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The time_since_last_hit field must be unset for a +TableEntry write. When reading a table entry, time_since_last_hit must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0. +

+ +

These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an INVALID_ARGUMENT error code if at least one of these +conditions is met: +

+
    +
  • idle_timeout_ns is set to a non-zero value, or +
  • +
  • time_since_last_hit is set +
+ +

The target should do its best to approximate the idle_timeout_ns value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the TableEntry write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for time_since_last_hit. +

+

P4Runtime does not support idle timeout for default entries. When the +is_default_action flag is set in a TableEntry message, idle_timeout_ns +must be set to 0 (default) and time_since_last_hit must be unset. If the +server receives a TableEntry message which violates this, it must return an +INVALID_ARGUMENT error. +

+

For more information about idle timeout, in particular regarding +IdleTimeoutNotification, please refer to the Table idle timeout +notifications section. +

9.2. ActionProfileMember & ActionProfileGroup

+

P4Runtime defines an API for programming a PSA ActionProfile extern using +ActionProfileMember messages. A PSA ActionSelector extern can be programmed +using both ActionProfileMember and ActionProfileGroup messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table t for L3 routing, implemented with an action +selector as. +

+
+
+
ActionSelector(HashAlgorithm.crc32,
+               /*size = */ 32w1024,
+               /*output_width = */ 32w10) as;
+
+action set_nhop(PortId_t p, EthAddr smac, EthAddr dmac) {
+  istd.egress_port = p;
+  hdr.ethernet.smac = smac;
+  hdr.ethernet.dmac = dmac;
+}
+
+table t {
+  key = {
+    hdr.ipv4.dip: lpm;  // LPM on destination IP address
+  }
+  actions = {
+    set_nhop;
+  }
+  implementation = as;
+}
+

When programming table t in the example above, a P4Runtime client should +specify the TableAction in the TableEntry to be a reference to either an +action profile member or group. The reference is a non-zero uint32 identifier +that uniquely identifies a member or group programmed in the action selector +as. +

+

If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata. +

+

If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata. +

9.2.1. Action Profile Member Programming

+

Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a uint32 identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the actions +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the actions attributes of the +tables must have an identical list of P4 actions. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector. +

+

An ActionProfileMember entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info. +

  • +
  • +

    member_id is the non-zero uint32 identifier of the action profile member +entry being updated. +

  • +
  • +

    action is the specification of the P4 action instance bound to the action +profile member entry. +

+ +

An action profile member may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an ALREADY_EXISTS error +code. The action specification must be provided, or the server must return +INVALID_ARGUMENT. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return RESOURCE_EXHAUSTED. +
  • +
  • MODIFY: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return NOT_FOUND, +and the action specification must be provided, or the server must return +INVALID_ARGUMENT. +
  • +
  • DELETE: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a NOT_FOUND error code. The member +must not be part of an action profile group, or the server must return +FAILED_PRECONDITION. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return FAILED_PRECONDITION. action_profile_id and member_id are the only +fields that are considered when performing a DELETE and every other field +will be ignored. +
+ +

When reading, an ActionProfileMember message with action_profile_id and +member_id equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with action_profile_id equal to the id of +an existing ActionProfile or ActionSelector object, and a member_id equal to +0, will read all members of that specified object. +

9.2.2. Action Profile Group Programming

+

Action profile groups are entries in an ActionSelector and are referenced by a +uint32 identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type. +

+

Within a single ActionSelector object, the uint32 values used to identify its +members are in a separate ‘scope’ from the uint32 values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5. +

+

There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it. +

+

An ActionProfileGroup entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionSelector +extern instance, as defined in P4Info. +

  • +
  • +

    group_id is the non-zero uint32 identifier of the action profile group +entry being updated. +

  • +
  • +

    members is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields: +

    +
      +
    • member_id for looking up the member table in the selector. +
    • +
    • weight specifying the probability of the member's selection at +runtime. 0 is not a valid weight value and the server must return +INVALID_ARGUMENT if the client attempts to use it. +
    • +
    • watch_port is the controller-defined port that the member's +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +9.2.4 for notes on the behavior if all members in +a group are excluded for this reason. If watch_port is empty, then the +member is always included in the selection, regardless of the status of +any port of the device. The value must be empty or the SDN port of an +existing port on the device, otherwise the server must return +INVALID_ARGUMENT. +
    +
  • +
  • +

    max_size is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +MODIFY update. See the subsection below for the rules on setting +max_size. +

+ +

An action profile group may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new group entry bound to a set of existing action profile +members. The group_id must be different from ids of already programmed +groups for that selector, or the server must return an ALREADY_EXISTS error +code. All members specified in the group must exist in the selector, or the +server must return NOT_FOUND. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target. +
  • +
  • MODIFY: Modify the member set specification of an existing group entry. An +entry with the group_id must exist, or the server must return +NOT_FOUND. All members specified in the group entry must exist in the +selector, or the server must return NOT_FOUND. The value of max_size must +be identical to the value used when inserting the group, otherwise an +INVALID_ARGUMENT error is returned. +
  • +
  • DELETE: Delete the group entry and deallocate the group_id. The group must +not be referenced in the table action of any table entry, or the server must +return a FAILED_PRECONDITION error code. If the group_id is invalid, the +server must return NOT_FOUND. action_profile_id and group_id are the +only fields that are considered when performing a DELETE and every other +field will be ignored. +
+ +

When setting the group membership with INSERT or MODIFY, the members +repeated field must not include duplicates, i.e. members with the same +member_id. The weight field is used instead to logically “repeat” the member +inside the group. +

+

It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation “stores” the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made. +

+

When reading, an ActionProfileGroup message with action_profile_id and +group_id equal to 0 will read all groups of all ActionSelector objects. A +message with action_profile_id equal to the id of an existing ActionSelector +object, and a group_id equal to 0, will read all groups of that one specified +object. +

9.2.2.1. Rules on Setting max_size
+

The valid values for max_size depend on the static max_group_size included +in the P4Info message: +

+
    +
  • +

    If max_group_size is greater than 0, then max_size must be greater than 0, +and less than or equal to max_group_size. We assume that the target can +support selector groups for which the sum of all member weights is up to +max_group_size, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If max_size is greater than max_group_size, the server +must return INVALID_ARGUMENT. +

  • +
  • +

    Otherwise (i.e. if max_group_size is 0), the P4Runtime client can set +max_size to any value greater than or equal to 0. +

    +
      +
    • +

      A max_size of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (INSERT or MODIFY), the target must return a +RESOURCE_EXHAUSTED error. +

    • +
    • +

      If max_size is greater than 0 and the value is not supported by the +target, the server must return a RESOURCE_EXHAUSTED error at +group-creation time. +

    +
+

9.2.3. One Shot Action Selector Programming

+

P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids. +

+

One shots are programmed by choosing the ActionProfileActionSet message as the +TableAction. The ActionProfileActionSet message consists of a set of +ActionProfileAction messages, which in turn have the following fields: +

+
    +
  • +

    action is one of the actions specified by the table that is being +programmed. +

  • +
  • +

    weight specifying the probability of the action's selection at runtime. 0 is +not a valid weight value and the server must return INVALID_ARGUMENT if +the client attempts to use it. The sum of all weights across all +ActionProfileAction messages for that ActionProfileActionSet message must +not exceed the max_group_size specificed in the P4Info (if greater than 0), +or the server must return INVALID_ARGUMENT. +

  • +
  • +

    watch_port is the controller-defined port that the action's liveness depends +on. At runtime, the action must be excluded from selection if the watch port +is down. See Section 9.2.2 for more details +on the watch_port field, which also apply for one shot action selector +programming. +

+ +

Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics. +

+

To preserve read-write symmetry, an implementation must answer ReadRequests +with the original one shot messages. It may not return a desugared version of +the one shot message. +

+

For example, consider the action selector table defined +here. This table could be programmed +with the following one shot update: +

+
+
+
table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action {
+    action_profile_action_set {
+      action_profile_actions {
+        action { /* set nexthop 1 */ }
+        weight: 1
+        watch_port: "\x01"
+      }
+      action_profile_actions {
+        action { /* set nexthop 2 */ }
+        weight: 2
+        watch_port: "\x02"
+      }
+      action_profile_actions {
+        action { /* set nexthop 3 */ }
+        weight: 3
+        watch_port: "\x03"
+      }
+    }
+  }
+}
+

Which would be equivalent to the following updates, where GROUP_ID, +MEMBER_ID_1, MEMBER_ID_2, and MEMBER_ID_3 are unused ids: +

+
+
+
action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_1
+  action { /* set nexthop 1 */ }
+}
+action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_2
+  action { /* set nexthop 2 */ }
+}
+action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_3
+  action {  /* set nexthop 3 */ }
+}
+action_profile_group {
+  action_profile_id: 0x11ab12cd
+  group_id: GROUP_ID
+  members {
+    member_id: MEMBER_ID_1
+    weight: 1
+    watch_port: "\x01"
+  }
+  members {
+    member_id: MEMBER_ID_2
+    weight: 2
+    watch_port: "\x02"
+  }
+  members {
+    member_id: MEMBER_ID_3
+    weight: 3
+    watch_port: "\x03"
+  }
+}
+table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action { action_profile_group_id: GROUP_ID }
+}
+

Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure correct ordering between the dependent +updates. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct WriteRequest batches are required. +

+

It is possible to include several ActionProfileAction messages with the same +exact action specification in one ActionProfileActionSet message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the weight field. Note that to preserve read-write symmetry, the server +must not coalesce multiple ActionProfileAction messages with the same action +specification into one. +

+

All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with ActionProfileMember and +ActionProfileGroup messages. Programming some entries with one shots, and +other entries with ActionProfileMember and ActionProfileGroup messages is +not allowed, and the server must return the error code INVALID_ARGUMENT in +that case. +

+

A P4Runtime server must support the one shot style of programming tables with +an action selector implementation. Support for the ActionProfileMember and +ActionProfileGroup style is optional. If ActionProfileMember and +ActionProfileGroup are not supported by a server, it must return an +UNIMPLEMENTED error for every ActionProfileMember or ActionProfileGroup +message that it receives. +

9.2.4. Constraints on action selector programming

+

The PSA specification states that the following features are optional in +action selector implementations [22]: +

+
    +
  1. Support for non-empty groups where in the same group, different members are +bound to different actions. +
  2. +
  3. Predictable data plane behavior when a matched table entry points to an empty +group. +
+ +

For 1., if a client tries to INSERT or MODIFY a group with members bound to +different actions, the server should return UNIMPLEMENTED if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return UNIMPLEMENTED (modifying the action parameter values must be +supported, however). +

+

PSA 1.1 introduces the psa_empty_group_action table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. psa_empty_group_action is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of psa_empty_group_action at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +NoAction. Even when psa_empty_group_action is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of psa_empty_group_action mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming. +

+

The PSA specification includes a discussion on how to implement +psa_empty_group_action in software in the P4Runtime server +[25]. +

+

If a P4Runtime implementation does support psa_empty_group_action, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down. +

+

If a P4Runtime implementation does not support psa_empty_group_action, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down. +

9.3. CounterEntry & DirectCounterEntry

+

PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The CounterData +P4Runtime message can be used for all three types of PSA counters PACKETS, +BYTES and PACKETS_AND_BYTES and consists of the following fields: +

+
    +
  • byte_count is an int64, corresponding to the number of octets. +
  • +
  • packet_count is an int64, corresponding to the number of packets. +
+ +
+
+
message CounterData {
+  int64 byte_count = 1;
+  int64 packet_count = 2;
+}
+

P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of byte_count and packet_count fields, which +is equivalent to specifying the counter type PACKETS_AND_BYTES. Counters may +be defined as direct or indirect (indexed) instances. +

9.3.1. DirectCounterEntry

+

A direct counter is a direct resource associated with a TableEntry (see +Direct Resources). The counter_data field of the +TableEntry message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +DirectCounterEntry message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed. +

+
+
+
message DirectCounterEntry {
+  TableEntry table_entry = 1;
+  CounterData data = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectCounterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match TableEntry.match of the table entry +to which this direct counter entry is associated. If a matching TableEntry +is not found, the server returns the error code NOT_FOUND. +

  • +
  • +

    data is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified. +

+ +

Specifying DirectCounterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read the contents of a +DirectCounter: +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the counter value in the counter_data field of the TableEntry message +(see Direct resources). +

  • +
  • +

    Explicitly request the counter value by including the DirectCounterEntry in +the ReadRequest. The table_entry.match field must match the TableEntry +whose counter is being read. If no such entry is found, the server returns the +error code NOT_FOUND. +

+

9.3.2. CounterEntry

+

An indirect or indexed counter is not associated with a specific TableEntry +and may be updated independently of any action. It may be read or written using +the P4Runtime CounterEntry message whose fields are defined as follows: +

+
    +
  • +

    counter_id is a uint32, the unique identifier for the counter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +the counter array. +

  • +
  • +

    data is a Protobuf message of type CounterData, which represents the +counter value. +

+ +
+
+
message CounterEntry {
+  uint32 counter_id = 1;
+  Index index = 2;
+  CounterData data = 3;
+}
+

The CounterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the counter entries in the +array have default value 0. +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect counter instance whose unique id is counter_id +and array index is specified by index. The counter value is set to the value +specified by the client in the data field. Note that the counter value is +not modified if this Protobuf field is not set. If index is omitted all +counter values in the array will be set to the value provided by the +client. The server must return INVALID_ARGUMENT for a negative index value +and OUT_OF_RANGE if the index value exceeds the size of the counter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a ReadRequest by including a CounterEntry +entity for each of the instances, specifying the counter_id and +index. Wildcard reads are also supported as follows. +

+
    +
  • +

    If the counter_id field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id counter_id. +

+

9.4. MeterEntry & DirectMeterEntry

+

Meters are an advanced mechanism for keeping statistics, involving stateful +“marking” and usually “throttling” of packets based on configured rates of +traffic. The PSA metering function is based on the Two Rate Three Color Marker +(trTCM) defined in RFC 2698 [2]. The trTCM meters an arbitrary packet +stream using two configured rates the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes and +“marks” its packets as GREEN, YELLOW or RED based on the observed rate. +

+

MeterEntry & DirectMeterEntry have an additional field counter_data that +may hold per color counter data for targets that support it, and that must +always be unset for targets that do not support it. If set in a request and +unsupported by a target, an UNIMPLEMENTED error code should be returned. +These counters provide a granular list of the counters applicable to the +possible meter colors GREEN, YELLOW and RED. The counter associated with a +specific color is incremented when a packet is “marked” with that color. The +primary purpose of the color counters is for debugging purposes. +

+

A meter may be configured as a direct or indirect instance, similar to a +counter. The MeterConfig P4Runtime message represents meter configuration. +

+
+
+
message MeterConfig {
+  int64 cir = 1;  // Committed Information Rate
+  int64 cburst = 2;  // Committed Burst Size
+  int64 pir = 3;  // Peak Information Rate
+  int64 pburst = 4;  // Peak Burst Size
+}

9.4.1. DirectMeterEntry

+

A direct meter is a direct resource associated with a TableEntry (see Direct +resources). The meter_config field of the TableEntry +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +DirectMeterEntry message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed. +

+
+
+
message DirectMeterEntry {
+  TableEntry table_entry = 1;
+  MeterConfig config = 2;
+  MeterCounterData counter_data = 3;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectMeterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match the match key of the TableEntry +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching TableEntry is not found, +the server returns the error code NOT_FOUND. +

  • +
  • +

    config is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets). +

  • +
  • +

    counter_data is used to set the per color counter values to the default +value of (0), which is essentially clearing the counters. If the field is +unset, the counter values are left untouched. If the field is set, targets +supporting these counters should reset all the color counters to (0), if any +of the sub-fields are set to a non-zero value, then an INVALID_ARGUMENT +error should be returned. +

+ +

Specifying DirectMeterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read a DirectMeter config. +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the meter config in the meter_config field of the TableEntry +message (see Direct resources). +

  • +
  • +

    Explicitly request the meter configuration by including the DirectMeterEntry +in the ReadRequest. The table_entry.match field must match the +TableEntry whose meter config is being read. If no such entry is found, the +server returns the error code NOT_FOUND. Read responses also include the +per color counter data for the meter entry, if supported and specified in +the request message. +

+

9.4.2. MeterEntry

+

An indirect or indexed meter is not associated with a specific TableEntry and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime MeterEntry message whose fields are defined as +follows: +

+
    +
  • +

    meter_id is a uint32, the unique identifier for the meter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +a meter array. +

  • +
  • +

    config is a Protobuf message of type MeterConfig, which represents the +meter configuration. +

  • +
  • +

    counter_data is a Protobuf message of type MeterCounterData, which +represents the per color counter values associated with the corresponding +meter. +

+ +
+
+
message MeterEntry {
+  uint32 meter_id = 1;
+  Index index = 2;
+  MeterConfig config = 3;
+  MeterCounterData counter_data = 4;
+}
+

The MeterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the meter entries in the +array have a default configuration (GREEN for all packets). +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect meter instance whose unique id is meter_id and +array index is specified by index. The meter is reconfigured using the +config field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the index field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if config is unset). The server must return INVALID_ARGUMENT for a +negative index value and OUT_OF_RANGE if the index value exceeds the size of +the meter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a ReadRequest by including a MeterEntry entity for each +of the instances, specifying the meter_id and index. Wildcard reads are also +supported as follows: +

+
    +
  • +

    If the meter_id field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the ReadResponse. +

  • +
  • +

    If the index field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id meter_id. +

+

9.4.3. MeterCounterData

+

The MeterCounterData P4Runtime message represents the per color counters +associated with a meter entry. Whenever a meter is executed and returns +a color, the corresponding color counter GREEN, YELLOW or RED is updated. +

+

As seen above, these counters can be associated with a DirectMeterEntry or +MeterEntry. Targets not capable of supporting these counters should return +UNIMPLEMENTED if a MeterCounterData field was set in a read or write +request. +

+
+
+
message MeterCounterData {
+  CounterData green = 1;
+  CounterData yellow = 2;
+  CounterData red = 3;
+}

9.5. PacketReplicationEngineEntry

+

The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets. +

9.5.1. MulticastGroupEntry

+

Multicasting is achieved in PSA programs by setting the multicast_group +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the MulticastGroupEntry API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example. +

+
+
+
control arp_multicast(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ethernet.isValid() &&
+        hdr.ethernet.eth_type == ETH_TYPE_ARP) {
+      smeta.multicast_group = (MulticastGroup_t) 1;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    multicast_group_entry {
+      multicast_group_id: 1
+      replicas { egress_port: 5 instance: 1 }
+      replicas { egress_port: 12 instance: 2 }
+      replicas { egress_port: 18 instance: 3 }
+      replicas { egress_port: 24 instance: 4 }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +PSA Metadata Translation section. +

+

The egress packets may be distinguished for further processing in the egress +using the instance metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 multicast_group metadata is set to a value that is not +programmed in the PRE, then the packet is dropped. +

+

A multicast group may be inserted, modified or deleted as per the following +semantics. +

+
    +
  • INSERT: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The multicast_group_id field is a uint32 and must be greater +than 0 (see explanation below), or the +P4Runtime server must return an INVALID_ARGUMENT error. The replica +instance ID is also a uint32, and its value may not exceed the maximum +allowed by the target for the EgressInstance_t type (0 is allowed), or the +server must return an INVALID_ARGUMENT error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of both egress_port and instance, or the server +must return INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify the set of replicas for a given multicast group entry, +indexed by the given multicast_group_id. Same restrictions as INSERT apply +here. +
  • +
  • DELETE: Delete the multicast group indexed by the given +multicast_group_id. The replicas need not be provided for this +operation. Any packets with their multicast_group metadata in the data plane +set to the deleted multicast_group_id will be dropped. +
+ +

When reading a multicast group, only multicast_group_id is considered. All +other fields in MulticastGroupEntry are ignored. To perform a wildcard +Read on all configured multicast group entries, the multicast_group_id field +must be set to 0, its default value. +

9.5.1.1. Valid Values for multicast_group_id
+

The PSA specification states that the valid data plane values for multicast +group ids (MulticastGroup_t) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target [24]. This means that, in the absence of +translation, the client must set the multicast_group_id field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special wildcard value which is used to read all the multicast groups +configured in the target, the multicast_group_id field must never be set to 0 +when performing a Write RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value. +

9.5.2. CloneSessionEntry

+

PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +clone_session_id identifier and a boolean flag clone in the packet +metadata. The clone_session_id serves as a handle to the clone attributes, +namely a set replicas of (egress port, instance) pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +CloneSessionEntry API. +

+

The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the clone_low_ttl control block is applied in the ingress +pipeline to create an ingress-to-egress clone. +

+
+
+
control clone_low_ttl(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ipv4.isValid() &&
+        hdr.ipv4.ttl <= LOW_TTL_THRESHOLD) {
+      smeta.clone_session_id = 10w100;
+      smeta.clone = true;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    clone_session_entry {
+      session_id: 100
+      replicas { egress_port: 0xfffffffd instance: 1 } # to CPU
+      class_of_service: 2
+      packet_length_bytes: 4096
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type CloneSessionId_t [24]). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes. +

+

The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port 0xfffffffd; see +Translation of Port Numbers). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port. +

+

If the clone_session_id data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created. +

+

A clone session may be inserted, modified or deleted as per the following +semantics: +

+
    +
  • INSERT: Add a new clone session entry bound to a set of egress ports and +replica IDs. The session_id is a uint32 and must be greater than 0 (see +explanation below), or the P4Runtime +server must return an INVALID_ARGUMENT error. The replica instance ID is +also a uint32, and its value may not exceed the maximum allowed by the +target for the EgressInstance_t type (0 is allowed), or the server must also +return an INVALID_ARGUMENT error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (class_of_service field). This value must be a valid +value for the PSA ClassOfService_t type, which supports runtime translation +by default [24], or the server must return +INVALID_ARGUMENT. See PSA Metadata +Translation for more information. The +packet_length_bytes field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +packet_length_bytes field is 0 (default), no truncation on the clone will be +performed. +
  • +
  • MODIFY: Modify the attributes of a given clone session entry, indexed by the +given clone_session_id. Same restrictions as INSERT apply here. +
  • +
  • DELETE: Delete the clone session indexed by the given +clone_session_id. Other fields need not be provided for this operation. Any +packet with their clone_session_id metadata in the data plane set to the +deleted session_id will no longer be cloned. +
+ +

When reading a clone session, only session_id is considered. All other fields +in CloneSessionEntry are ignored. To perform a wildcard Read on all +configured clone session entries, the session_id field must be set to 0, its +default value. The session_id field can never be equal to 0 in a Write +RPC. If it does, the server must return an INVALID_ARGUMENT error. +

9.5.2.1. Valid Values for session_id
+

The PSA specification states that the valid data plane values for clone +session ids (CloneSessionId_t) range from 0 to the maximum value supported by +the target [24]. Note that unlike for multicast group +ids, 0 is a valid data plane value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special wildcard value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a session_id +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is not enabled, we effectively +“lose” one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (e.g. because the target supports a very +limited number of clone sessions), one can enable translation on +CloneSessionId_t and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id. +

9.6. ValueSetEntry

+

Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the parse_trill_types state. +

+
+
+
state parse_l2 {
+  @id(1) value_set<ETH_TYPE_BITWIDTH>(MAX_TRILL_TYPES) trill_types;
+  extract(hdr.ethernet);
+  select (hdr.ethernet.eth_type) {
+    ETH_TYPE_IPV4: parse_ipv4;
+    ETH_TYPE_IPV6: parse_ipv6;
+    trill_types:   parse_trill_types;
+    _:             reject;
+  }
+}
+

The corresponding entry in the P4Info for this Value Set is: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "trill_types"
+  }
+  match {
+    id: 1
+    bitwidth: <ETH_TYPE_BITWIDTH>
+    match_type: EXACT
+  }
+  size: <MAX_TRILL_TYPES>
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0x22f3 }
+      }
+      match {
+        field_id: 1
+        exact { value: 0x893b }
+      }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the parse_trill_types state. +

+

A ValueSetEntry entity update message has the following fields: +

+
    +
  • +

    value_set_id is the uint32 identifier of the Value Set instance, as +defined in P4Info. +

  • +
  • +

    members is a repeated field of type ValueSetMember. When “selecting” +against a Value Set, every member will be considered and if at least one +“matches”, the corresponding parser transition will be taken. Each +ValueSetMember contains a repeated field of FieldMatch messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a ValueSetMember if and only if +it matches all its FieldMatch messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. FieldMatch messages in a ValueSetEntry follow +the same rules as in a TableEntry. +

+ +

A ValueSetEntry may only be modified. If the update type is INSERT or +DELETE, the server must return an INVALID_ARGUMENT error. If the update type +is MODIFY, the server writes the members given in the repeated field to the +Value Set entry indexed by the given value_set_id. The maximum number of +matches must not exceed the maximum size given by the size field in P4Info of +the Value Set, otherwise the server must return a RESOURCE_EXHAUSTED error. To +empty a Value Set (i.e. restore it to its initial state), the P4Runtime client +can perform a MODIFY update with an empty members repeated field. +

+

To facilitate read-write symmetry, the server must +return an ALREADY_EXISTS error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set. +

+

See Appendix A.3 for a more complex Value Set example. +

9.7. RegisterEntry

+

The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The RegisterEntry P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations. +

+

RegisterEntry has the following fields: +

+
    +
  • +

    register_id, which identifies the PSA Register extern instance which is +being accessed by the client; the register_id is specified by the P4Info +message. +

  • +
  • +

    index, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the RegisterEntry message +used for the request. When an index is provided , the server must validate +its value, and return INVALID_ARGUMENT for a negative index or +OUT_OF_RANGE if the index exceeds the size of the register array. +

  • +
  • +

    data: the data to be written to the array (if RegisterEntry is part of a +WriteRequest message) or the data read from the array (if RegisterEntry is +part of a ReadResponse message). The data field is a P4Data message and +must match the format described by the type_spec field of the corresponding +Register entry in the P4Info, or the server must return an INVALID_ARGUMENT +error. +

+

9.8. DigestEntry

+

A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly. +

+

The DigestEntry P4Runtime entity is used to configure how the device must +generate digest messages. The DigestEntry Protobuf message is not used to +carry digest data, which is done on the StreamChannel bidirectional stream +using the DigestList (digest data sent by the target to the client) and +DigestListAck (digest data acknowledgments sent by the client to the target) +Protobuf messages. +

+

In this section, we refer to the data learned by a single data plane call to +Digest<T>::pack as a “digest message” and we use “digest list” to designate +the list of digest messages bundled by the P4Runtime service in a single +DigestList stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are “duplicate” if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are “distinct” +if they are not duplicate. +

+

DigestEntry has the following fields: +

+
    +
  • +

    digest_id, which identifies the PSA Digest extern instance which emitted the +data; the digest_id is determined by the P4Info message. +

  • +
  • +

    config, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +digest_id; these parameters are: +

    +
      +
    • max_timeout_ns: the maximum server buffering delay in nanoseconds for an +outstanding digest message. +
    • +
    • max_list_size: the maximum digest list size in number of digest +messages sent by the server to the client as a single DigestList +Protobuf message. +
    • +
    • ack_timeout_ns: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data. +
    +
+ +

Here is the significance of the different Update types for DigestEntry: +

+
    +
  • INSERT: Enable server generation of DigestList messages for given digest +instance and use provided configuration parameters. +
  • +
  • MODIFY: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance. +
  • +
  • DELETE: Disable server generation of DigestList messages for given digest +instance. +
+ +

A server should buffer digest messages until either: +

+
    +
  • max_timeout_ns time has passed since the first digest message was added to +the empty buffer, or +
  • +
  • max_list_size distinct digest messages have been received from the +data plane and added to the buffer +
+ +

At which point the server should, with best effort, generate a DigestList +stream message with the buffer contents and send it to the primary client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software. +

+

To avoid sending duplicate digest messages across different DigestList +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the primary client indicates that it has received the +digest list and acted on it. The server must keep a “cache” containing the set +of all digest messages that have been sent, but not acknowledged yet by the +primary client, up-to ack_timeout_ns in the past. The server must delete all +cache entries for a given digest list when they are at least ack_timeout_ns +old or when a matching DigestListAck message (i.e. with the same digest_id +and list_id fields as the DigestList message) is received. +

+

The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged DigestList messages. +

+

When max_timeout_ns is set to 0 and / or max_list_size is set to 1, the +server should, with best effort, generate a DigestList message for every +digest message generated by the data plane which is not already in the cache. If +ack_timeout_ns is set to 0, the cache must always be an empty set. If +max_list_size is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +max_timeout_ns configuration parameter. +

+

The P4Runtime server may empty the digest message cache in case of a client +status change. +

+

Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server: +

+
+
+
DigestStream stream;
+DigestCache cache;
+DigestBuffer buffers;
+
+// sends digest list when it is ready
+send_buffer(Id digest_id) {
+  buffer = buffers[digest_id];
+  stream.write(DigestList(buffer));
+  cache.merge(buffer);  // updates cache with new digest list
+  buffer.clear();
+}
+
+// callback which handles data plane digest messages from device
+handle_dataplane_digest(Digest msg) {
+  digest_id = msg.digest_id();
+  buffer = buffers[digest_id];
+  if (msg in cache OR msg in buffer) return;
+  buffer.enqueue(msg);
+  if (buffer.length() < max_list_size(digest_id)) return;
+  send_buffer(digest_id);
+}
+
+// callback which handles ack messages received on the stream
+handle_stream_ack(DigestListAck ack) {
+  // clear all cache entries matching the tuple (digest_id, list_id)
+  cache.erase( (ack.digest_id(), ack.list_id() )
+}
+
+// loop to enforce timeouts
+while (true) {
+  now = now();
+  // check for buffers that need to be sent
+  for ((digest_id, buffer) in buffers) {
+    if (now - buffer.first_enq_time() >= max_timeout_ns(digest_id))
+      send_buffer(buffer_id);
+  }
+  // check for expired entries in cache
+  for ((digest_id, list_id, sent_time) in cache) {
+    if (now - sent_time >= ack_timeout_ns(digest_id))
+      cache.erase( (digest_id, list_id) );
+  }
+  sleep(X);
+}

9.9. ExternEntry

+

This is used to support a P4 extern entity that is not part of PSA. It is +defined as: +

+
+
+
message ExternEntry {
+  uint32 extern_type_id = 1;
+  uint32 extern_id = 2;
+  google.protobuf.Any entry = 3;
+}
+

Each ExternEntry entity maps to an Extern message in the +P4Info and an ExternInstance message within that +message. The extern_type_id field must be equal to the one in +ExternEntry. The extern_id field must be equal to the ID included in the +preamble of the corresponding ExternInstance message. +

+

entry itself is embedded as an Any Protobuf message [31] to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on Extending P4Runtime for non-PSA +Architectures for more information. +

10. Error Reporting Messages

+

P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case. +

+

gRPC uses grpc::Status [32] to represent the status returned by an +RPC. It has 3 attributes: +

+
+
+
StatusCode code_;
+grpc::string error_message_;
+grpc::string binary_error_details_;
+

The code_ represents a canonical error [34] and describes the +overall RPC status. The error_message_ is a developer-facing error message, +which should be in English. The binary_error_details_ carries a serialized +google.rpc.Status message [28] message, which has 3 fields: +

+
+
+
int32 code = 1;  // see code.proto
+string message = 2;
+repeated google.protobuf.Any details = 3;
+

The code and message fields must be the same as code_ and error_message_ +fields from grpc::Status above. The details field is a list that consists of +p4.Error messages that carry error details for individual elements inside +batch-request RPCs (e.g. Write and Read). p4.Error includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices [34]. +

+

Figure 7 illustrates how these messages fit together. +

+
+

error-report +

+
+ +
Figure 7. P4Runtime Error Report Message Format
+

gRPC provides utility functions ExtractErrorDetails() and SetErrorDetails() +[33] to easily convert between grpc::Status and +google.rpc.Status. +

+

Please see sections on individual P4Runtime RPCs for details on how +grpc::Status is populated for reporting errors. +

+

Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on Stream Error +Reporting for more information. +

11. Atomicity of Individual Write and Read Operations

+

Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane apply +operation, and every single Write operation on a table that inserts, deletes, +or modifies one table entry, the apply operation should behave as if that +Write operation has not yet occurred, or as if the Write operation is +complete. The P4 program should never behave as if the Write operation is +partially complete. These guarantees also apply to extern instances: Read and +Write operations on extern entities must execute atomically relative to extern +data plane methods. +

+

The atomicity guarantees provided by P4Runtime for individual Read and Write +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification [23]. +

+

The P416 language introduces an @atomic annotation [14], to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the @atomic annotation for Write +operations, as well as non-wildcard Read operations, +relative to data plane execution. Consider the following P4 example written for +PSA: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024) r1;
+
+  apply {
+    // ...
+    @atomic {
+        Value_t v = r1.read((Index_t)1);
+        v = v + 1;
+        r1.write((Index_t)1, v);
+    }
+  }
+}
+

If a P4Runtime server is processing messages which write to Register r1 at +index 1, these writes must not happen between the data plane read and +write. +

+

Now let's consider the following example: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024, (Value_t)0 /* initial value */) r1;
+
+  apply {
+    @atomic {
+        r1.write((Index_t)1, (Value_t)100);
+        r1.write((Index_t)2, (Value_t)100);
+    }
+    @atomic {
+        r1.write((Index_t)1, (Value_t)200);
+        r1.write((Index_t)2, (Value_t)200);
+    }
+  }
+}
+

If a P4Runtime client issues a wildcard Read on Register r1, there is no +guarantee that r1[1] == r1[2] in the response, as the read for r1[1] may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for r1[2] may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read r1[1] and r1[2] separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +ReadRequest message) of individual read requests. Similar to a batch +ReadRequest, a wildcard read of a register can execute the reads of the +register array elements (r1[1], r1[2], ) in an arbitrary order relative +to each other. +

+

If the @atomic annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program. +

12. Write RPC

+

The Write RPC updates one or more P4 entities on the target. The request is +defined as follows: +

+
+
+
message WriteRequest {
+  uint64 device_id = 1;
+  string role = 6;
+  Uint128 election_id = 3;
+  repeated Update updates = 4;
+  enum Atomicity {
+    CONTINUE_ON_ERROR = 0;
+    ROLLBACK_ON_ERROR = 1;
+    DATAPLANE_ATOMIC = 2;
+  }
+  Atomicity atomicity = 5;
+}
+

The device_id uniquely identifies the target P4 device. The role and +election_id define the client role and election-id as described in the +Primary-Backup Arbitration and Controller +Replication +section. The server is expected to perform the following checks (in this order) +before processing the updates list: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the primary for (device_id, role) according to +the election_id value, the server must return a PERMISSION_DENIED error. +

  4. +
  5. +

    If the Write is attempted before a ForwardingPipelineConfig has been set, +the server must return a FAILED_PRECONDITION error. +

+ +

The updates field is a list of P4 entity updates to be applied. Each update is +defined as: +

+
+
+
message Update {
+  enum Type {
+    UNSPECIFIED = 0;
+    INSERT = 1;
+    MODIFY = 2;
+    DELETE = 3;
+  }
+  Type type = 1;
+  Entity entity = 2;
+}
+

This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a logical table (e.g. +CounterEntry) or an actual table (e.g. TableEntry) in the P4 data +plane. Each entity in the container is uniquely identified by its key. Please +refer to the P4 Entity Messages section for details on +what parts of the entity specification make up the key for each P4 entity. +

+

An update can be one of the following types: +

+
    +
  • +

    INSERT: Inserts the given P4 entity in the entity container. +The entity field always specifies the full state of the P4 entity. +If the entity already exists, an ALREADY_EXISTS error is returned, and +the existing entity remains unchanged. If the entity is malformed, an +INVALID_ARGUMENT error is usually returned (unless a more specific error +code applies [34]). If the entity cannot be inserted because the +container is already full, a RESOURCE_EXHAUSTED error is returned. +

  • +
  • +

    MODIFY: Modifies the P4 entity to its new specified state. This uses +assign or full-snapshot semantics, i.e. the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an INVALID_ARGUMENT error is usually returned (unless a +more specific error code applies [34]). If the entity does not +exist, a NOT_FOUND error is returned. +

  • +
  • +

    DELETE: Deletes the specified P4 entity. If the entity does not exist, a +NOT_FOUND error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored. +

+ +

If an update is not allowed under the given controller role, the server must +return a PERMISSION_DENIED error for this update. +

12.1. Batching and Ordering of Updates

+

P4Runtime supports batching of Write operations. The list of updates in a +WriteRequest is referred to as a batch. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of TableEntry entities). +

+

The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +WriteRequests can also be processed interleaved and/or in parallel. +However, the processing of requests must be strictly serializable. That +is, given a history $S$ of WriteRequests including the responses to those +requests, there must exist an order $L$ for all updates in $S$, such that: +

+
    +
  1. All updates from the same write request must appear as a contiguous +subsequence in $L$, but the order within that subsequence can be arbitrary. +
  2. +
  3. For two updates $u_1$ and $u_2$, if the write request containing $u_1$ +completed before the write request of $u_2$ was sent, then $u_1$ must appear +before $u_2$ in $L$. +
  4. +
  5. Executing all updates in $L$ sequentially must yield the same response for +every update as in $S$. +
  6. +
  7. The observable state of the switch after $S$ (e.g., through the Read RPC) +is identical to the one obtained by sequentially executing $L$. +
+ +

The Write RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the Write RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (e.g. inserting an ActionProfileMember +followed by pointing a TableEntry to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding Write RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate Write calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each Write call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one. +

12.2. Batch Atomicity

+

A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the Atomicity +enum. A P4Runtime server is required to support only the modes marked as +Required below: +

+
    +
  • +

    Required: CONTINUE_ON_ERROR: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that see each of +these intermediate stages. +

  • +
  • +

    Optional: ROLLBACK_ON_ERROR: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is all-or-none, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that see each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure. +

    +

    If a P4Runtime server does not support this option at all, an +UNIMPLEMENTED error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (e.g. it is +more straightforward to implement batches that contain only INSERT +operations, vs. those that contain DELETE operations), an +UNIMPLEMENTED error is returned when the batch cannot be executed +in a data plane-atomic way. +

  • +
  • +

    Optional: DATAPLANE_ATOMIC: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +transaction. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane's table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table. +

    +

    If a P4Runtime server does not support this option at all, an UNIMPLEMENTED +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an UNIMPLEMENTED error is returned when the batch +cannot be executed in a data plane-atomic way. +

+ +

There is no expectation that a given client must always use the same Atomicity +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use DATAPLANE_ATOMIC at one time and default behavior +(CONTINUE_ON_ERROR) at other times. +

12.3. Error Reporting

+

Please see section Error Reporting Messages for +information on error reporting messages and guidelines. P4Runtime server will +populate grpc::Status as follows: +

+
    +
  1. +

    If all batch updates succeeded, set grpc::Status::code_ to OK and do not +populate any other field. +

  2. +
  3. +

    If an error is encountered before even trying to attempt individual batch +updates, set grpc::Status::code_ that best describes that RPC-wide +error. For example, use UNAVAILABLE if the P4Runtime service is not yet +ready to handle requests. Set error_message_ to describe the issue. Do not +set error_details in this case. +

  4. +
  5. +

    Otherwise, if one or more updates in the batch (WriteRequest.updates) +failed, set grpc::Status::code_ to UNKNOWN. For example, one update in +the batch may fail with RESOURCE_EXHAUSTED and another with +INVALID_ARGUMENT. A p4.Error message is used to capture the status of +each and every update in the batch. The number of p4.Error messages packed +into google.rpc.Status.details field should therefore always match the +number of updates in the WriteRequest, and the order of +p4.Error messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +p4.Error should set the code to OK and omit other fields. +

+ +
+
+
# Example of a grpc::Status returned for a Write RPC with a batch of 3 updates.
+# The first and third updates encountered an error, while the second update
+# succeeded.
+code_ = 2  # UNKNOWN
+error_message_ = "Write failure."
+binary_error_details {
+  code: 2  # UNKNOWN
+  message: "Write failure."
+  details {
+    canonical_code: 8  # RESOURCE_EXHAUSTED
+    message: "Table is full."
+    space: "targetX-psa-vendorY"
+    code: 500  # ERR_TABLE_FULL
+  }
+  details {
+    canonical_code: 0  # OK
+  }
+  details {
+    canonical_code: 6  # ALREADY_EXISTS
+    message: "Entity already exists."
+    space: "targetX-psa-vendorY"
+    code: 600  # ERR_ENTITY_ALREADY_EXISTS
+  }
+}

13. Read RPC

+

The Read RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as: +

+
+
+
message ReadRequest {
+  uint64 device_id = 1;
+  string role = 3;
+  repeated Entity entities = 2;
+}
+

The device_id uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +NOT_FOUND error. +If the Read is attempted before ForwardingPipelineConfig has been set, the +server must return a FAILED_PRECONDITION error. +The role field acts as a filter, restricting the reported entities based on +the role to which the entity belongs. +The entities repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server. +

+

Since ReadRequests do not mutate any state on the switch, they do not +require an election_id, and they do not require the presence of an open +StreamChannel between the server and client. +

+

The Read response consists of a sequence of messages (a gRPC stream) with +each message defined as: +

+
+
+
message ReadResponse {
+  repeated Entity entities = 1;
+}
+

The entities repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the Finish() method on the stream object +[10]). +

13.1. Nomenclature

+
+
request
+
An element of the p4.ReadRequest.entities repeated field. +
+
batch
+
Refers to the p4.ReadRequest.entities repeated field.
+

Each request acts as a query filter for that entity type. If a request fully +specifies the entity key, the Read operation should retrieve a single P4 +entity. Please refer to the P4 Entity Messages section +for details on what parts of the entity specification make up the entity key. +

13.2. Wildcard Reads

+

P4Runtime allows wildcard read of P4 entities. A request may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the P4 Entity Messages section for details on +what parts of the entity can be wildcarded in a given request. +

+

For example, in a request of type CounterEntry: +

+
    +
  • A default counter_id (0) implies a request to read all counter-entries for +all indirect counters. +
  • +
  • A particular (non-default) counter_id in conjunction with index unset +implies a request to read all counter-entries for the given indirect counter +ID. +
+ +

To read the entire forwarding state for a given device, the P4Runtime client can +generate the following ReadRequest: +

+
+
+
device_id: <ID>
+entities {
+  extern_entry { }  # read all extern instances for all supported extern types
+  table_entry { }  # read all table entries for all tables
+  action_profile_member { }  # read all members for all action profiles
+  action_profile_group { }  # read all groups for all action profiles
+  ...
+}
+

The entity oneof field in the Entity message must always be set, or the +server must return an INVALID_ARGUMENT error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty Entity message in the ReadRequest. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the entity oneof [20]. +

13.3. Batch Processing

+

A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type request +appears only once in the batch. +

+

A P4Runtime server will process the batch as follows: +

+
    +
  1. +

    Lock state (preventing new writes) and validate each request in the batch: +

    +
      +
    1. +

      If it is a valid request, perform the read; +

      +
        +
      1. If the read was successful, return the entities read in +ReadResponse stream. +
      2. +
      3. If the read failed (exception / critical-error), prepare a p4.Error +with code set to INTERNAL. +
      +
    2. +
    3. +

      If the request is invalid (invalid-argument, not-supported, etc.), +prepare a p4.Error with relevant canonical code to capture the error. +

    +
  2. +
  3. +

    Unlock the state (allowing new writes); +

  4. +
  5. +

    Close the ReadResponse stream and return a grpc::Status as follows: +

    +
      +
    1. +

      If no errors were encountered, set code to OK and do not populate any +other field. +

    2. +
    3. +

      Otherwise, the overall code should be set to UNKNOWN. See section +Error Reporting Messages for information +on error reporting messages and guidelines. Assemble a list of p4.Error +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +google.rpc.Status.details field. This behavior also matches Write +RPC. +

    +
+

13.3.1. Example

+

If a client asked to read {a,b,c,d} and b and d requests didn't +validate, the server will return entities corresponding to a and c, followed +by a status {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} in the +details field. +

+

The P4Runtime server is not required to perform any optimization (e.g. merge two +requests in the batch if one is a subset of other). As a result of this, it +is possible for the ReadResponse to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging. +

+

There is no requirement that each request in the batch will correspond to one +ReadResponse message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit. +

+

A P4Runtime server must be prepared to handle multiple concurrent Read RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (e.g. in a single-threaded architecture), it may choose to serialize +Read RPC processing. +

13.4. Parallelism of Read and Write Requests

+

A P4Runtime server may be implemented to serve at most one +ReadRequest or WriteRequest message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so. +

+

For example, imagine a client that wanted to use WriteRequest +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +WriteRequest messages with only a few updates to an ActionSelector +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +WriteRequest batch currently being processed, but it will not +complete for a significant amount of time. +

+

The restrictions on which a client may rely are: +

+
    +
  • The processing of any two WriteRequest messages W1 and W2 must +result in the same state as if one of them was completed before the +other began. +
  • +
  • For any WriteRequest W and any ReadRequest R, R must +return results consistent with a state where W has completed +processing, or W has not yet begun processing. +
+ +

For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a WriteRequest message it acquired a write lock for each stateful +object affected by the WriteRequest, and before starting the +processing of a ReadRequest message it acquired a read lock for each +stateful object accessed by the ReadRequest, such an implementation +meets all of the requirements above. +

+

It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, e.g. if the server somehow determined that two +WriteRequest messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly. +

14. SetForwardingPipelineConfig RPC

+

A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the SetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message SetForwardingPipelineConfigRequest {
+  enum Action {
+    UNSPECIFIED = 0;
+    VERIFY = 1;
+    VERIFY_AND_SAVE = 2;
+    VERIFY_AND_COMMIT = 3;
+    COMMIT = 4;
+    RECONCILE_AND_COMMIT = 5;
+  }
+  uint64 device_id = 1;
+  string role = 6;
+  Uint128 election_id = 3;
+  Action action = 4;
+  ForwardingPipelineConfig config = 5;
+}
+

The server is expected to perform the following checks (in this order) +before performing the required action: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the primary for (device_id, role) according to +the election_id value, the server must return a PERMISSION_DENIED error. +

+ +

The action is the type of configuration action requested, it can be one of: +

+
    +
  • +

    VERIFY: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an INVALID_ARGUMENT +error if config is not provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_SAVE: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent Read / Write requests must refer to fields in the new +config. Returns an INVALID_ARGUMENT error if the forwarding config is not +provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_COMMIT: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an INVALID_ARGUMENT error if the forwarding config is not provided or if the +provided config cannot be realized. +

  • +
  • +

    COMMIT: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a NOT_FOUND error if no saved config +is found, i.e. if no VERIFY_AND_SAVE action preceded this one. Returns an +INVALID_ARGUMENT error if a config is provided with this message. +

  • +
  • +

    RECONCILE_AND_COMMIT: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an UNIMPLEMENTED error. For targets that support this option, an +INVALID_ARGUMENT error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target. +

+ +

The config field is a message of type ForwardingPipelineConfig that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(e.g. generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the Forwarding-Pipeline +Configuration section for details. +

+

A P4Runtime server running on a non-programmable device may not +support SetForwardingPipelineConfig (e.g. the forwarding-pipeline +config is part of the device's software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +UNIMPLEMENTED error. +

15. GetForwardingPipelineConfig RPC

+

The forwarding-pipeline configuration of the target can be retrieved by invoking +the GetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message GetForwardingPipelineConfigRequest {
+  enum ResponseType {
+    ALL = 0;
+    COOKIE_ONLY = 1;
+    P4INFO_AND_COOKIE = 2;
+    DEVICE_CONFIG_AND_COOKIE = 3;
+  }
+  uint64 device_id = 1;
+  ResponseType response_type = 2;
+}
+

The device_id uniquely identifies the target P4 device. A NOT_FOUND error is +returned if the device_id is not recognized by the P4Runtime server. +

+

The response_type is used to specify which fields to populate in the response, +its value can be one of: +

+
    +
  • +

    ALL: returns a ForwardingPipelineConfig with all fields +set as stored by the target. This is the default behaviour if the +response_type field is not set. +

  • +
  • +

    COOKIE_ONLY: reply by setting only the cookie field in the +ForwardingPipelineConfig, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message. +

  • +
  • +

    P4INFO_AND_COOKIE: reply by setting the p4info and cookie fields. +

  • +
  • +

    DEVICE_CONFIG_AND_COOKIE: reply by setting the p4_device_config and +cookie fields. +

+ +

The response contains the ForwardingPipelineConfig for the specified device: +

+
+
+
message GetForwardingPipelineConfigResponse {
+  ForwardingPipelineConfig config = 1;
+}
+

If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level config field will be unset in the response. Examples are +(i) a server that only allows configuration via SetForwardingPipelineConfig +but this RPC hasn't been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn't yet occurred. +

+

Once a forwarding-pipeline config is installed on the device (either via +SetForwardingPipelineConfig or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +config.p4_device_config will be empty / unset in the response, even if +response_type in the request was set to ALL. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the SetForwardingPipelineConfig RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +SetForwardingPipelineConfig, the value of config.cookie will be unset. +

+

If a P4Runtime server supports both SetForwardingPipelineConfig as well as +returning the p4_device_config, there should be read-write symmetry between +SetForwardingPipelineConfig and GetForwardingPipelineConfig RPCs. +

16. P4Runtime Stream Messages

16.1. Packet I/O

+

P4Runtime supports controller packet-in and packet-out by means of PacketIn +and PacketOut stream messages, respectively. +

+

PacketIn messages are sent by the P4Runtime server to the client. Conversely, +PacketOut messages are sent by the client to the server. Any PacketOut +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a StreamMessageResponse message with the error field set to +report the error to the client. See the section on Stream Error +Reporting for more information on error. +

+

As introduced in the ControllerPacketMetadata +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with @controller_header. The expected metadata is described +in the P4Info using the ControllerPacketMetadata messages. +

+

Both PacketIn and PacketOut stream messages share the same fields and are +defined as follows: +

+
+
+
// Packet sent from the controller to the switch.
+message PacketOut {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+// Packet sent from the switch to the controller.
+message PacketIn {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+message PacketMetadata {
+  // This refers to Metadata.id coming from P4Info ControllerPacketMetadata.
+  uint32 metadata_id = 1;
+  bytes value = 2;
+}
+
    +
  • +

    payload is used to carry the full packet content, including the headers. +

  • +
  • +

    metadata is a repeated field of PacketMetadata messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +ControllerPacketMetadata. Indeed, when a P4Runtime client (or server) +generates a PacketOut (or PacketIn) message, it needs to populate the +metadata field with as many values as in ControllerPacketMetadata.metadata +for the packet-out (or packet-in) case. Each PacketMetadata.value is a +binary string and must conform to the Bytestrings +requirements based on the corresponding P4Info +ControllerPacketMetadata.metadata specification. If the metadata field +does not match the P4Info specification, the server must drop the PacketOut +message and may generate a StreamMessageResponse message with the error +field set to report the error to the client which issued the PacketOut. See +the section on Stream Error Reporting for more +information on error. +

+

16.2. Client Arbitration Update

+

P4Runtime's client arbitration mechanism ensures that only the current primary +can modify state on the switch, and that the election_id is monotonically +increasing. For example, the switch must finish all previous write operations +before before selecting a different primary, and must only accept write requests +from the current primary. +

+

As explained earlier in this document, the controller uses the StreamChannel +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via Write RPC), +it needs to start a controller session and become a “primary”. To do so, the +controller first opens a bidirectional stream channel to the server via +StreamChannel for each device and sends a StreamMessageRequest message. The +controller populates the MasterArbitrationUpdate field in this message using +its role and election_id and the device_id of the device, as explained +in detail in the Client Arbitration and Controller +Replication +section. For any given (device_id, role), the P4Runtime server keeps track +of the highest election_id that it has ever received. If a controller's +election_id is equal to the highest election_id that the server has ever +received, that controller is the primary. All other controllers are backups. +Note that it is possible that all controllers are backups, and that there is no +primary. There can be at most one primary, because for any given +(device_id, role), each connected controller has a unique election_id. +

+

This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest election_id after such a restart. +However, across a full restart, the election_id must be +reset. In fact, a full restart is the only way to reset the election_id. +

+

The MasterArbitrationUpdate message is defined as follows: +

+
+
+
message MasterArbitrationUpdate {
+  uint64 device_id = 1;
+  // The role for which the primary client is being arbitrated. For use-cases
+  // where multiple roles are not needed, the controller can leave this unset,
+  // implying default role and full pipeline access.
+  Role role = 2;
+  // The stream RPC with the highest election_id is the primary. The 'primary'
+  // controller instance populates this with its latest election_id. Switch
+  // populates with the highest election ID it has received from all connected
+  // controllers.
+  Uint128 election_id = 3;
+  // Switch populates this with OK for the client that is the primary, and
+  // with an error status for all other connected clients (at every primary
+  // client change). The controller does not populate this field.
+  .google.rpc.Status status = 4;
+}
+
+message Role {
+  // Uniquely identifies this role.
+  string name = 3;
+  // Describes the role configuration, i.e. what operations, P4 entities,
+  // behaviors, etc. are in the scope of a given role. If config is not set
+  // (default case), it implies all P4 objects and control behaviors are in
+  // scope, i.e. full pipeline access. The format of this message is
+  // out-of-scope of P4Runtime.
+  .google.protobuf.Any config = 2;
+}
+

Note that the status field in the MasterArbitrationUpdate message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a StreamMessageResponse message back to the controller, in which +it populates the MasterArbitrationUpdate message using the device_id, +role, and election_id it previously received from the controller. The server +also populates the status field in the MasterArbitrationUpdate according to +the rules in an earlier section. +

+

The sender need not specify an election_id. If the election_id is not +specified, the sender's election_id is considered lower than any +election_id, and the sender will thus never become primary. This way, a +controller can choose to be a backup controller, in order to avoid +“flapping” (if a backup controller connects to the switch shortly before the +actual primary controller, therefore becoming primary temporarily). +

16.3. Digest Messages

+

See the DigestEntry section. +

16.4. Table Idle Timeout Notification

+

When a table supports idle timeout (as per the P4Info message), the primary +client can specify a TTL value for each entry in the table (see +Idle-timeout section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an IdleTimeoutNotification message on the +StreamChannel bidirectional stream to the primary client. The primary client +can then take the action of its choice, most likely remove the idle entry. +

+

The IdleTimeoutNotification Protobuf message has the following fields: +

+
    +
  • +

    timestamp: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server's local clock. +

  • +
  • +

    table_entry: a repeated field of entries which have expired. Each individual +entry is identified by a single TableEntry message. For each TableEntry, +the key fields (table_id, match and priority) must be set, along with +the controller_metadata field, the metadata field, and the +idle_timeout_ns field. Other fields may be set by the server but should be +ignored by the client. +

+ +

Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +IdleTimeoutNotification message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an IdleTimeoutNotification +message with an empty table_entry repeated field. +

+

After generating an idle notification, the P4Runtime server must “reset” the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the primary client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle. +

+

Here is a reasonable pseudo-code implementation for idle timeout for table +entries: +

+
+
+
IdleTimeoutStream stream;
+
+scanning_interval = 10ms;
+
+while (true) {
+  // iterate over all tables which support idle timeout
+  for (table in tables) {
+    if (!table.idle_timeout_supported) continue;
+    // we coalesce all idle notifications for the same table in one
+    // message
+    IdleTimeoutNotification msg;
+    // read time_since_last_hit from device
+    entries = device.load_table_entries_from_hw(table);
+    for (entry in entries) {
+      if (entry.idle_timeout == 0) continue;  // no TTL
+      if (entry.time_since_last_hit < entry.idle_timeout) continue;
+      msg.table_entry_add(entry);
+      entry.reset_time_since_last_hit();
+    }
+    if (msg.table_entry_size() == 0) continue;  // no notifications
+    msg.set_timestamp(now());
+    stream.write(msg);
+  }
+  sleep(scanning_interval);
+}

16.5. Architecture-Specific Notifications

+

P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on StreamChannel, by including an Any Protobuf field [31] +named other in both StreamMessageRequest and StreamMessageResponse. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the PSA Digest +extern. See section on Extending P4Runtime for non-PSA +Architectures for more information. +

16.6. Stream Error Reporting

+

The P4Runtime server can asynchronously report errors which occur when +processing StreamMessageRequest messages, using the error message field (of +type StreamError) in StreamMessageResponse. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature. +

+

The StreamError message has the following fields: +

+
    +
  • canonical_code, which must be set to the appropriate canonical error code +[34]. +
  • +
  • message, an optional developer-facing error message describing the error. +
  • +
  • space and code, which are optional and can be used by vendors to provide +additional details on the error. code is a numeric error code drawn from a +vendor's chosen error space. +
  • +
  • details, which is a Protobuf oneof used to help the client identify which +StreamMessageRequest triggered the error. The server is required to set the +appropriate field in the oneof so that the client can identify which type +of stream message is responsible for the error (packet_out, +digest_list_ack or other), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid PacketOut message from the +client, the packet_out field (of type PacketOutError) should be set in +the details oneof, and the server may additionally set the packet_out +field in the PacketOutError sub-message (by copying it from the invalid +PacketOut message received on the stream channel) so that the client can +know exactly what packet-out triggered the error. +
+ +

The appropriate canonical error code [34] should be used when +populating the canonical_code field. For example: +

+
    +
  • if a controller is not allowed to send a PacketOut message under its +current role definition, the code should be set to PERMISSION_DENIED. +
  • +
  • if the metadata repeated field in PacketOut does not match the P4Info +definition, the code should be set to INVALID_ARGUMENT. It may be useful +for the server to set the packet_out field in this case, so that the client +can find out which set of metadata fields triggered the error. +
  • +
  • if the digest_id field in DigestListAck does not match any Digest entry +in P4Info, the code should be set to INVALID_ARGUMENT. +
+ +

The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, e.g. because of a +burst of PacketIn messages. +

+

Note that client arbitration errors are never reported using the StreamError +message. Invalid MasterArbitrationUpdate messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section 5.3. +

16.6.1. Examples of StreamError Messages

+
    +
  • +

    Malformed packet-out metadata. If the server receives a PacketOut +message with a metadata field with id 7 which is not included in the P4Info +ControllerPacketMetadata message for “packet_out”, the server may send the +following StreamMessageResponse back to the client: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Unknown metadata field id 7."
    + packet_out {
    +   # copied from the PacketOut message received from the client
    +   packet_out {
    +     payload: ...
    +     metadata {
    +       id: 7
    +       name: "I_should_not_be_here"
    +       bitwidth: 32
    +     }
    +     # more metadata
    +   }
    + }
    +}
  • +
  • +

    Packet-out which exceeds the MTU. If the server receives a PacketOut +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following StreamMessageResponse: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Packet exceeds the MTU for port."
    + space: "targetX-psa-vendor1"
    + code: 123  # MTU_EXCEEDED
    + packet_out {
    +   # we do not set the packet_out field as it does not provide any
    +   # extra information to the client
    + }
    +}
+

17. Capabilities RPC

+

The Capabilities RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the CapabilitiesRequest message is empty and the CapabilitiesResponse +message only includes the p4runtime_api_version string field. This field must +be set to the full semantic version string [27] corresponding to the +version of the P4Runtime API implemented by the server, e.g. “1.1.0-rc.1”. +

+

Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three atomicity +modes for WriteRequest batches, two of them being +optional. In the future we may decide to leverage the CapabilitiesResponse +message to enable the server to report to the client which subset of these +atomicity modes is supported. +

+

The semantic version string included in CapabilitiesResponse can be used by +the client to determine which exact feature set is implemented by the server, +since minor releases may introduce new +functionality. However, because the Capabilities RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (i.e. an UNIMPLEMENTED error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0). +

18. Portability Considerations

18.1. PSA Metadata Translation

+

The Portable Switch Architecture (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +[24]. For such metadata, a translation between the controller's +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the @p4runtime_translation annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture. +

+
+

psa-metadata-translation +

+
+ +
Figure 8. P4Runtime Metadata Translation for the Portable Switch Architecture
+

Figure 8 illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller's 32 bit port +numbers to a target's 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch. +

18.1.1. Translation of Port Numbers

+

In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller's space and the PSA device's space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +user-defined P4 types, namely PortId_t and +PortIdInHeader_t, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in psa.p4 for +the PSA device in Switch 1. +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type bit<9> PortId_t;
+@p4runtime_translation("p4.org/psa/v1/PortIdInHeader_t", 32)
+type bit<32> PortIdInHeader_t;
+

The first argument to the @p4runtime_translation annotation is a URI that +indicates to the P4Runtime server which numerical mapping provided by the +out-of-band switch configuration mechanism to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports). +

+

An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows: +

+
+
+
enum SdnPort {
+  SDN_PORT_UNSPECIFIED = 0;
+
+  // SDN ports are numbered starting from 1.
+  SDN_PORT_MIN = 1;
+
+  // The maximum value of an SDN port (physical or logical).
+  SDN_PORT_MAX = 0xfffffeff;
+
+  // Reserved SDN port numbers (0xfffffff0 - 0xffffffff)
+
+  SDN_PORT_RECIRCULATE = 0xfffffffa;
+  SDN_PORT_CPU = 0xfffffffd;
+}
+

The switch config will map SDN_PORT_RECIRCULATE and SDN_PORT_CPU as well +as any SDN port number corresponding to a “regular” front-panel port to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation. +

+

The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs. +

18.1.2. Translation of Packet-IO Header Fields

+

Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  PortIdInHeader_t egress_port;
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  PortIdInHeader_t ingress_port;
+}
+

The header-level annotation @controller_header is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (egress_port) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI first argument to the @p4runtime_translation +annotation). Any subsequent reference to the egress_port field in the +data plane will use the translated value. PortIdInHeader_t is used in the +header definition instead of PortId_t to guarantee byte-aligned headers in +case this is required by the target. +

+

A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target's PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the ingress_port field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller. +

18.1.3. Translation of Match Fields

+

Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table's match key as shown in the example below: +

+
+
+
table t {
+  key = {
+    istd.ingress_port: exact;  // PSA standard metadata ingress port
+  }
+  actions = {
+    drop;
+  }
+}
+

Table t has an exact match on PSA standard metadata ingress port +(istd.ingress_port). Since the field is of type PortId_t, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in t from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table t is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values. +

+

Note that it may be infeasible to translate the value-mask pair for ternary +matches: LPM, TERNARY or RANGE match kinds. The P4Runtime server may +require that for these match kinds the port match be either de facto “exact” +(0xffffffff mask for TERNARY, prefix-length of 32 for LPM, or same low and +high bounds for RANGE) or “don't care”. +

18.1.4. Translation of Action Parameters

+

PortId_t type parameters can be part of a P4 action definition as shown in the +example below: +

+
+
+
action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+}
+
+table t {
+  key = {
+    hdr.h.f: exact;
+  }
+  actions = {
+    a;
+  }
+}
+

The controller may write entries in table t with action a to set the egress +port as shown in the P4 code above. The action parameter p is of type +PortId_t, which leads to a 32-bit bitwidth for p being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device. +

18.1.5. Port Translation for PSA Extern APIs

+

The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch_port +field is of type bytes to carry the SDN representation of the port being +watched. The P4Runtime server will translate the given watch port into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device. +

+

The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type uint32 to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane. +

18.1.6. Using Port as an Index to a Register, Indirect Counter or Indirect Meter

+

P4Runtime supports using a translated value (PortId_t or any other translated +type for which the underlying built-in type is bit<W>) as an index to a +register, indirect counter, or indirect meter. +

+
+
+
Counter<bit<32> /* counter entry type */, PortId_t /* index type */>(
+  32w1024, PSA_CounterType_t.PACKETS) counter;
+action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+  counter.count(p);
+}
+

This P4 Counter declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
counters {
+  preamble {
+    id: 0x12000001
+    name: "counter"
+  }
+  spec {
+    unit: PACKETS
+  }
+  index_type_name {
+    name: "PortId_t"
+  }
+}
+

The controller may read and write counter values from indexed counter counter +using SDN port numbers as indices, and not device-specific port numbers. The +index_type_name field in the P4Info message is a signal to the P4Runtime +server that translation is required. +

19. P4Runtime Versioning

+

P4Runtime follows the Google guidelines for versioning cloud APIs +[6]. We use a MAJOR.MINOR.PATCH style version number scheme and +we increment the: +

+
    +
  • MAJOR version when we make incompatible API changes, +
  • +
  • MINOR version when we add functionality in a backwards-compatible manner, +
  • +
  • PATCH version when we make backwards-compatible bug fixes. +
+ +

The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is p4.v1 and the package +name for P4Info is p4.config.v1. Even though p4 and p4.config are two +different Protobuf packages, p4 depends on p4.config and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence. +

+

As recommended in [6], we may consider using pre-GA release +suffixes (such as alpha or beta) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1). +

+

Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner. [7] describes +what constitute a backwards-compatible change. We expect MAJOR version bumps +to be a rare event. +

+

Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor + patch version numbers in future releases. +

+

All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository [15] and the version label follows +semantic versioning rules [27]. +

20. Extending P4Runtime for non-PSA Architectures

+

P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place. +

+

When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names: +

+
    +
  • p4/[organization]/arch/config/<major version>/p4info.proto +
  • +
  • p4/[organization]/arch/<major version>/p4runtime.proto +
+ +

We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they “extend”. +

+

For the remainder of this section, we will refer to these two files as +p4info-ext and p4runtime-ext respectively. +

20.1. Extending P4Runtime for Architecture-Specific Externs

+

Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both p4info-ext and +p4runtime-ext. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example: +

+
+
+
// T must be a bit<W> type, it indicates the width of each counter cell
+extern MyNewPacketCounter<T> {
+  counter(bit<32> size);
+  increment(in bit<32> index);
+}

20.1.1. Extending the P4Info message

+
    +
  • Id prefixes 0x81 through 0xfe are reserved for architecture-specific +externs. It is recommended that p4info-ext include a P4Ids message based +on the one in p4info.proto that the P4 compiler can refer to when assigning +IDs to each extern instance. +
+ +
+
+
message P4Ids {
+  enum Prefix {
+    UNSPECIFIED = 0;
+    MY_NEW_PACKET_COUNTER = 0x81;
+  }
+}
+
    +
  • p4info-ext should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +p4.config.v1.ExternInstance message as the info +field, which is of type Any [31]. +
+ +
+
+
message MyNewPacketCounter {
+  // corresponds to the T type parameter in the P4 extern definition
+  p4.config.v1.P4DataTypeSpec type_spec = 1;
+  // constructor argument
+  int64 size = 2;
+}

20.1.2. Extending the P4Runtime Service

+

Just like p4info-ext, p4runtime-ext should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an ExternEntry message generated by the +P4Runtime client. +

+

Here is a possible Protobuf message for our MyNewPacketCounter P4 extern: +

+
+
+
// This message enables reading / writing data to the counter at the provided
+// index
+message MyNewPacketCounter {
+  int64 index = 1;
+  p4.v1.P4Data data = 2;
+}
+

P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an Any Protobuf field [31] named other +in both p4.v1.StreamMessageRequest and +p4.v1.StreamMessageResponse. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in p4runtime-ext and embed instances of these messages in +p4.v1.StreamMessageRequest and p4.v1.StreamMessageResponse as appropriate. +

20.2. Architecture-Specific Table Extensions

20.2.1. New Match Types

+

An architecture may introduce new table match types [12]. P4Runtime +accounts for this by providing the following hooks: +

+
    +
  • +

    The match field in p4.config.v1.MatchField (p4info.proto) is a oneof +which can be either one of the default match types (EXACT, LPM, TERNARY, +RANGE, or OPTIONAL) or an architecture-specific match type encoded as a +string. +

  • +
  • +

    The field_match_type field in p4.v1.FieldMatch (p4runtime.proto) is a +oneof which includes an Any Protobuf message [31] field +(other). p4info-ext should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in p4.v1.FieldMatch as the +other field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info. +

+

20.2.2. New Table Properties

+

An architecture may introduce additional table properties +[30]. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +p4.config.v1.Table message includes the other_properties Any Protobuf +field [31]. At the moment, there is not any mechanism to extend the +p4.v1.TableEntry message based on the value of architecture-specific table +properties, but we may include on in future versions of the API. +

21. Known Limitations of Current P4Runtime Version

+
    +
  • +

    FieldMatch, action Param, and controller packet metadata fields only +support unsigned bitstrings, i.e. values of one of the following types (not +the more general P4Data): +

    +
      +
    • bit<W> +
    • +
    • bool. Note that as far as the P4Info message contents and +thus controller software is concerned, such fields of type bool +will be indistinguishable from those that have been declared with +type bit<1>. P4Runtime server software will automatically +perform any conversion needed between the type bit<1> values in +P4Runtime messages and the data plane representation. +
    • +
    • an enum with underlying type bit<W> +
    • +
    • a type or typedef with an underlying type that is one of the above (or +in general a “chain” of type and/or typedef that eventually ends with +one of the types above) +
    +
  • +
  • +

    Support for PSA Random & Timestamp externs is postponed to a future minor +version update. +

  • +
  • +

    P4Info does not include information about which of a table's actions execute +which direct resource(s). +

  • +
  • +

    The default action for indirect match tables is restricted to a const +NoAction known at compile-time. +

  • +
  • +

    There is no mechanism for changing the value of the psa_empty_group_action +table property at runtime. +

  • +
  • +

    There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor + +patch version numbers. +

+

A. Appendix

A.1. Revision History

A.1.1. Changes in v1.4.0 (under development)

+

TODO +

A.1.2. Changes in v1.3.0

+
    +
  • Add IANA assigned TCP port, 9559, to P4Runtime server discussion. +
  • +
  • Move “Security considerations” section to P4Runtime server discussion. +
  • +
  • Deprecate watch field (int32) in favor of watch_port (bytes). This allows +using the watch port feature with the p4runtime_translation feature. +
  • +
  • Replace master, slave, master arbitration with more inclusive language: +primary, backup, and client arbitration +
  • +
  • Clarify that source locations for annotations are optional in the P4Info +message. +
+

A.1.3. Changes in v1.2.0

+
    +
  • Add new OPTIONAL match kind. At the moment, OPTIONAL is only supported by +the v1model architecture [38], and not by PSA. It will eventually be +included in the core P4 language. +
  • +
  • Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists. +
  • +
  • Add a new metadata field of type bytes to TableEntry. This is more +flexible than the now deprecated controller_metadata field. +
  • +
  • Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +@id annotation. +
  • +
  • Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature. +
  • +
  • Support using string as the controller type in the @p4runtime_translation +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type. +
  • +
  • Add optional P4 source locations to both structured and unstructured +annotations. +
+

A.1.4. Changes in v1.1.0

+
    +
  • Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously. +
  • +
  • Add error field to stream messages sent by the server. +
  • +
  • Add Capabilities RPC to query the P4Runtime API version implemented by the +server. +
  • +
  • Support wildcard reads for multicast groups and clone sessions. +
  • +
  • Support for modifying direct resources of const tables. +
  • +
  • Support P4 user-defined types for Packet IO metadata fields. +
  • +
  • Clarify consistency requirements for Write and Read RPCs. +
  • +
  • Add Appendix providing implementation advice for avoiding common pitfalls: + +
      +
    • advice on setting gRPC Metadata Maximum Size +
    • +
    • advice on setting gRPC Server Maximum Receive Message Size +
  • +
  • Clarify limitations on supported types for FieldMatch, action Param, and +Packet IO metadata fields. +
  • +
  • Clarify that reading entire forwarding state with empty entity is not +supported. +
  • +
  • Document that @p4runtime_translation need only be supported when applied to +type declarations in P4. +
+

A.2. P4 Annotations

+

Table 7 lists P416 annotations introduced primarily for +the purpose of adding features for the P4Runtime API. +

+
+ + + + + + + + + + +
Annotation Description
@brief See section 6.1.3
@controller_header See section 6.4.6
@description See section 6.1.3
@id See section 6.3
@max_group_size See sections 6.4.3, 9.2.2
@pkginfo See section 6.2.1
@p4runtime_translation See sections 8.5.6, 18.1.1
+
+ +
Table 7. P4 annotations introduced by P4Runtime

A.3. A More Complex Value Set Example

+

This section includes a more complex Value Set example, with multiple matches of +different kinds. +

+
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+

This P4 Value Set declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

A P4Runtime client can set the membership for this Value Set with WriteRequest +messages similar to this one: +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xac }
+      }
+      # match for field_id 2 is missing => don't care match
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xdc }
+      }
+      match {
+        field_id: 2
+        ternary { value: 0x88 mask: 8f }
+      }
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+  }
+}

A.4. Guidelines for Implementations

+

This section contains practical advice for implementing P4Runtime clients and +servers. +

A.4.1. gRPC Metadata Maximum Size

+

In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the grpc.max_metadata_size gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the Write P4Runtime RPC. The Write RPC +returns an individual error for every item in a batch (see Section +12), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +RESOURCE_EXHAUSTED error, without any of the individual errors. +

+

To fix this problem, one can set the grpc.max_metadata_size option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it's +limit, as only the receiving side's limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every p4.Error, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +8192 + MAX_UPDATES_PER_WRITE * 100 bytes of metadata. +

+

For example, in C++, one can create a client channel as follows: +

+
+
+
const int MAX_UPDATES_PER_WRITE = 100;
+::grpc::ChannelArguments arguments;
+arguments.SetInt(GRPC_ARG_MAX_METADATA_SIZE, 8192 + MAX_UPDATES_PER_WRITE*100);
+return grpc::CreateCustomChannel(address, credentials, arguments);

A.4.2. gRPC Server Maximum Receive Message Size

+

At the time of writing, the default maximum receive message size in gRPC is 4MB + while the default maximum send message size is unlimited. This can be a +problem for the SetForwardingPipelineConfig RPC, since for some targets the +binary p4_device_config can exceed 4MB, in which case by default the P4Runtime +server would return an INVALID_ARGUMENT error. To a lesser extent, this may +affect the Write RPC as well, in case of extremely large batches. +

+

To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of p4_device_config for their target(s). This can be done by +setting the grpc.max_receive_message_length when building the gRPC server. +

+

For example, in C++, one can set the maximum receive message size as follows: +

+
+
+
const int MAX_RECEIVE_MESSAGE_SIZE = 128 * 1024 * 1024;  // 128MB
+::grpc::ServerBuilder server_builder;
+builder.AddListeningPort(/*...*/);
+builder.RegisterService(/*...*/);  // register P4Runtime service
+builder.SetMaxReceiveMessageSize(MAX_RECEIVE_MESSAGE_SIZE);
+builder.BuildAndStart();
+

On the client side, we recommend that P4Runtime clients do not use Write +batches larger than the default maximum receive message size (4MB) in case +the server did not deem necessary to increase the default value , unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB). +

+

References

+
+ +
[2]“A Two Rate Three Color Marker.” https://​tools.​ietf.​org/​html/​rfc2698.
+ + + + +
[7]“Google Cloud APIs Versioning - Backwards-Compatibility.” https://​cloud.​google.​com/​apis/​design/​versioning#​backwards_​compatibility.
+ +
[9]“gRPC Main Site.” https://​grpc.​io.
+ + + + + +
[15]“p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” https://​github.​com/​p4lang/​p4runtime.
+
[16]“p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.” https://​github.​com/​p4lang/​PI.
+ + +
[19]“Portable Switch Architecture Specification (v1.1.0).” https://​p4.​org/​p4-​spec/​docs/​PSA-​v1.​1.​0.​html.
+ + + + + + + +
[27]“Semantic Versioning.” https://​semver.​org/​.
+ + + + + + + +
[35]“The OpenConfig Project.” http://​openconfig.​net.
+ +
[37]“The Stratum Project.” https://​stratumproject.​org/​.
+ +
+
+
+ +
+

1.an enum type used as a field in a header must specify a +underlying type and representation for enum elements. +

+ + + diff --git a/spec/v1.4.0-rc.5/P4Runtime-Spec.log b/spec/v1.4.0-rc.5/P4Runtime-Spec.log new file mode 100644 index 00000000..d5b4a289 --- /dev/null +++ b/spec/v1.4.0-rc.5/P4Runtime-Spec.log @@ -0,0 +1,14758 @@ +This is XeTeX, Version 3.14159265-2.6-0.99992 (TeX Live 2015/Debian) (preloaded format=xelatex 2018.8.17) 23 MAR 2022 23:30 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**build/P4Runtime-Spec.tex +(./build/P4Runtime-Spec.tex +LaTeX2e <2016/02/01> +Babel <3.9q> and hyphenation patterns for 81 language(s) loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2014/09/29 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo +File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@section=\count80 +\c@subsection=\count81 +\c@subsubsection=\count82 +\c@paragraph=\count83 +\c@subparagraph=\count84 +\c@figure=\count85 +\c@table=\count86 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) (build/madoko2.sty (/usr/share/texlive/texmf-dist/tex/latex/colortbl/colortbl.sty +Package: colortbl 2012/02/13 v1.0a Color table columns (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty +Package: array 2014/10/28 v2.4c Tabular extension package (FMi) +\col@sep=\dimen103 +\extrarowheight=\dimen104 +\NC@list=\toks14 +\extratabsurround=\skip43 +\backup@length=\skip44 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty +Package: color 2016/01/03 v1.1b Standard LaTeX Color (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package color Info: Driver file: xetex.def on input line 143. +(/usr/share/texlive/texmf-dist/tex/xelatex/xetex-def/xetex.def +File: xetex.def 2015/09/11 v4.06 LaTeX color/graphics driver for XeTeX (TeX Live/RRM/JK) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +))) +\everycr=\toks15 +\minrowclearance=\skip45 +) (/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: xetex.def on input line 225. +LaTeX Info: Redefining \color on input line 702. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) (build/options.sty +Package: options 2015/03/01, Daan Leijen, Provides convenient path-value (or key-value) options +(/usr/share/texlive/texmf-dist/tex/latex/etoolbox/etoolbox.sty +Package: etoolbox 2015/08/02 v2.2a e-TeX tools for LaTeX (JAW) +\etb@tempcnta=\count87 +) +\opt@nesting=\count88 +\opt@idx=\count89 +\opt@choiceord=\count90 +) (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty +Package: iftex 2013/04/04 v0.2 Provides if(tex) conditional for PDFTeX, XeTeX, and LuaTeX +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2014/10/28 v1.0g Enhanced LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks16 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2016/01/03 v1.0q Standard LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2016/01/03 v1.10 sin cos tan (DPC) +) (/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg +File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live +) +Package graphics Info: Driver file: xetex.def on input line 95. +) +\Gin@req@height=\dimen105 +\Gin@req@width=\dimen106 +) (build/longfbox.sty +Package: longfbox 2015/12/01, Daan Leijen, Provides long fbox that can break over pages +(build/longbox.sty +Package: longbox 2015/12/01, Daan Leijen, Provides basic longbox that can break over pages +(/usr/share/texlive/texmf-dist/tex/latex/mdwtools/footnote.sty +Package: footnote 1997/01/28 1.13 Save footnotes around boxes +\fn@notes=\box26 +\fn@width=\dimen107 +) +\lb@prevdepth=\skip46 +\lb@freevspace=\skip47 +\lb@headbox=\box27 +\lb@savebox=\box28 +\lb@mainbox=\box29 +\lb@usevbox=\count91 +\lb@width=\skip48 +\lb@height=\skip49 +\lb@skiptop=\skip50 +\lb@skipright=\skip51 +\lb@skipbottom=\skip52 +\lb@skipleft=\skip53 +\lb@skipbreaktop=\skip54 +\lb@skipbreakbottom=\skip55 +\lb@outerwidth=\skip56 +\lb@extrasplit=\skip57 +\lb@textalign=\count92 +\lb@baseline=\count93 +\lb@neededvspace=\skip58 +\lb@splitheight=\skip59 +\lb@insurance=\skip60 +\/longbox/@part-height=\skip61 +\/longbox/@part-width=\skip62 +\/longbox/@part-depth=\skip63 +\/longbox/@content-box-height=\skip64 +\/longbox/@content-box-width=\skip65 +\/longbox/@content-box-depth=\skip66 +\/longbox/@breakat-previous=\skip67 +\/longbox/@lower=\skip68 +\/longbox/split-minimum=\skip69 +\/longbox/split-badness=\skip70 +\/longbox/raise=\skip71 +\/longbox/height=\skip72 +\/longbox/width=\skip73 +\/longbox/outer-height=\skip74 +\/longbox/outer-width=\skip75 +\/longbox/skip-top=\skip76 +\/longbox/skip-right=\skip77 +\/longbox/skip-bottom=\skip78 +\/longbox/skip-left=\skip79 +\/longbox/skip-break-bottom=\skip80 +\/longbox/skip-break-top=\skip81 +) (/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.sty +Package: pict2e 2016/02/05 v0.3b Improved picture commands (HjG,RN,JT) +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.cfg +File: pict2e.cfg 2016/02/05 v0.1u pict2e configuration for teTeX/TeXLive +) +Package pict2e Info: Driver file: xetex.def on input line 119. +Package pict2e Info: Driver file for pict2e: p2e-xetex.def on input line 121. +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/p2e-xetex.def +File: p2e-xetex.def 2016/02/05 v0.1u Driver-dependant file (RN,HjG,JT) +) +\pIIe@GRAPH=\toks17 +\@arclen=\dimen108 +\@arcrad=\dimen109 +\@tempdimd=\dimen110 +) (build/ellipse.sty +Package: ellipse 2004/11/05 v1.0 .dtx ellipse file +) +\fbox@oct=\count94 +\fbox@quad=\count95 +\fbox@diaq=\count96 +\fbox@sign=\count97 +\fbox@anglestart=\skip82 +\fbox@angleend=\skip83 +\fbox@dash=\skip84 +\fbox@dashskip=\skip85 +\fbox@anglecur=\skip86 +\fbox@dashangle=\skip87 +\fbox@dashskipangle=\skip88 +\fbox@delta=\skip89 +\fbox@from=\skip90 +\fbox@to=\skip91 +\/fbox/padding-top=\skip92 +\/fbox/padding-right=\skip93 +\/fbox/padding-bottom=\skip94 +\/fbox/padding-left=\skip95 +\/fbox/padding-break-top=\skip96 +\/fbox/padding-break-bottom=\skip97 +\/fbox/margin-top=\skip98 +\/fbox/margin-right=\skip99 +\/fbox/margin-bottom=\skip100 +\/fbox/margin-left=\skip101 +\/fbox/margin-break-top=\skip102 +\/fbox/margin-break-bottom=\skip103 +\/fbox/border-top-width=\skip104 +\/fbox/border-right-width=\skip105 +\/fbox/border-bottom-width=\skip106 +\/fbox/border-left-width=\skip107 +\/fbox/border-break-top-width=\skip108 +\/fbox/border-break-bottom-width=\skip109 +\/fbox/@lower=\skip110 +\/fbox/@padding-box-height=\skip111 +\/fbox/@padding-box-depth=\skip112 +\/fbox/@padding-box-width=\skip113 +\/fbox/@border-box-width=\skip114 +\/fbox/@border-box-height=\skip115 +\/fbox/@border-box-depth=\skip116 +\/fbox/@border-top-left-radius-x=\skip117 +\/fbox/@border-top-right-radius-x=\skip118 +\/fbox/@border-bottom-left-radius-x=\skip119 +\/fbox/@border-bottom-right-radius-x=\skip120 +\/fbox/@border-top-left-radius-y=\skip121 +\/fbox/@border-top-right-radius-y=\skip122 +\/fbox/@border-bottom-left-radius-y=\skip123 +\/fbox/@border-bottom-right-radius-y=\skip124 +\/fbox/@border-top-left-ix=\skip125 +\/fbox/@border-top-left-iy=\skip126 +\/fbox/@border-top-right-ix=\skip127 +\/fbox/@border-top-right-iy=\skip128 +\/fbox/@border-bottom-left-ix=\skip129 +\/fbox/@border-bottom-left-iy=\skip130 +\/fbox/@border-bottom-right-ix=\skip131 +\/fbox/@border-bottom-right-iy=\skip132 +\/fbox/@border-top-left-phi=\skip133 +\/fbox/@border-top-right-phi=\skip134 +\/fbox/@border-bottom-left-phi=\skip135 +\/fbox/@border-bottom-right-phi=\skip136 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2016/03/03 v2.15a AMS math features +\@mathmargin=\skip137 +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2000/06/29 v2.01 AMS text +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen111 +)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen112 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 1999/12/14 v2.01 operator names +) +\inf@bad=\count98 +LaTeX Info: Redefining \frac on input line 199. +\uproot@=\count99 +\leftroot@=\count100 +LaTeX Info: Redefining \overline on input line 297. +\classnum@=\count101 +\DOTSCASE@=\count102 +LaTeX Info: Redefining \ldots on input line 394. +LaTeX Info: Redefining \dots on input line 397. +LaTeX Info: Redefining \cdots on input line 518. +\Mathstrutbox@=\box30 +\strutbox@=\box31 +\big@size=\dimen113 +LaTeX Font Info: Redeclaring font encoding OML on input line 630. +LaTeX Font Info: Redeclaring font encoding OMS on input line 631. +\macc@depth=\count103 +\c@MaxMatrixCols=\count104 +\dotsspace@=\muskip10 +\c@parentequation=\count105 +\dspbrk@lvl=\count106 +\tag@help=\toks19 +\row@=\count107 +\column@=\count108 +\maxfields@=\count109 +\andhelp@=\toks20 +\eqnshift@=\dimen114 +\alignsep@=\dimen115 +\tagshift@=\dimen116 +\tagwidth@=\dimen117 +\totwidth@=\dimen118 +\lineht@=\dimen119 +\@envbody=\toks21 +\multlinegap=\skip138 +\multlinetaggap=\skip139 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2735. +LaTeX Info: Redefining \] on input line 2736. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +) (/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/stmaryrd.sty +Package: stmaryrd 1994/03/03 St Mary's Road symbol package +\symstmry=\mathgroup6 +LaTeX Font Info: Overwriting symbol font `stmry' in version `bold' +(Font) U/stmry/m/n --> U/stmry/b/n on input line 89. +) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty +Package: textcomp 2005/09/27 v1.99g Standard LaTeX package +Package textcomp Info: Sub-encoding information: +(textcomp) 5 = only ISO-Adobe without \textcurrency +(textcomp) 4 = 5 + \texteuro +(textcomp) 3 = 4 + \textohm +(textcomp) 2 = 3 + \textestimated + \textcurrency +(textcomp) 1 = TS1 - \textcircled - \t +(textcomp) 0 = TS1 (full) +(textcomp) Font families with sub-encoding setting implement +(textcomp) only a restricted character set as indicated. +(textcomp) Family '?' is the default used for unknown fonts. +(textcomp) See the documentation for details. +Package textcomp Info: Setting ? sub-encoding to TS1/1 on input line 79. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +) +LaTeX Info: Redefining \oldstylenums on input line 334. +Package textcomp Info: Setting cmr sub-encoding to TS1/0 on input line 349. +Package textcomp Info: Setting cmss sub-encoding to TS1/0 on input line 350. +Package textcomp Info: Setting cmtt sub-encoding to TS1/0 on input line 351. +Package textcomp Info: Setting cmvtt sub-encoding to TS1/0 on input line 352. +Package textcomp Info: Setting cmbr sub-encoding to TS1/0 on input line 353. +Package textcomp Info: Setting cmtl sub-encoding to TS1/0 on input line 354. +Package textcomp Info: Setting ccr sub-encoding to TS1/0 on input line 355. +Package textcomp Info: Setting ptm sub-encoding to TS1/4 on input line 356. +Package textcomp Info: Setting pcr sub-encoding to TS1/4 on input line 357. +Package textcomp Info: Setting phv sub-encoding to TS1/4 on input line 358. +Package textcomp Info: Setting ppl sub-encoding to TS1/3 on input line 359. +Package textcomp Info: Setting pag sub-encoding to TS1/4 on input line 360. +Package textcomp Info: Setting pbk sub-encoding to TS1/4 on input line 361. +Package textcomp Info: Setting pnc sub-encoding to TS1/4 on input line 362. +Package textcomp Info: Setting pzc sub-encoding to TS1/4 on input line 363. +Package textcomp Info: Setting bch sub-encoding to TS1/4 on input line 364. +Package textcomp Info: Setting put sub-encoding to TS1/5 on input line 365. +Package textcomp Info: Setting uag sub-encoding to TS1/5 on input line 366. +Package textcomp Info: Setting ugq sub-encoding to TS1/5 on input line 367. +Package textcomp Info: Setting ul8 sub-encoding to TS1/4 on input line 368. +Package textcomp Info: Setting ul9 sub-encoding to TS1/4 on input line 369. +Package textcomp Info: Setting augie sub-encoding to TS1/5 on input line 370. +Package textcomp Info: Setting dayrom sub-encoding to TS1/3 on input line 371. +Package textcomp Info: Setting dayroms sub-encoding to TS1/3 on input line 372. +Package textcomp Info: Setting pxr sub-encoding to TS1/0 on input line 373. +Package textcomp Info: Setting pxss sub-encoding to TS1/0 on input line 374. +Package textcomp Info: Setting pxtt sub-encoding to TS1/0 on input line 375. +Package textcomp Info: Setting txr sub-encoding to TS1/0 on input line 376. +Package textcomp Info: Setting txss sub-encoding to TS1/0 on input line 377. +Package textcomp Info: Setting txtt sub-encoding to TS1/0 on input line 378. +Package textcomp Info: Setting lmr sub-encoding to TS1/0 on input line 379. +Package textcomp Info: Setting lmdh sub-encoding to TS1/0 on input line 380. +Package textcomp Info: Setting lmss sub-encoding to TS1/0 on input line 381. +Package textcomp Info: Setting lmssq sub-encoding to TS1/0 on input line 382. +Package textcomp Info: Setting lmvtt sub-encoding to TS1/0 on input line 383. +Package textcomp Info: Setting lmtt sub-encoding to TS1/0 on input line 384. +Package textcomp Info: Setting qhv sub-encoding to TS1/0 on input line 385. +Package textcomp Info: Setting qag sub-encoding to TS1/0 on input line 386. +Package textcomp Info: Setting qbk sub-encoding to TS1/0 on input line 387. +Package textcomp Info: Setting qcr sub-encoding to TS1/0 on input line 388. +Package textcomp Info: Setting qcs sub-encoding to TS1/0 on input line 389. +Package textcomp Info: Setting qpl sub-encoding to TS1/0 on input line 390. +Package textcomp Info: Setting qtm sub-encoding to TS1/0 on input line 391. +Package textcomp Info: Setting qzc sub-encoding to TS1/0 on input line 392. +Package textcomp Info: Setting qhvc sub-encoding to TS1/0 on input line 393. +Package textcomp Info: Setting futs sub-encoding to TS1/4 on input line 394. +Package textcomp Info: Setting futx sub-encoding to TS1/4 on input line 395. +Package textcomp Info: Setting futj sub-encoding to TS1/4 on input line 396. +Package textcomp Info: Setting hlh sub-encoding to TS1/3 on input line 397. +Package textcomp Info: Setting hls sub-encoding to TS1/3 on input line 398. +Package textcomp Info: Setting hlst sub-encoding to TS1/3 on input line 399. +Package textcomp Info: Setting hlct sub-encoding to TS1/5 on input line 400. +Package textcomp Info: Setting hlx sub-encoding to TS1/5 on input line 401. +Package textcomp Info: Setting hlce sub-encoding to TS1/5 on input line 402. +Package textcomp Info: Setting hlcn sub-encoding to TS1/5 on input line 403. +Package textcomp Info: Setting hlcw sub-encoding to TS1/5 on input line 404. +Package textcomp Info: Setting hlcf sub-encoding to TS1/5 on input line 405. +Package textcomp Info: Setting pplx sub-encoding to TS1/3 on input line 406. +Package textcomp Info: Setting pplj sub-encoding to TS1/3 on input line 407. +Package textcomp Info: Setting ptmx sub-encoding to TS1/4 on input line 408. +Package textcomp Info: Setting ptmj sub-encoding to TS1/4 on input line 409. +) (/usr/share/texlive/texmf-dist/tex/latex/psnfss/pifont.sty +Package: pifont 2005/04/12 PSNFSS-v9.2a Pi font support (SPQR) +LaTeX Font Info: Try loading font information for U+pzd on input line 63. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upzd.fd +File: upzd.fd 2001/06/04 font definitions for U/pzd. +) +LaTeX Font Info: Try loading font information for U+psy on input line 64. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upsy.fd +File: upsy.fd 2001/06/04 font definitions for U/psy. +)) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2012/11/06 v6.83m Hypertext links for LaTeX +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO) +Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO) +Package hobsub Info: Skipping package `infwarerr' (already loaded). +Package hobsub Info: Skipping package `ltxcmds' (already loaded). +Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO) +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is not detected. +Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) +Package etexcmds Info: Could not find \expanded. +(etexcmds) That can mean that you are not using pdfTeX 1.50 or +(etexcmds) that some package has redefined \expanded. +(etexcmds) In the latter case, load this package earlier. +Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) +Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO) +Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: pdfTeX >= 1.30 not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode not found. +Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO) +Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO) +Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO) +Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO) +Package: xcolor-patch 2011/01/30 xcolor patch +Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO) +Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO) +Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO) +Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2011/03/04 v1.3 Hooks for auxiliary files (HO) +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) +) +\@linkdim=\dimen120 +\Hy@linkcounter=\count110 +\Hy@pagecounter=\count111 +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count112 +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Hyper figures OFF on input line 4443. +Package hyperref Info: Link nesting OFF on input line 4448. +Package hyperref Info: Hyper index ON on input line 4451. +Package hyperref Info: Plain pages OFF on input line 4458. +Package hyperref Info: Backreferencing OFF on input line 4463. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4688. +\c@Hy@tempcnt=\count113 +(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip11 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 5041. +\XeTeXLinkMargin=\dimen121 +\Fld@menulength=\count114 +\Field@Width=\dimen122 +\Fld@charsize=\dimen123 +Package hyperref Info: Hyper figures OFF on input line 6295. +Package hyperref Info: Link nesting OFF on input line 6300. +Package hyperref Info: Hyper index ON on input line 6303. +Package hyperref Info: backreferencing OFF on input line 6310. +Package hyperref Info: Link coloring OFF on input line 6315. +Package hyperref Info: Link coloring with OCG OFF on input line 6320. +Package hyperref Info: PDF/A mode OFF on input line 6325. +LaTeX Info: Redefining \ref on input line 6365. +LaTeX Info: Redefining \pageref on input line 6369. +\Hy@abspage=\count115 +\c@Item=\count116 +\c@Hfootnote=\count117 +) + +Package hyperref Message: Driver (autodetected): hxetex. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hxetex.def +File: hxetex.def 2012/11/06 v6.83m Hyperref driver for XeTeX +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def +File: puenc.def 2012/11/06 v6.83m Hyperref: PDF Unicode definition (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/stringenc.sty +Package: stringenc 2011/12/02 v1.10 Convert strings between diff. encodings (HO) +) +\pdfm@box=\box32 +\c@Hy@AnnotLevel=\count118 +\HyField@AnnotCount=\count119 +\Fld@listcount=\count120 +\c@bookmark@seq@number=\count121 +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO) +Package rerunfilecheck Info: Feature \pdfmdfivesum is not available +(rerunfilecheck) (e.g. pdfTeX or LuaTeX with package `pdftexcmds'). +(rerunfilecheck) Therefore file contents cannot be checked efficiently +(rerunfilecheck) and the loading of the package is aborted. +) +\Hy@SectionHShift=\skip140 +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bookmark.sty +Package: bookmark 2011/12/02 v1.24 PDF bookmarks (HO) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bkm-dvipdfm.def +File: bkm-dvipdfm.def 2011/12/02 v1.24 bookmark driver for dvipdfm (HO) +\BKM@id=\count122 +)) (/usr/share/texlive/texmf-dist/tex/latex/booktabs/booktabs.sty +Package: booktabs 2005/04/14 v1.61803 publication quality tables +\heavyrulewidth=\dimen124 +\lightrulewidth=\dimen125 +\cmidrulewidth=\dimen126 +\belowrulesep=\dimen127 +\belowbottomsep=\dimen128 +\aboverulesep=\dimen129 +\abovetopsep=\dimen130 +\cmidrulesep=\dimen131 +\cmidrulekern=\dimen132 +\defaultaddspace=\dimen133 +\@cmidla=\count123 +\@cmidlb=\count124 +\@aboverulesep=\dimen134 +\@belowrulesep=\dimen135 +\@thisruleclass=\count125 +\@lastruleclass=\count126 +\@thisrulewidth=\dimen136 +) (/usr/share/texlive/texmf-dist/tex/latex/tools/longtable.sty +Package: longtable 2014/10/28 v4.11 Multi-page Table package (DPC) +\LTleft=\skip141 +\LTright=\skip142 +\LTpre=\skip143 +\LTpost=\skip144 +\LTchunksize=\count127 +\LTcapwidth=\dimen137 +\LT@head=\box33 +\LT@firsthead=\box34 +\LT@foot=\box35 +\LT@lastfoot=\box36 +\LT@cols=\count128 +\LT@rows=\count129 +\c@LT@tables=\count130 +\c@LT@chunks=\count131 +\LT@p@ftn=\toks23 +) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Package: anyfontsize 2007/11/22 anyfontsize.sty by pts +) (/usr/share/texlive/texmf-dist/tex/latex/enumitem/enumitem.sty +Package: enumitem 2011/09/28 v3.5.2 Customized lists +\labelindent=\skip145 +\enit@outerparindent=\dimen138 +\enit@toks=\toks24 +\enit@inbox=\box37 +\enitdp@description=\count132 +) (/usr/share/texlive/texmf-dist/tex/latex/wrapfig/wrapfig.sty +\wrapoverhang=\dimen139 +\WF@size=\dimen140 +\c@WF@wrappedlines=\count133 +\WF@box=\box38 +\WF@everypar=\toks25 +Package: wrapfig 2003/01/31 v 3.6 +) (/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.sty (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty +Package: expl3 2016/01/19 v6377 L3 programming layer (loader) +(/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3-code.tex +Package: expl3 2016/01/19 v6377 L3 programming layer (code) +L3 Module: l3bootstrap 2016/01/01 v6339 L3 Bootstrap code +L3 Module: l3names 2015/12/21 v6328 L3 Namespace for primitives +L3 Module: l3basics 2015/11/22 v6315 L3 Basic definitions +L3 Module: l3expan 2015/09/10 v5983 L3 Argument expansion +L3 Module: l3tl 2015/09/29 v6121 L3 Token lists +L3 Module: l3str 2016/01/03 v6357 L3 Strings +L3 Module: l3seq 2015/08/05 v5777 L3 Sequences and stacks +L3 Module: l3int 2016/01/05 v6366 L3 Integers +\c_max_int=\count134 +\l_tmpa_int=\count135 +\l_tmpb_int=\count136 +\g_tmpa_int=\count137 +\g_tmpb_int=\count138 +L3 Module: l3quark 2015/08/17 v5855 L3 Quarks +L3 Module: l3prg 2015/11/01 v6216 L3 Control structures +\g__prg_map_int=\count139 +L3 Module: l3clist 2015/09/02 v5901 L3 Comma separated lists +L3 Module: l3token 2015/11/11 v6249 L3 Experimental token manipulation +L3 Module: l3prop 2016/01/05 v6366 L3 Property lists +L3 Module: l3msg 2015/09/28 v6113 L3 Messages +L3 Module: l3file 2015/12/03 v6317 L3 File and I/O operations +\l_iow_line_count_int=\count140 +\l__iow_target_count_int=\count141 +\l__iow_current_line_int=\count142 +\l__iow_current_word_int=\count143 +\l__iow_current_indentation_int=\count144 +L3 Module: l3skip 2016/01/05 v6366 L3 Dimensions and skips +\c_zero_dim=\dimen141 +\c_max_dim=\dimen142 +\l_tmpa_dim=\dimen143 +\l_tmpb_dim=\dimen144 +\g_tmpa_dim=\dimen145 +\g_tmpb_dim=\dimen146 +\c_zero_skip=\skip146 +\c_max_skip=\skip147 +\l_tmpa_skip=\skip148 +\l_tmpb_skip=\skip149 +\g_tmpa_skip=\skip150 +\g_tmpb_skip=\skip151 +\c_zero_muskip=\muskip12 +\c_max_muskip=\muskip13 +\l_tmpa_muskip=\muskip14 +\l_tmpb_muskip=\muskip15 +\g_tmpa_muskip=\muskip16 +\g_tmpb_muskip=\muskip17 +L3 Module: l3keys 2015/11/17 v6284 L3 Key-value interfaces +\g__keyval_level_int=\count145 +\l_keys_choice_int=\count146 +L3 Module: l3fp 2015/08/25 v5890 L3 Floating points +\c__fp_leading_shift_int=\count147 +\c__fp_middle_shift_int=\count148 +\c__fp_trailing_shift_int=\count149 +\c__fp_big_leading_shift_int=\count150 +\c__fp_big_middle_shift_int=\count151 +\c__fp_big_trailing_shift_int=\count152 +\c__fp_Bigg_leading_shift_int=\count153 +\c__fp_Bigg_middle_shift_int=\count154 +\c__fp_Bigg_trailing_shift_int=\count155 +L3 Module: l3box 2015/08/09 v5822 L3 Experimental boxes +\c_empty_box=\box39 +\l_tmpa_box=\box40 +\l_tmpb_box=\box41 +\g_tmpa_box=\box42 +\g_tmpb_box=\box43 +L3 Module: l3coffins 2015/08/06 v5789 L3 Coffin code layer +\l__coffin_internal_box=\box44 +\l__coffin_internal_dim=\dimen147 +\l__coffin_offset_x_dim=\dimen148 +\l__coffin_offset_y_dim=\dimen149 +\l__coffin_x_dim=\dimen150 +\l__coffin_y_dim=\dimen151 +\l__coffin_x_prime_dim=\dimen152 +\l__coffin_y_prime_dim=\dimen153 +\c_empty_coffin=\box45 +\l__coffin_aligned_coffin=\box46 +\l__coffin_aligned_internal_coffin=\box47 +\l_tmpa_coffin=\box48 +\l_tmpb_coffin=\box49 +\l__coffin_display_coffin=\box50 +\l__coffin_display_coord_coffin=\box51 +\l__coffin_display_pole_coffin=\box52 +\l__coffin_display_offset_dim=\dimen154 +\l__coffin_display_x_dim=\dimen155 +\l__coffin_display_y_dim=\dimen156 +L3 Module: l3color 2014/08/23 v5354 L3 Experimental color support +L3 Module: l3sys 2015/09/25 v6087 L3 Experimental system/runtime functions +L3 Module: l3candidates 2016/01/14 v6376 L3 Experimental additions to l3kernel +\l__box_top_dim=\dimen157 +\l__box_bottom_dim=\dimen158 +\l__box_left_dim=\dimen159 +\l__box_right_dim=\dimen160 +\l__box_top_new_dim=\dimen161 +\l__box_bottom_new_dim=\dimen162 +\l__box_left_new_dim=\dimen163 +\l__box_right_new_dim=\dimen164 +\l__box_internal_box=\box53 +\l__coffin_bounding_shift_dim=\dimen165 +\l__coffin_left_corner_dim=\dimen166 +\l__coffin_right_corner_dim=\dimen167 +\l__coffin_bottom_corner_dim=\dimen168 +\l__coffin_top_corner_dim=\dimen169 +\l__coffin_scaled_total_height_dim=\dimen170 +\l__coffin_scaled_width_dim=\dimen171 +L3 Module: l3luatex 2015/11/11 v6250 L3 Experimental LuaTeX-specific functions +) (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def +File: l3xdvidpfmx.def 2015/11/11 v6250 L3 Experimental driver: xdvipdfmx +)) (/usr/share/texlive/texmf-dist/tex/latex/l3packages/xparse/xparse.sty +Package: xparse 2016/01/19 v6377 L3 Experimental document command parser +\l__xparse_current_arg_int=\count156 +\l__xparse_m_args_int=\count157 +\l__xparse_mandatory_args_int=\count158 +\l__xparse_processor_int=\count159 +\l__xparse_v_nesting_int=\count160 +) +Package: fontspec 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec-xetex.sty +Package: fontspec-xetex 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +\l_fontspec_script_int=\count161 +\l_fontspec_language_int=\count162 +\l_fontspec_strnum_int=\count163 +\l__fontspec_tmpa_dim=\dimen172 +\l__fontspec_tmpb_dim=\dimen173 +\l__fontspec_tmpc_dim=\dimen174 +\g__file_internal_ior=\read1 +(/usr/share/texlive/texmf-dist/tex/latex/base/fontenc.sty +Package: fontenc 2005/09/27 v1.99g Standard LaTeX package +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1enc.def +File: eu1enc.def 2010/05/27 v0.1h Experimental Unicode font encodings +) +LaTeX Font Info: Try loading font information for EU1+lmr on input line 105. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmr.fd +File: eu1lmr.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) (/usr/share/texlive/texmf-dist/tex/xelatex/xunicode/xunicode.sty +File: xunicode.sty 2011/09/09 v0.981 provides access to latin accents and many other characters in Unicode lower plane +(/usr/share/texmf/tex/latex/tipa/t3enc.def +File: t3enc.def 2001/12/31 T3 encoding +LaTeX Font Info: Try loading font information for EU1+lmss on input line 357. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmss.fd +File: eu1lmss.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) +\tipaTiiicode=\count164 +\tipasavetokens=\toks26 +\tipachecktokens=\toks27 +) +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \__fontspec_post_arg:w with sig. 'mmO{}' on line 353. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \fontspec with sig. 'om' on line 355. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmainfont with sig. 'om' on line 365. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setsansfont with sig. 'om' on line 375. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmonofont with sig. 'om' on line 385. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathrm with sig. 'om' on line 399. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setboldmathrm with sig. 'om' on line 407. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathsf with sig. 'om' on line 415. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathtt with sig. 'om' on line 423. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfamily with sig. 'mom' on line 437. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontface with sig. 'mom' on line 453. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \defaultfontfeatures with sig. 't+om' on line 467. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \addfontfeatures with sig. 'm' on line 529. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfeature with sig. 'mm' on line 540. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newAATfeature with sig. 'mmmm' on line 548. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newopentypefeature with sig. 'mmm' on line 556. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeature with sig. 'mm' on line 577. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeatureoption with sig. 'mmm' on line 586. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontscript with sig. 'mm' on line 590. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontlanguage with sig. 'mm' on line 594. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \DeclareFontsExtensions with sig. 'm' on line 599. +................................................. +\l__fontspec_tmp_int=\count165 +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.cfg) +LaTeX Info: Redefining \itshape on input line 2705. +LaTeX Info: Redefining \slshape on input line 2710. +LaTeX Info: Redefining \scshape on input line 2715. +LaTeX Info: Redefining \upshape on input line 2720. +\l__fontspec_em_int=\count166 +\l__fontspec_emdef_int=\count167 +LaTeX Info: Redefining \em on input line 2736. +LaTeX Info: Redefining \emph on input line 2742. +LaTeX Info: Redefining \- on input line 2746. +................................................. +. LaTeX info: "xparse/redefine-command" +. +. Redefining command \oldstylenums with sig. 'm' on line 2841. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \liningnums with sig. 'm' on line 2845. +................................................. +)) +Package hyperref Info: Option `colorlinks' set `true' on input line 87. +\px=\skip152 +\c@md@targetcount=\count168 +\mdcompactskip=\skip153 +\mdcompacttopsep=\skip154 +\dim@rem=\skip155 +\dim@ch=\skip156 +\md@height=\skip157 +\dim@marginbottom=\skip158 +\dim@paddingbottom=\skip159 +\md@interaction=\count169 +\mddefinitionsskip=\skip160 +\md@captionlen=\skip161 +\mdtoclevel=\count170 +\c@mdtoclevelbold=\count171 +\c@mdtocleveldots=\count172 +\mdtocskip=\skip162 +\mdpreskip=\skip163 +\presp=\skip164 +LaTeX Font Info: Try loading font information for EU1+lmtt on input line 801. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmtt.fd +File: eu1lmtt.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +\md@postskip=\skip165 +\ppresp=\skip166 +\md@thmcaption=\box54 +\md@defaultcolwidth=\skip167 +\mdtabularskip=\skip168 +\mdbibindentunit=\skip169 +\c@md@authorcount=\count173 +\c@mdx@authorcount=\count174 +\c@@mdTargetCount=\count175 +\@snippetBox=\box55 +\@snippetWidth=\skip170 +\@snippetHeight=\skip171 +\@snippetDepth=\skip172 +\c@snippets=\count176 +) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty +Package: geometry 2010/09/12 v5.6 Page Geometry +\Gm@cnth=\count177 +\Gm@cntv=\count178 +\c@Gm@tempcnt=\count179 +\Gm@bindingoffset=\dimen175 +\Gm@wd@mp=\dimen176 +\Gm@odd@mp=\dimen177 +\Gm@even@mp=\dimen178 +\Gm@layoutwidth=\dimen179 +\Gm@layoutheight=\dimen180 +\Gm@layouthoffset=\dimen181 +\Gm@layoutvoffset=\dimen182 +\Gm@dimlist=\toks28 +) (/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +\fancy@headwidth=\skip173 +\f@ncyO@elh=\skip174 +\f@ncyO@erh=\skip175 +\f@ncyO@olh=\skip176 +\f@ncyO@orh=\skip177 +\f@ncyO@elf=\skip178 +\f@ncyO@erf=\skip179 +\f@ncyO@olf=\skip180 +\f@ncyO@orf=\skip181 +) (build/P4Runtime-Spec.aux + +LaTeX Warning: Label `sec-example' multiply defined. + +) +\openout1 = `P4Runtime-Spec.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for TS1+cmr on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1cmr.fd +File: ts1cmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions +) +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for EU1/lmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T3/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for T3+cmr on input line 14. +(/usr/share/texmf/tex/latex/tipa/t3cmr.fd +File: t3cmr.fd 2001/12/31 TIPA font definitions +) +LaTeX Font Info: ... okay on input line 14. +\AtBeginShipoutBox=\box56 +Package hyperref Info: Link coloring ON on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2012/10/27 v2.43 Cross-referencing by name of section +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO) +) +\c@section@level=\count180 +) +LaTeX Info: Redefining \ref on input line 14. +LaTeX Info: Redefining \pageref on input line 14. +LaTeX Info: Redefining \nameref on input line 14. +................................................. +. fontspec info: "setup-math" +. +. Adjusting the maths setup (use [no-math] to avoid this). +................................................. +\symlegacymaths=\mathgroup7 +LaTeX Font Info: Overwriting symbol font `legacymaths' in version `bold' +(Font) OT1/cmr/m/n --> OT1/cmr/bx/n on input line 14. +LaTeX Font Info: Redeclaring math accent \acute on input line 14. +LaTeX Font Info: Redeclaring math accent \grave on input line 14. +LaTeX Font Info: Redeclaring math accent \ddot on input line 14. +LaTeX Font Info: Redeclaring math accent \tilde on input line 14. +LaTeX Font Info: Redeclaring math accent \bar on input line 14. +LaTeX Font Info: Redeclaring math accent \breve on input line 14. +LaTeX Font Info: Redeclaring math accent \check on input line 14. +LaTeX Font Info: Redeclaring math accent \hat on input line 14. +LaTeX Font Info: Redeclaring math accent \dot on input line 14. +LaTeX Font Info: Redeclaring math accent \mathring on input line 14. +LaTeX Font Info: Redeclaring math symbol \Gamma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Delta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Theta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Lambda on input line 14. +LaTeX Font Info: Redeclaring math symbol \Xi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Pi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Sigma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Upsilon on input line 14. +LaTeX Font Info: Redeclaring math symbol \Phi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Psi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Omega on input line 14. +LaTeX Font Info: Redeclaring math symbol \mathdollar on input line 14. +LaTeX Font Info: Redeclaring symbol font `operators' on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `normal' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/cmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `bold' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/cmr/bx/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) EU1/lmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/cmr/m/it --> EU1/lmr/m/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/cmr/bx/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/cmss/m/n --> EU1/lmss/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/cmtt/m/n --> EU1/lmtt/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) EU1/lmr/m/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' +(Font) OT1/cmr/bx/it --> EU1/lmr/bx/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/cmss/bx/n --> EU1/lmss/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/cmtt/m/n --> EU1/lmtt/bx/n on input line 14. +*geometry* driver: auto-detecting +*geometry* detected driver: xetex +*geometry* verbose mode - [ preamble ] result: +* driver: xetex +* paper: +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: +* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt) +* v-part:(T,H,B)=(72.26999pt, 632.3625pt, 90.3375pt) +* \paperwidth=614.295pt +* \paperheight=794.96999pt +* \textwidth=469.75502pt +* \textheight=632.3625pt +* \oddsidemargin=0.0pt +* \evensidemargin=0.0pt +* \topmargin=-37.0pt +* \headheight=30.0pt +* \headsep=25.0pt +* \topskip=11.0pt +* \footskip=30.0pt +* \marginparwidth=59.0pt +* \marginparsep=10.0pt +* \columnsep=10.0pt +* \skip\footins=10.0pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +resolve font stack: UtopiaStd-Regular + +\g__fontspec_family_UtopiaStd-Regular_int=\count181 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'UtopiaStd-Regular(0)' created for font 'UtopiaStd-Regular' with +. options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;" +. - 'small caps' (m/sc) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;+smcp;" +................................................. + +resolved font stack 'UtopiaStd-Regular' to: UtopiaStd-Regular +LaTeX Font Info: Try loading font information for U+msa on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Try loading font information for U+msb on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Try loading font information for U+stmry on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/Ustmry.fd) + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/bx/n' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 35. + +resolve font stack: LuxiMono + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +\g__fontspec_family_LuxiMono_int=\count182 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'LuxiMono(0)' created for font 'LuxiMono' with options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: <->"LuxiMono/OT:" +. - 'small caps' (m/sc) with NFSS spec.: +................................................. + +resolved font stack 'LuxiMono' to: LuxiMono +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/se-ascii-print.def +File: se-ascii-print.def 2011/12/02 v1.10 stringenc: Printable ASCII characters +) [1 + +] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[2] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <10.95> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 309. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Font Warning: Font shape `EU1/LuxiMono(0)/bx/n' undefined +(Font) using `EU1/LuxiMono(0)/m/n' instead on input line 309. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[3] [4] + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/m/it' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 521. + +[5] [6] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[7] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/reference-architecture.png Graphic file (type QTm) + [8] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[9] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[10] +File: build/single-embedded-controller.png Graphic file (type QTm) + [11] +File: build/single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-controllers.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-ha-controllers.png Graphic file (type QTm) + [12] [13] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[14] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[15] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <12> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 1532. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1532. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1532. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1532. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1532. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1532. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1532. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1532. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1532. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1532. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1532. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1532. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1532. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1532. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[16] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[17] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (65.03293pt too wide) in paragraph at lines 1800--1803 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For all backup controllers, \EU1/LuxiMono(0)/bx/n/8.2125 status \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set to non-OK (with \EU1/LuxiMono(0)/bx/n/8.2125 status.code \EU1/UtopiaStd-Regular(0)/m/it/10.95 set to \EU1/LuxiMono(0)/bx/n/8.2125 google.rpc.ALREADY_EXISTS\EU1/UtopiaStd-Regular(0)/m/it/10.95 ). + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[18] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1837. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1837. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1837. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1837. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1837. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1837. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1837. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1837. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1837. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1837. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1837. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1837. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1837. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1861. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1861. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1861. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1861. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1861. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1861. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1861. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1861. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1861. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1861. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1861. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1861. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1861. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[19] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1906. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1906. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1906. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1906. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1906. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1906. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1906. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1906. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1906. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1906. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1906. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1906. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1906. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[20] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[21] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[22] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2189. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2189. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2189. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2189. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2189. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2189. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2189. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2189. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2189. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2189. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2189. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2189. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2189. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[23] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1057) in paragraph at lines 2239--2243 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For structured annotations, every \EU1/LuxiMono(0)/bx/n/8.2125 StructuredAnnotation \EU1/UtopiaStd-Regular(0)/m/it/10.95 message contains an optional field + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2246. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2246. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2246. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2246. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2246. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2246. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2246. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2246. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2246. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2246. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2246. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2246. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2246. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[24] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[25] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[26] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (12.45624pt too wide) in paragraph at lines 2477--2490 + [] + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2513. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2513. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2513. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2513. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2513. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2513. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2513. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2513. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2513. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2513. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2513. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2513. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2513. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[27] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[28] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2704. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2704. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2764. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2764. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2764. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2764. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2764. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2764. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2764. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2764. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2764. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2764. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2764. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2764. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2764. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[29] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2838. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2838. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[30] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2919. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2919. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.59204pt too wide) in paragraph at lines 2973--2975 +[]\EU1/LuxiMono(0)/bx/n/8.2125 BYTES\EU1/UtopiaStd-Regular(0)/m/it/10.95 , which signifies that this meter can be configured with rates expressed in bytes/second. + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2998. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2998. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2998. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2998. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2998. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2998. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2998. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2998. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2998. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2998. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2998. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2998. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2998. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[31] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (18.74199pt too wide) in paragraph at lines 3015--3022 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 carrying P4 standard annotations \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_in") \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_out")\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[32] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[33] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3157. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3157. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3157. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3157. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3157. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3157. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3157. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3157. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3157. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3157. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3157. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3157. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3157. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[34] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[35] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3385. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3385. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3385. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3385. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3385. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3385. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3385. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3385. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3385. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3385. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3385. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3385. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3385. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3432. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3432. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3432. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3432. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3432. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3432. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3432. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3432. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3432. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3432. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3432. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3432. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3432. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[36] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3470. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3470. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3470. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3470. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3470. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3470. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3470. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3470. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3470. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3470. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3470. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3470. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3470. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[37] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[38] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[39] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[40] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[41] [42] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1629) in paragraph at lines 4074--4076 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For example, the following P4$[]$ objects involve complex types that need to be exposed in + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[43] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1454) in paragraph at lines 4122--4131 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 ification for all the named types in the P4$[]$ program. These named types are \EU1/LuxiMono(0)/bx/n/8.2125 struct\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 header\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + + +Underfull \hbox (badness 1831) in paragraph at lines 4122--4131 +\EU1/LuxiMono(0)/bx/n/8.2125 header_union\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 enum \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 serializable_enum\EU1/UtopiaStd-Regular(0)/m/it/10.95 ; for each of these we have a type specification mes- + [] + + +Underfull \hbox (badness 1845) in paragraph at lines 4122--4131 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 sage, respectively \EU1/LuxiMono(0)/bx/n/8.2125 P4StructTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnionTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4EnumTypeSpec \EU1/UtopiaStd-Regular(0)/m/it/10.95 and + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (33.06564pt too wide) in paragraph at lines 4157--4164 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 “binary string” types (\EU1/LuxiMono(0)/bx/n/8.2125 bit\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 int\EU1/UtopiaStd-Regular(0)/m/it/10.95 , and \EU1/LuxiMono(0)/bx/n/8.2125 varbit\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) are grouped together in the \EU1/LuxiMono(0)/bx/n/8.2125 P4BitstringLikeTypeSpec + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[44] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4174. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4174. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4174. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4174. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4174. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4174. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4174. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4174. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4174. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4174. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4174. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4174. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4174. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.46094pt too wide) in paragraph at lines 4211--4214 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 An invalid header union (i.e. all headers in the union are invalid) is represented by a \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnion + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[45] [46] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4348. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4348. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[47] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (24.68944pt too wide) in paragraph at lines 4436--4442 +[]\EU1/LuxiMono(0)/bx/n/8.2125 translated_type\EU1/UtopiaStd-Regular(0)/m/it/10.95 , if and only if the P4 \EU1/LuxiMono(0)/bx/n/8.2125 type \EU1/UtopiaStd-Regular(0)/m/it/10.95 declaration was annotated with \EU1/LuxiMono(0)/bx/n/8.2125 @p4runtime_translation\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[48] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[49] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (32.59732pt too wide) in paragraph at lines 4544--4550 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 in \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.MatchField\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.Action.Param \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.ControllerPacketMetadata.Metadata\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[50] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4651. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4651. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[51] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[52] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[53] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[54] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.53593pt too wide) in paragraph at lines 5114--5117 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 If the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 does not match the table description in the P4Info (e.g. the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 is \EU1/LuxiMono(0)/bx/n/8.2125 action_profile_member_id + [] + +[55] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[56] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[57] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[58] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[59] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[60] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[61] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5751. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5751. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[62] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[63] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[64] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (9.29865pt too wide) in paragraph at lines 6035--6037 + []\EU1/lmr/bx/n/10.95 9.2.2.1.| Rules on Setting \EU1/LuxiMono(0)/bx/n/8.2125 max_size[] \EU1/UtopiaStd-Regular(0)/m/it/10.95 The valid values for \EU1/LuxiMono(0)/bx/n/8.2125 max_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 depend on the static \EU1/LuxiMono(0)/bx/n/8.2125 max_group_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[65] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[66] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[67] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[68] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6323. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6323. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6363. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6363. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6363. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6363. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6363. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6363. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6363. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6363. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6363. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6363. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6363. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6363. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6363. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1331) in paragraph at lines 6366--6373 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 A direct counter is a direct resource associated with a \EU1/LuxiMono(0)/bx/n/8.2125 TableEntry \EU1/UtopiaStd-Regular(0)/m/it/10.95 (see [][]Direct Resources[][]). The + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[69] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6440. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6440. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6440. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6440. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6440. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6440. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6440. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6440. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6440. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6440. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6440. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6440. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6440. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[70] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6533. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6533. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6574. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6574. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6574. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6574. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6574. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6574. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6574. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6574. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6574. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6574. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6574. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6574. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6574. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[71] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6664. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6664. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6664. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6664. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6664. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6664. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6664. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6664. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6664. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6664. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6664. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6664. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6664. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[72] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6768. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6768. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6768. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6768. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6768. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6768. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6768. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6768. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6768. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6768. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6768. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6768. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6768. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6796. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6796. + +[73] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6806. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6806. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6806. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6806. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6806. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6806. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6806. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6806. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6806. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6806. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6806. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6806. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6806. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[74] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6930. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6930. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6930. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6930. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6930. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6930. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6930. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6930. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6930. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6930. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6930. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6930. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6930. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[75] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.93839pt too wide) in paragraph at lines 7041--7043 +[]\EU1/LuxiMono(0)/bx/n/8.2125 MODIFY\EU1/UtopiaStd-Regular(0)/m/it/10.95 : Modify the attributes of a given clone session entry, indexed by the given \EU1/LuxiMono(0)/bx/n/8.2125 clone_session_id\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[76] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7079. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7079. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7079. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7079. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7079. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7079. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7079. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7079. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7079. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7079. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7079. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7079. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7079. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[77] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[78] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7215. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7215. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7215. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7215. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7215. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7215. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7215. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7215. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7215. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7215. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7215. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7215. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7215. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7259. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[79] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[80] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7457. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7457. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7457. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7457. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7457. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7457. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7457. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7457. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7457. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7457. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7457. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7457. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7457. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[81] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/error-report.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[82] +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <14.4> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 7581. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7581. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7581. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: Hyper reference `wildcard-reads' on page 83 undefined on input line 7603. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[83] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7683. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7683. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7683. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7683. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7683. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7683. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7683. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7683. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7683. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7683. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7683. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7683. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7683. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[84] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[85] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[86] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (34.34796pt too wide) in paragraph at lines 7967--7972 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If an error is encountered before even trying to attempt individual batch updates, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +[87] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.66206pt too wide) in paragraph at lines 7976--7987 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 Otherwise, if one or more updates in the batch (\EU1/LuxiMono(0)/bx/n/8.2125 WriteRequest.updates\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) failed, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8023. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8023. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8023. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8023. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8023. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8023. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8023. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8023. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8023. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8023. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8023. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8023. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8023. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[88] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[89] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.4752pt too wide) in paragraph at lines 8258--8262 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 responding to \EU1/LuxiMono(0)/bx/n/8.2125 a \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 c\EU1/UtopiaStd-Regular(0)/m/it/10.95 , followed by a status \EU1/LuxiMono(0)/bx/n/8.2125 {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[90] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8344. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8344. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8344. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8344. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8344. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8344. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8344. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8344. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8344. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8344. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8344. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8344. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8344. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[91] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[92] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8467. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8467. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8467. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8467. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8467. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8467. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8467. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8467. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8467. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8467. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8467. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8467. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8467. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[93] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 8565--8568 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If a P4Runtime server supports both \EU1/LuxiMono(0)/bx/n/8.2125 SetForwardingPipelineConfig \EU1/UtopiaStd-Regular(0)/m/it/10.95 as well as returning the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[94] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[95] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[96] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[97] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[98] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8934. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8934. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[99] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 9002. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/psa-metadata-translation.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[100] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[101] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[102] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[103] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[104] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[105] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 9512--9519 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 p4info-ext should include a Protobuf message definition for every extern type that can + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[106] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 4036) in paragraph at lines 9567--9574 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 P4Runtime also supports streaming arbitrary Protobuf messages between the server and the + [] + + +Underfull \hbox (badness 1629) in paragraph at lines 9567--9574 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 client, by including an \EU1/LuxiMono(0)/bx/n/8.2125 Any \EU1/UtopiaStd-Regular(0)/m/it/10.95 Protobuf field [[][]31[][]] named \EU1/LuxiMono(0)/bx/n/8.2125 other \EU1/UtopiaStd-Regular(0)/m/it/10.95 in both \EU1/LuxiMono(0)/bx/n/8.2125 p4.v1.StreamMessageRequest + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[107] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[108] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1997) in paragraph at lines 9834--9836 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 Table [][]7[][] lists P4$[]$ annotations introduced primarily for the purpose of adding features for the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[109] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[110] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.61781pt too wide) in paragraph at lines 9981--9988 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 In gRPC, the status of a RPC request is sent as metadata, whose size is limited by the \EU1/LuxiMono(0)/bx/n/8.2125 grpc.max_metadata_size + [] + +[111] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 10000) in paragraph at lines 10072--10073 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Complex Types in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- p4- + [] + +[112] +Underfull \hbox (badness 4001) in paragraph at lines 10084--10085 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Google Cloud APIs Versioning - Backwards-Compatibility.” [][]\EU1/lmtt/m/n/10.95 https:// cloud. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10093--10094 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “gRPC Streaming RPCs in C++.” [][]\EU1/lmtt/m/n/10.95 https:// grpc. io/ docs/ tutorials/ basic/ c. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10105--10106 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “P4 Concurrency Model.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10108--10109 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10123--10124 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Protobuf OneOf Backwards-Compatibility Issues.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10129--10130 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Action Selector.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# sec- action- + [] + +[113] +Underfull \hbox (badness 2409) in paragraph at lines 10138--10139 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Empty Group Action Appendix.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10141--10142 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Select Expressions in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 1668) in paragraph at lines 10156--10157 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Any Protobuf Message.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ protocol- buffers/ docs/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10162--10163 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC C++ Error Details Library.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ grpc/ grpc/ blob/ master/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10165--10166 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC Canonical Status Codes.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ maps- booking/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10171--10172 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Protobuf MessageDifferencer in the C++ API.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10177--10178 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “v1model Architecture Definition.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ p4lang/ p4c/ blob/ master/ + [] + +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 10186. +[114] +Package atveryend Info: Empty hook `AfterLastShipout' on input line 10186. +(build/P4Runtime-Spec.aux) +Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 10186. +Package atveryend Info: Empty hook `AtEndAfterFileList' on input line 10186. + +LaTeX Font Warning: Some font shapes were not available, defaults substituted. + + +LaTeX Warning: There were undefined references. + + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 27555 strings out of 493638 + 517986 string characters out of 6146796 + 565138 words of memory out of 5000000 + 30657 multiletter control sequences out of 15000+600000 + 14633 words of font info for 98 fonts, out of 8000000 for 9000 + 1328 hyphenation exceptions out of 8191 + 48i,19n,81p,10429b,790s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on build/P4Runtime-Spec.pdf (114 pages). diff --git a/spec/v1.4.0-rc.5/P4Runtime-Spec.pdf b/spec/v1.4.0-rc.5/P4Runtime-Spec.pdf new file mode 100644 index 00000000..17fba13e Binary files /dev/null and b/spec/v1.4.0-rc.5/P4Runtime-Spec.pdf differ diff --git a/spec/v1.4.0-rc.5/P4Runtime-Spec.tex b/spec/v1.4.0-rc.5/P4Runtime-Spec.tex new file mode 100644 index 00000000..dc630a8e --- /dev/null +++ b/spec/v1.4.0-rc.5/P4Runtime-Spec.tex @@ -0,0 +1,10186 @@ +\documentclass[11pt]{article} +% generated by Madoko, version 1.1.4 +%mdk-data-line={1} + + +\usepackage[heading-base={2},section-num={False},bib-label={hide},fontspec={True}]{madoko2} +\usepackage[top=1in, bottom=1.25in, left=1in, right=1in]{geometry} +\usepackage{fancyhdr} +%mdk-data-line={11} + + \setlength{\headheight}{30pt} + \setlength{\emergencystretch}{2em} + +\begin{document} + + + +{\mdfontfamily{UtopiaStd-Regular} +%mdk-data-line={203} +\mdxtitleblockstart{} +%mdk-data-line={203} +\mdxtitle{{\sffamily{\bfseries\mdline{203}P4Runtime Specification}}}%mdk + +%mdk-data-line={206} +\mdxtitlenote{{\sffamily{\bfseries\mdline{206}version 1.4.0-dev}}}%mdk +\mdxauthorstart{} +%mdk-data-line={211} +\mdxauthorname{\mdline{211}The P4.org API Working Group}%mdk +\mdxauthorend +%mdk-data-line={220} +\mdxtitlefooter{{\sffamily{\bfseries\mdline{220}2022-03-23}}}%mdk +\mdtitleauthorrunning{}{}\mdxtitleblockend%mdk + +%mdk-data-line={205} +\begin{abstract}%mdk + +%mdk-data-line={206} +\noindent\mdline{206}P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.%mdk +%mdk +\end{abstract}%mdk +\mdline{214} +\begin{mdtoc}%mdk + +\section*{Contents}\label{sec-contents}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-introduction-and-scope}{\mdref{sec-introduction-and-scope}{1.\hspace*{0.5em}Introduction and Scope}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-language-version-applicability}{\mdref{sec-p4-language-version-applicability}{1.1.\hspace*{0.5em}P4 Language Version Applicability}}%mdk + +\mdtocitemx{sec-in-scope}{\mdref{sec-in-scope}{1.2.\hspace*{0.5em}In Scope}}%mdk + +\mdtocitemx{sec-not-in-scope}{\mdref{sec-not-in-scope}{1.3.\hspace*{0.5em}Not In Scope}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-terms-and-definitions}{\mdref{sec-terms-and-definitions}{2.\hspace*{0.5em}Terms and Definitions}}%mdk + +\mdtocitemx{sec-reference-architecture}{\mdref{sec-reference-architecture}{3.\hspace*{0.5em}Reference Architecture}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-service-implementation}{\mdref{sec-p4runtime-service-implementation}{3.1.\hspace*{0.5em}P4Runtime Service Implementation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-security-concerns}{\mdref{sec-security-concerns}{3.1.1.\hspace*{0.5em}Security concerns}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-idealized-workflow}{\mdref{sec-idealized-workflow}{3.2.\hspace*{0.5em}Idealized Workflow}}%mdk + +\mdtocitemx{sec-p4-as-behavioral-description-language}{\mdref{sec-p4-as-behavioral-description-language}{3.3.\hspace*{0.5em}P4 as a Behavioral Description Language}}%mdk + +\mdtocitemx{sec-alternative-workflows}{\mdref{sec-alternative-workflows}{3.4.\hspace*{0.5em}Alternative Workflows}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{\mdref{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{3.4.1.\hspace*{0.5em}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}}%mdk + +\mdtocitemx{sec-no-p4-source-available-p4info-available}{\mdref{sec-no-p4-source-available-p4info-available}{3.4.2.\hspace*{0.5em}No P4 Source Available, P4Info Available}}%mdk + +\mdtocitemx{sec-partial-p4info-and-p4-source-are-available}{\mdref{sec-partial-p4info-and-p4-source-are-available}{3.4.3.\hspace*{0.5em}Partial P4Info and P4 Source are Available}}%mdk + +\mdtocitemx{sec-p4info-role-based-subsets}{\mdref{sec-p4info-role-based-subsets}{3.4.4.\hspace*{0.5em}P4Info Role-Based Subsets}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-restarts}{\mdref{sec-restarts}{3.5.\hspace*{0.5em}P4Runtime State Across Restarts}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-controller-use-cases}{\mdref{sec-controller-use-cases}{4.\hspace*{0.5em}Controller Use-cases}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-single-embedded-controller}{\mdref{sec-single-embedded-controller}{4.1.\hspace*{0.5em}Single Embedded Controller}}%mdk + +\mdtocitemx{sec-single-remote-controller}{\mdref{sec-single-remote-controller}{4.2.\hspace*{0.5em}Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-single-remote-controller}{\mdref{sec-embedded-single-remote-controller}{4.3.\hspace*{0.5em}Embedded + Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-two-remote-controllers}{\mdref{sec-embedded-two-remote-controllers}{4.4.\hspace*{0.5em}Embedded + Two Remote Controllers}}%mdk + +\mdtocitemx{sec-embedded-controller-two-high-availability-remote-controllers}{\mdref{sec-embedded-controller-two-high-availability-remote-controllers}{4.5.\hspace*{0.5em}Embedded Controller + Two High-Availability Remote Controllers}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-client-arbitration-and-controller-replication}{\mdref{sec-client-arbitration-and-controller-replication}{5.\hspace*{0.5em}Client Arbitration and Controller Replication}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-default-role}{\mdref{sec-default-role}{5.1.\hspace*{0.5em}Default Role}}%mdk + +\mdtocitemx{sec-arbitration-role-config}{\mdref{sec-arbitration-role-config}{5.2.\hspace*{0.5em}Role Config}}%mdk + +\mdtocitemx{sec-arbitration-updates}{\mdref{sec-arbitration-updates}{5.3.\hspace*{0.5em}Rules for Handling \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}} Messages Received from Controllers}}%mdk + +\mdtocitemx{sec-arbitration-notification}{\mdref{sec-arbitration-notification}{5.4.\hspace*{0.5em}Client Arbitration Notifications}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-the-p4info-message}{\mdref{sec-the-p4info-message}{6.\hspace*{0.5em}The P4Info Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-common-messages}{\mdref{sec-common-messages}{6.1.\hspace*{0.5em}Common Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-documentation-message}{\mdref{sec-documentation-message}{6.1.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}} Message}}%mdk + +\mdtocitemx{sec-preamble-message}{\mdref{sec-preamble-message}{6.1.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}} Message}}%mdk + +\mdtocitemx{sec-annotating-p4-entities-with-documentation}{\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3.\hspace*{0.5em}Annotating P4 Entities with \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}}%mdk + +\mdtocitemx{sec-structured-annotations}{\mdref{sec-structured-annotations}{6.1.4.\hspace*{0.5em}Structured Annotations}}%mdk + +\mdtocitemx{sec-sourcelocation-message}{\mdref{sec-sourcelocation-message}{6.1.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}} Message}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-pkginfo-message}{\mdref{sec-pkginfo-message}{6.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}} Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-annotating-p4-code-with-pkginfo}{\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1.\hspace*{0.5em}Annotating P4 code with PkgInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-id-allocation}{\mdref{sec-id-allocation}{6.3.\hspace*{0.5em}ID Allocation for P4Info Objects}}%mdk + +\mdtocitemx{sec-p4info-objects}{\mdref{sec-p4info-objects}{6.4.\hspace*{0.5em}P4Info Objects}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table}{\mdref{sec-table}{6.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}}%mdk + +\mdtocitemx{sec-action}{\mdref{sec-action}{6.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}}%mdk + +\mdtocitemx{sec-p4info-action-profile}{\mdref{sec-p4info-action-profile}{6.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}}%mdk + +\mdtocitemx{sec-counter-directcounter}{\mdref{sec-counter-directcounter}{6.4.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}}%mdk + +\mdtocitemx{sec-meter-directmeter}{\mdref{sec-meter-directmeter}{6.4.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}}%mdk + +\mdtocitemx{sec-controller-packet-meta}{\mdref{sec-controller-packet-meta}{6.4.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}}%mdk + +\mdtocitemx{sec-valueset}{\mdref{sec-valueset}{6.4.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}}%mdk + +\mdtocitemx{sec-register}{\mdref{sec-register}{6.4.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}}%mdk + +\mdtocitemx{sec-digest}{\mdref{sec-digest}{6.4.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}}%mdk + +\mdtocitemx{sec-p4info-extern}{\mdref{sec-p4info-extern}{6.4.10.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{\mdref{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{6.5.\hspace*{0.5em}Support for Arbitrary P4 Types with P4TypeInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-fwd-pipe-config}{\mdref{sec-p4-fwd-pipe-config}{7.\hspace*{0.5em}P4 Forwarding-Pipeline Configuration}}%mdk + +\mdtocitemx{sec-general-principles-for-message-formatting}{\mdref{sec-general-principles-for-message-formatting}{8.\hspace*{0.5em}General Principles for Message Formatting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-set-unset-protobuf-field}{\mdref{sec-set-unset-protobuf-field}{8.1.\hspace*{0.5em}Set / Unset Protobuf Field}}%mdk + +\mdtocitemx{sec-read-write-symmetry}{\mdref{sec-read-write-symmetry}{8.2.\hspace*{0.5em}Read-Write Symmetry}}%mdk + +\mdtocitemx{sec-zero-as-reserved-value}{\mdref{sec-zero-as-reserved-value}{8.3.\hspace*{0.5em}Zero as Reserved Value}}%mdk + +\mdtocitemx{sec-bytestrings}{\mdref{sec-bytestrings}{8.4.\hspace*{0.5em}Bytestrings}}%mdk + +\mdtocitemx{sec-representation-of-arbitrary-p4-types}{\mdref{sec-representation-of-arbitrary-p4-types}{8.5.\hspace*{0.5em}Representation of Arbitrary P4 Types}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-problem-statement}{\mdref{sec-problem-statement}{8.5.1.\hspace*{0.5em}Problem Statement}}%mdk + +\mdtocitemx{sec-p4-type-specifications-in-p4infoproto}{\mdref{sec-p4-type-specifications-in-p4infoproto}{8.5.2.\hspace*{0.5em}P4 Type Specifications in p4info.proto}}%mdk + +\mdtocitemx{sec-p4data-in-p4runtime-proto}{\mdref{sec-p4data-in-p4runtime-proto}{8.5.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}} in p4runtime.proto}}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{8.5.4.\hspace*{0.5em}Example}}%mdk + +\mdtocitemx{sec-enum-serializable-enum-and-error}{\mdref{sec-enum-serializable-enum-and-error}{8.5.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}, serializable \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}}%mdk + +\mdtocitemx{sec-user-defined-types}{\mdref{sec-user-defined-types}{8.5.6.\hspace*{0.5em}User-defined types}}%mdk + +\mdtocitemx{sec-trade-off-for-v1x-releases}{\mdref{sec-trade-off-for-v1x-releases}{8.5.7.\hspace*{0.5em}Trade-off for v1.x Releases}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-entity-msgs}{\mdref{sec-p4-entity-msgs}{9.\hspace*{0.5em}P4 Entity Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table-entry}{\mdref{sec-table-entry}{9.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-match-format}{\mdref{sec-match-format}{9.1.1.\hspace*{0.5em}Match Format}}%mdk + +\mdtocitemx{sec-action-specification}{\mdref{sec-action-specification}{9.1.2.\hspace*{0.5em}Action Specification}}%mdk + +\mdtocitemx{sec-default-entry}{\mdref{sec-default-entry}{9.1.3.\hspace*{0.5em}Default Entry}}%mdk + +\mdtocitemx{sec-constant-tables}{\mdref{sec-constant-tables}{9.1.4.\hspace*{0.5em}Constant Tables}}%mdk + +\mdtocitemx{sec-table-wildcard-reads}{\mdref{sec-table-wildcard-reads}{9.1.5.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-direct-resources}{\mdref{sec-direct-resources}{9.1.6.\hspace*{0.5em}Direct Resources}}%mdk + +\mdtocitemx{sec-idle-timeout}{\mdref{sec-idle-timeout}{9.1.7.\hspace*{0.5em}Idle-timeout}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-and-group}{\mdref{sec-action-profile-member-and-group}{9.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-programming}{\mdref{sec-action-profile-member-programming}{9.2.1.\hspace*{0.5em}Action Profile Member Programming}}%mdk + +\mdtocitemx{sec-action-profile-group-programming}{\mdref{sec-action-profile-group-programming}{9.2.2.\hspace*{0.5em}Action Profile Group Programming}}%mdk + +\mdtocitemx{sec-oneshot}{\mdref{sec-oneshot}{9.2.3.\hspace*{0.5em}One Shot Action Selector Programming}}%mdk + +\mdtocitemx{action-selector-constraints}{\mdref{action-selector-constraints}{9.2.4.\hspace*{0.5em}Constraints on action selector programming}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-counterentry-directcounterentry}{\mdref{sec-counterentry-directcounterentry}{9.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directcounterentry}{\mdref{sec-directcounterentry}{9.3.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\mdtocitemx{sec-counterentry}{\mdref{sec-counterentry}{9.3.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-meterentry-directmeterentry}{\mdref{sec-meterentry-directmeterentry}{9.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directmeterentry}{\mdref{sec-directmeterentry}{9.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\mdtocitemx{sec-meterentry}{\mdref{sec-meterentry}{9.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}}%mdk + +\mdtocitemx{sec-metercounterdata}{\mdref{sec-metercounterdata}{9.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-packetreplicationengineentry}{\mdref{sec-packetreplicationengineentry}{9.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-multicastgroupentry}{\mdref{sec-multicastgroupentry}{9.5.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}}%mdk + +\mdtocitemx{sec-clonesessionentry}{\mdref{sec-clonesessionentry}{9.5.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-valuesetentry}{\mdref{sec-valuesetentry}{9.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}}%mdk + +\mdtocitemx{sec-registerentry}{\mdref{sec-registerentry}{9.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}}%mdk + +\mdtocitemx{sec-digestentry}{\mdref{sec-digestentry}{9.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}}%mdk + +\mdtocitemx{sec-extern-entry}{\mdref{sec-extern-entry}{9.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-error-reporting-messages}{\mdref{sec-error-reporting-messages}{10.\hspace*{0.5em}Error Reporting Messages}}%mdk + +\mdtocitemx{sec-atomicity-of-individual-write-and-read-operations}{\mdref{sec-atomicity-of-individual-write-and-read-operations}{11.\hspace*{0.5em}Atomicity of Individual \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} Operations}}%mdk + +\mdtocitemx{sec-write-rpc}{\mdref{sec-write-rpc}{12.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-batching-and-ordering-of-updates}{\mdref{sec-batching-and-ordering-of-updates}{12.1.\hspace*{0.5em}Batching and Ordering of Updates}}%mdk + +\mdtocitemx{sec-batch-atomicity}{\mdref{sec-batch-atomicity}{12.2.\hspace*{0.5em}Batch Atomicity}}%mdk + +\mdtocitemx{sec-error-reporting}{\mdref{sec-error-reporting}{12.3.\hspace*{0.5em}Error Reporting}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-read-rpc}{\mdref{sec-read-rpc}{13.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-nomenclature}{\mdref{sec-nomenclature}{13.1.\hspace*{0.5em}Nomenclature}}%mdk + +\mdtocitemx{sec-wildcard-reads}{\mdref{sec-wildcard-reads}{13.2.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-batch-processing}{\mdref{sec-batch-processing}{13.3.\hspace*{0.5em}Batch Processing}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{13.3.1.\hspace*{0.5em}Example}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-parallelism-of-read-and-write-requests}{\mdref{sec-parallelism-of-read-and-write-requests}{13.4.\hspace*{0.5em}Parallelism of Read and Write Requests}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-setforwardingpipelineconfig-rpc}{\mdref{sec-setforwardingpipelineconfig-rpc}{14.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-getforwardingpipelineconfig-rpc}{\mdref{sec-getforwardingpipelineconfig-rpc}{15.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-p4runtime-stream-messages}{\mdref{sec-p4runtime-stream-messages}{16.\hspace*{0.5em}P4Runtime Stream Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-packet-i_o}{\mdref{sec-packet-i_o}{16.1.\hspace*{0.5em}Packet I/O}}%mdk + +\mdtocitemx{sec-client-arbitration-update}{\mdref{sec-client-arbitration-update}{16.2.\hspace*{0.5em}Client Arbitration Update}}%mdk + +\mdtocitemx{sec-digest-messages}{\mdref{sec-digest-messages}{16.3.\hspace*{0.5em}Digest Messages}}%mdk + +\mdtocitemx{sec-table-idle-timeout-notification}{\mdref{sec-table-idle-timeout-notification}{16.4.\hspace*{0.5em}Table Idle Timeout Notification}}%mdk + +\mdtocitemx{sec-architecture-specific-notifications}{\mdref{sec-architecture-specific-notifications}{16.5.\hspace*{0.5em}Architecture-Specific Notifications}}%mdk + +\mdtocitemx{sec-stream-error-reporting}{\mdref{sec-stream-error-reporting}{16.6.\hspace*{0.5em}Stream Error Reporting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-examples-of-streamerror-messages}{\mdref{sec-examples-of-streamerror-messages}{16.6.1.\hspace*{0.5em}Examples of \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}} Messages}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-capabilities-rpc}{\mdref{sec-capabilities-rpc}{17.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}} RPC}}%mdk + +\mdtocitemx{sec-portability-considerations}{\mdref{sec-portability-considerations}{18.\hspace*{0.5em}Portability Considerations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-psa-metadata-translation}{\mdref{sec-psa-metadata-translation}{18.1.\hspace*{0.5em}PSA Metadata Translation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-translation-of-port-numbers}{\mdref{sec-translation-of-port-numbers}{18.1.1.\hspace*{0.5em}Translation of Port Numbers}}%mdk + +\mdtocitemx{sec-translation-of-packet-io-header-fields}{\mdref{sec-translation-of-packet-io-header-fields}{18.1.2.\hspace*{0.5em}Translation of Packet-IO Header Fields}}%mdk + +\mdtocitemx{sec-translation-of-match-fields}{\mdref{sec-translation-of-match-fields}{18.1.3.\hspace*{0.5em}Translation of Match Fields}}%mdk + +\mdtocitemx{sec-translation-of-action-parameters}{\mdref{sec-translation-of-action-parameters}{18.1.4.\hspace*{0.5em}Translation of Action Parameters}}%mdk + +\mdtocitemx{sec-port-translation-for-psa-extern-apis}{\mdref{sec-port-translation-for-psa-extern-apis}{18.1.5.\hspace*{0.5em}Port Translation for PSA Extern APIs}}%mdk + +\mdtocitemx{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{\mdref{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{18.1.6.\hspace*{0.5em}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-versioning}{\mdref{sec-p4runtime-versioning}{19.\hspace*{0.5em}P4Runtime Versioning}}%mdk + +\mdtocitemx{sec-extending-p4runtime}{\mdref{sec-extending-p4runtime}{20.\hspace*{0.5em}Extending P4Runtime for non-PSA Architectures}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-p4runtime-for-architecture-specific-externs}{\mdref{sec-extending-p4runtime-for-architecture-specific-externs}{20.1.\hspace*{0.5em}Extending P4Runtime for Architecture-Specific Externs}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-the-p4info-message}{\mdref{sec-extending-the-p4info-message}{20.1.1.\hspace*{0.5em}Extending the P4Info message}}%mdk + +\mdtocitemx{sec-extending-the-p4runtime-service}{\mdref{sec-extending-the-p4runtime-service}{20.1.2.\hspace*{0.5em}Extending the P4Runtime Service}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-architecture-specific-table-extensions}{\mdref{sec-architecture-specific-table-extensions}{20.2.\hspace*{0.5em}Architecture-Specific Table Extensions}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-new-match-types}{\mdref{sec-new-match-types}{20.2.1.\hspace*{0.5em}New Match Types}}%mdk + +\mdtocitemx{sec-new-table-properties}{\mdref{sec-new-table-properties}{20.2.2.\hspace*{0.5em}New Table Properties}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-known-limitations-of-current-p4runtime-version}{\mdref{sec-known-limitations-of-current-p4runtime-version}{21.\hspace*{0.5em}Known Limitations of Current P4Runtime Version}}%mdk + +\mdtocitemx{sec-appendix}{\mdref{sec-appendix}{A.\hspace*{0.5em}Appendix}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-revision-history}{\mdref{sec-revision-history}{A.1.\hspace*{0.5em}Revision History}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-changes-in-v140-under-development}{\mdref{sec-changes-in-v140-under-development}{A.1.1.\hspace*{0.5em}Changes in v1.4.0 (under development)}}%mdk + +\mdtocitemx{sec-changes-in-v130}{\mdref{sec-changes-in-v130}{A.1.2.\hspace*{0.5em}Changes in v1.3.0}}%mdk + +\mdtocitemx{sec-changes-in-v120}{\mdref{sec-changes-in-v120}{A.1.3.\hspace*{0.5em}Changes in v1.2.0}}%mdk + +\mdtocitemx{sec-changes-in-v110}{\mdref{sec-changes-in-v110}{A.1.4.\hspace*{0.5em}Changes in v1.1.0}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-annotations}{\mdref{sec-p4-annotations}{A.2.\hspace*{0.5em}P4 Annotations}}%mdk + +\mdtocitemx{sec-value-set-example}{\mdref{sec-value-set-example}{A.3.\hspace*{0.5em}A More Complex Value Set Example}}%mdk + +\mdtocitemx{sec-guidelines-for-implementations}{\mdref{sec-guidelines-for-implementations}{A.4.\hspace*{0.5em}Guidelines for Implementations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-grpc-metadata-maximum-size}{\mdref{sec-grpc-metadata-maximum-size}{A.4.1.\hspace*{0.5em}gRPC Metadata Maximum Size}}%mdk + +\mdtocitemx{sec-grpc-server-maximum-receive-message-size}{\mdref{sec-grpc-server-maximum-receive-message-size}{A.4.2.\hspace*{0.5em}gRPC Server Maximum Receive Message Size}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-bibliography}{\mdref{sec-bibliography}{References}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{215} +\begin{mdtoc}%mdk + +\section*{Figures}\label{sec-figures}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{fig-reference-architecture}{\mdref{fig-reference-architecture}{\mdcaptionlabel{1}. P4Runtime Reference Architecture.}}%mdk + +\mdtocitemx{fig-single-embedded-controller}{\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}. Use-Case: Single Embedded Controller}}%mdk + +\mdtocitemx{fig-single-remote-controller}{\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}. Use-Case: Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-single-remote-controller}{\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}. Use-Case: Embedded Plus Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-controllers}{\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}. Use-Case: Embedded Plus Two Remote Controllers}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-ha-controllers}{\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}. Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk + +\mdtocitemx{fig-error-report}{\mdref{fig-error-report}{\mdcaptionlabel{7}. P4Runtime Error Report Message Format}}%mdk + +\mdtocitemx{fig-psa-metadata-translation}{\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}. P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{216} +\begin{mdtoc}%mdk + +\section*{Tables}\label{sec-tables}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{tab-mapping-p4-obj-ids}{\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}. Mapping of P4Info object type to 8-bit ID prefix value}}%mdk + +\mdtocitemx{tab-format-p4-obj-ids}{\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}. Format of P4Info object IDs}}%mdk + +\mdtocitemx{tab-exmpl-p4-obj-ids}{\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}. Example of statically-assigned P4Info object IDs}}%mdk + +\mdtocitemx{tab-valid-bytestring-encoding}{\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}. Examples of Valid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-invalid-bytestring-encoding}{\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}. Examples of Invalid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-p4-type-usage}{\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}. P4 Type Usage}}%mdk + +\mdtocitemx{tab-p4-annotations}{\mdref{tab-p4-annotations}{\mdcaptionlabel{7}. P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk + +%mdk-data-line={218} +\section{\mdline{218}1.\hspace*{0.5em}\mdline{218}Introduction and Scope}\label{sec-introduction-and-scope}%mdk%mdk + +%mdk-data-line={220} +\noindent\mdline{220}This document is published by the \mdline{220}\emph{P4.org API Working Group}\mdline{220}, which was +chartered\mdline{221}~[\mdcite{p4apiwgcharter}{17}]\mdline{221} to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called \mdline{223}\emph{P4Runtime}\mdline{223}. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +\mdline{226}\href{https://github.com/p4lang/p4runtime/tree/main/proto}{https://github.com/p4lang/p4runtime/tree/main/proto}\mdline{226}.%mdk + +%mdk-data-line={228} +\subsection{\mdline{228}1.1.\hspace*{0.5em}\mdline{228}P4 Language Version Applicability}\label{sec-p4-language-version-applicability}%mdk%mdk + +%mdk-data-line={230} +\noindent\mdline{230}P4Runtime is designed to be implemented in conjunction with the P4\mdline{230}\mdsub{16}\mdline{230} language +version or later. P4\mdline{231}\mdsub{14}\mdline{231} programs should be translated into P4\mdline{231}\mdsub{16}\mdline{231} to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P4\mdline{233}\mdsub{16}\mdline{233} 1.0, but were introduced in P4\mdline{233}\mdsub{16}\mdline{233} 1.1.0\mdline{233}~[\mdcite{p4revisions110}{29}]\mdline{233}. For +this version of P4Runtime, we recommend using P4\mdline{234}\mdsub{16}\mdline{234} 1.2.1\mdline{234}~[\mdcite{p4spec}{1}]\mdline{234}.%mdk + +%mdk-data-line={236} +\subsection{\mdline{236}1.2.\hspace*{0.5em}\mdline{236}In Scope}\label{sec-in-scope}%mdk%mdk + +%mdk-data-line={238} +\noindent\mdline{238}This specification document defines the \mdline{238}\emph{semantics}\mdline{238} of \mdline{238}\emph{P4Runtime}\mdline{238} messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime:%mdk + +%mdk-data-line={242} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={242} +\item\mdline{242}Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA)\mdline{243}~[\mdcite{psa}{19}]\mdline{243} externs (\mdline{243}e.g.\mdline{243} Counters, Meters, Action +Profiles, \mdline{244}\dots{}\mdline{244}). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0.%mdk + +%mdk-data-line={246} +\item\mdline{246}Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism.%mdk + +%mdk-data-line={248} +\item\mdline{248}Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy.%mdk + +%mdk-data-line={251} +\item\mdline{251}Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities.%mdk + +%mdk-data-line={253} +\item\mdline{253}Packet I/O to enable streaming packets to \mdline{253}\&\mdline{253} from the control plane.%mdk + +%mdk-data-line={254} +\item\mdline{254}Batching support, with different atomicity guarantees.%mdk + +%mdk-data-line={255} +\item\mdline{255}In-the-field device-reconfiguration with a new P4 data plane.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={257} +\noindent\mdline{257}The following are in the scope of this specification document:%mdk + +%mdk-data-line={259} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={259} +\item\mdline{259}Rationale for the P4Runtime design.%mdk + +%mdk-data-line={260} +\item\mdline{260}Reference architecture and use-cases for deploying a P4Runtime service.%mdk + +%mdk-data-line={261} +\item\mdline{261}Detailed description of the API semantics.%mdk + +%mdk-data-line={262} +\item\mdline{262}Requirements for conformant implementations of the API.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={264} +\subsection{\mdline{264}1.3.\hspace*{0.5em}\mdline{264}Not In Scope}\label{sec-not-in-scope}%mdk%mdk + +%mdk-data-line={266} +\noindent\mdline{266}The following are not in scope of P4Runtime:%mdk + +%mdk-data-line={268} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={268} +\item\mdline{268}Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +\mdline{273}[\mdcite{openconfig}{35}]\mdline{273}. An open source implementation of these APIs is also in progress +as part of the Stratum project\mdline{274}~[\mdcite{stratum}{37}]\mdline{274}.%mdk + +%mdk-data-line={275} +\item\mdline{275}Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={280} +\noindent\mdline{280}The following are not in scope of this specification document:%mdk + +%mdk-data-line={282} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={282} +\item\mdline{282}Description of the P4 programming language; it is assumed that the reader is +already familiar with P4\mdline{283}\mdsub{16}\mdline{283}~[\mdcite{p4spec}{1}]\mdline{283}.%mdk + +%mdk-data-line={284} +\item\mdline{284}Descriptions of gRPC and Protobuf files in general.%mdk + +%mdk-data-line={285} +\item\mdline{285}Controller\mdline{285}~\mdref{sec-arbitration-role-config}{role}\mdline{285} definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={289} +\section{\mdline{289}2.\hspace*{0.5em}\mdline{289}Terms and Definitions}\label{sec-terms-and-definitions}%mdk%mdk + +%mdk-data-line={291} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries arbitration}}%mdk + +%mdk-data-line={291} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{291}Refers to the process through which P4Runtime ensures that at any given +time, there is a single primary controller (\mdline{292}i.e.\mdline{292} a client with write access) +for a given role. Also referred to as \mdline{293}\textquotedblleft{}client arbitration\textquotedblright{}\mdline{293}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries client}}%mdk + +%mdk-data-line={295} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{295}The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries COS}}%mdk + +%mdk-data-line={299} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{299}Class of Service. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries device}}%mdk + +%mdk-data-line={301} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{301}Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries entity}}%mdk + +%mdk-data-line={305} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{305}An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries gRPC}}%mdk + +%mdk-data-line={308} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{308}gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +\mdline{309}[\mdcite{grpc}{9}]\mdline{309}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries HA}}%mdk + +%mdk-data-line={311} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{311}High-Availability. Refers to a redundancy architecture. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Instrumentation}}%mdk + +%mdk-data-line={313} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{313}The part of the P4Runtime server which implements the calls to the device or +target native \mdline{314}\textquotedblleft{}SDK\textquotedblright{}\mdline{314} or backend. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries IPC}}%mdk + +%mdk-data-line={316} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{316}Inter-Process Communication. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Blob}}%mdk + +%mdk-data-line={318} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{318}A more colloquial term for P4 Device Config (Blob = Binary Large Object). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Device Config}}%mdk + +%mdk-data-line={320} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{320}The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its \mdline{322}\textquotedblleft{}program.\textquotedblright{}\mdline{322} +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4Info}}%mdk + +%mdk-data-line={324} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{324}Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4RT}}%mdk + +%mdk-data-line={328} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{328}Abbreviation for P4Runtime. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Protobuf (Protocol Buffers)}}%mdk + +%mdk-data-line={330} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{330}The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See\mdline{331}~[\mdcite{proto}{21}]\mdline{331}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries PSA}}%mdk + +%mdk-data-line={333} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{333}Portable Switch Architecture\mdline{333}~[\mdcite{psa}{19}]\mdline{333}; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RPC}}%mdk + +%mdk-data-line={337} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{337}Remote Procedure Call. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RTT}}%mdk + +%mdk-data-line={339} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{339}Round-trip time. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN}}%mdk + +%mdk-data-line={341} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{341}Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network \mdline{346}\emph{controller}\mdline{346}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN port}}%mdk + +%mdk-data-line={348} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{348}A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries server}}%mdk + +%mdk-data-line={352} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{352}The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries stream}}%mdk + +%mdk-data-line={356} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{356}Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (\mdline{357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{357}), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and client arbitration, among other things. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries switch config}}%mdk + +%mdk-data-line={361} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{361}Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries target}}%mdk + +%mdk-data-line={366} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{366}The hardware or software entity which \mdline{366}\textquotedblleft{}executes\textquotedblright{}\mdline{366} the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with \mdline{367}\textquotedblleft{}device\textquotedblright{}\mdline{367}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries URI}}%mdk + +%mdk-data-line={369} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{369}Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={373} +\section{\mdline{373}3.\hspace*{0.5em}\mdline{373}Reference Architecture}\label{sec-reference-architecture}%mdk%mdk + +%mdk-data-line={375} +\noindent\mdline{375}Figure\mdline{375}~\mdref{fig-reference-architecture}{\mdcaptionlabel{1}}\mdline{375} represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. P4Runtime only grants write access to a +single primary controller for each read/write entity. A role defines a grouping +of P4 entities. P4Runtime allows for a primary controller for each role, and a +role-based client arbitration scheme ensures only one controller has +write access to each read/write entity, or the pipeline config itself. Any +controller may perform read access to any entity or the pipeline config. Later +sections describe this in detail. For the sake of brevity, the term controller +may refer to one or more controllers.%mdk + +%mdk-data-line={386} +\mdline{386}The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +\mdline{389}[\mdcite{p4runtimerepo}{15}]\mdline{389}. It may be compiled via protoc\mdline{389} \mdline{389}\textemdash{}\mdline{389} the Protobuf compiler\mdline{389} \mdline{389}\textemdash{}\mdline{389} +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server.%mdk + +%mdk-data-line={394} +\mdline{394}Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository\mdline{395}~[\mdcite{pirepo}{16}]\mdline{395}. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, \mdline{397}e.g.\mdline{397} via callbacks, thus reducing the burden of implementing +P4Runtime.%mdk + +%mdk-data-line={400} +\mdline{400}The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard.%mdk + +%mdk-data-line={404} +\mdline{404}The controller can also set the \mdline{404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{404}, which amounts to +installing and running the compiled P4 program output, which is included in the +\mdline{406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{406} Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +\mdline{408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{408} to retrieve the device config and the P4Info.%mdk + +%mdk-data-line={411} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={412} +\noindent\mdline{412}\includegraphics[keepaspectratio=true,height=7cm]{build/reference-architecture}{}\mdline{412}%mdk + +%mdk-data-line={413} +\mdhr{}%mdk + +%mdk-data-line={414} +\noindent\mdline{414}\mdcaption{\textbf{Figure~\mdcaptionlabel{1}.}~\mdcaptiontext{P4Runtime Reference Architecture.}}%mdk +%mdk +\end{mdcenter}\label{fig-reference-architecture}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={418} +\subsection{\mdline{418}3.1.\hspace*{0.5em}\mdline{418}P4Runtime Service Implementation}\label{sec-p4runtime-service-implementation}%mdk%mdk + +%mdk-data-line={420} +\noindent\mdline{420}The P4Runtime API is implemented by a program that runs a gRPC server which +binds an implementation of auto-generated P4Runtime Service interface. This +program is called the \mdline{422}\textquotedblleft{}P4Runtime server.\textquotedblright{}\mdline{422} The server must listen on TCP port +9559 by default, which is the port that has been allocated by IANA for the +P4Runtime service. Servers should allow users to override the default port +using a configuration file or flag when starting the server. Uses of other +port numbers as the default should be discontinued.%mdk + +%mdk-data-line={428} +\subsubsection{\mdline{428}3.1.1.\hspace*{0.5em}\mdline{428}Security concerns}\label{sec-security-concerns}%mdk%mdk + +%mdk-data-line={430} +\noindent\mdline{430}Appropriate measures and security best practices must be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. Mutual TLS (mTLS) may +be used to facilitate the authentication of the client by the server and +vice-versa.%mdk + +%mdk-data-line={439} +\subsection{\mdline{439}3.2.\hspace*{0.5em}\mdline{439}Idealized Workflow}\label{sec-idealized-workflow}%mdk%mdk + +%mdk-data-line={441} +\noindent\mdline{441}In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the \mdline{442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{442} +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a \mdline{444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{444} +RPC. Metadata in the P4Info describes both the overall program itself +(\mdline{446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{446}) as well as all entity instances derived from the P4 program\mdline{446} \mdline{446}\textemdash{}\mdline{446} +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise \mdline{448}\textquotedblleft{}handle\textquotedblright{}\mdline{448} used in API +calls.%mdk + +%mdk-data-line={451} +\mdline{451}In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible.%mdk + +%mdk-data-line={457} +\mdline{457}In some use cases, it is expected that a controller will store a +collection of multiple P4 \mdline{458}\textquotedblleft{}packages\textquotedblright{}\mdline{458}, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the \mdline{460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{460} from the target via the +\mdline{461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineRequest}}}\mdline{461} RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state.%mdk + +%mdk-data-line={465} +\subsection{\mdline{465}3.3.\hspace*{0.5em}\mdline{465}P4 as a Behavioral Description Language}\label{sec-p4-as-behavioral-description-language}%mdk%mdk + +%mdk-data-line={467} +\noindent\mdline{467}P4 can be considered a behavioral description of a switching device which may or +may not execute \mdline{468}\textquotedblleft{}P4\textquotedblright{}\mdline{468} natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a \mdline{470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineRequest}}}\mdline{470} to +change its pipeline \mdline{471}\textquotedblleft{}program\textquotedblright{}\mdline{471}, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device.%mdk + +%mdk-data-line={477} +\mdline{477}While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API.%mdk + +%mdk-data-line={486} +\mdline{486}In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the \mdline{487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{487} +message as well as the embedded \mdline{488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{488} fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections.%mdk + +%mdk-data-line={492} +\subsection{\mdline{492}3.4.\hspace*{0.5em}\mdline{492}Alternative Workflows}\label{sec-alternative-workflows}%mdk%mdk + +%mdk-data-line={494} +\noindent\mdline{494}Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary.%mdk + +%mdk-data-line={498} +\subsubsection{\mdline{498}3.4.1.\hspace*{0.5em}\mdline{498}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}\label{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}%mdk%mdk + +%mdk-data-line={500} +\noindent\mdline{500}In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +\mdline{502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{502}. The device\mdline{502}'\mdline{502}s configuration might be derived via some other +means to implement the P4 source code\mdline{503}'\mdline{503}s intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane.%mdk + +%mdk-data-line={507} +\subsubsection{\mdline{507}3.4.2.\hspace*{0.5em}\mdline{507}No P4 Source Available, P4Info Available}\label{sec-no-p4-source-available-p4info-available}%mdk%mdk + +%mdk-data-line={509} +\noindent\mdline{509}In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are:%mdk + +%mdk-data-line={512} +\begin{enumerate}%mdk + +%mdk-data-line={512} +\item{} +%mdk-data-line={512} +\mdline{512}The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security.%mdk%mdk + +%mdk-data-line={515} +\item{} +%mdk-data-line={515} +\mdline{515}The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={518} +\noindent\mdline{518}As discussed in Section\mdline{518}~\mdref{sec-p4-as-behavioral-description-language}{3.3}\mdline{518}, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, \mdline{521}e.g.\mdline{521} documentation.%mdk + +%mdk-data-line={523} +\subsubsection{\mdline{523}3.4.3.\hspace*{0.5em}\mdline{523}Partial P4Info and P4 Source are Available}\label{sec-partial-p4info-and-p4-source-are-available}%mdk%mdk + +%mdk-data-line={525} +\noindent\mdline{525}In this situation, a subset of the target\mdline{525}'\mdline{525}s pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code.%mdk + +%mdk-data-line={532} +\subsubsection{\mdline{532}3.4.4.\hspace*{0.5em}\mdline{532}P4Info Role-Based Subsets}\label{sec-p4info-role-based-subsets}%mdk%mdk + +%mdk-data-line={534} +\noindent\mdline{534}In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more.%mdk + +%mdk-data-line={538} +\subsection{\mdline{538}3.5.\hspace*{0.5em}\mdline{538}P4Runtime State Across Restarts}\label{sec-restarts}%mdk%mdk + +%mdk-data-line={540} +\noindent\mdline{540}All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade.%mdk + +%mdk-data-line={546} +\section{\mdline{546}4.\hspace*{0.5em}\mdline{546}Controller Use-cases}\label{sec-controller-use-cases}%mdk%mdk + +%mdk-data-line={548} +\noindent\mdline{548}P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +\mdline{550}\mdref{sec-client-arbitration-and-controller-replication}{section}\mdline{550}. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime\mdline{552}'\mdline{552}s flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex.%mdk + +%mdk-data-line={555} +\subsection{\mdline{555}4.1.\hspace*{0.5em}\mdline{555}Single Embedded Controller}\label{sec-single-embedded-controller}%mdk%mdk + +%mdk-data-line={557} +\noindent\mdline{557}Figure\mdline{557}~\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}}\mdline{557} shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases.%mdk + +%mdk-data-line={562} +\mdline{562}P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC.%mdk + +%mdk-data-line={567} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={568} +\noindent\mdline{568}\includegraphics[keepaspectratio=true,height=6cm]{build/single-embedded-controller}{}\mdline{568}%mdk + +%mdk-data-line={569} +\mdhr{}%mdk + +%mdk-data-line={570} +\noindent\mdline{570}\mdcaption{\textbf{Figure~\mdcaptionlabel{2}.}~\mdcaptiontext{Use-Case: Single Embedded Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-embedded-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={574} +\subsection{\mdline{574}4.2.\hspace*{0.5em}\mdline{574}Single Remote Controller}\label{sec-single-remote-controller}%mdk%mdk + +%mdk-data-line={576} +\noindent\mdline{576}Figure\mdline{576}~\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}}\mdline{576} shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections.%mdk + +%mdk-data-line={581} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={582} +\noindent\mdline{582}\includegraphics[keepaspectratio=true,height=7cm]{build/single-remote-controller}{}\mdline{582}%mdk + +%mdk-data-line={583} +\mdhr{}%mdk + +%mdk-data-line={584} +\noindent\mdline{584}\mdcaption{\textbf{Figure~\mdcaptionlabel{3}.}~\mdcaptiontext{Use-Case: Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={588} +\subsection{\mdline{588}4.3.\hspace*{0.5em}\mdline{588}Embedded\mdline{588} \mdline{588}+ Single Remote Controller}\label{sec-embedded-single-remote-controller}%mdk%mdk + +%mdk-data-line={590} +\noindent\mdline{590}Figure\mdline{590}~\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}}\mdline{590} illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller.%mdk + +%mdk-data-line={597} +\mdline{597}For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables.%mdk + +%mdk-data-line={601} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={602} +\noindent\mdline{602}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-single-remote-controller}{}\mdline{602}%mdk + +%mdk-data-line={603} +\mdhr{}%mdk + +%mdk-data-line={604} +\noindent\mdline{604}\mdcaption{\textbf{Figure~\mdcaptionlabel{4}.}~\mdcaptiontext{Use-Case: Embedded Plus Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={609} +\subsection{\mdline{609}4.4.\hspace*{0.5em}\mdline{609}Embedded\mdline{609} \mdline{609}+ Two Remote Controllers}\label{sec-embedded-two-remote-controllers}%mdk%mdk + +%mdk-data-line={611} +\noindent\mdline{611}Figure\mdline{611}~\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}}\mdline{611} illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +\mdline{614}e.g.\mdline{614} routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership.%mdk + +%mdk-data-line={617} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={618} +\noindent\mdline{618}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-controllers}{}\mdline{618}%mdk + +%mdk-data-line={619} +\mdhr{}%mdk + +%mdk-data-line={620} +\noindent\mdline{620}\mdcaption{\textbf{Figure~\mdcaptionlabel{5}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={625} +\subsection{\mdline{625}4.5.\hspace*{0.5em}\mdline{625}Embedded Controller\mdline{625} \mdline{625}+ Two High-Availability Remote Controllers}\label{sec-embedded-controller-two-high-availability-remote-controllers}%mdk%mdk + +%mdk-data-line={627} +\noindent\mdline{627}Figure\mdline{627}~\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}}\mdline{627} illustrates a single +embedded controller plus two remote controllers in an active-standby (\mdline{628}i.e.\mdline{628} +primary-backup) HA (High-Availability) configuration. Controller \mdline{629}\#\mdline{629}1 is the +active controller and is in charge of some entities. If it fails, Controller \mdline{630}\#\mdline{630}2 +takes over and manages the tables formerly owned by Controller \mdline{631}\#\mdline{631}1. The mechanics +of HA architectures are beyond the scope of this document, but the P4Runtime +role-based client arbitration scheme supports it.%mdk + +%mdk-data-line={635} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={636} +\noindent\mdline{636}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-ha-controllers}{}\mdline{636}%mdk + +%mdk-data-line={637} +\mdhr{}%mdk + +%mdk-data-line={638} +\noindent\mdline{638}\mdcaption{\textbf{Figure~\mdcaptionlabel{6}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-ha-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={643} +\section{\mdline{643}5.\hspace*{0.5em}\mdline{643}Client Arbitration and Controller Replication}\label{sec-client-arbitration-and-controller-replication}%mdk%mdk + +%mdk-data-line={646} +\noindent\mdline{646}The P4Runtime interface allows multiple clients (\mdline{646}i.e.\mdline{646} controllers) to be +connected to the P4Runtime server running on the device at the same time for the +following reasons:%mdk + +%mdk-data-line={650} +\begin{enumerate}%mdk + +%mdk-data-line={650} +\item{} +%mdk-data-line={650} +\mdline{650}Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, \mdline{651}\textquotedblleft{}roles\textquotedblright{}\mdline{651} (or \mdline{651}\textquotedblleft{}realms\textquotedblright{}\mdline{651}) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +primary and the rest are backups. Role definition, \mdline{654}i.e.\mdline{654} how P4 entities get +assigned to each role, is \mdline{655}\textbf{out-of-scope}\mdline{655} of this document.%mdk%mdk + +%mdk-data-line={657} +\item{} +%mdk-data-line={657} +\mdline{657}Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby backup controllers. These can already have a connection +open, which can help them become primary more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={663} +\noindent\mdline{663}To support multiple controllers, P4Runtime uses the streaming channel (available +via \mdline{664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{664} RPC) for session management. The workflow is described as +follows:%mdk + +%mdk-data-line={667} +\begin{itemize}%mdk + +%mdk-data-line={667} +\item{} +%mdk-data-line={667} +\mdline{667}Each controller instance (\mdline{667}e.g.\mdline{667} a controller process) can participate in one or +more roles. For each (\mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{668}, \mdline{668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{668}), the controller receives an +\mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{669}. This \mdline{669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{669} can be the same for different roles and/or +devices, as long as the tuple (\mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{670}, \mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{670}, \mdline{670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{670}) is +unique. For each (\mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{671}, \mdline{671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{671}) that the controller wishes to +control, it establishes a \mdline{672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{672} with the P4Runtime server +responsible for that device, and sends a \mdline{673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{673} message +containing that tuple of (\mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{674}, \mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{674}, \mdline{674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{674}) values. The +P4Runtime server selects a primary independently for each (\mdline{675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{675}, +\mdline{676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{676}) pair. The primary is the client that has the highest \mdline{676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{676} +that the device has ever received for the same (\mdline{677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{677}, +\mdline{678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{678}) values. A connection between a controller instance and a device id +\mdline{679}\textemdash{}\mdline{679} which involves a persistent \mdline{679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{679} \mdline{679}\textemdash{}\mdline{679} can be referred to as a +P4Runtime client.%mdk + +%mdk-data-line={682} +\mdline{682}Note that the P4Runtime server does not assign a \mdline{682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{682} or \mdline{682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{682} to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the \mdline{684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{684} values used for each +\mdline{685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{685}. The P4Runtime server only keeps track of the (\mdline{685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{685}, +\mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{686}, \mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{686}) of each \mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{686} that has sent a successful +\mdline{687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{687} message, and maintains the invariant that all such +3-tuples are unique. A server must use all three of these values from a +\mdline{689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{689} message to identify which client is making the \mdline{689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{689}, +not only the \mdline{690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{690}. This enables controllers to re-use the same +numeric \mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{691} values across different (\mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{691}, \mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{691}) +pairs. P4Runtime does not require \mdline{692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{692} values be reused across such +different (\mdline{693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{693}, \mdline{693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{693}) pairs; it allows it.%mdk%mdk + +%mdk-data-line={695} +\item{} +%mdk-data-line={695} +\mdline{695}To start a controller session, a controller first opens a bidirectional stream +channel to the server via the \mdline{696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{696} RPC for each device. This stream +will be used for two purposes:%mdk + +%mdk-data-line={699} +\begin{itemize}%mdk + +%mdk-data-line={699} +\item{} +%mdk-data-line={699} +\mdline{699}\textbf{Session management:}\mdline{699} As soon as the controller opens the stream +channel, it sends a \mdline{700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{700} message to the switch. The +controller populates the \mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{701} field in this message +using its \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{702} and \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{702}, as well as the \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{702} of the +device. Note that the \mdline{703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{703} field in the \mdline{703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{703} is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below.%mdk%mdk + +%mdk-data-line={707} +\item{} +%mdk-data-line={707} +\mdline{707}\textbf{Streaming of notifications (e.g. digests) and packet I/O:}\mdline{707} The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the primary controller can participate in +packet I/O. This feature is explained in more details in the\mdline{711}~\mdref{sec-packet-i_o}{Packet +I/O}\mdline{712} section.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={714} +\mdline{714}Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state.%mdk%mdk + +%mdk-data-line={717} +\item{} +%mdk-data-line={717} +\mdline{717}Note that the stream is opened per device. In case a switching platform has +multiple devices (\mdline{718}e.g.\mdline{718} multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different primary clients for +different devices. In this case, it is the responsibility of the P4Runtime +server to keep track of the primary for each device (and role). More +specifically, the P4Runtime server will know which stream corresponds to the +primary controller for each pair of (\mdline{723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{723}, \mdline{723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{723}) at any point of +time.%mdk%mdk + +%mdk-data-line={726} +\item{} +%mdk-data-line={726} +\mdline{726}The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered \mdline{727}\textquotedblleft{}offline\textquotedblright{}\mdline{727} or +\mdline{728}\textquotedblleft{}dead\textquotedblright{}\mdline{728} as soon as its stream channel to the switch is broken. When a primary +channel gets broken: (i) an advisory message is sent to all other controllers +for that \mdline{730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{730} and \mdline{730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{730}, as described in the +\mdline{731}\mdref{sec-arbitration-notification}{following section}\mdline{731} (ii) the P4Runtime server +will be without a primary controller, until a client sends a successful +\mdline{733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{733} (as per the rules in a +\mdline{734}\mdref{sec-arbitration-updates}{later section}\mdline{734}).%mdk%mdk + +%mdk-data-line={736} +\item{} +%mdk-data-line={736} +\mdline{736}The mechanism via which the controller receives the P4Runtime server details +which includes the \mdline{737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{737}, \mdline{737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip}}}\mdline{737} and \mdline{737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{737}, as well as the mechanism via +which it receives the Forwarding Pipeline Config, are implementation specific +and beyond the scope of this specification. Similarly, the mechanism via which +the P4Runtime server receives its switch config (which notably includes the +\mdline{741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{741}) is beyond the scope of this specification. Nevertheless, if the +server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={746} +\noindent\mdline{746}gRPC enables the server to identify which client originated each message in the +\mdline{747}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{747} stream. For example, the C++ gRPC library\mdline{747}~[\mdcite{grpcstreamc}{10}]\mdline{747} in +synchronous mode enables a server process to cause a function to be called when +a new client creates a \mdline{749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{749} stream. This function should not return +until the stream is closed and the server has done any cleanup required when a +\mdline{751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{751} is closed normally (or broken, \mdline{751}e.g.\mdline{751} because a client process +unexpectedly terminated). Thus the server can easily associate all +\mdline{753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{753} messages received from the same client, because they are +processed within the context of the same function call.%mdk + +%mdk-data-line={756} +\mdline{756}A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values \mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{761}, \mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{761}, and \mdline{761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{761} in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods\mdline{763}~[\mdcite{grpcauth}{8}]\mdline{763} that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server.%mdk + +%mdk-data-line={767} +\subsection{\mdline{767}5.1.\hspace*{0.5em}\mdline{767}Default Role}\label{sec-default-role}%mdk%mdk + +%mdk-data-line={769} +\noindent\mdline{769}A controller can omit the role message in \mdline{769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{769}. This +implies the \mdline{770}\textquotedblleft{}default role\textquotedblright{}\mdline{770}, which corresponds to \mdline{770}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{770}. +This also implies that a default role has a \mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{771} of \mdline{771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}""}}}\mdline{771} (default). +If using a default role, all RPCs from the controller (\mdline{772}e.g.\mdline{772} \mdline{772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{772}) must +leave the \mdline{773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{773} unset.%mdk + +%mdk-data-line={775} +\subsection{\mdline{775}5.2.\hspace*{0.5em}\mdline{775}Role Config}\label{sec-arbitration-role-config}%mdk%mdk + +%mdk-data-line={777} +\noindent\mdline{777}The \mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{777} field in the \mdline{777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{777} message sent by the +controller describes the role configuration, \mdline{778}i.e.\mdline{778} which operations are in the +scope of a given role. In particular, the definition of a role may include the +following:%mdk + +%mdk-data-line={782} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={782} +\item\mdline{782}A list of P4 entities for which the controller may issue \mdline{782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{782} updates and +receive notification messages (\mdline{783}e.g.\mdline{783} \mdline{783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{783} and +\mdline{784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{784}).%mdk + +%mdk-data-line={785} +\item\mdline{785}Whether the controller is able to receive \mdline{785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{785} messages, along with a +filtering mechanism based on the values of the \mdline{786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{786} fields to +select which \mdline{787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{787} messages should be sent to the controller.%mdk + +%mdk-data-line={788} +\item\mdline{788}Whether the controller is able to send \mdline{788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{788} messages, along with a +filtering mechanism based on the values of the \mdline{789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{789} fields to +select which \mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{790} messages are allowed to be sent by the controller.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={792} +\noindent\mdline{792}An unset \mdline{792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{792} implies \mdline{792}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{792} (similar to the default +role explained above). In order to support different role definition schemes, +\mdline{794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{794} is defined as an \mdline{794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{794} Protobuf message\mdline{794}~[\mdcite{protoany}{31}]\mdline{794}. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion.%mdk + +%mdk-data-line={799} +\mdline{799}It is the job of the P4Runtime server to remember the \mdline{799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{799} for every +\mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{800} and \mdline{800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{800} pair.%mdk + +%mdk-data-line={802} +\subsection{\mdline{802}5.3.\hspace*{0.5em}\mdline{802}Rules for Handling \mdline{802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{802} Messages Received from Controllers}\label{sec-arbitration-updates}%mdk%mdk + +%mdk-data-line={804} +\begin{enumerate}%mdk + +%mdk-data-line={804} +\item{} +%mdk-data-line={804} +\mdline{804}If the \mdline{804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{804} message is received for the first time on +this particular channel (\mdline{805}i.e.\mdline{805} for a newly connected controller):%mdk + +%mdk-data-line={807} +\begin{enumerate}%mdk + +%mdk-data-line={807} +\item{} +%mdk-data-line={807} +\mdline{807}If \mdline{807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{807} does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +\mdline{809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{809} error.%mdk%mdk + +%mdk-data-line={811} +\item{} +%mdk-data-line={811} +\mdline{811}If the \mdline{811}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{811} is set and is already used by another controller for +the same (\mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{812}, \mdline{812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{812}), the P4Runtime server shall terminate +the stream by returning an \mdline{813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{813} error.%mdk%mdk + +%mdk-data-line={815} +\item{} +%mdk-data-line={815} +\mdline{815}If \mdline{815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{815} does not match the \mdline{815}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{815} scheme previously +agreed upon, the server must return an \mdline{816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{816} error.%mdk%mdk + +%mdk-data-line={818} +\item{} +%mdk-data-line={818} +\mdline{818}If the number of open streams for the given (\mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{818}, \mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{818}) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a \mdline{820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{820} error.%mdk%mdk + +%mdk-data-line={822} +\item{} +%mdk-data-line={822} +\mdline{822}Otherwise, the controller is added to a list of connected controllers for +the given (\mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{823}, \mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{823}) and the server remembers the +controllers \mdline{824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{824}, \mdline{824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{824} and \mdline{824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{824} for this gRPC +channel. See below for the rules to determine if this controller becomes +a primary or backup, and what notifications are sent as a consequence.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={828} +\item{} +%mdk-data-line={828} +\mdline{828}Otherwise, if the \mdline{828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{828} message is received from an +already connected controller:%mdk + +%mdk-data-line={831} +\begin{enumerate}%mdk + +%mdk-data-line={831} +\item{} +%mdk-data-line={831} +\mdline{831}If the \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{831} does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{833} error.%mdk%mdk + +%mdk-data-line={835} +\item{} +%mdk-data-line={835} +\mdline{835}If the \mdline{835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{835} does not match the current \mdline{835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{835} assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{837} error. If the controller wishes to change its role, +it must close the current stream channel and open a new one.%mdk%mdk + +%mdk-data-line={840} +\item{} +%mdk-data-line={840} +\mdline{840}If \mdline{840}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{840} does not match the \mdline{840}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{840} scheme previously +agreed upon, the server must return an \mdline{841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{841} error.%mdk%mdk + +%mdk-data-line={843} +\item{} +%mdk-data-line={843} +\mdline{843}If the \mdline{843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{843} is set and is already used by another controller +(excluding the controller making the request) for the same +(\mdline{845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{845}, \mdline{845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{845}), the P4Runtime server shall terminate the stream +by returning an \mdline{846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{846} error.%mdk%mdk + +%mdk-data-line={848} +\item{} +%mdk-data-line={848} +\mdline{848}Otherwise, the server updates the \mdline{848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{848} it has stored for this +controller. This change might cause a change in the primary client (this +controller might become primary, or the controller might have downgraded +itself to a backup, see below), as well as notifications being sent to +one or more controllers.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={854} +\noindent\mdline{854}If the \mdline{854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{854} is accepted by either of the two steps above +(cases 1.5. and 2.5. above), then the server determines if there are changes in +the primary client. Let \mdline{856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{856} be the highest election ID the server +has ever seen for the given \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{857} and \mdline{857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{857} (including the one of the +current primary if there is one).%mdk + +%mdk-data-line={860} +\begin{enumerate}%mdk + +%mdk-data-line={860} +\item{} +%mdk-data-line={860} +\mdline{860}If \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{860} is greater than or equal to \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{860}, then the +controller becomes, or stays, primary. The server updates the role +configuration to \mdline{862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{862} for the given \mdline{862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{862}. Furthermore:%mdk + +%mdk-data-line={864} +\begin{enumerate}%mdk + +%mdk-data-line={864} +\item{} +%mdk-data-line={864} +\mdline{864}If there was no primary for this \mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{864} and \mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{864} before and +there are no \mdline{865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{865} requests still processing from a previous primary, +then the server immediately sends an advisory notification to all +controllers for this \mdline{867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{867} and \mdline{867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{867}. See the +\mdline{868}\mdref{sec-arbitration-notification}{following section}\mdline{868} for the format of the +advisory message.%mdk%mdk + +%mdk-data-line={871} +\item{} +%mdk-data-line={871} +\mdline{871}If there was a previous primary, including this controller, or \mdline{871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{871} +requests in flight, then the server carries out the following steps +(in this order):%mdk + +%mdk-data-line={875} +\begin{enumerate}%mdk + +%mdk-data-line={875} +\item{} +%mdk-data-line={875} +\mdline{875}The server stops accepting \mdline{875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{875} requests from the previous primary +(if there is one). At this point, the server will reject all \mdline{876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{876} +requests with \mdline{877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{877}.%mdk%mdk + +%mdk-data-line={879} +\item{} +%mdk-data-line={879} +\mdline{879}The server notifies all controllers other than the new primary client +of the change by sending the advisory notification described in +the\mdline{881}~\mdref{sec-arbitration-notification}{following section}\mdline{881}.%mdk%mdk + +%mdk-data-line={883} +\item{} +%mdk-data-line={883} +\mdline{883}The server will finish processing any \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{883} requests that have +already started. If there are errors, they are reported as usual to +the previous primary. If the previous primary has already +disconnected, any possible errors are dropped and not reported.%mdk%mdk + +%mdk-data-line={888} +\item{} +%mdk-data-line={888} +\mdline{888}The server now accepts the current controller as the new primary, +thus accepting \mdline{889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{889} requests from this controller. The server +updates the highest election ID (\mdline{890}i.e.\mdline{890} \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{890}) it has seen +for this \mdline{891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{891} and \mdline{891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{891} to \mdline{891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{891}.%mdk%mdk + +%mdk-data-line={893} +\item{} +%mdk-data-line={893} +\mdline{893}The server notifies the new primary by sending the advisory message +described in the\mdline{894}~\mdref{sec-arbitration-notification}{following section}\mdline{894}.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={896} +\item{} +%mdk-data-line={896} +\mdline{896}Otherwise, the controller becomes a backup. If the controller was previously +a primary (and downgraded itself), then an advisory message is sent to all +controllers for this \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{898} and \mdline{898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{898}. Otherwise, the advisory +message is only sent to the controller that sent the initial +\mdline{900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{900}. See the +\mdline{901}\mdref{sec-arbitration-notification}{following section}\mdline{901} for the format of the +advisory message.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={904} +\subsection{\mdline{904}5.4.\hspace*{0.5em}\mdline{904}Client Arbitration Notifications}\label{sec-arbitration-notification}%mdk%mdk + +%mdk-data-line={906} +\noindent\mdline{906}For any given \mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{906} and \mdline{906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{906}, any time a new primary is chosen, a +primary downgrades its status to a backup, a primary disconnects, or the +\mdline{908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{908} is updated by the primary, all controllers for that +(\mdline{909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{909}, \mdline{909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{909}) are informed of this by sending a +\mdline{910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{910}. The \mdline{910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{910} is populated as follows:%mdk + +%mdk-data-line={912} +\begin{itemize}%mdk + +%mdk-data-line={912} +\item{} +%mdk-data-line={912} +\mdline{912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{912} and \mdline{912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{912} as given.%mdk%mdk + +%mdk-data-line={914} +\item{} +%mdk-data-line={914} +\mdline{914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{914} is set to the role configuration the server received most +recently in a \mdline{915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{915} from a primary.%mdk%mdk + +%mdk-data-line={917} +\item{} +%mdk-data-line={917} +\mdline{917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{917} is populated as follows:%mdk + +%mdk-data-line={919} +\begin{itemize}%mdk + +%mdk-data-line={919} +\item{} +%mdk-data-line={919} +\mdline{919}If there has not been any primary at all, the election\mdline{919}\_\mdline{919}id is left unset.%mdk%mdk + +%mdk-data-line={921} +\item{} +%mdk-data-line={921} +\mdline{921}Otherwise, \mdline{921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{921} is set to the highest election ID that the server +has seen for this \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{922} and \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{922} (which is the \mdline{922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{922} of +the current primary if there is any).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={925} +\item{} +%mdk-data-line={925} +\mdline{925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{925} is set differently based on whether the notification is sent to the +primary or a backup controller:%mdk + +%mdk-data-line={928} +\begin{itemize}%mdk + +%mdk-data-line={928} +\item{} +%mdk-data-line={928} +\mdline{928}If there is a primary:%mdk + +%mdk-data-line={930} +\begin{itemize}%mdk + +%mdk-data-line={930} +\item{} +%mdk-data-line={930} +\mdline{930}For the primary, \mdline{930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{930} is OK (with \mdline{930}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{930} set to +\mdline{931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.OK}}}\mdline{931}).%mdk%mdk + +%mdk-data-line={933} +\item{} +%mdk-data-line={933} +\mdline{933}For all backup controllers, \mdline{933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{933} is set to non-OK (with +\mdline{934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{934} set to \mdline{934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.ALREADY\_EXISTS}}}\mdline{934}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={936} +\item{} +%mdk-data-line={936} +\mdline{936}Otherwise, if there is no primary currently, for all backup controllers, +\mdline{937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{937} is set to non-OK (with \mdline{937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{937} set to +\mdline{938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.NOT\_FOUND}}}\mdline{938}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={940} +\noindent\mdline{940}Note that on primary client changes with outstanding \mdline{940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{940} request, some +notifications might be delayed, see the +\mdline{942}\mdref{sec-arbitration-updates}{previous section}\mdline{942} for details.%mdk + +%mdk-data-line={944} +\section{\mdline{944}6.\hspace*{0.5em}\mdline{944}The P4Info Message}\label{sec-the-p4info-message}%mdk%mdk + +%mdk-data-line={946} +\noindent\mdline{946}The purpose of P4Info was described under +\mdline{947}\mdref{sec-reference-architecture}{Reference Architecture}\mdline{947}. +Here we describe the various +components.%mdk + +%mdk-data-line={951} +\subsection{\mdline{951}6.1.\hspace*{0.5em}\mdline{951}Common Messages}\label{sec-common-messages}%mdk%mdk + +%mdk-data-line={953} +\noindent\mdline{953}These messages appear nested within many other messages.%mdk + +%mdk-data-line={955} +\subsubsection{\mdline{955}6.1.1.\hspace*{0.5em}\mdline{955}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{955} Message}\label{sec-documentation-message}%mdk%mdk + +%mdk-data-line={957} +\noindent\mdline{957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{957} is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers.%mdk + +%mdk-data-line={961} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={962} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Documentation~\{\\ +~~{\mdcolor{darkgreen}//~A~brief~description~of~something,~e.g.~one~sentence}\\ +~~{\bfseries{\mdcolor{navy}string}}~brief~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~A~more~verbose~description~of~something.}\\ +~~{\mdcolor{darkgreen}//~Multiline~is~accepted.~Markup~format~(if~any)~is~TBD.}\\ +~~{\bfseries{\mdcolor{navy}string}}~description~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={971} +\subsubsection{\mdline{971}6.1.2.\hspace*{0.5em}\mdline{971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{971} Message}\label{sec-preamble-message}%mdk%mdk + +%mdk-data-line={973} +\noindent\mdline{973}The preamble serves as the \mdline{973}\textquotedblleft{}descriptor\textquotedblright{}\mdline{973} for each entity and contains the unique +instance ID, name, alias, annotations and documentation.%mdk + +%mdk-data-line={976} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={977} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Preamble~\{\\ +~~{\mdcolor{darkgreen}//~ids~share~the~same~number-space;~e.g.~table~ids~cannot~overlap~with~counter}\\ +~~{\mdcolor{darkgreen}//~ids.~Even~though~this~is~irrelevant~to~this~proto~definition,~the~ids~are}\\ +~~{\mdcolor{darkgreen}//~allocated~in~such~a~way~that~it~is~possible~based~on~an~id~to~deduce~the}\\ +~~{\mdcolor{darkgreen}//~resource~type~(e.g.~table,~action,~counter,~...).~This~means~that~code}\\ +~~{\mdcolor{darkgreen}//~using~these~ids~can~detect~if~the~wrong~resource~type~is~used}\\ +~~{\mdcolor{darkgreen}//~somewhere.~This~also~means~that~ids~of~different~types~can~be~mixed}\\ +~~{\mdcolor{darkgreen}//~(e.g.~direct~resource~list~for~a~table)~without~ambiguity.~Note~that~id~0}\\ +~~{\mdcolor{darkgreen}//~is~reserved~and~means~"invalid~id".}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name~of~the~P4~object,~e.g.~c1.c2.ipv4\_lpm}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~an~alias~(alternative~name)~for~the~P4~object,~probably~shorter~than~its}\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name.~The~only~constraint~is~for~it~to~be~unique~with}\\ +~~{\mdcolor{darkgreen}//~respect~to~other~P4~objects~of~the~same~type.~By~default,~the~compiler~uses}\\ +~~{\mdcolor{darkgreen}//~the~shortest~suffix~of~the~name~that~uniquely~identifies~the~object.~For}\\ +~~{\mdcolor{darkgreen}//~example~if~the~P4~program~contains~two~tables~with~names~s.c1.t~and~s.c2.t,}\\ +~~{\mdcolor{darkgreen}//~the~default~aliases~will~respectively~be~c1.t~and~c2.t.~In~the~future,~the}\\ +~~{\mdcolor{darkgreen}//~P4~programmer~may~also~be~able~to~override~the~default~alias~for~any~P4}\\ +~~{\mdcolor{darkgreen}//~object~(TBD).}\\ +~~{\bfseries{\mdcolor{navy}string}}~alias~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~Optional.~If~present,~the~location~of~`annotations{}[i]`~is~given~by}\\ +~{\mdcolor{darkgreen}//~`annotation\_locations{}[i]`.}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~SourceLocation~annotation\_locations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~Documentation~of~the~entity}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1008} +\subsubsection{\mdline{1008}6.1.3.\hspace*{0.5em}\mdline{1008}Annotating P4 Entities with \mdline{1008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}\label{sec-annotating-p4-entities-with-documentation}%mdk%mdk + +%mdk-data-line={1010} +\noindent\mdline{1010}P4 entities may be annotated using the following annotations:%mdk + +%mdk-data-line={1012} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1013} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}(string...)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}(string...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1017} +\noindent\mdline{1017}Attaching either or both of these annotations to an entity will generate a +P4Info\mdline{1018}~\mdref{sec-documentation-message}{Documentation Message}\mdline{1018}, which in turn will +appear in the\mdline{1019}~\mdref{sec-preamble-message}{Preamble Message}\mdline{1019} for the entity.%mdk + +%mdk-data-line={1021} +\mdline{1021}The P4 compiler should not emit \mdline{1021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation}}}\mdline{1021} messages in the P4Info for these +specific cases; instead, it should generate the \mdline{1022}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1022} messages as +described.%mdk + +%mdk-data-line={1025} +\mdline{1025}The following example shows documentation annotations for a \mdline{1025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table}}}\mdline{1025} entity:%mdk + +%mdk-data-line={1027} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1028} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port.~\textbackslash{}}\\ +Uses~LPM~match~{\bfseries{\mdcolor{navy}type}}.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}table~my\_ipv4\_lkup~\{}\\ +{\mdcolor{maroon}~~...}\\ +{\mdcolor{maroon}\}}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1036} +\subsubsection{\mdline{1036}6.1.4.\hspace*{0.5em}\mdline{1036}Structured Annotations}\label{sec-structured-annotations}%mdk%mdk + +%mdk-data-line={1038} +\noindent\mdline{1038}P4 supports both unstructured and structured annotations\mdline{1038}~[\mdcite{p4annotations}{13}]\mdline{1038}. +Unstructured annotations of the form \mdline{1039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno1}}}\mdline{1039} or \mdline{1039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno2(body-content)}}}\mdline{1039} can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +\mdline{1042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno3{}[]}}}\mdline{1042} or \mdline{1042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno4{}[kvList\textbar{}expressionList]}}}\mdline{1042} have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this.%mdk + +%mdk-data-line={1047} +\mdline{1047}The annotations described up to this point, \mdline{1047}e.g.\mdline{1047} \mdline{1047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief()}}}\mdline{1047}, have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as \mdline{1049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1049} fields in the various \mdline{1049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{1049}s. +Similarly, structured annotations are represented in \mdline{1050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated\\ +StructuredAnnotation~structured\_annotations}}}\mdline{1051} fields which are siblings to the +unstructured \mdline{1052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1052}. The \mdline{1052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations}}}\mdline{1052} contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations.%mdk + +%mdk-data-line={1057} +\mdline{1057}The structured annotation messages are defined in p4types.proto.%mdk + +%mdk-data-line={1059} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1060} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~KeyValuePair~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~key~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Expression~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~KeyValuePairList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~KeyValuePair~kv\_pairs~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Expression~\{\\ +~~{\bfseries{\mdcolor{navy}oneof}}~value~\{\\ +~~~~{\bfseries{\mdcolor{navy}string}}~string\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~{\bfseries{\mdcolor{navy}int64}}~int64\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~{\bfseries{\mdcolor{navy}bool}}~bool\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~ExpressionList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Expression~expressions~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~StructuredAnnotation~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}oneof}}~body~\{\\ +~~~~ExpressionList~expression\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~KeyValuePairList~kv\_pair\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~Optional.~Location~of~the~'@'~symbol~of~this~annotation~in~the~source~code.}\\ +~~SourceLocation~source\_location~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1092} +\noindent\mdline{1092}The \mdline{1092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1092} message can represent either a \mdline{1092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1092} +or an \mdline{1093}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExpressionList}}}\mdline{1093}.%mdk + +%mdk-data-line={1095} +\mdline{1095}The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The \mdline{1096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{1096} +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don\mdline{1098}'\mdline{1098}t match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler \mdline{1100}\emph{may}\mdline{1100} print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions.%mdk + +%mdk-data-line={1104} +\mdline{1104}The following invariants hold:%mdk + +%mdk-data-line={1106} +\begin{enumerate}%mdk + +%mdk-data-line={1106} +\item{} +%mdk-data-line={1106} +\mdline{1106}For any P4 entity, there are no two \mdline{1106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1106}s that have the +same name.%mdk%mdk + +%mdk-data-line={1109} +\item{} +%mdk-data-line={1109} +\mdline{1109}Within a \mdline{1109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1109}, there are no two \mdline{1109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePair}}}\mdline{1109}s that have the +same \mdline{1110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key.}}}\mdline{1110}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1112} +\paragraph{\mdline{1112}6.1.4.1.\hspace*{0.5em}\mdline{1112}Structured Annotation Examples}\label{sec-structured-annotation-examples}%mdk%mdk + +%mdk-data-line={1114} +\noindent\mdline{1114}We omit the \mdline{1114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}source\_location}}}\mdline{1114} field in the following examples.%mdk + +%mdk-data-line={1116} +\mdline{1116}\textbf{Empty Expression List}\mdline{1116}%mdk + +%mdk-data-line={1118} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1119} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}Empty}{\mdcolor{maroon}{}[]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1125} +\noindent\mdline{1125}The generated P4Info will contain the following.%mdk + +%mdk-data-line={1127} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1128} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}Empty}{\mdcolor{maroon}"}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1133} +\noindent\mdline{1133}\textbf{Mixed Expression List}\mdline{1133}%mdk + +%mdk-data-line={1135} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1136} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~TEXT\_CONST~"hello"}\\ +{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~NUM\_CONST~6}\\ +{\mdcolor{gray}@}{\mdcolor{gray}MixedExprList}{\mdcolor{maroon}{}[1,TEXT\_CONST,true,1==2,5+NUM\_CONST]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1144} +\noindent\mdline{1144}The generated P4Info will contain:%mdk + +%mdk-data-line={1146} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1147} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedExprList}{\mdcolor{maroon}"}\\ +~~expression\_list~\{\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}1}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}hello}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~true\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~false\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}11}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1169} +\noindent\mdline{1169}\textbf{kvList of Mixed Expressions}\mdline{1169}%mdk + +%mdk-data-line={1171} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1172} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}MixedKV}{\mdcolor{maroon}{}[label="text",~my\_bool=true,~int\_val=2*3]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1178} +\noindent\mdline{1178}The generated P4Info will contain:%mdk + +%mdk-data-line={1180} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1181} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedKV}{\mdcolor{maroon}"}\\ +~~kv\_pair\_list~\{\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}label}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}text}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}my\_bool}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~bool\_value:~true\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}int\_val}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~int64\_value:~{\mdcolor{purple}6}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1206} +\subsubsection{\mdline{1206}6.1.5.\hspace*{0.5em}\mdline{1206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1206} Message}\label{sec-sourcelocation-message}%mdk%mdk + +%mdk-data-line={1208} +\noindent\mdline{1208}A source location describes a location within a \mdline{1208}\emph{.p4}\mdline{1208}-source file. The +\mdline{1209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1209} message is defined in p4types.proto as follows:%mdk + +%mdk-data-line={1211} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1212} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Location~of~code~relative~to~a~given~source~file.}\\ +{\bfseries{\mdcolor{navy}message}}~SourceLocation~\{\\ +~~{\mdcolor{darkgreen}//~Path~to~the~source~file~(absolute~or~relative~to~the~working~directory).}\\ +~~{\bfseries{\mdcolor{navy}string}}~file~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Line~and~column~numbers~within~the~source~file,~1-based.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~line~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}int32}}~column~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1222} +\noindent\mdline{1222}We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations.%mdk + +%mdk-data-line={1227} +\mdline{1227}The \mdline{1227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1227} message associated with an annotation holds the location of +the \mdline{1228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@}}}\mdline{1228} symbol introducing the annotation in the P4 source code; the message can +be found in the following place:%mdk + +%mdk-data-line={1231} +\begin{itemize}%mdk + +%mdk-data-line={1231} +\item{} +%mdk-data-line={1231} +\mdline{1231}For \mdline{1231}\textbf{unstructured annotations}\mdline{1231}, every message containing a field +\mdline{1232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1232} also contains a field +\mdline{1233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~SourceLocation~annotation\_locations}}}\mdline{1233}. The field must either be empty + or match the size of \mdline{1234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1234}. In the latter case, the i-th member of +\mdline{1235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation\_locations}}}\mdline{1235} is the source location of the i-th member of +\mdline{1236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1236}.%mdk%mdk + +%mdk-data-line={1238} +\item{} +%mdk-data-line={1238} +\mdline{1238}For \mdline{1238}\textbf{structured annotations}\mdline{1238}, every \mdline{1238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1238} message contains +an optional field \mdline{1239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation~source\_location}}}\mdline{1239} holding its source +location, if present.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1243} +\subsection{\mdline{1243}6.2.\hspace*{0.5em}\mdline{1243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1243} Message}\label{sec-pkginfo-message}%mdk%mdk + +%mdk-data-line={1245} +\noindent\mdline{1245}The \mdline{1245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1245} message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. \mdline{1246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1246} can be extracted +and used to facilitate \mdline{1247}\textquotedblleft{}browsing\textquotedblright{}\mdline{1247} of available P4 programs from a +library. Although all fields are technically \mdline{1248}\textquotedblleft{}optional,\textquotedblright{}\mdline{1248} every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included.%mdk + +%mdk-data-line={1252} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1253} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Can~be~used~to~manage~multiple~P4~packages.}\\ +{\bfseries{\mdcolor{navy}message}}~PkgInfo~\{\\ +~~{\mdcolor{darkgreen}//~a~definitive~name~for~this~configuration,~e.g.~switch.p4\_v1.0}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~configuration~version,~free-format~string}\\ +~~{\bfseries{\mdcolor{navy}string}}~version~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~brief~and~detailed~descriptions}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~free-form;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~the~target~architecture,~e.g.~"psa"}\\ +~~{\bfseries{\mdcolor{navy}string}}~arch~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\mdcolor{darkgreen}//~organization~which~produced~the~configuration,~e.g.~"p4.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~organization~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~{\mdcolor{darkgreen}//~contact~info~for~support,e.g.~"tech-support@acme.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~contact~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~url~for~more~information,~e.g.~"http://support.p4.org/ref/p4/switch.p4\_v1.0"}\\ +~~{\bfseries{\mdcolor{navy}string}}~url~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}8};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~structured;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}9};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1276} +\subsubsection{\mdline{1276}6.2.1.\hspace*{0.5em}\mdline{1276}Annotating P4 code with PkgInfo}\label{sec-annotating-p4-code-with-pkginfo}%mdk%mdk + +%mdk-data-line={1278} +\noindent\mdline{1278}A P4 progam\mdline{1278}'\mdline{1278}s \mdline{1278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1278} may be declared using one or more of the following +annotations, attached to the \mdline{1279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1279} block only:%mdk + +%mdk-data-line={1281} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1282} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value{}[,key=value,...])}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("A~brief~description")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("A~longer\textbackslash{}}\\ +description{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@custom\_annotation(...)}\\ +{\mdcolor{maroon}@another\_custom\_annotation(...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1291} +\noindent\mdline{1291}Above we see several different types of annotations:%mdk + +%mdk-data-line={1293} +\begin{itemize}%mdk + +%mdk-data-line={1293} +\item{} +%mdk-data-line={1293} +\mdline{1293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1293} \mdline{1293}- This is used to populate a specific field within the \mdline{1293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1293} +message. Multiple \mdline{1294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1294} annotations are allowed. For compactness, +multiple key-value pairs can appear in a single \mdline{1295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1295} annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The \mdline{1297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{1297}s must be from +among the message fields inside \mdline{1298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1298}, for example, \mdline{1298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1298}, \mdline{1298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}version}}}\mdline{1298}, +etc. Each key-value pair assigns a value to the corresponding field inside the +single \mdline{1300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1300} message for the program\mdline{1300}'\mdline{1300}s P4Info. One exception is that the +\mdline{1301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1301} field of \mdline{1301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1301} must be expressed as individual +\mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1302} and \mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1302} annotations, see next bullets. The key \mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}arch}}}\mdline{1302} will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself.%mdk%mdk + +%mdk-data-line={1306} +\item{} +%mdk-data-line={1306} +\mdline{1306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1306} \mdline{1306}- This will populate the \mdline{1306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.brief}}}\mdline{1306} message field.%mdk%mdk + +%mdk-data-line={1308} +\item{} +%mdk-data-line={1308} +\mdline{1308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1308} \mdline{1308}- This will populate the \mdline{1308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.description}}}\mdline{1308} message +field%mdk%mdk + +%mdk-data-line={1311} +\item{} +%mdk-data-line={1311} +\mdline{1311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@\textless{}anything~else\textgreater{}}}}\mdline{1311} \mdline{1311}- This will create a \mdline{1311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotation}}}\mdline{1311} entry%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1313} +\noindent\mdline{1313}Declaring one or more of these annotations on \mdline{1313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1313} will +generate a single corresponding \mdline{1314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1314} message in the P4Info as described in +\mdline{1315}\mdref{sec-pkginfo-message}{PkgInfo Message}\mdline{1315}.%mdk + +%mdk-data-line={1317} +\mdline{1317}The following example shows \mdline{1317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1317} annotations using a mixture of single and +multiple key-value pairs. It also shows \mdline{1318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1318} and \mdline{1318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1318} annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the \mdline{1320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1320} message. The custom annotations will +be appended to the \mdline{1321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotations}}}\mdline{1321} list.%mdk + +%mdk-data-line={1323} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1324} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(name="switch.p4",version="2")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(organization="p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(contact="info@p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(url="www.p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("L2/L3~switch")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("L2/L3~switch.\textbackslash{}}\\ +Built~for~data-center~profile.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@my\_annotation1(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}@my\_annotation2(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}PSA\_Switch(IgPipeline,~PacketReplicationEngine(),~EgPipeline,}\\ +{\mdcolor{maroon}~~~~~~~~~~~BufferingQueueingEngine())~main;}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1337} +\subsection{\mdline{1337}6.3.\hspace*{0.5em}\mdline{1337}ID Allocation for P4Info Objects}\label{sec-id-allocation}%mdk%mdk + +%mdk-data-line={1339} +\noindent\mdline{1339}P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(\mdline{1343}e.g.\mdline{1343} table, action, counter, \mdline{1343}\dots{}\mdline{1343}). The most significant 8 bits of the ID +encodes the object type (as per Table\mdline{1344}~\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}}\mdline{1344}). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (\mdline{1346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.P4Ids.Prefix}}}\mdline{1346}). These values must +be used (\mdline{1347}e.g.\mdline{1347} by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table\mdline{1349}~\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}}\mdline{1349} shows the ID +layout.%mdk + +%mdk-data-line={1352} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1354} 8-bit prefix value}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1354} P4 object type}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{1356} 0x00}&\multicolumn{1}{|l|}{\mdline{1356} Reserved (unspecified)}\\ +\multicolumn{1}{|l}{\mdline{1357} 0x01}&\multicolumn{1}{|l|}{\mdline{1357} Action}\\ +\multicolumn{1}{|l}{\mdline{1358} 0x02}&\multicolumn{1}{|l|}{\mdline{1358} Table}\\ +\multicolumn{1}{|l}{\mdline{1359} 0x03}&\multicolumn{1}{|l|}{\mdline{1359} Value-set}\\ +\multicolumn{1}{|l}{\mdline{1360} 0x04}&\multicolumn{1}{|l|}{\mdline{1360} Controller header (header type with \mdline{1360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1360} annotation)}\\ +\multicolumn{1}{|l}{\mdline{1361} 0x05\mdline{1361}\dots{}\mdline{1361}0x0f}&\multicolumn{1}{|l|}{\mdline{1361} Reserved (for future P4 built-in objects)}\\ +\multicolumn{1}{|l}{\mdline{1362} 0x10}&\multicolumn{1}{|l|}{\mdline{1362} Reserved (start of PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1363} 0x11}&\multicolumn{1}{|l|}{\mdline{1363} PSA Action profiles / selectors}\\ +\multicolumn{1}{|l}{\mdline{1364} 0x12}&\multicolumn{1}{|l|}{\mdline{1364} PSA Counter}\\ +\multicolumn{1}{|l}{\mdline{1365} 0x13}&\multicolumn{1}{|l|}{\mdline{1365} PSA Direct counter}\\ +\multicolumn{1}{|l}{\mdline{1366} 0x14}&\multicolumn{1}{|l|}{\mdline{1366} PSA Meter}\\ +\multicolumn{1}{|l}{\mdline{1367} 0x15}&\multicolumn{1}{|l|}{\mdline{1367} PSA Direct meter}\\ +\multicolumn{1}{|l}{\mdline{1368} 0x16}&\multicolumn{1}{|l|}{\mdline{1368} PSA Register}\\ +\multicolumn{1}{|l}{\mdline{1369} 0x17}&\multicolumn{1}{|l|}{\mdline{1369} PSA Digest}\\ +\multicolumn{1}{|l}{\mdline{1370} 0x18\mdline{1370}\dots{}\mdline{1370}0x7f}&\multicolumn{1}{|l|}{\mdline{1370} Reserved (for future PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1371} 0x80}&\multicolumn{1}{|l|}{\mdline{1371} Reserved (start of vendor-specific extern types)}\\ +\multicolumn{1}{|l}{\mdline{1372} 0x81\mdline{1372}\dots{}\mdline{1372}0xfe}&\multicolumn{1}{|l|}{\mdline{1372} Vendor-specific extern types}\\ +\multicolumn{1}{|l}{\mdline{1373} 0xff}&\multicolumn{1}{|l|}{\mdline{1373} Reserved (max prefix value)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1375} +\mdhr{}%mdk + +%mdk-data-line={1376} +\noindent\mdline{1376}\mdcaption{\textbf{Table~\mdcaptionlabel{1}.}~\mdcaptiontext{Mapping of P4Info object type to 8-bit ID prefix value}}%mdk +%mdk +\end{mdcenter}\label{tab-mapping-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1379} +\begin{table}[h!]%mdk +\begin{mdblock}{text-align=center,breakable=true}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{cc}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1381} MSB bit 31 \mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}.. bit 24}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1381} bit 23 \mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}\dots{}\mdline{1381}.. bit 0 LSB}}\\ + +\midrule +\multicolumn{1}{|c}{\mdline{1383} Object type prefix}&\multicolumn{1}{|c|}{\mdline{1383} Generated suffix (\mdline{1383}e.g.\mdline{1383} by the compiler)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1385} +\mdhr{}%mdk + +%mdk-data-line={1386} +\noindent\mdline{1386}\mdcaption{\textbf{Table~\mdcaptionlabel{2}.}~\mdcaptiontext{Format of P4Info object IDs}}%mdk%mdk +\end{mdblock}\label{tab-format-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1390} +\mdline{1390}It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with \mdline{1391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1391} (see Table +\mdline{1392}\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}}\mdline{1392}). The compiler must honor the \mdline{1392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1392} annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (\mdline{1394}i.e.\mdline{1394} if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same \mdline{1396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1396} value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct.%mdk + +%mdk-data-line={1405} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth-7cm)/1}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{\mdinline{width=7cm}{{\bfseries\mdline{1407} P4 declaration(s)}}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1407} Compiler-allocated ID(s)}}\\ + +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1409} \mdline{1409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1409}}}&\multicolumn{1}{|l|}{\mdline{1409} 0x0212ab34}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1411} \mdline{1411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1411}}}&\multicolumn{1}{|l|}{\mdline{1411} \mdline{1411}\textbf{Error}\mdline{1411}(same ID suffixes for 2 objects of the same type)}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1412} \mdline{1412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tB...}}}\mdline{1412}}}&\multicolumn{1}{|l|}{\mdline{1412}}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1414} \mdline{1414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1414}}}&\multicolumn{1}{|l|}{\mdline{1414} 0x0212ab34}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1415} \mdline{1415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~action~act1...}}}\mdline{1415}}}&\multicolumn{1}{|l|}{\mdline{1415} 0x0112ab34}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1417} +\mdhr{}%mdk + +%mdk-data-line={1418} +\noindent\mdline{1418}\mdcaption{\textbf{Table~\mdcaptionlabel{3}.}~\mdcaptiontext{Example of statically-assigned P4Info object IDs}}%mdk +%mdk +\end{mdcenter}\label{tab-exmpl-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1421} +\mdline{1421}The \mdline{1421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1421} annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively).%mdk + +%mdk-data-line={1427} +\subsection{\mdline{1427}6.4.\hspace*{0.5em}\mdline{1427}P4Info Objects}\label{sec-p4info-objects}%mdk%mdk + +%mdk-data-line={1429} +\subsubsection{\mdline{1429}6.4.1.\hspace*{0.5em}\mdline{1429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}\label{sec-table}%mdk%mdk + +%mdk-data-line={1431} +\noindent\mdline{1431}Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields:%mdk + +%mdk-data-line={1434} +\begin{itemize}%mdk + +%mdk-data-line={1434} +\item{} +%mdk-data-line={1434} +\mdline{1434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1434}, a \mdline{1434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1434} message with the ID, name, and alias of this table.%mdk%mdk + +%mdk-data-line={1436} +\item{} +%mdk-data-line={1436} +\mdline{1436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1436}, a repeated field of type \mdline{1436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1436} representing the data to +be used to construct the lookup key matched in this table. Each \mdline{1437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1437} +message is defined with the following fields:%mdk + +%mdk-data-line={1440} +\begin{itemize}%mdk + +%mdk-data-line={1440} +\item{} +%mdk-data-line={1440} +\mdline{1440}id, the \mdline{1440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1440} identifier of this \mdline{1440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1440}, unique in the scope of +this table. No rules are prescribed on the way \mdline{1441}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1441} IDs should be +allocated, as long as two \mdline{1442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1442} of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the \mdline{1446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1446} annotation, or let the compiler +choose them.%mdk%mdk + +%mdk-data-line={1449} +\item{} +%mdk-data-line={1449} +\mdline{1449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1449}, the string representing the name of this \mdline{1449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1449}.%mdk%mdk + +%mdk-data-line={1451} +\item{} +%mdk-data-line={1451} +\mdline{1451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1451}, a repeated field of strings, each one representing a P4 +annotation associated to this match field.%mdk%mdk + +%mdk-data-line={1454} +\item{} +%mdk-data-line={1454} +\mdline{1454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1454}, an \mdline{1454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1454} value set to the size in bits of this match field.%mdk%mdk + +%mdk-data-line={1456} +\item{} +%mdk-data-line={1456} +\mdline{1456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1456}, a \mdline{1456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{1456} describing the match behavior for this field; it can be +either:%mdk + +%mdk-data-line={1458} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1458} +\item\mdline{1458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1458}, an enum field of type \mdline{1458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchType}}}\mdline{1458}, which includes all +possible PSA match kinds.%mdk + +%mdk-data-line={1460} +\item\mdline{1460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_match\_type}}}\mdline{1460}, a string field which can be used to encode any +architecture-specific match type.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1463} +\item{} +%mdk-data-line={1463} +\mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1463}, a \mdline{1463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1463} message describing this match field.%mdk%mdk + +%mdk-data-line={1465} +\item{} +%mdk-data-line={1465} +\mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1465}, which indicates whether the match field has a\mdline{1465}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1466}; this is useful for +\mdline{1467}\mdref{sec-psa-metadata-translation}{translation}\mdline{1467}.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1469} +\item{} +%mdk-data-line={1469} +\mdline{1469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_refs}}}\mdline{1469}, a repeated \mdline{1469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1469} field representing the set of possible +actions for this table. The \mdline{1470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1470} message is used to reference an action +specified in the same P4Info message and it includes the following fields:%mdk + +%mdk-data-line={1472} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1472} +\item\mdline{1472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1472}, the \mdline{1472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1472} identifier of the action.%mdk + +%mdk-data-line={1473} +\item\mdline{1473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1473}, an enum value which can take one of three values: + \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1474}, \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1474} and \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1474}. The \mdline{1474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1474} of the + action is determined by the use of the P4 standard annotations + \mdline{1476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1476} and \mdline{1476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1476}~[\mdcite{p4actionannotations}{18}]\mdline{1476}. \mdline{1476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1476} + (\mdline{1477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1477} annotation) means that the action can only appear within + the table, and never as the default action. \mdline{1478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1478} + (\mdline{1479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1479} annotation) means that the action can only be used as the + default action. \mdline{1480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1480} is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action.%mdk + +%mdk-data-line={1483} +\item\mdline{1483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1483}, a repeated string field, each one representing a P4 +annotation associated to the action \mdline{1484}\emph{reference}\mdline{1484} in this table.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1486} +\item{} +%mdk-data-line={1486} +\mdline{1486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\_default\_action\_id}}}\mdline{1486}, if this table has a constant default action, this +field will carry the \mdline{1487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1487} identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action\mdline{1490}'\mdline{1490}s +arguments.%mdk%mdk + +%mdk-data-line={1493} +\item{} +%mdk-data-line={1493} +\mdline{1493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation\_id}}}\mdline{1493}, the \mdline{1493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1493} identifier of the \mdline{1493}\textquotedblleft{}implementation\textquotedblright{}\mdline{1493} of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (\mdline{1496}e.g.\mdline{1496} a PSA \mdline{1496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1496} or \mdline{1496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{1496} +instance). The table is then referred to as an indirect match table.%mdk%mdk + +%mdk-data-line={1499} +\item{} +%mdk-data-line={1499} +\mdline{1499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_resource\_ids}}}\mdline{1499}, repeated \mdline{1499}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1499} identifiers for all the direct +resources attached to this table, such as \mdline{1500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1500} and \mdline{1500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1500} +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2.%mdk%mdk + +%mdk-data-line={1506} +\item{} +%mdk-data-line={1506} +\mdline{1506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1506}, an \mdline{1506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1506} describing the desired number of table entries that the +target should support for the table. See the \mdline{1507}\textquotedblleft{}Size\textquotedblright{}\mdline{1507} subsection within the +\mdline{1508}\textquotedblleft{}Table Properties\textquotedblright{}\mdline{1508} section of the P4\mdline{1508}\mdsub{16}\mdline{1508} language specification for details +\mdline{1509}[\mdcite{p4tableproperties}{30}]\mdline{1509}.%mdk%mdk + +%mdk-data-line={1511} +\item{} +%mdk-data-line={1511} +\mdline{1511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_behavior}}}\mdline{1511}, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +\mdline{1513}\mdref{sec-idle-timeout}{Idle-Timeout}\mdline{1513} section). Value can be any of the +\mdline{1514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutBehavior}}}\mdline{1514} enum:%mdk + +%mdk-data-line={1515} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1515} +\item\mdline{1515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NO\_TIMEOUT}}}\mdline{1515} (default value), which means that idle timeout is not +supported for this table.%mdk + +%mdk-data-line={1517} +\item\mdline{1517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOTIFY\_CONTROL}}}\mdline{1517}, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +\mdline{1519}\mdref{sec-table-idle-timeout-notification}{Table Idle Timeout Notifications}\mdline{1519}).%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1521} +\item{} +%mdk-data-line={1521} +\mdline{1521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{1521}, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime.%mdk%mdk + +%mdk-data-line={1524} +\item{} +%mdk-data-line={1524} +\mdline{1524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{1524}, an \mdline{1524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1524} Protobuf message\mdline{1524}~[\mdcite{protoany}{31}]\mdline{1524} to embed +architecture-specific table properties\mdline{1525}~[\mdcite{p4tableproperties}{30}]\mdline{1525} which are not part +of the core P4 language or of the PSA architecture.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1528} +\subsubsection{\mdline{1528}6.4.2.\hspace*{0.5em}\mdline{1528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}\label{sec-action}%mdk%mdk + +%mdk-data-line={1530} +\noindent\mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1530} messages are used to specify all possible actions of all match-action +tables.%mdk + +%mdk-data-line={1533} +\mdline{1533}The \mdline{1533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1533} message defines the following fields:%mdk + +%mdk-data-line={1535} +\begin{itemize}%mdk + +%mdk-data-line={1535} +\item{} +%mdk-data-line={1535} +\mdline{1535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1535}, a \mdline{1535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1535} message with the ID, name, and alias of this action%mdk%mdk + +%mdk-data-line={1537} +\item{} +%mdk-data-line={1537} +\mdline{1537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{1537}, a repeated field of \mdline{1537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1537} messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each \mdline{1539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1539} message contains the +following fields:%mdk + +%mdk-data-line={1541} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1541} +\item\mdline{1541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1541}, the \mdline{1541}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1541} identifier of this parameter. No rules are prescribed +on the way \mdline{1542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1542} IDs should be allocated, as long as two \mdline{1542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1542} of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the \mdline{1546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1546} +annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1548} +\item\mdline{1548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1548}, the string representing the name of this parameter.%mdk + +%mdk-data-line={1549} +\item\mdline{1549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1549}, a repeated field of strings, each one representing a P4 +annotation associated to this parameter.%mdk + +%mdk-data-line={1551} +\item\mdline{1551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1551}, an \mdline{1551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1551} value set to the size in bits of this parameter.%mdk + +%mdk-data-line={1552} +\item\mdline{1552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1552}, which describes this parameter using a \mdline{1552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1552} message.%mdk + +%mdk-data-line={1553} +\item\mdline{1553}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1553}, which indicates whether the action parameter has a +\mdline{1554}\mdref{sec-user-defined-types}{user-defined type}\mdline{1554}; this is useful for +\mdline{1555}\mdref{sec-psa-metadata-translation}{translation}\mdline{1555}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1557} +\subsubsection{\mdline{1557}6.4.3.\hspace*{0.5em}\mdline{1557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}\label{sec-p4info-action-profile}%mdk%mdk + +%mdk-data-line={1559} +\noindent\mdline{1559}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1559} messages are used to specify all available instances of Action +Profile and Action Selector PSA externs.%mdk + +%mdk-data-line={1562} +\mdline{1562}PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile \mdline{1566}\emph{member}\mdline{1566}, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime.%mdk + +%mdk-data-line={1570} +\mdline{1570}PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into \mdline{1571}\emph{groups}\mdline{1571}. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime.%mdk + +%mdk-data-line={1580} +\mdline{1580}While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same \mdline{1581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1581} message to describe both.%mdk + +%mdk-data-line={1583} +\mdline{1583}The \mdline{1583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1583} message includes the following fields:%mdk + +%mdk-data-line={1585} +\begin{itemize}%mdk + +%mdk-data-line={1585} +\item{} +%mdk-data-line={1585} +\mdline{1585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1585}, a \mdline{1585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1585} message with the ID, name, and alias of this Action +Profile or Selector.%mdk%mdk + +%mdk-data-line={1588} +\item{} +%mdk-data-line={1588} +\mdline{1588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_ids}}}\mdline{1588}, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector.%mdk%mdk + +%mdk-data-line={1591} +\item{} +%mdk-data-line={1591} +\mdline{1591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}with\_selector}}}\mdline{1591}, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern.%mdk%mdk + +%mdk-data-line={1594} +\item{} +%mdk-data-line={1594} +\mdline{1594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1594}, an \mdline{1594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1594} representing the maximum number of member entries that the +Action Profile can hold, or, in the case of an Action Selector, the maximum +sum of all member weights across all selector groups.%mdk%mdk + +%mdk-data-line={1598} +\item{} +%mdk-data-line={1598} +\mdline{1598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1598}, an \mdline{1598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1598} which is 0 for an Action Profile, or, for an +Action Selector, represents the maximum sum of all member weights within any +given selector group. The \mdline{1600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1600} must be no larger than \mdline{1600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1600}. PSA +programs can use the \mdline{1601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{1601} annotation to provide this value for +Action Selectors. If the annotation is omitted, the P4Info field will default +to 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1605} +\subsubsection{\mdline{1605}6.4.4.\hspace*{0.5em}\mdline{1605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1605} \mdline{1605}\&\mdline{1605} \mdline{1605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}\label{sec-counter-directcounter}%mdk%mdk + +%mdk-data-line={1607} +\noindent\mdline{1607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1607} and \mdline{1607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1607} messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is:%mdk + +%mdk-data-line={1613} +\begin{itemize}%mdk + +%mdk-data-line={1613} +\item{} +%mdk-data-line={1613} +\mdline{1613}Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index.%mdk%mdk + +%mdk-data-line={1617} +\item{} +%mdk-data-line={1617} +\mdline{1617}Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1620} +\noindent\mdline{1620}Both \mdline{1620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1620} and \mdline{1620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1620} messages share the following fields:%mdk + +%mdk-data-line={1622} +\begin{itemize}%mdk + +%mdk-data-line={1622} +\item{} +%mdk-data-line={1622} +\mdline{1622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1622}, a \mdline{1622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1622} message with the ID, name, and alias of this counter +extern instance.%mdk%mdk + +%mdk-data-line={1625} +\item{} +%mdk-data-line={1625} +\mdline{1625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1625}, a message of of type \mdline{1625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1625} used to describe the compile-time +configuration of this counter. Currently, the \mdline{1626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1626} message is used to +carry only the counter unit, which can be any of the \mdline{1627}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec.Unit}}}\mdline{1627} enum +values:%mdk + +%mdk-data-line={1629} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1629} +\item\mdline{1629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1629}: reserved value.%mdk + +%mdk-data-line={1630} +\item\mdline{1630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1630}: byte counter.%mdk + +%mdk-data-line={1631} +\item\mdline{1631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1631}: packet counter.%mdk + +%mdk-data-line={1632} +\item\mdline{1632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BOTH}}}\mdline{1632}: combination of both byte and packet counter.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1634} +\noindent\mdline{1634}For indexed counters, the \mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1634} message contains also a \mdline{1634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1634} field, an +\mdline{1635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1635} representing the maximum number of independent values that can be held +by this counter array. Conversely, the \mdline{1636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1636} message contains a +\mdline{1637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1637} field that carries the \mdline{1637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}unit32}}}\mdline{1637} identifier of the table to +which this direct counter is attached.%mdk + +%mdk-data-line={1640} +\mdline{1640}For indexed counters, the \mdline{1640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1640} message contains also an \mdline{1640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1640} +field, which indicates whether the index has a\mdline{1641}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1642}. This is useful for +\mdline{1643}\mdref{sec-psa-metadata-translation}{translation}\mdline{1643}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1644}).%mdk + +%mdk-data-line={1646} +\subsubsection{\mdline{1646}6.4.5.\hspace*{0.5em}\mdline{1646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1646} \mdline{1646}\&\mdline{1646} \mdline{1646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}\label{sec-meter-directmeter}%mdk%mdk + +%mdk-data-line={1648} +\noindent\mdline{1648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1648} and \mdline{1648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1648} messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is:%mdk + +%mdk-data-line={1654} +\begin{itemize}%mdk + +%mdk-data-line={1654} +\item{} +%mdk-data-line={1654} +\mdline{1654}Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +\mdline{1656}e.g.\mdline{1656} to set the rate threshold.%mdk%mdk + +%mdk-data-line={1658} +\item{} +%mdk-data-line={1658} +\mdline{1658}Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1661} +\noindent\mdline{1661}Both \mdline{1661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1661} and \mdline{1661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1661} messages share the following fields:%mdk + +%mdk-data-line={1663} +\begin{itemize}%mdk + +%mdk-data-line={1663} +\item{} +%mdk-data-line={1663} +\mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1663}, a \mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1663} message with the ID, name, and alias of this meter +extern instance.%mdk%mdk + +%mdk-data-line={1666} +\item{} +%mdk-data-line={1666} +\mdline{1666}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1666}, a message of type \mdline{1666}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1666} used to describe the capabilities of +this meter extern instance. Currently, the \mdline{1667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1667} message is used to +carry only the meter unit, which can be any of the \mdline{1668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Unit}}}\mdline{1668} enum +values:%mdk + +%mdk-data-line={1670} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1670} +\item\mdline{1670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1670}: reserved value.%mdk + +%mdk-data-line={1671} +\item\mdline{1671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1671}, which signifies that this meter can be configured with rates +expressed in bytes/second.%mdk + +%mdk-data-line={1673} +\item\mdline{1673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1673}, for rates expressed in packets/second.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1675} +\noindent\mdline{1675}For indexed meters, the \mdline{1675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1675} message contains also a \mdline{1675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1675} field, an \mdline{1675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1675} +representing the maximum number of independent cells that can be held by this +meter. Conversely, the \mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1677} message contains a \mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1677} field +that carries the \mdline{1678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1678} identifier of the table to which this direct meter is +attached.%mdk + +%mdk-data-line={1681} +\mdline{1681}For indexed meters, the \mdline{1681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1681} message contains also an \mdline{1681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1681} +field, which indicates whether the index has a\mdline{1682}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1683}. This is useful for +\mdline{1684}\mdref{sec-psa-metadata-translation}{translation}\mdline{1684}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1685}).%mdk + +%mdk-data-line={1687} +\subsubsection{\mdline{1687}6.4.6.\hspace*{0.5em}\mdline{1687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\label{sec-controller-packet-meta}%mdk%mdk + +%mdk-data-line={1689} +\noindent\mdline{1689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1689} messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server.%mdk + +%mdk-data-line={1695} +\mdline{1695}When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet.%mdk + +%mdk-data-line={1701} +\mdline{1701}Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +\mdline{1703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_in")}}}\mdline{1703} and \mdline{1703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_out")}}}\mdline{1703}, +respectively. \mdline{1704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1704} messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages).%mdk + +%mdk-data-line={1709} +\mdline{1709}A P4Info message can contain at most two \mdline{1709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata~messages}}}\mdline{1709}, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields:%mdk + +%mdk-data-line={1713} +\begin{itemize}%mdk + +%mdk-data-line={1713} +\item{} +%mdk-data-line={1713} +\mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1713}, a \mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1713} message where \mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble.name}}}\mdline{1713} is set to \mdline{1713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_in"}}}\mdline{1713} +and \mdline{1714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_out"}}}\mdline{1714} for packet-in and packet-out metadata, respectively.%mdk%mdk + +%mdk-data-line={1716} +\item{} +%mdk-data-line={1716} +\mdline{1716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{1716}, a repeated field of type \mdline{1716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1716}, where each \mdline{1716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1716} message +includes the following fields:%mdk + +%mdk-data-line={1718} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1718} +\item\mdline{1718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1718}, a \mdline{1718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1718} identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two \mdline{1719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1719} of the +same \mdline{1720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1720} message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the \mdline{1724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1724} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1725} +\item\mdline{1725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1725}, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below).%mdk + +%mdk-data-line={1729} +\item\mdline{1729}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1729}, a repeated field of strings, each one representing a P4 +annotation associated to this metadata.%mdk + +%mdk-data-line={1731} +\item\mdline{1731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1731}, an \mdline{1731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1731} representing the size in bits of this metadata.%mdk + +%mdk-data-line={1732} +\item\mdline{1732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1732}, which indicates whether the metadata field has a +\mdline{1733}\mdref{sec-user-defined-types}{user-defined type}\mdline{1733}; this is useful for +\mdline{1734}\mdref{sec-psa-metadata-translation}{translation}\mdline{1734}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1736} +\noindent\mdline{1736}As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding \mdline{1737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1737} +messages.%mdk + +%mdk-data-line={1740} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1741} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~egress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~port~where~the~packet}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~should~be~sent~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~queue\_id;~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~queue~ID~}{\mdcolor{darkgreen}*/}\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~ingress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~data~plane~port~ID~where}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~the~original~packet~was~received~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}1}\textgreater{}~is\_clone;~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~1~if~this~is~a~clone~of~the}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~original~packet~}{\mdcolor{darkgreen}*/}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1756} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1757} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868916615}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_out}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_out}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}egress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}queue\_id}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~\}\\ +\}\\ +\\ +controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868941301}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_in}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_in}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ingress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}is\_clone}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}1}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1794} +\noindent\mdline{1794}Note that the use of \mdline{1794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1794} is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages.%mdk + +%mdk-data-line={1800} +\subsubsection{\mdline{1800}6.4.7.\hspace*{0.5em}\mdline{1800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}\label{sec-valueset}%mdk%mdk + +%mdk-data-line={1802} +\noindent\mdline{1802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1802} messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P4\mdline{1805}\mdsub{16}\mdline{1805} +specification\mdline{1806}~[\mdcite{p4valuesets}{39}]\mdline{1806}.%mdk + +%mdk-data-line={1808} +\mdline{1808}The \mdline{1808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1808} message defines the following fields:%mdk + +%mdk-data-line={1810} +\begin{itemize}%mdk + +%mdk-data-line={1810} +\item{} +%mdk-data-line={1810} +\mdline{1810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1810}, a \mdline{1810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1810} message with the ID, name, and alias of this Value +Set.%mdk%mdk + +%mdk-data-line={1813} +\item{} +%mdk-data-line={1813} +\mdline{1813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1813}, a repeated field of \mdline{1813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1813} messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the \mdline{1816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1816} repeated field in the +\mdline{1817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{1817} message.%mdk%mdk + +%mdk-data-line={1819} +\item{} +%mdk-data-line={1819} +\mdline{1819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1819}, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +\mdline{1821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set}}}\mdline{1821} constructor call.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1823} +\noindent\mdline{1823}According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of \mdline{1826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1826}, +\mdline{1827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1827}, or \mdline{1827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1827}~[\mdcite{p4selectexpr}{26}]\mdline{1827}. The rest of this section looks at all 3 of +these cases and gives an example \mdline{1828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1828} message when appropriate.%mdk + +%mdk-data-line={1830} +\begin{enumerate}%mdk + +%mdk-data-line={1830} +\item{} +%mdk-data-line={1830} +\mdline{1830}If the type parameter is \mdline{1830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1830}, \mdline{1830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1830} will include exactly one +\mdline{1831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1831} message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used):%mdk + +%mdk-data-line={1834} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1834} +\item\mdline{1834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1834}: set to 1%mdk + +%mdk-data-line={1835} +\item\mdline{1835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1835}: set to the value of \mdline{1835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1835}%mdk + +%mdk-data-line={1836} +\item\mdline{1836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1836}: set to \mdline{1836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1836}%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1838} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1839} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}bit\textless{}8\textgreater{}~\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(hdr.f8)~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1842} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1843} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1857} +\begin{enumerate}[,start=2]%mdk + +%mdk-data-line={1857} +\item{} +%mdk-data-line={1857} +\mdline{1857}If the type parameter is a \mdline{1857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1857}, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program.%mdk%mdk + +%mdk-data-line={1862} +\item{} +%mdk-data-line={1862} +\mdline{1862}If the type parameter is a \mdline{1862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1862}, this version of P4Runtime requires that +all the fields of the struct be of type \mdline{1863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1863} (where \mdline{1863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1863} can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +\mdline{1866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1866} field will include one \mdline{1866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1866} message for each field in the +struct, with the following fields:%mdk + +%mdk-data-line={1869} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1869} +\item\mdline{1869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1869}: must be unique with respect to the other \mdline{1869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1869} entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +\mdline{1873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1873} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1874} +\item\mdline{1874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1874}: set to the name of the corresponding struct field.%mdk + +%mdk-data-line={1875} +\item\mdline{1875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1875}: set to the list of P4 annotations associated with the struct +field, except for the \mdline{1876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1876} annotation, if present (see the \mdline{1876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1876} field +below).%mdk + +%mdk-data-line={1878} +\item\mdline{1878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1878}: set to the value of \mdline{1878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1878} for the corresponding struct field.%mdk + +%mdk-data-line={1879} +\item\mdline{1879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1879}, which indicates whether the struct field has a\mdline{1879}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1880}; this is useful for +\mdline{1881}\mdref{sec-psa-metadata-translation}{translation}\mdline{1881}.%mdk + +%mdk-data-line={1882} +\item\mdline{1882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1882}: by default \mdline{1882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1882} is set to \mdline{1882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1882}; the P4 programmer can +specify a different match type by using the \mdline{1883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1883} annotation +\mdline{1884}[\mdcite{p4selectexpr}{26}]\mdline{1884}.%mdk + +%mdk-data-line={1885} +\item\mdline{1885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1885}: documentation associated with the struct field.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1887} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1888} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~bit\textless{}8\textgreater{}~f8;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(2)~@match(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(3)~@match(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1896} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1897} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1924} +\noindent\mdline{1924}In the above example, the \mdline{1924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1924} annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs.%mdk + +%mdk-data-line={1927} +\mdline{1927}Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a\mdline{1928}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1929} that resolves to a \mdline{1929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1929}, or a \mdline{1929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1929} where +one or more fields is a\mdline{1930}~\mdref{sec-user-defined-types}{user-defined type}\mdline{1930} that +resolves to a \mdline{1931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1931}. For each \mdline{1931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1931} that corresponds to a user-defined +type, the \mdline{1932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1932} field must be set to the appropriate value (\mdline{1932}i.e.\mdline{1932} the name +of the type).%mdk + +%mdk-data-line={1935} +\subsubsection{\mdline{1935}6.4.8.\hspace*{0.5em}\mdline{1935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}\label{sec-register}%mdk%mdk + +%mdk-data-line={1937} +\noindent\mdline{1937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1937} messages are used to specify all possible instances of Register PSA +externs.%mdk + +%mdk-data-line={1940} +\mdline{1940}Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime.%mdk + +%mdk-data-line={1944} +\mdline{1944}The \mdline{1944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{1944} message defines the following fields:%mdk + +%mdk-data-line={1946} +\begin{itemize}%mdk + +%mdk-data-line={1946} +\item{} +%mdk-data-line={1946} +\mdline{1946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1946}, a \mdline{1946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1946} message with the ID, name, and alias of this register +instance.%mdk%mdk + +%mdk-data-line={1949} +\item{} +%mdk-data-line={1949} +\mdline{1949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1949}, which specifies the data type stored by this register, expressed +using a \mdline{1950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1950} message (see section on\mdline{1950}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary +P4 Types}\mdline{1951}).%mdk%mdk + +%mdk-data-line={1953} +\item{} +%mdk-data-line={1953} +\mdline{1953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1953}, an \mdline{1953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1953} value representing the total number of independent register +cells available.%mdk%mdk + +%mdk-data-line={1956} +\item{} +%mdk-data-line={1956} +\mdline{1956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1956}, which indicates whether the register index has a +\mdline{1957}\mdref{sec-user-defined-types}{user-defined type}\mdline{1957}. This is useful for +\mdline{1958}\mdref{sec-psa-metadata-translation}{translation}\mdline{1958}. The underlying built-in type +must be a fixed-width unsigned bitstring (\mdline{1959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1959}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1961} +\subsubsection{\mdline{1961}6.4.9.\hspace*{0.5em}\mdline{1961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}\label{sec-digest}%mdk%mdk + +%mdk-data-line={1963} +\noindent\mdline{1963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1963} messages are used to specify all possible instances of Packet Digest +PSA externs.%mdk + +%mdk-data-line={1966} +\mdline{1966}A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages.%mdk + +%mdk-data-line={1975} +\mdline{1975}The \mdline{1975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{1975} message defines the following fields:%mdk + +%mdk-data-line={1977} +\begin{itemize}%mdk + +%mdk-data-line={1977} +\item{} +%mdk-data-line={1977} +\mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1977}, a \mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1977} message with the ID, name, and alias of this digest +instance.%mdk%mdk + +%mdk-data-line={1980} +\item{} +%mdk-data-line={1980} +\mdline{1980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{1980}, which specifies the data type of an individual digest +notification using a \mdline{1981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{1981} message (see section on\mdline{1981}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation +of Arbitrary P4 Types}\mdline{1982}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1984} +\subsubsection{\mdline{1984}6.4.10.\hspace*{0.5em}\mdline{1984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}\label{sec-p4info-extern}%mdk%mdk + +%mdk-data-line={1986} +\noindent\mdline{1986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1986} messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one \mdline{1989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1989} message instance in P4Info. The \mdline{1989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{1989} message defines +the following fields:%mdk + +%mdk-data-line={1992} +\begin{itemize}%mdk + +%mdk-data-line={1992} +\item{} +%mdk-data-line={1992} +\mdline{1992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{1992}, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the\mdline{1993}~\mdref{sec-id-allocation}{reserved +range}\mdline{1994} \mdline{1994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{}[0x81,~0xfe]}}}\mdline{1994}. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture.%mdk%mdk + +%mdk-data-line={1999} +\item{} +%mdk-data-line={1999} +\mdline{1999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_name}}}\mdline{1999}, which specifies the fully-qualified P4 name of the extern +type.%mdk%mdk + +%mdk-data-line={2002} +\item{} +%mdk-data-line={2002} +\mdline{2002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instances}}}\mdline{2002}, a repeated field of \mdline{2002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{2002} Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +\mdline{2004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{2004} in turn defines the following fields:%mdk + +%mdk-data-line={2006} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2006} +\item\mdline{2006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{2006}, a \mdline{2006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{2006} message with the ID, name, and alias of this digest +instance.%mdk + +%mdk-data-line={2008} +\item\mdline{2008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{2008}, an \mdline{2008}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{2008} Protobuf message\mdline{2008}~[\mdcite{protoany}{31}]\mdline{2008} which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for \mdline{2010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{2010} should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on\mdline{2012}~\mdref{sec-extending-p4runtime}{Extending +P4Runtime for non-PSA Architectures}\mdline{2013} for more +information.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2016} +\noindent\mdline{2016}If the P4 program does not include any instance of a given extern type, the +\mdline{2017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2017} message instance for that type should be omitted from the P4Info.%mdk + +%mdk-data-line={2019} +\subsection{\mdline{2019}6.5.\hspace*{0.5em}\mdline{2019}Support for Arbitrary P4 Types with P4TypeInfo}\label{sec-support-for-arbitrary-p4-types-with-p4typeinfo}%mdk%mdk + +%mdk-data-line={2021} +\noindent\mdline{2021}See section on\mdline{2021}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary P4 +Types}\mdline{2022}.%mdk + +%mdk-data-line={2024} +\section{\mdline{2024}7.\hspace*{0.5em}\mdline{2024}P4 Forwarding-Pipeline Configuration}\label{sec-p4-fwd-pipe-config}%mdk%mdk + +%mdk-data-line={2026} +\noindent\mdline{2026}The \mdline{2026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2026} captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the \mdline{2028}\textquotedblleft{}Device Configuration\textquotedblright{}\mdline{2028} and sometimes also referred to as +the \mdline{2029}\textquotedblleft{}P4 Blob\textquotedblright{}\mdline{2029}. It is defined as:%mdk + +%mdk-data-line={2031} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2032} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ForwardingPipelineConfig~\{\\ +~~config.P{\mdcolor{purple}4}Info~p4info~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~p4\_device\_config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}message}}~Cookie~\{\\ +~~~~{\bfseries{\mdcolor{navy}uint64}}~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~\}\\ +~~Cookie~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2042} +\noindent\mdline{2042}The \mdline{2042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{2042} field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic.%mdk + +%mdk-data-line={2045} +\mdline{2045}The \mdline{2045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{2045} is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new \mdline{2047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2047} on that target.%mdk + +%mdk-data-line={2049} +\mdline{2049}The \mdline{2049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{2049} field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a \mdline{2054}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{2054} RPC. +When writing the config via a \mdline{2055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{2055} RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present.%mdk + +%mdk-data-line={2059} +\section{\mdline{2059}8.\hspace*{0.5em}\mdline{2059}General Principles for Message Formatting}\label{sec-general-principles-for-message-formatting}%mdk%mdk + +%mdk-data-line={2061} +\subsection{\mdline{2061}8.1.\hspace*{0.5em}\mdline{2061}Set / Unset Protobuf Field}\label{sec-set-unset-protobuf-field}%mdk%mdk + +%mdk-data-line={2063} +\noindent\mdline{2063}In Protobuf version 3 (\mdline{2063}\emph{proto3}\mdline{2063}), the default value for a message field is +\mdline{2064}\textquotedblleft{}unset\textquotedblright{}\mdline{2064}~[\mdcite{protodefaults}{4}]\mdline{2064}. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +\mdline{2069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2069} message, an \mdline{2069}\textquotedblleft{}unset\textquotedblright{}\mdline{2069} \mdline{2069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2069} field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the \mdline{2071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2071} message field is +set, a single entry will be read.%mdk + +%mdk-data-line={2074} +\mdline{2074}Let\mdline{2074}'\mdline{2074}s look at the counter example in more details. Based on this specification +document, the C++ server code which processes \mdline{2075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2075} messages may look +like this:%mdk + +%mdk-data-line={2077} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2078} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}auto}}~*counter\_entry~=~...\\ +{\bfseries{\mdcolor{navy}if}}~(counter\_entry-\textgreater{}has\_index())~\{\\ +~~{\bfseries{\mdcolor{navy}auto}}~index~=~counter\_entry-\textgreater{}index().index();\\ +~~read\_one\_entry(counter\_entry-\textgreater{}id(),~index);\\ +\}~{\bfseries{\mdcolor{navy}else}}~\{\\ +~~read\_all\_entries(counter\_entry-\textgreater{}id());\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2087} +\begin{enumerate}%mdk + +%mdk-data-line={2087} +\item{} +%mdk-data-line={2087} +\mdline{2087}Reading a single counter entry at index 0 in the counter array with id +\mdline{2088}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textless{}id\textgreater{}}}}\mdline{2088}:%mdk + +%mdk-data-line={2089} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2089} +\item\mdline{2089}Here is the C++ client code: + +%mdk-data-line={2090} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2091} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});\\ +entry.mutable\_index();\\ +{\mdcolor{darkgreen}//~The~above~line~sets~the~index~field;~it~is~equivalent~to:}\\ +{\mdcolor{darkgreen}//~auto~*index~=~entry.mutable\_index();}\\ +{\mdcolor{darkgreen}//~index-\textgreater{}set\_index(0);}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2098} +\item\mdline{2098}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2099} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2100} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}\\ +index~\{\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2103} +\item\mdline{2103}\textbf{Expected behavior}\mdline{2103}: Counter entry at index 0 is read. Notice that the +\mdline{2104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2104} subfield is missing under the \mdline{2104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2104} field message of +\mdline{2105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2105} in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2110} +\item{} +%mdk-data-line={2110} +\mdline{2110}Reading all counter entries by leaving the \mdline{2110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2110} field unset%mdk + +%mdk-data-line={2111} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2111} +\item\mdline{2111}Here is the C++ client code: + +%mdk-data-line={2112} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2113} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2116} +\item\mdline{2116}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2117} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2118} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2120} +\item\mdline{2120}\textbf{Expected behavior}\mdline{2120}: All counter entries for the provided counter +instance are read. Notice that the \mdline{2121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2121} message field is unset (default +value) and is therefore omitted from the textual representation of the +message.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={2125} +\subsection{\mdline{2125}8.2.\hspace*{0.5em}\mdline{2125}Read-Write Symmetry}\label{sec-read-write-symmetry}%mdk%mdk + +%mdk-data-line={2127} +\noindent\mdline{2127}The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully. Consider the following +pseudocode as an example:%mdk + +%mdk-data-line={2133} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2134} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}intended\_value~=~value\\ +\\ +status~=~server.write(intended\_value,~p4\_entity)\\ +observed\_value~=~server.read(p4\_entity)\\ +\\ +assert(intended\_value~==~observed\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2142} +\noindent\mdline{2142}To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If \mdline{2146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{2146} RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol\mdline{2149}'\mdline{2149}s complexities to the client implementations.%mdk + +%mdk-data-line={2151} +\mdline{2151}In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the \mdline{2154}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2154} fields in a \mdline{2154}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2154} message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +\mdline{2157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MessageDifferencer}}}\mdline{2157} class\mdline{2157}~[\mdcite{protomessagedifferencer}{36}]\mdline{2157} included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance.%mdk + +%mdk-data-line={2162} +\subsection{\mdline{2162}8.3.\hspace*{0.5em}\mdline{2162}Zero as Reserved Value}\label{sec-zero-as-reserved-value}%mdk%mdk + +%mdk-data-line={2164} +\noindent\mdline{2164}p4runtime.proto uses proto3 syntax, and so it does not allow not specifying a +scalar data type, such as a \mdline{2165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{2165}. Therefore, we usually reserve value 0 for +those fields to mean unset. In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +switch, such as in a \mdline{2168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{2168} or a \mdline{2168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfigRequest}}}\mdline{2168}.%mdk + +%mdk-data-line={2170} +\subsection{\mdline{2170}8.4.\hspace*{0.5em}\mdline{2170}Bytestrings}\label{sec-bytestrings}%mdk%mdk + +%mdk-data-line={2172} +\noindent\mdline{2172}P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (\mdline{2174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2174}) or signed (\mdline{2174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2174}), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +\mdline{2177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2177} Protobuf type. The correct bitwidth\mdline{2177} \mdline{2177}\textemdash{}\mdline{2177} as per the P4 program\mdline{2177} \mdline{2177}\textemdash{}\mdline{2177} of +each integer variable exposed through P4Runtime is specified in the P4Info +message.%mdk + +%mdk-data-line={2181} +\mdline{2181}The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals:%mdk + +%mdk-data-line={2184} +\begin{itemize}%mdk + +%mdk-data-line={2184} +\item{} +%mdk-data-line={2184} +\mdline{2184}It ensures that a properly encoded binary string\mdline{2184}'\mdline{2184}s integer value conforms +to the P4Info-specified bitwidth.%mdk%mdk + +%mdk-data-line={2187} +\item{} +%mdk-data-line={2187} +\mdline{2187}It supports\mdline{2187}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2187}.%mdk%mdk + +%mdk-data-line={2189} +\item{} +%mdk-data-line={2189} +\mdline{2189}It helps facilitate non-disruptive P4 program updates.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2191} +\noindent\mdline{2191}In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type \mdline{2196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2196} and/or \mdline{2196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2196}.%mdk + +%mdk-data-line={2198} +\mdline{2198}Note that this representation does \mdline{2198}\emph{not}\mdline{2198} make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range.%mdk + +%mdk-data-line={2207} +\mdline{2207}In the P4Runtime API version 1.0 (including minor version revisions), values +of table key fields, action parameters, and fields in packet-in and packet-out +headers between a device and the controller (see\mdline{2209}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{2209}), +may not be of type \mdline{2210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2210}. The rules for encoding signed values thus only +apply to messages of type \mdline{2211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2211} (see\mdline{2211}~\mdref{sec-p4data-in-p4runtime-proto}{8.5.3}\mdline{2211}).%mdk + +%mdk-data-line={2213} +\mdline{2213}For a value of type \mdline{2213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2213}, the fewest number of bits required to represent +the integer value \mdline{2214}$V > 0$\mdline{2214} is the smallest integer \mdline{2214}$A$\mdline{2214} such that \mdline{2214}$V \leq 2^A -1$\mdline{2215}.%mdk + +%mdk-data-line={2217} +\mdline{2217}For a value of type \mdline{2217}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2217}, the fewest number of bits required to represent +the integer value \mdline{2218}$V \neq 0$\mdline{2218} in 2\mdline{2218}'\mdline{2218}s complement form is the smallest integer \mdline{2218}$A$\mdline{2218} +such that \mdline{2219}$-2^{A-1} \leq V \leq 2^{A-1} - 1$\mdline{2219}.%mdk + +%mdk-data-line={2221} +\mdline{2221}As a special case, define that the value \mdline{2221}$V=0$\mdline{2221} requires at least \mdline{2221}$A=1$\mdline{2221} bit to +represent, regardless of whether it is signed or unsigned.%mdk + +%mdk-data-line={2224} +\mdline{2224}The shortest possible binary string for an integer \mdline{2224}$V$\mdline{2224} that needs \mdline{2224}$A$\mdline{2224} bits to +represent it is computed as:%mdk + +%mdk-data-line={2226} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2227} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size~=~floor(({\mdcolor{teal}A}~+~{\mdcolor{purple}7})~/~{\mdcolor{purple}8})}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2230} +\noindent\mdline{2230}Binary strings with the byte length computed as \mdline{2230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2230} promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies.%mdk + +%mdk-data-line={2234} +\mdline{2234}Any additional bits in the bytes sent for an unsigned integer value (type +\mdline{2235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2235}) must be 0. If additional bytes are transmitted above the +\mdline{2236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2236} minimum required, they must be filled with 0.%mdk + +%mdk-data-line={2238} +\mdline{2238}Any additional bits in the bytes sent for a signed integer value (type \mdline{2238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2238}) +must be copies of the sign bit, \mdline{2239}i.e.\mdline{2239} 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +\mdline{2241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2241} minimum required, they must be filled with copies of the +sign bit, \mdline{2242}i.e.\mdline{2242} 0 for non-negative values, or 0xff for negative values. In 2\mdline{2242}'\mdline{2242}s +complement representation, this is called \mdline{2243}\textquotedblleft{}sign extension\textquotedblright{}\mdline{2243}, and leaves the +numeric value represented unchanged.%mdk + +%mdk-data-line={2246} +\mdline{2246}Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value.%mdk + +%mdk-data-line={2252} +\mdline{2252}For a received bitstring expected to fit within a \mdline{2252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2252} type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring\mdline{2254}'\mdline{2254}s width is \mdline{2254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2254} bits or less.%mdk + +%mdk-data-line={2256} +\mdline{2256}For a received bitstring expected to fit within an \mdline{2256}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2256} type, the value it +represents is in range if, after \mdline{2257}\textquotedblleft{}undoing sign extension\textquotedblright{}\mdline{2257}, the remaining bit +string\mdline{2258}'\mdline{2258}s width is \mdline{2258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2258} bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other.%mdk + +%mdk-data-line={2264} +\mdline{2264}If the string\mdline{2264}'\mdline{2264}s byte length is zero, the server always rejects the string.%mdk + +%mdk-data-line={2266} +\mdline{2266}When the server rejects a binary string due to any of the previous criteria, +it returns an \mdline{2267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2267} error.%mdk + +%mdk-data-line={2269} +\mdline{2269}For all binary strings, P4Runtime uses big-endian (\mdline{2269}i.e.\mdline{2269} network) byte-order. +For signed integer values (\mdline{2270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2270} P4 type), P4Runtime uses the same two\mdline{2270}'\mdline{2270}s +complement bitwise representation as P4. Table\mdline{2271}~\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}}\mdline{2271} +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above.%mdk + +%mdk-data-line={2275} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2277} P4 type}}&\multicolumn{1}{|c}{{\bfseries\mdline{2277} Integer value}}&\multicolumn{1}{|c}{{\bfseries\mdline{2277} P4Runtime binary string}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2277} Read-write symmetry}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2279} \mdline{2279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2279}}&\multicolumn{1}{|l}{\mdline{2279} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2279} \mdline{2279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2279}}&\multicolumn{1}{|l|}{\mdline{2279} yes}\\ +\multicolumn{1}{|l}{\mdline{2280} \mdline{2280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2280}}&\multicolumn{1}{|l}{\mdline{2280} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2280} \mdline{2280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2280}}&\multicolumn{1}{|l|}{\mdline{2280} no}\\ +\multicolumn{1}{|l}{\mdline{2281} \mdline{2281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2281}}&\multicolumn{1}{|l}{\mdline{2281} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2281} \mdline{2281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2281}}&\multicolumn{1}{|l|}{\mdline{2281} yes}\\ +\multicolumn{1}{|l}{\mdline{2282} \mdline{2282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2282}}&\multicolumn{1}{|l}{\mdline{2282} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2282} \mdline{2282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x30\textbackslash{}x64}}}\mdline{2282}}&\multicolumn{1}{|l|}{\mdline{2282} yes}\\ +\multicolumn{1}{|l}{\mdline{2283} \mdline{2283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2283}}&\multicolumn{1}{|l}{\mdline{2283} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2283} \mdline{2283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x30\textbackslash{}x64}}}\mdline{2283}}&\multicolumn{1}{|l|}{\mdline{2283} no}\\ +\multicolumn{1}{|l}{\mdline{2284} \mdline{2284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2284}}&\multicolumn{1}{|l}{\mdline{2284} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2284} \mdline{2284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2284}}&\multicolumn{1}{|l|}{\mdline{2284} no}\\ +\multicolumn{1}{|l}{\mdline{2285} \mdline{2285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2285}}&\multicolumn{1}{|l}{\mdline{2285} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2285} \mdline{2285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2285}}&\multicolumn{1}{|l|}{\mdline{2285} yes}\\ +\multicolumn{1}{|l}{\mdline{2286} \mdline{2286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2286}}&\multicolumn{1}{|l}{\mdline{2286} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2286} \mdline{2286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00\textbackslash{}x63}}}\mdline{2286}}&\multicolumn{1}{|l|}{\mdline{2286} no}\\ +\multicolumn{1}{|l}{\mdline{2287} \mdline{2287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2287}}&\multicolumn{1}{|l}{\mdline{2287} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2287} \mdline{2287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2287}}&\multicolumn{1}{|l|}{\mdline{2287} yes}\\ +\multicolumn{1}{|l}{\mdline{2288} \mdline{2288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2288}}&\multicolumn{1}{|l}{\mdline{2288} \mdline{2288}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2288} \mdline{2288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x9d}}}\mdline{2288}}&\multicolumn{1}{|l|}{\mdline{2288} yes}\\ +\multicolumn{1}{|l}{\mdline{2289} \mdline{2289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2289}}&\multicolumn{1}{|l}{\mdline{2289} \mdline{2289}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2289} \mdline{2289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xff\textbackslash{}x9d}}}\mdline{2289}}&\multicolumn{1}{|l|}{\mdline{2289} no}\\ +\multicolumn{1}{|l}{\mdline{2290} \mdline{2290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2290}}&\multicolumn{1}{|l}{\mdline{2290} \mdline{2290}-739 (-0x2e3)}&\multicolumn{1}{|l}{\mdline{2290} \mdline{2290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xfd\textbackslash{}x1d}}}\mdline{2290}}&\multicolumn{1}{|l|}{\mdline{2290} yes}\\ +\multicolumn{1}{|l}{\mdline{2291} \mdline{2291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2291}}&\multicolumn{1}{|l}{\mdline{2291} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2291} \mdline{2291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00}}}\mdline{2291}}&\multicolumn{1}{|l|}{\mdline{2291} no}\\ +\multicolumn{1}{|l}{\mdline{2292} \mdline{2292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2292}}&\multicolumn{1}{|l}{\mdline{2292} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2292} \mdline{2292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00}}}\mdline{2292}}&\multicolumn{1}{|l|}{\mdline{2292} yes}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2294} +\mdhr{}%mdk + +%mdk-data-line={2295} +\noindent\mdline{2295}\mdcaption{\textbf{Table~\mdcaptionlabel{4}.}~\mdcaptiontext{Examples of Valid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-valid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2297} +\mdline{2297}Table\mdline{2297}~\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}}\mdline{2297} shows some examples of invalid +P4Runtime binary strings:%mdk + +%mdk-data-line={2300} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2302} P4 type}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2302} P4Runtime binary string}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2304} \mdline{2304}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2304}}&\multicolumn{1}{|l|}{\mdline{2304} \mdline{2304}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x63}}}\mdline{2304}}\\ +\multicolumn{1}{|l}{\mdline{2305} \mdline{2305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2305}}&\multicolumn{1}{|l|}{\mdline{2305} \mdline{2305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2305}}\\ +\multicolumn{1}{|l}{\mdline{2306} \mdline{2306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2306}}&\multicolumn{1}{|l|}{\mdline{2306} \mdline{2306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2306}}\\ +\multicolumn{1}{|l}{\mdline{2307} \mdline{2307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2307}}&\multicolumn{1}{|l|}{\mdline{2307} \mdline{2307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x10\textbackslash{}x63}}}\mdline{2307}}\\ +\multicolumn{1}{|l}{\mdline{2308} \mdline{2308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2308}}&\multicolumn{1}{|l|}{\mdline{2308} \mdline{2308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2308}}\\ +\multicolumn{1}{|l}{\mdline{2309} \mdline{2309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2309}}&\multicolumn{1}{|l|}{\mdline{2309} \mdline{2309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x40\textbackslash{}x63}}}\mdline{2309}}\\ +\multicolumn{1}{|l}{\mdline{2310} \mdline{2310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2310}}&\multicolumn{1}{|l|}{\mdline{2310} \mdline{2310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x9d}}}\mdline{2310}}\\ +\multicolumn{1}{|l}{\mdline{2311} \mdline{2311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2311}}&\multicolumn{1}{|l|}{\mdline{2311} \mdline{2311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x8d\textbackslash{}x1d}}}\mdline{2311}}\\ +\multicolumn{1}{|l}{\mdline{2312} \mdline{2312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2312}}&\multicolumn{1}{|l|}{\mdline{2312} \mdline{2312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2312}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2314} +\mdhr{}%mdk + +%mdk-data-line={2315} +\noindent\mdline{2315}\mdcaption{\textbf{Table~\mdcaptionlabel{5}.}~\mdcaptiontext{Examples of Invalid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-invalid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2317} +\mdline{2317}As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from \mdline{2322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2322} to \mdline{2322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2322}, a server +running the \mdline{2323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2323} version of the P4 program will accept requests from +clients that remain on the \mdline{2324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2324} P4Runtime version.%mdk + +%mdk-data-line={2326} +\mdline{2326}Despite the server\mdline{2326}'\mdline{2326}s binary string flexibility for P4 program update support, +the client and server must both remain aware of the +\mdline{2328}\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2328} +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values.%mdk + +%mdk-data-line={2333} +\mdline{2333}Representation of variable-length integer values (\mdline{2333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2333} P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the \mdline{2335}\emph{dynamic-length}\mdline{2335} of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an \mdline{2338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2338} error code otherwise.%mdk + +%mdk-data-line={2340} +\subsection{\mdline{2340}8.5.\hspace*{0.5em}\mdline{2340}Representation of Arbitrary P4 Types}\label{sec-representation-of-arbitrary-p4-types}%mdk%mdk + +%mdk-data-line={2342} +\subsubsection{\mdline{2342}8.5.1.\hspace*{0.5em}\mdline{2342}Problem Statement}\label{sec-problem-statement}%mdk%mdk + +%mdk-data-line={2344} +\noindent\mdline{2344}The P4\mdline{2344}\mdsub{16}\mdline{2344} language includes more complex types than just binary strings +\mdline{2345}[\mdcite{p4complextypes}{3}]\mdline{2345}. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table\mdline{2348}~\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}}\mdline{2348} shows the different +P4\mdline{2349}\mdsub{16}\mdline{2349} types and how they are allowed to be used, as per the P4\mdline{2349}\mdsub{16}\mdline{2349} +specification.%mdk + +%mdk-data-line={2352} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|l}{{\bfseries\mdline{2354}}}&\multicolumn{3}{|c|}{{\bfseries\mdline{2354} Container type}}\\ +\cmidrule{2-2}\cmidrule{3-3}\cmidrule{4-4} +\multicolumn{1}{|l}{{\bfseries\mdline{2356} Element type}}&\multicolumn{1}{|l}{{\bfseries\mdline{2356} header}}&\multicolumn{1}{|l}{{\bfseries\mdline{2356} header\mdline{2356}\_\mdline{2356}union}}&\multicolumn{1}{|l|}{{\bfseries\mdline{2356} struct or tuple}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2358} \mdline{2358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2358}}&\multicolumn{1}{|l}{\mdline{2358} allowed}&\multicolumn{1}{|l}{\mdline{2358} error}&\multicolumn{1}{|l|}{\mdline{2358} allowed}\\ +\multicolumn{1}{|l}{\mdline{2359} \mdline{2359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2359}}&\multicolumn{1}{|l}{\mdline{2359} allowed}&\multicolumn{1}{|l}{\mdline{2359} error}&\multicolumn{1}{|l|}{\mdline{2359} allowed}\\ +\multicolumn{1}{|l}{\mdline{2360} \mdline{2360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2360}}&\multicolumn{1}{|l}{\mdline{2360} allowed}&\multicolumn{1}{|l}{\mdline{2360} error}&\multicolumn{1}{|l|}{\mdline{2360} allowed}\\ +\multicolumn{1}{|l}{\mdline{2361} \mdline{2361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int}}}\mdline{2361}}&\multicolumn{1}{|l}{\mdline{2361} error}&\multicolumn{1}{|l}{\mdline{2361} error}&\multicolumn{1}{|l|}{\mdline{2361} error}\\ +\multicolumn{1}{|l}{\mdline{2362} \mdline{2362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}void}}}\mdline{2362}}&\multicolumn{1}{|l}{\mdline{2362} error}&\multicolumn{1}{|l}{\mdline{2362} error}&\multicolumn{1}{|l|}{\mdline{2362} error}\\ +\multicolumn{1}{|l}{\mdline{2363} \mdline{2363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2363}}&\multicolumn{1}{|l}{\mdline{2363} error}&\multicolumn{1}{|l}{\mdline{2363} error}&\multicolumn{1}{|l|}{\mdline{2363} allowed}\\ +\multicolumn{1}{|l}{\mdline{2364} \mdline{2364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_kind}}}\mdline{2364}}&\multicolumn{1}{|l}{\mdline{2364} error}&\multicolumn{1}{|l}{\mdline{2364} error}&\multicolumn{1}{|l|}{\mdline{2364} error}\\ +\multicolumn{1}{|l}{\mdline{2365} \mdline{2365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2365}}&\multicolumn{1}{|l}{\mdline{2365} error}&\multicolumn{1}{|l}{\mdline{2365} error}&\multicolumn{1}{|l|}{\mdline{2365} allowed}\\ +\multicolumn{1}{|l}{\mdline{2366} \mdline{2366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2366}}&\multicolumn{1}{|l}{\mdline{2366} allowed\mdline{2366}\mdfootnote{1}{%mdk-data-line={2376} +%mdk-data-line={2376} +\noindent\mdline{2376}an \mdline{2376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2376} type used as a field in a \mdline{2376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2376} must specify a +underlying type and representation for \mdline{2377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2377} elements.%mdk +\label{fn-enum_header}%mdk%mdk +}\mdline{2366}}&\multicolumn{1}{|l}{\mdline{2366} error}&\multicolumn{1}{|l|}{\mdline{2366} allowed}\\ +\multicolumn{1}{|l}{\mdline{2367} \mdline{2367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2367}}&\multicolumn{1}{|l}{\mdline{2367} error}&\multicolumn{1}{|l}{\mdline{2367} allowed}&\multicolumn{1}{|l|}{\mdline{2367} allowed}\\ +\multicolumn{1}{|l}{\mdline{2368} header stack}&\multicolumn{1}{|l}{\mdline{2368} error}&\multicolumn{1}{|l}{\mdline{2368} error}&\multicolumn{1}{|l|}{\mdline{2368} allowed}\\ +\multicolumn{1}{|l}{\mdline{2369} \mdline{2369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2369}}&\multicolumn{1}{|l}{\mdline{2369} error}&\multicolumn{1}{|l}{\mdline{2369} error}&\multicolumn{1}{|l|}{\mdline{2369} allowed}\\ +\multicolumn{1}{|l}{\mdline{2370} \mdline{2370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2370}}&\multicolumn{1}{|l}{\mdline{2370} error}&\multicolumn{1}{|l}{\mdline{2370} error}&\multicolumn{1}{|l|}{\mdline{2370} allowed}\\ +\multicolumn{1}{|l}{\mdline{2371} \mdline{2371}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2371}}&\multicolumn{1}{|l}{\mdline{2371} error}&\multicolumn{1}{|l}{\mdline{2371} error}&\multicolumn{1}{|l|}{\mdline{2371} allowed}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2373} +\mdhr{}%mdk + +%mdk-data-line={2374} +\noindent\mdline{2374}\mdcaption{\textbf{Table~\mdcaptionlabel{6}.}~\mdcaptiontext{P4 Type Usage}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-type-usage}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2379} +\mdline{2379}For example, the following P4\mdline{2379}\mdsub{16}\mdline{2379} objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects.%mdk + +%mdk-data-line={2382} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2383} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}{\bfseries{\mdcolor{navy}tuple}}\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}4}\textgreater{},~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~\textgreater{}~\textgreater{}()~digest\_complex;\\ +digest\_complex.pack(\{~hdr.ipv4.version,~hdr.ipv4.protocol~\});\\ +{\mdcolor{darkgreen}//~...}\\ +{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2393} +\noindent\mdline{2393}One solution would be to use only binary string (\mdline{2393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2393} type) in +p4runtime.proto and to define a custom serialization format for complex P4\mdline{2394}\mdsub{16}\mdline{2394} +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P4\mdline{2401}\mdsub{16}\mdline{2401} types.%mdk + +%mdk-data-line={2403} +\subsubsection{\mdline{2403}8.5.2.\hspace*{0.5em}\mdline{2403}P4 Type Specifications in p4info.proto}\label{sec-p4-type-specifications-in-p4infoproto}%mdk%mdk + +%mdk-data-line={2405} +\noindent\mdline{2405}In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type \mdline{2409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip\_t}}}\mdline{2409}, which is a header union with 2 possible headers: +\mdline{2410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4}}}\mdline{2410} with type \mdline{2410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4\_t}}}\mdline{2410} and \mdline{2410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6}}}\mdline{2410} with type \mdline{2410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6\_t}}}\mdline{2410}. Similarly, they need to +know the field layout for both of these header types.%mdk + +%mdk-data-line={2413} +\mdline{2413}To achieve this we introduce 2 main Protobuf messages: \mdline{2413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2413} and +\mdline{2414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2414}.%mdk + +%mdk-data-line={2416} +\mdline{2416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2416} is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P4\mdline{2417}\mdsub{16}\mdline{2417} program. These +named types are \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2418}, \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2418}, \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2418}, \mdline{2418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2418} and +\mdline{2419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2419}; for each of these we have a type specification message, +respectively \mdline{2420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructTypeSpec}}}\mdline{2420}, \mdline{2420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderTypeSpec}}}\mdline{2420}, \mdline{2420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionTypeSpec}}}\mdline{2420}, +\mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4EnumTypeSpec}}}\mdline{2421} and \mdline{2421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4SerializableEnumTypeSpec}}}\mdline{2421}. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. \mdline{2423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2423} also includes the list of parser errors for the program, as +a \mdline{2424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4ErrorTypeSpec}}}\mdline{2424} message.%mdk + +%mdk-data-line={2426} +\mdline{2426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2426} is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each \mdline{2428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2428} message corresponds to a compile-time type in the +original P4\mdline{2429}\mdsub{16}\mdline{2429} program (\mdline{2429}e.g.\mdline{2429} the type parameter of an extern). This +compile-time type is represented as a Protobuf \mdline{2430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2430}, which can be:%mdk + +%mdk-data-line={2432} +\begin{itemize}%mdk + +%mdk-data-line={2432} +\item{} +%mdk-data-line={2432} +\mdline{2432}a string representing the name of the type in case of a named type (\mdline{2432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2432}, +\mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2433}, \mdline{2433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2433} or user-defined \mdline{2433}\textquotedblleft{}new\textquotedblright{}\mdline{2433} +\mdline{2434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2434}),%mdk%mdk + +%mdk-data-line={2436} +\item{} +%mdk-data-line={2436} +\mdline{2436}an empty Protobuf message for \mdline{2436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2436} and \mdline{2436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2436}, or%mdk%mdk + +%mdk-data-line={2438} +\item{} +%mdk-data-line={2438} +\mdline{2438}a Protobuf message for other anonymous types (\mdline{2438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2438}, \mdline{2438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2438}, \mdline{2438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2438}, +\mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2439} or stack). The \mdline{2439}\textquotedblleft{}binary string\textquotedblright{}\mdline{2439} types (\mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2439}, \mdline{2439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2439}, and +\mdline{2440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2440}) are grouped together in the \mdline{2440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4BitstringLikeTypeSpec}}}\mdline{2440} message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf \mdline{2442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2442} +type).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2445} +\noindent\mdline{2445}For all P4\mdline{2445}\mdsub{16}\mdline{2445} compound types (\mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2445}, \mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2445}, \mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2445}, and \mdline{2445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2445}), +the order of \mdline{2446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2446} in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P4\mdline{2448}\mdsub{16}\mdline{2448} declaration. The same goes for the order of members of an \mdline{2448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2448} +(serializable or not) or members of \mdline{2449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2449}.%mdk + +%mdk-data-line={2451} +\subsubsection{\mdline{2451}8.5.3.\hspace*{0.5em}\mdline{2451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2451} in p4runtime.proto}\label{sec-p4data-in-p4runtime-proto}%mdk%mdk + +%mdk-data-line={2453} +\noindent\mdline{2453}P4Runtime uses the \mdline{2453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2453} message to represent values of arbitrary types. The +P4Runtime client must generate correct \mdline{2454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2454} messages based on the type +specification information included in P4Info. The \mdline{2455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2455} message was designed +to introduce little overhead compared to using binary strings in the most common +case (P4\mdline{2457}\mdsub{16}\mdline{2457} \mdline{2457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2457} type).%mdk + +%mdk-data-line={2459} +\mdline{2459}Just like its P4Info counterpart\mdline{2459} \mdline{2459}- \mdline{2459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2459} \mdline{2459}-, \mdline{2459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2459} uses a Protobuf +\mdline{2460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2460} to represent all possible values.%mdk + +%mdk-data-line={2462} +\mdline{2462}We define a canonical representation for \mdline{2462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2462} messages\mdline{2462} \mdline{2462}\textemdash{}\mdline{2462} therefore +guaranteeing read-write symmetry\mdline{2463} \mdline{2463}\textemdash{}\mdline{2463} by introducing the following requirements:%mdk + +%mdk-data-line={2465} +\begin{itemize}%mdk + +%mdk-data-line={2465} +\item{} +%mdk-data-line={2465} +\mdline{2465}The order of \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2465} in \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructLike}}}\mdline{2465} and the order of \mdline{2465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2465} in +\mdline{2466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2466} must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P4\mdline{2467}\mdsub{16}\mdline{2467} type +declaration.%mdk%mdk + +%mdk-data-line={2470} +\item{} +%mdk-data-line={2470} +\mdline{2470}An invalid header is represented by a \mdline{2470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2470} message where the \mdline{2470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_valid}}}\mdline{2470} +field is false and the \mdline{2471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2471} repeated field is empty.%mdk%mdk + +%mdk-data-line={2473} +\item{} +%mdk-data-line={2473} +\mdline{2473}An invalid header union (\mdline{2473}i.e.\mdline{2473} all headers in the union are invalid) is +represented by a \mdline{2474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnion}}}\mdline{2474} message where the \mdline{2474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header\_name}}}\mdline{2474} is the +empty string (default value for the field) and the \mdline{2475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header}}}\mdline{2475} is unset.%mdk%mdk + +%mdk-data-line={2477} +\item{} +%mdk-data-line={2477} +\mdline{2477}The order of \mdline{2477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2477} in \mdline{2477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStack}}}\mdline{2477} and \mdline{2477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStack}}}\mdline{2477} is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the \mdline{2479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2479} field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding \mdline{2481}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStackTypeSpec}}}\mdline{2481} or +\mdline{2482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStackTypeSpec}}}\mdline{2482} message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2484} +\subsubsection{\mdline{2484}8.5.4.\hspace*{0.5em}\mdline{2484}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={2486} +\noindent\mdline{2486}Let\mdline{2486}'\mdline{2486}s look at the Register example again:%mdk + +%mdk-data-line={2488} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2489} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2496} +\noindent\mdline{2496}Here\mdline{2496}'\mdline{2496}s the corresponding entry in the P4Info message:%mdk + +%mdk-data-line={2498} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2499} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}registers~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}369119267}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~\}\\ +~~type\_spec~\{\\ +~~~~header\_union~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~size:~{\mdcolor{purple}128}\\ +\}\\ +type\_info~\{\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~header\_unions~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2555} +\noindent\mdline{2555}Here\mdline{2555}'\mdline{2555}s a \mdline{2555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.WriteRequest}}}\mdline{2555} to set the value of \mdline{2555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_ip{}[12]}}}\mdline{2555}:%mdk + +%mdk-data-line={2557} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2558} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}update~\{\\ +~~type:~INSERT\\ +~~entity~\{\\ +~~~~register\_entry~\{\\ +~~~~~~register\_id:~{\mdcolor{purple}369119267}\\ +~~~~~~index~\{\\ +~~~~~~~~index:~{\mdcolor{purple}12}\\ +~~~~~~\}\\ +~~~~~~data~\{\\ +~~~~~~~~header\_union~\{\\ +~~~~~~~~~~valid\_header\_name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~~~valid\_header~\{\\ +~~~~~~~~~~~~is\_valid:~true\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x04}{\mdcolor{maroon}"}\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{darkgreen}\#~...}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2581} +\subsubsection{\mdline{2581}8.5.5.\hspace*{0.5em}\mdline{2581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2581}, serializable \mdline{2581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2581} and \mdline{2581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}\label{sec-enum-serializable-enum-and-error}%mdk%mdk + +%mdk-data-line={2583} +\noindent\mdline{2583}P4\mdline{2583}\mdsub{16}\mdline{2583} supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or \mdline{2584}\textquotedblleft{}unsafe\textquotedblright{}\mdline{2584} enum) +\mdline{2585}[\mdcite{p4enums}{5}]\mdline{2585}. For \mdline{2585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2585} types with no underlying type\mdline{2585} \mdline{2585}\textemdash{}\mdline{2585} as well as \mdline{2585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2585} \mdline{2585}\textemdash{}\mdline{2585} +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in \mdline{2588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2588} to represent \mdline{2588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2588} and +\mdline{2589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2589} values.%mdk + +%mdk-data-line={2591} +\mdline{2591}Serializable \mdline{2591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2591} types have an underlying fixed-width unsigned integer +representation (\mdline{2592}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2592}). All named enum members must be assigned an integer +value by the P4 programmer, but \mdline{2593}\emph{not all}\mdline{2593} valid numeric values for the +underlying type need to have a corresponding name. \mdline{2594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2594} includes the +mapping between entry name and entry value. When providing serializable enum +values through \mdline{2596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2596}, one must use the assigned integer value (\mdline{2596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum\_value}}}\mdline{2596} +bytestring field). P4Runtime does not provide a way for the client to use the +name\mdline{2598} \mdline{2598}\textemdash{}\mdline{2598} even when the enum member has one\mdline{2598} \mdline{2598}\textemdash{}\mdline{2598} instead of the value, as it makes +it easier for the server to respect the\mdline{2599}~\mdref{sec-read-write-symmetry}{read-write +symmetry}\mdline{2600} principle.%mdk + +%mdk-data-line={2602} +\subsubsection{\mdline{2602}8.5.6.\hspace*{0.5em}\mdline{2602}User-defined types}\label{sec-user-defined-types}%mdk%mdk + +%mdk-data-line={2604} +\noindent\mdline{2604}P4\mdline{2604}\mdsub{16}\mdline{2604} enables programmers to introduce new types\mdline{2604}~[\mdcite{p4newtypes}{11}]\mdline{2604}. While similar +to \mdline{2605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{2605}, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +\mdline{2608}\mdref{sec-psa-metadata-translation}{translation}\mdline{2608}. When introducing a new type, the +declaration can be annotated with \mdline{2609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2609} to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for\mdline{2611}~\mdref{sec-translation-of-port-numbers}{port numbers}\mdline{2611}, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. \mdline{2614}\textbf{The \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}} annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}})}\mdline{2616}. The type exposed to the control plane (referred to as the +\mdline{2617}\emph{controller\_type}\mdline{2617}) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a \mdline{2619}\emph{URI}\mdline{2619} (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the \mdline{2621}\emph{controller\_type}\mdline{2621} of the values exposed to the control plane. The +\mdline{2622}\emph{controller\_type}\mdline{2622} can be either \mdline{2622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2622} where \mdline{2622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2622} is any positive integer, or +\mdline{2623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{2623}, or a positive integer \mdline{2623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2623} which has the same meaning as \mdline{2623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2623}. +Specifying just an integer is deprecated.%mdk + +%mdk-data-line={2626} +\mdline{2626}It is recommended that the URI includes at least the P4 architecture name and +the type name.%mdk + +%mdk-data-line={2629} +\mdline{2629}A \mdline{2629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2629} annotation need not have any effect if it is used to +annotate anything in a P4 program other than a \mdline{2630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2630} declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect.%mdk + +%mdk-data-line={2634} +\mdline{2634}User-defined types are specified using the \mdline{2634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{2634} message, which has +the following fields:%mdk + +%mdk-data-line={2637} +\begin{itemize}%mdk + +%mdk-data-line={2637} +\item{} +%mdk-data-line={2637} +\mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}representation}}}\mdline{2637}, a Protobuf \mdline{2637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2637} specifying how values of this type are +exchanged between client and server; it can be either:%mdk + +%mdk-data-line={2640} +\begin{itemize}%mdk + +%mdk-data-line={2640} +\item{} +%mdk-data-line={2640} +\mdline{2640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2640}, if and only if no \mdline{2640}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2640} annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 \mdline{2642}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2642} declaration is itself a +user-defined type, \mdline{2643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2643} is obtained by \mdline{2643}\textquotedblleft{}walking\textquotedblright{}\mdline{2643} the chain of +\mdline{2644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2644} declarations recursively until a built-in type (\mdline{2644}e.g.\mdline{2644} \mdline{2644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2644}) is +found.%mdk%mdk + +%mdk-data-line={2647} +\item{} +%mdk-data-line={2647} +\mdline{2647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}translated\_type}}}\mdline{2647}, if and only if the P4 \mdline{2647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2647} declaration was annotated +with \mdline{2648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2648}. It is of type \mdline{2648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeTranslation}}}\mdline{2648}, +which itself has two fields\mdline{2649} \mdline{2649}\textemdash{}\mdline{2649} \mdline{2649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uri}}}\mdline{2649} and either \mdline{2649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_string}}}\mdline{2649} or +\mdline{2650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_bitwidth}}}\mdline{2650} \mdline{2650}\textemdash{}\mdline{2650}, which map to the two input parameters to the +annotation.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2653} +\item{} +%mdk-data-line={2653} +\mdline{2653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{2653}, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2656} +\noindent\mdline{2656}For example, an architecture\mdline{2656} \mdline{2656}\textemdash{}\mdline{2656} in this case PSA\mdline{2656} \mdline{2656}\textemdash{}\mdline{2656} may introduce a new type +for port numbers:%mdk + +%mdk-data-line={2658} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2659} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~string,~e.g.~"eth0".}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~32-bit~integer,~e.g.~0xffffffff.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{darkgreen}//~Same~as~above.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_32\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_32\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2672} +\noindent\mdline{2672}In this case, the P4Info message would include the following \mdline{2672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2672} +messages:%mdk + +%mdk-data-line={2675} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2676} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_string:~\{\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2713} +\noindent\mdline{2713}Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (\mdline{2714}e.g.\mdline{2714} through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over \mdline{2716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2716} to enable users +to overwrite annotations included as part of the P4 architecture definition.%mdk + +%mdk-data-line={2719} +\subsubsection{\mdline{2719}8.5.7.\hspace*{0.5em}\mdline{2719}Trade-off for v1.x Releases}\label{sec-trade-off-for-v1x-releases}%mdk%mdk + +%mdk-data-line={2721} +\noindent\mdline{2721}For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +\mdline{2722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2722} with \mdline{2722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2722} in the \mdline{2722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{2722} message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +\mdline{2725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2725} to provide action parameter values and controller metadata +values. However \mdline{2726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2726} is used whenever appropriate for PSA externs and we +encourage the use of \mdline{2727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2727} in architecture-specific extensions.%mdk + +%mdk-data-line={2729} +\mdline{2729}In order to support\mdline{2729}~\mdref{sec-psa-metadata-translation}{translation}\mdline{2729} for action +parameters and match fields, we include a \mdline{2730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2730} field in +\mdline{2731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{2731}, \mdline{2731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Action.Param}}}\mdline{2731} and +\mdline{2732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ControllerPacketMetadata.Metadata}}}\mdline{2732}. In addition, the \mdline{2732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2732} +field for all of these message types must abide by the following rule when +\mdline{2734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2734} names a translated user-defined type:%mdk + +%mdk-data-line={2736} +\begin{itemize}%mdk + +%mdk-data-line={2736} +\item{} +%mdk-data-line={2736} +\mdline{2736}If the \mdline{2736}\emph{controller\_type}\mdline{2736} is a fixed-width unsigned bitstring, the \mdline{2736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2736} +field must be set to the bitwidth of the \mdline{2737}\emph{controller\_type}\mdline{2737}. This information +is redundant with the one included in the \mdline{2738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2738} entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent.%mdk%mdk + +%mdk-data-line={2744} +\item{} +%mdk-data-line={2744} +\mdline{2744}Otherwise (\mdline{2744}i.e.\mdline{2744}, if the \mdline{2744}\emph{controller\_type}\mdline{2744} is a string), the \mdline{2744}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2744} must +be \mdline{2745}\textquotedblleft{}unset\textquotedblright{}\mdline{2745}, which, in Protobuf version 3, is the same as setting the field to +0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2748} +\noindent\mdline{2748}For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types:%mdk + +%mdk-data-line={2750} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2751} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{navy}@}{\mdcolor{navy}name}{\mdcolor{maroon}(".t")}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~meta.port1:~exact;~~{\mdcolor{darkgreen}//~meta.port1~has~type~PortId\_String\_t}\\ +~~~~meta.port2:~exact;~~{\mdcolor{darkgreen}//~meta.port2~has~type~PortId\_Bit32\_t}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2769} +\noindent\mdline{2769}This table would have the following representation in the generated P4Info +message:%mdk + +%mdk-data-line={2771} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2772} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tables~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}34728461}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port1}{\mdcolor{maroon}"}\\ +~~~~{\mdcolor{darkgreen}\#~notice~that~bitwidth~is~unset}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port2}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~{\mdcolor{darkgreen}\#~...}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2800} +\section{\mdline{2800}9.\hspace*{0.5em}\mdline{2800}P4 Entity Messages}\label{sec-p4-entity-msgs}%mdk%mdk + +%mdk-data-line={2802} +\noindent\mdline{2802}P4Runtime covers P4 entities that are either part of the P4\mdline{2802}\mdsub{16}\mdline{2802} language, or +defined as PSA externs. The sections below describe the messages for each +supported entity.%mdk + +%mdk-data-line={2806} +\subsection{\mdline{2806}9.1.\hspace*{0.5em}\mdline{2806}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}\label{sec-table-entry}%mdk%mdk + +%mdk-data-line={2808} +\noindent\mdline{2808}The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action\mdline{2810}'\mdline{2810}s +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification.%mdk + +%mdk-data-line={2816} +\mdline{2816}P4Runtime supports inserting, modifying, deleting and reading table entries with +the \mdline{2817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2817} entity, which has the following fields:%mdk + +%mdk-data-line={2819} +\begin{itemize}%mdk + +%mdk-data-line={2819} +\item{} +%mdk-data-line={2819} +\mdline{2819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2819}, which identifies the table instance; the \mdline{2819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{2819} is determined +by the P4Info message.%mdk%mdk + +%mdk-data-line={2822} +\item{} +%mdk-data-line={2822} +\mdline{2822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2822}, a repeated field of \mdline{2822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2822} messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration.%mdk%mdk + +%mdk-data-line={2826} +\item{} +%mdk-data-line={2826} +\mdline{2826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{2826}, which indicates which of the table\mdline{2826}'\mdline{2826}s actions to execute in case of +match and with which argument values.%mdk%mdk + +%mdk-data-line={2829} +\item{} +%mdk-data-line={2829} +\mdline{2829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2829}, a 32-bit integer used to order entries when the table\mdline{2829}'\mdline{2829}s match key +includes an optional, ternary or range match.%mdk%mdk + +%mdk-data-line={2832} +\item{} +%mdk-data-line={2832} +\mdline{2832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{2832}, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +\mdline{2836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{2836} field.%mdk%mdk + +%mdk-data-line={2838} +\item{} +%mdk-data-line={2838} +\mdline{2838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{2838}, an arbitrary \mdline{2838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2838} value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry.%mdk%mdk + +%mdk-data-line={2843} +\item{} +%mdk-data-line={2843} +\mdline{2843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{2843}, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See\mdline{2844}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2845} section for more information.%mdk%mdk + +%mdk-data-line={2847} +\item{} +%mdk-data-line={2847} +\mdline{2847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2847}, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See\mdline{2848}~\mdref{sec-direct-resources}{Direct +resources}\mdline{2849} section for more information.%mdk%mdk + +%mdk-data-line={2851} +\item{} +%mdk-data-line={2851} +\mdline{2851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{2851}, which is used to read and write the per-color counter +values for the direct meter entry attached to this table entry, if any. +See\mdline{2853}~\mdref{sec-direct-resources}{Direct resources}\mdline{2853} section for more information.%mdk%mdk + +%mdk-data-line={2855} +\item{} +%mdk-data-line={2855} +\mdline{2855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2855}, a boolean flag which indicates whether the table entry is +the default entry for the table. See\mdline{2856}~\mdref{sec-default-entry}{Default entry}\mdline{2856} +section for more information.%mdk%mdk + +%mdk-data-line={2859} +\item{} +%mdk-data-line={2859} +\mdline{2859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2859} and \mdline{2859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{2859}, which are two fields used to +implement idle-timeout support for the table, if applicable. See +\mdline{2861}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{2861} section for more information.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2863} +\noindent\mdline{2863}The \mdline{2863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2863} field must be set to a non-zero value if the match key includes a +ternary match (\mdline{2864}i.e.\mdline{2864} in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an \mdline{2865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{2865}, \mdline{2865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2865} or +\mdline{2866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2866} match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches.%mdk + +%mdk-data-line={2875} +\mdline{2875}The \mdline{2875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2875} and \mdline{2875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{2875} fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for \mdline{2877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{2877} and \mdline{2877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{2877} updates. When deleting +an entry, these key fields (along with \mdline{2878}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{2878}) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a \mdline{2880}\emph{keyless}\mdline{2880} +table (the table has an empty match key), the server must reject all attempts to +\mdline{2882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{2882} a match entry and return an \mdline{2882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2882} error.%mdk + +%mdk-data-line={2884} +\mdline{2884}The number of match entries that a table \mdline{2884}\emph{should}\mdline{2884} support is indicated in P4Info +(\mdline{2885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2885} field of \mdline{2885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{2885} message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P4\mdline{2886}\mdsub{16}\mdline{2886} specification for the +\mdline{2887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2887} property\mdline{2887}~[\mdcite{p4tableproperties}{30}]\mdline{2887}. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +\mdline{2891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{2891} when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached.%mdk + +%mdk-data-line={2896} +\subsubsection{\mdline{2896}9.1.1.\hspace*{0.5em}\mdline{2896}Match Format}\label{sec-match-format}%mdk%mdk + +%mdk-data-line={2898} +\noindent\mdline{2898}The bytes fields in the \mdline{2898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2898} message follow the format described in +\mdline{2899}\mdref{sec-bytestrings}{Bytestrings}\mdline{2899}.%mdk + +%mdk-data-line={2901} +\mdline{2901}For \mdline{2901}\textquotedblleft{}don't care\textquotedblright{}\mdline{2901} matches, the P4Runtime client must omit the field\mdline{2901}'\mdline{2901}s entire +\mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{2902} entry when building the \mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2902} repeated field of the \mdline{2902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2902} +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for \mdline{2904}\textquotedblleft{}don't care\textquotedblright{}\mdline{2904} matches, which is needed +to ensure\mdline{2905}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2905}. For PSA match types, +a \mdline{2906}\textquotedblleft{}don't care\textquotedblright{}\mdline{2906} match for a specific match key field is defined as follows:%mdk + +%mdk-data-line={2908} +\begin{itemize}%mdk + +%mdk-data-line={2908} +\item{} +%mdk-data-line={2908} +\mdline{2908}For a \mdline{2908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2908} match, it is logically equivalent to a mask of zeros.%mdk%mdk + +%mdk-data-line={2910} +\item{} +%mdk-data-line={2910} +\mdline{2910}For a \mdline{2910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{2910} match, it is logically equivalent to a wildcard match.%mdk%mdk + +%mdk-data-line={2912} +\item{} +%mdk-data-line={2912} +\mdline{2912}For an \mdline{2912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2912} match, it is logically equivalent to a prefix\mdline{2912}\_\mdline{2912}len of zero.%mdk%mdk + +%mdk-data-line={2914} +\item{} +%mdk-data-line={2914} +\mdline{2914}For a \mdline{2914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{2914} match, it is logically equivalent to a range which includes all +possible values for the field.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2917} +\noindent\mdline{2917}Note that there is no \mdline{2917}\textquotedblleft{}don't care\textquotedblright{}\mdline{2917} value for \mdline{2917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2917} matches and therefore exact +match fields can never be omitted from the \mdline{2918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2918} message.%mdk + +%mdk-data-line={2920} +\mdline{2920}The following example shows a P4Runtime message that treats a \mdline{2920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2920} field +as a \mdline{2921}\textquotedblleft{}don't care\textquotedblright{}\mdline{2921} match. The P4 program defines table \mdline{2921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{2921} with \mdline{2921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2921} +and \mdline{2922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2922} fields in its match key:%mdk + +%mdk-data-line={2924} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2925} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~ternary;\\ +~~~~istd.ingress\_port:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2936} +\noindent\mdline{2936}In this P4Runtime request, the client omits the table\mdline{2936}'\mdline{2936}s \mdline{2936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2936} field +from the repeated \mdline{2937}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2937} field to indicate a \mdline{2937}\textquotedblleft{}don't care\textquotedblright{}\mdline{2937} match. As shown +below, the \mdline{2938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2938} specifies only the \mdline{2938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2938} field given by \mdline{2938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id:~2}}}\mdline{2938}.%mdk + +%mdk-data-line={2940} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2941} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}33554439}~~{\mdcolor{darkgreen}\#~Table~t's~ID.}\\ +~~~~match~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~field\_id~1~is~not~present~to~use~the~don't~care~ternary~value.}\\ +~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~exact~\{\\ +~~~~~~~~value:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x20}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~action~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~Action~selection~goes~here.}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2959} +\noindent\mdline{2959}For every member of the \mdline{2959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2959} repeated \mdline{2959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2959} field, \mdline{2959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id}}}\mdline{2959} must be +a valid id for the table, as per the P4Info, and one of the fields in +\mdline{2961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{2961} must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an \mdline{2963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{2963} error code.%mdk + +%mdk-data-line={2965} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2965} +\item\mdline{2965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{2965} match + +%mdk-data-line={2966} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2966} +\item\mdline{2966}The binary string encoding of the value must conform to the +\mdline{2967}\mdref{sec-bytestrings}{Bytestrings}\mdline{2967} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2969} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2970} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.exact().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2973} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2973} +\item\mdline{2973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{2973} match + +%mdk-data-line={2974} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2974} +\item\mdline{2974}The binary string encoding of the value (when present) must conform to the +\mdline{2975}\mdref{sec-bytestrings}{Bytestrings}\mdline{2975} requirements.%mdk + +%mdk-data-line={2976} +\item\mdline{2976}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2976} match must be omitted.%mdk + +%mdk-data-line={2977} +\item\mdline{2977}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2977} bits must be 0 in value.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2979} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2980} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.lpm().value()))\\ +\\ +pLen~=~match.lpm().prefix\_len()\\ +assert(pLen~\textgreater{}~0)\\ +\\ +trailing\_zeros~=~countTrailingZeros(match.lpm().value())\\ +assert(trailing\_zeros~\textgreater{}=~field\_bits~-~pLen)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2989} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2989} +\item\mdline{2989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{2989} match + +%mdk-data-line={2990} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2990} +\item\mdline{2990}The binary string encoding of the value (when present) and mask (when +present) must conform to the\mdline{2991}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2991} requirements.%mdk + +%mdk-data-line={2992} +\item\mdline{2992}\textquotedblleft{}Don't care\textquotedblright{}\mdline{2992} match must be omitted.%mdk + +%mdk-data-line={2993} +\item\mdline{2993}Masked bits must be 0 in value. This constraint taken together +with the\mdline{2994}~\mdref{sec-bytestrings}{Bytestrings}\mdline{2994} requirements means that the +value\mdline{2995}'\mdline{2995}s binary string is never longer than the mask\mdline{2995}'\mdline{2995}s binary string. +When the value\mdline{2996}'\mdline{2996}s string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3000} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3001} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.ternary().value()))\\ +assert(BytestringValid(match.ternary().mask()))\\ +assert(match.ternary().value().size()~\textless{}=~match.ternary().mask().size());\\ +\\ +value~=~parseInteger(match.ternary().value())\\ +mask~=~parseInteger(match.ternary().mask())\\ +\\ +assert(mask~!=~0)\\ +\\ +assert(value~\&~mask~==~value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3013} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3013} +\item\mdline{3013}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3013} match + +%mdk-data-line={3014} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3014} +\item\mdline{3014}The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the\mdline{3015}~\mdref{sec-bytestrings}{Bytestrings}\mdline{3015} +requirements.%mdk + +%mdk-data-line={3017} +\item\mdline{3017}Low bound must be less than or equal to the high bound.%mdk + +%mdk-data-line={3018} +\item\mdline{3018}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3018} match must be omitted.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3020} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3021} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.range().low()))\\ +assert(BytestringValid(match.range().high()))\\ +\\ +low~=~parseInteger(match.range().low())\\ +high~=~parseInteger(match.range().high())\\ +\\ +assert(low~\textless{}=~high)\\ +\\ +assert(low~!=~min\_field\_value~\textbar{}\textbar{}~high~!=~max\_field\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3032} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3032} +\item\mdline{3032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3032} match + +%mdk-data-line={3033} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3033} +\item\mdline{3033}The binary string encoding of the value must conform to the +\mdline{3034}\mdref{sec-bytestrings}{Bytestrings}\mdline{3034} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3036} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3037} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.optional().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3040} +\subsubsection{\mdline{3040}9.1.2.\hspace*{0.5em}\mdline{3040}Action Specification}\label{sec-action-specification}%mdk%mdk + +%mdk-data-line={3042} +\noindent\mdline{3042}The \mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3042} \mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3042} field must be set for every \mdline{3042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3042} update but may be +left unset for \mdline{3043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3043} updates, in which case the action specification for the +table entry will not be modified (if a \mdline{3044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3044} update has an unset action field +and does not modify any direct resource attached to the table then the \mdline{3045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3045} +update is a no-op). Based on the implementation property value of the P4 table, +the \mdline{3047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3047} in the \mdline{3047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3047} message will either be:%mdk + +%mdk-data-line={3049} +\begin{itemize}%mdk + +%mdk-data-line={3049} +\item{} +%mdk-data-line={3049} +\mdline{3049}an \mdline{3049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3049} specification for direct tables (with no P4 \mdline{3049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3049} +property)%mdk%mdk + +%mdk-data-line={3052} +\item{} +%mdk-data-line={3052} +\mdline{3052}an action profile member id for indirect tables for which the \mdline{3052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3052} +property is an action profile with no selector.%mdk%mdk + +%mdk-data-line={3055} +\item{} +%mdk-data-line={3055} +\mdline{3055}an action profile member id or group id for indirect tables for which the +\mdline{3056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3056} property is an action profile with selector.%mdk%mdk + +%mdk-data-line={3058} +\item{} +%mdk-data-line={3058} +\mdline{3058}an \mdline{3058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3058} specification for indirect tables for +which the \mdline{3059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3059} property is an action profile with +selector. This usage is described in\mdline{3060}~\mdref{sec-oneshot}{One Shot Action Selector +Programming}\mdline{3061}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3063} +\noindent\mdline{3063}If the \mdline{3063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3063} does not match the table description in the P4Info (\mdline{3063}e.g.\mdline{3063} the +\mdline{3064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3064} is \mdline{3064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member\_id}}}\mdline{3064} for a direct table), the server must +return an \mdline{3065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3065} error code.%mdk + +%mdk-data-line={3067} +\mdline{3067}The \mdline{3067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3067} Protobuf message has the following fields:%mdk + +%mdk-data-line={3069} +\begin{itemize}%mdk + +%mdk-data-line={3069} +\item{} +%mdk-data-line={3069} +\mdline{3069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3069}, which identifies the action instance; the \mdline{3069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3069} is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an \mdline{3071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3071} error +code. If the client uses a valid \mdline{3072}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3072} for the table but does not +respect the action scope specified in P4Info (\mdline{3073}e.g.\mdline{3073} tries to set a \mdline{3073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{3073} +action as the default action), the server must return a \mdline{3074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3074} +error code.%mdk%mdk + +%mdk-data-line={3077} +\item{} +%mdk-data-line={3077} +\mdline{3077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{3077}: a repeated Protobuf field of action parameter values, each encoded +as a \mdline{3078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{3078} message. For each parameter, \mdline{3078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}param\_id}}}\mdline{3078} must be valid for the +action (as per the P4Info) and value must follow the format described in +\mdline{3080}\mdref{sec-bytestrings}{Bytestrings}\mdline{3080}. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an \mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3082} error code +if a parameter id is missing, if an extra parameter\mdline{3083} \mdline{3083}\textemdash{}\mdline{3083} id not found in the +P4Info\mdline{3084} \mdline{3084}\textemdash{}\mdline{3084} was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +\mdline{3086}\mdref{sec-bytestrings}{Bytestrings}\mdline{3086} format.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3088} +\noindent\mdline{3088}For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a \mdline{3090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3090} error code.%mdk + +%mdk-data-line={3092} +\subsubsection{\mdline{3092}9.1.3.\hspace*{0.5em}\mdline{3092}Default Entry}\label{sec-default-entry}%mdk%mdk + +%mdk-data-line={3094} +\noindent\mdline{3094}According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer\mdline{3095} \mdline{3095}\textemdash{}\mdline{3095} or defaults to \mdline{3095}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3095} +(which is a no-op) otherwise\mdline{3096} \mdline{3096}\textemdash{}\mdline{3096} and assuming it is not declared as \mdline{3096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3096}, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow \mdline{3098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3098} and \mdline{3098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3098} updates on the default entry and the +P4Runtime server must return an \mdline{3099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3099} error code if the client +attempts one.%mdk + +%mdk-data-line={3102} +\mdline{3102}The default entry is identified by setting the \mdline{3102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3102} boolean field +to true. When this flag is set to true, the repeated \mdline{3103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3103} field must be empty +and the \mdline{3104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3104} field must be set to zero, otherwise the P4Runtime server +must return an \mdline{3105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3105} error code. When performing a \mdline{3105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3105} update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its \mdline{3109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3109} and \mdline{3109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3109} value as well as the +configurations for its\mdline{3110}~\mdref{sec-direct-resources}{direct resources}\mdline{3110} will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a \mdline{3112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3112} +error code if the client attempts to modify it.%mdk + +%mdk-data-line={3115} +\mdline{3115}Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to\mdline{3116}~\mdref{sec-direct-resources}{direct resources}\mdline{3116}.%mdk + +%mdk-data-line={3118} +\mdline{3118}In this P4Runtime release, we have decided to restrict the default entry for +indirect tables\mdline{3119} \mdline{3119}\textemdash{}\mdline{3119} tables with an ActionProfile or ActionSelector +\mdline{3120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3120} property\mdline{3120} \mdline{3120}\textemdash{}\mdline{3120} to a constant \mdline{3120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3120} action entry, with the +hope that it would simplify the implementation of the P4Runtime service.%mdk + +%mdk-data-line={3123} +\subsubsection{\mdline{3123}9.1.4.\hspace*{0.5em}\mdline{3123}Constant Tables}\label{sec-constant-tables}%mdk%mdk + +%mdk-data-line={3125} +\noindent\mdline{3125}Constant tables are defined as tables whose match entries are immutable. They +are identified by the \mdline{3126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3126} flag in P4Info.%mdk + +%mdk-data-line={3128} +\mdline{3128}The only write updates which are allowed for constant tables are \mdline{3128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3128} +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +\mdline{3132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3132} error. Just like any table entry \mdline{3132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3132} request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a \mdline{3136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3136} error.%mdk + +%mdk-data-line={3138} +\mdline{3138}The contents of const tables can be queried by the client through a +\mdline{3139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3139}. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: \mdline{3140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3140}, \mdline{3140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3140}, \mdline{3140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3140}, +\mdline{3141}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3141}, and \mdline{3141}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3141} (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. If the table requires a priority value for entries, the server +must populate the \mdline{3144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3144} field appropriately, starting at 1 for the lowest +priority entry and incrementing the value by 1 for each successive entry. Note +that P4\mdline{3146}\mdsub{16}\mdline{3146} does not support assigning explicit priorities to static +entries. When a priority value is required (\mdline{3147}e.g.\mdline{3147} for tables including \mdline{3147}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3147}, +\mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3148} or \mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3148} matches), it is inferred based on the order in which +entries appear in the table declaration.%mdk + +%mdk-data-line={3151} +\subsubsection{\mdline{3151}9.1.5.\hspace*{0.5em}\mdline{3151}Wildcard Reads}\label{sec-table-wildcard-reads}%mdk%mdk + +%mdk-data-line={3153} +\noindent\mdline{3153}When performing a \mdline{3153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3153}, the P4Runtime client can select all entries +from one or all tables on the target and use several of the \mdline{3154}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3154} fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as \mdline{3158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3158} and \mdline{3158}\textquotedblleft{}unset\textquotedblright{}\mdline{3158} for message fields such as \mdline{3158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3158}. The following +fields may be used to select and filter results:%mdk + +%mdk-data-line={3161} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3161} +\item\mdline{3161}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3161}: If default (0), entries from all tables\mdline{3161} \mdline{3161}\textemdash{}\mdline{3161} including constant +tables\mdline{3162} \mdline{3162}\textemdash{}\mdline{3162} will be selected and no other filter can be used. Otherwise only +the specified table will be considered.%mdk + +%mdk-data-line={3164} +\item\mdline{3164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3164}: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned.%mdk + +%mdk-data-line={3168} +\item\mdline{3168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3168}: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an \mdline{3169}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3169} (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id.%mdk + +%mdk-data-line={3175} +\item\mdline{3175}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3175}: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value.%mdk + +%mdk-data-line={3178} +\item\mdline{3178}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3178}: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +\mdline{3180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3180} value.%mdk + +%mdk-data-line={3181} +\item\mdline{3181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3181}: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided \mdline{3183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3183} value.%mdk + +%mdk-data-line={3184} +\item\mdline{3184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3184}: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered.%mdk + +%mdk-data-line={3187} +\item\mdline{3187}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{3187}: If default (unset), all table entries will be considered. Otherwise, +table entries will be filtered based on the provided role value.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3190} +\noindent\mdline{3190}For example, in order to read all entries from all tables from device 3, the +client can use the following \mdline{3191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3191} message.%mdk + +%mdk-data-line={3193} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3194} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0}\\ +~~~~priority:~{\mdcolor{purple}0}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3205} +\noindent\mdline{3205}In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following \mdline{3206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3206} +message:%mdk + +%mdk-data-line={3209} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3210} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~priority:~{\mdcolor{purple}11}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3221} +\noindent\mdline{3221}The canonical representation of \mdline{3221}\textquotedblleft{}don't care\textquotedblright{}\mdline{3221} matches, combined with the ability +to do a wildcard read on all table entries by leaving the \mdline{3222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3222} field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single \mdline{3224}\textquotedblleft{}don't care\textquotedblright{}\mdline{3224} entry or to do a wildcard +read. If a table has no fields with match kind \mdline{3225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3225}, it is possible via +P4Runtime to add an entry that is \mdline{3226}\textquotedblleft{}don't care\textquotedblright{}\mdline{3226} for all fields (\mdline{3226}i.e.\mdline{3226} has an empty +\mdline{3227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3227} field) but is not the default entry (\mdline{3227}i.e.\mdline{3227} \mdline{3227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3227} is +false). When reading this entry from the table, there is no way to read \mdline{3228}\emph{only}\mdline{3228} +that entry from the table, because it would require providing an unset \mdline{3229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3229} +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single \mdline{3232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{3232} match:%mdk + +%mdk-data-line={3234} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3235} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;~fwd;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3245} +\noindent\mdline{3245}The following \mdline{3245}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3245} message can be used to add 2 entries:%mdk + +%mdk-data-line={3246} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3247} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{~{\mdcolor{darkgreen}\#~don't~care~entry}\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +~~table~entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~match~\{\\ +~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~lpm~\{\\ +~~~~~~~~value:~{\mdcolor{purple}0x0a000000}\\ +~~~~~~~~prefix\_len:~{\mdcolor{purple}8}\\ +~~~~~~\}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3266} +\noindent\mdline{3266}The first entry is a \mdline{3266}\textquotedblleft{}don't care\textquotedblright{}\mdline{3266} entry, while the second one matches all +\mdline{3267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}10.0.0.0/8}}}\mdline{3267} addresses. The second entry has higher priority than the first one.%mdk + +%mdk-data-line={3269} +\mdline{3269}The following \mdline{3269}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3269} message will return \mdline{3269}\emph{all}\mdline{3269} entries in the table, not +just the \mdline{3270}\textquotedblleft{}don't care\textquotedblright{}\mdline{3270} entry.%mdk + +%mdk-data-line={3271} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3272} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3280} +\noindent\mdline{3280}This issue also exists for tables with \mdline{3280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3280}, \mdline{3280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3280}, and \mdline{3280}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3280} +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the \mdline{3283}\textquotedblleft{}don't care\textquotedblright{}\mdline{3283} entry will be returned to the +client. If the client uses distinct priority values for all entries\mdline{3284} \mdline{3284}\textemdash{}\mdline{3284} which is +strongly recommended to achieve\mdline{3285}~\mdref{sec-table-entry}{deterministic behavior}\mdline{3285} \mdline{3285}\textemdash{}\mdline{3285}, +then there is no ambiguity because the wildcard read will actually return a +single entry (the \mdline{3287}\textquotedblleft{}don't care\textquotedblright{}\mdline{3287} entry) as long as the \mdline{3287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3287} field is set to +the correct value.%mdk + +%mdk-data-line={3290} +\subsubsection{\mdline{3290}9.1.6.\hspace*{0.5em}\mdline{3290}Direct Resources}\label{sec-direct-resources}%mdk%mdk + +%mdk-data-line={3292} +\noindent\mdline{3292}In addition to the \mdline{3292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3292} and \mdline{3292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3292} entities, +P4Runtime support reading and writing direct resources as part of the +\mdline{3294}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3294} message. This is convenient for two reasons:%mdk + +%mdk-data-line={3296} +\begin{itemize}%mdk + +%mdk-data-line={3296} +\item{} +%mdk-data-line={3296} +\mdline{3296}A table entry and its direct resources can be read with a single entity when +doing a \mdline{3297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{3297} RPC call%mdk%mdk + +%mdk-data-line={3299} +\item{} +%mdk-data-line={3299} +\mdline{3299}The initial configuration for an entry\mdline{3299}'\mdline{3299}s direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can \mdline{3304}\textquotedblleft{}hit\textquotedblright{}\mdline{3304} the table entry without +executing the appropriate meter entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3307} +\noindent\mdline{3307}Once the table entry has been inserted, the P4Runtime client is free to use the +\mdline{3308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3308} and \mdline{3308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3308} messages for read and write +operations on \mdline{3309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3309} and \mdline{3309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3309} instances. For example, it is +usually more convenient as well as more efficient to use \mdline{3310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3310} to +query a counter entry value rather than use \mdline{3311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3311}, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry.%mdk + +%mdk-data-line={3315} +\mdline{3315}The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does \mdline{3316}\emph{not}\mdline{3316} need to be \mdline{3316}\textquotedblleft{}executed\textquotedblright{}\mdline{3316} in +every action bound to the table. It is an error to provide a direct resource +configuration in a \mdline{3318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3318} message when programming an action that does not +execute the direct resource, and the server must return an \mdline{3319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3319} +error code.%mdk + +%mdk-data-line={3322} +\mdline{3322}We leverage Protobuf\mdline{3322}'\mdline{3322}s ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the \mdline{3324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3324} message. The list below describes how +the server must handle the \mdline{3325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3325}, \mdline{3325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3325} and +\mdline{3326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3326} fields for read and write requests, based on whether the +fields are set or not. We do not cover error cases in the list, \mdline{3327}i.e.\mdline{3327} we assume +that we are dealing with a table which is assigned a direct counter / a direct +meter, and that the action being used for the table entry \mdline{3329}\textquotedblleft{}executes\textquotedblright{}\mdline{3329} the direct +resource appropriately.%mdk + +%mdk-data-line={3332} +\begin{itemize}%mdk + +%mdk-data-line={3332} +\item{} +%mdk-data-line={3332} +\mdline{3332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3332} field%mdk + +%mdk-data-line={3333} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3333} +\item\mdline{3333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3333} + +%mdk-data-line={3334} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3334} +\item\mdline{3334}if \mdline{3334}\textbf{unset}\mdline{3334}: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets).%mdk + +%mdk-data-line={3336} +\item\mdline{3336}if \mdline{3336}\textbf{set}\mdline{3336}: The initial configuration for the meter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3338} +\item\mdline{3338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3338} + +%mdk-data-line={3339} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3339} +\item\mdline{3339}if \mdline{3339}\textbf{unset}\mdline{3339}: The meter entry\mdline{3339}'\mdline{3339}s configuration is reset to the default +(meter returns GREEN for all packets).%mdk + +%mdk-data-line={3341} +\item\mdline{3341}if \mdline{3341}\textbf{set}\mdline{3341}: The value provided by the client is used to re-configure +the meter entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3343} +\item\mdline{3343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3343} + +%mdk-data-line={3344} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3344} +\item\mdline{3344}if \mdline{3344}\textbf{unset}\mdline{3344}: The response does not include the meter entry\mdline{3344}'\mdline{3344}s +configuration (\mdline{3345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3345} is unset in the response).%mdk + +%mdk-data-line={3346} +\item\mdline{3346}if \mdline{3346}\textbf{set}\mdline{3346}: If the meter entry\mdline{3346}'\mdline{3346}s configuration is the default +configuration, \mdline{3347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3347} is unset in the response. Otherwise, the +response includes the meter entry\mdline{3348}'\mdline{3348}s configuration that was written by +the client earlier. This respects the \mdline{3349}\textquotedblleft{}read-write symmetry\textquotedblright{}\mdline{3349} principle.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3351} +\item{} +%mdk-data-line={3351} +\mdline{3351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3351} field%mdk + +%mdk-data-line={3352} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3352} +\item\mdline{3352}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3352} + +%mdk-data-line={3353} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3353} +\item\mdline{3353}if \mdline{3353}\textbf{unset}\mdline{3353}: The initial value for the counter entry is the default +(0).%mdk + +%mdk-data-line={3355} +\item\mdline{3355}if \mdline{3355}\textbf{set}\mdline{3355}: The initial value for the counter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3357} +\item\mdline{3357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3357} + +%mdk-data-line={3358} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3358} +\item\mdline{3358}if \mdline{3358}\textbf{unset}\mdline{3358}: The counter entry\mdline{3358}'\mdline{3358}s value is not changed.%mdk + +%mdk-data-line={3359} +\item\mdline{3359}if \mdline{3359}\textbf{set}\mdline{3359}: The value provided by the client is written to the counter +entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3361} +\item\mdline{3361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3361} + +%mdk-data-line={3362} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3362} +\item\mdline{3362}if \mdline{3362}\textbf{unset}\mdline{3362}: The response does not include the counter entry\mdline{3362}'\mdline{3362}s value +(\mdline{3363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3363} is unset in the response).%mdk + +%mdk-data-line={3364} +\item\mdline{3364}if \mdline{3364}\textbf{set}\mdline{3364}: The response includes the counter entry\mdline{3364}'\mdline{3364}s value read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3367} +\item{} +%mdk-data-line={3367} +\mdline{3367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3367} field%mdk + +%mdk-data-line={3368} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3368} +\item\mdline{3368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3368} + +%mdk-data-line={3369} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3369} +\item\mdline{3369}if \mdline{3369}\textbf{unset}\mdline{3369}: The initial value for all 3 counter entries is the +default (0).%mdk + +%mdk-data-line={3371} +\item\mdline{3371}if \mdline{3371}\textbf{set}\mdline{3371}: The initial value for all 3 counter entries is the +default (0). Sub-field, if any, can only have zero (0) as its value. +\mdline{3373}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3373} error is returned for any non-zero sub-field value.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3374} +\item\mdline{3374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3374} + +%mdk-data-line={3375} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3375} +\item\mdline{3375}if \mdline{3375}\textbf{unset}\mdline{3375}: All the 3 counter entries are unchanged.%mdk + +%mdk-data-line={3376} +\item\mdline{3376}if \mdline{3376}\textbf{set}\mdline{3376}: All the 3 counters are reset to 0. Sub-field, if any, can +only have zero (0) as its value. \mdline{3377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3377} error is returned +for any non-zero sub-field value.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3379} +\item\mdline{3379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3379} + +%mdk-data-line={3380} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3380} +\item\mdline{3380}if \mdline{3380}\textbf{unset}\mdline{3380}: The response does not include counter values +(\mdline{3381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3381} is unset in the response).%mdk + +%mdk-data-line={3382} +\item\mdline{3382}if \mdline{3382}\textbf{set}\mdline{3382}: The response includes all the 3 counter values read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3385} +\noindent\mdline{3385}In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +\mdline{3387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3387} field unset when inserting \mdline{3387}\textbf{or modifying}\mdline{3387} a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the \mdline{3389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3389} message +(\mdline{3390}i.e.\mdline{3390} the \mdline{3390}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3390} field must be set to match the existing configuration).%mdk + +%mdk-data-line={3392} +\subsubsection{\mdline{3392}9.1.7.\hspace*{0.5em}\mdline{3392}Idle-timeout}\label{sec-idle-timeout}%mdk%mdk + +%mdk-data-line={3394} +\noindent\mdline{3394}P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not \mdline{3396}\textquotedblleft{}hit\textquotedblright{}\mdline{3396} (\mdline{3396}i.e.\mdline{3396} not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification\mdline{3398} \mdline{3398}\textemdash{}\mdline{3398} using the +\mdline{3399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3399} message\mdline{3399} \mdline{3399}\textemdash{}\mdline{3399} to the primary client, which can then take +action, such as remove the idle table entry.%mdk + +%mdk-data-line={3402} +\mdline{3402}Two fields of the \mdline{3402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3402} Protobuf message are used to implement idle +timeout:%mdk + +%mdk-data-line={3405} +\begin{itemize}%mdk + +%mdk-data-line={3405} +\item{} +%mdk-data-line={3405} +\mdline{3405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3405}: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, \mdline{3406}i.e.\mdline{3406} no +\mdline{3407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3407} message will ever be generated for this entry. When +a client reads a \mdline{3408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3408}, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry.%mdk%mdk + +%mdk-data-line={3412} +\item{} +%mdk-data-line={3412} +\mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3412}: a Protobuf message with a single field (\mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{3412}) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The \mdline{3414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3414} field must be unset for a +\mdline{3415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3415} write. When reading a table entry, \mdline{3415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3415} must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3420} +\noindent\mdline{3420}These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an \mdline{3422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3422} error code if at least one of these +conditions is met:%mdk + +%mdk-data-line={3425} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3425} +\item\mdline{3425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3425} is set to a non-zero value, or%mdk + +%mdk-data-line={3426} +\item\mdline{3426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3426} is set%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3428} +\noindent\mdline{3428}The target should do its best to approximate the \mdline{3428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3428} value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the \mdline{3431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3431} write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for \mdline{3433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3433}.%mdk + +%mdk-data-line={3435} +\mdline{3435}P4Runtime does not support idle timeout for default entries. When the +\mdline{3436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3436} flag is set in a \mdline{3436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3436} message, \mdline{3436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3436} +must be set to 0 (default) and \mdline{3437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3437} must be unset. If the +server receives a \mdline{3438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3438} message which violates this, it must return an +\mdline{3439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3439} error.%mdk + +%mdk-data-line={3441} +\mdline{3441}For more information about idle timeout, in particular regarding +\mdline{3442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3442}, please refer to the\mdline{3442}~\mdref{sec-table-idle-timeout-notification}{Table idle timeout +notifications}\mdline{3443} section.%mdk + +%mdk-data-line={3445} +\subsection{\mdline{3445}9.2.\hspace*{0.5em}\mdline{3445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3445} \mdline{3445}\&\mdline{3445} \mdline{3445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}\label{sec-action-profile-member-and-group}%mdk%mdk + +%mdk-data-line={3447} +\noindent\mdline{3447}P4Runtime defines an API for programming a PSA ActionProfile extern using +\mdline{3448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3448} messages. A PSA ActionSelector extern can be programmed +using both \mdline{3449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3449} and \mdline{3449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3449} messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table \mdline{3453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3453} for L3 routing, implemented with an action +selector \mdline{3454}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3454}.%mdk + +%mdk-data-line={3456} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3457} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector(HashAlgorithm.crc32,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}size~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w1024,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}output\_width~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w10)~as;\\ +\\ +{\bfseries{\mdcolor{navy}action}}~set\_nhop(PortId\_t~p,~EthAddr~smac,~EthAddr~dmac)~\{\\ +~~istd.egress\_port~=~p;\\ +~~hdr.ethernet.smac~=~smac;\\ +~~hdr.ethernet.dmac~=~dmac;\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;~~{\mdcolor{darkgreen}//~LPM~on~destination~IP~address}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~set\_nhop;\\ +~~\}\\ +~~implementation~=~as;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3478} +\noindent\mdline{3478}When programming table \mdline{3478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3478} in the example above, a P4Runtime client should +specify the \mdline{3479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3479} in the \mdline{3479}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3479} to be a reference to either an +action profile member or group. The reference is a non-zero \mdline{3480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3480} identifier +that uniquely identifies a member or group programmed in the action selector +\mdline{3482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3482}.%mdk + +%mdk-data-line={3484} +\mdline{3484}If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata.%mdk + +%mdk-data-line={3489} +\mdline{3489}If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata.%mdk + +%mdk-data-line={3500} +\subsubsection{\mdline{3500}9.2.1.\hspace*{0.5em}\mdline{3500}Action Profile Member Programming}\label{sec-action-profile-member-programming}%mdk%mdk + +%mdk-data-line={3502} +\noindent\mdline{3502}Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a \mdline{3503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3503} identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the \mdline{3505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3505} +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the \mdline{3507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3507} attributes of the +tables \mdline{3508}\emph{must have an identical list of P4 actions}\mdline{3508}. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector.%mdk + +%mdk-data-line={3512} +\mdline{3512}An \mdline{3512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3512} entity update message has the following fields:%mdk + +%mdk-data-line={3514} +\begin{itemize}%mdk + +%mdk-data-line={3514} +\item{} +%mdk-data-line={3514} +\mdline{3514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3514} is the \mdline{3514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3514} identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3517} +\item{} +%mdk-data-line={3517} +\mdline{3517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3517} is the non-zero \mdline{3517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3517} identifier of the action profile member +entry being updated.%mdk%mdk + +%mdk-data-line={3520} +\item{} +%mdk-data-line={3520} +\mdline{3520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3520} is the specification of the P4 action instance bound to the action +profile member entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3523} +\noindent\mdline{3523}An action profile member may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3526} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3526} +\item\mdline{3526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3526}: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an \mdline{3528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3528} error +code. The action specification must be provided, or the server must return +\mdline{3530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3530}. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return \mdline{3532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3532}.%mdk + +%mdk-data-line={3533} +\item\mdline{3533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3533}: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return \mdline{3534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3534}, +and the action specification must be provided, or the server must return +\mdline{3536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3536}.%mdk + +%mdk-data-line={3537} +\item\mdline{3537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3537}: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a \mdline{3538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3538} error code. The member +must not be part of an action profile group, or the server must return +\mdline{3540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3540}. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return \mdline{3543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3543}. \mdline{3543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3543} and \mdline{3543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3543} are the only +fields that are considered when performing a \mdline{3544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3544} and every other field +will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3547} +\noindent\mdline{3547}When reading, an \mdline{3547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3547} message with \mdline{3547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3547} and +\mdline{3548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3548} equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with \mdline{3549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3549} equal to the id of +an existing ActionProfile or ActionSelector object, and a \mdline{3550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3550} equal to +0, will read all members of that specified object.%mdk + +%mdk-data-line={3553} +\subsubsection{\mdline{3553}9.2.2.\hspace*{0.5em}\mdline{3553}Action Profile Group Programming}\label{sec-action-profile-group-programming}%mdk%mdk + +%mdk-data-line={3555} +\noindent\mdline{3555}Action profile groups are entries in an ActionSelector and are referenced by a +\mdline{3556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3556} identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type.%mdk + +%mdk-data-line={3560} +\mdline{3560}Within a single ActionSelector object, the \mdline{3560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3560} values used to identify its +members are in a separate \mdline{3561}\textquoteleft{}scope\textquoteright{}\mdline{3561} from the \mdline{3561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3561} values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5.%mdk + +%mdk-data-line={3565} +\mdline{3565}There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it.%mdk + +%mdk-data-line={3571} +\mdline{3571}An \mdline{3571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3571} entity update message has the following fields:%mdk + +%mdk-data-line={3573} +\begin{itemize}%mdk + +%mdk-data-line={3573} +\item{} +%mdk-data-line={3573} +\mdline{3573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3573} is the \mdline{3573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3573} identifier of the PSA ActionSelector +extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3576} +\item{} +%mdk-data-line={3576} +\mdline{3576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3576} is the non-zero \mdline{3576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3576} identifier of the action profile group +entry being updated.%mdk%mdk + +%mdk-data-line={3579} +\item{} +%mdk-data-line={3579} +\mdline{3579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3579} is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields:%mdk + +%mdk-data-line={3582} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3582} +\item\mdline{3582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3582} for looking up the member table in the selector.%mdk + +%mdk-data-line={3583} +\item\mdline{3583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3583} specifying the probability of the member\mdline{3583}'\mdline{3583}s selection at +runtime. 0 is not a valid \mdline{3584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3584} value and the server must return +\mdline{3585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3585} if the client attempts to use it.%mdk + +%mdk-data-line={3586} +\item\mdline{3586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3586} is the controller-defined port that the member\mdline{3586}'\mdline{3586}s +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +\mdline{3589}\mdref{action-selector-constraints}{9.2.4}\mdline{3589} for notes on the behavior if all members in +a group are excluded for this reason. If \mdline{3590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3590} is empty, then the +member is always included in the selection, regardless of the status of +any port of the device. The value must be empty or the SDN port of an +existing port on the device, otherwise the server must return +\mdline{3594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3594}.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3596} +\item{} +%mdk-data-line={3596} +\mdline{3596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3596} is the maximum sum of all member weights for the group. This field +is defined when the group is inserted, and must not be changed in a +\mdline{3598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3598} update. See the subsection below for the\mdline{3598}~\mdref{sec-max-size-rules}{rules on setting +\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\mdline{3599}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3601} +\noindent\mdline{3601}An action profile group may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3604} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3604} +\item\mdline{3604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3604}: Add a new group entry bound to a set of existing action profile +members. \mdline{3605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}The~group\_id}}}\mdline{3605} must be different from ids of already programmed +groups for that selector, or the server must return an \mdline{3606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3606} error +code. All members specified in the group must exist in the selector, or the +server must return \mdline{3608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3608}. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target.%mdk + +%mdk-data-line={3610} +\item\mdline{3610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3610}: Modify the member set specification of an existing group entry. An +entry with the \mdline{3611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3611} must exist, or the server must return +\mdline{3612}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3612}. All members specified in the group entry must exist in the +selector, or the server must return \mdline{3613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3613}. The value of \mdline{3613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3613} must +be identical to the value used when inserting the group, otherwise an +\mdline{3615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3615} error is returned.%mdk + +%mdk-data-line={3616} +\item\mdline{3616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3616}: Delete the group entry and deallocate the \mdline{3616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3616}. The group must +not be referenced in the table action of any table entry, or the server must +return a \mdline{3618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3618} error code. If the \mdline{3618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3618} is invalid, the +server must return \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3619}. \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3619} and \mdline{3619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3619} are the +only fields that are considered when performing a \mdline{3620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3620} and every other +field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3623} +\noindent\mdline{3623}When setting the group membership with \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3623} or \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3623}, the \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3623} +repeated field must not include duplicates, \mdline{3624}i.e.\mdline{3624} members with the same +\mdline{3625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3625}. The \mdline{3625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3625} field is used instead to logically \mdline{3625}\textquotedblleft{}repeat\textquotedblright{}\mdline{3625} the member +inside the group.%mdk + +%mdk-data-line={3628} +\mdline{3628}It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation \mdline{3629}\textquotedblleft{}stores\textquotedblright{}\mdline{3629} the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made.%mdk + +%mdk-data-line={3633} +\mdline{3633}When reading, an \mdline{3633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3633} message with \mdline{3633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3633} and +\mdline{3634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3634} equal to 0 will read all groups of all ActionSelector objects. A +message with \mdline{3635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3635} equal to the id of an existing ActionSelector +object, and a \mdline{3636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3636} equal to 0, will read all groups of that one specified +object.%mdk + +%mdk-data-line={3639} +\paragraph{\mdline{3639}9.2.2.1.\hspace*{0.5em}\mdline{3639}Rules on Setting \mdline{3639}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\label{sec-max-size-rules}%mdk%mdk + +%mdk-data-line={3641} +\noindent\mdline{3641}The valid values for \mdline{3641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3641} depend on the static \mdline{3641}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3641} included +in the P4Info message:%mdk + +%mdk-data-line={3644} +\begin{itemize}%mdk + +%mdk-data-line={3644} +\item{} +%mdk-data-line={3644} +\mdline{3644}If \mdline{3644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3644} is greater than 0, then \mdline{3644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3644} must be greater than 0, +and less than or equal to \mdline{3645}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3645}. We assume that the target can +support selector groups for which the sum of all member weights is up to +\mdline{3647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3647}, or the P4Runtime server would have rejected the Forwarding +Pipeline Config. If \mdline{3648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3648} is greater than \mdline{3648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3648}, the server +must return \mdline{3649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3649}.%mdk%mdk + +%mdk-data-line={3651} +\item{} +%mdk-data-line={3651} +\mdline{3651}Otherwise (\mdline{3651}i.e.\mdline{3651} if \mdline{3651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3651} is 0), the P4Runtime client can set +\mdline{3652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3652} to any value greater than or equal to 0.%mdk + +%mdk-data-line={3654} +\begin{itemize}%mdk + +%mdk-data-line={3654} +\item{} +%mdk-data-line={3654} +\mdline{3654}A \mdline{3654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3654} of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (\mdline{3657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3657} or \mdline{3657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3657}), the target must return a +\mdline{3658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3658} error.%mdk%mdk + +%mdk-data-line={3660} +\item{} +%mdk-data-line={3660} +\mdline{3660}If \mdline{3660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3660} is greater than 0 and the value is not supported by the +target, the server must return a \mdline{3661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3661} error at +group-creation time.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3664} +\subsubsection{\mdline{3664}9.2.3.\hspace*{0.5em}\mdline{3664}One Shot Action Selector Programming}\label{sec-oneshot}%mdk%mdk + +%mdk-data-line={3666} +\noindent\mdline{3666}P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids.%mdk + +%mdk-data-line={3672} +\mdline{3672}One shots are programmed by choosing the \mdline{3672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3672} message as the +\mdline{3673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3673}. The \mdline{3673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3673} message consists of a set of +\mdline{3674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3674} messages, which in turn have the following fields:%mdk + +%mdk-data-line={3676} +\begin{itemize}%mdk + +%mdk-data-line={3676} +\item{} +%mdk-data-line={3676} +\mdline{3676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3676} is one of the actions specified by the table that is being +programmed.%mdk%mdk + +%mdk-data-line={3679} +\item{} +%mdk-data-line={3679} +\mdline{3679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3679} specifying the probability of the action\mdline{3679}'\mdline{3679}s selection at runtime. 0 is +not a valid \mdline{3680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3680} value and the server must return \mdline{3680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3680} if +the client attempts to use it. The sum of all weights across all +\mdline{3682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3682} messages for that \mdline{3682}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3682} message must +not exceed the \mdline{3683}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3683} specificed in the P4Info (if greater than 0), +or the server must return \mdline{3684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3684}.%mdk%mdk + +%mdk-data-line={3686} +\item{} +%mdk-data-line={3686} +\mdline{3686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3686} is the controller-defined port that the action\mdline{3686}'\mdline{3686}s liveness depends +on. At runtime, the action must be excluded from selection if the watch port +is down. See Section\mdline{3688}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{3688} for more details +on the \mdline{3689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3689} field, which also apply for one shot action selector +programming.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3693} +\noindent\mdline{3693}Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics.%mdk + +%mdk-data-line={3698} +\mdline{3698}To preserve read-write symmetry, an implementation must answer \mdline{3698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3698}s +with the original one shot messages. It may not return a desugared version of +the one shot message.%mdk + +%mdk-data-line={3702} +\mdline{3702}For example, consider the action selector table defined +\mdline{3703}\mdref{sec-action-profile-member-and-group}{here}\mdline{3703}. This table could be programmed +with the following one shot update:%mdk + +%mdk-data-line={3706} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3707} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{\\ +~~~~action\_profile\_action\_set~\{\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}1}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x01}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}2}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x02}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}3}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x03}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3732} +\noindent\mdline{3732}Which would be equivalent to the following updates, where \mdline{3732}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GROUP\_ID}}}\mdline{3732}, +\mdline{3733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_1}}}\mdline{3733}, \mdline{3733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_2}}}\mdline{3733}, and \mdline{3733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_3}}}\mdline{3733} are unused ids:%mdk + +%mdk-data-line={3735} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3736} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_1\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_2\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_3\\ +~~action~\{~~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +\}\\ +action\_profile\_group~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~group\_id:~GROUP\_ID\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_1\\ +~~~~weight:~{\mdcolor{purple}1}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x01}{\mdcolor{maroon}"}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_2\\ +~~~~weight:~{\mdcolor{purple}2}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x02}{\mdcolor{maroon}"}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_3\\ +~~~~weight:~{\mdcolor{purple}3}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x03}{\mdcolor{maroon}"}\\ +~~\}\\ +\}\\ +table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{~action\_profile\_group\_id:~GROUP\_ID~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3777} +\noindent\mdline{3777}Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure\mdline{3778}~\mdref{sec-batching-and-ordering-of-updates}{correct ordering between the dependent +updates}\mdline{3779}. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct \mdline{3781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3781} batches are required.%mdk + +%mdk-data-line={3783} +\mdline{3783}It is possible to include several \mdline{3783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3783} messages with the same +exact \mdline{3784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3784} specification in one \mdline{3784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3784} message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the \mdline{3786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3786} field. Note that to preserve read-write symmetry, the server +must not coalesce multiple \mdline{3787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3787} messages with the same \mdline{3787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3787} +specification into one.%mdk + +%mdk-data-line={3790} +\mdline{3790}All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with \mdline{3791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3791} and +\mdline{3792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3792} messages. Programming some entries with one shots, and +other entries with \mdline{3793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3793} and \mdline{3793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3793} messages is +not allowed, and the server must return the error code \mdline{3794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3794} in +that case.%mdk + +%mdk-data-line={3797} +\mdline{3797}A P4Runtime server \mdline{3797}\emph{must}\mdline{3797} support the one shot style of programming tables with +an action selector implementation. Support for the \mdline{3798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3798} and +\mdline{3799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3799} style is \mdline{3799}\emph{optional}\mdline{3799}. If \mdline{3799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3799} and +\mdline{3800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3800} are not supported by a server, it must return an +\mdline{3801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3801} error for every \mdline{3801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3801} or \mdline{3801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3801} +message that it receives.%mdk + +%mdk-data-line={3804} +\subsubsection{\mdline{3804}9.2.4.\hspace*{0.5em}\mdline{3804}Constraints on action selector programming}\label{action-selector-constraints}%mdk%mdk + +%mdk-data-line={3806} +\noindent\mdline{3806}The PSA specification states that the following features are \mdline{3806}\emph{optional}\mdline{3806} in +action selector implementations\mdline{3807}~[\mdcite{psaactionselector}{22}]\mdline{3807}:%mdk + +%mdk-data-line={3809} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3809} +\item\mdline{3809}Support for non-empty groups where in the same group, different members are +bound to different actions.%mdk + +%mdk-data-line={3811} +\item\mdline{3811}Predictable data plane behavior when a matched table entry points to an empty +group.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={3814} +\noindent\mdline{3814}For 1., if a client tries to \mdline{3814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3814} or \mdline{3814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3814} a group with members bound to +different actions, the server should return \mdline{3815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3815} if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return \mdline{3821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3821} (modifying the action parameter values must be +supported, however).%mdk + +%mdk-data-line={3824} +\mdline{3824}PSA 1.1 introduces the \mdline{3824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3824} table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. \mdline{3828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3828} is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of \mdline{3831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3831} at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +\mdline{3833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3833}. Even when \mdline{3833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3833} is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of \mdline{3837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3837} mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming.%mdk + +%mdk-data-line={3842} +\mdline{3842}The PSA specification includes a discussion on how to implement +\mdline{3843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3843} in software in the P4Runtime server +\mdline{3844}[\mdcite{psaemptygroupactionappendix}{25}]\mdline{3844}.%mdk + +%mdk-data-line={3846} +\mdline{3846}If a P4Runtime implementation does support \mdline{3846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3846}, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down.%mdk + +%mdk-data-line={3850} +\mdline{3850}If a P4Runtime implementation does not support \mdline{3850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{3850}, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down.%mdk + +%mdk-data-line={3856} +\subsection{\mdline{3856}9.3.\hspace*{0.5em}\mdline{3856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3856} \mdline{3856}\&\mdline{3856} \mdline{3856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-counterentry-directcounterentry}%mdk%mdk + +%mdk-data-line={3858} +\noindent\mdline{3858}PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The \mdline{3860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3860} +P4Runtime message can be used for all three types of PSA counters\mdline{3861} \mdline{3861}\textemdash{}\mdline{3861} \mdline{3861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{3861}, +\mdline{3862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{3862} and \mdline{3862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3862} \mdline{3862}\textemdash{}\mdline{3862} and consists of the following fields:%mdk + +%mdk-data-line={3864} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3864} +\item\mdline{3864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3864} is an \mdline{3864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3864}, corresponding to the number of octets.%mdk + +%mdk-data-line={3865} +\item\mdline{3865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3865} is an \mdline{3865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3865}, corresponding to the number of packets.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3867} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3868} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterData~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~byte\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}int64}}~packet\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3874} +\noindent\mdline{3874}P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of \mdline{3875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{3875} and \mdline{3875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{3875} fields, which +is equivalent to specifying the counter type \mdline{3876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{3876}. Counters may +be defined as direct or indirect (indexed) instances.%mdk + +%mdk-data-line={3879} +\subsubsection{\mdline{3879}9.3.1.\hspace*{0.5em}\mdline{3879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-directcounterentry}%mdk%mdk + +%mdk-data-line={3881} +\noindent\mdline{3881}A direct counter is a direct resource associated with a \mdline{3881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3881} (see +\mdline{3882}\mdref{sec-direct-resources}{Direct Resources}\mdline{3882}). The \mdline{3882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3882} field of the +\mdline{3883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3883} message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +\mdline{3886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3886} message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed.%mdk + +%mdk-data-line={3889} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3890} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectCounterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3896} +\noindent\mdline{3896}A \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3896} may only include an \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3896} message of type \mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3896} with a +\mdline{3897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3897}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={3899} +\begin{itemize}%mdk + +%mdk-data-line={3899} +\item{} +%mdk-data-line={3899} +\mdline{3899}the \mdline{3899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3899} field must match \mdline{3899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry.match}}}\mdline{3899} of the table entry +to which this direct counter entry is associated. If a matching \mdline{3900}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3900} +is not found, the server returns the error code \mdline{3901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3901}.%mdk%mdk + +%mdk-data-line={3903} +\item{} +%mdk-data-line={3903} +\mdline{3903}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3903} is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3907} +\noindent\mdline{3907}Specifying \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3907} in an \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{3907} message of type \mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3907} or +\mdline{3908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3908} is not allowed, and the server must return the error code +\mdline{3909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3909} in that case.%mdk + +%mdk-data-line={3911} +\mdline{3911}A client may use \mdline{3911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3911} in two ways to read the contents of a +\mdline{3912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3912}:%mdk + +%mdk-data-line={3914} +\begin{itemize}%mdk + +%mdk-data-line={3914} +\item{} +%mdk-data-line={3914} +\mdline{3914}As a direct resource associated with a table entry, request the server to +return the counter value in the \mdline{3915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3915} field of the \mdline{3915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3915} message +(see\mdline{3916}~\mdref{sec-direct-resources}{Direct resources}\mdline{3916}).%mdk%mdk + +%mdk-data-line={3918} +\item{} +%mdk-data-line={3918} +\mdline{3918}Explicitly request the counter value by including the \mdline{3918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3918} in +the \mdline{3919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3919}. The \mdline{3919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{3919} field must match the \mdline{3919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3919} +whose counter is being read. If no such entry is found, the server returns the +error code \mdline{3921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3921}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3923} +\subsubsection{\mdline{3923}9.3.2.\hspace*{0.5em}\mdline{3923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}\label{sec-counterentry}%mdk%mdk + +%mdk-data-line={3925} +\noindent\mdline{3925}An indirect or indexed counter is not associated with a specific \mdline{3925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3925} +and may be updated independently of any action. It may be read or written using +the P4Runtime \mdline{3927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3927} message whose fields are defined as follows:%mdk + +%mdk-data-line={3929} +\begin{itemize}%mdk + +%mdk-data-line={3929} +\item{} +%mdk-data-line={3929} +\mdline{3929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3929} is a \mdline{3929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3929}, the unique identifier for the counter.%mdk%mdk + +%mdk-data-line={3931} +\item{} +%mdk-data-line={3931} +\mdline{3931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3931} is a Protobuf message that encapsulates an \mdline{3931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{3931}, used to index into +the counter array.%mdk%mdk + +%mdk-data-line={3934} +\item{} +%mdk-data-line={3934} +\mdline{3934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3934} is a Protobuf message of type \mdline{3934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{3934}, which represents the +counter value.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3937} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3938} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~counter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3945} +\noindent\mdline{3945}The \mdline{3945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3945} can only be used in a \mdline{3945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3945} with the \mdline{3945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3945} update +type. The P4Runtime server must return an \mdline{3946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3946} error code for +update types \mdline{3947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3947} and \mdline{3947}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3947}. By default all the counter entries in the +array have default value 0.%mdk + +%mdk-data-line={3950} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3950} +\item\mdline{3950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3950}: Server returns the error code \mdline{3950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3950}.%mdk + +%mdk-data-line={3951} +\item\mdline{3951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3951}: Modify an indirect counter instance whose unique id is \mdline{3951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3951} +and array index is specified by \mdline{3952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3952}. The counter value is set to the value +specified by the client in the \mdline{3953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{3953} field. Note that the counter value is +not modified if this Protobuf field is not set. If \mdline{3954}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3954} is omitted all +counter values in the array will be set to the value provided by the +client. The server must return \mdline{3956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3956} for a negative index value +and \mdline{3957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{3957} if the index value exceeds the size of the counter array.%mdk + +%mdk-data-line={3958} +\item\mdline{3958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3958}: Server returns the error code \mdline{3958}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3958}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3960} +\noindent\mdline{3960}A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a \mdline{3961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3961} by including a \mdline{3961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{3961} +entity for each of the instances, specifying the \mdline{3962}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3962} and +\mdline{3963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3963}. Wildcard reads are also supported as follows.%mdk + +%mdk-data-line={3965} +\begin{itemize}%mdk + +%mdk-data-line={3965} +\item{} +%mdk-data-line={3965} +\mdline{3965}If the \mdline{3965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3965} field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the \mdline{3966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{3966}.%mdk%mdk + +%mdk-data-line={3968} +\item{} +%mdk-data-line={3968} +\mdline{3968}If the \mdline{3968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{3968} field is not set, the server returns the counter values for all +indirect counters in the array identified by the unique id \mdline{3969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{3969}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3971} +\subsection{\mdline{3971}9.4.\hspace*{0.5em}\mdline{3971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3971} \mdline{3971}\&\mdline{3971} \mdline{3971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-meterentry-directmeterentry}%mdk%mdk + +%mdk-data-line={3973} +\noindent\mdline{3973}Meters are an advanced mechanism for keeping statistics, involving stateful +\mdline{3974}\textquotedblleft{}marking\textquotedblright{}\mdline{3974} and usually \mdline{3974}\textquotedblleft{}throttling\textquotedblright{}\mdline{3974} of packets based on configured rates of +traffic. The PSA metering function is based on the \mdline{3975}\emph{Two Rate Three Color Marker}\mdline{3975} +(trTCM) defined in RFC 2698\mdline{3976}~[\mdcite{rfc2698}{2}]\mdline{3976}. The trTCM meters an arbitrary packet +stream using two configured rates\mdline{3977} \mdline{3977}\textemdash{}\mdline{3977} the Peak Information Rate (PIR) and +Committed Information Rate (CIR), and their associated burst sizes\mdline{3978} \mdline{3978}\textemdash{}\mdline{3978} and +\mdline{3979}\textquotedblleft{}marks\textquotedblright{}\mdline{3979} its packets as GREEN, YELLOW or RED based on the observed rate.%mdk + +%mdk-data-line={3981} +\mdline{3981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{3981} \mdline{3981}\&\mdline{3981} \mdline{3981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3981} have an additional field \mdline{3981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3981} that +may hold per color counter data for targets that support it, and that must +always be unset for targets that do not support it. If set in a request and +unsupported by a target, an \mdline{3984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3984} error code should be returned. +These counters provide a granular list of the counters applicable to the +possible meter colors GREEN, YELLOW and RED. The counter associated with a +specific color is incremented when a packet is \mdline{3987}\textquotedblleft{}marked\textquotedblright{}\mdline{3987} with that color. The +primary purpose of the color counters is for debugging purposes.%mdk + +%mdk-data-line={3990} +\mdline{3990}A meter may be configured as a direct or indirect instance, similar to a +counter. The \mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{3991} P4Runtime message represents meter configuration.%mdk + +%mdk-data-line={3993} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3994} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterConfig~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~cir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~Committed~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~cburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};~~{\mdcolor{darkgreen}//~Committed~Burst~Size}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};~~{\mdcolor{darkgreen}//~Peak~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};~~{\mdcolor{darkgreen}//~Peak~Burst~Size}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4002} +\subsubsection{\mdline{4002}9.4.1.\hspace*{0.5em}\mdline{4002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-directmeterentry}%mdk%mdk + +%mdk-data-line={4004} +\noindent\mdline{4004}A direct meter is a direct resource associated with a \mdline{4004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4004} (see\mdline{4004}~\mdref{sec-direct-resources}{Direct +resources}\mdline{4005}). The \mdline{4005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{4005} field of the \mdline{4005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4005} +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +\mdline{4009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4009} message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed.%mdk + +%mdk-data-line={4012} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4013} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectMeterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterCounterData~counter\_data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4020} +\noindent\mdline{4020}A \mdline{4020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4020} may only include an \mdline{4020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4020} message of type \mdline{4020}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4020} with a +\mdline{4021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4021}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={4023} +\begin{itemize}%mdk + +%mdk-data-line={4023} +\item{} +%mdk-data-line={4023} +\mdline{4023}the \mdline{4023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4023} field must match the match key of the \mdline{4023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4023} +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching \mdline{4025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4025} is not found, +the server returns the error code \mdline{4026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4026}.%mdk%mdk + +%mdk-data-line={4028} +\item{} +%mdk-data-line={4028} +\mdline{4028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4028} is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets).%mdk%mdk + +%mdk-data-line={4032} +\item{} +%mdk-data-line={4032} +\mdline{4032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4032} is used to set the per color counter values to the default +value of (0), which is essentially clearing the counters. If the field is +unset, the counter values are left untouched. If the field is set, targets +supporting these counters should reset all the color counters to (0), if any +of the sub-fields are set to a non-zero value, then an \mdline{4036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4036} +error should be returned.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4039} +\noindent\mdline{4039}Specifying \mdline{4039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4039} in an \mdline{4039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4039} message of type \mdline{4039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4039} or +\mdline{4040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4040} is not allowed, and the server must return the error code +\mdline{4041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4041} in that case.%mdk + +%mdk-data-line={4043} +\mdline{4043}A client may use \mdline{4043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4043} in two ways to read a \mdline{4043}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{4043} config.%mdk + +%mdk-data-line={4045} +\begin{itemize}%mdk + +%mdk-data-line={4045} +\item{} +%mdk-data-line={4045} +\mdline{4045}As a direct resource associated with a table entry, request the server to +return the meter config in the \mdline{4046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{4046} field of the \mdline{4046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4046} +message (see\mdline{4047}~\mdref{sec-direct-resources}{Direct resources}\mdline{4047}).%mdk%mdk + +%mdk-data-line={4049} +\item{} +%mdk-data-line={4049} +\mdline{4049}Explicitly request the meter configuration by including the \mdline{4049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4049} +in the \mdline{4050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4050}. The \mdline{4050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4050} field must match the +\mdline{4051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4051} whose meter config is being read. If no such entry is found, the +server returns the error code \mdline{4052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4052}. Read responses also include the +per color counter data for the meter entry, if supported and specified in +the request message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4056} +\subsubsection{\mdline{4056}9.4.2.\hspace*{0.5em}\mdline{4056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}\label{sec-meterentry}%mdk%mdk + +%mdk-data-line={4058} +\noindent\mdline{4058}An indirect or indexed meter is not associated with a specific \mdline{4058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4058} and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime \mdline{4060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4060} message whose fields are defined as +follows:%mdk + +%mdk-data-line={4063} +\begin{itemize}%mdk + +%mdk-data-line={4063} +\item{} +%mdk-data-line={4063} +\mdline{4063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4063} is a \mdline{4063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4063}, the unique identifier for the meter.%mdk%mdk + +%mdk-data-line={4065} +\item{} +%mdk-data-line={4065} +\mdline{4065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4065} is a Protobuf message that encapsulates an \mdline{4065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4065}, used to index into +a meter array.%mdk%mdk + +%mdk-data-line={4068} +\item{} +%mdk-data-line={4068} +\mdline{4068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4068} is a Protobuf message of type \mdline{4068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{4068}, which represents the +meter configuration.%mdk%mdk + +%mdk-data-line={4071} +\item{} +%mdk-data-line={4071} +\mdline{4071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4071} is a Protobuf message of type \mdline{4071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4071}, which +represents the per color counter values associated with the corresponding +meter.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4075} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4076} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~meter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~MeterCounterData~counter\_data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4084} +\noindent\mdline{4084}The \mdline{4084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4084} can only be used in a \mdline{4084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4084} with the \mdline{4084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4084} update +type. The P4Runtime server must return an \mdline{4085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4085} error code for +update types \mdline{4086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4086} and \mdline{4086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4086}. By default all the meter entries in the +array have a default configuration (GREEN for all packets).%mdk + +%mdk-data-line={4089} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4089} +\item\mdline{4089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4089}: Server returns the error code \mdline{4089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4089}.%mdk + +%mdk-data-line={4090} +\item\mdline{4090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4090}: Modify an indirect meter instance whose unique id is \mdline{4090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4090} and +array index is specified by \mdline{4091}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4091}. The meter is reconfigured using the +\mdline{4092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4092} field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the \mdline{4094}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4094} field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if \mdline{4096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4096} is unset). The server must return \mdline{4096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4096} for a +negative index value and \mdline{4097}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4097} if the index value exceeds the size of +the meter array.%mdk + +%mdk-data-line={4099} +\item\mdline{4099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4099}: Server returns the error code \mdline{4099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4099}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4101} +\noindent\mdline{4101}A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a \mdline{4102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4102} by including a \mdline{4102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4102} entity for each +of the instances, specifying the \mdline{4103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4103} and \mdline{4103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4103}. Wildcard reads are also +supported as follows:%mdk + +%mdk-data-line={4106} +\begin{itemize}%mdk + +%mdk-data-line={4106} +\item{} +%mdk-data-line={4106} +\mdline{4106}If the \mdline{4106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4106} field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the \mdline{4107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4107}.%mdk%mdk + +%mdk-data-line={4109} +\item{} +%mdk-data-line={4109} +\mdline{4109}If the \mdline{4109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4109} field is not set, the server returns the configuration for all +indirect meters in the array identified by the unique id \mdline{4110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4110}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4112} +\subsubsection{\mdline{4112}9.4.3.\hspace*{0.5em}\mdline{4112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}}\label{sec-metercounterdata}%mdk%mdk + +%mdk-data-line={4114} +\noindent\mdline{4114}The \mdline{4114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4114} P4Runtime message represents the per color counters +associated with a meter entry. Whenever a meter is executed and returns +a color, the corresponding color counter GREEN, YELLOW or RED is updated.%mdk + +%mdk-data-line={4118} +\mdline{4118}As seen above, these counters can be associated with a \mdline{4118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4118} or +\mdline{4119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4119}. Targets not capable of supporting these counters should return +\mdline{4120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4120} if a \mdline{4120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4120} field was set in a read or write +request.%mdk + +%mdk-data-line={4123} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4124} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterCounterData~\{\\ +~~CounterData~green~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~yellow~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~red~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4132} +\subsection{\mdline{4132}9.5.\hspace*{0.5em}\mdline{4132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}\label{sec-packetreplicationengineentry}%mdk%mdk + +%mdk-data-line={4134} +\noindent\mdline{4134}The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets.%mdk + +%mdk-data-line={4140} +\subsubsection{\mdline{4140}9.5.1.\hspace*{0.5em}\mdline{4140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}\label{sec-multicastgroupentry}%mdk%mdk + +%mdk-data-line={4142} +\noindent\mdline{4142}Multicasting is achieved in PSA programs by setting the \mdline{4142}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4142} +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the \mdline{4145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4145} API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example.%mdk + +%mdk-data-line={4150} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4151} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~arp\_multicast({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ethernet.isValid()~\&\&\\ +~~~~~~~~hdr.ethernet.eth\_type~==~ETH\_TYPE\_ARP)~\{\\ +~~~~~~smeta.multicast\_group~=~(MulticastGroup\_t)~{\mdcolor{purple}1};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4161} +\noindent\mdline{4161}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4164} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4165} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~multicast\_group\_entry~\{\\ +~~~~~~multicast\_group\_id:~{\mdcolor{purple}1}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}5}~instance:~{\mdcolor{purple}1}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}12}~instance:~{\mdcolor{purple}2}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}18}~instance:~{\mdcolor{purple}3}~\}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}24}~instance:~{\mdcolor{purple}4}~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4179} +\noindent\mdline{4179}As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +\mdline{4184}\mdref{sec-translation-of-port-numbers}{PSA Metadata Translation}\mdline{4184} section.%mdk + +%mdk-data-line={4186} +\mdline{4186}The egress packets may be distinguished for further processing in the egress +using the \mdline{4187}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4187} metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 \mdline{4189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4189} metadata is set to a value that is not +programmed in the PRE, then the packet is dropped.%mdk + +%mdk-data-line={4192} +\mdline{4192}A multicast group may be inserted, modified or deleted as per the following +semantics.%mdk + +%mdk-data-line={4195} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4195} +\item\mdline{4195}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4195}: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The \mdline{4196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4196} field is a \mdline{4196}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4196} and must be greater +than 0 (see explanation\mdline{4197}~\mdref{sec-valid-values-for-mg-id}{below}\mdline{4197}), or the +P4Runtime server must return an \mdline{4198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4198} error. The replica +\mdline{4199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4199} ID is also a \mdline{4199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4199}, and its value may not exceed the maximum +allowed by the target for the \mdline{4200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4200} type (0 is allowed), or the +server must return an \mdline{4201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4201} error. The egress port must be a +32-bit SDN port number and must refer to a singleton port. No two replicas may +have identical values of \mdline{4203}\emph{both}\mdline{4203} \mdline{4203}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{4203} and \mdline{4203}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4203}, or the server +must return \mdline{4204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4204}.%mdk + +%mdk-data-line={4205} +\item\mdline{4205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4205}: Modify the set of replicas for a given multicast group entry, +indexed by the given \mdline{4206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4206}. Same restrictions as \mdline{4206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4206} apply +here.%mdk + +%mdk-data-line={4208} +\item\mdline{4208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4208}: Delete the multicast group indexed by the given +\mdline{4209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4209}. The replicas need not be provided for this +operation. Any packets with their \mdline{4210}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4210} metadata in the data plane +set to the deleted \mdline{4211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4211} will be dropped.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4213} +\noindent\mdline{4213}When reading a multicast group, only \mdline{4213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4213} is considered. All +other fields in \mdline{4214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4214} are ignored. To perform a \mdline{4214}\emph{wildcard}\mdline{4214} +\mdline{4215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4215} on all configured multicast group entries, the \mdline{4215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4215} field +must be set to 0, its default value.%mdk + +%mdk-data-line={4218} +\paragraph{\mdline{4218}9.5.1.1.\hspace*{0.5em}\mdline{4218}Valid Values for \mdline{4218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}}\label{sec-valid-values-for-mg-id}%mdk%mdk + +%mdk-data-line={4220} +\noindent\mdline{4220}The PSA specification states that the valid \mdline{4220}\emph{data plane}\mdline{4220} values for multicast +group ids (\mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroup\_t}}}\mdline{4221}) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target\mdline{4223}~[\mdcite{psatranslation}{24}]\mdline{4223}. This means that, in the absence of +translation, the client must set the \mdline{4224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4224} field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special \mdline{4226}\emph{wildcard}\mdline{4226} value which is used to read all the multicast groups +configured in the target, the \mdline{4227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4227} field must never be set to 0 +when performing a \mdline{4228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4228} RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value.%mdk + +%mdk-data-line={4233} +\subsubsection{\mdline{4233}9.5.2.\hspace*{0.5em}\mdline{4233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}\label{sec-clonesessionentry}%mdk%mdk + +%mdk-data-line={4235} +\noindent\mdline{4235}PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +\mdline{4239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4239} identifier and a boolean flag \mdline{4239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone}}}\mdline{4239} in the packet +metadata. The \mdline{4240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4240} serves as a handle to the clone attributes, +namely a set \mdline{4241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}replicas}}}\mdline{4241} of \mdline{4241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(egress~port,~instance)}}}\mdline{4241} pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +\mdline{4244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4244} API.%mdk + +%mdk-data-line={4246} +\mdline{4246}The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the \mdline{4249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_low\_ttl}}}\mdline{4249} control block is applied in the ingress +pipeline to create an ingress-to-egress clone.%mdk + +%mdk-data-line={4252} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4253} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~clone\_low\_ttl({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ipv4.isValid()~\&\&\\ +~~~~~~~~hdr.ipv4.ttl~\textless{}=~LOW\_TTL\_THRESHOLD)~\{\\ +~~~~~~smeta.clone\_session\_id~=~{\mdcolor{purple}10}w100;\\ +~~~~~~smeta.clone~=~{\bfseries{\mdcolor{navy}true}};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4265} +\noindent\mdline{4265}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4268} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4269} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~clone\_session\_entry~\{\\ +~~~~~~session\_id:~{\mdcolor{purple}100}\\ +~~~~~~replicas~\{~egress\_port:~{\mdcolor{purple}0xfffffffd}~instance:~{\mdcolor{purple}1}~\}~{\mdcolor{darkgreen}\#~to~CPU}\\ +~~~~~~class\_of\_service:~{\mdcolor{purple}2}\\ +~~~~~~packet\_length\_bytes:~{\mdcolor{purple}4096}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4282} +\noindent\mdline{4282}As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type \mdline{4286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4286}~[\mdcite{psatranslation}{24}]\mdline{4286}). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes.%mdk + +%mdk-data-line={4291} +\mdline{4291}The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port \mdline{4292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfffffffd}}}\mdline{4292}; see +\mdline{4293}\mdref{sec-translation-of-port-numbers}{Translation of Port Numbers}\mdline{4293}). Note that the +egress port must be a 32-bit SDN port number and must refer to a singleton port.%mdk + +%mdk-data-line={4296} +\mdline{4296}If the \mdline{4296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4296} data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created.%mdk + +%mdk-data-line={4299} +\mdline{4299}A clone session may be inserted, modified or deleted as per the following +semantics:%mdk + +%mdk-data-line={4302} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4302} +\item\mdline{4302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4302}: Add a new clone session entry bound to a set of egress ports and +replica IDs. The \mdline{4303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4303} is a \mdline{4303}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4303} and must be greater than 0 (see +explanation\mdline{4304}~\mdref{sec-valid-values-for-session-id}{below}\mdline{4304}), or the P4Runtime +server must return an \mdline{4305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4305} error. The replica \mdline{4305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4305} ID is +also a \mdline{4306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4306}, and its value may not exceed the maximum allowed by the +target for the \mdline{4307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4307} type (0 is allowed), or the server must also +return an \mdline{4308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4308} error. The egress port in the replica must be a +32-bit SDN port number and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (\mdline{4311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}class\_of\_service}}}\mdline{4311} field). This value must be a valid +value for the PSA \mdline{4312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ClassOfService\_t}}}\mdline{4312} type, which supports runtime translation +by default\mdline{4313}~[\mdcite{psatranslation}{24}]\mdline{4313}, or the server must return +\mdline{4314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4314}. See\mdline{4314}~\mdref{sec-translation-of-port-numbers}{PSA Metadata +Translation}\mdline{4315} for more information. The +\mdline{4316}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4316} field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +\mdline{4318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4318} field is 0 (default), no truncation on the clone will be +performed.%mdk + +%mdk-data-line={4320} +\item\mdline{4320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4320}: Modify the attributes of a given clone session entry, indexed by the +given \mdline{4321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4321}. Same restrictions as \mdline{4321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4321} apply here.%mdk + +%mdk-data-line={4322} +\item\mdline{4322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4322}: Delete the clone session indexed by the given +\mdline{4323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4323}. Other fields need not be provided for this operation. Any +packet with their \mdline{4324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4324} metadata in the data plane set to the +deleted \mdline{4325}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4325} will no longer be cloned.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4327} +\noindent\mdline{4327}When reading a clone session, only \mdline{4327}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4327} is considered. All other fields +in \mdline{4328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4328} are ignored. To perform a \mdline{4328}\emph{wildcard}\mdline{4328} \mdline{4328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4328} on all +configured clone session entries, the \mdline{4329}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4329} field must be set to 0, its +default value. The \mdline{4330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4330} field can never be equal to 0 in a \mdline{4330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4330} +RPC. If it does, the server must return an \mdline{4331}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4331} error.%mdk + +%mdk-data-line={4333} +\paragraph{\mdline{4333}9.5.2.1.\hspace*{0.5em}\mdline{4333}Valid Values for \mdline{4333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}}\label{sec-valid-values-for-session-id}%mdk%mdk + +%mdk-data-line={4335} +\noindent\mdline{4335}The PSA specification states that the valid \mdline{4335}\emph{data plane}\mdline{4335} values for clone +session ids (\mdline{4336}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4336}) range from 0 to the maximum value supported by +the target\mdline{4337}~[\mdcite{psatranslation}{24}]\mdline{4337}. Note that unlike for\mdline{4337}~\mdref{sec-valid-values-for-mg-id}{multicast group +ids}\mdline{4338}, 0 is a valid \mdline{4338}\emph{data plane}\mdline{4338} value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special \mdline{4340}\emph{wildcard}\mdline{4340} value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a \mdline{4341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4341} +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is \mdline{4343}\emph{not}\mdline{4343} enabled, we effectively +\mdline{4344}\textquotedblleft{}lose\textquotedblright{}\mdline{4344} one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (\mdline{4345}e.g.\mdline{4345} because the target supports a very +limited number of clone sessions), one can enable translation on +\mdline{4347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4347} and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id.%mdk + +%mdk-data-line={4350} +\subsection{\mdline{4350}9.6.\hspace*{0.5em}\mdline{4350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}\label{sec-valuesetentry}%mdk%mdk + +%mdk-data-line={4352} +\noindent\mdline{4352}Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the \mdline{4356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4356} state.%mdk + +%mdk-data-line={4358} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4359} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}state}}~parse\_l2~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}(MAX\_TRILL\_TYPES)~trill\_types;}\\ +~~extract(hdr.ethernet);\\ +~~{\bfseries{\mdcolor{navy}select}}~(hdr.ethernet.eth\_type)~\{\\ +~~~~ETH\_TYPE\_IPV4:~parse\_ipv4;\\ +~~~~ETH\_TYPE\_IPV6:~parse\_ipv6;\\ +~~~~trill\_types:~~~parse\_trill\_types;\\ +~~~~\_:~~~~~~~~~~~~~reject;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4371} +\noindent\mdline{4371}The corresponding entry in the P4Info for this Value Set is:%mdk + +%mdk-data-line={4373} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4374} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}trill\_types}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~\textless{}MAX\_TRILL\_TYPES\textgreater{}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4388} +\noindent\mdline{4388}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4391} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4392} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x22f3}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x893b}~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4410} +\noindent\mdline{4410}As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the \mdline{4412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4412} state.%mdk + +%mdk-data-line={4414} +\mdline{4414}A \mdline{4414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4414} entity update message has the following fields:%mdk + +%mdk-data-line={4416} +\begin{itemize}%mdk + +%mdk-data-line={4416} +\item{} +%mdk-data-line={4416} +\mdline{4416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4416} is the \mdline{4416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4416} identifier of the Value Set instance, as +defined in P4Info.%mdk%mdk + +%mdk-data-line={4419} +\item{} +%mdk-data-line={4419} +\mdline{4419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4419} is a repeated field of type \mdline{4419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4419}. When \mdline{4419}\textquotedblleft{}selecting\textquotedblright{}\mdline{4419} +against a Value Set, every member will be considered and if at least one +\mdline{4421}\textquotedblleft{}matches\textquotedblright{}\mdline{4421}, the corresponding parser transition will be taken. Each +\mdline{4422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4422} contains a repeated field of \mdline{4422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4422} messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a \mdline{4424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4424} if and only if +it matches all its \mdline{4425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4425} messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. \mdline{4427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4427} messages in a \mdline{4427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4427} follow +the\mdline{4428}~\mdref{sec-match-format}{same rules}\mdline{4428} as in a \mdline{4428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4428}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4430} +\noindent\mdline{4430}A \mdline{4430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4430} may only be modified. If the update type is \mdline{4430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4430} or +\mdline{4431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4431}, the server must return an \mdline{4431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4431} error. If the update type +is \mdline{4432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4432}, the server writes the members given in the repeated field to the +Value Set entry indexed by the given \mdline{4433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4433}. The maximum number of +matches must not exceed the maximum size given by the \mdline{4434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{4434} field in P4Info of +the Value Set, otherwise the server must return a \mdline{4435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4435} error. To +empty a Value Set (\mdline{4436}i.e.\mdline{4436} restore it to its initial state), the P4Runtime client +can perform a \mdline{4437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4437} update with an empty \mdline{4437}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4437} repeated field.%mdk + +%mdk-data-line={4439} +\mdline{4439}To facilitate\mdline{4439}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{4439}, the server must +return an \mdline{4440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4440} error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set.%mdk + +%mdk-data-line={4446} +\mdline{4446}See Appendix\mdline{4446}~\mdref{sec-value-set-example}{A.3}\mdline{4446} for a more complex Value Set example.%mdk + +%mdk-data-line={4448} +\subsection{\mdline{4448}9.7.\hspace*{0.5em}\mdline{4448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}\label{sec-registerentry}%mdk%mdk + +%mdk-data-line={4450} +\noindent\mdline{4450}The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The \mdline{4451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4451} P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations.%mdk + +%mdk-data-line={4455} +\mdline{4455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4455} has the following fields:%mdk + +%mdk-data-line={4457} +\begin{itemize}%mdk + +%mdk-data-line={4457} +\item{} +%mdk-data-line={4457} +\mdline{4457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4457}, which identifies the PSA Register extern instance which is +being accessed by the client; the \mdline{4458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4458} is specified by the P4Info +message.%mdk%mdk + +%mdk-data-line={4461} +\item{} +%mdk-data-line={4461} +\mdline{4461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4461}, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4463} message +used for the request. When an \mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4464} is provided , the server must validate +its value, and return \mdline{4465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4465} for a negative index or +\mdline{4466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4466} if the index exceeds the size of the register array.%mdk%mdk + +%mdk-data-line={4468} +\item{} +%mdk-data-line={4468} +\mdline{4468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4468}: the data to be written to the array (if \mdline{4468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4468} is part of a +\mdline{4469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4469} message) or the data read from the array (if \mdline{4469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4469} is +part of a \mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4470} message). The \mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4470} field is a \mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{4470} message and +must match the format described by the \mdline{4471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{4471} field of the corresponding +Register entry in the P4Info, or the server must return an \mdline{4472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4472} +error.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4475} +\subsection{\mdline{4475}9.8.\hspace*{0.5em}\mdline{4475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}\label{sec-digestentry}%mdk%mdk + +%mdk-data-line={4477} +\noindent\mdline{4477}A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly.%mdk + +%mdk-data-line={4482} +\mdline{4482}The \mdline{4482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4482} P4Runtime entity is used to \mdline{4482}\textbf{configure}\mdline{4482} how the device must +generate digest messages. The \mdline{4483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4483} Protobuf message is not used to +carry digest data, which is done on the \mdline{4484}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4484} bidirectional stream +using the \mdline{4485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4485} (digest data sent by the target to the client) and +\mdline{4486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4486} (digest data acknowledgments sent by the client to the target) +Protobuf messages.%mdk + +%mdk-data-line={4489} +\mdline{4489}In this section, we refer to the data learned by a single data plane call to +\mdline{4490}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}T\textgreater{}::pack}}}\mdline{4490} as a \mdline{4490}\textquotedblleft{}digest message\textquotedblright{}\mdline{4490} and we use \mdline{4490}\textquotedblleft{}digest list\textquotedblright{}\mdline{4490} to designate +the list of digest messages bundled by the P4Runtime service in a single +\mdline{4492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4492} stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are \mdline{4494}\textquotedblleft{}duplicate\textquotedblright{}\mdline{4494} if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are \mdline{4495}\textquotedblleft{}distinct\textquotedblright{}\mdline{4495} +if they are not duplicate.%mdk + +%mdk-data-line={4498} +\mdline{4498}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4498} has the following fields:%mdk + +%mdk-data-line={4500} +\begin{itemize}%mdk + +%mdk-data-line={4500} +\item{} +%mdk-data-line={4500} +\mdline{4500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4500}, which identifies the PSA Digest extern instance which emitted the +data; the \mdline{4501}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4501} is determined by the P4Info message.%mdk%mdk + +%mdk-data-line={4503} +\item{} +%mdk-data-line={4503} +\mdline{4503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4503}, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +\mdline{4505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4505}; these parameters are:%mdk + +%mdk-data-line={4507} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4507} +\item\mdline{4507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4507}: the maximum server buffering delay in nanoseconds for an +outstanding digest message.%mdk + +%mdk-data-line={4509} +\item\mdline{4509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4509}: the maximum digest list size\mdline{4509} \mdline{4509}\textemdash{}\mdline{4509} in number of digest +messages\mdline{4510} \mdline{4510}\textemdash{}\mdline{4510} sent by the server to the client as a single \mdline{4510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4510} +Protobuf message.%mdk + +%mdk-data-line={4512} +\item\mdline{4512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4512}: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4516} +\noindent\mdline{4516}Here is the significance of the different \mdline{4516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4516} types for \mdline{4516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4516}:%mdk + +%mdk-data-line={4518} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4518} +\item\mdline{4518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4518}: Enable server generation of \mdline{4518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4518} messages for given digest +instance and use provided configuration parameters.%mdk + +%mdk-data-line={4520} +\item\mdline{4520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4520}: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance.%mdk + +%mdk-data-line={4522} +\item\mdline{4522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4522}: Disable server generation of \mdline{4522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4522} messages for given digest +instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4525} +\noindent\mdline{4525}A server should buffer digest messages until either:%mdk + +%mdk-data-line={4527} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4527} +\item\mdline{4527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4527} time has passed since the first digest message was added to +the empty buffer, or%mdk + +%mdk-data-line={4529} +\item\mdline{4529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4529} \mdline{4529}\emph{distinct}\mdline{4529} digest messages have been received from the +data plane and added to the buffer%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4532} +\noindent\mdline{4532}At which point the server should, with best effort, generate a \mdline{4532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4532} +stream message with the buffer contents and send it to the primary client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software.%mdk + +%mdk-data-line={4538} +\mdline{4538}To avoid sending duplicate digest messages across different \mdline{4538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4538} +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the primary client indicates that it has received the +digest list and acted on it. The server must keep a \mdline{4541}\textquotedblleft{}cache\textquotedblright{}\mdline{4541} containing the set +of all digest messages that have been sent, but not acknowledged yet by the +primary client, up-to \mdline{4543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4543} in the past. The server must delete all +cache entries for a given digest list when they are at least \mdline{4544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4544} +old or when a matching \mdline{4545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4545} message (\mdline{4545}i.e.\mdline{4545} with the same \mdline{4545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4545} +and \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}list\_id}}}\mdline{4546} fields as the \mdline{4546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4546} message) is received.%mdk + +%mdk-data-line={4548} +\mdline{4548}The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged \mdline{4553}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4553} messages.%mdk + +%mdk-data-line={4555} +\mdline{4555}When \mdline{4555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4555} is set to 0 and / or \mdline{4555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4555} is set to 1, the +server should, with best effort, generate a \mdline{4556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4556} message for every +digest message generated by the data plane which is not already in the cache. If +\mdline{4558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4558} is set to 0, the cache must always be an empty set. If +\mdline{4559}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4559} is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +\mdline{4561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4561} configuration parameter.%mdk + +%mdk-data-line={4563} +\mdline{4563}The P4Runtime server may empty the digest message cache in case of a client +status change.%mdk + +%mdk-data-line={4566} +\mdline{4566}Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server:%mdk + +%mdk-data-line={4569} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4570} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestStream~stream;\\ +DigestCache~cache;\\ +DigestBuffer~buffers;\\ +\\ +{\mdcolor{darkgreen}//~sends~digest~list~when~it~is~ready}\\ +send\_buffer(Id~digest\_id)~\{\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~stream.write(DigestList(buffer));\\ +~~cache.merge(buffer);~~{\mdcolor{darkgreen}//~updates~cache~with~new~digest~list}\\ +~~buffer.clear();\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~data~plane~digest~messages~from~device}\\ +handle\_dataplane\_digest(Digest~msg)~\{\\ +~~digest\_id~=~msg.digest\_id();\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~{\bfseries{\mdcolor{navy}if}}~(msg~in~cache~{\mdcolor{teal}OR}~msg~in~buffer)~{\bfseries{\mdcolor{navy}return}};\\ +~~buffer.enqueue(msg);\\ +~~{\bfseries{\mdcolor{navy}if}}~(buffer.length()~\textless{}~max\_list\_size(digest\_id))~{\bfseries{\mdcolor{navy}return}};\\ +~~send\_buffer(digest\_id);\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~ack~messages~received~on~the~stream}\\ +handle\_stream\_ack(DigestListAck~ack)~\{\\ +~~{\mdcolor{darkgreen}//~clear~all~cache~entries~matching~the~tuple~(digest\_id,~list\_id)}\\ +~~cache.erase(~(ack.digest\_id(),~ack.list\_id()~)\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~loop~to~enforce~timeouts}\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~now~=~now();\\ +~~{\mdcolor{darkgreen}//~check~for~buffers~that~need~to~be~sent}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~buffer)~in~buffers)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~buffer.first\_enq\_time()~\textgreater{}=~max\_timeout\_ns(digest\_id))\\ +~~~~~~send\_buffer(buffer\_id);\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~check~for~expired~entries~in~cache}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~list\_id,~sent\_time)~in~cache)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~sent\_time~\textgreater{}=~ack\_timeout\_ns(digest\_id))\\ +~~~~~~cache.erase(~(digest\_id,~list\_id)~);\\ +~~\}\\ +~~sleep({\mdcolor{teal}X});\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4615} +\subsection{\mdline{4615}9.9.\hspace*{0.5em}\mdline{4615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\label{sec-extern-entry}%mdk%mdk + +%mdk-data-line={4617} +\noindent\mdline{4617}This is used to support a P4 extern entity that is not part of PSA. It is +defined as:%mdk + +%mdk-data-line={4620} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4621} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ExternEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_type\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~google.protobuf.Any~entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4628} +\noindent\mdline{4628}Each \mdline{4628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4628} entity maps to an \mdline{4628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{4628} message in the +\mdline{4629}\mdref{sec-p4info-extern}{P4Info}\mdline{4629} and an \mdline{4629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4629} message within that +message. The \mdline{4630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{4630} field must be equal to the one in +\mdline{4631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4631}. The \mdline{4631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_id}}}\mdline{4631} field must be equal to the ID included in the +\mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{4632} of the corresponding \mdline{4632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4632} message.%mdk + +%mdk-data-line={4634} +\mdline{4634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entry}}}\mdline{4634} itself is embedded as an \mdline{4634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{4634} Protobuf message\mdline{4634}~[\mdcite{protoany}{31}]\mdline{4634} to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on\mdline{4638}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{4639} for more information.%mdk + +%mdk-data-line={4641} +\section{\mdline{4641}10.\hspace*{0.5em}\mdline{4641}Error Reporting Messages}\label{sec-error-reporting-messages}%mdk%mdk + +%mdk-data-line={4643} +\noindent\mdline{4643}P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case.%mdk + +%mdk-data-line={4647} +\mdline{4647}gRPC uses \mdline{4647}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4647}~[\mdcite{grpcstatus}{32}]\mdline{4647} to represent the status returned by an +RPC. It has 3 attributes:%mdk + +%mdk-data-line={4650} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4651} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StatusCode~code\_;\\ +{\mdcolor{navy}grpc::}string~error\_message\_;\\ +{\mdcolor{navy}grpc::}string~binary\_error\_details\_;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4656} +\noindent\mdline{4656}The \mdline{4656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4656} represents a canonical error\mdline{4656}~[\mdcite{grpcstatuscodes}{34}]\mdline{4656} and describes the +overall RPC status. The \mdline{4657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4657} is a developer-facing error message, +which should be in English. The \mdline{4658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}binary\_error\_details\_}}}\mdline{4658} carries a serialized +\mdline{4659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4659} message\mdline{4659}~[\mdcite{protostatus}{28}]\mdline{4659} message, which has 3 fields:%mdk + +%mdk-data-line={4661} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4662} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}int32}}~code~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~see~code.proto}\\ +{\bfseries{\mdcolor{navy}string}}~{\bfseries{\mdcolor{navy}message}}~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +{\bfseries{\mdcolor{navy}repeated}}~google.protobuf.Any~details~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4667} +\noindent\mdline{4667}The code and message fields must be the same as \mdline{4667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{4667} and \mdline{4667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4667} +fields from \mdline{4668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4668} above. The \mdline{4668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{4668} field is a list that consists of +\mdline{4669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4669} messages that carry error details for individual elements inside +batch-request RPCs (\mdline{4670}e.g.\mdline{4670} \mdline{4670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4670} and \mdline{4670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4670}). \mdline{4670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4670} includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices\mdline{4674}~[\mdcite{grpcstatuscodes}{34}]\mdline{4674}.%mdk + +%mdk-data-line={4676} +\mdline{4676}Figure\mdline{4676}~\mdref{fig-error-report}{\mdcaptionlabel{7}}\mdline{4676} illustrates how these messages fit together.%mdk + +%mdk-data-line={4678} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={4679} +\noindent\mdline{4679}\includegraphics[keepaspectratio=true,width=\dimwidth{0.70}]{build/error-report}{}\mdline{4679}%mdk + +%mdk-data-line={4680} +\mdhr{}%mdk + +%mdk-data-line={4681} +\noindent\mdline{4681}\mdcaption{\textbf{Figure~\mdcaptionlabel{7}.}~\mdcaptiontext{P4Runtime Error Report Message Format}}%mdk +%mdk +\end{mdcenter}\label{fig-error-report}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={4683} +\noindent\mdline{4683}gRPC provides utility functions \mdline{4683}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExtractErrorDetails()}}}\mdline{4683} and \mdline{4683}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetErrorDetails()}}}\mdline{4683} +\mdline{4684}[\mdcite{grpcerrordetails}{33}]\mdline{4684} to easily convert between \mdline{4684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4684} and +\mdline{4685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{4685}.%mdk + +%mdk-data-line={4687} +\mdline{4687}Please see sections on individual P4Runtime RPCs for details on how +\mdline{4688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4688} is populated for reporting errors.%mdk + +%mdk-data-line={4690} +\mdline{4690}Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on\mdline{4693}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{4694} for more information.%mdk + +%mdk-data-line={4696} +\section{\mdline{4696}11.\hspace*{0.5em}\mdline{4696}Atomicity of Individual \mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4696} and \mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4696} Operations}\label{sec-atomicity-of-individual-write-and-read-operations}%mdk%mdk + +%mdk-data-line={4698} +\noindent\mdline{4698}Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane \mdline{4699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4699} +operation, and every single \mdline{4700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4700} operation on a table that inserts, deletes, +or modifies one table entry, the \mdline{4701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{4701} operation should behave as if that +\mdline{4702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4702} operation has not yet occurred, or as if the \mdline{4702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4702} operation is +complete. The P4 program should never behave as if the \mdline{4703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4703} operation is +partially complete. These guarantees also apply to extern instances: \mdline{4704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4704} and +\mdline{4705}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4705} operations on extern entities must execute atomically relative to extern +data plane methods.%mdk + +%mdk-data-line={4708} +\mdline{4708}The atomicity guarantees provided by P4Runtime for individual \mdline{4708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4708} and \mdline{4708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4708} +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification\mdline{4710}~[\mdcite{psaatomicityofcontrolplaneops}{23}]\mdline{4710}.%mdk + +%mdk-data-line={4712} +\mdline{4712}The P4\mdline{4712}\mdsub{16}\mdline{4712} language introduces an \mdline{4712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4712} annotation\mdline{4712}~[\mdcite{p4concurrency}{14}]\mdline{4712}, to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the \mdline{4714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4714} annotation for \mdline{4714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4714} +operations, as well as\mdline{4715}~\mdref{wildcard-reads}{non-wildcard \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} operations}\mdline{4715}, +relative to data plane execution. Consider the following P4 example written for +PSA:%mdk + +%mdk-data-line={4719} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4720} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024)~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\mdcolor{darkgreen}//~...}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~Value\_t~v~=~r1.read((Index\_t){\mdcolor{purple}1});\\ +~~~~~~~~v~=~v~+~{\mdcolor{purple}1};\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~v);\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4736} +\noindent\mdline{4736}If a P4Runtime server is processing messages which write to Register \mdline{4736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4736} at +index \mdline{4737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}1}}}\mdline{4737}, these writes must not happen between the data plane \mdline{4737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}read}}}\mdline{4737} and +\mdline{4738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}write}}}\mdline{4738}.%mdk + +%mdk-data-line={4740} +\mdline{4740}Now let\mdline{4740}'\mdline{4740}s consider the following example:%mdk + +%mdk-data-line={4742} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4743} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024,~(Value\_t){\mdcolor{purple}0}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~initial~value~}{\mdcolor{darkgreen}*/})~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}100});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}100});\\ +~~~~\}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}200});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}200});\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4761} +\noindent\mdline{4761}If a P4Runtime client issues a \mdline{4761}\emph{wildcard}\mdline{4761} \mdline{4761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4761} on Register \mdline{4761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{4761}, there is no +guarantee that \mdline{4762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]~==~r1{}[2]}}}\mdline{4762} in the response, as the read for \mdline{4762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4762} may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for \mdline{4764}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4764} may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read \mdline{4766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4766} and \mdline{4766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4766} separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +\mdline{4769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4769} message) of individual read requests. Similar to a batch +\mdline{4770}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4770}, a wildcard read of a register can execute the reads of the +register array elements (\mdline{4771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{4771}, \mdline{4771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{4771}, \mdline{4771}\dots{}\mdline{4771}) in an arbitrary order relative +to each other.%mdk + +%mdk-data-line={4774} +\mdline{4774}If the \mdline{4774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{4774} annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program.%mdk + +%mdk-data-line={4778} +\section{\mdline{4778}12.\hspace*{0.5em}\mdline{4778}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4778} RPC}\label{sec-write-rpc}%mdk%mdk + +%mdk-data-line={4780} +\noindent\mdline{4780}The \mdline{4780}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4780} RPC updates one or more P4 entities on the target. The request is +defined as follows:%mdk + +%mdk-data-line={4783} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4784} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~WriteRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Update~updates~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\bfseries{\mdcolor{navy}enum}}~Atomicity~\{\\ +~~~~CONTINUE\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~ROLLBACK\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~DATAPLANE\_ATOMIC~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~\}\\ +~~Atomicity~atomicity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4798} +\noindent\mdline{4798}The \mdline{4798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4798} uniquely identifies the target P4 device. The \mdline{4798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{4798} and +\mdline{4799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4799} define the client role and election-id as described in the +\mdline{4800}\mdref{sec-client-arbitration-and-controller-replication}{Primary-Backup Arbitration and Controller +Replication}\mdline{4801} +section. The server is expected to perform the following checks (in this order) +before processing the \mdline{4803}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}updates}}}\mdline{4803} list:%mdk + +%mdk-data-line={4805} +\begin{enumerate}%mdk + +%mdk-data-line={4805} +\item{} +%mdk-data-line={4805} +\mdline{4805}If \mdline{4805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4805} does not match any of the devices known to the P4Runtime +server or if \mdline{4806}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{4806} does not match any of the roles for the device, the +server must return a \mdline{4807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4807} error.%mdk%mdk + +%mdk-data-line={4809} +\item{} +%mdk-data-line={4809} +\mdline{4809}If the client is not the primary for (\mdline{4809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{4809}, \mdline{4809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{4809}) according to +the \mdline{4810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{4810} value, the server must return a \mdline{4810}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4810} error.%mdk%mdk + +%mdk-data-line={4812} +\item{} +%mdk-data-line={4812} +\mdline{4812}If the \mdline{4812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4812} is attempted before a \mdline{4812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{4812} has been set, +the server must return a \mdline{4813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{4813} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4815} +\noindent\mdline{4815}The updates field is a list of P4 entity updates to be applied. Each update is +defined as:%mdk + +%mdk-data-line={4818} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4819} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Update~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Type~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~INSERT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~MODIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DELETE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~Type~type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Entity~entity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4831} +\noindent\mdline{4831}This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a \mdline{4832}\emph{logical}\mdline{4832} table (\mdline{4832}e.g.\mdline{4832} +\mdline{4833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4833}) or an actual table (\mdline{4833}e.g.\mdline{4833} \mdline{4833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4833}) in the P4 data +plane. Each entity in the container is uniquely identified by its \mdline{4834}\emph{key}\mdline{4834}. Please +refer to the\mdline{4835}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{4835} section for details on +what parts of the entity specification make up the \mdline{4836}\emph{key}\mdline{4836} for each P4 entity.%mdk + +%mdk-data-line={4838} +\mdline{4838}An update can be one of the following types:%mdk + +%mdk-data-line={4840} +\begin{itemize}%mdk + +%mdk-data-line={4840} +\item{} +%mdk-data-line={4840} +\mdline{4840}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4840}: Inserts the given P4 entity in the entity container. +The \mdline{4841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{4841} field always specifies the full state of the P4 entity. +If the entity already exists, an \mdline{4842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4842} error is returned, and +the existing entity remains unchanged. If the entity is malformed, an +\mdline{4844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4844} error is usually returned (unless a more specific error +code applies\mdline{4845}~[\mdcite{grpcstatuscodes}{34}]\mdline{4845}). If the entity cannot be inserted because the +container is already full, a \mdline{4846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4846} error is returned.%mdk%mdk + +%mdk-data-line={4848} +\item{} +%mdk-data-line={4848} +\mdline{4848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4848}: Modifies the P4 entity to its new specified state. This uses +\mdline{4849}\emph{assign}\mdline{4849} or \mdline{4849}\emph{full-snapshot}\mdline{4849} semantics, \mdline{4849}i.e.\mdline{4849} the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an \mdline{4851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4851} error is usually returned (unless a +more specific error code applies\mdline{4852}~[\mdcite{grpcstatuscodes}{34}]\mdline{4852}). If the entity does not +exist, a \mdline{4853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4853} error is returned.%mdk%mdk + +%mdk-data-line={4855} +\item{} +%mdk-data-line={4855} +\mdline{4855}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4855}: Deletes the specified P4 entity. If the entity does not exist, a +\mdline{4856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4856} error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4859} +\noindent\mdline{4859}If an update is not allowed under the given controller role, the server must +return a \mdline{4860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{4860} error for this update.%mdk + +%mdk-data-line={4862} +\subsection{\mdline{4862}12.1.\hspace*{0.5em}\mdline{4862}Batching and Ordering of Updates}\label{sec-batching-and-ordering-of-updates}%mdk%mdk + +%mdk-data-line={4864} +\noindent\mdline{4864}P4Runtime supports batching of \mdline{4864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4864} operations. The list of updates in a +\mdline{4865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4865} is referred to as a \mdline{4865}\emph{batch}\mdline{4865}. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of \mdline{4867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4867} entities).%mdk + +%mdk-data-line={4869} +\mdline{4869}The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +\mdline{4871}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4871}s can also be processed interleaved and/or in parallel. +However, \mdline{4872}\textbf{the processing of requests must be strictly serializable}\mdline{4872}. That +is, given a history \mdline{4873}$S$\mdline{4873} of \mdline{4873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4873}s including the responses to those +requests, there must exist an order \mdline{4874}$L$\mdline{4874} for all updates in \mdline{4874}$S$\mdline{4874}, such that:%mdk + +%mdk-data-line={4876} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4876} +\item\mdline{4876}All updates from the same write request must appear as a contiguous +subsequence in \mdline{4877}$L$\mdline{4877}, but the order within that subsequence can be arbitrary.%mdk + +%mdk-data-line={4878} +\item\mdline{4878}For two updates \mdline{4878}$u_1$\mdline{4878} and \mdline{4878}$u_2$\mdline{4878}, if the write request containing \mdline{4878}$u_1$\mdline{4878} +completed before the write request of \mdline{4879}$u_2$\mdline{4879} was sent, then \mdline{4879}$u_1$\mdline{4879} must appear +before \mdline{4880}$u_2$\mdline{4880} in \mdline{4880}$L$\mdline{4880}.%mdk + +%mdk-data-line={4881} +\item\mdline{4881}Executing all updates in \mdline{4881}$L$\mdline{4881} sequentially must yield the same response for +every update as in \mdline{4882}$S$\mdline{4882}.%mdk + +%mdk-data-line={4883} +\item\mdline{4883}The observable state of the switch after \mdline{4883}$S$\mdline{4883} (\mdline{4883}e.g.\mdline{4883}, through the \mdline{4883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4883} RPC) +is identical to the one obtained by sequentially executing \mdline{4884}$L$\mdline{4884}.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4886} +\noindent\mdline{4886}The \mdline{4886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4886} RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the \mdline{4887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4887} RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (\mdline{4890}e.g.\mdline{4890} inserting an \mdline{4890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4890} +followed by pointing a \mdline{4891}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4891} to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding \mdline{4893}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4893} RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate \mdline{4897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4897} calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each \mdline{4898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4898} call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one.%mdk + +%mdk-data-line={4903} +\subsection{\mdline{4903}12.2.\hspace*{0.5em}\mdline{4903}Batch Atomicity}\label{sec-batch-atomicity}%mdk%mdk + +%mdk-data-line={4905} +\noindent\mdline{4905}A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the \mdline{4906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4906} +enum. A P4Runtime server is required to support only the modes marked as +\mdline{4908}\emph{Required}\mdline{4908} below:%mdk + +%mdk-data-line={4910} +\begin{itemize}%mdk + +%mdk-data-line={4910} +\item{} +%mdk-data-line={4910} +\mdline{4910}\emph{Required}\mdline{4910}: \mdline{4910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4910}: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that \mdline{4914}\emph{see}\mdline{4914} each of +these intermediate stages.%mdk%mdk + +%mdk-data-line={4917} +\item{} +%mdk-data-line={4917} +\mdline{4917}\emph{Optional}\mdline{4917}: \mdline{4917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ROLLBACK\_ON\_ERROR}}}\mdline{4917}: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is \mdline{4921}\emph{all-or-none}\mdline{4921}, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that \mdline{4925}\emph{see}\mdline{4925} each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure.%mdk + +%mdk-data-line={4930} +\mdline{4930}If a P4Runtime server does not support this option at all, an +\mdline{4931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4931} error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (\mdline{4932}e.g.\mdline{4932} it is +more straightforward to implement batches that contain only \mdline{4933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4933} +operations, vs. those that contain \mdline{4934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4934} operations), an +\mdline{4935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4935} error is returned when the batch cannot be executed +in a data plane-atomic way.%mdk%mdk + +%mdk-data-line={4938} +\item{} +%mdk-data-line={4938} +\mdline{4938}\emph{Optional}\mdline{4938}: \mdline{4938}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4938}: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +\mdline{4942}\emph{transaction}\mdline{4942}. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane\mdline{4944}'\mdline{4944}s table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table.%mdk + +%mdk-data-line={4951} +\mdline{4951}If a P4Runtime server does not support this option at all, an \mdline{4951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4951} +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an \mdline{4953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4953} error is returned when the batch +cannot be executed in a data plane-atomic way.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4956} +\noindent\mdline{4956}There is no expectation that a given client must always use the same \mdline{4956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{4956} +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use \mdline{4959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{4959} at one time and default behavior +(\mdline{4960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{4960}) at other times.%mdk + +%mdk-data-line={4962} +\subsection{\mdline{4962}12.3.\hspace*{0.5em}\mdline{4962}Error Reporting}\label{sec-error-reporting}%mdk%mdk + +%mdk-data-line={4964} +\noindent\mdline{4964}Please see section\mdline{4964}~\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{4964} for +information on error reporting messages and guidelines. P4Runtime server will +populate \mdline{4966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{4966} as follows:%mdk + +%mdk-data-line={4968} +\begin{enumerate}%mdk + +%mdk-data-line={4968} +\item{} +%mdk-data-line={4968} +\mdline{4968}If all batch updates succeeded, set \mdline{4968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4968} to \mdline{4968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4968} and do not +populate any other field.%mdk%mdk + +%mdk-data-line={4971} +\item{} +%mdk-data-line={4971} +\mdline{4971}If an error is encountered before even trying to attempt individual batch +updates, set \mdline{4972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4972} that best describes that RPC-wide +error. For example, use \mdline{4973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNAVAILABLE}}}\mdline{4973} if the P4Runtime service is not yet +ready to handle requests. Set \mdline{4974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{4974} to describe the issue. Do not +set \mdline{4975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_details}}}\mdline{4975} in this case.%mdk%mdk + +%mdk-data-line={4977} +\item{} +%mdk-data-line={4977} +\mdline{4977}Otherwise, if one or more updates in the batch (\mdline{4977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest.updates}}}\mdline{4977}) +failed, set \mdline{4978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{4978} to \mdline{4978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{4978}. For example, one update in +the batch may fail with \mdline{4979}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4979} and another with +\mdline{4980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4980}. A \mdline{4980}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4980} message is used to capture the status of +each and every update in the batch. The number of \mdline{4981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4981} messages packed +into \mdline{4982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{4982} field should therefore always match the +number of updates in the \mdline{4983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4983}, and the order of +\mdline{4984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4984} messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +\mdline{4986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{4986} should set the code to \mdline{4986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{4986} and omit other fields.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4988} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4989} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}\#~Example~of~a~grpc::Status~returned~for~a~Write~RPC~with~a~batch~of~3~updates.}\\ +{\mdcolor{darkgreen}\#~The~first~and~third~updates~encountered~an~error,~while~the~second~update}\\ +{\mdcolor{darkgreen}\#~succeeded.}\\ +code\_~=~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +error\_message\_~=~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +binary\_error\_details~\{\\ +~~code:~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}8}~~{\mdcolor{darkgreen}\#~RESOURCE\_EXHAUSTED}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Table~is~full.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}500}~~{\mdcolor{darkgreen}\#~ERR\_TABLE\_FULL}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}0}~~{\mdcolor{darkgreen}\#~OK}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}6}~~{\mdcolor{darkgreen}\#~ALREADY\_EXISTS}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Entity~already~exists.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}600}~~{\mdcolor{darkgreen}\#~ERR\_ENTITY\_ALREADY\_EXISTS}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5015} +\section{\mdline{5015}13.\hspace*{0.5em}\mdline{5015}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5015} RPC}\label{sec-read-rpc}%mdk%mdk + +%mdk-data-line={5017} +\noindent\mdline{5017}The \mdline{5017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5017} RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as:%mdk + +%mdk-data-line={5020} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5021} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5028} +\noindent\mdline{5028}The \mdline{5028}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5028} uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +\mdline{5030}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5030} error. +If the \mdline{5031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5031} is attempted before \mdline{5031}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5031} has been set, the +server must return a \mdline{5032}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{5032} error. +The \mdline{5033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5033} field acts as a filter, restricting the reported entities based on +the role to which the entity belongs. +The \mdline{5035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{5035} repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server.%mdk + +%mdk-data-line={5038} +\mdline{5038}Since \mdline{5038}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5038}s do not mutate any state on the switch, they do not +require an \mdline{5039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5039}, and they do not require the presence of an open +\mdline{5040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5040} between the server and client.%mdk + +%mdk-data-line={5042} +\mdline{5042}The \mdline{5042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read~}}}\mdline{5042}response consists of a sequence of messages (a gRPC \mdline{5042}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}stream}}}\mdline{5042}) with +each message defined as:%mdk + +%mdk-data-line={5045} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5046} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadResponse~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5051} +\noindent\mdline{5051}The \mdline{5051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{5051} repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the \mdline{5055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Finish()}}}\mdline{5055} method on the stream object +\mdline{5056}[\mdcite{grpcstreamc}{10}]\mdline{5056}).%mdk + +%mdk-data-line={5058} +\subsection{\mdline{5058}13.1.\hspace*{0.5em}\mdline{5058}Nomenclature}\label{sec-nomenclature}%mdk%mdk + +%mdk-data-line={5060} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries request}}%mdk + +%mdk-data-line={5060} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{5060}An element of the \mdline{5060}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{5060} repeated field. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries batch}}%mdk + +%mdk-data-line={5062} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{5062}Refers to the \mdline{5062}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{5062} repeated field.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={5065} +\noindent\mdline{5065}Each \mdline{5065}\emph{request}\mdline{5065} acts as a query filter for that entity type. If a \mdline{5065}\emph{request}\mdline{5065} fully +specifies the entity key, the \mdline{5066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5066} operation should retrieve a single P4 +entity. Please refer to the\mdline{5067}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{5067} section +for details on what parts of the entity specification make up the entity \mdline{5068}\emph{key}\mdline{5068}.%mdk + +%mdk-data-line={5070} +\subsection{\mdline{5070}13.2.\hspace*{0.5em}\mdline{5070}Wildcard Reads}\label{sec-wildcard-reads}%mdk%mdk + +%mdk-data-line={5072} +\noindent\mdline{5072}P4Runtime allows wildcard read of P4 entities. A \mdline{5072}\emph{request}\mdline{5072} may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the\mdline{5074}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{5074} section for details on +what parts of the entity can be wildcarded in a given \mdline{5075}\emph{request}\mdline{5075}.%mdk + +%mdk-data-line={5077} +\mdline{5077}For example, in a \mdline{5077}\emph{request}\mdline{5077} of type \mdline{5077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{5077}:%mdk + +%mdk-data-line={5079} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5079} +\item\mdline{5079}A default \mdline{5079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{5079} (0) implies a request to read all counter-entries for +all indirect counters.%mdk + +%mdk-data-line={5081} +\item\mdline{5081}A particular (non-default) \mdline{5081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{5081} in conjunction with \mdline{5081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{5081} unset +implies a request to read all counter-entries for the given indirect counter +ID.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5085} +\noindent\mdline{5085}To read the entire forwarding state for a given device, the P4Runtime client can +generate the following \mdline{5086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5086}:%mdk + +%mdk-data-line={5088} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5089} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~\textless{}ID\textgreater{}\\ +entities~\{\\ +~~extern\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~extern~instances~for~all~supported~extern~types}\\ +~~table\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~table~entries~for~all~tables}\\ +~~action\_profile\_member~\{~\}~~{\mdcolor{darkgreen}\#~read~all~members~for~all~action~profiles}\\ +~~action\_profile\_group~\{~\}~~{\mdcolor{darkgreen}\#~read~all~groups~for~all~action~profiles}\\ +~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5099} +\noindent\mdline{5099}The \mdline{5099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5099} oneof field in the \mdline{5099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5099} message must always be set, or the +server must return an \mdline{5100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5100} error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty \mdline{5102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5102} message in the \mdline{5102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5102}. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the \mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5104} oneof\mdline{5104}~[\mdcite{protooneofbackwardscompatibility}{20}]\mdline{5104}.%mdk + +%mdk-data-line={5106} +\subsection{\mdline{5106}13.3.\hspace*{0.5em}\mdline{5106}Batch Processing}\label{sec-batch-processing}%mdk%mdk + +%mdk-data-line={5108} +\noindent\mdline{5108}A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type \mdline{5109}\emph{request}\mdline{5109} +appears only once in the batch.%mdk + +%mdk-data-line={5112} +\mdline{5112}A P4Runtime server will process the batch as follows:%mdk + +%mdk-data-line={5114} +\begin{enumerate}%mdk + +%mdk-data-line={5114} +\item{} +%mdk-data-line={5114} +\mdline{5114}Lock state (preventing new writes) and validate each \mdline{5114}\emph{request}\mdline{5114} in the batch:%mdk + +%mdk-data-line={5116} +\begin{enumerate}%mdk + +%mdk-data-line={5116} +\item{} +%mdk-data-line={5116} +\mdline{5116}If it is a valid \mdline{5116}\emph{request}\mdline{5116}, perform the read;%mdk + +%mdk-data-line={5118} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5118} +\item\mdline{5118}If the read was successful, return the entities read in +\mdline{5119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5119} stream.%mdk + +%mdk-data-line={5120} +\item\mdline{5120}If the read failed (exception / critical-error), prepare a \mdline{5120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5120} +with code set to \mdline{5121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INTERNAL}}}\mdline{5121}.%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5123} +\item{} +%mdk-data-line={5123} +\mdline{5123}If the \mdline{5123}\emph{request}\mdline{5123} is invalid (invalid-argument, not-supported, etc.), +prepare a \mdline{5124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5124} with relevant canonical code to capture the error.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5126} +\item{} +%mdk-data-line={5126} +\mdline{5126}Unlock the state (allowing new writes);%mdk%mdk + +%mdk-data-line={5128} +\item{} +%mdk-data-line={5128} +\mdline{5128}Close the \mdline{5128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5128} stream and return a \mdline{5128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5128} as follows:%mdk + +%mdk-data-line={5130} +\begin{enumerate}%mdk + +%mdk-data-line={5130} +\item{} +%mdk-data-line={5130} +\mdline{5130}If no errors were encountered, set code to \mdline{5130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{5130} and do not populate any +other field.%mdk%mdk + +%mdk-data-line={5133} +\item{} +%mdk-data-line={5133} +\mdline{5133}Otherwise, the overall code should be set to \mdline{5133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{5133}. See section +\mdline{5134}\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{5134} for information +on error reporting messages and guidelines. Assemble a list of \mdline{5135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5135} +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +\mdline{5139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{5139} field. This behavior also matches \mdline{5139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5139} +RPC.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5142} +\subsubsection{\mdline{5142}13.3.1.\hspace*{0.5em}\mdline{5142}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={5144} +\noindent\mdline{5144}If a client asked to read \mdline{5144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{a,b,c,d\}}}}\mdline{5144} and \mdline{5144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}b}}}\mdline{5144} and \mdline{5144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}d}}}\mdline{5144} \mdline{5144}\emph{requests}\mdline{5144} didn\mdline{5144}'\mdline{5144}t +validate, the server will return entities corresponding to \mdline{5145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5145} and \mdline{5145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}c}}}\mdline{5145}, followed +by a status \mdline{5146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{p4.Error(OK),~p4.Error(xxx),~p4.Error(yyy),~p4.Error(OK)\}}}}\mdline{5146} in the +\mdline{5147}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5147} field.%mdk + +%mdk-data-line={5149} +\mdline{5149}The P4Runtime server is not required to perform any optimization (\mdline{5149}e.g.\mdline{5149} merge two +\mdline{5150}\emph{requests}\mdline{5150} in the \mdline{5150}\emph{batch}\mdline{5150} if one is a subset of other). As a result of this, it +is possible for the \mdline{5151}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5151} to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging.%mdk + +%mdk-data-line={5154} +\mdline{5154}There is no requirement that each request in the batch will correspond to one +\mdline{5155}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5155} message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit.%mdk + +%mdk-data-line={5160} +\mdline{5160}A P4Runtime server must be prepared to handle multiple concurrent \mdline{5160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5160} RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (\mdline{5165}e.g.\mdline{5165} in a single-threaded architecture), it may choose to serialize +\mdline{5166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5166} RPC processing.%mdk + +%mdk-data-line={5168} +\subsection{\mdline{5168}13.4.\hspace*{0.5em}\mdline{5168}Parallelism of Read and Write Requests}\label{sec-parallelism-of-read-and-write-requests}%mdk%mdk + +%mdk-data-line={5170} +\noindent\mdline{5170}A P4Runtime server may be implemented to serve at most one +\mdline{5171}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5171} or \mdline{5171}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5171} message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so.%mdk + +%mdk-data-line={5176} +\mdline{5176}For example, imagine a client that wanted to use \mdline{5176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5176} +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +\mdline{5180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5180} messages with only a few updates to an \mdline{5180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{5180} +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +\mdline{5183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5183} batch currently being processed, but it will not +complete for a significant amount of time.%mdk + +%mdk-data-line={5186} +\mdline{5186}The restrictions on which a client may rely are:%mdk + +%mdk-data-line={5188} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5188} +\item\mdline{5188}The processing of any two \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5188} messages \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W1}}}\mdline{5188} and \mdline{5188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W2}}}\mdline{5188} must +result in the same state as if one of them was completed before the +other began.%mdk + +%mdk-data-line={5191} +\item\mdline{5191}For any \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5191} \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5191} and any \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5191} \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5191}, \mdline{5191}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5191} must +return results consistent with a state where \mdline{5192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5192} has completed +processing, or \mdline{5193}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5193} has not yet begun processing.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5195} +\noindent\mdline{5195}For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a \mdline{5198}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5198} message it acquired a write lock for each stateful +object affected by the \mdline{5199}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5199}, and before starting the +processing of a \mdline{5200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5200} message it acquired a read lock for each +stateful object accessed by the \mdline{5201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5201}, such an implementation +meets all of the requirements above.%mdk + +%mdk-data-line={5204} +\mdline{5204}It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, \mdline{5206}e.g.\mdline{5206} if the server somehow determined that two +\mdline{5207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5207} messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly.%mdk + +%mdk-data-line={5213} +\section{\mdline{5213}14.\hspace*{0.5em}\mdline{5213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5213} RPC}\label{sec-setforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5215} +\noindent\mdline{5215}A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the \mdline{5216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig~RPC}}}\mdline{5216}. The request is defined as:%mdk + +%mdk-data-line={5218} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5219} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~SetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Action~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~VERIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~VERIFY\_AND\_SAVE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~VERIFY\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~~~COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~~~RECONCILE\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~Action~action~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5236} +\noindent\mdline{5236}The server is expected to perform the following checks (in this order) +before performing the required \mdline{5237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{5237}:%mdk + +%mdk-data-line={5239} +\begin{enumerate}%mdk + +%mdk-data-line={5239} +\item{} +%mdk-data-line={5239} +\mdline{5239}If \mdline{5239}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5239} does not match any of the devices known to the P4Runtime +server or if \mdline{5240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5240} does not match any of the roles for the device, the +server must return a \mdline{5241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5241} error.%mdk%mdk + +%mdk-data-line={5243} +\item{} +%mdk-data-line={5243} +\mdline{5243}If the client is not the primary for (\mdline{5243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5243}, \mdline{5243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5243}) according to +the \mdline{5244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5244} value, the server must return a \mdline{5244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5244} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5246} +\noindent\mdline{5246}The action is the type of configuration action requested, it can be one of:%mdk + +%mdk-data-line={5248} +\begin{itemize}%mdk + +%mdk-data-line={5248} +\item{} +%mdk-data-line={5248} +\mdline{5248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY}}}\mdline{5248}: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an \mdline{5249}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5249} +error if config is not provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5252} +\item{} +%mdk-data-line={5252} +\mdline{5252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5252}: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent \mdline{5254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5254} / \mdline{5254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5254} requests must refer to fields in the new +config. Returns an \mdline{5255}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5255} error if the forwarding config is not +provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5258} +\item{} +%mdk-data-line={5258} +\mdline{5258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_COMMIT}}}\mdline{5258}: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an \mdline{5260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5260} error if the forwarding config is not provided or if the +provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5263} +\item{} +%mdk-data-line={5263} +\mdline{5263}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COMMIT}}}\mdline{5263}: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a \mdline{5266}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5266} error if no saved config +is found, \mdline{5267}i.e.\mdline{5267} if no \mdline{5267}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5267} action preceded this one. Returns an +\mdline{5268}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5268} error if a config is provided with this message.%mdk%mdk + +%mdk-data-line={5270} +\item{} +%mdk-data-line={5270} +\mdline{5270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RECONCILE\_AND\_COMMIT}}}\mdline{5270}: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an \mdline{5276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5276} error. For targets that support this option, an +\mdline{5277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5277} error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5281} +\noindent\mdline{5281}The \mdline{5281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5281} field is a message of type \mdline{5281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5281} that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(\mdline{5283}e.g.\mdline{5283} generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the\mdline{5284}~\mdref{sec-p4-fwd-pipe-config}{Forwarding-Pipeline +Configuration}\mdline{5285} section for details.%mdk + +%mdk-data-line={5287} +\mdline{5287}A P4Runtime server running on a non-programmable device may not +support \mdline{5288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5288} (\mdline{5288}e.g.\mdline{5288} the forwarding-pipeline +config is part of the device\mdline{5289}'\mdline{5289}s software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +\mdline{5291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5291} error.%mdk + +%mdk-data-line={5293} +\section{\mdline{5293}15.\hspace*{0.5em}\mdline{5293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5293} RPC}\label{sec-getforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5295} +\noindent\mdline{5295}The forwarding-pipeline configuration of the target can be retrieved by invoking +the \mdline{5296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig~RPC}}}\mdline{5296}. The request is defined as:%mdk + +%mdk-data-line={5298} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5299} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~ResponseType~\{\\ +~~~~ALL~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~COOKIE\_ONLY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~P{\mdcolor{purple}4}INFO\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DEVICE\_CONFIG\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~ResponseType~response\_type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5311} +\noindent\mdline{5311}The \mdline{5311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5311} uniquely identifies the target P4 device. A \mdline{5311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5311} error is +returned if the \mdline{5312}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5312} is not recognized by the P4Runtime server.%mdk + +%mdk-data-line={5314} +\mdline{5314}The \mdline{5314}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5314} is used to specify which fields to populate in the response, +its value can be one of:%mdk + +%mdk-data-line={5317} +\begin{itemize}%mdk + +%mdk-data-line={5317} +\item{} +%mdk-data-line={5317} +\mdline{5317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5317}: returns a \mdline{5317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5317} with all fields +set as stored by the target. This is the default behaviour if the +\mdline{5319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5319} field is not set.%mdk%mdk + +%mdk-data-line={5321} +\item{} +%mdk-data-line={5321} +\mdline{5321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COOKIE\_ONLY}}}\mdline{5321}: reply by setting only the \mdline{5321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5321} field in the +\mdline{5322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5322}, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message.%mdk%mdk + +%mdk-data-line={5326} +\item{} +%mdk-data-line={5326} +\mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4INFO\_AND\_COOKIE}}}\mdline{5326}: reply by setting the \mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{5326} and \mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5326} fields.%mdk%mdk + +%mdk-data-line={5328} +\item{} +%mdk-data-line={5328} +\mdline{5328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEVICE\_CONFIG\_AND\_COOKIE}}}\mdline{5328}: reply by setting the \mdline{5328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5328} and +\mdline{5329}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5329} fields.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5331} +\noindent\mdline{5331}The response contains the \mdline{5331}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5331} for the specified device:%mdk + +%mdk-data-line={5333} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5334} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigResponse~\{\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5339} +\noindent\mdline{5339}If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level \mdline{5340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5340} field will be unset in the response. Examples are +(i) a server that only allows configuration via \mdline{5341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5341} +but this RPC hasn\mdline{5342}'\mdline{5342}t been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn\mdline{5343}'\mdline{5343}t yet occurred.%mdk + +%mdk-data-line={5345} +\mdline{5345}Once a forwarding-pipeline config is installed on the device (either via +\mdline{5346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5346} or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +\mdline{5348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.p4\_device\_config}}}\mdline{5348} will be empty / unset in the response, even if +\mdline{5349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5349} in the request was set to \mdline{5349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5349}. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the \mdline{5351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5351} RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +\mdline{5353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5353}, the value of \mdline{5353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.cookie}}}\mdline{5353} will be unset.%mdk + +%mdk-data-line={5355} +\mdline{5355}If a P4Runtime server supports both \mdline{5355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5355} as well as +returning the \mdline{5356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5356}, there should be read-write symmetry between +\mdline{5357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5357} and \mdline{5357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5357} RPCs.%mdk + +%mdk-data-line={5359} +\section{\mdline{5359}16.\hspace*{0.5em}\mdline{5359}P4Runtime Stream Messages}\label{sec-p4runtime-stream-messages}%mdk%mdk + +%mdk-data-line={5361} +\subsection{\mdline{5361}16.1.\hspace*{0.5em}\mdline{5361}Packet I/O}\label{sec-packet-i_o}%mdk%mdk + +%mdk-data-line={5363} +\noindent\mdline{5363}P4Runtime supports controller packet-in and packet-out by means of \mdline{5363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5363} +and \mdline{5364}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5364} stream messages, respectively.%mdk + +%mdk-data-line={5366} +\mdline{5366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5366} messages are sent by the P4Runtime server to the client. Conversely, +\mdline{5367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5367} messages are sent by the client to the server. Any \mdline{5367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5367} +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a \mdline{5370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5370} message with the \mdline{5370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5370} field set to +report the error to the client. See the section on\mdline{5371}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{5372} for more information on \mdline{5372}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5372}.%mdk + +%mdk-data-line={5374} +\mdline{5374}As introduced in the\mdline{5374}~\mdref{sec-controller-packet-meta}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\mdline{5374} +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with \mdline{5376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5376}. The expected metadata is described +in the P4Info using the \mdline{5377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5377} messages.%mdk + +%mdk-data-line={5379} +\mdline{5379}Both \mdline{5379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5379} and \mdline{5379}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5379} stream messages share the same fields and are +defined as follows:%mdk + +%mdk-data-line={5382} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5383} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Packet~sent~from~the~controller~to~the~switch.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketOut~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~Packet~sent~from~the~switch~to~the~controller.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketIn~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~PacketMetadata~\{\\ +~~{\mdcolor{darkgreen}//~This~refers~to~Metadata.id~coming~from~P4Info~ControllerPacketMetadata.}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~metadata\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5402} +\begin{itemize}%mdk + +%mdk-data-line={5402} +\item{} +%mdk-data-line={5402} +\mdline{5402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}payload}}}\mdline{5402} is used to carry the full packet content, including the headers.%mdk%mdk + +%mdk-data-line={5404} +\item{} +%mdk-data-line={5404} +\mdline{5404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5404} is a repeated field of \mdline{5404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{5404} messages used to carry the +arbitrary controller metadata. The size and value of each metadata entry need +to be consistent with what is specified in the corresponding P4Info +\mdline{5407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5407}. Indeed, when a P4Runtime client (or server) +generates a \mdline{5408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5408} (or \mdline{5408}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5408}) message, it needs to populate the +\mdline{5409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5409} field with as many values as in \mdline{5409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{5409} +for the packet-out (or packet-in) case. Each \mdline{5410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata.value}}}\mdline{5410} is a +binary string and must conform to the\mdline{5411}~\mdref{sec-bytestrings}{Bytestrings}\mdline{5411} +requirements based on the corresponding P4Info +\mdline{5413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.metadata}}}\mdline{5413} specification. If the \mdline{5413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5413} field +does not match the P4Info specification, the server must drop the \mdline{5414}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5414} +message and may generate a \mdline{5415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5415} message with the \mdline{5415}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5415} +field set to report the error to the client which issued the \mdline{5416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5416}. See +the section on\mdline{5417}~\mdref{sec-stream-error-reporting}{Stream Error Reporting}\mdline{5417} for more +information on \mdline{5418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5418}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5420} +\subsection{\mdline{5420}16.2.\hspace*{0.5em}\mdline{5420}Client Arbitration Update}\label{sec-client-arbitration-update}%mdk%mdk + +%mdk-data-line={5422} +\noindent\mdline{5422}P4Runtime\mdline{5422}'\mdline{5422}s client arbitration mechanism ensures that only the current primary +can modify state on the switch, and that the \mdline{5423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5423} is monotonically +increasing. For example, the switch must finish all previous write operations +before before selecting a different primary, and must only accept write requests +from the current primary.%mdk + +%mdk-data-line={5428} +\mdline{5428}As explained earlier in this document, the controller uses the \mdline{5428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5428} +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via \mdline{5430}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5430} RPC), +it needs to start a controller session and become a \mdline{5431}\textquotedblleft{}primary\textquotedblright{}\mdline{5431}. To do so, the +controller first opens a bidirectional stream channel to the server via +\mdline{5433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5433} for each device and sends a \mdline{5433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5433} message. The +controller populates the \mdline{5434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5434} field in this message using +its \mdline{5435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5435} and \mdline{5435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5435} and the \mdline{5435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5435} of the device, as explained +in detail in the\mdline{5436}~\mdref{sec-client-arbitration-and-controller-replication}{Client Arbitration and Controller +Replication}\mdline{5437} +section. For any given \mdline{5438}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role)}}}\mdline{5438}, the P4Runtime server keeps track +of the highest \mdline{5439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5439} that it has ever received. If a controller\mdline{5439}'\mdline{5439}s +\mdline{5440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5440} is equal to the highest \mdline{5440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5440} that the server has ever +received, that controller is the primary. All other controllers are backups. +Note that it is possible that all controllers are backups, and that there is no +primary. There can be at most one primary, because for any given +\mdline{5444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role)}}}\mdline{5444}, each connected controller has a unique \mdline{5444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5444}.%mdk + +%mdk-data-line={5446} +\mdline{5446}This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest \mdline{5447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5447} after such a restart. +However, across a\mdline{5448}~\mdref{sec-restarts}{full restart}\mdline{5448}, the \mdline{5448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5448} must be +reset. In fact, a full restart is the only way to reset the \mdline{5449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5449}.%mdk + +%mdk-data-line={5451} +\mdline{5451}The \mdline{5451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5451} message is defined as follows:%mdk + +%mdk-data-line={5453} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5454} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MasterArbitrationUpdate~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~The~role~for~which~the~primary~client~is~being~arbitrated.~For~use-cases}\\ +~~{\mdcolor{darkgreen}//~where~multiple~roles~are~not~needed,~the~controller~can~leave~this~unset,}\\ +~~{\mdcolor{darkgreen}//~implying~default~role~and~full~pipeline~access.}\\ +~~Role~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~The~stream~RPC~with~the~highest~election\_id~is~the~primary.~The~'primary'}\\ +~~{\mdcolor{darkgreen}//~controller~instance~populates~this~with~its~latest~election\_id.~Switch}\\ +~~{\mdcolor{darkgreen}//~populates~with~the~highest~election~ID~it~has~received~from~all~connected}\\ +~~{\mdcolor{darkgreen}//~controllers.}\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Switch~populates~this~with~OK~for~the~client~that~is~the~primary,~and}\\ +~~{\mdcolor{darkgreen}//~with~an~error~status~for~all~other~connected~clients~(at~every~primary}\\ +~~{\mdcolor{darkgreen}//~client~change).~The~controller~does~not~populate~this~field.}\\ +~~.google.{\bfseries{\mdcolor{navy}rpc}}.Status~status~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Role~\{\\ +~~{\mdcolor{darkgreen}//~Uniquely~identifies~this~role.}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Describes~the~role~configuration,~i.e.~what~operations,~P4~entities,}\\ +~~{\mdcolor{darkgreen}//~behaviors,~etc.~are~in~the~scope~of~a~given~role.~If~config~is~not~set}\\ +~~{\mdcolor{darkgreen}//~(default~case),~it~implies~all~P4~objects~and~control~behaviors~are~in}\\ +~~{\mdcolor{darkgreen}//~scope,~i.e.~full~pipeline~access.~The~format~of~this~message~is}\\ +~~{\mdcolor{darkgreen}//~out-of-scope~of~P4Runtime.}\\ +~~.google.protobuf.Any~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5483} +\noindent\mdline{5483}Note that the \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5483} field in the \mdline{5483}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5483} message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a \mdline{5485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5485} message back to the controller, in which +it populates the \mdline{5486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5486} message using the \mdline{5486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5486}, +\mdline{5487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5487}, and \mdline{5487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5487} it previously received from the controller. The server +also populates the \mdline{5488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5488} field in the \mdline{5488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5488} according to +the rules in an\mdline{5489}~\mdref{sec-arbitration-updates}{earlier section}\mdline{5489}.%mdk + +%mdk-data-line={5491} +\mdline{5491}The sender need not specify an \mdline{5491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5491}. If the \mdline{5491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5491} is not +specified, the sender\mdline{5492}'\mdline{5492}s \mdline{5492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5492} is considered lower than any +\mdline{5493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5493}, and the sender will thus never become primary. This way, a +controller can choose to be a backup controller, in order to avoid +\mdline{5495}\textquotedblleft{}flapping\textquotedblright{}\mdline{5495} (if a backup controller connects to the switch shortly before the +actual primary controller, therefore becoming primary temporarily).%mdk + +%mdk-data-line={5499} +\subsection{\mdline{5499}16.3.\hspace*{0.5em}\mdline{5499}Digest Messages}\label{sec-digest-messages}%mdk%mdk + +%mdk-data-line={5501} +\noindent\mdline{5501}See the\mdline{5501}~\mdref{sec-digestentry}{DigestEntry}\mdline{5501} section.%mdk + +%mdk-data-line={5503} +\subsection{\mdline{5503}16.4.\hspace*{0.5em}\mdline{5503}Table Idle Timeout Notification}\label{sec-table-idle-timeout-notification}%mdk%mdk + +%mdk-data-line={5505} +\noindent\mdline{5505}When a table supports idle timeout (as per the P4Info message), the primary +client can specify a TTL value for each entry in the table (see +\mdline{5507}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{5507} section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an \mdline{5509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5509} message on the +\mdline{5510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5510} bidirectional stream to the primary client. The primary client +can then take the action of its choice, most likely remove the idle entry.%mdk + +%mdk-data-line={5513} +\mdline{5513}The \mdline{5513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5513} Protobuf message has the following fields:%mdk + +%mdk-data-line={5515} +\begin{itemize}%mdk + +%mdk-data-line={5515} +\item{} +%mdk-data-line={5515} +\mdline{5515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}timestamp}}}\mdline{5515}: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server\mdline{5516}'\mdline{5516}s local clock.%mdk%mdk + +%mdk-data-line={5518} +\item{} +%mdk-data-line={5518} +\mdline{5518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5518}: a repeated field of entries which have expired. Each individual +entry is identified by a single \mdline{5519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5519} message. For each \mdline{5519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5519}, +the \mdline{5520}\emph{key}\mdline{5520} fields (\mdline{5520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{5520}, \mdline{5520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{5520} and \mdline{5520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{5520}) must be set, along with +the \mdline{5521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{5521} field, the \mdline{5521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5521} field, and the +\mdline{5522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{5522} field. Other fields may be set by the server but should be +ignored by the client.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5525} +\noindent\mdline{5525}Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +\mdline{5527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5527} message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an \mdline{5532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5532} +message with an empty \mdline{5533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5533} repeated field.%mdk + +%mdk-data-line={5535} +\mdline{5535}After generating an idle notification, the P4Runtime server must \mdline{5535}\textquotedblleft{}reset\textquotedblright{}\mdline{5535} the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the primary client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle.%mdk + +%mdk-data-line={5542} +\mdline{5542}Here is a reasonable pseudo-code implementation for idle timeout for table +entries:%mdk + +%mdk-data-line={5545} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5546} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutStream~stream;\\ +\\ +scanning\_interval~=~{\mdcolor{purple}10}ms;\\ +\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~{\mdcolor{darkgreen}//~iterate~over~all~tables~which~support~idle~timeout}\\ +~~{\bfseries{\mdcolor{navy}for}}~(table~in~tables)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(!table.idle\_timeout\_supported)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~{\mdcolor{darkgreen}//~we~coalesce~all~idle~notifications~for~the~same~table~in~one}\\ +~~~~{\mdcolor{darkgreen}//~message}\\ +~~~~IdleTimeoutNotification~msg;\\ +~~~~{\mdcolor{darkgreen}//~read~time\_since\_last\_hit~from~device}\\ +~~~~entries~=~device.load\_table\_entries\_from\_hw(table);\\ +~~~~{\bfseries{\mdcolor{navy}for}}~(entry~in~entries)~\{\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.idle\_timeout~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~TTL}\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.time\_since\_last\_hit~\textless{}~entry.idle\_timeout)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~~~msg.table\_entry\_add(entry);\\ +~~~~~~entry.reset\_time\_since\_last\_hit();\\ +~~~~\}\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(msg.table\_entry\_size()~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~notifications}\\ +~~~~msg.set\_timestamp(now());\\ +~~~~stream.write(msg);\\ +~~\}\\ +~~sleep(scanning\_interval);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5573} +\subsection{\mdline{5573}16.5.\hspace*{0.5em}\mdline{5573}Architecture-Specific Notifications}\label{sec-architecture-specific-notifications}%mdk%mdk + +%mdk-data-line={5575} +\noindent\mdline{5575}P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on \mdline{5576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5576}, by including an \mdline{5576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5576} Protobuf field\mdline{5576}~[\mdcite{protoany}{31}]\mdline{5576} +named \mdline{5577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5577} in both \mdline{5577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5577} and \mdline{5577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5577}. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the\mdline{5579}~\mdref{sec-digestentry}{PSA \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}} +extern}\mdline{5580}. See section on\mdline{5580}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{5581} for more information.%mdk + +%mdk-data-line={5583} +\subsection{\mdline{5583}16.6.\hspace*{0.5em}\mdline{5583}Stream Error Reporting}\label{sec-stream-error-reporting}%mdk%mdk + +%mdk-data-line={5585} +\noindent\mdline{5585}The P4Runtime server can asynchronously report errors which occur when +processing \mdline{5586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5586} messages, using the \mdline{5586}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5586} message field (of +type \mdline{5587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5587}) in \mdline{5587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5587}. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature.%mdk + +%mdk-data-line={5591} +\mdline{5591}The \mdline{5591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5591} message has the following fields:%mdk + +%mdk-data-line={5593} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5593} +\item\mdline{5593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5593}, which must be set to the appropriate canonical error code +\mdline{5594}[\mdcite{grpcstatuscodes}{34}]\mdline{5594}.%mdk + +%mdk-data-line={5595} +\item\mdline{5595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{5595}, an optional developer-facing error message describing the error.%mdk + +%mdk-data-line={5596} +\item\mdline{5596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5596} and \mdline{5596}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5596}, which are optional and can be used by vendors to provide +additional details on the error. \mdline{5597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5597} is a numeric error code drawn from a +vendor\mdline{5598}'\mdline{5598}s chosen error \mdline{5598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5598}.%mdk + +%mdk-data-line={5599} +\item\mdline{5599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5599}, which is a Protobuf \mdline{5599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5599} used to help the client identify which +\mdline{5600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5600} triggered the error. The server is required to set the +appropriate field in the \mdline{5601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5601} so that the client can identify which type +of stream message is responsible for the error (\mdline{5602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5602}, +\mdline{5603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_list\_ack}}}\mdline{5603} or \mdline{5603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5603}), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid \mdline{5605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5605} message from the +client, the \mdline{5606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5606} field (of type \mdline{5606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError)}}}\mdline{5606} should be set in +the \mdline{5607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5607} \mdline{5607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5607}, and the server may additionally set the \mdline{5607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5607} +field in the \mdline{5608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError}}}\mdline{5608} sub-message (by copying it from the invalid +\mdline{5609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5609} message received on the stream channel) so that the client can +know exactly what packet-out triggered the error.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5612} +\noindent\mdline{5612}The appropriate canonical error code\mdline{5612}~[\mdcite{grpcstatuscodes}{34}]\mdline{5612} should be used when +populating the \mdline{5613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5613} field. For example:%mdk + +%mdk-data-line={5615} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5615} +\item\mdline{5615}if a controller is not allowed to send a \mdline{5615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5615} message under its +current role definition, the code should be set to \mdline{5616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5616}.%mdk + +%mdk-data-line={5617} +\item\mdline{5617}if the \mdline{5617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5617} repeated field in \mdline{5617}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5617} does not match the P4Info +definition, the code should be set to \mdline{5618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5618}. It may be useful +for the server to set the \mdline{5619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5619} field in this case, so that the client +can find out which set of metadata fields triggered the error.%mdk + +%mdk-data-line={5621} +\item\mdline{5621}if the \mdline{5621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{5621} field in \mdline{5621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{5621} does not match any \mdline{5621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{5621} entry +in P4Info, the code should be set to \mdline{5622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5622}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5624} +\noindent\mdline{5624}The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, \mdline{5625}e.g.\mdline{5625} because of a +burst of \mdline{5626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5626} messages.%mdk + +%mdk-data-line={5628} +\mdline{5628}Note that client arbitration errors are never reported using the \mdline{5628}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5628} +message. Invalid \mdline{5629}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5629} messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section\mdline{5631}~\mdref{sec-arbitration-updates}{5.3}\mdline{5631}.%mdk + +%mdk-data-line={5633} +\subsubsection{\mdline{5633}16.6.1.\hspace*{0.5em}\mdline{5633}Examples of \mdline{5633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5633} Messages}\label{sec-examples-of-streamerror-messages}%mdk%mdk + +%mdk-data-line={5635} +\begin{itemize}%mdk + +%mdk-data-line={5635} +\item{} +%mdk-data-line={5635} +\mdline{5635}\textbf{Malformed packet-out metadata.}\mdline{5635} If the server receives a \mdline{5635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5635} +message with a \mdline{5636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5636} field with id 7 which is not included in the P4Info +\mdline{5637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5637} message for \mdline{5637}\textquotedblleft{}packet\_out\textquotedblright{}\mdline{5637}, the server may send the +following \mdline{5638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5638} back to the client:%mdk + +%mdk-data-line={5639} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5640} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Unknown~metadata~field~id~7.}{\mdcolor{maroon}"}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~copied~from~the~PacketOut~message~received~from~the~client}\\ +~~~packet\_out~\{\\ +~~~~~payload:~...\\ +~~~~~metadata~\{\\ +~~~~~~~id:~{\mdcolor{purple}7}\\ +~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}I\_should\_not\_be\_here}{\mdcolor{maroon}"}\\ +~~~~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~~\}\\ +~~~~~{\mdcolor{darkgreen}\#~more~metadata}\\ +~~~\}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={5658} +\item{} +%mdk-data-line={5658} +\mdline{5658}\textbf{Packet-out which exceeds the MTU.}\mdline{5658} If the server receives a \mdline{5658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5658} +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following \mdline{5661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5661}:%mdk + +%mdk-data-line={5662} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5663} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Packet~exceeds~the~MTU~for~port.}{\mdcolor{maroon}"}\\ +~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendor1}{\mdcolor{maroon}"}\\ +~code:~{\mdcolor{purple}123}~~{\mdcolor{darkgreen}\#~MTU\_EXCEEDED}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~we~do~not~set~the~packet\_out~field~as~it~does~not~provide~any}\\ +~~~{\mdcolor{darkgreen}\#~extra~information~to~the~client}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5675} +\section{\mdline{5675}17.\hspace*{0.5em}\mdline{5675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5675} RPC}\label{sec-capabilities-rpc}%mdk%mdk + +%mdk-data-line={5677} +\noindent\mdline{5677}The \mdline{5677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5677} RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the \mdline{5679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesRequest}}}\mdline{5679} message is empty and the \mdline{5679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5679} +message only includes the \mdline{5680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_api\_version}}}\mdline{5680} string field. This field must +be set to the full semantic version string\mdline{5681}~[\mdcite{semver}{27}]\mdline{5681} corresponding to the +version of the P4Runtime API implemented by the server, \mdline{5682}e.g.\mdline{5682} \mdline{5682}\textquotedblleft{}1.1.0-rc.1\textquotedblright{}\mdline{5682}.%mdk + +%mdk-data-line={5684} +\mdline{5684}Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three\mdline{5685}~\mdref{sec-batch-atomicity}{atomicity +modes}\mdline{5686} for \mdline{5686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5686} batches, two of them being +optional. In the future we may decide to leverage the \mdline{5687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5687} +message to enable the server to report to the client which subset of these +atomicity modes is supported.%mdk + +%mdk-data-line={5691} +\mdline{5691}The semantic version string included in \mdline{5691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{5691} can be used by +the client to determine which exact feature set is implemented by the server, +since\mdline{5693}~\mdref{sec-p4runtime-versioning}{minor releases}\mdline{5693} may introduce new +functionality. However, because the \mdline{5694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{5694} RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (\mdline{5696}i.e.\mdline{5696} an \mdline{5696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5696} error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0).%mdk + +%mdk-data-line={5700} +\section{\mdline{5700}18.\hspace*{0.5em}\mdline{5700}Portability Considerations}\label{sec-portability-considerations}%mdk%mdk + +%mdk-data-line={5702} +\subsection{\mdline{5702}18.1.\hspace*{0.5em}\mdline{5702}PSA Metadata Translation}\label{sec-psa-metadata-translation}%mdk%mdk + +%mdk-data-line={5704} +\noindent\mdline{5704}The \mdline{5704}\emph{Portable Switch Architecture}\mdline{5704} (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +\mdline{5708}[\mdcite{psatranslation}{24}]\mdline{5708}. For such metadata, a translation between the controller\mdline{5708}'\mdline{5708}s +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the \mdline{5712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5712} annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture.%mdk + +%mdk-data-line={5716} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={5717} +\noindent\mdline{5717}\includegraphics[keepaspectratio=true,height=7cm]{build/psa-metadata-translation}{}\mdline{5717}%mdk + +%mdk-data-line={5718} +\mdhr{}%mdk + +%mdk-data-line={5719} +\noindent\mdline{5719}\mdcaption{\textbf{Figure~\mdcaptionlabel{8}.}~\mdcaptiontext{P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdcenter}\label{fig-psa-metadata-translation}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={5723} +\noindent\mdline{5723}Figure\mdline{5723}~\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}}\mdline{5723} illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller\mdline{5729}'\mdline{5729}s 32 bit port +numbers to a target\mdline{5730}'\mdline{5730}s 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch.%mdk + +%mdk-data-line={5734} +\subsubsection{\mdline{5734}18.1.1.\hspace*{0.5em}\mdline{5734}Translation of Port Numbers}\label{sec-translation-of-port-numbers}%mdk%mdk + +%mdk-data-line={5736} +\noindent\mdline{5736}In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller\mdline{5737}'\mdline{5737}s space and the PSA device\mdline{5737}'\mdline{5737}s space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +\mdline{5741}\mdref{sec-user-defined-types}{user-defined P4 types}\mdline{5741}, namely \mdline{5741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5741} and +\mdline{5742}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5742}, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in \mdline{5745}\emph{psa.p4}\mdline{5745} for +the PSA device in Switch 1.%mdk + +%mdk-data-line={5748} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5749} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_t;\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortIdInHeader\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~PortIdInHeader\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5755} +\noindent\mdline{5755}The first argument to the \mdline{5755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5755} annotation is a URI that +indicates to the P4Runtime server which numerical mapping\mdline{5756} \mdline{5756}\textemdash{}\mdline{5756} provided by the +out-of-band switch configuration mechanism\mdline{5757} \mdline{5757}\textemdash{}\mdline{5757} to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports).%mdk + +%mdk-data-line={5761} +\mdline{5761}An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows:%mdk + +%mdk-data-line={5767} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5768} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}enum}}~SdnPort~\{\\ +~~SDN\_PORT\_UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +\\ +~~{\mdcolor{darkgreen}//~SDN~ports~are~numbered~starting~from~1.}\\ +~~SDN\_PORT\_MIN~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\\ +~~{\mdcolor{darkgreen}//~The~maximum~value~of~an~SDN~port~(physical~or~logical).}\\ +~~SDN\_PORT\_MAX~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffeff};\\ +\\ +~~{\mdcolor{darkgreen}//~Reserved~SDN~port~numbers~(0xfffffff0~-~0xffffffff)}\\ +\\ +~~SDN\_PORT\_RECIRCULATE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffa};\\ +~~SDN\_PORT\_CPU~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffd};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5784} +\noindent\mdline{5784}The switch config will map \mdline{5784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_RECIRCULATE}}}\mdline{5784} and \mdline{5784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_CPU}}}\mdline{5784} \mdline{5784}\textemdash{}\mdline{5784} as well +as any SDN port number corresponding to a \mdline{5785}\textquotedblleft{}regular\textquotedblright{}\mdline{5785} front-panel port\mdline{5785} \mdline{5785}\textemdash{}\mdline{5785} to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation.%mdk + +%mdk-data-line={5789} +\mdline{5789}The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs.%mdk + +%mdk-data-line={5792} +\subsubsection{\mdline{5792}18.1.2.\hspace*{0.5em}\mdline{5792}Translation of Packet-IO Header Fields}\label{sec-translation-of-packet-io-header-fields}%mdk%mdk + +%mdk-data-line={5794} +\noindent\mdline{5794}Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:.%mdk + +%mdk-data-line={5797} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5798} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~PortIdInHeader\_t~egress\_port;\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~PortIdInHeader\_t~ingress\_port;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5809} +\noindent\mdline{5809}The header-level annotation \mdline{5809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5809} is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (\mdline{5813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5813}) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI\mdline{5817} \mdline{5817}\textemdash{}\mdline{5817} first argument to the \mdline{5817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5817} +annotation). Any subsequent reference to the \mdline{5818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{5818} field in the +data plane will use the translated value. \mdline{5819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{5819} is used in the +header definition instead of \mdline{5820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5820} to guarantee byte-aligned headers in +case this is required by the target.%mdk + +%mdk-data-line={5823} +\mdline{5823}A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target\mdline{5825}'\mdline{5825}s PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the \mdline{5827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ingress\_port}}}\mdline{5827} field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller.%mdk + +%mdk-data-line={5833} +\subsubsection{\mdline{5833}18.1.3.\hspace*{0.5em}\mdline{5833}Translation of Match Fields}\label{sec-translation-of-match-fields}%mdk%mdk + +%mdk-data-line={5835} +\noindent\mdline{5835}Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table\mdline{5836}'\mdline{5836}s match key as shown in the example below:%mdk + +%mdk-data-line={5838} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5839} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~istd.ingress\_port:~exact;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~ingress~port}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5849} +\noindent\mdline{5849}Table \mdline{5849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5849} has an exact match on PSA standard metadata ingress port +(\mdline{5850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}istd.ingress\_port}}}\mdline{5850}). Since the field is of type \mdline{5850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5850}, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in \mdline{5853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5853} from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table \mdline{5858}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5858} is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values.%mdk + +%mdk-data-line={5862} +\mdline{5862}Note that it may be infeasible to translate the value-mask pair for ternary +matches: \mdline{5863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5863}, \mdline{5863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5863} or \mdline{5863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5863} match kinds. The P4Runtime server may +require that for these match kinds the port match be either \mdline{5864}\emph{de facto}\mdline{5864} \mdline{5864}\textquotedblleft{}exact\textquotedblright{}\mdline{5864} +(0xffffffff mask for \mdline{5865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{5865}, prefix-length of 32 for \mdline{5865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{5865}, or same low and +high bounds for \mdline{5866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{5866}) or \mdline{5866}\textquotedblleft{}don't care\textquotedblright{}\mdline{5866}.%mdk + +%mdk-data-line={5868} +\subsubsection{\mdline{5868}18.1.4.\hspace*{0.5em}\mdline{5868}Translation of Action Parameters}\label{sec-translation-of-action-parameters}%mdk%mdk + +%mdk-data-line={5870} +\noindent\mdline{5870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5870} type parameters can be part of a P4 action definition as shown in the +example below:%mdk + +%mdk-data-line={5873} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5874} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.h.f:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~a;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5888} +\noindent\mdline{5888}The controller may write entries in table \mdline{5888}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{5888} with action \mdline{5888}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5888} to set the egress +port as shown in the P4 code above. The action parameter \mdline{5889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5889} is of type +\mdline{5890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5890}, which leads to a 32-bit bitwidth for \mdline{5890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{5890} being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device.%mdk + +%mdk-data-line={5896} +\subsubsection{\mdline{5896}18.1.5.\hspace*{0.5em}\mdline{5896}Port Translation for PSA Extern APIs}\label{sec-port-translation-for-psa-extern-apis}%mdk%mdk + +%mdk-data-line={5898} +\noindent\mdline{5898}The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The \mdline{5903}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{5903} +field is of type \mdline{5904}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{5904} to carry the SDN representation of the port being +watched. The P4Runtime server will translate the given watch port into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device.%mdk + +%mdk-data-line={5909} +\mdline{5909}The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type \mdline{5911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{5911} to carry the 32-bit +SDN port number(s). The P4Runtime server will translate these SDN port numbers +to device-specific port numbers for multicasting and cloning in the data plane.%mdk + +%mdk-data-line={5915} +\subsubsection{\mdline{5915}18.1.6.\hspace*{0.5em}\mdline{5915}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}\label{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}%mdk%mdk + +%mdk-data-line={5917} +\noindent\mdline{5917}P4Runtime supports using a translated value (\mdline{5917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{5917} or any other translated +type for which the underlying built-in type is \mdline{5918}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{5918}) as an index to a +register, indirect counter, or indirect meter.%mdk + +%mdk-data-line={5921} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5922} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~counter~entry~type~}{\mdcolor{darkgreen}*/},~PortId\_t~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~index~type~}{\mdcolor{darkgreen}*/}\textgreater{}(\\ +~~{\mdcolor{purple}32}w1024,~PSA\_CounterType\_t.PACKETS)~counter;\\ +{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +~~counter.count(p);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5930} +\noindent\mdline{5930}This P4 Counter declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={5933} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5934} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counters~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x12000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}counter}{\mdcolor{maroon}"}\\ +~~\}\\ +~~spec~\{\\ +~~~~unit:~PACKETS\\ +~~\}\\ +~~index\_type\_name~\{\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5948} +\noindent\mdline{5948}The controller may read and write counter values from indexed counter \mdline{5948}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter}}}\mdline{5948} +using SDN port numbers as indices, and not device-specific port numbers. The +\mdline{5950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{5950} field in the P4Info message is a signal to the P4Runtime +server that translation is required.%mdk + +%mdk-data-line={5953} +\section{\mdline{5953}19.\hspace*{0.5em}\mdline{5953}P4Runtime Versioning}\label{sec-p4runtime-versioning}%mdk%mdk + +%mdk-data-line={5955} +\noindent\mdline{5955}P4Runtime follows the Google guidelines for versioning cloud APIs +\mdline{5956}[\mdcite{apiversioning}{6}]\mdline{5956}. We use a \mdline{5956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR.MINOR.PATCH}}}\mdline{5956} style version number scheme and +we increment the:%mdk + +%mdk-data-line={5959} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5959} +\item\mdline{5959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5959} version when we make incompatible API changes,%mdk + +%mdk-data-line={5960} +\item\mdline{5960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MINOR}}}\mdline{5960} version when we add functionality in a backwards-compatible manner,%mdk + +%mdk-data-line={5961} +\item\mdline{5961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PATCH}}}\mdline{5961} version when we make backwards-compatible bug fixes.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5963} +\noindent\mdline{5963}The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is \mdline{5965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1}}}\mdline{5965} and the package +name for P4Info is \mdline{5966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1}}}\mdline{5966}. Even though \mdline{5966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5966} and \mdline{5966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5966} are two +different Protobuf packages, \mdline{5967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{5967} depends on \mdline{5967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{5967} and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence.%mdk + +%mdk-data-line={5971} +\mdline{5971}As recommended in\mdline{5971}~[\mdcite{apiversioning}{6}]\mdline{5971}, we may consider using pre-GA release +suffixes (such as \mdline{5972}\emph{alpha}\mdline{5972} or \mdline{5972}\emph{beta}\mdline{5972}) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1).%mdk + +%mdk-data-line={5976} +\mdline{5976}Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner.\mdline{5977}~[\mdcite{apiversioningbackwardscompatibility}{7}]\mdline{5977} describes +what constitute a backwards-compatible change. We expect \mdline{5978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{5978} version bumps +to be a \mdline{5979}\textbf{rare}\mdline{5979} event.%mdk + +%mdk-data-line={5981} +\mdline{5981}Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor\mdline{5986} \mdline{5986}+ patch version numbers in future releases.%mdk + +%mdk-data-line={5988} +\mdline{5988}All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository\mdline{5989}~[\mdcite{p4runtimerepo}{15}]\mdline{5989} and the version label follows +semantic versioning rules\mdline{5990}~[\mdcite{semver}{27}]\mdline{5990}.%mdk + +%mdk-data-line={5992} +\section{\mdline{5992}20.\hspace*{0.5em}\mdline{5992}Extending P4Runtime for non-PSA Architectures}\label{sec-extending-p4runtime}%mdk%mdk + +%mdk-data-line={5994} +\noindent\mdline{5994}P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place.%mdk + +%mdk-data-line={6002} +\mdline{6002}When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names:%mdk + +%mdk-data-line={6006} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6006} +\item\mdline{6006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/config/\textless{}major~version\textgreater{}/p4info.proto}}}\mdline{6006}%mdk + +%mdk-data-line={6007} +\item\mdline{6007}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/\textless{}major~version\textgreater{}/p4runtime.proto}}}\mdline{6007}%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6009} +\noindent\mdline{6009}We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they \mdline{6010}\textquotedblleft{}extend\textquotedblright{}\mdline{6010}.%mdk + +%mdk-data-line={6012} +\mdline{6012}For the remainder of this section, we will refer to these two files as +\mdline{6013}\emph{p4info-ext}\mdline{6013} and \mdline{6013}\emph{p4runtime-ext}\mdline{6013} respectively.%mdk + +%mdk-data-line={6015} +\subsection{\mdline{6015}20.1.\hspace*{0.5em}\mdline{6015}Extending P4Runtime for Architecture-Specific Externs}\label{sec-extending-p4runtime-for-architecture-specific-externs}%mdk%mdk + +%mdk-data-line={6017} +\noindent\mdline{6017}Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both \mdline{6018}\emph{p4info-ext}\mdline{6018} and +\mdline{6019}\emph{p4runtime-ext}\mdline{6019}. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example:%mdk + +%mdk-data-line={6023} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6024} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~T~must~be~a~bit\textless{}W\textgreater{}~type,~it~indicates~the~width~of~each~counter~cell}\\ +{\bfseries{\mdcolor{navy}extern}}~MyNewPacketCounter\textless{}T\textgreater{}~\{\\ +~~counter({\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~size);\\ +~~increment({\bfseries{\mdcolor{navy}in}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~index);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6031} +\subsubsection{\mdline{6031}20.1.1.\hspace*{0.5em}\mdline{6031}Extending the P4Info message}\label{sec-extending-the-p4info-message}%mdk%mdk + +%mdk-data-line={6033} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6033} +\item\mdline{6033}Id prefixes \mdline{6033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0x81}}}\mdline{6033} through \mdline{6033}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfe}}}\mdline{6033} are reserved for architecture-specific +externs. It is recommended that \mdline{6034}\emph{p4info-ext}\mdline{6034} include a \mdline{6034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Ids}}}\mdline{6034} message based +on the one in p4info.proto that the P4 compiler can refer to when\mdline{6035}~\mdref{sec-id-allocation}{assigning +IDs}\mdline{6036} to each extern instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6038} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6039} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~P{\mdcolor{purple}4}Ids~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Prefix~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~MY\_NEW\_PACKET\_COUNTER~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0x81};\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6047} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6047} +\item\mdline{6047}\emph{p4info-ext}\mdline{6047} should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +\mdline{6051}\mdref{sec-p4info-extern}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ExternInstance}}}}\mdline{6051} message as the \mdline{6051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{6051} +field, which is of type \mdline{6052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6052}~[\mdcite{protoany}{31}]\mdline{6052}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6054} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6055} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\mdcolor{darkgreen}//~corresponds~to~the~T~type~parameter~in~the~P4~extern~definition}\\ +~~p4.config.v1.P{\mdcolor{purple}4}DataTypeSpec~type\_spec~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~constructor~argument}\\ +~~{\bfseries{\mdcolor{navy}int64}}~size~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6063} +\subsubsection{\mdline{6063}20.1.2.\hspace*{0.5em}\mdline{6063}Extending the P4Runtime Service}\label{sec-extending-the-p4runtime-service}%mdk%mdk + +%mdk-data-line={6065} +\noindent\mdline{6065}Just like \mdline{6065}\emph{p4info-ext}\mdline{6065}, \mdline{6065}\emph{p4runtime-ext}\mdline{6065} should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an\mdline{6070}~\mdref{sec-extern-entry}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\mdline{6070} message generated by the +P4Runtime client.%mdk + +%mdk-data-line={6073} +\mdline{6073}Here is a possible Protobuf message for our \mdline{6073}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyNewPacketCounter}}}\mdline{6073} P4 extern:%mdk + +%mdk-data-line={6074} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6075} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~This~message~enables~reading~/~writing~data~to~the~counter~at~the~provided}\\ +{\mdcolor{darkgreen}//~index}\\ +{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~p4.v1.P{\mdcolor{purple}4}Data~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6083} +\noindent\mdline{6083}P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an \mdline{6084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6084} Protobuf field\mdline{6084}~[\mdcite{protoany}{31}]\mdline{6084} named \mdline{6084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6084} +in both \mdline{6085}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{6085} and +\mdline{6086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{6086}. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in \mdline{6088}\emph{p4runtime-ext}\mdline{6088} and embed instances of these messages in +\mdline{6089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{6089} and \mdline{6089}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{6089} as appropriate.%mdk + +%mdk-data-line={6091} +\subsection{\mdline{6091}20.2.\hspace*{0.5em}\mdline{6091}Architecture-Specific Table Extensions}\label{sec-architecture-specific-table-extensions}%mdk%mdk + +%mdk-data-line={6093} +\subsubsection{\mdline{6093}20.2.1.\hspace*{0.5em}\mdline{6093}New Match Types}\label{sec-new-match-types}%mdk%mdk + +%mdk-data-line={6095} +\noindent\mdline{6095}An architecture may introduce new table match types\mdline{6095}~[\mdcite{p4matchtypes}{12}]\mdline{6095}. P4Runtime +accounts for this by providing the following hooks:%mdk + +%mdk-data-line={6098} +\begin{itemize}%mdk + +%mdk-data-line={6098} +\item{} +%mdk-data-line={6098} +\mdline{6098}The \mdline{6098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{6098} field in \mdline{6098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{6098} (p4info.proto) is a \mdline{6098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6098} +which can be either one of the default match types (\mdline{6099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{6099}, \mdline{6099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{6099}, \mdline{6099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{6099}, +\mdline{6100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{6100}, or \mdline{6100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6100}) or an architecture-specific match type encoded as a +string.%mdk%mdk + +%mdk-data-line={6103} +\item{} +%mdk-data-line={6103} +\mdline{6103}The \mdline{6103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{6103} field in \mdline{6103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6103} (p4runtime.proto) is a +\mdline{6104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6104} which includes an \mdline{6104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6104} Protobuf message\mdline{6104}~[\mdcite{protoany}{31}]\mdline{6104} field +(\mdline{6105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6105}). \mdline{6105}\emph{p4info-ext}\mdline{6105} should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in \mdline{6108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6108} as the +\mdline{6109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6109} field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6112} +\subsubsection{\mdline{6112}20.2.2.\hspace*{0.5em}\mdline{6112}New Table Properties}\label{sec-new-table-properties}%mdk%mdk + +%mdk-data-line={6114} +\noindent\mdline{6114}An architecture may introduce additional table properties +\mdline{6115}[\mdcite{p4tableproperties}{30}]\mdline{6115}. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +\mdline{6117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Table}}}\mdline{6117} message includes the \mdline{6117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{6117} \mdline{6117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6117} Protobuf +field\mdline{6118}~[\mdcite{protoany}{31}]\mdline{6118}. At the moment, there is not any mechanism to extend the +\mdline{6119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.TableEntry}}}\mdline{6119} message based on the value of architecture-specific table +properties, but we may include on in future versions of the API.%mdk + +%mdk-data-line={6122} +\section{\mdline{6122}21.\hspace*{0.5em}\mdline{6122}Known Limitations of Current P4Runtime Version}\label{sec-known-limitations-of-current-p4runtime-version}%mdk%mdk + +%mdk-data-line={6124} +\begin{itemize}%mdk + +%mdk-data-line={6124} +\item{} +%mdk-data-line={6124} +\mdline{6124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6124}, action \mdline{6124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6124}, and controller packet metadata fields only +support unsigned bitstrings, \mdline{6125}i.e.\mdline{6125} values of one of the following types (not +the more general \mdline{6126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{6126}):%mdk + +%mdk-data-line={6127} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6127} +\item\mdline{6127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6127}%mdk + +%mdk-data-line={6128} +\item\mdline{6128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6128}. Note that as far as the \mdline{6128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Info}}}\mdline{6128} message contents and +thus controller software is concerned, such fields of type \mdline{6129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6129} +will be indistinguishable from those that have been declared with +type \mdline{6131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6131}. P4Runtime server software will automatically +perform any conversion needed between the type \mdline{6132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6132} values in +P4Runtime messages and the data plane representation.%mdk + +%mdk-data-line={6134} +\item\mdline{6134}an \mdline{6134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{6134} with underlying type \mdline{6134}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6134}%mdk + +%mdk-data-line={6135} +\item\mdline{6135}a \mdline{6135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6135} or \mdline{6135}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6135} with an underlying type that is one of the above (or +in general a \mdline{6136}\textquotedblleft{}chain\textquotedblright{}\mdline{6136} of \mdline{6136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6136} and/or \mdline{6136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6136} that eventually ends with +one of the types above)%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6139} +\item{} +%mdk-data-line={6139} +\mdline{6139}Support for PSA Random \mdline{6139}\&\mdline{6139} Timestamp externs is postponed to a future minor +version update.%mdk%mdk + +%mdk-data-line={6142} +\item{} +%mdk-data-line={6142} +\mdline{6142}P4Info does not include information about which of a table\mdline{6142}'\mdline{6142}s actions execute +which direct resource(s).%mdk%mdk + +%mdk-data-line={6145} +\item{} +%mdk-data-line={6145} +\mdline{6145}The default action for indirect match tables is restricted to a \mdline{6145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\\ +NoAction}}}\mdline{6146} known at compile-time.%mdk%mdk + +%mdk-data-line={6148} +\item{} +%mdk-data-line={6148} +\mdline{6148}There is no mechanism for changing the value of the \mdline{6148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{6148} +table property at runtime.%mdk%mdk + +%mdk-data-line={6151} +\item{} +%mdk-data-line={6151} +\mdline{6151}There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor\mdline{6152} \mdline{6152}+ +patch version numbers.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6155} +\section{\mdline{6155}A.\hspace*{0.5em}\mdline{6155}Appendix}\label{sec-appendix}%mdk%mdk + +%mdk-data-line={6157} +\subsection{\mdline{6157}A.1.\hspace*{0.5em}\mdline{6157}Revision History}\label{sec-revision-history}%mdk%mdk + +%mdk-data-line={6159} +\subsubsection{\mdline{6159}A.1.1.\hspace*{0.5em}\mdline{6159}Changes in v1.4.0 (under development)}\label{sec-changes-in-v140-under-development}%mdk%mdk + +%mdk-data-line={6161} +\noindent\mdline{6161}TODO%mdk + +%mdk-data-line={6163} +\subsubsection{\mdline{6163}A.1.2.\hspace*{0.5em}\mdline{6163}Changes in v1.3.0}\label{sec-changes-in-v130}%mdk%mdk + +%mdk-data-line={6165} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6165} +\item\mdline{6165}Add IANA assigned TCP port, 9559, to P4Runtime server discussion.%mdk + +%mdk-data-line={6166} +\item\mdline{6166}Move \mdline{6166}\textquotedblleft{}Security considerations\textquotedblright{}\mdline{6166} section to P4Runtime server discussion.%mdk + +%mdk-data-line={6167} +\item\mdline{6167}Deprecate \mdline{6167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{6167} field (int32) in favor of \mdline{6167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{6167} (bytes). This allows +using the watch port feature with the \mdline{6168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_translation}}}\mdline{6168} feature.%mdk + +%mdk-data-line={6169} +\item\mdline{6169}Replace master, slave, master arbitration with more inclusive language: +primary, backup, and client arbitration%mdk + +%mdk-data-line={6171} +\item\mdline{6171}Clarify that source locations for annotations are optional in the P4Info +message.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6174} +\subsubsection{\mdline{6174}A.1.3.\hspace*{0.5em}\mdline{6174}Changes in v1.2.0}\label{sec-changes-in-v120}%mdk%mdk + +%mdk-data-line={6176} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6176} +\item\mdline{6176}Add new \mdline{6176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6176} match kind. At the moment, \mdline{6176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6176} is only supported by +the v1model architecture\mdline{6177}~[\mdcite{v1model}{38}]\mdline{6177}, and not by PSA. It will eventually be +included in the core P4 language.%mdk + +%mdk-data-line={6179} +\item\mdline{6179}Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists.%mdk + +%mdk-data-line={6181} +\item\mdline{6181}Add a new \mdline{6181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6181} field of type \mdline{6181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{6181} to \mdline{6181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{6181}. This is more +flexible than the now deprecated \mdline{6182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{6182} field.%mdk + +%mdk-data-line={6183} +\item\mdline{6183}Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +\mdline{6185}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6185} annotation.%mdk + +%mdk-data-line={6186} +\item\mdline{6186}Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature.%mdk + +%mdk-data-line={6188} +\item\mdline{6188}Support using \mdline{6188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{6188} as the controller type in the \mdline{6188}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6188} +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type.%mdk + +%mdk-data-line={6191} +\item\mdline{6191}Add optional P4 source locations to both structured and unstructured +annotations.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6194} +\subsubsection{\mdline{6194}A.1.4.\hspace*{0.5em}\mdline{6194}Changes in v1.1.0}\label{sec-changes-in-v110}%mdk%mdk + +%mdk-data-line={6196} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6196} +\item\mdline{6196}Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously.%mdk + +%mdk-data-line={6202} +\item\mdline{6202}Add \mdline{6202}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{6202} field to stream messages sent by the server.%mdk + +%mdk-data-line={6203} +\item\mdline{6203}Add \mdline{6203}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6203} RPC to query the P4Runtime API version implemented by the +server.%mdk + +%mdk-data-line={6205} +\item\mdline{6205}Support wildcard reads for multicast groups and clone sessions.%mdk + +%mdk-data-line={6206} +\item\mdline{6206}Support for modifying direct resources of const tables.%mdk + +%mdk-data-line={6207} +\item\mdline{6207}Support P4 user-defined types for Packet IO metadata fields.%mdk + +%mdk-data-line={6208} +\item\mdline{6208}Clarify consistency requirements for \mdline{6208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6208} and \mdline{6208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{6208} RPCs.%mdk + +%mdk-data-line={6209} +\item\mdline{6209}Add Appendix providing implementation advice for avoiding common pitfalls: + +%mdk-data-line={6210} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6210} +\item\mdline{6210}advice on setting gRPC Metadata Maximum Size%mdk + +%mdk-data-line={6211} +\item\mdline{6211}advice on setting gRPC Server Maximum Receive Message Size%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6212} +\item\mdline{6212}Clarify limitations on supported types for \mdline{6212}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6212}, action \mdline{6212}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6212}, and +Packet IO metadata fields.%mdk + +%mdk-data-line={6214} +\item\mdline{6214}Clarify that reading entire forwarding state with empty \mdline{6214}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{6214} is not +supported.%mdk + +%mdk-data-line={6216} +\item\mdline{6216}Document that \mdline{6216}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6216} need only be supported when applied to +type declarations in P4.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6219} +\subsection{\mdline{6219}A.2.\hspace*{0.5em}\mdline{6219}P4 Annotations}\label{sec-p4-annotations}%mdk%mdk + +%mdk-data-line={6221} +\noindent\mdline{6221}Table\mdline{6221}~\mdref{tab-p4-annotations}{\mdcaptionlabel{7}}\mdline{6221} lists P4\mdline{6221}\mdsub{16}\mdline{6221} annotations introduced primarily for +the purpose of adding features for the P4Runtime API.%mdk + +%mdk-data-line={6224} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{6226} Annotation}}&\multicolumn{1}{|c|}{{\bfseries\mdline{6226} Description}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{6228} \mdline{6228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{6228}}&\multicolumn{1}{|l|}{\mdline{6228} See section\mdline{6228}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6228}}\\ +\multicolumn{1}{|l}{\mdline{6229} \mdline{6229}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{6229}}&\multicolumn{1}{|l|}{\mdline{6229} See section\mdline{6229}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{6229}}\\ +\multicolumn{1}{|l}{\mdline{6230} \mdline{6230}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{6230}}&\multicolumn{1}{|l|}{\mdline{6230} See section\mdline{6230}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6230}}\\ +\multicolumn{1}{|l}{\mdline{6231} \mdline{6231}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6231}}&\multicolumn{1}{|l|}{\mdline{6231} See section\mdline{6231}~\mdref{sec-id-allocation}{6.3}\mdline{6231}}\\ +\multicolumn{1}{|l}{\mdline{6232} \mdline{6232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{6232}}&\multicolumn{1}{|l|}{\mdline{6232} See sections\mdline{6232}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{6232},\mdline{6232}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{6232}}\\ +\multicolumn{1}{|l}{\mdline{6233} \mdline{6233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{6233}}&\multicolumn{1}{|l|}{\mdline{6233} See section\mdline{6233}~\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1}\mdline{6233}}\\ +\multicolumn{1}{|l}{\mdline{6234} \mdline{6234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6234}}&\multicolumn{1}{|l|}{\mdline{6234} See sections\mdline{6234}~\mdref{sec-user-defined-types}{8.5.6}\mdline{6234},\mdline{6234}~\mdref{sec-translation-of-port-numbers}{18.1.1}\mdline{6234}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={6236} +\mdhr{}%mdk + +%mdk-data-line={6237} +\noindent\mdline{6237}\mdcaption{\textbf{Table~\mdcaptionlabel{7}.}~\mdcaptiontext{P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-annotations}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={6240} +\subsection{\mdline{6240}A.3.\hspace*{0.5em}\mdline{6240}A More Complex Value Set Example}\label{sec-value-set-example}%mdk%mdk + +%mdk-data-line={6242} +\noindent\mdline{6242}This section includes a more complex Value Set example, with multiple matches of +different kinds.%mdk + +%mdk-data-line={6245} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6246} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6255} +\noindent\mdline{6255}This P4 Value Set declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={6258} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6259} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6286} +\noindent\mdline{6286}A P4Runtime client can set the membership for this Value Set with \mdline{6286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6286} +messages similar to this one:%mdk + +%mdk-data-line={6289} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6290} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xac}~\}\\ +~~~~~~\}\\ +~~~~~~{\mdcolor{darkgreen}\#~match~for~field\_id~2~is~missing~=\textgreater{}~don't~care~match}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xdc}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~~~ternary~\{~value:~{\mdcolor{purple}0x88}~mask:~{\mdcolor{purple}8}f~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6324} +\subsection{\mdline{6324}A.4.\hspace*{0.5em}\mdline{6324}Guidelines for Implementations}\label{sec-guidelines-for-implementations}%mdk%mdk + +%mdk-data-line={6326} +\noindent\mdline{6326}This section contains practical advice for implementing P4Runtime clients and +servers.%mdk + +%mdk-data-line={6329} +\subsubsection{\mdline{6329}A.4.1.\hspace*{0.5em}\mdline{6329}gRPC Metadata Maximum Size}\label{sec-grpc-metadata-maximum-size}%mdk%mdk + +%mdk-data-line={6331} +\noindent\mdline{6331}In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the \mdline{6332}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6332} gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the \mdline{6333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6333} P4Runtime RPC. The \mdline{6333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6333} RPC +returns an individual error for every item in a batch (see Section +\mdline{6335}\mdref{sec-write-rpc}{12}\mdline{6335}), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +\mdline{6337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{6337} error, without any of the individual errors.%mdk + +%mdk-data-line={6339} +\mdline{6339}To fix this problem, one can set the \mdline{6339}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6339} option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it\mdline{6341}'\mdline{6341}s +limit, as only the receiving side\mdline{6342}'\mdline{6342}s limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every \mdline{6344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{6344}, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +\mdline{6346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}8192~+~MAX\_UPDATES\_PER\_WRITE~*~100}}}\mdline{6346} bytes of metadata.%mdk + +%mdk-data-line={6348} +\mdline{6348}For example, in C++, one can create a client channel as follows:%mdk + +%mdk-data-line={6349} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6350} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}~=~{\mdcolor{purple}100};\\ +::{\mdcolor{navy}grpc::}ChannelArguments~arguments;\\ +arguments{\bfseries{\mdcolor{navy}.}}SetInt({\mdcolor{teal}GRPC\_ARG\_MAX\_METADATA\_SIZE},~{\mdcolor{purple}8192}~+~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}*{\mdcolor{purple}100});\\ +{\bfseries{\mdcolor{navy}return}}~{\mdcolor{navy}grpc::}CreateCustomChannel(address,~credentials,~arguments);}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6356} +\subsubsection{\mdline{6356}A.4.2.\hspace*{0.5em}\mdline{6356}gRPC Server Maximum Receive Message Size}\label{sec-grpc-server-maximum-receive-message-size}%mdk%mdk + +%mdk-data-line={6358} +\noindent\mdline{6358}At the time of writing, the default maximum receive message size in gRPC is 4MB +\mdline{6359}\textemdash{}\mdline{6359} while the default maximum send message size is unlimited. This can be a +problem for the \mdline{6360}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{6360} RPC, since for some targets the +binary \mdline{6361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6361} can exceed 4MB, in which case by default the P4Runtime +server would return an \mdline{6362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6362} error. To a lesser extent, this may +affect the \mdline{6363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6363} RPC as well, in case of extremely large batches.%mdk + +%mdk-data-line={6365} +\mdline{6365}To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of \mdline{6367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6367} for their target(s). This can be done by +setting the \mdline{6368}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_receive\_message\_length}}}\mdline{6368} when building the gRPC server.%mdk + +%mdk-data-line={6370} +\mdline{6370}For example, in C++, one can set the maximum receive message size as follows:%mdk + +%mdk-data-line={6371} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6372} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE}~=~{\mdcolor{purple}128}~*~{\mdcolor{purple}1024}~*~{\mdcolor{purple}1024};~~{\mdcolor{darkgreen}//~128MB}\\ +::{\mdcolor{navy}grpc::}ServerBuilder~server\_builder;\\ +builder{\bfseries{\mdcolor{navy}.}}AddListeningPort({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});\\ +builder{\bfseries{\mdcolor{navy}.}}RegisterService({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});~~{\mdcolor{darkgreen}//~register~P4Runtime~service}\\ +builder{\bfseries{\mdcolor{navy}.}}SetMaxReceiveMessageSize({\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE});\\ +builder{\bfseries{\mdcolor{navy}.}}BuildAndStart();}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6380} +\noindent\mdline{6380}On the client side, we recommend that P4Runtime clients do not use \mdline{6380}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6380} +batches larger than the default maximum receive message size (4MB)\mdline{6381} \mdline{6381}\textemdash{}\mdline{6381} in case +the server did not deem necessary to increase the default value\mdline{6382} \mdline{6382}\textemdash{}\mdline{6382}, unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB).%mdk + +%mdk-data-line={6387;build/P4Runtime-Spec-bib.bbl.mdk:1} +%mdk-data-line={6387;build/P4Runtime-Spec-bib.bbl.mdk:2} +\mdsetrefname{References}%mdk +{\mdbibindent{0}%mdk +\begin{thebibliography}{39}%mdk +\label{sec-bibliography}%mdk + +%mdk-data-line={references.bib:68} +\bibitem{p4spec}\mdbibitemlabel{{}[1]}\textquotedblleft{}$P4_{16}$ 1.2.1 Specification.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html}}.\label{p4spec}%mdk%mdk + +%mdk-data-line={references.bib:134} +\bibitem{rfc2698}\mdbibitemlabel{{}[2]}\textquotedblleft{}A Two Rate Three Color Marker.\textquotedblright{} \href{https://tools.ietf.org/html/rfc2698}{{\ttfamily https://\hspace{0pt}tools.\hspace{0pt}ietf.\hspace{0pt}org/\hspace{0pt}html/\hspace{0pt}rfc2698}}.\label{rfc2698}%mdk%mdk + +%mdk-data-line={references.bib:32} +\bibitem{p4complextypes}\mdbibitemlabel{{}[3]}\textquotedblleft{}Complex Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-p4-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}p4-\hspace{0pt}type}}.\label{p4complextypes}%mdk%mdk + +%mdk-data-line={references.bib:37} +\bibitem{protodefaults}\mdbibitemlabel{{}[4]}\textquotedblleft{}Default Values for Protobuf 3 ($proto3$) Fields.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23default}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}default}}.\label{protodefaults}%mdk%mdk + +%mdk-data-line={references.bib:78} +\bibitem{p4enums}\mdbibitemlabel{{}[5]}\textquotedblleft{}Enums in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-enum-types}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}enum-\hspace{0pt}types}}.\label{p4enums}%mdk%mdk + +%mdk-data-line={references.bib:119} +\bibitem{apiversioning}\mdbibitemlabel{{}[6]}\textquotedblleft{}Google Cloud APIs Versioning.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning}}.\label{apiversioning}%mdk%mdk + +%mdk-data-line={references.bib:124} +\bibitem{apiversioningbackwardscompatibility}\mdbibitemlabel{{}[7]}\textquotedblleft{}Google Cloud APIs Versioning - Backwards-Compatibility.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning\%23backwards_compatibility}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning\#\hspace{0pt}backwards\_\hspace{0pt}compatibility}}.\label{apiversioningbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:149} +\bibitem{grpcauth}\mdbibitemlabel{{}[8]}\textquotedblleft{}gRPC Authentication.\textquotedblright{} \href{https://grpc.io/docs/guides/auth.html}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}guides/\hspace{0pt}auth.\hspace{0pt}html}}.\label{grpcauth}%mdk%mdk + +%mdk-data-line={references.bib:7} +\bibitem{grpc}\mdbibitemlabel{{}[9]}\textquotedblleft{}gRPC Main Site.\textquotedblright{} \href{https://grpc.io}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io}}.\label{grpc}%mdk%mdk + +%mdk-data-line={references.bib:144} +\bibitem{grpcstreamc}\mdbibitemlabel{{}[10]}\textquotedblleft{}gRPC Streaming RPCs in C++.\textquotedblright{} \href{https://grpc.io/docs/tutorials/basic/c.html\%23streaming-rpcs}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}tutorials/\hspace{0pt}basic/\hspace{0pt}c.\hspace{0pt}html\#\hspace{0pt}streaming-\hspace{0pt}rpcs}}.\label{grpcstreamc}%mdk%mdk + +%mdk-data-line={references.bib:114} +\bibitem{p4newtypes}\mdbibitemlabel{{}[11]}\textquotedblleft{}Introducing New Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-newtype}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}newtype}}.\label{p4newtypes}%mdk%mdk + +%mdk-data-line={references.bib:139} +\bibitem{p4matchtypes}\mdbibitemlabel{{}[12]}\textquotedblleft{}Match Types in P4.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-match-kind-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}match-\hspace{0pt}kind-\hspace{0pt}type}}.\label{p4matchtypes}%mdk%mdk + +%mdk-data-line={references.bib:194} +\bibitem{p4annotations}\mdbibitemlabel{{}[13]}\textquotedblleft{}P4 Annotations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-annotations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}annotations}}.\label{p4annotations}%mdk%mdk + +%mdk-data-line={references.bib:174} +\bibitem{p4concurrency}\mdbibitemlabel{{}[14]}\textquotedblleft{}P4 Concurrency Model.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-concurrency}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}concurrency}}.\label{p4concurrency}%mdk%mdk + +%mdk-data-line={references.bib:1} +\bibitem{p4runtimerepo}\mdbibitemlabel{{}[15]}\textquotedblleft{}p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.\textquotedblright{} \href{https://github.com/p4lang/p4runtime}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4runtime}}.\label{p4runtimerepo}%mdk%mdk + +%mdk-data-line={references.bib:42} +\bibitem{pirepo}\mdbibitemlabel{{}[16]}\textquotedblleft{}p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.\textquotedblright{} \href{https://github.com/p4lang/PI}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}PI}}.\label{pirepo}%mdk%mdk + +%mdk-data-line={references.bib:109} +\bibitem{p4apiwgcharter}\mdbibitemlabel{{}[17]}\textquotedblleft{}P4.org API Working Group Charter.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4_API_WG_charter.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4\_\hspace{0pt}API\_\hspace{0pt}WG\_\hspace{0pt}charter.\hspace{0pt}html}}.\label{p4apiwgcharter}%mdk%mdk + +%mdk-data-line={references.bib:154} +\bibitem{p4actionannotations}\mdbibitemlabel{{}[18]}\textquotedblleft{}P4 Standard Annotations on Table Actions.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-action-anno}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}action-\hspace{0pt}anno}}.\label{p4actionannotations}%mdk%mdk + +%mdk-data-line={references.bib:73} +\bibitem{psa}\mdbibitemlabel{{}[19]}\textquotedblleft{}Portable Switch Architecture Specification (v1.1.0).\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html}}.\label{psa}%mdk%mdk + +%mdk-data-line={references.bib:189} +\bibitem{protooneofbackwardscompatibility}\mdbibitemlabel{{}[20]}\textquotedblleft{}Protobuf OneOf Backwards-Compatibility Issues.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23backwards-compatibility-issues}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}backwards-\hspace{0pt}compatibility-\hspace{0pt}issues}}.\label{protooneofbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:12} +\bibitem{proto}\mdbibitemlabel{{}[21]}\textquotedblleft{}Protocol Buffers Main Site.\textquotedblright{} \href{https://developers.google.com/protocol-buffers}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers}}.\label{proto}%mdk%mdk + +%mdk-data-line={references.bib:159} +\bibitem{psaactionselector}\mdbibitemlabel{{}[22]}\textquotedblleft{}PSA Action Selector.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-action-selector}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}action-\hspace{0pt}selector}}.\label{psaactionselector}%mdk%mdk + +%mdk-data-line={references.bib:169} +\bibitem{psaatomicityofcontrolplaneops}\mdbibitemlabel{{}[23]}\textquotedblleft{}PSA Atomicity of Control Plane Operations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-atomicity-of-control-plane-api-operations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}atomicity-\hspace{0pt}of-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}api-\hspace{0pt}operations}}.\label{psaatomicityofcontrolplaneops}%mdk%mdk + +%mdk-data-line={references.bib:179} +\bibitem{psatranslation}\mdbibitemlabel{{}[24]}\textquotedblleft{}PSA Data Plane vs Control Plane Types.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-data-plane-vs-control-plane-values}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}data-\hspace{0pt}plane-\hspace{0pt}vs-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}values}}.\label{psatranslation}%mdk%mdk + +%mdk-data-line={references.bib:164} +\bibitem{psaemptygroupactionappendix}\mdbibitemlabel{{}[25]}\textquotedblleft{}PSA Empty Group Action Appendix.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23appendix-empty-action-selector-groups}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}appendix-\hspace{0pt}empty-\hspace{0pt}action-\hspace{0pt}selector-\hspace{0pt}groups}}.\label{psaemptygroupactionappendix}%mdk%mdk + +%mdk-data-line={references.bib:58} +\bibitem{p4selectexpr}\mdbibitemlabel{{}[26]}\textquotedblleft{}Select Expressions in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-select}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}select}}.\label{p4selectexpr}%mdk%mdk + +%mdk-data-line={references.bib:129} +\bibitem{semver}\mdbibitemlabel{{}[27]}\textquotedblleft{}Semantic Versioning.\textquotedblright{} \href{https://semver.org/}{{\ttfamily https://\hspace{0pt}semver.\hspace{0pt}org/\hspace{0pt}}}.\label{semver}%mdk%mdk + +%mdk-data-line={references.bib:98} +\bibitem{protostatus}\mdbibitemlabel{{}[28]}\textquotedblleft{}Status.proto:the Protobuf Status Message.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}src/\hspace{0pt}proto/\hspace{0pt}grpc/\hspace{0pt}status/\hspace{0pt}status.\hspace{0pt}proto}}.\label{protostatus}%mdk%mdk + +%mdk-data-line={references.bib:63} +\bibitem{p4revisions110}\mdbibitemlabel{{}[29]}\textquotedblleft{}Summary of Changes Made in $P4_{16}$ Version 1.1.0.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-summary-of-changes-made-in-version-110}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}summary-\hspace{0pt}of-\hspace{0pt}changes-\hspace{0pt}made-\hspace{0pt}in-\hspace{0pt}version-\hspace{0pt}110}}.\label{p4revisions110}%mdk%mdk + +%mdk-data-line={references.bib:48} +\bibitem{p4tableproperties}\mdbibitemlabel{{}[30]}\textquotedblleft{}Table Properties in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-props}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}props}}.\label{p4tableproperties}%mdk%mdk + +%mdk-data-line={references.bib:83} +\bibitem{protoany}\mdbibitemlabel{{}[31]}\textquotedblleft{}The Any Protobuf Message.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23any}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}any}}.\label{protoany}%mdk%mdk + +%mdk-data-line={references.bib:88} +\bibitem{grpcstatus}\mdbibitemlabel{{}[32]}\textquotedblleft{}The gRPC $Status$ Class.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/status.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}impl/\hspace{0pt}codegen/\hspace{0pt}status.\hspace{0pt}h}}.\label{grpcstatus}%mdk%mdk + +%mdk-data-line={references.bib:104} +\bibitem{grpcerrordetails}\mdbibitemlabel{{}[33]}\textquotedblleft{}The gRPC C++ Error Details Library.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/support/error_details.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}support/\hspace{0pt}error\_\hspace{0pt}details.\hspace{0pt}h}}.\label{grpcerrordetails}%mdk%mdk + +%mdk-data-line={references.bib:93} +\bibitem{grpcstatuscodes}\mdbibitemlabel{{}[34]}\textquotedblleft{}The gRPC Canonical Status Codes.\textquotedblright{} \href{https://developers.google.com/maps-booking/reference/grpc-api/status_codes}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}maps-\hspace{0pt}booking/\hspace{0pt}reference/\hspace{0pt}grpc-\hspace{0pt}api/\hspace{0pt}status\_\hspace{0pt}codes}}.\label{grpcstatuscodes}%mdk%mdk + +%mdk-data-line={references.bib:22} +\bibitem{openconfig}\mdbibitemlabel{{}[35]}\textquotedblleft{}The OpenConfig Project.\textquotedblright{} \href{http://openconfig.net}{{\ttfamily http://\hspace{0pt}openconfig.\hspace{0pt}net}}.\label{openconfig}%mdk%mdk + +%mdk-data-line={references.bib:184} +\bibitem{protomessagedifferencer}\mdbibitemlabel{{}[36]}\textquotedblleft{}The Protobuf MessageDifferencer in the C++ API.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.util.message_differencer}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}reference/\hspace{0pt}cpp/\hspace{0pt}google.\hspace{0pt}protobuf.\hspace{0pt}util.\hspace{0pt}message\_\hspace{0pt}differencer}}.\label{protomessagedifferencer}%mdk%mdk + +%mdk-data-line={references.bib:27} +\bibitem{stratum}\mdbibitemlabel{{}[37]}\textquotedblleft{}The Stratum Project.\textquotedblright{} \href{https://stratumproject.org/}{{\ttfamily https://\hspace{0pt}stratumproject.\hspace{0pt}org/\hspace{0pt}}}.\label{stratum}%mdk%mdk + +%mdk-data-line={references.bib:199} +\bibitem{v1model}\mdbibitemlabel{{}[38]}\textquotedblleft{}v1model Architecture Definition.\textquotedblright{} \href{https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4c/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}p4include/\hspace{0pt}v1model.\hspace{0pt}p4}}.\label{v1model}%mdk%mdk + +%mdk-data-line={references.bib:53} +\bibitem{p4valuesets}\mdbibitemlabel{{}[39]}\textquotedblleft{}Value Sets in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-value-set}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}value-\hspace{0pt}set}}.\label{p4valuesets}%mdk%mdk +\par%mdk +\end{thebibliography}}%mdk%mdk +}%mdk + + +\end{document} diff --git a/spec/v1.4.0-rc.5/ellipse.sty b/spec/v1.4.0-rc.5/ellipse.sty new file mode 100644 index 00000000..7c0ecb3e --- /dev/null +++ b/spec/v1.4.0-rc.5/ellipse.sty @@ -0,0 +1,318 @@ +%% +%% This is file `ellipse.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ellipse.dtx (with options: `package') +%% +%% Copyright (C) 2015 +%% Daan Leijen +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". +%% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{ellipse} + [2004/11/05 v1.0 .dtx ellipse file] +\RequirePackage{pict2e} + +\providecommand*\pIIe@csedef[1]{\expandafter\edef\csname #1\endcsname} +\newcommand*\pIIe@ellip@csqrt[3]{% + \@ovxx=#1\relax + \ifdim\@ovxx<\z@\@ovxx-\@ovxx\fi + \@ovyy=#2\relax + \ifdim\@ovyy<\z@\@ovyy-\@ovyy\fi + \edef\pIIe@csname{@csqrt(\number\@ovxx,\number\@ovyy)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@ellip@csqrt@% + \pIIe@csedef{\pIIe@csname}{\the\dimen@}% + #3\dimen@ + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} +\newcommand*\pIIe@ellip@csqrt@{% + \@ovdx\@ovxx + \advance\@ovdx by \@ovyy + \dimen@0.7071067\@ovdx + \ifdim\dimen@<\@ovyy\dimen@\@ovyy\fi + \ifdim\dimen@<\@ovxx\dimen@\@ovxx\fi + \ifdim\@ovdx<128\p@ + \edef\@tempa{\strip@pt\@ovxx}% + \@ovxx\@tempa\@ovxx + \edef\@tempa{\strip@pt\@ovyy}% + \@ovyy\@tempa\@ovyy + \advance\@ovxx by \@ovyy + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \fi +} + +\newcommand*\pIIe@atan@{% + \@tempdima\dimen@ + \@tempdimb\@tempdima + \ifdim\@tempdimb<\z@\@tempdimb-\@tempdimb\fi + \dimen@0.0663\@tempdimb + \advance\dimen@ 0.2447pt\relax + \advance\@tempdimb -1pt\relax + \edef\@tempa{\strip@pt\@tempdimb}% + \dimen@\@tempa\dimen@ + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \dimen@-\dimen@ + \advance\dimen@ 0.7853\@tempdima +} + +\newcommand*\pIIe@atantwo[3]{% + \edef\pIIe@csname{@atan2(\number\dimexpr#1\relax,\number\dimexpr#2\relax)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@atantwo@{#1}{#2}{#3}% + \pIIe@csedef{\pIIe@csname}{\the\dimexpr#3\relax}% + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} + +\newcommand*\pIIe@atantwo@[3]{% + \@tempdima\dimexpr#2\relax + \@tempdimb\dimexpr#1\relax + \ifdim\@tempdima=\z@\relax + \ifdim\@tempdimb>\z@\relax\dimen@90\p@ + \else\ifdim\@tempdimb<\z@\relax\dimen@-90\p@ + \else\dimen@0\p@ + \fi\fi + \else + \@tempdimd\z@ + \ifdim\@tempdima<\z@\relax + \ifdim\@tempdimb<\z@\relax\@tempdimd-180\p@ + \else\@tempdimd180\p@ + \fi + \fi + \dimen@\dimexpr1pt * \@tempdimb/\@tempdima\relax + \@tempdimc\dimen@ + \ifdim\@tempdimc<\z@\relax\@tempdimc-\@tempdimc\fi + \ifdim\@tempdimc>\p@\relax + \dimen@\dimexpr1pt * \@tempdima/\@tempdimb\relax + \ifdim\dimen@<\z@\relax\def\@tempsign{-}\else\def\@tempsign{}\fi + \pIIe@atan@ + \dimen@-\dimen@ + \advance\dimen@ by \@tempsign1.5707pt\relax + \else + \pIIe@atan@ + \fi + \dimen@57.29578\dimen@ + \advance\dimen@ by \@tempdimd + \fi + #3\dimen@% +} + +\newcommand*\pIIe@noneto[2]{} +\newcommand*\pIIe@ellip@sincost@[2]{% + \CalculateSin{#1}% + \CalculateCos{#1}% + \@tempdima\UseSin{#1}\p@ + \@tempdimb\UseCos{#1}\p@ + \ifdim\@tempdima=\p@\relax + \pIIe@csedef{@ellipsin#2}{1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else\ifdim\@tempdima=-\p@\relax + \pIIe@csedef{@ellipsin#2}{-1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else + \@tempdimc\@ellipratio\dimexpr1pt * \@tempdima/\@tempdimb\relax + %\typeout{ i#2=\the\@tempdimc, sin(#1)=\the\@tempdima}% + \pIIe@ellip@csqrt{\p@}{\@tempdimc}\@tempdimd + \ifdim\@tempdimb<\z@\relax\@tempdimd-\@tempdimd\fi + \pIIe@csedef{@ellipsin#2}{\strip@pt\dimexpr1pt * \@tempdimc/\@tempdimd\relax}% + \pIIe@csedef{@ellipcos#2}{\strip@pt\dimexpr1pt * \p@/\@tempdimd\relax}% + \fi\fi +} + +\newcommand*\pIIe@ellip@sincost[2]{% + %\typeout{ calc sin cos: angles (#1,#2), radii: (\the\@ovro,\the\@ovri)}% + \edef\@ellipratio{\strip@pt\dimexpr1pt * \@ovro/\@ovri\relax}% + \pIIe@ellip@sincost@{#1}{one}% + \pIIe@ellip@sincost@{#2}{two}% + %\typeout{ sincos(a=#1)=(\@ellipsinone,\@ellipcosone), sincos(a=#2)=(\@ellipsintwo,\@ellipcostwo), }% +} +\newcommand*\pIIe@omega[3]{% + \@tempdima\csname @ellipcos#3\endcsname\@ovro + \advance\@tempdima by #1\relax + \@tempdimb\csname @ellipsin#3\endcsname\@ovri + \advance\@tempdimb by #2\relax +} + +\newcommand*\pIIe@omegai[1]{% + \@tempdimc\csname @ellipsin#1\endcsname\@ovro + \@tempdimc-\@tempdimc + \@tempdimd\csname @ellipcos#1\endcsname\@ovri +} + +\newcommand*\pIIe@ellip@kappa{% + \@ovyy\@ellipsinone\p@ + \@ovxx\@ellipcosone\p@ + \@tempdima\@ellipcostwo\@ovyy + \@tempdima-\@tempdima + \advance\@tempdima by \@ellipsintwo\@ovxx + \@tempdimb\@ellipcostwo\@ovxx + \advance\@tempdimb by \@ellipsintwo\@ovyy + \ifdim\@tempdima=\z@\relax + \edef\@ellipkappa{0}% + \else + \dimen@\dimexpr1pt - \@tempdimb\relax + \dimen@\dimexpr1pt * \dimen@/\@tempdima\relax + \pIIe@ellip@csqrt{2\p@}{1.73205\dimen@}{\dimen@}% + \advance\dimen@ by -\p@ + \divide\dimen@ by 3% + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \edef\@ellipkappa{\strip@pt\dimen@}% + \fi + %\typeout{ calculated kappa: \@ellipkappa}% +} + +\newcommand*\pIIe@elliparc@[5]{% + %\typeout{elliparc: #1, center: (#2, #3), radius (\the\@ovro, \the\@ovri),angle (#4, #5)}% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \pIIe@ellip@sincost{#4}{#5}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@t[5]{% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \CalculateSin{#4}\CalculateCos{#4}% + \edef\@ellipsinone{\UseSin{#4}}% + \edef\@ellipcosone{\UseCos{#4}}% + \CalculateSin{#5}\CalculateCos{#5}% + \edef\@ellipsintwo{\UseSin{#5}}% + \edef\@ellipcostwo{\UseCos{#5}}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@draw[2]{% + \pIIe@ellip@kappa% + \pIIe@omega{#1}{#2}{one}% + %\typeout{ point one: (\the\@tempdima,\the\@tempdimb)}% + \@ellip@startto\@tempdima\@tempdimb + \pIIe@omegai{one}% + \advance\@tempdima by \@ellipkappa\@tempdimc + \advance\@tempdimb by \@ellipkappa\@tempdimd + \pIIe@add@nums\@tempdima\@tempdimb + %\typeout{ control one: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@omega{#1}{#2}{two}% + \pIIe@omegai{two}% + \@tempdimc\@ellipkappa\@tempdimc + \@tempdimd\@ellipkappa\@tempdimd + \@tempdimc-\@tempdimc + \@tempdimd-\@tempdimd + \advance\@tempdimc by \@tempdima + \advance\@tempdimd by \@tempdimb + \pIIe@add@nums\@tempdimc\@tempdimd + %\typeout{ control two: (\the\@tempdimc,\the\@tempdimd)}% + \pIIe@add@CP\@tempdima\@tempdimb + %\typeout{ point two: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@addtoGraph\pIIe@curveto@op +} +\newcommand*\pIIe@elliparc[7][0]{% + \@ovro #4\relax + \@ovri #5\relax + \iffalse%dim\@ovro=\@ovri + \pIIe@arc[#1]{#2}{#3}{#4}{#6}{#7} + \else + \ifdim \@ovro<\z@ \pIIe@badcircarg\else + \ifdim \@ovri<\z@ \pIIe@badcircarg\else + \@arclen #7\p@ \advance\@arclen -#6\p@ + \ifdim \@arclen<\z@ \def\@tempsign{-}\else\def\@tempsign{}\fi + \ifdim \@tempsign\@arclen>720\p@ + \PackageWarning {ellipse}{The arc angle is reduced to -720..720}% + \@whiledim \@tempsign\@arclen>720\p@ \do {\advance\@arclen-\@tempsign360\p@}% + \@tempdima #6\p@ \advance\@tempdima \@arclen + \edef\@angleend{\strip@pt\@tempdima}% + \pIIe@@elliparc{#1}{#2}{#3}{#6}{\@angleend}% + \else + \pIIe@@elliparc{#1}{#2}{#3}{#6}{#7}% + \fi + \fi + \fi + \fi +} +\newcommand*\pIIe@@elliparc[5]{% + \begingroup + \ifdim \@tempsign\@arclen>90\p@ + \divide\@arclen 2% + \@tempdima #4\p@\advance\@tempdima by \@arclen + \edef\@anglemid{\strip@pt\@tempdima}% + \def\@tempa{\pIIe@@elliparc{#1}{#2}{#3}{#4}}% + \expandafter\@tempa\expandafter{\@anglemid}% + \def\@tempa{\pIIe@@elliparc{2}{#2}{#3}}% + \expandafter\@tempa\expandafter{\@anglemid}{#5}% + \else + \pIIe@elliparc@{#1}{#2}{#3}{#4}{#5}% + \fi + \endgroup +}% + +\newcommand*\pIIeelliparc[7][0]{% + \@killglue + \pIIe@elliparc[#1]{#2\unitlength}{#3\unitlength}{#4\unitlength}{#5\unitlength}{#6}{#7}% + \ignorespaces% +} +\ifx\undefined\elliparc\else + \PackageWarning{ellipse}{\protect\elliparc\space is redefined}% +\fi +\let\elliparc\pIIeelliparc + +\newcommand*\pIIeearc + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\newcommand*\pIIe@earc@[3][0,360]{\pIIe@earc@@(#1){#2}{#3}} +\def\pIIe@earc@@(#1,#2)#3#4{% + \if@tempswa + \pIIe@moveto\z@\z@ + \pIIe@elliparc{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@closepath\pIIe@fillGraph + \else + \pIIe@elliparc[1]{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@strokeGraph + \fi} +\ifx\undefined\earc\else + \PackageWarning{ellipse}{\protect\earc\space is redefined}% +\fi +\let\earc\pIIeearc + +\newcommand*\pIIeellipse + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\let\ellipse\pIIeellipse + +\endinput +%% +%% End of file `ellipse.sty'. diff --git a/spec/v1.4.0-rc.5/embedded-plus-single-remote-controller.png b/spec/v1.4.0-rc.5/embedded-plus-single-remote-controller.png new file mode 100644 index 00000000..2e0f1803 Binary files /dev/null and b/spec/v1.4.0-rc.5/embedded-plus-single-remote-controller.png differ diff --git a/spec/v1.4.0-rc.5/embedded-plus-single-remote-controller.svg b/spec/v1.4.0-rc.5/embedded-plus-single-remote-controller.svg new file mode 100644 index 00000000..9fe2ce9c --- /dev/null +++ b/spec/v1.4.0-rc.5/embedded-plus-single-remote-controller.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0-rc.5/embedded-plus-two-remote-controllers.png b/spec/v1.4.0-rc.5/embedded-plus-two-remote-controllers.png new file mode 100644 index 00000000..b6dc04fc Binary files /dev/null and b/spec/v1.4.0-rc.5/embedded-plus-two-remote-controllers.png differ diff --git a/spec/v1.4.0-rc.5/embedded-plus-two-remote-controllers.svg b/spec/v1.4.0-rc.5/embedded-plus-two-remote-controllers.svg new file mode 100644 index 00000000..0f97ba38 --- /dev/null +++ b/spec/v1.4.0-rc.5/embedded-plus-two-remote-controllers.svg @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + + + Entities + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0-rc.5/embedded-plus-two-remote-ha-controllers.png b/spec/v1.4.0-rc.5/embedded-plus-two-remote-ha-controllers.png new file mode 100644 index 00000000..392f8963 Binary files /dev/null and b/spec/v1.4.0-rc.5/embedded-plus-two-remote-ha-controllers.png differ diff --git a/spec/v1.4.0-rc.5/embedded-plus-two-remote-ha-controllers.svg b/spec/v1.4.0-rc.5/embedded-plus-two-remote-ha-controllers.svg new file mode 100644 index 00000000..97ab6fc3 --- /dev/null +++ b/spec/v1.4.0-rc.5/embedded-plus-two-remote-ha-controllers.svg @@ -0,0 +1,511 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + Primary (Active) + + + + + + Backup (Standby) + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0-rc.5/error-report.png b/spec/v1.4.0-rc.5/error-report.png new file mode 100644 index 00000000..766cb77f Binary files /dev/null and b/spec/v1.4.0-rc.5/error-report.png differ diff --git a/spec/v1.4.0-rc.5/error-report.svg b/spec/v1.4.0-rc.5/error-report.svg new file mode 100644 index 00000000..a2709a72 --- /dev/null +++ b/spec/v1.4.0-rc.5/error-report.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StatusCode error_code_; // canonical error codestring error_message_;string binary_error_details_; // serialized google.rpc.Status + + + + + + + + + + + + + google.rpc.Status + + + + + + int32 error_code; // canonical error codestring message;repeated Any details; // P4Error + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + + + p4.Error + + + + + + p4.Error + + + + + + + + + + + + + + + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + grpc::Status + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0-rc.5/longbox.sty b/spec/v1.4.0-rc.5/longbox.sty new file mode 100644 index 00000000..cab48934 --- /dev/null +++ b/spec/v1.4.0-rc.5/longbox.sty @@ -0,0 +1,853 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longbox}[2015/12/01, Daan Leijen, Provides basic longbox that can break over pages] +\RequirePackage{options} + +\@ifclassloaded{beamer}{% + \newcommand\lb@savefootnotes{}% + \newcommand\lb@restorefootnotes{}% +}% +{\RequirePackage{footnote}% + \newcommand\lb@savefootnotes{\savenotes}% + \newcommand\lb@restorefootnotes{\spewnotes}% +} + + +% -------------------------------------------------------- +% Debugging +% -------------------------------------------------------- + +\newcommand*\lb@debug[1]{% + \ontoggle{lb@debug}{\typeout{longbox debug: #1}}% +} +\newcommand*\lb@typeout[1]{% + \ontoggle{lb@verbose}{\typeout{longbox: #1}}% +} +\newcommand*\lb@warncannotsplit{% + \PackageWarning{longbox}{Cannot split box; it seems you are using a non-splittable contents}% +} +\newcommand*\lb@warnbadsplit[1]{% + \PackageWarning{longbox}{Bad split (underful vbox by \the#1)}% +} + + +% -------------------------------------------------------- +% Utilities for LaTeX internals +% -------------------------------------------------------- + +% Suppress the indentation on the following paragraph +\providecommand\nofirstindent{\@afterindentfalse\@afterheading} + +% Suppress the paragraph skip on the following paragraph +\providecommand\nofirstparskip{\addvskip{-\parskip}} + +% In contrast to addvspace, addvskip is not suppressed in a minipage +\providecommand\addvskip[1]{% + \ifvmode + \ifdim\lastskip=\z@ + \vskip #1\relax + \else + \@tempskipb#1\relax\@xaddvskip + \fi + \else\@noitemerr\fi +} + + +% Skip to 0.3\baselineskip multiple taking prevdepth into account. +\newskip\lb@prevdepth +\newcommand\lb@skiptobaseline{% + \global\lb@prevdepth=-\@m\p@\relax + \ifvmode + \ifdim\lastskip=\z@\relax + \ifdim\prevdepth=-\@m\p@\else + \dimen@\prevdepth + % Calculate the modulus of the previous depth with 0.3|\baselineskip| in |\dimen@|. + \@tempcnta\prevdepth + \@tempskipa=0.3\baselineskip\relax + \@tempcntb=\@tempskipa\relax + \divide \@tempcnta by \@tempcntb + \dimen@\prevdepth + \advance\dimen@ -\@tempcnta\@tempskipa + % Skip back by that amount, and then skip by 0.3|\baselineskip|. + \vskip -\dimen@ + \vskip \@tempskipa\relax + \global\lb@prevdepth=\@tempskipa\relax + \fi + \fi + \fi +} + +% unvbox a box, and return a vbox with a given background color +% \unvcolorbox{}{} +\newcommand\unvcolorbox[2]{% + \ifoptionblank{#1}{\vbox{\unvbox#2}}{% + \lb@debug{vcolorbox: #1}% + \vbox{\offinterlineskip + \hbox to \z@{\vbox to \z@{\optioncolor{#1}\hrule\@width\wd#2\@height\ht#2\@depth\dp#2\vss}\hss}% + \unvbox#2% + }% + }% +} + +% create a vbox with a given background color +\newcommand\vcolorbox[2]{% + \eifblank{#1}{\vbox{#2}}{% + \setbox\z@=\vbox{#2}\relax + \unvcolorbox{#1}{\z@}% + }% +}% + +% -------------------------------------------------------- +% The following macros come from mdframed +% -------------------------------------------------------- + +% Determine the amount of free space left on the current page +\newlength\lb@freevspace +\newcommand*\lb@setfreevspace@page{% + \lb@debug{ determine free space}% + \bgroup\@nobreakfalse\addpenalty\z@\egroup% + \penalty\@M\relax\vskip 2\baselineskip\relax% + \penalty9999\relax\vskip -2\baselineskip\relax% + \penalty9999% + \ifdim\pagegoal=\maxdimen\relax% + \lb@freevspace=\vsize% + \else + \lb@freevspace=\dimexpr\pagegoal-\pagetotal-\parskip\relax% + \fi + \lb@debug{free space: \the\lb@freevspace, in page: \the\textheight, vsize=\the\vsize}% +} + +\newcommand*\lb@shiftdim[2]{% + %\letoption{#1}\lb@list + \expandafter\lb@setheadtail@#1,\relax + \eifblank{\lb@head}{}{\option@invoke{/longbox/@breakat-previous}{\lb@head}}% + #2\option{/longbox/@breakat-previous}% + \eifblank{\lb@tail}{}{\let#1\lb@tail}% push back tail +} +\def\lb@comma{,}% +\def\lb@setheadtail@#1,#2\relax{% + \def\lb@head{#1}% + \def\lb@tail{#2}% adds commas! +} + +\newcommand*\lb@setfreevspace{% + \eifblank{\lb@breakat}{\lb@setfreevspace@page}{% + \def\lb@eject{\par}%no eject + \lb@extrasplit=\z@\relax% + \lb@shiftdim{\lb@breakat}\lb@freevspace + \ifdim\lb@freevspace>\z@\else\lb@setfreevspace@page\fi + }% +} + + +% Suppress overfull-underfull vbox messages +\newcommand*\lb@ignorevbadness{% + \edef\lb@currentvbadness{\the\vbadness}% + \edef\lb@currentvfuzz{\the\vfuzz}% + \vbadness=\@M\relax% + \vfuzz=\maxdimen\relax% + \afterassignment\lb@restorevbadness +} +\newcommand*\lb@restorevbadness{% + \vbadness=\lb@currentvbadness\relax + \vfuzz=\lb@currentvfuzz\relax +} + + +% -------------------------------------------------------- +% The 'long vbox' (lvbox) environment collects long material +% into a long \vbox, instead of a \hbox like a lrbox in latex. +% The collected box can contain any box, minipage, lrbox, fbox etc, +% but not outer-par material like a figure. Footnotes can be +% dealt with useing lb@savefootnotes. +% +% The material is typeset in a \vbox according to a given width. +% inside the environment, the boolean 'inlvbox' is true. +% +% \begin{lvbox}{}{} +% -------------------------------------------------------- + +\newif\ifinlvbox +\newcommand\lvbox[4]{% + \setbox#1\vbox\bgroup + \begingroup + \inlvboxtrue + % reset defaults + \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\par\@@par + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + % set margin and linewidth + \leftmargin=#2\relax\rightmargin=#4\relax + \@totalleftmargin=\leftmargin% + %\leftskip=#2\relax\rightskip=#4\relax\@rightskip=#4\relax + \linewidth=#3\relax + % set primitive tex margins + \leftskip=\@totalleftmargin% + \rightskip=\rightmargin% + \@rightskip=\rightmargin% + \hsize=\dimexpr\@totalleftmargin+\linewidth+\rightmargin\relax + \columnwidth\hsize + \textwidth\hsize + \nofirstindent + %\nofirstparskip +} +\def\endlvbox{\endgroup\egroup} + + + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + + +\newsavebox\lb@headbox +\newsavebox\lb@savebox +\newsavebox\lb@mainbox + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@setbaseline[1]{% + %\typeout{ set baseline, \the\dp#1,\the\ht#1}% + \ifcase\lb@baseline% + \relax%bottom + \or%middle + \setbox#1=\vbox{\hbox{\lower \dimexpr(\dp#1 + \ht#1)/2 - \dp#1\relax\vbox{\unvbox#1}}}% + \or%top + \setbox#1=\vtop{\unvbox#1}% + \fi + %\typeout{ .new dim: \the\dp#1, \the\ht#1}% +} + + +\@ifundefined{define@key}{}% + {\define@key{longbox}{options}{\options{#1}\option{/longbox/adjust-options}}}% + +\newcommand*\lb@render@breakbox{% + %\typeout{render breakbox entry (in output routine), height=\the\bb@height}% + \bb@restorekeys{longbox}% + \lb@skiptop=\ifbb@isfirst\option{/longbox/skip-top}\else\option{/longbox/skip-break-top}\fi\relax + \lb@skipbottom=\ifbb@islast\option{/longbox/skip-bottom}\else\option{/longbox/skip-break-bottom}\fi\relax + \lb@skipbreaktop=\ifbb@isfirst 0pt\else\option{/longbox/skip-break-top}\fi + \lb@skipbreakbottom=\ifbb@islast 0pt\else\option{/longbox/skip-break-bottom}\fi + %\typeout{ render: skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom, break-top=\the\dimexpr\option{/longbox/skip-bottom}}% + \options{% + /longbox/@part-height=\bb@height + \lb@skipbreaktop + \lb@skipbreakbottom, + /longbox/@part-width=\option{/longbox/width} + \option{/longbox/skip-left} + \option{/longbox/skip-right},%\bb@width, + /longbox/@part-depth=0pt, + /longbox/@part-needtop=\ifbb@isfirst true\else false\fi, + /longbox/@part-needbottom=\ifbb@islast true\else false\fi, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-depth=\option{/longbox/@part-depth}, + }% + %\typeout{breakbox: width=\expandafter\the\option{/longbox/width}, \the\bb@width, \the\dimexpr\option{/longbox/@part-width}}% + \vbox{% + \kern -\lb@skipbreaktop% todo: move to breakbox? + \option{/longbox/render}% + \kern -\lb@skipbreakbottom + }% +} + +\newcommand*\lb@render@vbox[1]{% + \lb@debug{render vbox entry}% + \lb@restoreoptions + \lb@skiptop=\dimexpr\iftoggle{/longbox/@part-needtop}{\option{/longbox/skip-top}}{\option{/longbox/skip-break-top}}\relax + \lb@skipbottom=\dimexpr\iftoggle{/longbox/@part-needbottom}{\option{/longbox/skip-bottom}}{\option{/longbox/skip-break-bottom}}\relax + %\typeout{ skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom}% + % add top skip while maintaining the baseline. + \ifdim\lb@skiptop=\z@\relax\else + \setbox\z@=\vtop{\unvcopy#1}% + \dimen@=\ht\z@ + \setbox#1=\vbox{\offinterlineskip + \hrule width \z@ height \dimexpr\dimen@ + \lb@skiptop\relax depth -\dimen@ + \unvbox#1% + }% + \fi + % add bottom skip while maintaining the baseline. + \ifdim\lb@skipbottom=\z@\relax\else + \dimen@=\dp#1% + \setbox#1=\vbox{\offinterlineskip\unvbox#1\hrule width \z@ height -\dimen@ depth \dimexpr\dimen@ + \lb@skipbottom\relax}% + \fi + \lb@setbaseline{#1}% + \options{% + /longbox/@part-height=\dimexpr\ht#1 + \dp#1\relax, + /longbox/@part-width=\dimexpr\wd#1 + \option{/longbox/skip-left} + \option{/longbox/skip-right}\relax, + /longbox/@part-depth=\dp#1, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-depth=\option{/longbox/@part-depth} - \lb@skipbottom, + }% + %\typeout{ longbox: height=\the\dimexpr\option{/longbox/@content-box-height}, outer height=\the\dimexpr\option{/longbox/@part-height}\relax}% + % lower the box depending on vertical alignment + \ifcase\option{/longbox/vertical-align/@ord}\relax + \@tempdima\z@ + \or + %bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%middle + \@tempdima\dimexpr0.5\option{/longbox/@part-height} - \option{/longbox/@part-depth}\relax + \or%top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%text-bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%text-top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%super + \@tempdima=-0.9ex% + \or%sub + \@tempdima=0.7ex% + \else + \@tempdima\z@ + \fi + \advance\@tempdima by -\option{/longbox/raise}% + \option@invoke{/longbox/@lower}{\@tempdima}% + \noindent\hbox{\lower \@tempdima\vbox{\offinterlineskip + \hbox to \z@{% + \vbox to \z@{% + \hbox{\lower \option{/longbox/@part-height}\vbox{\offinterlineskip{\option{/longbox/render}}}}% + \vss}% + \hss + }% + \hbox{% + \ifdim\option{/longbox/skip-left}=\z@\else\hskip\option{/longbox/skip-left}\fi + \box#1% + \ifdim\option{/longbox/skip-right}=\z@\else\hskip\option{/longbox/skip-right}\fi + %$\box#1% + }% + }}% +} + +\newcommand*\lb@single@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} +\newcommand*\lb@first@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@middle@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@last@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand*\lb@env@start{% + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore +} + +\newcount\lb@usevbox +\newlength\lb@width +\newlength\lb@height +\newlength\lb@skiptop +\newlength\lb@skipright +\newlength\lb@skipbottom +\newlength\lb@skipleft +\newlength\lb@skipbreaktop +\newlength\lb@skipbreakbottom +\newlength\lb@outerwidth +\newlength\lb@extrasplit +\newcount\lb@textalign +\newcount\lb@baseline +\newtoggle{lb@baselineskip}% +\newtoggle{lb@breakable}% +\newtoggle{lb@debug}% +\newtoggle{lb@verbose}% +\def\lb@breakat{}% +\def\lb@halign{}% +\def\lb@eject{}% +\def\lb@insertafter{} +\def\lb@insertbefore{} + +\newcommand*\lb@peekoptions[1]{% + % process options inside a group and just set necessary parameters + % this way, nested boxes don't influence each other's parameters + \begingroup + \options{#1}% + \option{/longbox/adjust-options}% + \protected@edef\lb@temp{\endgroup + \lb@width=\the\dimexpr\option{/longbox/width}\relax + \lb@height=\the\dimexpr\option{/longbox/height}\relax + \lb@textalign=\the\numexpr\option{/longbox/text-align/@ord}\relax + \lb@baseline=\the\numexpr\option{/longbox/baseline/@ord}\relax + \lb@skiptop=\the\dimexpr\option{/longbox/skip-top}\relax + \lb@skipright=\the\dimexpr\option{/longbox/skip-right}\relax + \lb@skipbottom=\the\dimexpr\option{/longbox/skip-bottom}\relax + \lb@skipleft=\the\dimexpr\option{/longbox/skip-left}\relax + \lb@skipbreaktop=\the\dimexpr\option{/longbox/skip-break-top}\relax + \lb@skipbreakbottom=\the\dimexpr\option{/longbox/skip-break-bottom}\relax + \lb@usevbox=\iftoggle{/longbox/use-vbox}{1}{0}\relax + \lb@outerwidth=\the\dimexpr\option{/longbox/outer-width}\relax + \lb@extrasplit=\the\dimexpr\option{/longbox/split-minimum}\relax + \def\noexpand\lb@insertafter{\option{/longbox/insert-after}}% + \def\noexpand\lb@insertbefore{\option{/longbox/insert-before}}% + \def\noexpand\lb@breakat{\option{/longbox/breakat}}% + \def\noexpand\lb@halign{\option{/longbox/height-align}}% + \def\noexpand\lb@eject{\option{/longbox/eject}}% + \noexpand\csname toggle\iftoggle{/longbox/baseline-skip}{true}{false}\endcsname{lb@baselineskip}% + \noexpand\csname toggle\iftoggle{/longbox/breakable}{true}{false}\endcsname{lb@breakable}% + \noexpand\csname toggle\iftoggle{/longbox/debug}{true}{false}\endcsname{lb@debug}% + \noexpand\csname toggle\iftoggle{/longbox/verbose}{true}{false}\endcsname{lb@verbose}% + }% + \lb@temp +} + +\newenvironment{longbox@env}[2]{% + % save options + \lb@peekoptions{#1,#2}% + % + \ifnum\lb@usevbox=0\relax + \lb@debug{start breakbox}% + \let\bb@render\lb@render@breakbox + \bb@savekeys{longbox}{options={#1,#2,outer-width=\the\lb@outerwidth}}% + \iftoggle{lb@baselineskip}{\typeout{**insert bskip}}{\typeout{**suppress bskip}\vskip 1pt}% + \begin{breakbox}% + \ifdim\lb@skiptop=\z@\relax\else\vspace{\lb@skiptop}\fi% + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \begin{bb@margins}{\lb@skipleft}{\dimen@}% + \else + \lb@debug{start vbox}% + \def\lb@restoreoptions{\options{#1,#2}\option{/longbox/adjust-options}}% + \lb@savefootnotes + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \lb@debug{ width=\the\lb@width, linewidth=\the\linewidth, skipleft=\the\lb@skipleft, right=\the\lb@skipright, total right=\the\dimen@}% + \iftoggle{lb@baselineskip}{\lb@skiptobaseline}{\lb@prevdepth=-\@m pt}% + \lvbox{\lb@mainbox}{0pt}{\lb@width}{0pt}%{\lb@skipleft}{\lb@width}{\lb@skipright}% + \prevdepth=\lb@prevdepth + \fi + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore + \begingroup +}{% + \par\unskip + \endgroup + \lb@insertafter + %\ifdim\lb@skipbottom=\z@\relax\else\vskip\lb@skipbottom\fi% + \ifnum\lb@usevbox=0\relax + \end{bb@margins}% + \ifdim\lb@skipbottom=\z@\relax\else\hrule width \z@ height \lb@skipbottom\fi%\vspace{\lb@skipbottom}\fi% + \iftoggle{lb@baselineskip}{}{\vskip 1sp}% + \end{breakbox}% + \lb@debug{end breakbox}% + \else + \ontoggle{lb@baselineskip}{\lb@skiptobaseline}% + \endlvbox% + \lb@debug{initial lvbox: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@processbox + %\setbox\lb@mainbox=\hbox{\lower \lb@skipbottom\vbox{\offinterlineskip\unvbox\lb@mainbox}}% + \lb@restorefootnotes + \lb@debug{end vbox}% + \fi +} + +\newcommand\longbox@cmd[3]{% + \begingroup + %\options{/options/collectunknown,/longbox/scoped,#2}% set scoped options first + %\option{/longbox/scoped/@adjust-options}% + \lb@peekoptions{#1,#2}% + \leavevmode + %\setbox\lb@mainbox=\hbox{% + % \begingroup + % #3% + % \endgroup + %}% + \setbox\lb@mainbox=\hbox{% + \begingroup + \ifcase\lb@textalign\relax + %default=left + \or%left + \or\hss%center + \or\hss%right + \else%justify + \fi + \lb@insertbefore + #3% + \lb@insertafter + \ifnum\lb@textalign<3\relax\hss\fi% default,left,center + \endgroup + }% + \options{#1,#2}% + \ifdim\option{/longbox/width}=-1sp\relax + \options{/longbox/width=\wd\lb@mainbox}%set to natural width + \fi + \option{/longbox/adjust-options}% + % make it a vbox + \setbox\lb@mainbox=\vbox{\offinterlineskip% + \hbox to \option{/longbox/width}{% + \unhbox\lb@mainbox + }% + }% + \def\lb@restoreoptions{}% + \letoption{/longbox/height-align}\lb@halign + \lb@height=\option{/longbox/height}\relax + \lb@baseline=\option{/longbox/baseline/@ord}\relax + \lb@processbox + \endgroup +} + +\newcommand\lb@processbox{% + \ifdim\lb@height<0pt\relax + \lb@setbaseline{\lb@mainbox}% + \else + \lb@restrictheight + \fi + \lb@typesetbox +} + +\newcommand\lb@typesetbox{% + \ifinlvbox + \iftoggle{lb@breakable}{% + %\lb@debug{disable breakable due to nesting of long-boxes}% + \togglefalse{lb@breakable}% + }{}% + \fi + \ifhmode\lb@single@{\lb@mainbox}\else\lb@typeset\fi +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@restrictheight{% + \lb@typeout{restrict height to \the\lb@height}% + \lb@splitheight=\lb@height% + %lb@debug{before height split: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + %split failed.. do nothing + \lb@debug{could not restrict height}% + \else + % store splitted off content in the mainbox (and discard the rest) + \setbox\lb@mainbox\vbox{\unvbox\lb@headbox}% + \lb@debug{restricted height to \the\ht\lb@mainbox}% + \fi + % set baseline + \lb@setbaseline{\lb@mainbox}% + % height align + %\letoption{/longbox/height-align}\lb@halign + \eifstrequal{\lb@halign}{bottom}% + {\setbox\lb@mainbox=\vbox{\hbox{\vbox to \lb@splitheight{\vss\unvbox\lb@mainbox}}}}% + {\eifstrequal{\lb@halign}{middle}% + {\dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\hbox{% + \lower \dimexpr0.5\dimen@ + \dp\lb@mainbox\relax% + \vbox to \lb@splitheight{\vss\unvbox\lb@mainbox\vss}}}}% + {% default is top + \dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\vtop to \lb@splitheight{\box\lb@mainbox\vss}}% + }% + }% +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newlength\lb@neededvspace +\newcommand\lb@typeset[1][0pt]{% + \iftoggle{lb@breakable}{% + \lb@setfreevspace + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skiptop+\lb@skipbottom\relax}% + \lb@debug{needed: \the\lb@neededvspace, available: \the\lb@freevspace}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@single@{\lb@mainbox}% + \else + \lb@typeout{longbox needs splitting}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skiptop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \ifdim\dimexpr\lb@freevspace + #1\relax<\textheight\relax % test if we were at a fresh page.. (and prevent infinite recursion) + \lb@debug{failed to split the box, inserting a page break}% + \hrule \@height\z@ \@width\hsize + \lb@eject% + \lb@typeset[\textheight]% try again, but pass \textheight to guard against infinite recursion + \else + % on a fresh page we should not fail anymore.. just output as is.. + % lb@warncannotsplit + \lb@single@{\lb@mainbox}% + \fi + \else + % first part success + \lb@typeout{first part splitted}% + \lb@first@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest + \fi + \fi + }{%\else + \lb@debug{unbreakable box}% + \lb@single@{\lb@mainbox}% always directly output an unbreakable box + }% +} + +\newcommand\lb@typesetrest{% + \lb@setfreevspace% + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skipbottom+\lb@skipbreaktop\relax}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@typeout{output last part of box}% + \lb@last@{\lb@mainbox}% + \else + \lb@debug{split box further}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skipbreaktop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \lb@typeout{failed to split box!}% + \lb@last@{\lb@mainbox}% + \else + % middle part success + \lb@typeout{output middle part of box}% + \lb@middle@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest% continue the iteration... + \fi + \fi +} + +% -------------------------------------------------------- +% Split a long vbox over multiple pages. +% This code is based on similar code in the mdframed package +% -------------------------------------------------------- + +\newlength\lb@splitheight +\newlength\lb@insurance % tiny extra space to ensure our box will really fit +\setlength\lb@insurance{1pt} + +% expects split target height in lb@splitheight, and splits off the start of lb@mainbox to lb@headbox +\newcommand\lb@splitbox{% + \ifdim\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax>\lb@splitheight\relax + % the main box is larger than our target split height.. + \ifdim\lb@extrasplit>\lb@splitheight\relax + % not enough space to bother + \lb@typeout{not enough space on page for a split}% + \setbox\lb@headbox=\vbox{}% empty head + \else + % try a split; lower the split height a bit so we are sure to fit + \advance\lb@splitheight -\lb@insurance\relax + \lb@debug{split: \the\lb@splitheight, from \the\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax}% + \setbox\lb@savebox=\vbox{\unvcopy\lb@mainbox}% save original + \lb@trysplit{\lb@splitheight}% + \ifdim\dimexpr\ht\lb@headbox + \dp\lb@headbox>\lb@splitheight\relax + % too big, bad split. Try other splits.. iterate N times with 1 or 5pt less before giving up + \dimen@=\lb@splitheight\relax + \@tempcnta=\z@\relax + \loop + \ifdim\dimexpr\ht\lb@headbox+\dp\lb@headbox\relax>\lb@splitheight\relax + \ifnum\@tempcnta<50% + \advance\dimen@ by -\p@\relax% try a slightly smaller height.. + \else + \advance\dimen@ by -5\p@\relax% try larger increase after 50pt.. + \fi + \advance\@tempcnta by \@ne\relax + \lb@ignorevbadness + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \lb@trysplit{\dimen@}% + \ifdim\lb@extrasplit<\dimen@\relax\else\lb@splitstop\fi % don't try to split too small + \ifnum\@tempcnta<100\relax\else\lb@splitstop\fi % and not more than N attempts + \repeat% + \ifnum\@tempcnta<100\relax + \dimen@=\dimexpr\lb@splitheight - \ht\lb@headbox - \dp\lb@headbox\relax + \ifdim\dimen@>\option{/longbox/split-badness}\relax + \lb@warnbadsplit{\dimen@}% + \fi + \fi + \fi + \fi + \else + % mainbox fits in our target lb@splitheight + \setbox\lb@headbox=\vbox{\unvbox\lb@mainbox}% + \setbox\lb@mainbox=\vbox{}% + \fi +} + +\newcommand\lb@splitstop{% + \lb@typeout{cannot find a good split}% + \let\iterate\relax + \lb@warncannotsplit + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \setbox\lb@headbox=\vbox{}% empty head + \@tempcnta=\@M\relax +} + +\newcommand\lb@trysplit[1]{% try to split at given height + \lb@typeout{try to split at: \the\dimexpr #1\relax}% + \lb@ignorevbadness + \setbox\lb@headbox=\vsplit\lb@mainbox to #1\relax% + \setbox\lb@headbox=\vbox{\unvbox\lb@headbox}% + \setbox\lb@mainbox=\vbox{\unvbox\lb@mainbox}% +} + +% -------------------------------------------------------- +% The longbox environment uses options to set its options +% -------------------------------------------------------- + + +% keys and styles that can be set once globally +\options{% + /longbox/.new family, +}% + +\options{/longbox,% + % computed + @part-needtop/.new toggle, + @part-needbottom/.new toggle, + @part-height/.new length, + @part-width/.new length, + @part-depth/.new length, + @content-box-height/.new length, + @content-box-width/.new length, + @content-box-depth/.new length, + @breakat-previous/.new length, + @lower/.new length, + % + debug/.new toggle, + verbose/.new toggle, + render/.new value =\lb@render@fbox, + adjust-options/.new value = {\longbox@adjustoptions}, + eject/.new value = {\protect\vfill\protect\eject}, + use-vbox/.new toggle = true, + split-minimum/.new length = {1.5\baselineskip}, + split-badness/.new length = \baselineskip, + % + height-align/.new choice= {top,middle,bottom}, + baseline/.new choice = {bottom,middle,top}, + text-align/.new choice = {default,left,center,right,justify}, + vertical-align/.new choice = {baseline,bottom,middle,top,text-bottom,text-top,super,sub}, + raise/.new length = {0pt}, + baseline-skip/.new toggle =true, + % + height/.new length = -1sp, + width/.new length = -1sp, + outer-height/.new length= -1sp, + outer-width/.new length = -1sp, + insert-before/.new value= {}, + insert-after/.new value = {}, + breakat/.new value = {}, + breakable/.new toggle = false, + skip/.new style = {skip-top=#1,skip-right=#1,skip-bottom=#1,skip-left=#1}, + skip-top/.new length, + skip-right/.new length, + skip-bottom/.new length, + skip-left/.new length, + skip-break-bottom/.new length, + skip-break-top/.new length, +} + +\newcommand\longbox@adjustoptions{% + %\typeout{ standard longbox adjustoptions}% + \lb@debug{ current width=\the\dimexpr\option{/longbox/width}, outer=\the\dimexpr\option{/longbox/outer-width}, linewidth=\the\linewidth}% + \ontoggle{/longbox/debug}{\option@invoke{/longbox/verbose}{true}}% + % adjust height + \ifdim\option{/longbox/height}=-1sp\relax + \ifdim\option{/longbox/outer-height}=-1sp\else + \option@invoke{/longbox/height}% + {\option{/longbox/outer-height}-\option{/longbox/skip-top}-\option{/longbox/skip-bottom}}% + \fi + \fi + % set width + \ifdim\option{/longbox/width}=-1sp\relax + \ifdim\option{/longbox/outer-width}=-1sp\relax + \option@invoke{/longbox/outer-width}{\linewidth}% + \fi + \dimen@=\dimexpr\option{/longbox/outer-width}-\option{/longbox/skip-left}-\option{/longbox/skip-right}\relax + \ifdim\dimen@<\z@\relax\dimen@=\z@\fi + \option@invoke{/longbox/width}{\dimen@}% + \fi + % use a breakbox whenever we are in external vertical mode and not width or height restricted. + \iftoggle{/longbox/use-vbox}{}{% + \ifinner\toggletrue{/longbox/use-vbox}\else + \ifhmode\toggletrue{/longbox/use-vbox}\else + \ifdim\option{/longbox/height}>-1sp\toggletrue{/longbox/use-vbox}\else + \iftoggle{/longbox/breakable}{}{\toggletrue{/longbox/use-vbox}}% + \ifoptionblank{/longbox/breakat}{}{\toggletrue{/longbox/use-vbox}}% + \fi\fi\fi + }% +} + +\newenvironment{longbox}[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \begin{longbox@env}{/longbox}{#1}% +}{\end{longbox@env}} + +\newcommand\lbox[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \longbox@cmd{/longbox}{#1}% +} + +\newcommand*\lb@render@fbox{% + %\typeout{render defaultbox: bgcolor=\bb@bgcolor, needtop=\iftoggle{/longbox/@part-needtop}{true}{false}}% + \@ovdx=\dimexpr\option{/longbox/@part-width} - 2\fboxrule\relax% + \@ovdy=\dimexpr\option{/longbox/@part-height}\relax% + \iftoggle{/longbox/@part-needbottom}% + {\@tempdima=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdima=\dimexpr\fboxrule + \bb@stickout\relax + \advance\bb@height by \@tempdima + \advance\@ovdy by \@tempdima}% + \iftoggle{/longbox/@part-needtop}% + {\@tempdimb=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdimb=\dimexpr\bb@stickout\relax + \advance\bb@height by \@tempdimb + \advance\@ovdy by \@tempdimb}% + % + \hbox{\lower \@tempdima\vbox{% + \vskip -\@tempdimb + \ontoggle{/longbox/@part-needtop}{\lb@debug{toprule wd=\expandafter\the\option{/longbox/width}}\hrule width \option{/longbox/@part-width} height \fboxrule}% + \hbox{% + \vrule width \fboxrule height \@ovdy% + \ifx\bb@bgcolor\@empty + \vrule width \@ovdx height \z@\relax + \else + {\color{\bb@bgcolor}\vrule width \@ovdx height \@ovdy}% + \fi + \vrule width \fboxrule height \@ovdy% + }% + \ontoggle{/longbox/@part-needbottom}{\hrule width \option{/longbox/@part-width} height \fboxrule}% + }}% +} \ No newline at end of file diff --git a/spec/v1.4.0-rc.5/longfbox.sty b/spec/v1.4.0-rc.5/longfbox.sty new file mode 100644 index 00000000..0df01331 --- /dev/null +++ b/spec/v1.4.0-rc.5/longfbox.sty @@ -0,0 +1,1344 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longfbox}[2015/12/01, Daan Leijen, Provides long fbox that can break over pages] + +\RequirePackage{options} +\RequirePackage{longbox} +\RequirePackage{pict2e} +\RequirePackage{ellipse} + +% -------------------------------------------------------- +% Dimension calulations +% -------------------------------------------------------- + +% dimmin/dimmax return minimum or maximum dimension +\providecommand\dim@min[2]{\ifdim#1>#2#2\else #1\fi} +\providecommand\dim@max[2]{\ifdim#1>#2#1\else #2\fi} + +\newcommand*\option@dimmin[2]{\dim@min{\option{#1}}{\option{#2}}} +\newcommand*\option@dimmax[2]{\dim@max{\option{#1}}{\option{#2}}} + + +% -------------------------------------------------------- +% Add a new 'sides' option type +% -------------------------------------------------------- + +\options{ + /handlers/new sides/.new handler = []{ + \ifblank{#2}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#1-top={##1}, #1-right={##2}, #1-bottom={##3}, #1-left={##4}}}}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#2}}}% + \optionsalso{ + #1/.new cmdx = {##1,##2,##3,##4,##5\relax}{,,,,\relax}{% + \ifblank{##2##3##4}{\option{#1/@cmd@sides}{##1}{##1}{##1}{##1}}% + {\ifblank{##3##4}{\option{#1/@cmd@sides}{##1}{##2}{##1}{##2}}% + {\ifblank{##4}{\option{#1/@cmd@sides}{##1}{##2}{##3}{##2}}% + {\option{#1/@cmd@sides}{##1}{##2}{##3}{##4}}% + }% + }% + }, + #1/.type = sides, + }% + },% +} + +\newcommand*\optionlengthlimit[3]{% len, min, max + \letoption{#1}\opt@temp + \ifdim\opt@temp<\dimexpr#2\relax + \option@invoke{#1}{#2}% + \else\ifdim\opt@temp>\dimexpr#3\relax + \option@invoke{#1}{#3}% + \fi\fi +} + +\newcommand*\optionradiuslimit[4]{% r1, r2, min, max + \letoption{#1}\opt@tempa + \letoption{#2}\opt@tempb + \ifdim\opt@tempa<\dimexpr#3\relax\option@invoke{#1}{#3}\fi + \ifdim\opt@tempb<\dimexpr#3\relax\option@invoke{#2}{#3}\fi + \ifdim\dimexpr\opt@tempa + \opt@tempb\relax=\z@\relax\else + \ifdim\dimexpr\opt@tempa+\opt@tempb\relax>\dimexpr#4\relax + \edef\opt@perc{\the\numexpr(\number\dimexpr#4\relax)/% + (\number\dimexpr(\opt@tempa+\opt@tempb)/100\relax)}% + %\typeout{scale:\the\opt@tempa,\the\opt@tempb, by \opt@perc percent to make \the\dimexpr#4\relax}% + \edef\opt@temp{\dimexpr\opt@perc\dimexpr\the\opt@tempa\relax / 100\relax}% + \option@einvoke{#1}{\opt@temp}% + \option@einvoke{#2}{\dimexpr#4 - \opt@temp\relax}% + %\typeout{ scaled to: \the\opt@temp,\the\dimexpr#4 - \opt@temp\relax}% + \fi + \fi +} + + +% \begin{macro}{\trig@atantan} +% \marg{a}\marg{b}\marg{$\alpha$}{dimen$_\mathit{reg}$}\\ +% Assigns $\atan_2(\frac{\sin(\alpha)}{b},\frac{\cos(\alpha)}{a})$ to dimension register \textit{dimen$_\mathit{reg}$}, +% where $a$ and $b$ are dimensions. +% Returns $\alpha$ when $a = b$, or when $a=0$ or $b=0$. +% \begin{macrocode} +\newcommand*\trig@atantan[4]{% + %\typeout{ atantan:(\the#1,\the#2,\the#3, #4)}% + \@tempdima\dimexpr#1\relax + \@tempdimb\dimexpr#2\relax +% \end{macrocode} +% If $a = b$, we have a circle and the result is $\alpha$. +% \begin{macrocode} + \ifdim\@tempdima=\@tempdimb + #4\dimexpr#3\relax + \else\ifdim\@tempdima=\z@ + #4\dimexpr#3\relax + \else\ifdim\@tempdimb=\z@ + #4\dimexpr#3\relax + \else + \edef\trig@temp{\strip@pt\dimexpr#3\relax}% + \CalculateSin{\trig@temp}\CalculateCos{\trig@temp}% + \@tempdimc\dimexpr1\p@ * \dimexpr\UseSin{\trig@temp}\p@\relax/\@tempdimb\relax + \@tempdimd\dimexpr1\p@ * \dimexpr\UseCos{\trig@temp}\p@\relax/\@tempdima\relax + \pIIe@atantwo{\@tempdimc}{\@tempdimd}\dimen@ + \ifdim\dimen@<\z@ + \ifdim\dimexpr#3\relax<\z@\else\advance\dimen@360\p@\fi + \fi + \@tempdima\dimexpr#3 - \dimen@\relax + \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi + \ifdim\@tempdima<360\p@\else\advance\dimen@360\p@\fi + %\typeout{atan: \the\dimexpr#3\relax versus. \the\dimen@ }% + #4\dimen@ + \fi\fi\fi +} +% \end{macrocode} +% \end{macro} + +% rough approximation of the perimeter; +% if |radius-x == radius-y| = 0 (a circle), the approximation is precise. +% otherwise, works best when |angle2-angle1| <= 45 and gets worse from there on. +\newcommand*\ellip@letarcperimeter[5]{% 'radius-x', 'radius-y', 'angle-1', 'angle-2', '\result' + \@tempdima\dimexpr#3\relax + \@tempdimb\dimexpr#4\relax + \@tempdimc\dimexpr\@tempdima - \@tempdimb\relax + \ifdim\@tempdimc<\z@\@tempdimc-\@tempdimc\fi + \ifdim#1=#2\relax% circle? + \edef\@tempa{\strip@pt\@tempdimc}% angle difference delta as factor + \dimen@\@tempa\dimexpr#1\relax% r*delta + \dimen@0.017453\dimen@% (2*pi/360) * r * delta = 2*pi*r * (delta/360) + \else% ellipse: take the distance between the points on the ellipse, works pretty good if delta <= 45, and ok'ish for delta <= 90 + \@ovro\dimexpr#1\relax + \@ovri\dimexpr#2\relax + \edef\fbox@tempa{\strip@pt\@tempdima}% + \edef\fbox@tempb{\strip@pt\@tempdimb}% + \pIIe@ellip@sincost{\fbox@tempa}{\fbox@tempb}% + \@tempdima\@ellipcosone\@ovro + \@tempdimb\@ellipsinone\@ovri + \@tempdimc\@ellipcostwo\@ovro + \@tempdimd\@ellipsintwo\@ovri + \advance\@tempdimc by -\@tempdima% + \advance\@tempdimd by -\@tempdimb% + \pIIe@ellip@csqrt{\@tempdimc}{\@tempdimd}{\dimen@}% + %\typeout{ distance: \the\dimen@, from (x,y)=(\the\@tempdimc,\the\@tempdimd), radii=(\the#1,\the#2), angles=(\the#3,\the#4)}% + \fi + \edef#5{\the\dimen@}% +} + + +% ------------------------------------------------------------------------------ +% Borders using the picture environment +% ------------------------------------------------------------------------------ + +\newcommand*\fbox@border@pict{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \begingroup + \hbox{% + \unitlength\p@ + \begin{picture}(0,0)(0,\optionunit{/fbox/@border-box-height})% bottom-left is origin + % markers + \ontoggle{/fbox/show-markers}{% + \linethickness{\option{/fbox/marker-width}}% + \optioncolor{/fbox/marker-color}% + \fbox@rect{0pt}{0pt}{\option{/fbox/@border-box-width}}{\option{/fbox/@border-box-height}}% + \fbox@rect{\option{/fbox/border-left-width}}{\option{/fbox/border-\fbox@bottom-width}}% + {\option{/fbox/@border-box-width}-\option{/fbox/border-right-width}}% + {\option{/fbox/@border-box-height}-\option{/fbox/border-\fbox@top-width}}%S + }% + %compute corner coordinates + \fbox@border@calccorners + %put down the background color + \fbox@border@colorbackground + \option{/fbox/picture-insert-before}% + %put down the sides + \fbox@border@side{3}{-2}{0}%top + \fbox@border@side{5}{-4}{3}%left + \fbox@border@side{-6}{7}{2}%bottom + \fbox@border@side{-8}{1}{1}%right + \end{picture}% + }% + \endgroup + \fi +} + +\newcommand*\fbox@border@pict@after{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \letoption{/fbox/picture-insert-after}\fbox@insertafter + \eifblank{\fbox@insertafter}{}{% + \begingroup + \hbox{% + \begin{picture}(0,0)(0,0)% bottom-left is origin + \fbox@insertafter + \end{picture}% + }% + \endgroup + }% + \fi +} + +\newcommand*\fbox@border@side[3]{% + \fbox@setoct@angles{#1}% + \edef\fbox@style{\option{/fbox/border-\fbox@side-style}}% + \optioncolor{/fbox/border-\fbox@side-color}% + \option{/fbox/picture-side-insert-before}% + \ifcsdef{fbox@border@pict@\fbox@style}% + {\csuse{fbox@border@pict@\fbox@style}{#1}{#2}{#3}}% + {\PackageWarning{longfbox}{Unknown style "\fbox@style". Using "solid" instead.}% + \fbox@border@pict@solid{#1}{#2}{#3}}% + \option{/fbox/picture-side-insert-after}% +} + +% ------------------------------------------------------------------------------ +% Define standard border styles for the picture environment +% +% a style has the form \fbox@border@pict@ + + + + + + +
+
+
+
P4Runtime Specification
+
version 1.4.0-dev
+
+
+
The P4.org API Working Group
+
2024-09-13
+
+

Abstract. P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.

+ + +

1. Introduction and Scope

+

This document is published by the P4.org API Working Group, which was +chartered [21] to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called P4Runtime. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +https://github.com/p4lang/p4runtime/tree/main/proto. +

1.1. P4 Language Version Applicability

+

P4Runtime is designed to be implemented in conjunction with the P416 language +version or later. P414 programs should be translated into P416 to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P416 1.0, but were introduced in P416 1.2.4 [35]. For +this version of P4Runtime, we recommend using P416 1.2.4 [35]. +

+

This version of the P4Runtime specification does not yet explicitly +address compatibility with the following P416 language features +introduced in versions 1.2.2 or 1.2.4 of the language specification: +

+
    +
  • Added support for generic structures [34]. +
  • +
  • Added support for additional enumeration types [34]. +
  • +
  • Added support for 0-width bitstrings and varbits [34]. +
  • +
  • Clarified restrictions for parameters with default values +[35]. +
  • +
  • Allow ranges to be specified by serializable enums +[35]. +
  • +
  • Added list type [35]. +
  • +
  • Clarified behavior of table with no key property, or if its list +of keys is empty [35]. +
+

1.2. In Scope

+

This specification document defines the semantics of P4Runtime messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime: +

+
    +
  • Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA) [24] externs (e.g. Counters, Meters, Action +Profiles, ). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0. +
  • +
  • Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism. +
  • +
  • Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy. +
  • +
  • Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities. +
  • +
  • Packet I/O to enable streaming packets to & from the control plane. +
  • +
  • Batching support, with different atomicity guarantees. +
  • +
  • In-the-field device-reconfiguration with a new P4 data plane. +
+ +

The following are in the scope of this specification document: +

+
    +
  • Rationale for the P4Runtime design. +
  • +
  • Reference architecture and use-cases for deploying a P4Runtime service. +
  • +
  • Detailed description of the API semantics. +
  • +
  • Requirements for conformant implementations of the API. +
+

1.3. Not In Scope

+

The following are not in scope of P4Runtime: +

+
    +
  • Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +[41]. An open source implementation of these APIs is also in progress +as part of the Stratum project [43]. +
  • +
  • Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures. +
+ +

The following are not in scope of this specification document: +

+
    +
  • Description of the P4 programming language; it is assumed that the reader is +already familiar with P416 [1]. +
  • +
  • Descriptions of gRPC and Protobuf files in general. +
  • +
  • Controller role definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme. +
+

2. Terms and Definitions

+
+
arbitration
+
Refers to the process through which P4Runtime ensures that at any given +time, there is a single primary controller (i.e. a client with write access) +for a given role. Also referred to as “client arbitration”. +
+
client
+
The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +
+
COS
+
Class of Service. +
+
device
+
Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +
+
entity
+
An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +
+
gRPC
+
gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +[11]. +
+
HA
+
High-Availability. Refers to a redundancy architecture. +
+
Instrumentation
+
The part of the P4Runtime server which implements the calls to the device or +target native “SDK” or backend. +
+
IPC
+
Inter-Process Communication. +
+
P4 Blob
+
A more colloquial term for P4 Device Config (Blob = Binary Large Object). +
+
P4 Device Config
+
The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its “program.” +
+
P4Info
+
Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +
+
P4RT
+
Abbreviation for P4Runtime. +
+
Protobuf (Protocol Buffers)
+
The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See [26]. +
+
PSA
+
Portable Switch Architecture [24]; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +
+
RPC
+
Remote Procedure Call. +
+
RTT
+
Round-trip time. +
+
SDN
+
Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network controller. +
+
SDN port
+
A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +
+
server
+
The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +
+
stream
+
Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (StreamChannel), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and client arbitration, among other things. +
+
switch config
+
Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +
+
target
+
The hardware or software entity which “executes” the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with “device”. +
+
URI
+
Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.

3. Reference Architecture

+

Figure 1 represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. P4Runtime only grants write access to a +single primary controller for each read/write entity. A role defines a grouping +of P4 entities. P4Runtime allows for a primary controller for each role, and a +role-based client arbitration scheme ensures only one controller has +write access to each read/write entity, or the pipeline config itself. Any +controller may perform read access to any entity or the pipeline config. Later +sections describe this in detail. For the sake of brevity, the term controller +may refer to one or more controllers. +

+

The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +[19]. It may be compiled via protoc the Protobuf compiler +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server. +

+

Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository [20]. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, e.g. via callbacks, thus reducing the burden of implementing +P4Runtime. +

+

The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard. +

+

The controller can also set the ForwardingPipelineConfig, which amounts to +installing and running the compiled P4 program output, which is included in the +p4_device_config Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +ForwardingPipelineConfig to retrieve the device config and the P4Info. +

+
+

reference-architecture +

+
+ +
Figure 1. P4Runtime Reference Architecture.

3.1. P4Runtime Service Implementation

+

The P4Runtime API is implemented by a program that runs a gRPC server which +binds an implementation of auto-generated P4Runtime Service interface. This +program is called the “P4Runtime server.” The server must listen on TCP port +9559 by default, which is the port that has been allocated by IANA for the +P4Runtime service. Servers should allow users to override the default port +using a configuration file or flag when starting the server. Uses of other +port numbers as the default should be discontinued. +

3.1.1. Security concerns

+

Appropriate measures and security best practices must be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. Mutual TLS (mTLS) may +be used to facilitate the authentication of the client by the server and +vice-versa. +

3.2. Idealized Workflow

+

In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the ForwardingPipelineConfig +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a SetForwardingPipelineConfig +RPC. Metadata in the P4Info describes both the overall program itself +(PkgInfo) as well as all entity instances derived from the P4 program +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise “handle” used in API +calls. +

+

In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible. +

+

In some use cases, it is expected that a controller will store a +collection of multiple P4 “packages”, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the ForwardingPipelineConfig from the target via the +GetForwardingPipelineRequest RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state. +

3.3. P4 as a Behavioral Description Language

+

P4 can be considered a behavioral description of a switching device which may or +may not execute “P4” natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a SetForwardingPipelineRequest to +change its pipeline “program”, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device. +

+

While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API. +

+

In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the PkgInfo +message as well as the embedded doc fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections. +

3.4. Alternative Workflows

+

Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary. +

3.4.1. P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config

+

In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +p4_device_config. The device's configuration might be derived via some other +means to implement the P4 source code's intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane. +

3.4.2. No P4 Source Available, P4Info Available

+

In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are: +

+
    +
  1. +

    The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security. +

  2. +
  3. +

    The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info. +

+ +

As discussed in Section 3.3, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, e.g. documentation. +

3.4.3. Partial P4Info and P4 Source are Available

+

In this situation, a subset of the target's pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code. +

3.4.4. P4Info Role-Based Subsets

+

In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more. +

3.5. P4Runtime State Across Restarts

+

All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade. +

4. Controller Use-cases

+

P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +section. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime's flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex. +

4.1. Single Embedded Controller

+

Figure 2 shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases. +

+

P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC. +

+
+

single-embedded-controller +

+
+ +
Figure 2. Use-Case: Single Embedded Controller

4.2. Single Remote Controller

+

Figure 3 shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections. +

+
+

single-remote-controller +

+
+ +
Figure 3. Use-Case: Single Remote Controller

4.3. Embedded + Single Remote Controller

+

Figure 4 illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller. +

+

For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables. +

+
+

embedded-plus-single-remote-controller +

+
+ +
Figure 4. Use-Case: Embedded Plus Single Remote Controller

4.4. Embedded + Two Remote Controllers

+

Figure 5 illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +e.g. routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership. +

+
+

embedded-plus-two-remote-controllers +

+
+ +
Figure 5. Use-Case: Embedded Plus Two Remote Controllers

4.5. Embedded Controller + Two High-Availability Remote Controllers

+

Figure 6 illustrates a single +embedded controller plus two remote controllers in an active-standby (i.e. +primary-backup) HA (High-Availability) configuration. Controller #1 is the +active controller and is in charge of some entities. If it fails, Controller #2 +takes over and manages the tables formerly owned by Controller #1. The mechanics +of HA architectures are beyond the scope of this document, but the P4Runtime +role-based client arbitration scheme supports it. +

+
+

embedded-plus-two-remote-ha-controllers +

+
+ +
Figure 6. Use-Case: Embedded Plus Two Remote High-Availability Controllers

5. Client Arbitration and Controller Replication

+

The P4Runtime interface allows multiple clients (i.e. controllers) to be +connected to the P4Runtime server running on the device at the same time for the +following reasons: +

+
    +
  1. +

    Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, “roles” (or “realms”) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +primary and the rest are backups. Role definition, i.e. how P4 entities get +assigned to each role, is out-of-scope of this document. +

  2. +
  3. +

    Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby backup controllers. These can already have a connection +open, which can help them become primary more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved. +

+ +

To support multiple controllers, P4Runtime uses the streaming channel (available +via StreamChannel RPC) for session management. The workflow is described as +follows: +

+
    +
  • +

    Each controller instance (e.g. a controller process) can participate in one or +more roles. For each (device_id, role), the controller receives an +election_id. This election_id can be the same for different roles and/or +devices, as long as the tuple (device_id, role, election_id) is +unique among live controllers, as defined below. For each (device_id, +role) that the controller wishes to control, it establishes a +StreamChannel with the P4Runtime server responsible for that device, and +sends a MasterArbitrationUpdate message containing that tuple of +(device_id, role, election_id) values. The P4Runtime server selects a +primary independently for each (device_id, role) pair. The primary is the +client that has the highest election_id that the device has ever received +for the same (device_id, role) values. A connection between a controller +instance and a device id which involves a persistent StreamChannel +can be referred to as a P4Runtime client. +

    +

    Note that the P4Runtime server does not assign a role or election_id to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the election_id values used for each +StreamChannel. The P4Runtime server only keeps track of the (device_id, +role, election_id) of each StreamChannel that has sent a successful +MasterArbitrationUpdate message, and maintains the invariant that all such +3-tuples are unique among live controllers. A server must use all three of +these values from a WriteRequest message to identify which client is making +the WriteRequest, not only the election_id. This enables controllers to +re-use the same numeric election_id values across different (device_id, +role) pairs. P4Runtime does not require election_id values be reused +across such different (device_id, role) pairs; it allows it. +

  • +
  • +

    To start a controller session, a controller first opens a bidirectional stream +channel to the server via the StreamChannel RPC for each device. This stream +will be used for two purposes: +

    +
      +
    • +

      Session management: As soon as the controller opens the stream +channel, it sends a StreamMessageRequest message to the switch. The +controller populates the MasterArbitrationUpdate field in this message +using its role and election_id, as well as the device_id of the +device. Note that the status field in the MasterArbitrationUpdate is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below. +

    • +
    • +

      Streaming of notifications (e.g. digests) and packet I/O: The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the primary controller can participate in +packet I/O. This feature is explained in more details in the Packet +I/O section. +

    + +

    Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state. +

  • +
  • +

    Note that the stream is opened per device. In case a switching platform has +multiple devices (e.g. multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different primary clients for +different devices. In this case, it is the responsibility of the P4Runtime +server to keep track of the primary for each device (and role). More +specifically, the P4Runtime server will know which stream corresponds to the +primary controller for each pair of (device_id, role) at any point of +time. +

  • +
  • +

    The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered “offline”, +“disconnected”, or “dead” as soon as its stream channel to the switch is +broken. When a primary channel gets broken: +

    +
      +
    1. +

      An advisory message is sent to all other controllers for that device_id +and role, as described in a +later section; and +

    2. +
    3. +

      The P4Runtime server will be without a primary controller, until a client +sends a successful MasterArbitrationUpdate (as per the rules in a +later section). +

    +
  • +
  • +

    The mechanism through which the controller receives the P4Runtime server +details are implementation specific and beyond the scope of this +specification. This includes the device_id, ip and port, as +well as the Forwarding Pipeline Config. Similarly, the mechanism through +which the P4Runtime server receives its switch config (which notably includes +the device_id) is beyond the scope of this specification. Nevertheless, if +the server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks. +

+ +

gRPC enables the server to identify which client originated each message in the +StreamChannel stream. For example, the C++ gRPC library [12] in +synchronous mode enables a server process to cause a function to be called when +a new client creates a StreamChannel stream. This function should not return +until the stream is closed and the server has completed any cleanup required +when a StreamChannel is closed normally (or broken, e.g. because a client +process unexpectedly terminated). Thus the server can easily associate all +StreamChannel messages received from the same client, because they are +processed within the context of the same function call. +

+

A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values device_id, role, and election_id in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods [10] that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server. +

5.1. Default Role

+

A controller can omit the role message in MasterArbitrationUpdate. This +implies the “default role”, which corresponds to “full pipeline access”. +This also implies that a default role has a role_id of "" (default). +If using a default role, all RPCs from the controller (e.g. Write) must +leave the role unset. +

5.2. Role Config

+

The role.config field in the MasterArbitrationUpdate message sent by the +controller describes the role configuration, i.e. which operations are in the +scope of a given role. In particular, the definition of a role may include the +following: +

+
    +
  • A list of P4 entities for which the controller may issue Write updates and +receive notification messages (e.g. DigestList and +IdleTimeoutNotification). +
  • +
  • Whether the controller is able to receive PacketIn messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketIn messages should be sent to the controller. +
  • +
  • Whether the controller is able to send PacketOut messages, along with a +filtering mechanism based on the values of the PacketMetadata fields to +select which PacketOut messages are allowed to be sent by the controller. +
+ +

An unset role.config implies “full pipeline access” (similar to the default +role explained above). In order to support different role definition schemes, +role.config is defined as an Any Protobuf message [37]. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion. +

+

It is the job of the P4Runtime server to remember the role.config for every +device_id and role pair. +

5.3. Rules for Handling MasterArbitrationUpdate Messages Received from Controllers

+
    +
  1. +

    If the MasterArbitrationUpdate message is received for the first time on +this particular channel (i.e. for a newly connected controller): +

    +
      +
    1. +

      If device_id does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +NOT_FOUND error. +

    2. +
    3. +

      If the election_id is set and is already used by another live +controller for the same (device_id, role), the P4Runtime server shall +terminate the stream by returning an INVALID_ARGUMENT error. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the number of open streams for the given (device_id, role) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a RESOURCE_EXHAUSTED error. +

    8. +
    9. +

      Otherwise, the controller is added to a list of live controllers for +the given (device_id, role) and the server remembers the +controllers device_id, role and election_id for this gRPC +channel. See below for the rules to determine if this controller becomes +a primary or backup, and what notifications are sent as a consequence. +

    +
  2. +
  3. +

    Otherwise, if the MasterArbitrationUpdate message is received from an +already live controller: +

    +
      +
    1. +

      If the device_id does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. +

    2. +
    3. +

      If the role does not match the current role assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +FAILED_PRECONDITION error. If the controller wishes to change its role, +it must close the current stream channel and open a new one. +

    4. +
    5. +

      If role.config does not match the “out-of-band” scheme previously +agreed upon, the server must return an INVALID_ARGUMENT error. +

    6. +
    7. +

      If the election_id is set and is already used by another live +controller (excluding the controller making the request) for the same +(device_id, role), the P4Runtime server shall terminate the stream +by returning an INVALID_ARGUMENT error. +

    8. +
    9. +

      Otherwise, the server updates the election_id it has stored for this +controller. This change might cause a change in the primary client (this +controller might become primary, or the controller might have downgraded +itself to a backup, see below), as well as notifications being sent to +one or more controllers. +

    +
+ +

If the MasterArbitrationUpdate is accepted by either of the two steps above +(cases 1.5. and 2.5. above), then the server determines if there are changes in +the primary client. Let election_id_past be the highest election ID the server +has ever seen for the given device_id and role (including the one of the +current primary if there is one). +

+
    +
  1. +

    If election_id is greater than or equal to election_id_past, then the +controller becomes, or stays, primary. The server updates the role +configuration to role.config for the given role. Furthermore: +

    +
      +
    1. +

      If there was no primary for this device_id and role before and +there are no Write requests still processing from a previous primary, +then the server immediately sends an advisory notification to all +controllers for this device_id and role. See the +following section for the format of the +advisory message. +

    2. +
    3. +

      If there was a previous primary, including this controller, or Write +requests in flight, then the server carries out the following steps +(in this order): +

      +
        +
      1. +

        The server stops accepting Write requests from the previous primary +(if there is one). At this point, the server will reject all Write +requests with PERMISSION_DENIED. +

      2. +
      3. +

        The server notifies all controllers other than the new primary client +of the change by sending the advisory notification described in +the following section. +

      4. +
      5. +

        The server will finish processing any Write requests that have +already started. If there are errors, they are reported as usual to +the previous primary. If the previous primary has already +disconnected, any possible errors are dropped and not reported. +

      6. +
      7. +

        The server now accepts the current controller as the new primary, +thus accepting Write requests from this controller. The server +updates the highest election ID (i.e. election_id_past) it has seen +for this device_id and role to election_id. +

      8. +
      9. +

        The server notifies the new primary by sending the advisory message +described in the following section. +

      +
    +
  2. +
  3. +

    Otherwise, the controller becomes a backup. If the controller was previously +a primary (and downgraded itself), then an advisory message is sent to all +controllers for this device_id and role. Otherwise, the advisory +message is only sent to the controller that sent the initial +MasterArbitrationUpdate. See the +following section for the format of the +advisory message. +

+

5.4. Client Arbitration Notifications

+

For any given device_id and role, any time a new primary is chosen, a +primary downgrades its status to a backup, a primary disconnects, or the +role.config is updated by the primary, all controllers for that +(device_id, role) are informed of this by sending a +StreamMessageResponse. The MasterArbitrationUpdate is populated as follows: +

+
    +
  • +

    device_id and role as given. +

  • +
  • +

    role.config is set to the role configuration the server received most +recently in a MasterArbitrationUpdate from a primary. +

  • +
  • +

    election_id is populated as follows: +

    +
      +
    • +

      If there has not been any primary at all, the election_id is left unset. +

    • +
    • +

      Otherwise, election_id is set to the highest election ID that the server +has seen for this device_id and role (which is the election_id of +the current primary if there is any). +

    +
  • +
  • +

    status is set differently based on whether the notification is sent to the +primary or a backup controller: +

    +
      +
    • +

      If there is a primary: +

      +
        +
      • +

        For the primary, status is OK (with status.code set to +google.rpc.OK). +

      • +
      • +

        For all backup controllers, status is set to non-OK (with +status.code set to google.rpc.ALREADY_EXISTS). +

      +
    • +
    • +

      Otherwise, if there is no primary currently, for all backup controllers, +status is set to non-OK (with status.code set to +google.rpc.NOT_FOUND). +

    +
+ +

Note that on primary client changes with outstanding Write request, some +notifications might be delayed, see the +previous section for details. +

6. The P4Info Message

+

The purpose of P4Info was described under +Reference Architecture. +Here we describe the various +components. +

6.1. Common Messages

+

These messages appear nested within many other messages. +

6.1.1. Documentation Message

+

Documentation is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers. +

+
+
+
message Documentation {
+  // A brief description of something, e.g. one sentence
+  string brief = 1;
+  // A more verbose description of something.
+  // Multiline is accepted. Markup format (if any) is TBD.
+  string description = 2;
+}

6.1.2. Preamble Message

+

The preamble serves as the “descriptor” for each entity and contains the unique +instance ID, name, alias, annotations and documentation. +

+
+
+
message Preamble {
+  // ids share the same number-space; e.g. table ids cannot overlap with counter
+  // ids. Even though this is irrelevant to this proto definition, the ids are
+  // allocated in such a way that it is possible based on an id to deduce the
+  // resource type (e.g. table, action, counter, ...). This means that code
+  // using these ids can detect if the wrong resource type is used
+  // somewhere. This also means that ids of different types can be mixed
+  // (e.g. direct resource list for a table) without ambiguity. Note that id 0
+  // is reserved and means "invalid id".
+  uint32 id = 1;
+  // fully qualified name of the P4 object, e.g. c1.c2.ipv4_lpm
+  string name = 2;
+  // an alias (alternative name) for the P4 object, probably shorter than its
+  // fully qualified name. The only constraint is for it to be unique with
+  // respect to other P4 objects of the same type. By default, the compiler uses
+  // the shortest suffix of the name that uniquely identifies the object. For
+  // example if the P4 program contains two tables with names s.c1.t and s.c2.t,
+  // the default aliases will respectively be c1.t and c2.t. In the future, the
+  // P4 programmer may also be able to override the default alias for any P4
+  // object (TBD).
+  string alias = 3;
+  repeated string annotations = 4;
+  // Optional. If present, the location of `annotations[i]` is given by
+ // `annotation_locations[i]`.
+  repeated SourceLocation annotation_locations = 7;
+  // Documentation of the entity
+  Documentation doc = 5;
+  repeated StructuredAnnotation structured_annotations = 6;
+}

6.1.3. Annotating P4 Entities with Documentation

+

P4 entities may be annotated using the following annotations: +

+
+
+
@brief(string...)
+@description(string...)
+

Attaching either or both of these annotations to an entity will generate a +P4Info Documentation Message, which in turn will +appear in the Preamble Message for the entity. +

+

The P4 compiler should not emit annotation messages in the P4Info for these +specific cases; instead, it should generate the Documentation messages as +described. +

+

The following example shows documentation annotations for a table entity: +

+
+
+
@brief("Match IPv4 addresses to next-hop MAC and port")
+@description("Match IPv4 addresses to next-hop MAC and port. \
+Uses LPM match type.")
+table my_ipv4_lkup {
+  ...
+}

6.1.4. Structured Annotations

+

P4 supports both unstructured and structured annotations [17]. +Unstructured annotations of the form MyAnno1 or MyAnno2(body-content) can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +MyAnno3[] or MyAnno4[kvList|expressionList] have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this. +

+

The annotations described up to this point, e.g. @brief(), have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as repeated string annotations fields in the various messages. +Similarly, structured annotations are represented in repeated +StructuredAnnotation structured_annotations fields which are siblings to the +unstructured annotations. The structured_annotations contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations. +

+

The structured annotation messages are defined in p4types.proto. +

+
+
+
message KeyValuePair {
+  string key = 1;
+  Expression value = 2;
+}
+
+message KeyValuePairList {
+  repeated KeyValuePair kv_pairs = 1;
+}
+
+message Expression {
+  oneof value {
+    string string_value = 1;
+    int64 int64_value = 2;
+    bool bool_value = 3;
+  }
+}
+
+message ExpressionList {
+  repeated Expression expressions = 1;
+}
+
+message StructuredAnnotation {
+  string name = 1;
+  oneof body {
+    ExpressionList expression_list = 2;
+    KeyValuePairList kv_pair_list = 3;
+  }
+  // Optional. Location of the '@' symbol of this annotation in the source code.
+  SourceLocation source_location = 4;
+}
+

The StructuredAnnotation message can represent either a KeyValuePairList +or an ExpressionList. +

+

The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The p4c +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don't match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler may print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions. +

+

The following invariants hold: +

+
    +
  1. +

    For any P4 entity, there are no two StructuredAnnotations that have the +same name. +

  2. +
  3. +

    Within a KeyValuePairList, there are no two KeyValuePairs that have the +same key. +

+
6.1.4.1. Structured Annotation Examples
+

We omit the source_location field in the following examples. +

+

Empty Expression List +

+
+
+
@Empty[]
+table t {
+    ...
+}
+

The generated P4Info will contain the following. +

+
+
+
structured_annotations {
+  name: "Empty"
+}
+

Mixed Expression List +

+
+
+
#define TEXT_CONST "hello"
+#define NUM_CONST 6
+@MixedExprList[1,TEXT_CONST,true,1==2,5+NUM_CONST]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedExprList"
+  expression_list {
+    expressions {
+      int64_value: 1
+    }
+    expressions {
+      string_value: "hello"
+    }
+    expressions {
+      bool_value: true
+    }
+    expressions {
+      bool_value: false
+    }
+    expressions {
+      int64_value: 11
+    }
+  }
+}
+

kvList of Mixed Expressions +

+
+
+
@MixedKV[label="text", my_bool=true, int_val=2*3]
+table t {
+    ...
+}
+

The generated P4Info will contain: +

+
+
+
structured_annotations {
+  name: "MixedKV"
+  kv_pair_list {
+    kv_pairs {
+      key: "label"
+      value {
+        string_value: "text"
+      }
+    }
+    kv_pairs {
+      key: "my_bool"
+      value {
+        bool_value: true
+      }
+    }
+    kv_pairs {
+      key: "int_val"
+      value {
+        int64_value: 6
+      }
+    }
+  }
+}

6.1.5. SourceLocation Message

+

A source location describes a location within a .p4-source file. The +SourceLocation message is defined in p4types.proto as follows: +

+
+
+
// Location of code relative to a given source file.
+message SourceLocation {
+  // Path to the source file (absolute or relative to the working directory).
+  string file = 1;
+  // Line and column numbers within the source file, 1-based.
+  int32 line = 2;
+  int32 column = 3;
+}
+

We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations. +

+

The SourceLocation message associated with an annotation holds the location of +the @ symbol introducing the annotation in the P4 source code; the message can +be found in the following place: +

+
    +
  • +

    For unstructured annotations, every message containing a field +repeated string annotations also contains a field +repeated SourceLocation annotation_locations. The field must either be empty + or match the size of annotations. In the latter case, the i-th member of +annotation_locations is the source location of the i-th member of +annotations. +

  • +
  • +

    For structured annotations, every StructuredAnnotation message contains +an optional field SourceLocation source_location holding its source +location, if present. +

+

6.2. PkgInfo Message

+

The PkgInfo message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. PkgInfo can be extracted +and used to facilitate “browsing” of available P4 programs from a +library. Although all fields are technically “optional,” every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included. +

+
+
+
// Can be used to manage multiple P4 packages.
+message PkgInfo {
+  // a definitive name for this configuration, e.g. switch.p4_v1.0
+  string name = 1;
+  // configuration version, free-format string
+  string version = 2;
+  // brief and detailed descriptions
+  Documentation doc = 3;
+  // Miscellaneous metadata, free-form; a way to extend PkgInfo
+  repeated string annotations = 4;
+  // Optional. If present, the location of `annotations[i]` is given by
+  // `annotation_locations[i]`.
+  repeated SourceLocation annotation_locations = 10;
+  // the target architecture, e.g. "psa"
+  string arch = 5;
+  // organization which produced the configuration, e.g. "p4.org"
+  string organization = 6;
+  // contact info for support,e.g. "tech-support@acme.org"
+  string contact = 7;
+  // url for more information, e.g. "http://support.p4.org/ref/p4/switch.p4_v1.0"
+  string url = 8;
+  // Miscellaneous metadata, structured; a way to extend PkgInfo
+  repeated StructuredAnnotation structured_annotations = 9;
+  // If set, specifies the properties that the underlying platform should have.
+  // If the platform does not conform to these properties, the server should
+  // reject the P4Info when used with a SetForwardingPipelineConfigRequest.
+  PlatformProperties platform_properties = 11;
+}
+

where the PlatformProperties message looks as follows: +

+
+
+
// Used to describe the required properties of the underlying platform.
+message PlatformProperties {
+  // The minimum number of multicast entries (i.e. multicast groups) that the
+  // platform is required to support. If 0, there are no requirements.
+  int32 multicast_group_table_size = 1;
+  // The minimum number of replicas that the platform is required to support
+  // across all  groups. If 0, there are no requirements.
+  int32 multicast_group_table_total_replicas = 2;
+  // The number of replicas that the platform is required to support per
+  // group/entry. If 0, `multicast_group_table_total_replicas` should be used.
+  // Must be no larger than `multicast_group_table_total_replicas`.
+  int32 multicast_group_table_max_replicas_per_entry = 3;
+}

6.2.1. Annotating P4 code with PkgInfo

+

A P4 program's PkgInfo may be declared using one or more of the following +annotations, attached to the main block only: +

+
+
+
@pkginfo(key=value)
+@pkginfo(key=value[,key=value,...])
+@brief("A brief description")
+@description("A longer\
+description")
+@custom_annotation(...)
+@another_custom_annotation(...)
+@platform_property(key=value)
+@platform_property(key=value[,key=value,...])
+

Above we see several different types of annotations: +

+
    +
  • +

    @pkginfo - This is used to populate a specific field within the PkgInfo +message. Multiple @pkginfo annotations are allowed. For compactness, +multiple key-value pairs can appear in a single @pkginfo annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The keys must be from +among the message fields inside PkgInfo, for example, name, version, +etc. Each key-value pair assigns a value to the corresponding field inside the +single PkgInfo message for the program's P4Info. One exception is that the +Documentation field of PkgInfo must be expressed as individual +@description and @brief annotations, see next bullets. The key arch will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself. +

  • +
  • +

    @brief - This will populate the PkgInfo.doc.brief message field. +

  • +
  • +

    @description - This will populate the PkgInfo.doc.description message +field +

  • +
  • +

    @platform_property - This is used to populate a specific field within the +PlatformProperty message in PkgInfo.platform_property. Multiple +@platform_property annotations are allowed. For compactness, +multiple key-value pairs can appear in a single @platform_property +annotation, separated by commas. Each key must only appear once and the +compiler must reject the program if one appears multiple times. The keys +must be from among the message fields inside PlatformProperty, for example, +multicast_group_table_size or multicast_group_table_total_replicas. Each +key-value pair assigns a value to the corresponding field inside the single +PlatformProperty message inside the program's P4Info. +

  • +
  • +

    @<anything else> - This will create a PkgInfo.annotation entry +

+ +

Declaring one or more of these annotations on main will +generate a single corresponding PkgInfo message in the P4Info as described in +PkgInfo Message. +

+

The following example shows @pkginfo annotations using a mixture of single and +multiple key-value pairs. It also shows @brief and @description annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the PkgInfo message. The custom annotations will +be appended to the PkgInfo.annotations list. +

+
+
+
@pkginfo(name="switch.p4",version="2")
+@pkginfo(organization="p4.org")
+@pkginfo(contact="info@p4.org")
+@pkginfo(url="www.p4.org")
+@brief("L2/L3 switch")
+@description("L2/L3 switch.\
+Built for data-center profile.")
+@my_annotation1(...) // Not well-known, this will appear in PkgInfo annotations
+@my_annotation2(...) // Not well-known, this will appear in PkgInfo annotations
+PSA_Switch(IgPipeline, PacketReplicationEngine(), EgPipeline,
+           BufferingQueueingEngine()) main;

6.3. ID Allocation for P4Info Objects

+

P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(e.g. table, action, counter, ). The most significant 8 bits of the ID +encodes the object type (as per Table 1). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (p4.config.v1.P4Ids.Prefix). These values must +be used (e.g. by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table 2 shows the ID +layout. +

+
+ + + + + + + + + + + + + + + + + + + + + +
8-bit prefix value P4 object type
0x00 Reserved (unspecified)
0x01 Action
0x02 Table
0x03 Value-set
0x04 Controller header (header type with @controller_header annotation)
0x050x0f Reserved (for future P4 built-in objects)
0x10 Reserved (start of PSA extern types)
0x11 PSA Action profiles / selectors
0x12 PSA Counter
0x13 PSA Direct counter
0x14 PSA Meter
0x15 PSA Direct meter
0x16 PSA Register
0x17 PSA Digest
0x180x7f Reserved (for future PSA extern types)
0x80 Reserved (start of vendor-specific extern types)
0x810xfe Vendor-specific extern types
0xff Reserved (max prefix value)
+
+ +
Table 1. Mapping of P4Info object type to 8-bit ID prefix value
+
+ + + + +
MSB bit 31 .. bit 24 bit 23 .. bit 0 LSB
Object type prefix Generated suffix (e.g. by the compiler)
+
+ +
Table 2. Format of P4Info object IDs
+

It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with @id (see Table +3). The compiler must honor the @id annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (i.e. if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same @id value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct. +

+
+ + + + + + + + + + +
P4 declaration(s) Compiler-allocated ID(s)
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) table tA... Error(same ID suffixes for 2 objects of the same type)
@id(0x12ab34) table tB...
@id(0x12ab34) table tA... 0x0212ab34
@id(0x12ab34) action act1... 0x0112ab34
+
+ +
Table 3. Example of statically-assigned P4Info object IDs
+

The @id annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively). +

6.4. P4Info Objects

6.4.1. Table

+

Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this table. +

  • +
  • +

    match_fields, a repeated field of type MatchField representing the data to +be used to construct the lookup key matched in this table. Each MatchField +message is defined with the following fields: +

    +
      +
    • +

      id, the uint32 identifier of this MatchField, unique in the scope of +this table. No rules are prescribed on the way MatchField IDs should be +allocated, as long as two MatchField of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the @id annotation, or let the compiler +choose them. +

    • +
    • +

      name, the string representing the name of this MatchField. +

    • +
    • +

      annotations, a repeated field of strings, each one representing a P4 +annotation associated to this match field. +

    • +
    • +

      bitwidth, an int32 value set to the size in bits of this match field. +

    • +
    • +

      match, a oneof describing the match behavior for this field; it can be +either: +

      +
        +
      • match_type, an enum field of type MatchType, which includes all +possible PSA match kinds. +
      • +
      • other_match_type, a string field which can be used to encode any +architecture-specific match type. +
      +
    • +
    • +

      doc, a Documentation message describing this match field. +

    • +
    • +

      type_name, which indicates whether the match field has a user-defined +type; this is useful for +translation. +

    +
  • +
  • +

    action_refs, a repeated ActionRef field representing the set of possible +actions for this table. The ActionRef message is used to reference an action +specified in the same P4Info message and it includes the following fields: +

    +
      +
    • id, the uint32 identifier of the action. +
    • +
    • scope, an enum value which can take one of three values: + TABLE_AND_DEFAULT, TABLE_ONLY and DEFAULT_ONLY. The scope of the + action is determined by the use of the P4 standard annotations + @tableonly and @defaultonly [22]. TABLE_ONLY + (@tableonly annotation) means that the action can only appear within + the table, and never as the default action. DEFAULT_ONLY + (@defaultonly annotation) means that the action can only be used as the + default action. TABLE_AND_DEFAULT is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action. +
    • +
    • annotations, a repeated string field, each one representing a P4 +annotation associated to the action reference in this table. +
    +
  • +
  • +

    const_default_action_id, if this table has a constant default action, this +field will carry the uint32 identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action's +arguments. +

  • +
  • +

    initial_default_action, the default action that is executed with the + specified arguments when the table does not match. If no explicit + default action is set, the identifier of this field will default to + the id of the NoAction action. +

  • +
  • +

    implementation_id, the uint32 identifier of the “implementation” of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (e.g. a PSA ActionProfile or ActionSelector +instance). The table is then referred to as an indirect match table. +

  • +
  • +

    direct_resource_ids, repeated uint32 identifiers for all the direct +resources attached to this table, such as DirectMeter and DirectCounter +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2. +

  • +
  • +

    size, an int64 describing the desired number of table entries that the +target should support for the table. See the “Size” subsection within the +“Table Properties” section of the P416 language specification for details +[36]. +

  • +
  • +

    idle_timeout_behavior, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +Idle-Timeout section). Value can be any of the +IdleTimeoutBehavior enum: +

    +
      +
    • NO_TIMEOUT (default value), which means that idle timeout is not +supported for this table. +
    • +
    • NOTIFY_CONTROL, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +Table Idle Timeout Notifications). +
    +
  • +
  • +

    is_const_table, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime. +

  • +
  • +

    has_initial_entries, a boolean flag indicating that the table has +entries populated into it when the P4 program is loaded, which is +true for tables in the P4 source code with either the entries or +const entries properties, and there is at least one entry in the +list. +

  • +
  • +

    other_properties, an Any Protobuf message [37] to embed +architecture-specific table properties [36] which are not part +of the core P4 language or of the PSA architecture. +

+

6.4.2. Action

+

Action messages are used to specify all possible actions of all match-action +tables. +

+

The Action message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this action +

  • +
  • +

    params, a repeated field of Param messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each Param message contains the +following fields: +

    +
      +
    • id, the uint32 identifier of this parameter. No rules are prescribed +on the way Param IDs should be allocated, as long as two Param of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the @id +annotation, or let the compiler choose them. +
    • +
    • name, the string representing the name of this parameter. +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this parameter. +
    • +
    • bitwidth, an int32 value set to the size in bits of this parameter. +
    • +
    • doc, which describes this parameter using a Documentation message. +
    • +
    • type_name, which indicates whether the action parameter has a +user-defined type; this is useful for +translation. +
    +
+

6.4.3. ActionProfile

+

ActionProfile messages are used to specify all available instances of Action +Profile and Action Selector PSA externs. +

+

PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile member, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime. +

+

PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into groups. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime. +

+

While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same ActionProfile message to describe both. +

+

The ActionProfile message includes the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Action +Profile or Selector. +

  • +
  • +

    table_ids, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector. +

  • +
  • +

    with_selector, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern. +

  • +
  • +

    size, an int64 representing the maximum number of member entries that the +Action Profile can hold. For Action Selectors, its semantics is specified by +the selector_size_semantics value as described below. +

  • +
  • +

    max_group_size, an int32 which is 0 for an Action Profile, or, for an +Action Selector, its semantics is specified by the selector_size_semantics +value as described below. +The max_group_size must be no larger than size. PSA programs can use the +@max_group_size annotation to provide this value for Action Selectors. +If the annotation is omitted, the P4Info field will default to 0. +

  • +
  • +

    selector_size_semantics, a oneof for Action Selectors that +specifies how size and max_group_size are interpreted. It can be either: +

    +
      +
    • sum_of_weights, indicating that size and max_group_size represent +the maximum sum of weights that can be present across all selector groups +and within a single selector group respectively. +
    • +
    • sum_of_members, indicating that size and max_group_size represent +the maximum number of members that can be present across all selector +groups and within a single selector group respectively, irrespective of +their weight. The SumOfMembers message used to represent this value also +contains an optional int32 max_member_weight, which indicates the +maximum weight of each individual member. If unset, any 32-bit integer is +allowed for weight. +
    +
+ +

PSA programs can use the @selector_size_semantics annotation with one of + sum_of_weights or sum_of_members to specify this value for Action + Selectors. In the sum_of_members case, the @max_member_weight annotation + can be used to specify max_member_weight. Unless otherwise specified, the + value of selector_size_semantics should default to sum_of_weights. + However, an unset selector_size_semantics should also be treated as + sum_of_weights for backwards compatibility in Action Selectors. In Action + Profiles, this value must be unset. +

6.4.4. Counter & DirectCounter

+

Counter and DirectCounter messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is: +

+
    +
  • +

    Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index. +

  • +
  • +

    Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table. +

+ +

Both Counter and DirectCounter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this counter +extern instance. +

  • +
  • +

    spec, a message of of type CounterSpec used to describe the compile-time +configuration of this counter. Currently, the CounterSpec message is used to +carry only the counter unit, which can be any of the CounterSpec.Unit enum +values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES: byte counter. +
    • +
    • PACKETS: packet counter. +
    • +
    • BOTH: combination of both byte and packet counter. +
    +
+ +

For indexed counters, the Counter message contains also a size field, an +int64 representing the maximum number of independent values that can be held +by this counter array. Conversely, the DirectCounter message contains a +direct_table_id field that carries the unit32 identifier of the table to +which this direct counter is attached. +

+

For indexed counters, the Counter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.5. Meter & DirectMeter

+

Meter and DirectMeter messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is: +

+
    +
  • +

    Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +e.g. to set the rate threshold. +

  • +
  • +

    Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table. +

+ +

Both Meter and DirectMeter messages share the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this meter +extern instance. +

  • +
  • +

    spec, a message of type MeterSpec used to describe the capabilities of +this meter extern instance. The MeterSpec message is used to describe the +meter unit and the meter type. The meter unit can be any of the +MeterSpec.Unit enum values: +

    +
      +
    • UNSPECIFIED: reserved value. +
    • +
    • BYTES, which signifies that this meter can be configured with rates +expressed in bytes/second. +
    • +
    • PACKETS, for rates expressed in packets/second. +
    + +

    The meter type can be any of the MeterSpec.Type enum values: +

    +
      +
    • TWO_RATE_THREE_COLOR: This is the Two Rate Three Color Marker (trTCM) +defined in RFC 2698 [3]. This is the standard P4Runtime meter type +and allows meters to use two rates to split packets into three potential +colors: GREEN, YELLOW, or RED. This mode is the default, but can also be +set explicitly in a P4 program by adding the @two_rate_three_color +annotation to the meter definition. +For example, in a V1Model P4 program, we might define a trTCM direct meter +as follows: + +
      +
      +
      @two_rate_three_color
      +direct_meter<color_type>(MeterType.bytes) my_meter;
    • +
    • SINGLE_RATE_THREE_COLOR: This is the Single Rate Three Color Marker +(srTCM) defined in RFC 2697 [2]. This allows meters to use one rate +and an Excess Burst Size (EBS) to split packets into three potential +colors: GREEN, YELLOW, or RED. In a P4 program, this mode can be set by +adding the @single_rate_three_color annotation to the meter definition. +
    • +
    • SINGLE_RATE_TWO_COLOR: This is a simplified version of RFC 2697 +[2], and the SINGLE_RATE_THREE_COLOR mode above. +SINGLE_RATE_TWO_COLOR restricts meters to use only a single rate +specified by the Committed Information Rate (CIR) and Committed Burst Size +(CBS) to mark packets GREEN or RED. In a P4 program, this mode can be set +by adding the @single_rate_two_color annotation to the meter definition. +
    +
+ +

For indexed meters, the Meter message contains also a size field, an int64 +representing the maximum number of independent cells that can be held by this +meter. Conversely, the DirectMeter message contains a direct_table_id field +that carries the uint32 identifier of the table to which this direct meter is +attached. +

+

For indexed meters, the Meter message contains also an index_type_name +field, which indicates whether the index has a user-defined +type. This is useful for +translation. The underlying built-in type must +be a fixed-width unsigned bitstring (bit<W>). +

6.4.6. ControllerPacketMetadata

+

ControllerPacketMetadata messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server. +

+

When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet. +

+

Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +@controller_header("packet_in") and @controller_header("packet_out"), +respectively. ControllerPacketMetadata messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages). +

+

A P4Info message can contain at most two ControllerPacketMetadata messages, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields: +

+
    +
  • +

    preamble, a Preamble message where preamble.name is set to "packet_in" +and "packet_out" for packet-in and packet-out metadata, respectively. +

  • +
  • +

    metadata, a repeated field of type Metadata, where each Metadata message +includes the following fields: +

    +
      +
    • id, a uint32 identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two Metadata of the +same ControllerPacketMetadata message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the @id annotation, or let the compiler choose them. +
    • +
    • name, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below). +
    • +
    • annotations, a repeated field of strings, each one representing a P4 +annotation associated to this metadata. +
    • +
    • bitwidth, an int32 representing the size in bits of this metadata. +
    • +
    • type_name, which indicates whether the metadata field has a +user-defined type; this is useful for +translation. +
    +
+ +

As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding ControllerPacketMetadata +messages. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  bit<9> egress_port; /* suggested port where the packet
+                         should be sent */
+  bit<8> queue_id;    /* suggested queue ID */
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  bit<9> ingress_port; /* data plane port ID where
+                          the original packet was received */
+  bit<1> is_clone;     /* 1 if this is a clone of the
+                          original packet */
+}
+
+
+
controller_packet_metadata {
+  preamble {
+    id: 2868916615
+    name: "packet_out"
+    annotations: "@controller_header(\"packet_out\")"
+  }
+  metadata {
+    id: 1
+    name: "egress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "queue_id"
+    bitwidth: 8
+  }
+}
+
+controller_packet_metadata {
+  preamble {
+    id: 2868941301
+    name: "packet_in"
+    annotations: "@controller_header(\"packet_in\")"
+  }
+  metadata {
+    id: 1
+    name: "ingress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "is_clone"
+    bitwidth: 1
+  }
+}
+

Note that the use of @controller_header is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages. +

6.4.7. ValueSet

+

ValueSet messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P416 +specification [45]. +

+

The ValueSet message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this Value +Set. +

  • +
  • +

    match, a repeated field of MatchField messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the match_fields repeated field in the +Table message. +

  • +
  • +

    size, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +value_set constructor call. +

+ +

According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of bit<W>, +tuple, or struct [31]. The rest of this section looks at all 3 of +these cases and gives an example ValueSet message when appropriate. +

+
    +
  1. +

    If the type parameter is bit<W>, match will include exactly one +MatchField message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used): +

    +
      +
    • id: set to 1 +
    • +
    • bitwidth: set to the value of W +
    • +
    • match_type: set to EXACT +
    +
+ +
+
+
@id(1) value_set<bit<8> >(4) pvs;
+select (hdr.f8) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    bitwidth: 8
+    match_type: EXACT
+  }
+  size: 4
+}
+
    +
  1. +

    If the type parameter is a tuple, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program. +

  2. +
  3. +

    If the type parameter is a struct, this version of P4Runtime requires that +all the fields of the struct be of type bit<W> (where W can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +match field will include one MatchField message for each field in the +struct, with the following fields: +

    +
      +
    • id: must be unique with respect to the other match entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +@id annotation, or let the compiler choose them. +
    • +
    • name: set to the name of the corresponding struct field. +
    • +
    • annotations: set to the list of P4 annotations associated with the struct +field, except for the @match annotation, if present (see the match field +below). +
    • +
    • bitwidth: set to the value of W for the corresponding struct field. +
    • +
    • type_name, which indicates whether the struct field has a user-defined +type; this is useful for +translation. +
    • +
    • match: by default match_type is set to EXACT; the P4 programmer can +specify a different match type by using the @match annotation +[31]. +
    • +
    • doc: documentation associated with the struct field. +
    +
+ +
+
+
struct match_t {
+  @id(1) bit<8> f8;
+  @id(2) @match(ternary) bit<16> f16;
+  @id(3) @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

In the above example, the @id annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs. +

+

Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a user-defined +type that resolves to a bit<W>, or a struct where +one or more fields is a user-defined type that +resolves to a bit<W>. For each MatchField that corresponds to a user-defined +type, the type_name field must be set to the appropriate value (i.e. the name +of the type). +

6.4.8. Register

+

Register messages are used to specify all possible instances of Register PSA +externs. +

+

Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime. +

+

The Register message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this register +instance. +

  • +
  • +

    type_spec, which specifies the data type stored by this register, expressed +using a P4DataTypeSpec message (see section on Representation of Arbitrary +P4 Types). +

  • +
  • +

    size, an int32 value representing the total number of independent register +cells available. +

  • +
  • +

    index_type_name, which indicates whether the register index has a +user-defined type. This is useful for +translation. The underlying built-in type +must be a fixed-width unsigned bitstring (bit<W>). +

+

6.4.9. Digest

+

Digest messages are used to specify all possible instances of Packet Digest +PSA externs. +

+

A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages. +

+

The Digest message defines the following fields: +

+
    +
  • +

    preamble, a Preamble message with the ID, name, and alias of this digest +instance. +

  • +
  • +

    type_spec, which specifies the data type of an individual digest +notification using a P4DataTypeSpec message (see section on Representation +of Arbitrary P4 Types). +

+

6.4.10. Extern

+

Extern messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one Extern message instance in P4Info. The Extern message defines +the following fields: +

+
    +
  • +

    extern_type_id, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the reserved +range [0x81, 0xfe]. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture. +

  • +
  • +

    extern_type_name, which specifies the fully-qualified P4 name of the extern +type. +

  • +
  • +

    instances, a repeated field of ExternInstance Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +ExternInstance in turn defines the following fields: +

    +
      +
    • preamble, a Preamble message with the ID, name, and alias of this digest +instance. +
    • +
    • info, an Any Protobuf message [37] which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for info should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on Extending +P4Runtime for non-PSA Architectures for more +information. +
    +
+ +

If the P4 program does not include any instance of a given extern type, the +Extern message instance for that type should be omitted from the P4Info. +

6.5. Support for Arbitrary P4 Types with P4TypeInfo

+

See section on Representation of Arbitrary P4 +Types. +

7. P4 Forwarding-Pipeline Configuration

+

The ForwardingPipelineConfig captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the “Device Configuration” and sometimes also referred to as +the “P4 Blob”. It is defined as: +

+
+
+
message ForwardingPipelineConfig {
+  config.P4Info p4info = 1;
+  bytes p4_device_config = 2;
+  message Cookie {
+    uint64 cookie = 1;
+  }
+  Cookie cookie = 3;
+}
+

The p4info field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic. +

+

The p4_device_config is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new ForwardingPipelineConfig on that target. +

+

The cookie field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a GetForwardingPipelineConfig RPC. +When writing the config via a SetForwardingPipelineConfig RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present. +

8. General Principles for Message Formatting

8.1. Default-valued Fields

+

There is a subtle distinction between the treatment of default-valued scalar +fields vs default-valued message fields in P4Runtime. +

8.1.1. Set / Unset Scalar Fields

+

In Protobuf version 3 (proto3), the default value of scalar fields is 0 for +numeric types such as int32, and the empty string "" for string types +(string and bytes). An application, such as the P4Runtime client or +server, is unable to distinguish between an unset scalar field and a scalar +field set to its default value. Therefore, we usually reserve the default +values 0 and “” of scalar fields to mean “unset”. +

+

In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +server, such as in a WriteRequest or a SetForwardingPipelineConfigRequest. +

+

In contrast to scalar fields, note that for message fields, we often do make +a distinction between an unset message field vs a message field set to its +default value, see the next section. +

8.1.2. Set / Unset Message Fields

+

In Protobuf version 3 (proto3), the default value for a message field is +“unset” [6]. An application, such as the P4Runtime client or +server, is able to distinguish between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +CounterEntry message, an “unset” index field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the index message field is +set, a single entry will be read. +

+

Let's look at the counter example in more details. Based on this specification +document, the C++ server code which processes CounterEntry messages may look +like this: +

+
+
+
auto *counter_entry = ...
+if (counter_entry->has_index()) {
+  auto index = counter_entry->index().index();
+  read_one_entry(counter_entry->id(), index);
+} else {
+  read_all_entries(counter_entry->id());
+}
+
    +
  1. +

    Reading a single counter entry at index 0 in the counter array with id +<id>: +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
      +entry.mutable_index();
      +// The above line sets the index field; it is equivalent to:
      +// auto *index = entry.mutable_index();
      +// index->set_index(0);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
      +index {}
    • +
    • Expected behavior: Counter entry at index 0 is read. Notice that the +index subfield is missing under the index field message of +CounterEntry in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages. +
    +
  2. +
  3. +

    Reading all counter entries by leaving the index field unset +

    +
      +
    • Here is the C++ client code: + +
      +
      +
      p4::v1::CounterEntry entry;
      +entry.set_counter_id(<id>);
    • +
    • Here is the corresponding Protobuf message in text format: + +
      +
      +
      counter_id: <id>
    • +
    • Expected behavior: All counter entries for the provided counter +instance are read. Notice that the index message field is unset (default +value) and is therefore omitted from the textual representation of the +message. +
    +
+

8.2. Read-Write Symmetry

+

The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully (with the exception of parts +of the response known to be data plane volatile, as explained in section +8.2.1). Consider the following pseudocode as an +example: +

+
+
+
intended_value = value
+
+status = server.write(intended_value, p4_entity)
+observed_value = server.read(p4_entity)
+
+assert(intended_value == observed_value)
+

To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If Read RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol's complexities to the client implementations. +

+

In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the match fields in a TableEntry message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +MessageDifferencer class [42] included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance. +

8.2.1. Data plane volatile objects

+

An exception to read-write symmetry are objects whose contents or +fields can change by the action of the data plane alone, even if no +controller modifies them. These objects are called data plane +volatile. +

+

The following sections describe all possible values of an Entity +message, since these are the messages that a controller can use to +modify objects in the data plane via an Update message. For each, a +description is given of the parts of that entity that are data plane +volatile. +

8.2.1.1. ExternEntry
+

Data plane volatility depends upon the definition of the extern and +its control plane API. +

8.2.1.2. TableEntry
+

For a table with a direct counter associated with it, the counter_data +field of a TableEntry can be modified by the data plane when packets +match the entry. +

+

For a table with a direct meter associated with it, the +meter_counter_data field of a TableEntry can be modified by the data +plane when packets match the entry. +

+

For a PSA [24] table with property psa_idle_timeout equal to +PSA_IdleTimeout_t.NOTIFY_CONTROL, the data plane can modify the +elapsed_ns field of a TableEntry when no packets match the entry +for an implementation-specific amount of time. +

+

For a PNA [23] table with property pna_idle_timeout equal to +PNA_IdleTimeout_t.NOTIFY_CONTROL or PNA_IdleTimeout_t.AUTO_DELETE +the data plane can modify the elapsed_ns field of a TableEntry +when no packets cause the extern function restart_expire_timer to +be called for an implementation-specific amount of time (nor any other +extern function defined to also have the same effect as +restart_expire_timer). +

+

Similarly, for a table in PNA with any of the values of +pna_idle_timeout listed above, the data plane can modify the +idle_timeout_ns field of a TableEntry when packets match the entry +and the action calls the set_entry_expire_time extern function (or any +of the other extern functions defined to have an effect similar to +calling set_entry_expire_time). +

+

For a PNA [23] table with the property add_on_miss equal to true +the data plane can insert new entries into the table without any +controller's involvement. +

+

For a PNA [23] table with the property pna_idle_timeout equal to +PNA_IdleTimeout_t.AUTO_DELETE, the data plane can delete existing +entries from the table without any controller's involvement. +

8.2.1.3. ActionProfileMember
+

Not data plane volatile in any architectures defined by P4.org +specifications. +

8.2.1.4. ActionProfileGroup
+

Not data plane volatile in any architectures defined by P4.org +specifications. The watch_port feature does affect how action +selectors behave while processing packets, but this feature does not +affect what a P4Runtime client sees when it reads the configuration. +

8.2.1.5. MeterEntry
+

The field counter_data is modified by the data plane when the +corresponding meter is updated in the data plane. +

8.2.1.6. DirectMeterEntry
+

The field counter_data is modified by the data plane when the +corresponding meter is updated in the data plane. +

8.2.1.7. CounterEntry
+

The field data is modified by the data plane when the corresponding +counter is updated in the data plane. +

8.2.1.8. DirectCounterEntry
+

The field data is modified by the data plane when the corresponding +counter is updated in the data plane. +

8.2.1.9. PacketReplicationEngineEntry
+

Not data plane volatile in any architectures defined by P4.org +specifications. +

8.2.1.10. ValueSetEntry
+

Not data plane volatile in any architectures defined by P4.org +specifications. +

8.2.1.11. RegisterEntry
+

The field data can be modified by the data plane when the +corresponding register entry is updated in the data plane. +

8.2.1.12. DigestEntry
+

Not data plane volatile in any architectures defined by P4.org +specifications. +

8.3. Bytestrings

+

P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (bit<W>) or signed (int<W>), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +bytes Protobuf type. The correct bitwidth as per the P4 program of +each integer variable exposed through P4Runtime is specified in the P4Info +message. +

+

The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals: +

+
    +
  • +

    It ensures that a properly encoded binary string's integer value conforms +to the P4Info-specified bitwidth. +

  • +
  • +

    It supports read-write symmetry. +

  • +
  • +

    It helps facilitate non-disruptive P4 program updates. +

+ +

In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type bit<W> and/or int<W>. +

+

Note that this representation does not make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range. +

+

In the P4Runtime API version 1.0 (including minor version revisions), values +of table key fields, action parameters, and fields in packet-in and packet-out +headers between a device and the controller (see 6.4.6), +may not be of type int<W>. The rules for encoding signed values thus only +apply to messages of type P4Data (see 8.4.3). +

+

For a value of type bit<W>, the fewest number of bits required to represent +the integer value $V > 0$ is the smallest integer $A$ such that $V \leq 2^A -1$. +

+

For a value of type int<W>, the fewest number of bits required to represent +the integer value $V \neq 0$ in 2's complement form is the smallest integer $A$ +such that $-2^{A-1} \leq V \leq 2^{A-1} - 1$. +

+

As a special case, define that the value $V=0$ requires at least $A=1$ bit to +represent, regardless of whether it is signed or unsigned. +

+

The shortest possible binary string for an integer $V$ that needs $A$ bits to +represent it is computed as: +

+
+
+
minimum_string_size = floor((A + 7) / 8)
+

Binary strings with the byte length computed as minimum_string_size promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies. +

+

Any additional bits in the bytes sent for an unsigned integer value (type +bit<W>) must be 0. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with 0. +

+

Any additional bits in the bytes sent for a signed integer value (type int<W>) +must be copies of the sign bit, i.e. 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +minimum_string_size minimum required, they must be filled with copies of the +sign bit, i.e. 0 for non-negative values, or 0xff for negative values. In 2's +complement representation, this is called “sign extension”, and leaves the +numeric value represented unchanged. +

+

Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the maximum length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value. +

+

For a received bitstring expected to fit within a bit<W> type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring's width is W bits or less. +

+

For a received bitstring expected to fit within an int<W> type, the value it +represents is in range if, after “undoing sign extension”, the remaining bit +string's width is W bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other. +

+

If the string's byte length is zero, the server always rejects the string. +

+

When the server rejects a binary string due to any of the previous criteria, +it returns an OUT_OF_RANGE error. +

+

For all binary strings, P4Runtime uses big-endian (i.e. network) byte-order. +For signed integer values (int<W> P4 type), P4Runtime uses the same two's +complement bitwise representation as P4. Table 4 +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above. +

+
+ + + + + + + + + + + + + + + + + +
P4 type Integer value P4Runtime binary string Read-write symmetry
bit<8> 99 (0x63) \x63 yes
bit<16> 99 (0x63) \x00\x63 no
bit<16> 99 (0x63) \x63 yes
bit<16> 12388 (0x3064) \x30\x64 yes
bit<16> 12388 (0x3064) \x00\x30\x64 no
bit<12> 99 (0x63) \x00\x63 no
bit<12> 99 (0x63) \x63 yes
bit<12> 99 (0x63) \x00\x00\x63 no
int<8> 99 (0x63) \x63 yes
int<8> -99 (-0x63) \x9d yes
int<8> -99 (-0x63) \xff\x9d no
int<12> -739 (-0x2e3) \xfd\x1d yes
int<16> 0 (0x0) \x00\x00 no
int<16> 0 (0x0) \x00 yes
+
+ +
Table 4. Examples of Valid Bytestring Encoding
+

Table 5 shows some examples of invalid +P4Runtime binary strings: +

+
+ + + + + + + + + + + + +
P4 type P4Runtime binary string
bit<8> \x01\x63
bit<8> empty string
bit<16> \x01\x00\x63
bit<12> \x10\x63
bit<12> \x01\x00\x63
bit<12> \x00\x40\x63
int<8> \x00\x9d
int<12> \x8d\x1d
int<16> empty string
+
+ +
Table 5. Examples of Invalid Bytestring Encoding
+

As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from bit<8> to bit<9>, a server +running the bit<9> version of the P4 program will accept requests from +clients that remain on the bit<8> P4Runtime version. +

+

Despite the server's binary string flexibility for P4 program update support, +the client and server must both remain aware of the +read-write symmetry +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values. +

+

Representation of variable-length integer values (varbit<W> P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the dynamic-length of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an OUT_OF_RANGE error code otherwise. +

8.4. Representation of Arbitrary P4 Types

8.4.1. Problem Statement

+

The P416 language includes more complex types than just binary strings +[5]. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table 6 shows the different +P416 types and how they are allowed to be used, as per the P416 +specification. +

+
+ + + + + + + + + + + + + + + + + + + +
Container type
Element type header header_union struct or tuple
bit<W> allowed error allowed
int<W> allowed error allowed
varbit<W> allowed error allowed
int error error error
void error error error
error error error allowed
match_kind error error error
bool error error allowed
enum allowed1 error allowed
header error allowed allowed
header stack error error allowed
header_union error error allowed
struct error error allowed
tuple error error allowed
+
+ +
Table 6. P4 Type Usage
+

For example, the following P416 objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects. +

+
+
+
Digest<tuple<bit<4>, bit<8> > >() digest_complex;
+digest_complex.pack({ hdr.ipv4.version, hdr.ipv4.protocol });
+// ...
+header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

One solution would be to use only binary string (bytes type) in +p4runtime.proto and to define a custom serialization format for complex P416 +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P416 types. +

8.4.2. P4 Type Specifications in p4info.proto

+

In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type ip_t, which is a header union with 2 possible headers: +ipv4 with type ipv4_t and ipv6 with type ipv6_t. Similarly, they need to +know the field layout for both of these header types. +

+

To achieve this we introduce 2 main Protobuf messages: P4TypeInfo and +P4DataTypeSpec. +

+

P4TypeInfo is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P416 program. These +named types are struct, header, header_union, enum and +serializable_enum; for each of these we have a type specification message, +respectively P4StructTypeSpec, P4HeaderTypeSpec, P4HeaderUnionTypeSpec, +P4EnumTypeSpec and P4SerializableEnumTypeSpec. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. P4TypeInfo also includes the list of parser errors for the program, as +a P4ErrorTypeSpec message. +

+

P4DataTypeSpec is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each P4DataTypeSpec message corresponds to a compile-time type in the +original P416 program (e.g. the type parameter of an extern). This +compile-time type is represented as a Protobuf oneof, which can be: +

+
    +
  • +

    a string representing the name of the type in case of a named type (struct, +header, header_union, enum, serializable_enum or user-defined “new” +type), +

  • +
  • +

    an empty Protobuf message for bool and error, or +

  • +
  • +

    a Protobuf message for other anonymous types (bit<W>, int<W>, varbit<W>, +tuple or stack). The “binary string” types (bit<W>, int<W>, and +varbit<W>) are grouped together in the P4BitstringLikeTypeSpec message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf bytes +type). +

+ +

For all P416 compound types (tuple, struct, header, and header_union), +the order of members in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P416 declaration. The same goes for the order of members of an enum +(serializable or not) or members of error. +

8.4.3. P4Data in p4runtime.proto

+

P4Runtime uses the P4Data message to represent values of arbitrary types. The +P4Runtime client must generate correct P4Data messages based on the type +specification information included in P4Info. The P4Data message was designed +to introduce little overhead compared to using binary strings in the most common +case (P416 bit<W> type). +

+

Just like its P4Info counterpart - P4DataTypeSpec -, P4Data uses a Protobuf +oneof to represent all possible values. +

+

We define a canonical representation for P4Data messages therefore +guaranteeing read-write symmetry by introducing the following requirements: +

+
    +
  • +

    The order of members in P4StructLike and the order of bitstrings in +P4Header must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P416 type +declaration. +

  • +
  • +

    An invalid header is represented by a P4Header message where the is_valid +field is false and the bitstrings repeated field is empty. +

  • +
  • +

    An invalid header union (i.e. all headers in the union are invalid) is +represented by a P4HeaderUnion message where the valid_header_name is the +empty string (default value for the field) and the valid_header is unset. +

  • +
  • +

    The order of entries in P4HeaderStack and P4HeaderUnionStack is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the entries field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding P4HeaderStackTypeSpec or +P4HeaderUnionStackTypeSpec message. +

+

8.4.4. Example

+

Let's look at the Register example again: +

+
+
+
header_union ip_t {
+   ipv4_t ipv4;
+   ipv6_t ipv6;
+}
+Register<ip_t, bit<32> >(128) register_ip;
+

Here's the corresponding entry in the P4Info message: +

+
+
+
registers {
+  preamble {
+    id: 369119267
+    name: "register_ip"
+    alias: "register_ip"
+  }
+  type_spec {
+    header_union {
+      name: "ip_t"
+    }
+  }
+  size: 128
+}
+type_info {
+  headers {
+    key: "ipv4_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  headers {
+    key: "ipv6_t"
+    value {
+      members {
+        name: "version"
+        type_spec {
+          bit {
+            bitwidth: 4
+          }
+        }
+      } # ...
+  header_unions {
+    key: "ip_t"
+    value {
+      members {
+        name: "ipv4"
+        header {
+          name: "ipv4_t"
+        }
+      }
+      members {
+        name: "ipv6"
+        header {
+          name: "ipv6_t"
+        }
+      }
+    }
+  }
+}
+

Here's a p4.WriteRequest to set the value of register_ip[12]: +

+
+
+
update {
+  type: INSERT
+  entity {
+    register_entry {
+      register_id: 369119267
+      index {
+        index: 12
+      }
+      data {
+        header_union {
+          valid_header_name: "ipv4"
+          valid_header {
+            is_valid: true
+            bitstrings: "\x04"
+            bitstrings: # ...
+          }
+        }
+      }
+    }
+  }
+}

8.4.5. enum, serializable enum and error

+

P416 supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or “unsafe” enum) +[7]. For enum types with no underlying type as well as error +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in P4Data to represent enum and +error values. +

+

Serializable enum types have an underlying fixed-width unsigned integer +representation (bit<W>). All named enum members must be assigned an integer +value by the P4 programmer, but not all valid numeric values for the +underlying type need to have a corresponding name. P4TypeInfo includes the +mapping between entry name and entry value. When providing serializable enum +values through P4Data, one must use the assigned integer value (enum_value +bytestring field). P4Runtime does not provide a way for the client to use the +name even when the enum member has one instead of the value, as it makes +it easier for the server to respect the read-write +symmetry principle. +

8.4.6. User-defined types

+

P416 enables programmers to introduce new types [13]. While similar +to typedef, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +translation. When introducing a new type, the +declaration can be annotated with @p4runtime_translation to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for port numbers, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. The @p4runtime_translation annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (bit<W>). The type exposed to the control plane (referred to as the +controller_type) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a URI (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the controller_type of the values exposed to the control plane. The +controller_type can be either bit<W> where W is any positive integer, or +string, or a positive integer W which has the same meaning as bit<W>. +Specifying just an integer is deprecated. +

+

It is recommended that the URI includes at least the P4 architecture name and +the type name. +

+

A @p4runtime_translation annotation need not have any effect if it is used to +annotate anything in a P4 program other than a type declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect. +

+

User-defined types are specified using the P4NewTypeSpec message, which has +the following fields: +

+
    +
  • +

    representation, a Protobuf oneof specifying how values of this type are +exchanged between client and server; it can be either: +

    +
      +
    • +

      original_type, if and only if no @p4runtime_translation annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 type declaration is itself a +user-defined type, original_type is obtained by “walking” the chain of +type declarations recursively until a built-in type (e.g. bit<W>) is +found. +

    • +
    • +

      translated_type, if and only if the P4 type declaration was annotated +with @p4runtime_translation. It is of type P4NewTypeTranslation, +which itself has two fields uri and either sdn_string or +sdn_bitwidth , which map to the two input parameters to the +annotation. +

    +
  • +
  • +

    annotations, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration. +

+ +

For example, an architecture in this case PSA may introduce a new type +for port numbers: +

+
+
+
// Controller refers to ports as a string, e.g. "eth0".
+@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+// Controller refers to ports as a 32-bit integer, e.g. 0xffffffff.
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+// Same as above.
+@p4runtime_translation("p4.org/psa/v1/PortId_32_t", 32)
+type bit<9> PortId_32_t;
+

In this case, the P4Info message would include the following P4TypeInfo +messages: +

+
+
+
type_info {
+  new_types {
+    key: "PortId_String_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_String_t"
+        sdn_string: {}
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_Bit32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_Bit32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+
+type_info {
+  new_types {
+    key: "PortId_32_t"
+    value {  # P4NewTypeSpec
+      translated_type {  # P4NewTypeTranslation
+        uri: "p4.org/psa/v1/PortId_32_t"
+        sdn_bitwidth: 32
+      }
+    }
+  }
+}
+

Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (e.g. through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over @p4runtime_translation to enable users +to overwrite annotations included as part of the P4 architecture definition. +

8.4.7. Trade-off for v1.x Releases

+

For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +bytes with P4Data in the p4.v1.FieldMatch message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +bytes to provide action parameter values and controller metadata +values. However P4Data is used whenever appropriate for PSA externs and we +encourage the use of P4Data in architecture-specific extensions. +

+

In order to support translation for action +parameters and match fields, we include a type_name field in +p4.config.v1.MatchField, p4.config.v1.Action.Param and +p4.config.v1.ControllerPacketMetadata.Metadata. In addition, the bitwidth +field for all of these message types must abide by the following rule when +type_name names a translated user-defined type: +

+
    +
  • +

    If the controller_type is a fixed-width unsigned bitstring, the bitwidth +field must be set to the bitwidth of the controller_type. This information +is redundant with the one included in the P4TypeInfo entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent. +

  • +
  • +

    Otherwise (i.e., if the controller_type is a string), the bitwidth must +be “unset”, which, in Protobuf version 3, is the same as setting the field to +0. +

+ +

For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types: +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_String_t", string)
+type bit<9> PortId_String_t;
+
+@p4runtime_translation("p4.org/psa/v1/PortId_Bit32_t", bit<32>)
+type bit<9> PortId_Bit32_t;
+
+@name(".t")
+table t {
+  key = {
+    meta.port1: exact;  // meta.port1 has type PortId_String_t
+    meta.port2: exact;  // meta.port2 has type PortId_Bit32_t
+  }
+  actions = {
+    drop;
+  }
+}
+

This table would have the following representation in the generated P4Info +message: +

+
+
+
tables {
+  preamble {
+    id: 34728461
+    name: "t"
+    alias: "t"
+  }
+  match_fields {
+    id: 1
+    name: "meta.port1"
+    # notice that bitwidth is unset
+    match_type: EXACT
+    type_name {
+      name: "PortId_String_t"
+    }
+  }
+  match_fields {
+    id: 2
+    name: "meta.port2"
+    bitwidth: 32
+    match_type: EXACT
+    type_name {
+      name: "PortId_Bit32_t"
+    }
+  }
+  # ...
+}

9. P4 Entity Messages

+

P4Runtime covers P4 entities that are either part of the P416 language, or +defined as PSA externs. The sections below describe the messages for each +supported entity. +

9.1. TableEntry

+

The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action's +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification. +

+

P4Runtime supports inserting, modifying, deleting and reading table entries with +the TableEntry entity, which has the following fields: +

+
    +
  • +

    table_id, which identifies the table instance; the table_id is determined +by the P4Info message. +

  • +
  • +

    match, a repeated field of FieldMatch messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration. +

  • +
  • +

    action, which indicates which of the table's actions to execute in case of +match and with which argument values. +

  • +
  • +

    priority, a 32-bit integer used to order entries when the table's match key +includes an optional, ternary or range match. +

  • +
  • +

    controller_metadata, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +metadata field. +

  • +
  • +

    metadata, an arbitrary bytes value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. +

  • +
  • +

    meter_config, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    counter_data, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See Direct +resources section for more information. +

  • +
  • +

    meter_counter_data, which is used to read and write the per-color counter +values for the direct meter entry attached to this table entry, if any. +See Direct resources section for more information. +

  • +
  • +

    is_default_action, a boolean flag which indicates whether the table entry is +the default entry for the table. See Default entry +section for more information. +

  • +
  • +

    idle_timeout_ns and time_since_last_hit, which are two fields used to +implement idle-timeout support for the table, if applicable. See +Idle-timeout section for more information. +

  • +
  • +

    is_const, a boolean value that is true if and only if the entry +cannot be modified or deleted by the client. +

+ +

The priority field must be set to a non-zero value if the match key includes a +ternary match (i.e. in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an OPTIONAL, TERNARY or +RANGE match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches. +

+

The match and priority fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for MODIFY and DELETE updates. When deleting +an entry, these key fields (along with is_default_action) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a keyless +table (the table has an empty match key), the server must reject all attempts to +INSERT a match entry and return an INVALID_ARGUMENT error. +

+

The number of match entries that a table should support is indicated in P4Info +(size field of Table message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P416 specification for the +size property [36]. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +RESOURCE_EXHAUSTED when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached. +

+

The is_const field must be false in any INSERT, MODIFY, or +DELETE write request of a table entry. If it is true, the server +must reject the operation and return an INVALID_ARGUMENT error. +

9.1.1. Match Format

+

The bytes fields in the FieldMatch message follow the format described in +Bytestrings. +

+

For “don't care” matches, the P4Runtime client must omit the field's entire +FieldMatch entry when building the match repeated field of the TableEntry +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for “don't care” matches, which is needed +to ensure read-write symmetry. For PSA match types, +a “don't care” match for a specific match key field is defined as follows: +

+
    +
  • +

    For a TERNARY match, it is logically equivalent to a mask of zeros. +

  • +
  • +

    For a OPTIONAL match, it is logically equivalent to a wildcard match. +

  • +
  • +

    For an LPM match, it is logically equivalent to a prefix_len of zero. +

  • +
  • +

    For a RANGE match, it is logically equivalent to a range which includes all +possible values for the field. +

+ +

Note that there is no “don't care” value for EXACT matches and therefore exact +match fields can never be omitted from the TableEntry message. +

+

The following example shows a P4Runtime message that treats a TERNARY field +as a “don't care” match. The P4 program defines table t with TERNARY +and EXACT fields in its match key: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: ternary;
+    istd.ingress_port: exact;
+  }
+  actions = {
+    drop;
+  }
+}
+

In this P4Runtime request, the client omits the table's TERNARY field +from the repeated match field to indicate a “don't care” match. As shown +below, the match specifies only the EXACT field given by field_id: 2. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 33554439  # Table t's ID.
+    match {
+      # field_id 1 is not present to use the don't care ternary value.
+      field_id: 2
+      exact {
+        value: "\x20"
+      }
+    }
+    action {
+      # Action selection goes here.
+    }
+  }
+}
+

For every member of the TableEntry repeated match field, field_id must be +a valid id for the table, as per the P4Info, and one of the fields in +field_match_type must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an INVALID_ARGUMENT error code. +

+
    +
  • EXACT match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.exact().value()))
+
    +
  • LPM match + +
      +
    • The binary string encoding of the value (when present) must conform to the +Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • “Don't care” bits must be 0 in value. +
+ +
+
+
assert(BytestringValid(match.lpm().value()))
+
+pLen = match.lpm().prefix_len()
+assert(pLen > 0)
+
+trailing_zeros = countTrailingZeros(match.lpm().value())
+assert(trailing_zeros >= field_bits - pLen)
+
    +
  • TERNARY match + +
      +
    • The binary string encoding of the value (when present) and mask (when +present) must conform to the Bytestrings requirements. +
    • +
    • “Don't care” match must be omitted. +
    • +
    • Masked bits must be 0 in value. This constraint taken together +with the Bytestrings requirements means that the +value's binary string is never longer than the mask's binary string. +When the value's string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask. +
+ +
+
+
assert(BytestringValid(match.ternary().value()))
+assert(BytestringValid(match.ternary().mask()))
+assert(match.ternary().value().size() <= match.ternary().mask().size());
+
+value = parseInteger(match.ternary().value())
+mask = parseInteger(match.ternary().mask())
+
+assert(mask != 0)
+
+assert(value & mask == value)
+
    +
  • RANGE match + +
      +
    • The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the Bytestrings +requirements. +
    • +
    • Low bound must be less than or equal to the high bound. +
    • +
    • “Don't care” match must be omitted. +
+ +
+
+
assert(BytestringValid(match.range().low()))
+assert(BytestringValid(match.range().high()))
+
+low = parseInteger(match.range().low())
+high = parseInteger(match.range().high())
+
+assert(low <= high)
+
+assert(low != min_field_value || high != max_field_value)
+
    +
  • OPTIONAL match + +
      +
    • The binary string encoding of the value must conform to the +Bytestrings requirements. +
+ +
+
+
assert(BytestringValid(match.optional().value()))

9.1.2. Action Specification

+

The TableEntry action field must be set for every INSERT update but may be +left unset for MODIFY updates, in which case the action specification for the +table entry will not be modified (if a MODIFY update has an unset action field +and does not modify any direct resource attached to the table then the MODIFY +update is a no-op). Based on the implementation property value of the P4 table, +the oneof in the TableAction message will either be: +

+
    +
  • +

    an Action specification for direct tables (with no P4 implementation +property) +

  • +
  • +

    an action profile member id for indirect tables for which the implementation +property is an action profile with no selector. +

  • +
  • +

    an action profile member id or group id for indirect tables for which the +implementation property is an action profile with selector. +

  • +
  • +

    an ActionProfileActionSet specification for indirect tables for +which the implementation property is an action profile with +selector. This usage is described in One Shot Action Selector +Programming +

+ +

If the oneof does not match the table description in the P4Info (e.g. the +oneof is action_profile_member_id for a direct table), the server must +return an INVALID_ARGUMENT error code. +

+

The Action Protobuf message has the following fields: +

+
    +
  • +

    action_id, which identifies the action instance; the action_id is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an INVALID_ARGUMENT error +code. If the client uses a valid action_id for the table but does not +respect the action scope specified in P4Info (e.g. tries to set a TABLE_ONLY +action as the default action), the server must return a PERMISSION_DENIED +error code. +

  • +
  • +

    params: a repeated Protobuf field of action parameter values, each encoded +as a Param message. For each parameter, param_id must be valid for the +action (as per the P4Info) and value must follow the format described in +Bytestrings. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an INVALID_ARGUMENT error code +if a parameter id is missing, if an extra parameter id not found in the +P4Info was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +Bytestrings format. +

+ +

For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a NOT_FOUND error code. +

9.1.3. Default Entry

+

According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer or defaults to NoAction +(which is a no-op) otherwise and assuming it is not declared as const, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow INSERT and DELETE updates on the default entry and the +P4Runtime server must return an INVALID_ARGUMENT error code if the client +attempts one. +

+

The default entry is identified by setting the is_default_action boolean field +to true. When this flag is set to true, the repeated match field must be empty +and the priority field must be set to zero, otherwise the P4Runtime server +must return an INVALID_ARGUMENT error code. When performing a MODIFY update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its controller_metadata and metadata value as well as the +configurations for its direct resources will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a PERMISSION_DENIED +error code if the client attempts to modify it. +

+

Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to direct resources. +

+

In this P4Runtime release, we have decided to restrict the default entry for +indirect tables tables with an ActionProfile or ActionSelector +implementation property to a constant NoAction action entry, with the +hope that it would simplify the implementation of the P4Runtime service. +

9.1.4. Constant Tables

+

Constant tables are defined as tables whose match entries are +immutable. They are identified by the table property const entries +in the P416 source code. In the P4Info, such tables have +is_const_table equal to true, and if the list of entries in the +source code has at least one entry in it, they also have +has_initial_entries flag equal to true. For tables declared with +the entries property, without const before entries see Section +9.1.5. +

+

The only write updates which are allowed for constant tables are MODIFY +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +PERMISSION_DENIED error. Just like any table entry MODIFY request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a PERMISSION_DENIED error. +

+

The contents of const tables can be queried by the client through a +ReadRequest. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: table_id, match, action, +is_default_action, and priority (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries. +

+

When a priority value is required (e.g. for tables including RANGE, +TERNARY or OPTIONAL matches), it is inferred based on the order in +which entries appear in the table declaration. As of August 2023, the +open source p4c compiler always assigns entry priority values in a +constant table with N entries starting at N for the first entry +and decrementing the value by 1 for each successive entry. The P416 +language specification does not preclude the P4 developer from +explicitly specifying priorities for entries in constant tables, but +p4c does not yet support this. +

9.1.5. Preinitialized tables

+

Preinitialized tables are those defined with an entries table +property in the P416 source code, with no const qualifier before +entries, and at least one entry in that list. In the P4Info, such +tables have has_initial_entries flag equal to true, but +is_const_table is false. For tables declared with const entries, +see Section 9.1.4. +

+

Every P4 table falls into one of three categories: +

+
    +
  • Normal table: Neither entries nor const entries are declared +in the source code, and thus is_const_table and +has_initial_entries will both be false. A corner case is that if +it has entries = { } with no const before entries, i.e. an +empty list of entries, that is also a normal table. +
  • +
  • Constant table: The table has const entries declared, and thus a +separate entries property is not permitted by the language. Such +a table will have is_const_table true. Such a table will have +has_initial_entries true if there is at least one entry in the +source code, or false if the list is empty. +
  • +
  • Preinitialized table: The table has entries declared, and thus a +separate const entries property is not permitted by the language. +It also has at least one entry in the list. Such a table will have +is_const_table false and has_initial_entries true. +
+ +

A preinitialized table is allowed to have a mix of some entries marked +const, and other entries not marked const. +

+

Entries not marked const may be modified or deleted, just as a +client may do for any entry in a normal table. +

+

Entries marked const behave like entries in a constant table, +i.e. only MODIFY operations on direct resources are allowed. +

+

Unlike a table with is_const_table = true, a client may insert +entries into a table with has_initial_entries = true and +is_const_table = false, subject to capacity constraints on the +number of entries supported by the target for the table. +

+

The contents of preinitialized tables can be queried by the client +through a ReadRequest. The server fills in the same fields in the +response as it does for constant tables, as described in Section +9.1.4, and with the same restrictions on table +features supported. +

+

If the table requires a priority value for entries, the priorities of +the initial entries are determined according to the P416 language +specification. After the P4 program is initially loaded, the entries +not marked const can be modified at run time just as table entries +in a normal table can. +

+

The contents of all table entries within the entries table +properties in a P4 program can be written to a separate output file by +the open source p4c compiler. See Section A.5 for +details. +

9.1.6. Wildcard Reads

+

When performing a ReadRequest, the P4Runtime client can select all entries +from one or all tables on the target and use several of the TableEntry fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as priority and “unset” for message fields such as match. The following +fields may be used to select and filter results: +

+
    +
  • table_id: If default (0), entries from all tables including constant +tables will be selected and no other filter can be used. Otherwise only +the specified table will be considered. +
  • +
  • match: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned. +
  • +
  • action: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an action_id (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id. +
  • +
  • priority: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value. +
  • +
  • controller_metadata: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +controller_metadata value. +
  • +
  • metadata: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided metadata value. +
  • +
  • is_default_action: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered. +
  • +
  • role: If default (unset), all table entries will be considered. Otherwise, +table entries will be filtered based on the provided role value. +
+ +

For example, in order to read all entries from all tables from device 3, the +client can use the following ReadRequest message. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0
+    priority: 0
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following ReadRequest +message: +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+    priority: 11
+    controller_metadata: 0
+    metadata: ""
+  }
+}
+

The canonical representation of “don't care” matches, combined with the ability +to do a wildcard read on all table entries by leaving the match field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single “don't care” entry or to do a wildcard +read. If a table has no fields with match kind EXACT, it is possible via +P4Runtime to add an entry that is “don't care” for all fields (i.e. has an empty +match field) but is not the default entry (i.e. is_default_action is +false). When reading this entry from the table, there is no way to read only +that entry from the table, because it would require providing an unset match +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single LPM match: +

+
+
+
table t {
+  key = {
+    hdr.ipv4.dip: lpm;
+  }
+  actions = {
+    drop; fwd;
+  }
+}
+

The following WriteRequest message can be used to add 2 entries: +

+
+
+
device_id: 3
+entities {
+  table_entry { # don't care entry
+    table_id: 0x0212ab34
+    # ...
+  }
+  table entry {
+    table_id: 0x0212ab34
+    match {
+      field_id: 1
+      lpm {
+        value: 0x0a000000
+        prefix_len: 8
+      }
+    # ...
+  }
+}
+

The first entry is a “don't care” entry, while the second one matches all +10.0.0.0/8 addresses. The second entry has higher priority than the first one. +

+

The following ReadRequest message will return all entries in the table, not +just the “don't care” entry. +

+
+
+
device_id: 3
+entities {
+  table_entry {
+    table_id: 0x0212ab34
+  }
+}
+

This issue also exists for tables with TERNARY, RANGE, and OPTIONAL +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the “don't care” entry will be returned to the +client. If the client uses distinct priority values for all entries which is +strongly recommended to achieve deterministic behavior , +then there is no ambiguity because the wildcard read will actually return a +single entry (the “don't care” entry) as long as the priority field is set to +the correct value. +

9.1.7. Direct Resources

+

In addition to the DirectCounterEntry and DirectMeterEntry entities, +P4Runtime support reading and writing direct resources as part of the +TableEntry message. This is convenient for two reasons: +

+
    +
  • +

    A table entry and its direct resources can be read with a single entity when +doing a Read RPC call +

  • +
  • +

    The initial configuration for an entry's direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can “hit” the table entry without +executing the appropriate meter entry. +

+ +

Once the table entry has been inserted, the P4Runtime client is free to use the +DirectCounterEntry and DirectMeterEntry messages for read and write +operations on DirectCounter and DirectMeter instances. For example, it is +usually more convenient as well as more efficient to use DirectCounterEntry to +query a counter entry value rather than use TableEntry, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry. +

+

The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does not need to be “executed” in +every action bound to the table. It is an error to provide a direct resource +configuration in a TableEntry message when programming an action that does not +execute the direct resource, and the server must return an INVALID_ARGUMENT +error code. +

+

We leverage Protobuf's ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the TableEntry message. The list below describes how +the server must handle the meter_config, counter_data and +meter_counter_data fields for read and write requests, based on whether the +fields are set or not. We do not cover error cases in the list, i.e. we assume +that we are dealing with a table which is assigned a direct counter / a direct +meter, and that the action being used for the table entry “executes” the direct +resource appropriately. +

+
    +
  • +

    meter_config field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets). +
      • +
      • if set: The initial configuration for the meter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The meter entry's configuration is reset to the default +(meter returns GREEN for all packets). +
      • +
      • if set: The value provided by the client is used to re-configure +the meter entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the meter entry's +configuration (meter_config is unset in the response). +
      • +
      • if set: If the meter entry's configuration is the default +configuration, meter_config is unset in the response. Otherwise, the +response includes the meter entry's configuration that was written by +the client earlier. This respects the “read-write symmetry” principle. +
    +
  • +
  • +

    counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for the counter entry is the default +(0). +
      • +
      • if set: The initial value for the counter entry is the one +provided by the client. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: The counter entry's value is not changed. +
      • +
      • if set: The value provided by the client is written to the counter +entry. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include the counter entry's value +(counter_data is unset in the response). +
      • +
      • if set: The response includes the counter entry's value read from +the target. +
    +
  • +
  • +

    meter_counter_data field +

    +
      +
    • WriteRequest (INSERT) + +
        +
      • if unset: The initial value for all 3 counter entries is the +default (0). +
      • +
      • if set: The initial value for all 3 counter entries is the +default (0). Sub-field, if any, can only have zero (0) as its value. +INVALID_ARGUMENT error is returned for any non-zero sub-field value. +
    • +
    • WriteRequest (MODIFY) + +
        +
      • if unset: All the 3 counter entries are unchanged. +
      • +
      • if set: All the 3 counters are reset to 0. Sub-field, if any, can +only have zero (0) as its value. INVALID_ARGUMENT error is returned +for any non-zero sub-field value. +
    • +
    • ReadRequest + +
        +
      • if unset: The response does not include counter values +(meter_counter_data is unset in the response). +
      • +
      • if set: The response includes all the 3 counter values read from +the target. +
    +
+ +

In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +meter_config field unset when inserting or modifying a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the TableEntry message +(i.e. the meter_config field must be set to match the existing configuration). +

9.1.8. Idle-timeout

+

P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not “hit” (i.e. not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification using the +IdleTimeoutNotification message to the primary client, which can then take +action, such as remove the idle table entry. +

+

Two fields of the TableEntry Protobuf message are used to implement idle +timeout: +

+
    +
  • +

    idle_timeout_ns: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, i.e. no +IdleTimeoutNotification message will ever be generated for this entry. When +a client reads a TableEntry, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry. +

  • +
  • +

    time_since_last_hit: a Protobuf message with a single field (elapsed_ns) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The time_since_last_hit field must be unset for a +TableEntry write. When reading a table entry, time_since_last_hit must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0. +

+ +

These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an INVALID_ARGUMENT error code if at least one of these +conditions is met: +

+
    +
  • idle_timeout_ns is set to a non-zero value, or +
  • +
  • time_since_last_hit is set +
+ +

The target should do its best to approximate the idle_timeout_ns value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the TableEntry write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for time_since_last_hit. +

+

P4Runtime does not support idle timeout for default entries. When the +is_default_action flag is set in a TableEntry message, idle_timeout_ns +must be set to 0 (default) and time_since_last_hit must be unset. If the +server receives a TableEntry message which violates this, it must return an +INVALID_ARGUMENT error. +

+

For more information about idle timeout, in particular regarding +IdleTimeoutNotification, please refer to the Table idle timeout +notifications section. +

9.2. ActionProfileMember & ActionProfileGroup

+

P4Runtime defines an API for programming a PSA ActionProfile extern using +ActionProfileMember messages. A PSA ActionSelector extern can be programmed +using both ActionProfileMember and ActionProfileGroup messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table t for L3 routing, implemented with an action +selector as. +

+
+
+
ActionSelector(HashAlgorithm.crc32,
+               /*size = */ 32w1024,
+               /*output_width = */ 32w10) as;
+
+action set_nhop(PortId_t p, EthAddr smac, EthAddr dmac) {
+  istd.egress_port = p;
+  hdr.ethernet.smac = smac;
+  hdr.ethernet.dmac = dmac;
+}
+
+table t {
+  key = {
+    hdr.ipv4.dip: lpm;  // LPM on destination IP address
+  }
+  actions = {
+    set_nhop;
+  }
+  implementation = as;
+}
+

When programming table t in the example above, a P4Runtime client should +specify the TableAction in the TableEntry to be a reference to either an +action profile member or group. The reference is a non-zero uint32 identifier +that uniquely identifies a member or group programmed in the action selector +as. +

+

If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata. +

+

If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata. +

9.2.1. Action Profile Member Programming

+

Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a uint32 identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the actions +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the actions attributes of the +tables must have an identical list of P4 actions. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector. +

+

An ActionProfileMember entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info. +

  • +
  • +

    member_id is the non-zero uint32 identifier of the action profile member +entry being updated. +

  • +
  • +

    action is the specification of the P4 action instance bound to the action +profile member entry. +

+ +

An action profile member may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an ALREADY_EXISTS error +code. The action specification must be provided, or the server must return +INVALID_ARGUMENT. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return RESOURCE_EXHAUSTED. +
  • +
  • MODIFY: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return NOT_FOUND, +and the action specification must be provided, or the server must return +INVALID_ARGUMENT. +
  • +
  • DELETE: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a NOT_FOUND error code. The member +must not be part of an action profile group, or the server must return +FAILED_PRECONDITION. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return FAILED_PRECONDITION. action_profile_id and member_id are the only +fields that are considered when performing a DELETE and every other field +will be ignored. +
+ +

When reading, an ActionProfileMember message with action_profile_id and +member_id equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with action_profile_id equal to the id of +an existing ActionProfile or ActionSelector object, and a member_id equal to +0, will read all members of that specified object. +

9.2.2. Action Profile Group Programming

+

Action profile groups are entries in an ActionSelector and are referenced by a +uint32 identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type. +

+

Within a single ActionSelector object, the uint32 values used to identify its +members are in a separate ‘scope’ from the uint32 values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5. +

+

There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it. +

+

An ActionProfileGroup entity update message has the following fields: +

+
    +
  • +

    action_profile_id is the uint32 identifier of the PSA ActionSelector +extern instance, as defined in P4Info. +

  • +
  • +

    group_id is the non-zero uint32 identifier of the action profile group +entry being updated. +

  • +
  • +

    members is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields: +

    +
      +
    • member_id for looking up the member table in the selector. +
    • +
    • weight specifying the probability of the member's selection at +runtime. 0 is not a valid weight value and the server must return +INVALID_ARGUMENT if the client attempts to use it. +
    • +
    • watch_port is the controller-defined port that the member's +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +9.2.4 for notes on the behavior if all members in +a group are excluded for this reason. If watch_port is empty, then the +member is always included in the selection, regardless of the status of +any port of the device. The value must be empty or the SDN port of an +existing port on the device, otherwise the server must return +INVALID_ARGUMENT. If the target does not support using the SDN port as a +watch port (e.g. on some targets LAGs cannot be used for this purpose), +the server must return UNIMPLEMENTED. +
    +
  • +
  • +

    max_size is the maximum sum of all members or member weights (as per the +selector_size_semantics) for the group. This field is defined when the group +is inserted, and must not be changed in a MODIFY update, otherwise an +INVALID_ARGUMENT error is returned. See the subsection below for the +rules on setting max_size. +

+ +

An action profile group may be inserted, modified or deleted as per the +following semantics. +

+
    +
  • INSERT: Add a new group entry bound to a set of existing action profile +members. The group_id must be different from ids of already programmed +groups for that selector, or the server must return an ALREADY_EXISTS error +code. All members specified in the group must exist in the selector, or the +server must return NOT_FOUND. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target. +
  • +
  • MODIFY: Modify the member set specification of an existing group entry. An +entry with the group_id must exist, or the server must return +NOT_FOUND. All members specified in the group entry must exist in the +selector, or the server must return NOT_FOUND. The value of max_size must +be identical to the value used when inserting the group, otherwise an +INVALID_ARGUMENT error is returned. +
  • +
  • DELETE: Delete the group entry and deallocate the group_id. The group must +not be referenced in the table action of any table entry, or the server must +return a FAILED_PRECONDITION error code. If the group_id is invalid, the +server must return NOT_FOUND. action_profile_id and group_id are the +only fields that are considered when performing a DELETE and every other +field will be ignored. +
+ +

When setting the group membership with INSERT or MODIFY, the members +repeated field must not include duplicates, i.e. members with the same +member_id. The weight field is used instead to logically “repeat” the member +inside the group. +

+

It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation “stores” the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made. +

+

When reading, an ActionProfileGroup message with action_profile_id and +group_id equal to 0 will read all groups of all ActionSelector objects. A +message with action_profile_id equal to the id of an existing ActionSelector +object, and a group_id equal to 0, will read all groups of that one specified +object. +

9.2.2.1. Rules on Setting max_size
+

The valid values for max_size depend on the static max_group_size included +in the P4Info message: +

+
    +
  • +

    If max_group_size is greater than 0, then max_size must be greater than 0, +and less than or equal to max_group_size. We assume that the target can +support selector groups for which the size of the members (as defined by +selector_size_semantics) is up to max_group_size, or the P4Runtime server +would have rejected the Forwarding Pipeline Config. If max_size is greater +than max_group_size, the server must return INVALID_ARGUMENT. +

  • +
  • +

    Otherwise (i.e. if max_group_size is 0), the P4Runtime client can set +max_size to any value greater than or equal to 0. +

    +
      +
    • +

      A max_size of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (INSERT or MODIFY), the target must return a +RESOURCE_EXHAUSTED error. +

    • +
    • +

      If max_size is greater than 0 and the value is not supported by the +target, the server must return a RESOURCE_EXHAUSTED error at +group-creation time. +

    +
+

9.2.3. One Shot Action Selector Programming

+

P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids. +

+

One shots are programmed by choosing the ActionProfileActionSet message as the +TableAction. The ActionProfileActionSet message consists of a set of +ActionProfileAction messages. This set should have cardinality no greater than +max_group_size (if max_group_size is nonzero) if selector_size_semantics +is sum_of_members, or else the server must return INVALID_ARGUMENT. Each +ActionProfileAction message has the following fields: +

+
    +
  • +

    action is one of the actions specified by the table that is being +programmed. +

  • +
  • +

    weight specifying the probability of the action's selection at runtime. 0 is +not a valid weight value and the server must return INVALID_ARGUMENT if +the client attempts to use it. If selector_size_semantics is +sum_of_weights, then the sum of all weights across all ActionProfileAction +messages for that ActionProfileActionSet message must not exceed the +max_group_size specified in the P4Info (if greater than 0), or the server +must return INVALID_ARGUMENT. If selector_size_semantics is +sum_of_members, the individual weight of each member must not exceed +max_member_weight (if greater than 0), or the server must return +INVALID_ARGUMENT. +

  • +
  • +

    watch_port is the controller-defined port that the action's liveness depends +on. At runtime, the action must be excluded from selection if the watch port +is down. See Section 9.2.2 for more details +on the watch_port field, which also apply for one shot action selector +programming. +

+ +

Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics. +

+

To preserve read-write symmetry, an implementation must answer ReadRequests +with the original one shot messages. It may not return a desugared version of +the one shot message. +

+

For example, consider the action selector table defined +here. This table could be programmed +with the following one shot update: +

+
+
+
table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action {
+    action_profile_action_set {
+      action_profile_actions {
+        action { /* set nexthop 1 */ }
+        weight: 1
+        watch_port: "\x01"
+      }
+      action_profile_actions {
+        action { /* set nexthop 2 */ }
+        weight: 2
+        watch_port: "\x02"
+      }
+      action_profile_actions {
+        action { /* set nexthop 3 */ }
+        weight: 3
+        watch_port: "\x03"
+      }
+    }
+  }
+}
+

Which would be equivalent to the following updates, where GROUP_ID, +MEMBER_ID_1, MEMBER_ID_2, and MEMBER_ID_3 are unused ids: +

+
+
+
action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_1
+  action { /* set nexthop 1 */ }
+}
+action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_2
+  action { /* set nexthop 2 */ }
+}
+action_profile_member {
+  action_profile_id: 0x11ab12cd
+  member_id: MEMBER_ID_3
+  action {  /* set nexthop 3 */ }
+}
+action_profile_group {
+  action_profile_id: 0x11ab12cd
+  group_id: GROUP_ID
+  members {
+    member_id: MEMBER_ID_1
+    weight: 1
+    watch_port: "\x01"
+  }
+  members {
+    member_id: MEMBER_ID_2
+    weight: 2
+    watch_port: "\x02"
+  }
+  members {
+    member_id: MEMBER_ID_3
+    weight: 3
+    watch_port: "\x03"
+  }
+}
+table_entry {
+  table_id: 0x0212ab34
+  match { /* lpm match */ }
+  action { action_profile_group_id: GROUP_ID }
+}
+

Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure correct ordering between the dependent +updates. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct WriteRequest batches are required. +

+

It is possible to include several ActionProfileAction messages with the same +exact action specification in one ActionProfileActionSet message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the weight field. Note that to preserve read-write symmetry, the server +must not coalesce multiple ActionProfileAction messages with the same action +specification into one. Additionally, each action specification would count as +a separate member for the purposes of e.g. the sum_of_members group size +calculation for Action Selectors. +

+

All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with ActionProfileMember and +ActionProfileGroup messages. Programming some entries with one shots, and +other entries with ActionProfileMember and ActionProfileGroup messages is +not allowed, and the server must return the error code INVALID_ARGUMENT in +that case. +

+

A P4Runtime server must support the one shot style of programming tables with +an action selector implementation. Support for the ActionProfileMember and +ActionProfileGroup style is optional. If ActionProfileMember and +ActionProfileGroup are not supported by a server, it must return an +UNIMPLEMENTED error for every ActionProfileMember or ActionProfileGroup +message that it receives. +

9.2.4. Constraints on action selector programming

+

The PSA specification states that the following features are optional in +action selector implementations [27]: +

+
    +
  1. Support for non-empty groups where in the same group, different members are +bound to different actions. +
  2. +
  3. Predictable data plane behavior when a matched table entry points to an empty +group. +
+ +

For 1., if a client tries to INSERT or MODIFY a group with members bound to +different actions, the server should return UNIMPLEMENTED if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return UNIMPLEMENTED (modifying the action parameter values must be +supported, however). +

+

PSA 1.1 introduces the psa_empty_group_action table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. psa_empty_group_action is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of psa_empty_group_action at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +NoAction. Even when psa_empty_group_action is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of psa_empty_group_action mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming. +

+

The PSA specification includes a discussion on how to implement +psa_empty_group_action in software in the P4Runtime server +[30]. +

+

If a P4Runtime implementation does support psa_empty_group_action, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down. +

+

If a P4Runtime implementation does not support psa_empty_group_action, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down. +

9.3. CounterEntry & DirectCounterEntry

+

PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The CounterData +P4Runtime message can be used for all three types of PSA counters PACKETS, +BYTES and PACKETS_AND_BYTES and consists of the following fields: +

+
    +
  • byte_count is an int64, corresponding to the number of octets. +
  • +
  • packet_count is an int64, corresponding to the number of packets. +
+ +
+
+
message CounterData {
+  int64 byte_count = 1;
+  int64 packet_count = 2;
+}
+

P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of byte_count and packet_count fields, which +is equivalent to specifying the counter type PACKETS_AND_BYTES. Counters may +be defined as direct or indirect (indexed) instances. +

9.3.1. DirectCounterEntry

+

A direct counter is a direct resource associated with a TableEntry (see +Direct Resources). The counter_data field of the +TableEntry message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +DirectCounterEntry message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed. +

+
+
+
message DirectCounterEntry {
+  TableEntry table_entry = 1;
+  CounterData data = 2;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectCounterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match TableEntry.match of the table entry +to which this direct counter entry is associated. If a matching TableEntry +is not found, the server returns the error code NOT_FOUND. +

  • +
  • +

    data is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified. +

+ +

Specifying DirectCounterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read the contents of a +DirectCounter: +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the counter value in the counter_data field of the TableEntry message +(see Direct resources). +

  • +
  • +

    Explicitly request the counter value by including the DirectCounterEntry in +the ReadRequest. The table_entry.match field must match the TableEntry +whose counter is being read. If no such entry is found, the server returns the +error code NOT_FOUND. +

+

9.3.2. CounterEntry

+

An indirect or indexed counter is not associated with a specific TableEntry +and may be updated independently of any action. It may be read or written using +the P4Runtime CounterEntry message whose fields are defined as follows: +

+
    +
  • +

    counter_id is a uint32, the unique identifier for the counter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +the counter array. +

  • +
  • +

    data is a Protobuf message of type CounterData, which represents the +counter value. +

+ +
+
+
message CounterEntry {
+  uint32 counter_id = 1;
+  Index index = 2;
+  CounterData data = 3;
+}
+

The CounterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the counter entries in the +array have default value 0. +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect counter instance whose unique id is counter_id +and array index is specified by index. The counter value is set to the value +specified by the client in the data field. Note that the counter value is +not modified if this Protobuf field is not set. If index is omitted all +counter values in the array will be set to the value provided by the +client. The server must return INVALID_ARGUMENT for a negative index value +and OUT_OF_RANGE if the index value exceeds the size of the counter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a ReadRequest by including a CounterEntry +entity for each of the instances, specifying the counter_id and +index. Wildcard reads are also supported as follows: +

+
    +
  • +

    If the counter_id field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the ReadResponse. +

  • +
  • +

    Otherwise, if the index field is not set, the server returns the counter +values for all indirect counters in the array identified by the unique id +counter_id. +

+

9.4. MeterEntry & DirectMeterEntry

+

Meters are an advanced mechanism for keeping statistics, involving stateful +“marking” and usually “throttling” of packets based on configured rates of +traffic. The PSA metering function is based on the Two Rate Three Color Marker +(trTCM) defined in RFC 2698 [3]. P4Runtime clients may additionally +restrict meter usage on a table to RFC 2697's [2] Single Rate Three +Color Marker (srTCM) or a simplified version of it that we call Single Rate +Two Color Marker. The type of a table's meter is set by the MeterSpec.Type as +described in the Meter & DirectMeter section. +

+

The trTCM meters an arbitrary packet stream using two configured rates +the Peak Information Rate (PIR) and Committed Information Rate (CIR), and their +associated burst sizes and “marks” its packets as GREEN, YELLOW or RED based +on the observed rate. +

+

The srTCM meters an arbitrary packet stream using a single configured rate +the Committed Information Rate (CIR) and its associated burst size as well +as the Excess Burst Size (EBS) and “marks” its packets as GREEN, YELLOW or RED +based on the observed rate. +

+

The Single Rate Two Color Marker meters an arbitary packet stream using a +single configured rate the Committed Information Rate (CIR) and its +associated burst size and “marks” its packets as GREEN or RED based on the +observed rate. +

+

MeterEntry & DirectMeterEntry have an additional field counter_data that +may hold per color counter data for targets that support it, and that must +always be unset for targets that do not support it. If set in a request and +unsupported by a target, an UNIMPLEMENTED error code should be returned. +These counters provide a granular list of the counters applicable to the +possible meter colors GREEN, YELLOW and RED. The counter associated with a +specific color is incremented when a packet is “marked” with that color. The +primary purpose of the color counters is for debugging purposes. +

+

A meter may be configured as a direct or indirect instance, similar to a +counter. The MeterConfig P4Runtime message represents meter configuration. +

+
+
+
message MeterConfig {
+  int64 cir = 1;  // Committed Information Rate
+  int64 cburst = 2;  // Committed Burst Size
+  int64 pir = 3;  // Peak Information Rate
+  int64 pburst = 4;  // Peak Burst Size
+  int64 eburst = 5; // Excess burst size (only used for srTCM)
+}
+

A MeterConfig for a trTCM typed meter must only be accepted if eburst is +unset. Otherwise, the server should return an INVALID_ARGUMENT error. +

+

A MeterConfig for a srTCM typed meter must only be accepted if pir and +pburst are equal to cir and cburst respectively. Otherwise, the server +should return an INVALID_ARGUMENT error. +

+

A MeterConfig for a Single Rate Two Color Marker typed meter must only be +accepted if pir and pburst are equal to cir and cburst respectively and +eburst is unset. Otherwise, the server should return an INVALID_ARGUMENT +error. +

+

Note: Any acceptable MeterConfig for a Single Rate Two Color Marker typed +meter is also acceptable for either of the other two meter types and will mark +packets identically in all three cases. Thus, changing the meter type from +Single Rate Two Color Marker to Single Rate Three Color Marker or +Two Rate Three Color Marker is a non-breaking change. +

9.4.1. DirectMeterEntry

+

A direct meter is a direct resource associated with a TableEntry (see Direct +resources). The meter_config field of the TableEntry +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +DirectMeterEntry message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed. +

+
+
+
message DirectMeterEntry {
+  TableEntry table_entry = 1;
+  MeterConfig config = 2;
+  MeterCounterData counter_data = 3;
+}
+

A WriteRequest may only include an Update message of type MODIFY with a +DirectMeterEntry, whose fields are specified by the client as follows: +

+
    +
  • +

    the table_entry.match field must match the match key of the TableEntry +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching TableEntry is not found, +the server returns the error code NOT_FOUND. +

  • +
  • +

    config is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets). +

  • +
  • +

    counter_data is used to set the per color counter values to the default +value of (0), which is essentially clearing the counters. If the field is +unset, the counter values are left untouched. If the field is set, targets +supporting these counters should reset all the color counters to (0), if any +of the sub-fields are set to a non-zero value, then an INVALID_ARGUMENT +error should be returned. +

+ +

Specifying DirectMeterEntry in an Update message of type INSERT or +DELETE is not allowed, and the server must return the error code +INVALID_ARGUMENT in that case. +

+

A client may use ReadRequest in two ways to read a DirectMeter config. +

+
    +
  • +

    As a direct resource associated with a table entry, request the server to +return the meter config in the meter_config field of the TableEntry +message (see Direct resources). +

  • +
  • +

    Explicitly request the meter configuration by including the DirectMeterEntry +in the ReadRequest. The table_entry.match field must match the +TableEntry whose meter config is being read. If no such entry is found, the +server returns the error code NOT_FOUND. Read responses also include the +per color counter data for the meter entry, if supported and specified in +the request message. +

+

9.4.2. MeterEntry

+

An indirect or indexed meter is not associated with a specific TableEntry and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime MeterEntry message whose fields are defined as +follows: +

+
    +
  • +

    meter_id is a uint32, the unique identifier for the meter. +

  • +
  • +

    index is a Protobuf message that encapsulates an int64, used to index into +a meter array. +

  • +
  • +

    config is a Protobuf message of type MeterConfig, which represents the +meter configuration. +

  • +
  • +

    counter_data is a Protobuf message of type MeterCounterData, which +represents the per color counter values associated with the corresponding +meter. +

+ +
+
+
message MeterEntry {
+  uint32 meter_id = 1;
+  Index index = 2;
+  MeterConfig config = 3;
+  MeterCounterData counter_data = 4;
+}
+

The MeterEntry can only be used in a WriteRequest with the MODIFY update +type. The P4Runtime server must return an INVALID_ARGUMENT error code for +update types INSERT and DELETE. By default all the meter entries in the +array have a default configuration (GREEN for all packets). +

+
    +
  • INSERT: Server returns the error code INVALID_ARGUMENT. +
  • +
  • MODIFY: Modify an indirect meter instance whose unique id is meter_id and +array index is specified by index. The meter is reconfigured using the +config field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the index field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if config is unset). The server must return INVALID_ARGUMENT for a +negative index value and OUT_OF_RANGE if the index value exceeds the size of +the meter array. +
  • +
  • DELETE: Server returns the error code INVALID_ARGUMENT. +
+ +

A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a ReadRequest by including a MeterEntry entity for each +of the instances, specifying the meter_id and index. Wildcard reads are also +supported as follows: +

+
    +
  • +

    If the meter_id field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the ReadResponse. +

  • +
  • +

    Otherwise, if the index field is not set, the server returns the +configuration for all indirect meters in the array identified by the unique id +meter_id. +

+

9.4.3. MeterCounterData

+

The MeterCounterData P4Runtime message represents the per color counters +associated with a meter entry. Whenever a meter is executed and returns +a color, the corresponding color counter GREEN, YELLOW or RED is updated. +

+

As seen above, these counters can be associated with a DirectMeterEntry or +MeterEntry. Targets not capable of supporting these counters should return +UNIMPLEMENTED if a MeterCounterData field was set in a read or write +request. +

+
+
+
message MeterCounterData {
+  CounterData green = 1;
+  CounterData yellow = 2;
+  CounterData red = 3;
+}

9.5. PacketReplicationEngineEntry

+

The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets. +

9.5.1. MulticastGroupEntry

+

Multicasting is achieved in PSA programs by setting the multicast_group +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the MulticastGroupEntry API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example. +

+
+
+
control arp_multicast(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ethernet.isValid() &&
+        hdr.ethernet.eth_type == ETH_TYPE_ARP) {
+      smeta.multicast_group = (MulticastGroup_t) 1;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    multicast_group_entry {
+      multicast_group_id: 1
+      replicas { port: "\x05" instance: 1 }
+      replicas { port: "\x0c" instance: 2 }
+      replicas { port: "\x12" instance: 3 }
+      replicas { port: "\x18" instance: 4 }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +PSA Metadata Translation section. +

+

The egress packets may be distinguished for further processing in the egress +using the instance metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 multicast_group metadata is set to a value that is not +programmed in the PRE, then the packet is dropped. +

+

A multicast group may be inserted, modified or deleted as per the following +semantics. +

+
    +
  • INSERT: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The multicast_group_id field is a uint32 and must be greater +than 0 (see explanation below), or the +P4Runtime server must return an INVALID_ARGUMENT error. The replica +instance ID is also a uint32, and its value may not exceed the maximum +allowed by the target for the EgressInstance_t type (0 is allowed), or the +server must return an INVALID_ARGUMENT error. The egress port (port field) +must be an SDN port and must refer to a singleton port. No two replicas may +have identical values of both port and instance, or the server must +return INVALID_ARGUMENT. The metadata field is an arbitrary bytes value +which is opaque to the target. There is no requirement of where this is +stored, but it must be returned by the server along with the rest of the entry +when the client performs a read on the entry. +
  • +
  • MODIFY: Modify the set of replicas and metadata for a given multicast group +entry, indexed by the given multicast_group_id. Same restrictions as +INSERT apply here. +
  • +
  • DELETE: Delete the multicast group indexed by the given +multicast_group_id. The replicas and metadata fields need not be +provided for this operation. Any packets with their multicast_group +metadata in the data plane set to the deleted multicast_group_id will be +dropped. +
+ +

When reading a multicast group, only multicast_group_id is considered. All +other fields in MulticastGroupEntry are ignored. To perform a wildcard +Read on all configured multicast group entries, the multicast_group_id field +must be set to 0, its default value. +

9.5.1.1. Valid Values for multicast_group_id
+

The PSA specification states that the valid data plane values for multicast +group ids (MulticastGroup_t) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target [29]. This means that, in the absence of +translation, the client must set the multicast_group_id field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special wildcard value which is used to read all the multicast groups +configured in the target, the multicast_group_id field must never be set to 0 +when performing a Write RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value. +

9.5.2. CloneSessionEntry

+

PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +clone_session_id identifier and a boolean flag clone in the packet +metadata. The clone_session_id serves as a handle to the clone attributes, +namely a set replicas of (egress port, instance) pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +CloneSessionEntry API. +

+

The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the clone_low_ttl control block is applied in the ingress +pipeline to create an ingress-to-egress clone. +

+
+
+
control clone_low_ttl(inout H hdr, inout M smeta) {
+  apply {
+    if (hdr.ipv4.isValid() &&
+        hdr.ipv4.ttl <= LOW_TTL_THRESHOLD) {
+      smeta.clone_session_id = 10w100;
+      smeta.clone = true;
+    }
+  }
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: INSERT
+entity {
+  packet_replication_engine_entry {
+    clone_session_entry {
+      session_id: 100
+      replicas { port: "\xff\xff\xff\xfd" instance: 1 } # to CPU
+      class_of_service: 2
+      packet_length_bytes: 4096
+    }
+  }
+}
+

As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type CloneSessionId_t [29]). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes. +

+

The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port 0xfffffffd; see +Translation of Port Numbers). Note that the +egress port (port field) must be an SDN port and must refer to a singleton +port. +

+

If the clone_session_id data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created. +

+

A clone session may be inserted, modified or deleted as per the following +semantics: +

+
    +
  • INSERT: Add a new clone session entry bound to a set of egress ports and +replica IDs. The session_id is a uint32 and must be greater than 0 (see +explanation below), or the P4Runtime +server must return an INVALID_ARGUMENT error. The replica instance ID is +also a uint32, and its value may not exceed the maximum allowed by the +target for the EgressInstance_t type (0 is allowed), or the server must also +return an INVALID_ARGUMENT error. The egress port (port field) in the +replica must be an SDN port and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (class_of_service field). This value must be a valid +value for the PSA ClassOfService_t type, which supports runtime translation +by default [29], or the server must return +INVALID_ARGUMENT. See PSA Metadata +Translation for more information. The +packet_length_bytes field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +packet_length_bytes field is 0 (default), no truncation on the clone will be +performed. +
  • +
  • MODIFY: Modify the attributes of a given clone session entry, indexed by the +given clone_session_id. Same restrictions as INSERT apply here. +
  • +
  • DELETE: Delete the clone session indexed by the given +clone_session_id. Other fields need not be provided for this operation. Any +packet with their clone_session_id metadata in the data plane set to the +deleted session_id will no longer be cloned. +
+ +

When reading a clone session, only session_id is considered. All other fields +in CloneSessionEntry are ignored. To perform a wildcard Read on all +configured clone session entries, the session_id field must be set to 0, its +default value. The session_id field can never be equal to 0 in a Write +RPC. If it does, the server must return an INVALID_ARGUMENT error. +

9.5.2.1. Valid Values for session_id
+

The PSA specification states that the valid data plane values for clone +session ids (CloneSessionId_t) range from 0 to the maximum value supported by +the target [29]. Note that unlike for multicast group +ids, 0 is a valid data plane value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special wildcard value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a session_id +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is not enabled, we effectively +“lose” one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (e.g. because the target supports a very +limited number of clone sessions), one can enable translation on +CloneSessionId_t and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id. +

9.6. ValueSetEntry

+

Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the parse_trill_types state. +

+
+
+
state parse_l2 {
+  @id(1) value_set<ETH_TYPE_BITWIDTH>(MAX_TRILL_TYPES) trill_types;
+  extract(hdr.ethernet);
+  select (hdr.ethernet.eth_type) {
+    ETH_TYPE_IPV4: parse_ipv4;
+    ETH_TYPE_IPV6: parse_ipv6;
+    trill_types:   parse_trill_types;
+    _:             reject;
+  }
+}
+

The corresponding entry in the P4Info for this Value Set is: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "trill_types"
+  }
+  match {
+    id: 1
+    bitwidth: <ETH_TYPE_BITWIDTH>
+    match_type: EXACT
+  }
+  size: <MAX_TRILL_TYPES>
+}
+

At runtime, the client writes the following update in the target (shown in +Protobuf text format). +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0x22f3 }
+      }
+      match {
+        field_id: 1
+        exact { value: 0x893b }
+      }
+    }
+  }
+}
+

As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the parse_trill_types state. +

+

A ValueSetEntry entity update message has the following fields: +

+
    +
  • +

    value_set_id is the uint32 identifier of the Value Set instance, as +defined in P4Info. +

  • +
  • +

    members is a repeated field of type ValueSetMember. When “selecting” +against a Value Set, every member will be considered and if at least one +“matches”, the corresponding parser transition will be taken. Each +ValueSetMember contains a repeated field of FieldMatch messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a ValueSetMember if and only if +it matches all its FieldMatch messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. FieldMatch messages in a ValueSetEntry follow +the same rules as in a TableEntry. +

+ +

A ValueSetEntry may only be modified. If the update type is INSERT or +DELETE, the server must return an INVALID_ARGUMENT error. If the update type +is MODIFY, the server writes the members given in the repeated field to the +Value Set entry indexed by the given value_set_id. The maximum number of +matches must not exceed the maximum size given by the size field in P4Info of +the Value Set, otherwise the server must return a RESOURCE_EXHAUSTED error. To +empty a Value Set (i.e. restore it to its initial state), the P4Runtime client +can perform a MODIFY update with an empty members repeated field. +

+

To facilitate read-write symmetry, the server must +return an ALREADY_EXISTS error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set. +

+

See Appendix A.3 for a more complex Value Set example. +

9.7. RegisterEntry

+

The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The RegisterEntry P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations. +

+

RegisterEntry has the following fields: +

+
    +
  • +

    register_id, which identifies the PSA Register extern instance which is +being accessed by the client; the register_id is specified by the P4Info +message. +

  • +
  • +

    index, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the RegisterEntry message +used for the request. When an index is provided , the server must validate +its value, and return INVALID_ARGUMENT for a negative index or +OUT_OF_RANGE if the index exceeds the size of the register array. +

  • +
  • +

    data: the data to be written to the array (if RegisterEntry is part of a +WriteRequest message) or the data read from the array (if RegisterEntry is +part of a ReadResponse message). The data field is a P4Data message and +must match the format described by the type_spec field of the corresponding +Register entry in the P4Info, or the server must return an INVALID_ARGUMENT +error. +

+

9.8. DigestEntry

+

A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly. +

+

The DigestEntry P4Runtime entity is used to configure how the device must +generate digest messages. The DigestEntry Protobuf message is not used to +carry digest data, which is done on the StreamChannel bidirectional stream +using the DigestList (digest data sent by the target to the client) and +DigestListAck (digest data acknowledgments sent by the client to the target) +Protobuf messages. +

+

In this section, we refer to the data learned by a single data plane call to +Digest<T>::pack as a “digest message” and we use “digest list” to designate +the list of digest messages bundled by the P4Runtime service in a single +DigestList stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are “duplicate” if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are “distinct” +if they are not duplicate. +

+

DigestEntry has the following fields: +

+
    +
  • +

    digest_id, which identifies the PSA Digest extern instance which emitted the +data; the digest_id is determined by the P4Info message. +

  • +
  • +

    config, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +digest_id; these parameters are: +

    +
      +
    • max_timeout_ns: the maximum server buffering delay in nanoseconds for an +outstanding digest message. +
    • +
    • max_list_size: the maximum digest list size in number of digest +messages sent by the server to the client as a single DigestList +Protobuf message. +
    • +
    • ack_timeout_ns: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data. +
    +
+ +

Here is the significance of the different Update types for DigestEntry: +

+
    +
  • INSERT: Enable server generation of DigestList messages for given digest +instance and use provided configuration parameters. +
  • +
  • MODIFY: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance. +
  • +
  • DELETE: Disable server generation of DigestList messages for given digest +instance. +
+ +

A server should buffer digest messages until either: +

+
    +
  • max_timeout_ns time has passed since the first digest message was added to +the empty buffer, or +
  • +
  • max_list_size distinct digest messages have been received from the +data plane and added to the buffer +
+ +

At which point the server should, with best effort, generate a DigestList +stream message with the buffer contents and send it to the primary client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software. +

+

To avoid sending duplicate digest messages across different DigestList +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the primary client indicates that it has received the +digest list and acted on it. The server must keep a “cache” containing the set +of all digest messages that have been sent, but not acknowledged yet by the +primary client, up-to ack_timeout_ns in the past. The server must delete all +cache entries for a given digest list when they are at least ack_timeout_ns +old or when a matching DigestListAck message (i.e. with the same digest_id +and list_id fields as the DigestList message) is received. +

+

The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged DigestList messages. +

+

When max_timeout_ns is set to 0 and / or max_list_size is set to 1, the +server should, with best effort, generate a DigestList message for every +digest message generated by the data plane which is not already in the cache. If +ack_timeout_ns is set to 0, the cache must always be an empty set. If +max_list_size is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +max_timeout_ns configuration parameter. +

+

The P4Runtime server may empty the digest message cache in case of a client +status change. +

+

Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server: +

+
+
+
DigestStream stream;
+DigestCache cache;
+DigestBuffer buffers;
+
+// sends digest list when it is ready
+send_buffer(Id digest_id) {
+  buffer = buffers[digest_id];
+  stream.write(DigestList(buffer));
+  cache.merge(buffer);  // updates cache with new digest list
+  buffer.clear();
+}
+
+// callback which handles data plane digest messages from device
+handle_dataplane_digest(Digest msg) {
+  digest_id = msg.digest_id();
+  buffer = buffers[digest_id];
+  if (msg in cache OR msg in buffer) return;
+  buffer.enqueue(msg);
+  if (buffer.length() < max_list_size(digest_id)) return;
+  send_buffer(digest_id);
+}
+
+// callback which handles ack messages received on the stream
+handle_stream_ack(DigestListAck ack) {
+  // clear all cache entries matching the tuple (digest_id, list_id)
+  cache.erase( (ack.digest_id(), ack.list_id() )
+}
+
+// loop to enforce timeouts
+while (true) {
+  now = now();
+  // check for buffers that need to be sent
+  for ((digest_id, buffer) in buffers) {
+    if (now - buffer.first_enq_time() >= max_timeout_ns(digest_id))
+      send_buffer(buffer_id);
+  }
+  // check for expired entries in cache
+  for ((digest_id, list_id, sent_time) in cache) {
+    if (now - sent_time >= ack_timeout_ns(digest_id))
+      cache.erase( (digest_id, list_id) );
+  }
+  sleep(X);
+}

9.9. ExternEntry

+

This is used to support a P4 extern entity that is not part of PSA. It is +defined as: +

+
+
+
message ExternEntry {
+  uint32 extern_type_id = 1;
+  uint32 extern_id = 2;
+  google.protobuf.Any entry = 3;
+}
+

Each ExternEntry entity maps to an Extern message in the +P4Info and an ExternInstance message within that +message. The extern_type_id field must be equal to the one in +ExternEntry. The extern_id field must be equal to the ID included in the +preamble of the corresponding ExternInstance message. +

+

entry itself is embedded as an Any Protobuf message [37] to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on Extending P4Runtime for non-PSA +Architectures for more information. +

10. Error Reporting Messages

+

P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case. +

+

gRPC uses grpc::Status [38] to represent the status returned by an +RPC. It has 3 attributes: +

+
+
+
StatusCode code_;
+grpc::string error_message_;
+grpc::string binary_error_details_;
+

The code_ represents a canonical error [40] and describes the +overall RPC status. The error_message_ is a developer-facing error message, +which should be in English. The binary_error_details_ carries a serialized +google.rpc.Status message [33] message, which has 3 fields: +

+
+
+
int32 code = 1;  // see code.proto
+string message = 2;
+repeated google.protobuf.Any details = 3;
+

The code and message fields must be the same as code_ and error_message_ +fields from grpc::Status above. The details field is a list that consists of +p4.Error messages that carry error details for individual elements inside +batch-request RPCs (e.g. Write and Read). p4.Error includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices [40]. +

+

Figure 7 illustrates how these messages fit together. +

+
+

error-report +

+
+ +
Figure 7. P4Runtime Error Report Message Format
+

gRPC provides utility functions ExtractErrorDetails() and SetErrorDetails() +[39] to easily convert between grpc::Status and +google.rpc.Status. +

+

Please see sections on individual P4Runtime RPCs for details on how +grpc::Status is populated for reporting errors. +

+

Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on Stream Error +Reporting for more information. +

11. Atomicity of Individual Write and Read Operations

+

Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane apply +operation, and every single Write operation on a table that inserts, deletes, +or modifies one table entry, the apply operation should behave as if that +Write operation has not yet occurred, or as if the Write operation is +complete. The P4 program should never behave as if the Write operation is +partially complete. These guarantees also apply to extern instances: Read and +Write operations on extern entities must execute atomically relative to extern +data plane methods. +

+

The atomicity guarantees provided by P4Runtime for individual Read and Write +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification [28]. +

+

The P416 language introduces an @atomic annotation [18], to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the @atomic annotation for Write +operations, as well as non-wildcard Read operations, +relative to data plane execution. Consider the following P4 example written for +PSA: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024) r1;
+
+  apply {
+    // ...
+    @atomic {
+        Value_t v = r1.read((Index_t)1);
+        v = v + 1;
+        r1.write((Index_t)1, v);
+    }
+  }
+}
+

If a P4Runtime server is processing messages which write to Register r1 at +index 1, these writes must not happen between the data plane read and +write. +

+

Now let's consider the following example: +

+
+
+
control C1 {
+  typedef bit<10> Index_t;
+  typedef bit<32> Value_t;
+  Register<Value_t, Index_t>(32w1024, (Value_t)0 /* initial value */) r1;
+
+  apply {
+    @atomic {
+        r1.write((Index_t)1, (Value_t)100);
+        r1.write((Index_t)2, (Value_t)100);
+    }
+    @atomic {
+        r1.write((Index_t)1, (Value_t)200);
+        r1.write((Index_t)2, (Value_t)200);
+    }
+  }
+}
+

If a P4Runtime client issues a wildcard Read on Register r1, there is no +guarantee that r1[1] == r1[2] in the response, as the read for r1[1] may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for r1[2] may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read r1[1] and r1[2] separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +ReadRequest message) of individual read requests. Similar to a batch +ReadRequest, a wildcard read of a register can execute the reads of the +register array elements (r1[1], r1[2], ) in an arbitrary order relative +to each other. +

+

If the @atomic annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program. +

12. Write RPC

+

The Write RPC updates one or more P4 entities on the target. The request is +defined as follows: +

+
+
+
message WriteRequest {
+  uint64 device_id = 1;
+  string role = 6;
+  Uint128 election_id = 3;
+  repeated Update updates = 4;
+  enum Atomicity {
+    CONTINUE_ON_ERROR = 0;
+    ROLLBACK_ON_ERROR = 1;
+    DATAPLANE_ATOMIC = 2;
+  }
+  Atomicity atomicity = 5;
+}
+

The device_id uniquely identifies the target P4 device. The role and +election_id define the client role and election-id as described in the +Primary-Backup Arbitration and Controller +Replication +section. The server is expected to perform the following checks (in this order) +before processing the updates list: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the primary for (device_id, role) according to +the election_id value, the server must return a PERMISSION_DENIED error. +

  4. +
  5. +

    If the Write is attempted before a ForwardingPipelineConfig has been set, +the server must return a FAILED_PRECONDITION error. +

+ +

The updates field is a list of P4 entity updates to be applied. Each update is +defined as: +

+
+
+
message Update {
+  enum Type {
+    UNSPECIFIED = 0;
+    INSERT = 1;
+    MODIFY = 2;
+    DELETE = 3;
+  }
+  Type type = 1;
+  Entity entity = 2;
+}
+

This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a logical table (e.g. +CounterEntry) or an actual table (e.g. TableEntry) in the P4 data +plane. Each entity in the container is uniquely identified by its key. Please +refer to the P4 Entity Messages section for details on +what parts of the entity specification make up the key for each P4 entity. +

+

An update can be one of the following types: +

+
    +
  • +

    INSERT: Inserts the given P4 entity in the entity container. +The entity field always specifies the full state of the P4 entity. +If the entity already exists, an ALREADY_EXISTS error is returned, and +the existing entity remains unchanged. If the entity is malformed, an +INVALID_ARGUMENT error is usually returned (unless a more specific error +code applies [40]). If the entity cannot be inserted because the +container is already full, a RESOURCE_EXHAUSTED error is returned. +

  • +
  • +

    MODIFY: Modifies the P4 entity to its new specified state. This uses +assign or full-snapshot semantics, i.e. the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an INVALID_ARGUMENT error is usually returned (unless a +more specific error code applies [40]). If the entity does not +exist, a NOT_FOUND error is returned. +

  • +
  • +

    DELETE: Deletes the specified P4 entity. If the entity does not exist, a +NOT_FOUND error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored. +

+ +

If an update is not allowed under the given controller role, the server must +return a PERMISSION_DENIED error for this update. +

12.1. Batching and Ordering of Updates

+

P4Runtime supports batching of Write operations. The list of updates in a +WriteRequest is referred to as a batch. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of TableEntry entities). +

+

The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +WriteRequests can also be processed interleaved and/or in parallel. +However, the processing of requests must be strictly serializable. That +is, given a history $S$ of WriteRequests including the responses to those +requests, there must exist an order $L$ for all updates in $S$, such that: +

+
    +
  1. All updates from the same write request must appear as a contiguous +subsequence in $L$, but the order within that subsequence can be arbitrary. +
  2. +
  3. For two updates $u_1$ and $u_2$, if the write request containing $u_1$ +completed before the write request of $u_2$ was sent, then $u_1$ must appear +before $u_2$ in $L$. +
  4. +
  5. Executing all updates in $L$ sequentially must yield the same response for +every update as in $S$. +
  6. +
  7. The observable state of the switch after $S$ (e.g., through the Read RPC) +is identical to the one obtained by sequentially executing $L$. +
+ +

The Write RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the Write RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (e.g. inserting an ActionProfileMember +followed by pointing a TableEntry to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding Write RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate Write calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each Write call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one. +

12.2. Batch Atomicity

+

A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the Atomicity +enum. A P4Runtime server is required to support only the modes marked as +Required below: +

+
    +
  • +

    Required: CONTINUE_ON_ERROR: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that see each of +these intermediate stages. +

  • +
  • +

    Optional: ROLLBACK_ON_ERROR: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is all-or-none, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that see each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure. +

    +

    If a P4Runtime server does not support this option at all, an +UNIMPLEMENTED error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (e.g. it is +more straightforward to implement batches that contain only INSERT +operations, vs. those that contain DELETE operations), an +UNIMPLEMENTED error is returned when the batch cannot be executed +in a data plane-atomic way. +

  • +
  • +

    Optional: DATAPLANE_ATOMIC: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +transaction. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane's table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table. +

    +

    If a P4Runtime server does not support this option at all, an UNIMPLEMENTED +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an UNIMPLEMENTED error is returned when the batch +cannot be executed in a data plane-atomic way. +

+ +

There is no expectation that a given client must always use the same Atomicity +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use DATAPLANE_ATOMIC at one time and default behavior +(CONTINUE_ON_ERROR) at other times. +

12.3. Error Reporting

+

Please see section Error Reporting Messages for +information on error reporting messages and guidelines. P4Runtime server will +populate grpc::Status as follows: +

+
    +
  1. +

    If all batch updates succeeded, set grpc::Status::code_ to OK and do not +populate any other field. +

  2. +
  3. +

    If an error is encountered before even trying to attempt individual batch +updates, set grpc::Status::code_ that best describes that RPC-wide +error. For example, use UNAVAILABLE if the P4Runtime service is not yet +ready to handle requests. Set error_message_ to describe the issue. Do not +set error_details in this case. +

  4. +
  5. +

    Otherwise, if one or more updates in the batch (WriteRequest.updates) +failed, set grpc::Status::code_ to UNKNOWN. For example, one update in +the batch may fail with RESOURCE_EXHAUSTED and another with +INVALID_ARGUMENT. A p4.Error message is used to capture the status of +each and every update in the batch. The number of p4.Error messages packed +into google.rpc.Status.details field should therefore always match the +number of updates in the WriteRequest, and the order of +p4.Error messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +p4.Error should set the code to OK and omit other fields. +

+ +
+
+
# Example of a grpc::Status returned for a Write RPC with a batch of 3 updates.
+# The first and third updates encountered an error, while the second update
+# succeeded.
+code_ = 2  # UNKNOWN
+error_message_ = "Write failure."
+binary_error_details {
+  code: 2  # UNKNOWN
+  message: "Write failure."
+  details {
+    canonical_code: 8  # RESOURCE_EXHAUSTED
+    message: "Table is full."
+    space: "targetX-psa-vendorY"
+    code: 500  # ERR_TABLE_FULL
+  }
+  details {
+    canonical_code: 0  # OK
+  }
+  details {
+    canonical_code: 6  # ALREADY_EXISTS
+    message: "Entity already exists."
+    space: "targetX-psa-vendorY"
+    code: 600  # ERR_ENTITY_ALREADY_EXISTS
+  }
+}

13. Read RPC

+

The Read RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as: +

+
+
+
message ReadRequest {
+  uint64 device_id = 1;
+  string role = 3;
+  repeated Entity entities = 2;
+}
+

The device_id uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +NOT_FOUND error. +If the Read is attempted before ForwardingPipelineConfig has been set, the +server must return a FAILED_PRECONDITION error. +The role field acts as a filter, restricting the reported entities based on +the role to which the entity belongs. +The entities repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server. +

+

Since ReadRequests do not mutate any state on the switch, they do not +require an election_id, and they do not require the presence of an open +StreamChannel between the server and client. +

+

The Read response consists of a sequence of messages (a gRPC stream) with +each message defined as: +

+
+
+
message ReadResponse {
+  repeated Entity entities = 1;
+}
+

The entities repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the Finish() method on the stream object +[12]). +

13.1. Nomenclature

+
+
request
+
An element of the p4.ReadRequest.entities repeated field. +
+
batch
+
Refers to the p4.ReadRequest.entities repeated field.
+

Each request acts as a query filter for that entity type. If a request fully +specifies the entity key, the Read operation should retrieve a single P4 +entity. Please refer to the P4 Entity Messages section +for details on what parts of the entity specification make up the entity key. +

13.2. Wildcard Reads

+

P4Runtime allows wildcard read of P4 entities. A request may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the P4 Entity Messages section for details on +what parts of the entity can be wildcarded in a given request. +

+

For example, in a request of type CounterEntry: +

+
    +
  • A default counter_id (0) implies a request to read all counter-entries for +all indirect counters. +
  • +
  • A particular (non-default) counter_id in conjunction with index unset +implies a request to read all counter-entries for the given indirect counter +ID. +
+ +

To read the entire forwarding state for a given device, the P4Runtime client can +generate the following ReadRequest: +

+
+
+
device_id: <ID>
+entities {
+  extern_entry { }  # read all extern instances for all supported extern types
+  table_entry { }  # read all table entries for all tables
+  action_profile_member { }  # read all members for all action profiles
+  action_profile_group { }  # read all groups for all action profiles
+  ...
+}
+

The entity oneof field in the Entity message must always be set, or the +server must return an INVALID_ARGUMENT error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty Entity message in the ReadRequest. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the entity oneof [25]. +

13.3. Batch Processing

+

A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type request +appears only once in the batch. +

+

A P4Runtime server will process the batch as follows: +

+
    +
  1. +

    Lock state (preventing new writes) and validate each request in the batch: +

    +
      +
    1. +

      If it is a valid request, perform the read; +

      +
        +
      1. If the read was successful, return the entities read in +ReadResponse stream. +
      2. +
      3. If the read failed (exception / critical-error), prepare a p4.Error +with code set to INTERNAL. +
      +
    2. +
    3. +

      If the request is invalid (invalid-argument, not-supported, etc.), +prepare a p4.Error with relevant canonical code to capture the error. +

    +
  2. +
  3. +

    Unlock the state (allowing new writes); +

  4. +
  5. +

    Close the ReadResponse stream and return a grpc::Status as follows: +

    +
      +
    1. +

      If no errors were encountered, set code to OK and do not populate any +other field. +

    2. +
    3. +

      Otherwise, the overall code should be set to UNKNOWN. See section +Error Reporting Messages for information +on error reporting messages and guidelines. Assemble a list of p4.Error +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +google.rpc.Status.details field. This behavior also matches Write +RPC. +

    +
+

13.3.1. Example

+

If a client asked to read {a,b,c,d} and b and d requests didn't +validate, the server will return entities corresponding to a and c, followed +by a status {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} in the +details field. +

+

The P4Runtime server is not required to perform any optimization (e.g. merge two +requests in the batch if one is a subset of other). As a result of this, it +is possible for the ReadResponse to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging. +

+

There is no requirement that each request in the batch will correspond to one +ReadResponse message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit. +

+

A P4Runtime server must be prepared to handle multiple concurrent Read RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (e.g. in a single-threaded architecture), it may choose to serialize +Read RPC processing. +

13.4. Parallelism of Read and Write Requests

+

A P4Runtime server may be implemented to serve at most one +ReadRequest or WriteRequest message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so. +

+

For example, imagine a client that wanted to use WriteRequest +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +WriteRequest messages with only a few updates to an ActionSelector +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +WriteRequest batch currently being processed, but it will not +complete for a significant amount of time. +

+

The restrictions on which a client may rely are: +

+
    +
  • The processing of any two WriteRequest messages W1 and W2 must +result in the same state as if one of them was completed before the +other began. +
  • +
  • For any WriteRequest W and any ReadRequest R, R must +return results consistent with a state where W has completed +processing, or W has not yet begun processing. +
+ +

For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a WriteRequest message it acquired a write lock for each stateful +object affected by the WriteRequest, and before starting the +processing of a ReadRequest message it acquired a read lock for each +stateful object accessed by the ReadRequest, such an implementation +meets all of the requirements above. +

+

It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, e.g. if the server somehow determined that two +WriteRequest messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly. +

14. SetForwardingPipelineConfig RPC

+

A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the SetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message SetForwardingPipelineConfigRequest {
+  enum Action {
+    UNSPECIFIED = 0;
+    VERIFY = 1;
+    VERIFY_AND_SAVE = 2;
+    VERIFY_AND_COMMIT = 3;
+    COMMIT = 4;
+    RECONCILE_AND_COMMIT = 5;
+  }
+  uint64 device_id = 1;
+  string role = 6;
+  Uint128 election_id = 3;
+  Action action = 4;
+  ForwardingPipelineConfig config = 5;
+}
+

The server is expected to perform the following checks (in this order) +before performing the required action: +

+
    +
  1. +

    If device_id does not match any of the devices known to the P4Runtime +server or if role does not match any of the roles for the device, the +server must return a NOT_FOUND error. +

  2. +
  3. +

    If the client is not the primary for (device_id, role) according to +the election_id value, the server must return a PERMISSION_DENIED error. +

+ +

The action is the type of configuration action requested, it can be one of: +

+
    +
  • +

    VERIFY: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an INVALID_ARGUMENT +error if config is not provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_SAVE: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent Read / Write requests must refer to fields in the new +config. Returns an INVALID_ARGUMENT error if the forwarding config is not +provided or if the provided config cannot be realized. +

  • +
  • +

    VERIFY_AND_COMMIT: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an INVALID_ARGUMENT error if the forwarding config is not provided or if the +provided config cannot be realized. +

  • +
  • +

    COMMIT: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a NOT_FOUND error if no saved config +is found, i.e. if no VERIFY_AND_SAVE action preceded this one. Returns an +INVALID_ARGUMENT error if a config is provided with this message. +

  • +
  • +

    RECONCILE_AND_COMMIT: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an UNIMPLEMENTED error. For targets that support this option, an +INVALID_ARGUMENT error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target. +

+ +

The config field is a message of type ForwardingPipelineConfig that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(e.g. generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the Forwarding-Pipeline +Configuration section for details. +

+

A P4Runtime server running on a non-programmable device may not +support SetForwardingPipelineConfig (e.g. the forwarding-pipeline +config is part of the device's software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +UNIMPLEMENTED error. +

15. GetForwardingPipelineConfig RPC

+

The forwarding-pipeline configuration of the target can be retrieved by invoking +the GetForwardingPipelineConfig RPC. The request is defined as: +

+
+
+
message GetForwardingPipelineConfigRequest {
+  enum ResponseType {
+    ALL = 0;
+    COOKIE_ONLY = 1;
+    P4INFO_AND_COOKIE = 2;
+    DEVICE_CONFIG_AND_COOKIE = 3;
+  }
+  uint64 device_id = 1;
+  ResponseType response_type = 2;
+}
+

The device_id uniquely identifies the target P4 device. A NOT_FOUND error is +returned if the device_id is not recognized by the P4Runtime server. +

+

The response_type is used to specify which fields to populate in the response, +its value can be one of: +

+
    +
  • +

    ALL: returns a ForwardingPipelineConfig with all fields +set as stored by the target. This is the default behaviour if the +response_type field is not set. +

  • +
  • +

    COOKIE_ONLY: reply by setting only the cookie field in the +ForwardingPipelineConfig, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message. +

  • +
  • +

    P4INFO_AND_COOKIE: reply by setting the p4info and cookie fields. +

  • +
  • +

    DEVICE_CONFIG_AND_COOKIE: reply by setting the p4_device_config and +cookie fields. +

+ +

The response contains the ForwardingPipelineConfig for the specified device: +

+
+
+
message GetForwardingPipelineConfigResponse {
+  ForwardingPipelineConfig config = 1;
+}
+

If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level config field will be unset in the response. Examples are +(i) a server that only allows configuration via SetForwardingPipelineConfig +but this RPC hasn't been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn't yet occurred. +

+

Once a forwarding-pipeline config is installed on the device (either via +SetForwardingPipelineConfig or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +config.p4_device_config will be empty / unset in the response, even if +response_type in the request was set to ALL. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the SetForwardingPipelineConfig RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +SetForwardingPipelineConfig, the value of config.cookie will be unset. +

+

If a P4Runtime server supports both SetForwardingPipelineConfig as well as +returning the p4_device_config, there should be read-write symmetry between +SetForwardingPipelineConfig and GetForwardingPipelineConfig RPCs. +

16. P4Runtime Stream Messages

16.1. Packet I/O

+

P4Runtime supports controller packet-in and packet-out by means of PacketIn +and PacketOut stream messages, respectively. +

+

PacketIn messages are sent by the P4Runtime server to the client. Conversely, +PacketOut messages are sent by the client to the server. Any PacketOut +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a StreamMessageResponse message with the error field set to +report the error to the client. See the section on Stream Error +Reporting for more information on error. +

+

As introduced in the ControllerPacketMetadata +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with @controller_header. The expected metadata is described +in the P4Info using the ControllerPacketMetadata messages. +

+

Both PacketIn and PacketOut stream messages share the same fields and are +defined as follows: +

+
+
+
// Packet sent from the controller to the switch.
+message PacketOut {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+// Packet sent from the switch to the controller.
+message PacketIn {
+  bytes payload = 1;
+  repeated PacketMetadata metadata = 2;
+}
+
+message PacketMetadata {
+  // This refers to Metadata.id coming from P4Info ControllerPacketMetadata.
+  uint32 metadata_id = 1;
+  bytes value = 2;
+}
+
    +
  • +

    payload is used to carry the full packet content, including the headers. +

  • +
  • +

    metadata is a repeated field of PacketMetadata messages used to carry the +arbitrary controller metadata. When a P4Runtime client (or server) +generates a PacketOut (or PacketIn) message, it must populate precisely +one metadata field for each metadata field in the +ControllerPacketMetadata for packet-out (or packet-in) in the P4Info, such +that the two metadata.id fields match. +The size and value of each PacketIn/PacketOut metadata entry needs +to be consistent with what is specified in the corresponding P4Info +ControllerPacketMetadata.Metadata message with the same id, in the +following sense: +

    +
      +
    • If ControllerPacketMetadata.Metadata.bitwidth is set, or if +ControllerPacketMetadata.Metadata.type_name is set and +P4NewTypeSpec.translated_type.sdn_bitwidth is set in the P4NewTypeSpec +for the type name, then PacketMetadata.value must be a binary string of +the specified bit width conforming to the Bytestrings +requirements. +
    • +
    • If ControllerPacketMetadata.Metadata.type_name is set and +P4NewTypeSpec.translated_type.sdn_string is set in the +P4NewTypeSpec message for the specified type name, then +PacketMetadata.value can be an arbitrary SDN string subject to the +@p4runtime_translation. +If a metadata field +does not match the P4Info specification, the server must drop the PacketOut +message and may generate a StreamMessageResponse message with the error +field set to report the error to the client which issued the PacketOut. See +the section on Stream Error Reporting for more +information on error. +
    +
+

16.2. Client Arbitration Update

+

P4Runtime's client arbitration mechanism ensures that only the current primary +can modify state on the switch, and that the election_id is monotonically +increasing. For example, the switch must finish all previous write operations +before before selecting a different primary, and must only accept write requests +from the current primary. +

+

As explained earlier in this document, the controller uses the StreamChannel +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via Write RPC), +it needs to start a controller session and become a “primary”. To do so, the +controller first opens a bidirectional stream channel to the server via +StreamChannel for each device and sends a StreamMessageRequest message. The +controller populates the MasterArbitrationUpdate field in this message using +its role and election_id and the device_id of the device, as explained +in detail in the Client Arbitration and Controller +Replication +section. For any given (device_id, role), the P4Runtime server keeps track +of the highest election_id that it has ever received. If a controller's +election_id is equal to the highest election_id that the server has ever +received, that controller is the primary. All other controllers are backups. +Note that it is possible that all controllers are backups, and that there is no +primary. There can be at most one primary, because for any given +(device_id, role), each connected controller has a unique election_id. +

+

This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest election_id after such a restart. +However, across a full restart, the election_id must be +reset. In fact, a full restart is the only way to reset the election_id. +

+

The MasterArbitrationUpdate message is defined as follows: +

+
+
+
message MasterArbitrationUpdate {
+  uint64 device_id = 1;
+  // The role for which the primary client is being arbitrated. For use-cases
+  // where multiple roles are not needed, the controller can leave this unset,
+  // implying default role and full pipeline access.
+  Role role = 2;
+  // The stream RPC with the highest election_id is the primary. The 'primary'
+  // controller instance populates this with its latest election_id. Switch
+  // populates with the highest election ID it has received from all connected
+  // controllers.
+  Uint128 election_id = 3;
+  // Switch populates this with OK for the client that is the primary, and
+  // with an error status for all other connected clients (at every primary
+  // client change). The controller does not populate this field.
+  .google.rpc.Status status = 4;
+}
+
+message Role {
+  // Uniquely identifies this role.
+  string name = 3;
+  // Describes the role configuration, i.e. what operations, P4 entities,
+  // behaviors, etc. are in the scope of a given role. If config is not set
+  // (default case), it implies all P4 objects and control behaviors are in
+  // scope, i.e. full pipeline access. The format of this message is
+  // out-of-scope of P4Runtime.
+  .google.protobuf.Any config = 2;
+}
+

Note that the status field in the MasterArbitrationUpdate message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a StreamMessageResponse message back to the controller, in which +it populates the MasterArbitrationUpdate message using the device_id, +role, and election_id it previously received from the controller. The server +also populates the status field in the MasterArbitrationUpdate according to +the rules in an earlier section. +

16.2.1. Unset Election ID

+

The sender need not specify an election_id. If the election_id is +unset, the sender's election_id is considered lower than any +election_id, and the sender will thus never become primary. This way, a +controller can choose to be a standby controller, in order to avoid primary +“flapping” (if a standby controller connects to the switch shortly before the +actual primary controller, therefore becoming primary temporarily). +

+

Note that +

+
election_id : { high: 0 low: 0 }
+

is different from an unset election_id, see +the section on default-valued fields. +

16.3. Digest Messages

+

See the DigestEntry section. +

16.4. Table Idle Timeout Notification

+

When a table supports idle timeout (as per the P4Info message), the primary +client can specify a TTL value for each entry in the table (see +Idle-timeout section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an IdleTimeoutNotification message on the +StreamChannel bidirectional stream to the primary client. The primary client +can then take the action of its choice, most likely remove the idle entry. +

+

The IdleTimeoutNotification Protobuf message has the following fields: +

+
    +
  • +

    timestamp: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server's local clock. +

  • +
  • +

    table_entry: a repeated field of entries which have expired. Each individual +entry is identified by a single TableEntry message. For each TableEntry, +the key fields (table_id, match and priority) must be set, along with +the controller_metadata field, the metadata field, and the +idle_timeout_ns field. Other fields may be set by the server but should be +ignored by the client. +

+ +

Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +IdleTimeoutNotification message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an IdleTimeoutNotification +message with an empty table_entry repeated field. +

+

After generating an idle notification, the P4Runtime server must “reset” the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the primary client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle. +

+

Here is a reasonable pseudo-code implementation for idle timeout for table +entries: +

+
+
+
IdleTimeoutStream stream;
+
+scanning_interval = 10ms;
+
+while (true) {
+  // iterate over all tables which support idle timeout
+  for (table in tables) {
+    if (!table.idle_timeout_supported) continue;
+    // we coalesce all idle notifications for the same table in one
+    // message
+    IdleTimeoutNotification msg;
+    // read time_since_last_hit from device
+    entries = device.load_table_entries_from_hw(table);
+    for (entry in entries) {
+      if (entry.idle_timeout == 0) continue;  // no TTL
+      if (entry.time_since_last_hit < entry.idle_timeout) continue;
+      msg.table_entry_add(entry);
+      entry.reset_time_since_last_hit();
+    }
+    if (msg.table_entry_size() == 0) continue;  // no notifications
+    msg.set_timestamp(now());
+    stream.write(msg);
+  }
+  sleep(scanning_interval);
+}

16.5. Architecture-Specific Notifications

+

P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on StreamChannel, by including an Any Protobuf field [37] +named other in both StreamMessageRequest and StreamMessageResponse. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the PSA Digest +extern. See section on Extending P4Runtime for non-PSA +Architectures for more information. +

16.6. Stream Error Reporting

+

The P4Runtime server can asynchronously report errors which occur when +processing StreamMessageRequest messages, using the error message field (of +type StreamError) in StreamMessageResponse. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature. +

+

The StreamError message has the following fields: +

+
    +
  • canonical_code, which must be set to the appropriate canonical error code +[40]. +
  • +
  • message, an optional developer-facing error message describing the error. +
  • +
  • space and code, which are optional and can be used by vendors to provide +additional details on the error. code is a numeric error code drawn from a +vendor's chosen error space. +
  • +
  • details, which is a Protobuf oneof used to help the client identify which +StreamMessageRequest triggered the error. The server is required to set the +appropriate field in the oneof so that the client can identify which type +of stream message is responsible for the error (packet_out, +digest_list_ack or other), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid PacketOut message from the +client, the packet_out field (of type PacketOutError) should be set in +the details oneof, and the server may additionally set the packet_out +field in the PacketOutError sub-message (by copying it from the invalid +PacketOut message received on the stream channel) so that the client can +know exactly what packet-out triggered the error. +
+ +

The appropriate canonical error code [40] should be used when +populating the canonical_code field. For example: +

+
    +
  • if a controller is not allowed to send a PacketOut message under its +current role definition, the code should be set to PERMISSION_DENIED. +
  • +
  • if the metadata repeated field in PacketOut does not match the P4Info +definition, the code should be set to INVALID_ARGUMENT. It may be useful +for the server to set the packet_out field in this case, so that the client +can find out which set of metadata fields triggered the error. +
  • +
  • if the digest_id field in DigestListAck does not match any Digest entry +in P4Info, the code should be set to INVALID_ARGUMENT. +
+ +

The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, e.g. because of a +burst of PacketIn messages. +

+

Note that client arbitration errors are never reported using the StreamError +message. Invalid MasterArbitrationUpdate messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section 5.3. +

16.6.1. Examples of StreamError Messages

+
    +
  • +

    Malformed packet-out metadata. If the server receives a PacketOut +message with a metadata field with id 7 which is not included in the P4Info +ControllerPacketMetadata message for “packet_out”, the server may send the +following StreamMessageResponse back to the client: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Unknown metadata field id 7."
    + packet_out {
    +   # copied from the PacketOut message received from the client
    +   packet_out {
    +     payload: ...
    +     metadata {
    +       id: 7
    +       name: "I_should_not_be_here"
    +       bitwidth: 32
    +     }
    +     # more metadata
    +   }
    + }
    +}
  • +
  • +

    Packet-out which exceeds the MTU. If the server receives a PacketOut +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following StreamMessageResponse: +

    +
    +
    +
    error {
    + canonical_code: 3  # INVALID_ARGUMENT
    + message: "Packet exceeds the MTU for port."
    + space: "targetX-psa-vendor1"
    + code: 123  # MTU_EXCEEDED
    + packet_out {
    +   # we do not set the packet_out field as it does not provide any
    +   # extra information to the client
    + }
    +}
+

17. Capabilities RPC

+

The Capabilities RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the CapabilitiesRequest message is empty and the CapabilitiesResponse +message only includes the p4runtime_api_version string field. This field must +be set to the full semantic version string [32] corresponding to the +version of the P4Runtime API implemented by the server, e.g. “1.1.0-rc.1”. +

+

Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three atomicity +modes for WriteRequest batches, two of them being +optional. In the future we may decide to leverage the CapabilitiesResponse +message to enable the server to report to the client which subset of these +atomicity modes is supported. +

+

The semantic version string included in CapabilitiesResponse can be used by +the client to determine which exact feature set is implemented by the server, +since minor releases may introduce new +functionality. However, because the Capabilities RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (i.e. an UNIMPLEMENTED error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0). +

18. Portability Considerations

18.1. PSA Metadata Translation

+

The Portable Switch Architecture (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +[29]. For such metadata, a translation between the controller's +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the @p4runtime_translation annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture. +

+
+

psa-metadata-translation +

+
+ +
Figure 8. P4Runtime Metadata Translation for the Portable Switch Architecture
+

Figure 8 illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller's 32 bit port +numbers to a target's 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch. +

18.1.1. Translation of Port Numbers

+

In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller's space and the PSA device's space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +user-defined P4 types, namely PortId_t and +PortIdInHeader_t, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in psa.p4 for +the PSA device in Switch 1. +

+
+
+
@p4runtime_translation("p4.org/psa/v1/PortId_t", 32)
+type bit<9> PortId_t;
+@p4runtime_translation("p4.org/psa/v1/PortIdInHeader_t", 32)
+type bit<32> PortIdInHeader_t;
+

The first argument to the @p4runtime_translation annotation is a URI that +indicates to the P4Runtime server which numerical mapping provided by the +out-of-band switch configuration mechanism to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports). +

+

An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows: +

+
+
+
enum SdnPort {
+  SDN_PORT_UNKNOWN = 0;
+
+  // SDN ports are numbered starting from 1.
+  SDN_PORT_MIN = 1;
+
+  // The maximum value of an SDN port (physical or logical).
+  SDN_PORT_MAX = 0xfffffeff;
+
+  // Reserved SDN port numbers (0xfffffff0 - 0xffffffff)
+
+  SDN_PORT_RECIRCULATE = 0xfffffffa;
+  SDN_PORT_CPU = 0xfffffffd;
+}
+

The switch config will map SDN_PORT_RECIRCULATE and SDN_PORT_CPU as well +as any SDN port number corresponding to a “regular” front-panel port to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation. +

+

The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs. +

18.1.2. Translation of Packet-IO Header Fields

+

Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:. +

+
+
+
@controller_header("packet_out")
+header PacketOut_t {
+  PortIdInHeader_t egress_port;
+}
+
+@controller_header("packet_in")
+header PacketIn_t {
+  PortIdInHeader_t ingress_port;
+}
+

The header-level annotation @controller_header is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (egress_port) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI first argument to the @p4runtime_translation +annotation). Any subsequent reference to the egress_port field in the +data plane will use the translated value. PortIdInHeader_t is used in the +header definition instead of PortId_t to guarantee byte-aligned headers in +case this is required by the target. +

+

A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target's PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the ingress_port field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller. +

18.1.3. Translation of Match Fields

+

Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table's match key as shown in the example below: +

+
+
+
table t {
+  key = {
+    istd.ingress_port: exact;  // PSA standard metadata ingress port
+  }
+  actions = {
+    drop;
+  }
+}
+

Table t has an exact match on PSA standard metadata ingress port +(istd.ingress_port). Since the field is of type PortId_t, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in t from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table t is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values. +

+

Note that it may be infeasible to translate the value-mask pair for ternary +matches: LPM, TERNARY or RANGE match kinds. The P4Runtime server may +require that for these match kinds the port match be either de facto “exact” +(0xffffffff mask for TERNARY, prefix-length of 32 for LPM, or same low and +high bounds for RANGE) or “don't care”. +

18.1.4. Translation of Action Parameters

+

PortId_t type parameters can be part of a P4 action definition as shown in the +example below: +

+
+
+
action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+}
+
+table t {
+  key = {
+    hdr.h.f: exact;
+  }
+  actions = {
+    a;
+  }
+}
+

The controller may write entries in table t with action a to set the egress +port as shown in the P4 code above. The action parameter p is of type +PortId_t, which leads to a 32-bit bitwidth for p being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device. +

18.1.5. Port Translation for PSA Extern APIs

+

The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The watch_port +field is of type bytes to carry the SDN representation of the port being +watched. The P4Runtime server will translate the given watch port into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device. +

+

The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress port fields defined in the PRE +multicast entry and clone session entry are of type bytes to carry the SDN +representation of the port(s). The P4Runtime server will translate these SDN +ports to device-specific port numbers for multicasting and cloning in the data +plane. +

18.1.6. Using Port as an Index to a Register, Indirect Counter or Indirect Meter

+

P4Runtime supports using a translated value (PortId_t or any other translated +type for which the underlying built-in type is bit<W>) as an index to a +register, indirect counter, or indirect meter. +

+
+
+
Counter<bit<32> /* counter entry type */, PortId_t /* index type */>(
+  32w1024, PSA_CounterType_t.PACKETS) counter;
+action a(PortId_t p) {
+  istd.egress_port = p;  // PSA standard metadata egress port
+  counter.count(p);
+}
+

This P4 Counter declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
counters {
+  preamble {
+    id: 0x12000001
+    name: "counter"
+  }
+  spec {
+    unit: PACKETS
+  }
+  index_type_name {
+    name: "PortId_t"
+  }
+}
+

The controller may read and write counter values from indexed counter counter +using SDN port numbers as indices, and not device-specific port numbers. The +index_type_name field in the P4Info message is a signal to the P4Runtime +server that translation is required. +

19. P4Runtime Versioning

+

P4Runtime follows the Google guidelines for versioning cloud APIs +[8]. We use a MAJOR.MINOR.PATCH style version number scheme and +we increment the: +

+
    +
  • MAJOR version when we make incompatible API changes, +
  • +
  • MINOR version when we add functionality in a backwards-compatible manner, +
  • +
  • PATCH version when we make backwards-compatible bug fixes. +
+ +

The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is p4.v1 and the package +name for P4Info is p4.config.v1. Even though p4 and p4.config are two +different Protobuf packages, p4 depends on p4.config and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence. +

+

As recommended in [8], we may consider using pre-GA release +suffixes (such as alpha or beta) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1). +

+

Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner. [9] describes +what constitute a backwards-compatible change. We expect MAJOR version bumps +to be a rare event. +

+

Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor + patch version numbers in future releases. +

+

All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository [19] and the version label follows +semantic versioning rules [32]. +

20. Extending P4Runtime for non-PSA Architectures

+

P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place. +

+

When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names: +

+
    +
  • p4/[organization]/arch/config/<major version>/p4info.proto +
  • +
  • p4/[organization]/arch/<major version>/p4runtime.proto +
+ +

We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they “extend”. +

+

For the remainder of this section, we will refer to these two files as +p4info-ext and p4runtime-ext respectively. +

20.1. Extending P4Runtime for Architecture-Specific Externs

+

Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both p4info-ext and +p4runtime-ext. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example: +

+
+
+
// T must be a bit<W> type, it indicates the width of each counter cell
+extern MyNewPacketCounter<T> {
+  counter(bit<32> size);
+  increment(in bit<32> index);
+}

20.1.1. Extending the P4Info message

+
    +
  • Id prefixes 0x81 through 0xfe are reserved for architecture-specific +externs. It is recommended that p4info-ext include a P4Ids message based +on the one in p4info.proto that the P4 compiler can refer to when assigning +IDs to each extern instance. +
+ +
+
+
message P4Ids {
+  enum Prefix {
+    UNSPECIFIED = 0;
+    MY_NEW_PACKET_COUNTER = 0x81;
+  }
+}
+
    +
  • p4info-ext should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +p4.config.v1.ExternInstance message as the info +field, which is of type Any [37]. +
+ +
+
+
message MyNewPacketCounter {
+  // corresponds to the T type parameter in the P4 extern definition
+  p4.config.v1.P4DataTypeSpec type_spec = 1;
+  // constructor argument
+  int64 size = 2;
+}

20.1.2. Extending the P4Runtime Service

+

Just like p4info-ext, p4runtime-ext should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an ExternEntry message generated by the +P4Runtime client. +

+

Here is a possible Protobuf message for our MyNewPacketCounter P4 extern: +

+
+
+
// This message enables reading / writing data to the counter at the provided
+// index
+message MyNewPacketCounter {
+  int64 index = 1;
+  p4.v1.P4Data data = 2;
+}
+

P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an Any Protobuf field [37] named other +in both p4.v1.StreamMessageRequest and +p4.v1.StreamMessageResponse. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in p4runtime-ext and embed instances of these messages in +p4.v1.StreamMessageRequest and p4.v1.StreamMessageResponse as appropriate. +

20.2. Architecture-Specific Table Extensions

20.2.1. New Match Types

+

An architecture may introduce new table match types [14]. P4Runtime +accounts for this by providing the following hooks: +

+
    +
  • +

    The match field in p4.config.v1.MatchField (p4info.proto) is a oneof +which can be either one of the default match types (EXACT, LPM, TERNARY, +RANGE, or OPTIONAL) or an architecture-specific match type encoded as a +string. +

  • +
  • +

    The field_match_type field in p4.v1.FieldMatch (p4runtime.proto) is a +oneof which includes an Any Protobuf message [37] field +(other). p4info-ext should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in p4.v1.FieldMatch as the +other field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info. +

+

20.2.2. New Table Properties

+

An architecture may introduce additional table properties +[36]. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +p4.config.v1.Table message includes the other_properties Any Protobuf +field [37]. At the moment, there is not any mechanism to extend the +p4.v1.TableEntry message based on the value of architecture-specific table +properties, but we may include on in future versions of the API. +

21. Known Limitations of Current P4Runtime Version

+
    +
  • +

    FieldMatch, action Param, and controller packet metadata fields only +support unsigned bitstrings, i.e. values of one of the following types (not +the more general P4Data): +

    +
      +
    • bit<W> +
    • +
    • bool. Note that as far as the P4Info message contents and +thus controller software is concerned, such fields of type bool +will be indistinguishable from those that have been declared with +type bit<1>. P4Runtime server software will automatically +perform any conversion needed between the type bit<1> values in +P4Runtime messages and the data plane representation. +
    • +
    • an enum with underlying type bit<W> +
    • +
    • a type or typedef with an underlying type that is one of the above (or +in general a “chain” of type and/or typedef that eventually ends with +one of the types above) +
    +
  • +
  • +

    Support for PSA Random & Timestamp externs is postponed to a future minor +version update. +

  • +
  • +

    P4Info does not include information about which of a table's actions execute +which direct resource(s). +

  • +
  • +

    The default action for indirect match tables is restricted to a const +NoAction known at compile-time. +

  • +
  • +

    There is no mechanism for changing the value of the psa_empty_group_action +table property at runtime. +

  • +
  • +

    There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor + +patch version numbers. +

+

A. Appendix

A.1. Revision History

A.1.1. Changes in v1.4.0

+
    +
  • Add a Type field to the MeterSpec message allowing users to restrict the +type of meters that can be used for a table and a new eburst field to the +MeterConfig message for use with one of the new MeterSpec types. +
  • +
  • Add a PlatformProperties message specifying desired underlying platform +properties to the PkgInfo message. +
  • +
  • Add a metadata field to the MulticastGroupEntry message. +
  • +
  • Clarify that the limitation on supported types for FieldMatch, action +Param, and Packet IO metadata fields (no support for signed integers, with +type int<W>) apply to all minor revisions of P4Runtime v1, not just to +P4Runtime v1.0. +
  • +
  • Fix invalid action_profile_id in the One Shot Action Selector Programming +example. +
  • +
  • Specify Read behavior in the absence of a P4Info (ForwardingPipelineConfig +not set yet). +
  • +
  • Clarify that for updates of type INSERT, error codes other than +INVALID_ARGUMENT can be returned when applicable. +
  • +
  • Enable C++ Arena Allocation [4] by default in p4runtime.proto. +
  • +
  • Add support for string role identifiers and deprecate integer role +identifiers. +
  • +
  • Add support for specifying a role in ReadRequest messages: if present, only +entities belonging to this specific role are returned. +
  • +
  • Specify that max_group_size must be less than or equal to size for Action +Selectors. +
  • +
  • Simplify specification for arbitration updates for which there is no change to +the controller's election_id; in particular, a “no-op” arbitration update +from a primary controller (the controller already was, and remains, the +primary controller) is essentially treated the same way as an arbitration +update which leads to the election of a new primary controller. +
  • +
  • Enable P4Runtime servers to provide per-color counter values when direct or +indirect meter entries are read. +
  • +
  • Clarify that the (device_id, role, election_id) 3-tuples are only unique +for live controllers. +
  • +
  • Add a selector_size_semantics field to the ActionProfile message +in P4Info. +
+

A.1.2. Changes in v1.3.0

+
    +
  • Add IANA assigned TCP port, 9559, to P4Runtime server discussion. +
  • +
  • Move “Security considerations” section to P4Runtime server discussion. +
  • +
  • Deprecate watch field (int32) in favor of watch_port (bytes). This allows +using the watch port feature with the p4runtime_translation feature. +
  • +
  • Replace master, slave, master arbitration with more inclusive language: +primary, backup, and client arbitration +
  • +
  • Clarify that source locations for annotations are optional in the P4Info +message. +
+

A.1.3. Changes in v1.2.0

+
    +
  • Add new OPTIONAL match kind. At the moment, OPTIONAL is only supported by +the v1model architecture [44], and not by PSA. It will eventually be +included in the core P4 language. +
  • +
  • Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists. +
  • +
  • Add a new metadata field of type bytes to TableEntry. This is more +flexible than the now deprecated controller_metadata field. +
  • +
  • Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +@id annotation. +
  • +
  • Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature. +
  • +
  • Support using string as the controller type in the @p4runtime_translation +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type. +
  • +
  • Add optional P4 source locations to both structured and unstructured +annotations. +
+

A.1.4. Changes in v1.1.0

+
    +
  • Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously. +
  • +
  • Add error field to stream messages sent by the server. +
  • +
  • Add Capabilities RPC to query the P4Runtime API version implemented by the +server. +
  • +
  • Support wildcard reads for multicast groups and clone sessions. +
  • +
  • Support for modifying direct resources of const tables. +
  • +
  • Support P4 user-defined types for Packet IO metadata fields. +
  • +
  • Clarify consistency requirements for Write and Read RPCs. +
  • +
  • Add Appendix providing implementation advice for avoiding common pitfalls: + +
      +
    • advice on setting gRPC Metadata Maximum Size +
    • +
    • advice on setting gRPC Server Maximum Receive Message Size +
  • +
  • Clarify limitations on supported types for FieldMatch, action Param, and +Packet IO metadata fields. +
  • +
  • Clarify that reading entire forwarding state with empty entity is not +supported. +
  • +
  • Document that @p4runtime_translation need only be supported when applied to +type declarations in P4. +
+

A.2. P4 Annotations

+

Table 7 lists P416 annotations introduced primarily for +the purpose of adding features for the P4Runtime API. +

+
+ + + + + + + + + + + + + + + + +
Annotation Description
@brief See section 6.1.3
@controller_header See section 6.4.6
@description See section 6.1.3
@id See section 6.3
@max_group_size See sections 6.4.3, 9.2.2
@selector_size_semantics See section 6.4.3
@max_member_weight See section 6.4.3
@two_rate_three_color See section 6.4.5
@single_rate_three_color See section 6.4.5
@single_rate_two_color See section 6.4.5
@pkginfo See section 6.2.1
@platform_property See section 6.2.1
@p4runtime_translation See sections 8.4.6, 18.1.1
+
+ +
Table 7. P4 annotations introduced by P4Runtime

A.3. A More Complex Value Set Example

+

This section includes a more complex Value Set example, with multiple matches of +different kinds. +

+
+
+
struct match_t {
+  bit<8> f8;
+  @match(ternary) bit<16> f16;
+  @match(custom) bit<32> f32;
+}
+@id(1) value_set<match_t>(4) pvs;
+select ({ hdr.f8, hdr.f16, hdr.f32 }) { /* ... */ }
+

This P4 Value Set declaration will translate into the following entry in the +P4Info messsage: +

+
+
+
value_sets {
+  preamble {
+    id: 0x03000001
+    name: "pvs"
+  }
+  match {
+    id: 1
+    name: "f8"
+    bitwidth: 8
+    match_type: EXACT
+  }
+  match {
+    id: 2
+    name: "f16"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match {
+    id: 3
+    name: "f32"
+    bitwidth: 32
+    other_match_type: "custom"
+  }
+  size: 4
+}
+

A P4Runtime client can set the membership for this Value Set with WriteRequest +messages similar to this one: +

+
+
+
type: MODIFY
+entity {
+  value_set_entry {
+    value_set_id: 0x03000001
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xac }
+      }
+      # match for field_id 2 is missing => don't care match
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+    members {
+      match {
+        field_id: 1
+        exact { value: 0xdc }
+      }
+      match {
+        field_id: 2
+        ternary { value: 0x88 mask: 8f }
+      }
+      match {
+        field_id: 3
+        other { ... }  # some serialized Any message (architecture-specific)
+      }
+    }
+  }
+}

A.4. Guidelines for Implementations

+

This section contains practical advice for implementing P4Runtime clients and +servers. +

A.4.1. gRPC Metadata Maximum Size

+

In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the grpc.max_metadata_size gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the Write P4Runtime RPC. The Write RPC +returns an individual error for every item in a batch (see Section +12), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +RESOURCE_EXHAUSTED error, without any of the individual errors. +

+

To fix this problem, one can set the grpc.max_metadata_size option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it's +limit, as only the receiving side's limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every p4.Error, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +8192 + MAX_UPDATES_PER_WRITE * 100 bytes of metadata. +

+

For example, in C++, one can create a client channel as follows: +

+
+
+
const int MAX_UPDATES_PER_WRITE = 100;
+::grpc::ChannelArguments arguments;
+arguments.SetInt(GRPC_ARG_MAX_METADATA_SIZE, 8192 + MAX_UPDATES_PER_WRITE*100);
+return grpc::CreateCustomChannel(address, credentials, arguments);

A.4.2. gRPC Server Maximum Receive Message Size

+

At the time of writing, the default maximum receive message size in gRPC is 4MB + while the default maximum send message size is unlimited. This can be a +problem for the SetForwardingPipelineConfig RPC, since for some targets the +binary p4_device_config can exceed 4MB, in which case by default the P4Runtime +server would return an INVALID_ARGUMENT error. To a lesser extent, this may +affect the Write RPC as well, in case of extremely large batches. +

+

To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of p4_device_config for their target(s). This can be done by +setting the grpc.max_receive_message_length when building the gRPC server. +

+

For example, in C++, one can set the maximum receive message size as follows: +

+
+
+
const int MAX_RECEIVE_MESSAGE_SIZE = 128 * 1024 * 1024;  // 128MB
+::grpc::ServerBuilder server_builder;
+builder.AddListeningPort(/*...*/);
+builder.RegisterService(/*...*/);  // register P4Runtime service
+builder.SetMaxReceiveMessageSize(MAX_RECEIVE_MESSAGE_SIZE);
+builder.BuildAndStart();
+

On the client side, we recommend that P4Runtime clients do not use Write +batches larger than the default maximum receive message size (4MB) in case +the server did not deem necessary to increase the default value , unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB). +

A.5. P4Runtime Entries files

+

The open source P4 compiler p4c [15] implements an option to +generate an “entries file”, i.e. a file that contains all table +entries declared via the entries table property within the program. +

+

An example P416 program that can be used to demonstrate this +capability is table-entries-ternary-bmv2.p4 [16]: +

+
git clone https://github.com/p4lang/p4c
+cd p4c/testdata/p4_16_samples
+mkdir tmp
+p4test --arch v1model \
+    --p4runtime-files tmp/p4info.txt \
+    --p4runtime-entries-files tmp/entries.txt \
+    table-entries-ternary-bmv2.p4
+

You can replace the .txt suffix of the file name tmp/entries.txt +in the example command above with .json or .bin. The .bin +format is a binary P4Runtime API protobuf message format. The .txt +format is the text encoding of the same Protobuf messages. +

+

Target devices are not required to use this file. For example, if a +target has a P4 compiler back end that encodes all of the necessary +details from the P4 source program, including the entries of tables, +in a target-specific binary format, then that target might have no +reason to generate these entries files. +

+

Some target devices might choose to generate entries files, and also +to require doing so in order to have a correct implementation. For +example, a target runtime implementation might take a target-specific +binary format for the compiled P4 program that does not contain any +data describing the entries of tables, plus the entries file +generated by p4c, and use the entries file to load the initial +entries of tables into the device. +

+

The format of the entries file is a single WriteRequest message +containing one Update sub-message per entry in the P4 source program +defined via an entries table property. All Update sub-messages +have type equal to INSERT, and entity is a TableEntry message +containing the data for one table entry. +

+

Note that if a P4Runtime client attempted to send a WriteRequest to +a P4Runtime server with the contents of the entries file, the server +must return an error for each entry that has is_const true, as +described in Section 9.1. +

+

References

+
+ +
[2]“A Single Rate Three Color Marker.” https://​tools.​ietf.​org/​html/​rfc2697.
+
[3]“A Two Rate Three Color Marker.” https://​tools.​ietf.​org/​html/​rfc2698.
+ + + + + +
[9]“Google Cloud APIs Versioning - Backwards-Compatibility.” https://​cloud.​google.​com/​apis/​design/​versioning#​backwards_​compatibility.
+ +
[11]“gRPC Main Site.” https://​grpc.​io.
+ + + +
[15]“P4_16 Reference Compiler.” https://​github.​com/​p4lang/​p4c.
+ + + +
[19]“p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” https://​github.​com/​p4lang/​p4runtime.
+
[20]“p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.” https://​github.​com/​p4lang/​PI.
+ + +
[23]“Portable NIC Architecture Specification (v0.7).” https://​p4.​org/​p4-​spec/​docs/​PNA-​v0.​7.​html.
+
[24]“Portable Switch Architecture Specification (v1.1.0).” https://​p4.​org/​p4-​spec/​docs/​PSA-​v1.​1.​0.​html.
+ + + + + + + +
[32]“Semantic Versioning.” https://​semver.​org/​.
+ + + + + + + + +
[41]“The OpenConfig Project.” http://​openconfig.​net.
+ +
[43]“The Stratum Project.” https://​stratumproject.​org/​.
+ +
+
+
+ +
+

1.an enum type used as a field in a header must specify a +underlying type and representation for enum elements. +

+ + + diff --git a/spec/v1.4.0/P4Runtime-Spec.log b/spec/v1.4.0/P4Runtime-Spec.log new file mode 100644 index 00000000..fd653333 --- /dev/null +++ b/spec/v1.4.0/P4Runtime-Spec.log @@ -0,0 +1,16059 @@ +This is XeTeX, Version 3.14159265-2.6-0.99992 (TeX Live 2015/Debian) (preloaded format=xelatex 2018.8.17) 13 SEP 2024 17:11 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**build/P4Runtime-Spec.tex +(./build/P4Runtime-Spec.tex +LaTeX2e <2016/02/01> +Babel <3.9q> and hyphenation patterns for 81 language(s) loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2014/09/29 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo +File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@section=\count80 +\c@subsection=\count81 +\c@subsubsection=\count82 +\c@paragraph=\count83 +\c@subparagraph=\count84 +\c@figure=\count85 +\c@table=\count86 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) (build/madoko2.sty (/usr/share/texlive/texmf-dist/tex/latex/colortbl/colortbl.sty +Package: colortbl 2012/02/13 v1.0a Color table columns (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty +Package: array 2014/10/28 v2.4c Tabular extension package (FMi) +\col@sep=\dimen103 +\extrarowheight=\dimen104 +\NC@list=\toks14 +\extratabsurround=\skip43 +\backup@length=\skip44 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty +Package: color 2016/01/03 v1.1b Standard LaTeX Color (DPC) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package color Info: Driver file: xetex.def on input line 143. +(/usr/share/texlive/texmf-dist/tex/xelatex/xetex-def/xetex.def +File: xetex.def 2015/09/11 v4.06 LaTeX color/graphics driver for XeTeX (TeX Live/RRM/JK) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +))) +\everycr=\toks15 +\minrowclearance=\skip45 +) (/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: xetex.def on input line 225. +LaTeX Info: Redefining \color on input line 702. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) (build/options.sty +Package: options 2015/03/01, Daan Leijen, Provides convenient path-value (or key-value) options +(/usr/share/texlive/texmf-dist/tex/latex/etoolbox/etoolbox.sty +Package: etoolbox 2015/08/02 v2.2a e-TeX tools for LaTeX (JAW) +\etb@tempcnta=\count87 +) +\opt@nesting=\count88 +\opt@idx=\count89 +\opt@choiceord=\count90 +) (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty +Package: iftex 2013/04/04 v0.2 Provides if(tex) conditional for PDFTeX, XeTeX, and LuaTeX +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2014/10/28 v1.0g Enhanced LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks16 +) (/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2016/01/03 v1.0q Standard LaTeX Graphics (DPC,SPQR) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2016/01/03 v1.10 sin cos tan (DPC) +) (/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg +File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live +) +Package graphics Info: Driver file: xetex.def on input line 95. +) +\Gin@req@height=\dimen105 +\Gin@req@width=\dimen106 +) (build/longfbox.sty +Package: longfbox 2015/12/01, Daan Leijen, Provides long fbox that can break over pages +(build/longbox.sty +Package: longbox 2015/12/01, Daan Leijen, Provides basic longbox that can break over pages +(/usr/share/texlive/texmf-dist/tex/latex/mdwtools/footnote.sty +Package: footnote 1997/01/28 1.13 Save footnotes around boxes +\fn@notes=\box26 +\fn@width=\dimen107 +) +\lb@prevdepth=\skip46 +\lb@freevspace=\skip47 +\lb@headbox=\box27 +\lb@savebox=\box28 +\lb@mainbox=\box29 +\lb@usevbox=\count91 +\lb@width=\skip48 +\lb@height=\skip49 +\lb@skiptop=\skip50 +\lb@skipright=\skip51 +\lb@skipbottom=\skip52 +\lb@skipleft=\skip53 +\lb@skipbreaktop=\skip54 +\lb@skipbreakbottom=\skip55 +\lb@outerwidth=\skip56 +\lb@extrasplit=\skip57 +\lb@textalign=\count92 +\lb@baseline=\count93 +\lb@neededvspace=\skip58 +\lb@splitheight=\skip59 +\lb@insurance=\skip60 +\/longbox/@part-height=\skip61 +\/longbox/@part-width=\skip62 +\/longbox/@part-depth=\skip63 +\/longbox/@content-box-height=\skip64 +\/longbox/@content-box-width=\skip65 +\/longbox/@content-box-depth=\skip66 +\/longbox/@breakat-previous=\skip67 +\/longbox/@lower=\skip68 +\/longbox/split-minimum=\skip69 +\/longbox/split-badness=\skip70 +\/longbox/raise=\skip71 +\/longbox/height=\skip72 +\/longbox/width=\skip73 +\/longbox/outer-height=\skip74 +\/longbox/outer-width=\skip75 +\/longbox/skip-top=\skip76 +\/longbox/skip-right=\skip77 +\/longbox/skip-bottom=\skip78 +\/longbox/skip-left=\skip79 +\/longbox/skip-break-bottom=\skip80 +\/longbox/skip-break-top=\skip81 +) (/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.sty +Package: pict2e 2016/02/05 v0.3b Improved picture commands (HjG,RN,JT) +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/pict2e.cfg +File: pict2e.cfg 2016/02/05 v0.1u pict2e configuration for teTeX/TeXLive +) +Package pict2e Info: Driver file: xetex.def on input line 119. +Package pict2e Info: Driver file for pict2e: p2e-xetex.def on input line 121. +(/usr/share/texlive/texmf-dist/tex/latex/pict2e/p2e-xetex.def +File: p2e-xetex.def 2016/02/05 v0.1u Driver-dependant file (RN,HjG,JT) +) +\pIIe@GRAPH=\toks17 +\@arclen=\dimen108 +\@arcrad=\dimen109 +\@tempdimd=\dimen110 +) (build/ellipse.sty +Package: ellipse 2004/11/05 v1.0 .dtx ellipse file +) +\fbox@oct=\count94 +\fbox@quad=\count95 +\fbox@diaq=\count96 +\fbox@sign=\count97 +\fbox@anglestart=\skip82 +\fbox@angleend=\skip83 +\fbox@dash=\skip84 +\fbox@dashskip=\skip85 +\fbox@anglecur=\skip86 +\fbox@dashangle=\skip87 +\fbox@dashskipangle=\skip88 +\fbox@delta=\skip89 +\fbox@from=\skip90 +\fbox@to=\skip91 +\/fbox/padding-top=\skip92 +\/fbox/padding-right=\skip93 +\/fbox/padding-bottom=\skip94 +\/fbox/padding-left=\skip95 +\/fbox/padding-break-top=\skip96 +\/fbox/padding-break-bottom=\skip97 +\/fbox/margin-top=\skip98 +\/fbox/margin-right=\skip99 +\/fbox/margin-bottom=\skip100 +\/fbox/margin-left=\skip101 +\/fbox/margin-break-top=\skip102 +\/fbox/margin-break-bottom=\skip103 +\/fbox/border-top-width=\skip104 +\/fbox/border-right-width=\skip105 +\/fbox/border-bottom-width=\skip106 +\/fbox/border-left-width=\skip107 +\/fbox/border-break-top-width=\skip108 +\/fbox/border-break-bottom-width=\skip109 +\/fbox/@lower=\skip110 +\/fbox/@padding-box-height=\skip111 +\/fbox/@padding-box-depth=\skip112 +\/fbox/@padding-box-width=\skip113 +\/fbox/@border-box-width=\skip114 +\/fbox/@border-box-height=\skip115 +\/fbox/@border-box-depth=\skip116 +\/fbox/@border-top-left-radius-x=\skip117 +\/fbox/@border-top-right-radius-x=\skip118 +\/fbox/@border-bottom-left-radius-x=\skip119 +\/fbox/@border-bottom-right-radius-x=\skip120 +\/fbox/@border-top-left-radius-y=\skip121 +\/fbox/@border-top-right-radius-y=\skip122 +\/fbox/@border-bottom-left-radius-y=\skip123 +\/fbox/@border-bottom-right-radius-y=\skip124 +\/fbox/@border-top-left-ix=\skip125 +\/fbox/@border-top-left-iy=\skip126 +\/fbox/@border-top-right-ix=\skip127 +\/fbox/@border-top-right-iy=\skip128 +\/fbox/@border-bottom-left-ix=\skip129 +\/fbox/@border-bottom-left-iy=\skip130 +\/fbox/@border-bottom-right-ix=\skip131 +\/fbox/@border-bottom-right-iy=\skip132 +\/fbox/@border-top-left-phi=\skip133 +\/fbox/@border-top-right-phi=\skip134 +\/fbox/@border-bottom-left-phi=\skip135 +\/fbox/@border-bottom-right-phi=\skip136 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2016/03/03 v2.15a AMS math features +\@mathmargin=\skip137 +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2000/06/29 v2.01 AMS text +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen111 +)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen112 +) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 1999/12/14 v2.01 operator names +) +\inf@bad=\count98 +LaTeX Info: Redefining \frac on input line 199. +\uproot@=\count99 +\leftroot@=\count100 +LaTeX Info: Redefining \overline on input line 297. +\classnum@=\count101 +\DOTSCASE@=\count102 +LaTeX Info: Redefining \ldots on input line 394. +LaTeX Info: Redefining \dots on input line 397. +LaTeX Info: Redefining \cdots on input line 518. +\Mathstrutbox@=\box30 +\strutbox@=\box31 +\big@size=\dimen113 +LaTeX Font Info: Redeclaring font encoding OML on input line 630. +LaTeX Font Info: Redeclaring font encoding OMS on input line 631. +\macc@depth=\count103 +\c@MaxMatrixCols=\count104 +\dotsspace@=\muskip10 +\c@parentequation=\count105 +\dspbrk@lvl=\count106 +\tag@help=\toks19 +\row@=\count107 +\column@=\count108 +\maxfields@=\count109 +\andhelp@=\toks20 +\eqnshift@=\dimen114 +\alignsep@=\dimen115 +\tagshift@=\dimen116 +\tagwidth@=\dimen117 +\totwidth@=\dimen118 +\lineht@=\dimen119 +\@envbody=\toks21 +\multlinegap=\skip138 +\multlinetaggap=\skip139 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2735. +LaTeX Info: Redefining \] on input line 2736. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols +) (/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/stmaryrd.sty +Package: stmaryrd 1994/03/03 St Mary's Road symbol package +\symstmry=\mathgroup6 +LaTeX Font Info: Overwriting symbol font `stmry' in version `bold' +(Font) U/stmry/m/n --> U/stmry/b/n on input line 89. +) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty +Package: textcomp 2005/09/27 v1.99g Standard LaTeX package +Package textcomp Info: Sub-encoding information: +(textcomp) 5 = only ISO-Adobe without \textcurrency +(textcomp) 4 = 5 + \texteuro +(textcomp) 3 = 4 + \textohm +(textcomp) 2 = 3 + \textestimated + \textcurrency +(textcomp) 1 = TS1 - \textcircled - \t +(textcomp) 0 = TS1 (full) +(textcomp) Font families with sub-encoding setting implement +(textcomp) only a restricted character set as indicated. +(textcomp) Family '?' is the default used for unknown fonts. +(textcomp) See the documentation for details. +Package textcomp Info: Setting ? sub-encoding to TS1/1 on input line 79. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +) +LaTeX Info: Redefining \oldstylenums on input line 334. +Package textcomp Info: Setting cmr sub-encoding to TS1/0 on input line 349. +Package textcomp Info: Setting cmss sub-encoding to TS1/0 on input line 350. +Package textcomp Info: Setting cmtt sub-encoding to TS1/0 on input line 351. +Package textcomp Info: Setting cmvtt sub-encoding to TS1/0 on input line 352. +Package textcomp Info: Setting cmbr sub-encoding to TS1/0 on input line 353. +Package textcomp Info: Setting cmtl sub-encoding to TS1/0 on input line 354. +Package textcomp Info: Setting ccr sub-encoding to TS1/0 on input line 355. +Package textcomp Info: Setting ptm sub-encoding to TS1/4 on input line 356. +Package textcomp Info: Setting pcr sub-encoding to TS1/4 on input line 357. +Package textcomp Info: Setting phv sub-encoding to TS1/4 on input line 358. +Package textcomp Info: Setting ppl sub-encoding to TS1/3 on input line 359. +Package textcomp Info: Setting pag sub-encoding to TS1/4 on input line 360. +Package textcomp Info: Setting pbk sub-encoding to TS1/4 on input line 361. +Package textcomp Info: Setting pnc sub-encoding to TS1/4 on input line 362. +Package textcomp Info: Setting pzc sub-encoding to TS1/4 on input line 363. +Package textcomp Info: Setting bch sub-encoding to TS1/4 on input line 364. +Package textcomp Info: Setting put sub-encoding to TS1/5 on input line 365. +Package textcomp Info: Setting uag sub-encoding to TS1/5 on input line 366. +Package textcomp Info: Setting ugq sub-encoding to TS1/5 on input line 367. +Package textcomp Info: Setting ul8 sub-encoding to TS1/4 on input line 368. +Package textcomp Info: Setting ul9 sub-encoding to TS1/4 on input line 369. +Package textcomp Info: Setting augie sub-encoding to TS1/5 on input line 370. +Package textcomp Info: Setting dayrom sub-encoding to TS1/3 on input line 371. +Package textcomp Info: Setting dayroms sub-encoding to TS1/3 on input line 372. +Package textcomp Info: Setting pxr sub-encoding to TS1/0 on input line 373. +Package textcomp Info: Setting pxss sub-encoding to TS1/0 on input line 374. +Package textcomp Info: Setting pxtt sub-encoding to TS1/0 on input line 375. +Package textcomp Info: Setting txr sub-encoding to TS1/0 on input line 376. +Package textcomp Info: Setting txss sub-encoding to TS1/0 on input line 377. +Package textcomp Info: Setting txtt sub-encoding to TS1/0 on input line 378. +Package textcomp Info: Setting lmr sub-encoding to TS1/0 on input line 379. +Package textcomp Info: Setting lmdh sub-encoding to TS1/0 on input line 380. +Package textcomp Info: Setting lmss sub-encoding to TS1/0 on input line 381. +Package textcomp Info: Setting lmssq sub-encoding to TS1/0 on input line 382. +Package textcomp Info: Setting lmvtt sub-encoding to TS1/0 on input line 383. +Package textcomp Info: Setting lmtt sub-encoding to TS1/0 on input line 384. +Package textcomp Info: Setting qhv sub-encoding to TS1/0 on input line 385. +Package textcomp Info: Setting qag sub-encoding to TS1/0 on input line 386. +Package textcomp Info: Setting qbk sub-encoding to TS1/0 on input line 387. +Package textcomp Info: Setting qcr sub-encoding to TS1/0 on input line 388. +Package textcomp Info: Setting qcs sub-encoding to TS1/0 on input line 389. +Package textcomp Info: Setting qpl sub-encoding to TS1/0 on input line 390. +Package textcomp Info: Setting qtm sub-encoding to TS1/0 on input line 391. +Package textcomp Info: Setting qzc sub-encoding to TS1/0 on input line 392. +Package textcomp Info: Setting qhvc sub-encoding to TS1/0 on input line 393. +Package textcomp Info: Setting futs sub-encoding to TS1/4 on input line 394. +Package textcomp Info: Setting futx sub-encoding to TS1/4 on input line 395. +Package textcomp Info: Setting futj sub-encoding to TS1/4 on input line 396. +Package textcomp Info: Setting hlh sub-encoding to TS1/3 on input line 397. +Package textcomp Info: Setting hls sub-encoding to TS1/3 on input line 398. +Package textcomp Info: Setting hlst sub-encoding to TS1/3 on input line 399. +Package textcomp Info: Setting hlct sub-encoding to TS1/5 on input line 400. +Package textcomp Info: Setting hlx sub-encoding to TS1/5 on input line 401. +Package textcomp Info: Setting hlce sub-encoding to TS1/5 on input line 402. +Package textcomp Info: Setting hlcn sub-encoding to TS1/5 on input line 403. +Package textcomp Info: Setting hlcw sub-encoding to TS1/5 on input line 404. +Package textcomp Info: Setting hlcf sub-encoding to TS1/5 on input line 405. +Package textcomp Info: Setting pplx sub-encoding to TS1/3 on input line 406. +Package textcomp Info: Setting pplj sub-encoding to TS1/3 on input line 407. +Package textcomp Info: Setting ptmx sub-encoding to TS1/4 on input line 408. +Package textcomp Info: Setting ptmj sub-encoding to TS1/4 on input line 409. +) (/usr/share/texlive/texmf-dist/tex/latex/psnfss/pifont.sty +Package: pifont 2005/04/12 PSNFSS-v9.2a Pi font support (SPQR) +LaTeX Font Info: Try loading font information for U+pzd on input line 63. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upzd.fd +File: upzd.fd 2001/06/04 font definitions for U/pzd. +) +LaTeX Font Info: Try loading font information for U+psy on input line 64. +(/usr/share/texlive/texmf-dist/tex/latex/psnfss/upsy.fd +File: upsy.fd 2001/06/04 font definitions for U/psy. +)) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2012/11/06 v6.83m Hypertext links for LaTeX +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO) +Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO) +Package hobsub Info: Skipping package `infwarerr' (already loaded). +Package hobsub Info: Skipping package `ltxcmds' (already loaded). +Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO) +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is not detected. +Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) +Package etexcmds Info: Could not find \expanded. +(etexcmds) That can mean that you are not using pdfTeX 1.50 or +(etexcmds) that some package has redefined \expanded. +(etexcmds) In the latter case, load this package earlier. +Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) +Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO) +Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: pdfTeX >= 1.30 not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode not found. +Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO) +Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO) +Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO) +Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO) +Package: xcolor-patch 2011/01/30 xcolor patch +Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO) +Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO) +Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO) +Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2011/03/04 v1.3 Hooks for auxiliary files (HO) +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) +) +\@linkdim=\dimen120 +\Hy@linkcounter=\count110 +\Hy@pagecounter=\count111 +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count112 +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Hyper figures OFF on input line 4443. +Package hyperref Info: Link nesting OFF on input line 4448. +Package hyperref Info: Hyper index ON on input line 4451. +Package hyperref Info: Plain pages OFF on input line 4458. +Package hyperref Info: Backreferencing OFF on input line 4463. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4688. +\c@Hy@tempcnt=\count113 +(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip11 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 5041. +\XeTeXLinkMargin=\dimen121 +\Fld@menulength=\count114 +\Field@Width=\dimen122 +\Fld@charsize=\dimen123 +Package hyperref Info: Hyper figures OFF on input line 6295. +Package hyperref Info: Link nesting OFF on input line 6300. +Package hyperref Info: Hyper index ON on input line 6303. +Package hyperref Info: backreferencing OFF on input line 6310. +Package hyperref Info: Link coloring OFF on input line 6315. +Package hyperref Info: Link coloring with OCG OFF on input line 6320. +Package hyperref Info: PDF/A mode OFF on input line 6325. +LaTeX Info: Redefining \ref on input line 6365. +LaTeX Info: Redefining \pageref on input line 6369. +\Hy@abspage=\count115 +\c@Item=\count116 +\c@Hfootnote=\count117 +) + +Package hyperref Message: Driver (autodetected): hxetex. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hxetex.def +File: hxetex.def 2012/11/06 v6.83m Hyperref driver for XeTeX +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def +File: puenc.def 2012/11/06 v6.83m Hyperref: PDF Unicode definition (HO) +) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/stringenc.sty +Package: stringenc 2011/12/02 v1.10 Convert strings between diff. encodings (HO) +) +\pdfm@box=\box32 +\c@Hy@AnnotLevel=\count118 +\HyField@AnnotCount=\count119 +\Fld@listcount=\count120 +\c@bookmark@seq@number=\count121 +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO) +Package rerunfilecheck Info: Feature \pdfmdfivesum is not available +(rerunfilecheck) (e.g. pdfTeX or LuaTeX with package `pdftexcmds'). +(rerunfilecheck) Therefore file contents cannot be checked efficiently +(rerunfilecheck) and the loading of the package is aborted. +) +\Hy@SectionHShift=\skip140 +) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bookmark.sty +Package: bookmark 2011/12/02 v1.24 PDF bookmarks (HO) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/bkm-dvipdfm.def +File: bkm-dvipdfm.def 2011/12/02 v1.24 bookmark driver for dvipdfm (HO) +\BKM@id=\count122 +)) (/usr/share/texlive/texmf-dist/tex/latex/booktabs/booktabs.sty +Package: booktabs 2005/04/14 v1.61803 publication quality tables +\heavyrulewidth=\dimen124 +\lightrulewidth=\dimen125 +\cmidrulewidth=\dimen126 +\belowrulesep=\dimen127 +\belowbottomsep=\dimen128 +\aboverulesep=\dimen129 +\abovetopsep=\dimen130 +\cmidrulesep=\dimen131 +\cmidrulekern=\dimen132 +\defaultaddspace=\dimen133 +\@cmidla=\count123 +\@cmidlb=\count124 +\@aboverulesep=\dimen134 +\@belowrulesep=\dimen135 +\@thisruleclass=\count125 +\@lastruleclass=\count126 +\@thisrulewidth=\dimen136 +) (/usr/share/texlive/texmf-dist/tex/latex/tools/longtable.sty +Package: longtable 2014/10/28 v4.11 Multi-page Table package (DPC) +\LTleft=\skip141 +\LTright=\skip142 +\LTpre=\skip143 +\LTpost=\skip144 +\LTchunksize=\count127 +\LTcapwidth=\dimen137 +\LT@head=\box33 +\LT@firsthead=\box34 +\LT@foot=\box35 +\LT@lastfoot=\box36 +\LT@cols=\count128 +\LT@rows=\count129 +\c@LT@tables=\count130 +\c@LT@chunks=\count131 +\LT@p@ftn=\toks23 +) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Invalid UTF-8 byte or sequence at line 3 replaced by U+FFFD. +Package: anyfontsize 2007/11/22 anyfontsize.sty by pts +) (/usr/share/texlive/texmf-dist/tex/latex/enumitem/enumitem.sty +Package: enumitem 2011/09/28 v3.5.2 Customized lists +\labelindent=\skip145 +\enit@outerparindent=\dimen138 +\enit@toks=\toks24 +\enit@inbox=\box37 +\enitdp@description=\count132 +) (/usr/share/texlive/texmf-dist/tex/latex/wrapfig/wrapfig.sty +\wrapoverhang=\dimen139 +\WF@size=\dimen140 +\c@WF@wrappedlines=\count133 +\WF@box=\box38 +\WF@everypar=\toks25 +Package: wrapfig 2003/01/31 v 3.6 +) (/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.sty (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty +Package: expl3 2016/01/19 v6377 L3 programming layer (loader) +(/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3-code.tex +Package: expl3 2016/01/19 v6377 L3 programming layer (code) +L3 Module: l3bootstrap 2016/01/01 v6339 L3 Bootstrap code +L3 Module: l3names 2015/12/21 v6328 L3 Namespace for primitives +L3 Module: l3basics 2015/11/22 v6315 L3 Basic definitions +L3 Module: l3expan 2015/09/10 v5983 L3 Argument expansion +L3 Module: l3tl 2015/09/29 v6121 L3 Token lists +L3 Module: l3str 2016/01/03 v6357 L3 Strings +L3 Module: l3seq 2015/08/05 v5777 L3 Sequences and stacks +L3 Module: l3int 2016/01/05 v6366 L3 Integers +\c_max_int=\count134 +\l_tmpa_int=\count135 +\l_tmpb_int=\count136 +\g_tmpa_int=\count137 +\g_tmpb_int=\count138 +L3 Module: l3quark 2015/08/17 v5855 L3 Quarks +L3 Module: l3prg 2015/11/01 v6216 L3 Control structures +\g__prg_map_int=\count139 +L3 Module: l3clist 2015/09/02 v5901 L3 Comma separated lists +L3 Module: l3token 2015/11/11 v6249 L3 Experimental token manipulation +L3 Module: l3prop 2016/01/05 v6366 L3 Property lists +L3 Module: l3msg 2015/09/28 v6113 L3 Messages +L3 Module: l3file 2015/12/03 v6317 L3 File and I/O operations +\l_iow_line_count_int=\count140 +\l__iow_target_count_int=\count141 +\l__iow_current_line_int=\count142 +\l__iow_current_word_int=\count143 +\l__iow_current_indentation_int=\count144 +L3 Module: l3skip 2016/01/05 v6366 L3 Dimensions and skips +\c_zero_dim=\dimen141 +\c_max_dim=\dimen142 +\l_tmpa_dim=\dimen143 +\l_tmpb_dim=\dimen144 +\g_tmpa_dim=\dimen145 +\g_tmpb_dim=\dimen146 +\c_zero_skip=\skip146 +\c_max_skip=\skip147 +\l_tmpa_skip=\skip148 +\l_tmpb_skip=\skip149 +\g_tmpa_skip=\skip150 +\g_tmpb_skip=\skip151 +\c_zero_muskip=\muskip12 +\c_max_muskip=\muskip13 +\l_tmpa_muskip=\muskip14 +\l_tmpb_muskip=\muskip15 +\g_tmpa_muskip=\muskip16 +\g_tmpb_muskip=\muskip17 +L3 Module: l3keys 2015/11/17 v6284 L3 Key-value interfaces +\g__keyval_level_int=\count145 +\l_keys_choice_int=\count146 +L3 Module: l3fp 2015/08/25 v5890 L3 Floating points +\c__fp_leading_shift_int=\count147 +\c__fp_middle_shift_int=\count148 +\c__fp_trailing_shift_int=\count149 +\c__fp_big_leading_shift_int=\count150 +\c__fp_big_middle_shift_int=\count151 +\c__fp_big_trailing_shift_int=\count152 +\c__fp_Bigg_leading_shift_int=\count153 +\c__fp_Bigg_middle_shift_int=\count154 +\c__fp_Bigg_trailing_shift_int=\count155 +L3 Module: l3box 2015/08/09 v5822 L3 Experimental boxes +\c_empty_box=\box39 +\l_tmpa_box=\box40 +\l_tmpb_box=\box41 +\g_tmpa_box=\box42 +\g_tmpb_box=\box43 +L3 Module: l3coffins 2015/08/06 v5789 L3 Coffin code layer +\l__coffin_internal_box=\box44 +\l__coffin_internal_dim=\dimen147 +\l__coffin_offset_x_dim=\dimen148 +\l__coffin_offset_y_dim=\dimen149 +\l__coffin_x_dim=\dimen150 +\l__coffin_y_dim=\dimen151 +\l__coffin_x_prime_dim=\dimen152 +\l__coffin_y_prime_dim=\dimen153 +\c_empty_coffin=\box45 +\l__coffin_aligned_coffin=\box46 +\l__coffin_aligned_internal_coffin=\box47 +\l_tmpa_coffin=\box48 +\l_tmpb_coffin=\box49 +\l__coffin_display_coffin=\box50 +\l__coffin_display_coord_coffin=\box51 +\l__coffin_display_pole_coffin=\box52 +\l__coffin_display_offset_dim=\dimen154 +\l__coffin_display_x_dim=\dimen155 +\l__coffin_display_y_dim=\dimen156 +L3 Module: l3color 2014/08/23 v5354 L3 Experimental color support +L3 Module: l3sys 2015/09/25 v6087 L3 Experimental system/runtime functions +L3 Module: l3candidates 2016/01/14 v6376 L3 Experimental additions to l3kernel +\l__box_top_dim=\dimen157 +\l__box_bottom_dim=\dimen158 +\l__box_left_dim=\dimen159 +\l__box_right_dim=\dimen160 +\l__box_top_new_dim=\dimen161 +\l__box_bottom_new_dim=\dimen162 +\l__box_left_new_dim=\dimen163 +\l__box_right_new_dim=\dimen164 +\l__box_internal_box=\box53 +\l__coffin_bounding_shift_dim=\dimen165 +\l__coffin_left_corner_dim=\dimen166 +\l__coffin_right_corner_dim=\dimen167 +\l__coffin_bottom_corner_dim=\dimen168 +\l__coffin_top_corner_dim=\dimen169 +\l__coffin_scaled_total_height_dim=\dimen170 +\l__coffin_scaled_width_dim=\dimen171 +L3 Module: l3luatex 2015/11/11 v6250 L3 Experimental LuaTeX-specific functions +) (/usr/share/texlive/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def +File: l3xdvidpfmx.def 2015/11/11 v6250 L3 Experimental driver: xdvipdfmx +)) (/usr/share/texlive/texmf-dist/tex/latex/l3packages/xparse/xparse.sty +Package: xparse 2016/01/19 v6377 L3 Experimental document command parser +\l__xparse_current_arg_int=\count156 +\l__xparse_m_args_int=\count157 +\l__xparse_mandatory_args_int=\count158 +\l__xparse_processor_int=\count159 +\l__xparse_v_nesting_int=\count160 +) +Package: fontspec 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec-xetex.sty +Package: fontspec-xetex 2016/02/01 v2.5a Font selection for XeLaTeX and LuaLaTeX +\l_fontspec_script_int=\count161 +\l_fontspec_language_int=\count162 +\l_fontspec_strnum_int=\count163 +\l__fontspec_tmpa_dim=\dimen172 +\l__fontspec_tmpb_dim=\dimen173 +\l__fontspec_tmpc_dim=\dimen174 +\g__file_internal_ior=\read1 +(/usr/share/texlive/texmf-dist/tex/latex/base/fontenc.sty +Package: fontenc 2005/09/27 v1.99g Standard LaTeX package +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1enc.def +File: eu1enc.def 2010/05/27 v0.1h Experimental Unicode font encodings +) +LaTeX Font Info: Try loading font information for EU1+lmr on input line 105. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmr.fd +File: eu1lmr.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) (/usr/share/texlive/texmf-dist/tex/xelatex/xunicode/xunicode.sty +File: xunicode.sty 2011/09/09 v0.981 provides access to latin accents and many other characters in Unicode lower plane +(/usr/share/texmf/tex/latex/tipa/t3enc.def +File: t3enc.def 2001/12/31 T3 encoding +LaTeX Font Info: Try loading font information for EU1+lmss on input line 357. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmss.fd +File: eu1lmss.fd 2009/10/30 v1.6 Font defs for Latin Modern +)) +\tipaTiiicode=\count164 +\tipasavetokens=\toks26 +\tipachecktokens=\toks27 +) +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \__fontspec_post_arg:w with sig. 'mmO{}' on line 353. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \fontspec with sig. 'om' on line 355. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmainfont with sig. 'om' on line 365. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setsansfont with sig. 'om' on line 375. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmonofont with sig. 'om' on line 385. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathrm with sig. 'om' on line 399. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setboldmathrm with sig. 'om' on line 407. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathsf with sig. 'om' on line 415. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \setmathtt with sig. 'om' on line 423. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfamily with sig. 'mom' on line 437. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontface with sig. 'mom' on line 453. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \defaultfontfeatures with sig. 't+om' on line 467. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \addfontfeatures with sig. 'm' on line 529. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontfeature with sig. 'mm' on line 540. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newAATfeature with sig. 'mmmm' on line 548. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newopentypefeature with sig. 'mmm' on line 556. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeature with sig. 'mm' on line 577. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \aliasfontfeatureoption with sig. 'mmm' on line 586. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontscript with sig. 'mm' on line 590. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \newfontlanguage with sig. 'mm' on line 594. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \DeclareFontsExtensions with sig. 'm' on line 599. +................................................. +\l__fontspec_tmp_int=\count165 +(/usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.cfg) +LaTeX Info: Redefining \itshape on input line 2705. +LaTeX Info: Redefining \slshape on input line 2710. +LaTeX Info: Redefining \scshape on input line 2715. +LaTeX Info: Redefining \upshape on input line 2720. +\l__fontspec_em_int=\count166 +\l__fontspec_emdef_int=\count167 +LaTeX Info: Redefining \em on input line 2736. +LaTeX Info: Redefining \emph on input line 2742. +LaTeX Info: Redefining \- on input line 2746. +................................................. +. LaTeX info: "xparse/redefine-command" +. +. Redefining command \oldstylenums with sig. 'm' on line 2841. +................................................. +................................................. +. LaTeX info: "xparse/define-command" +. +. Defining command \liningnums with sig. 'm' on line 2845. +................................................. +)) +Package hyperref Info: Option `colorlinks' set `true' on input line 87. +\px=\skip152 +\c@md@targetcount=\count168 +\mdcompactskip=\skip153 +\mdcompacttopsep=\skip154 +\dim@rem=\skip155 +\dim@ch=\skip156 +\md@height=\skip157 +\dim@marginbottom=\skip158 +\dim@paddingbottom=\skip159 +\md@interaction=\count169 +\mddefinitionsskip=\skip160 +\md@captionlen=\skip161 +\mdtoclevel=\count170 +\c@mdtoclevelbold=\count171 +\c@mdtocleveldots=\count172 +\mdtocskip=\skip162 +\mdpreskip=\skip163 +\presp=\skip164 +LaTeX Font Info: Try loading font information for EU1+lmtt on input line 801. +(/usr/share/texlive/texmf-dist/tex/latex/euenc/eu1lmtt.fd +File: eu1lmtt.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +\md@postskip=\skip165 +\ppresp=\skip166 +\md@thmcaption=\box54 +\md@defaultcolwidth=\skip167 +\mdtabularskip=\skip168 +\mdbibindentunit=\skip169 +\c@md@authorcount=\count173 +\c@mdx@authorcount=\count174 +\c@@mdTargetCount=\count175 +\@snippetBox=\box55 +\@snippetWidth=\skip170 +\@snippetHeight=\skip171 +\@snippetDepth=\skip172 +\c@snippets=\count176 +) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty +Package: geometry 2010/09/12 v5.6 Page Geometry +\Gm@cnth=\count177 +\Gm@cntv=\count178 +\c@Gm@tempcnt=\count179 +\Gm@bindingoffset=\dimen175 +\Gm@wd@mp=\dimen176 +\Gm@odd@mp=\dimen177 +\Gm@even@mp=\dimen178 +\Gm@layoutwidth=\dimen179 +\Gm@layoutheight=\dimen180 +\Gm@layouthoffset=\dimen181 +\Gm@layoutvoffset=\dimen182 +\Gm@dimlist=\toks28 +) (/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +\fancy@headwidth=\skip173 +\f@ncyO@elh=\skip174 +\f@ncyO@erh=\skip175 +\f@ncyO@olh=\skip176 +\f@ncyO@orh=\skip177 +\f@ncyO@elf=\skip178 +\f@ncyO@erf=\skip179 +\f@ncyO@olf=\skip180 +\f@ncyO@orf=\skip181 +) (build/P4Runtime-Spec.aux + +LaTeX Warning: Label `sec-directcounterentry' multiply defined. + + +LaTeX Warning: Label `sec-counterentry' multiply defined. + + +LaTeX Warning: Label `sec-directmeterentry' multiply defined. + + +LaTeX Warning: Label `sec-meterentry' multiply defined. + + +LaTeX Warning: Label `sec-packetreplicationengineentry' multiply defined. + + +LaTeX Warning: Label `sec-valuesetentry' multiply defined. + + +LaTeX Warning: Label `sec-registerentry' multiply defined. + + +LaTeX Warning: Label `sec-digestentry' multiply defined. + + +LaTeX Warning: Label `sec-example' multiply defined. + +) +\openout1 = `P4Runtime-Spec.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for TS1+cmr on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/base/ts1cmr.fd +File: ts1cmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions +) +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for EU1/lmr/m/n on input line 14. +LaTeX Font Info: ... okay on input line 14. +LaTeX Font Info: Checking defaults for T3/cmr/m/n on input line 14. +LaTeX Font Info: Try loading font information for T3+cmr on input line 14. +(/usr/share/texmf/tex/latex/tipa/t3cmr.fd +File: t3cmr.fd 2001/12/31 TIPA font definitions +) +LaTeX Font Info: ... okay on input line 14. +\AtBeginShipoutBox=\box56 +Package hyperref Info: Link coloring ON on input line 14. +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2012/10/27 v2.43 Cross-referencing by name of section +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO) +) +\c@section@level=\count180 +) +LaTeX Info: Redefining \ref on input line 14. +LaTeX Info: Redefining \pageref on input line 14. +LaTeX Info: Redefining \nameref on input line 14. +................................................. +. fontspec info: "setup-math" +. +. Adjusting the maths setup (use [no-math] to avoid this). +................................................. +\symlegacymaths=\mathgroup7 +LaTeX Font Info: Overwriting symbol font `legacymaths' in version `bold' +(Font) OT1/cmr/m/n --> OT1/cmr/bx/n on input line 14. +LaTeX Font Info: Redeclaring math accent \acute on input line 14. +LaTeX Font Info: Redeclaring math accent \grave on input line 14. +LaTeX Font Info: Redeclaring math accent \ddot on input line 14. +LaTeX Font Info: Redeclaring math accent \tilde on input line 14. +LaTeX Font Info: Redeclaring math accent \bar on input line 14. +LaTeX Font Info: Redeclaring math accent \breve on input line 14. +LaTeX Font Info: Redeclaring math accent \check on input line 14. +LaTeX Font Info: Redeclaring math accent \hat on input line 14. +LaTeX Font Info: Redeclaring math accent \dot on input line 14. +LaTeX Font Info: Redeclaring math accent \mathring on input line 14. +LaTeX Font Info: Redeclaring math symbol \Gamma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Delta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Theta on input line 14. +LaTeX Font Info: Redeclaring math symbol \Lambda on input line 14. +LaTeX Font Info: Redeclaring math symbol \Xi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Pi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Sigma on input line 14. +LaTeX Font Info: Redeclaring math symbol \Upsilon on input line 14. +LaTeX Font Info: Redeclaring math symbol \Phi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Psi on input line 14. +LaTeX Font Info: Redeclaring math symbol \Omega on input line 14. +LaTeX Font Info: Redeclaring math symbol \mathdollar on input line 14. +LaTeX Font Info: Redeclaring symbol font `operators' on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `normal' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/cmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Encoding `OT1' has changed to `EU1' for symbol font +(Font) `operators' in the math version `bold' on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/cmr/bx/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) EU1/lmr/m/n --> EU1/lmr/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/cmr/m/it --> EU1/lmr/m/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/cmr/bx/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/cmss/m/n --> EU1/lmss/m/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/cmtt/m/n --> EU1/lmtt/m/n on input line 14. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) EU1/lmr/m/n --> EU1/lmr/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' +(Font) OT1/cmr/bx/it --> EU1/lmr/bx/it on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/cmss/bx/n --> EU1/lmss/bx/n on input line 14. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/cmtt/m/n --> EU1/lmtt/bx/n on input line 14. +*geometry* driver: auto-detecting +*geometry* detected driver: xetex +*geometry* verbose mode - [ preamble ] result: +* driver: xetex +* paper: +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: +* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt) +* v-part:(T,H,B)=(72.26999pt, 632.3625pt, 90.3375pt) +* \paperwidth=614.295pt +* \paperheight=794.96999pt +* \textwidth=469.75502pt +* \textheight=632.3625pt +* \oddsidemargin=0.0pt +* \evensidemargin=0.0pt +* \topmargin=-37.0pt +* \headheight=30.0pt +* \headsep=25.0pt +* \topskip=11.0pt +* \footskip=30.0pt +* \marginparwidth=59.0pt +* \marginparsep=10.0pt +* \columnsep=10.0pt +* \skip\footins=10.0pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +resolve font stack: UtopiaStd-Regular + +\g__fontspec_family_UtopiaStd-Regular_int=\count181 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font UtopiaStd-Regular/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'UtopiaStd-Regular(0)' created for font 'UtopiaStd-Regular' with +. options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;" +. - 'small caps' (m/sc) with NFSS spec.: +. <->"UtopiaStd-Regular/OT:script=latn;language=DFLT;+smcp;" +................................................. + +resolved font stack 'UtopiaStd-Regular' to: UtopiaStd-Regular +LaTeX Font Info: Try loading font information for U+msa on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Try loading font information for U+msb on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Try loading font information for U+stmry on input line 33. +(/usr/share/texlive/texmf-dist/tex/latex/stmaryrd/Ustmry.fd) + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/bx/n' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 35. + +resolve font stack: LuxiMono + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +\g__fontspec_family_LuxiMono_int=\count182 +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/BI (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/B (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "no-font-shape" +. +. Could not resolve font LuxiMono/I (it probably doesn't exist). +................................................. +................................................. +. fontspec info: "defining-font" +. +. Font family 'LuxiMono(0)' created for font 'LuxiMono' with options []. +. +. This font family consists of the following NFSS series/shapes: +. - 'normal' (m/n) with NFSS spec.: <->"LuxiMono/OT:" +. - 'small caps' (m/sc) with NFSS spec.: +................................................. + +resolved font stack 'LuxiMono' to: LuxiMono +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/se-ascii-print.def +File: se-ascii-print.def 2011/12/02 v1.10 stringenc: Printable ASCII characters +) [1 + +] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[2] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <10.95> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 323. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Font Warning: Font shape `EU1/LuxiMono(0)/bx/n' undefined +(Font) using `EU1/LuxiMono(0)/m/n' instead on input line 323. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[3] [4] + +LaTeX Font Warning: Font shape `EU1/UtopiaStd-Regular(0)/m/it' undefined +(Font) using `EU1/UtopiaStd-Regular(0)/m/n' instead on input line 543. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[5] [6] [7] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/reference-architecture.png Graphic file (type QTm) + [8] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[9] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[10] +File: build/single-embedded-controller.png Graphic file (type QTm) + +File: build/single-remote-controller.png Graphic file (type QTm) + [11] [12] +File: build/embedded-plus-single-remote-controller.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-controllers.png Graphic file (type QTm) + +File: build/embedded-plus-two-remote-ha-controllers.png Graphic file (type QTm) + [13] [14] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[15] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[16] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <12> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 1602. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1602. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1602. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[17] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[18] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (65.03293pt too wide) in paragraph at lines 1870--1873 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For all backup controllers, \EU1/LuxiMono(0)/bx/n/8.2125 status \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set to non-OK (with \EU1/LuxiMono(0)/bx/n/8.2125 status.code \EU1/UtopiaStd-Regular(0)/m/it/10.95 set to \EU1/LuxiMono(0)/bx/n/8.2125 google.rpc.ALREADY_EXISTS\EU1/UtopiaStd-Regular(0)/m/it/10.95 ). + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1907. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1907. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[19] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1931. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1931. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[20] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 1976. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 1976. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[21] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[22] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[23] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2259. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2259. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[24] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1057) in paragraph at lines 2309--2313 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For structured annotations, every \EU1/LuxiMono(0)/bx/n/8.2125 StructuredAnnotation \EU1/UtopiaStd-Regular(0)/m/it/10.95 message contains an optional field + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2316. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2316. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[25] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1442) in paragraph at lines 2449--2459 +\EU1/LuxiMono(0)/bx/n/8.2125 Property\EU1/UtopiaStd-Regular(0)/m/it/10.95 , for example, \EU1/LuxiMono(0)/bx/n/8.2125 multicast_group_table_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 or \EU1/LuxiMono(0)/bx/n/8.2125 multicast_group_table_total_replicas\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +[26] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +LaTeX Warning: `!h' float specifier changed to `!ht'. + + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (12.45624pt too wide) in paragraph at lines 2595--2608 + [] + [] + + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[27] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2631. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2631. + +[28] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[29] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2839. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2839. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[30] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 2899. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 2899. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[31] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1546) in paragraph at lines 2998--3006 + \EU1/UtopiaStd-Regular(0)/m/it/10.95 PSA programs can use the \EU1/LuxiMono(0)/bx/n/8.2125 @selector_size_semantics \EU1/UtopiaStd-Regular(0)/m/it/10.95 annotation with one of \EU1/LuxiMono(0)/bx/n/8.2125 sum_of_weights \EU1/UtopiaStd-Regular(0)/m/it/10.95 or + [] + + +Overfull \hbox (13.9818pt too wide) in paragraph at lines 2998--3006 +\EU1/LuxiMono(0)/bx/n/8.2125 sum_of_members \EU1/UtopiaStd-Regular(0)/m/it/10.95 to specify this value for Action Selectors. In the \EU1/LuxiMono(0)/bx/n/8.2125 sum_of_members \EU1/UtopiaStd-Regular(0)/m/it/10.95 case, the \EU1/LuxiMono(0)/bx/n/8.2125 @max_member_weight + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3008. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3008. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[32] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3089. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3089. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.59204pt too wide) in paragraph at lines 3143--3145 +[]\EU1/LuxiMono(0)/bx/n/8.2125 BYTES\EU1/UtopiaStd-Regular(0)/m/it/10.95 , which signifies that this meter can be configured with rates expressed in bytes/second. + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (32.19182pt too wide) in paragraph at lines 3186--3193 +[]\EU1/LuxiMono(0)/bx/n/8.2125 SINGLE_RATE_TWO_COLOR\EU1/UtopiaStd-Regular(0)/m/it/10.95 : This is a simplified version of RFC 2697 [[][]2[][]], and the \EU1/LuxiMono(0)/bx/n/8.2125 SINGLE_RATE_THREE_COLOR + [] + +[33] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3212. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (18.74199pt too wide) in paragraph at lines 3229--3236 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 carrying P4 standard annotations \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_in") \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 @controller_header("packet_out")\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[34] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[35] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3371. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3371. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[36] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[37] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3599. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3599. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[38] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3646. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3646. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 3684. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 3684. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[39] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[40] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[41] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[42] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[43] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[44] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[45] [46] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1629) in paragraph at lines 4449--4451 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 For example, the following P4$[]$ objects involve complex types that need to be exposed in + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[47] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1454) in paragraph at lines 4497--4506 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 ification for all the named types in the P4$[]$ program. These named types are \EU1/LuxiMono(0)/bx/n/8.2125 struct\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 header\EU1/UtopiaStd-Regular(0)/m/it/10.95 , + [] + + +Underfull \hbox (badness 1831) in paragraph at lines 4497--4506 +\EU1/LuxiMono(0)/bx/n/8.2125 header_union\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 enum \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 serializable_enum\EU1/UtopiaStd-Regular(0)/m/it/10.95 ; for each of these we have a type specification mes- + [] + + +Underfull \hbox (badness 1845) in paragraph at lines 4497--4506 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 sage, respectively \EU1/LuxiMono(0)/bx/n/8.2125 P4StructTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnionTypeSpec\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 P4EnumTypeSpec \EU1/UtopiaStd-Regular(0)/m/it/10.95 and + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (33.06564pt too wide) in paragraph at lines 4532--4539 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 “binary string” types (\EU1/LuxiMono(0)/bx/n/8.2125 bit\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 int\EU1/UtopiaStd-Regular(0)/m/it/10.95 , and \EU1/LuxiMono(0)/bx/n/8.2125 varbit\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) are grouped together in the \EU1/LuxiMono(0)/bx/n/8.2125 P4BitstringLikeTypeSpec + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4549. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4549. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[48] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.46094pt too wide) in paragraph at lines 4586--4589 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 An invalid header union (i.e. all headers in the union are invalid) is represented by a \EU1/LuxiMono(0)/bx/n/8.2125 P4HeaderUnion + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[49] [50] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 4723. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 4723. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[51] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (24.68944pt too wide) in paragraph at lines 4811--4817 +[]\EU1/LuxiMono(0)/bx/n/8.2125 translated_type\EU1/UtopiaStd-Regular(0)/m/it/10.95 , if and only if the P4 \EU1/LuxiMono(0)/bx/n/8.2125 type \EU1/UtopiaStd-Regular(0)/m/it/10.95 declaration was annotated with \EU1/LuxiMono(0)/bx/n/8.2125 @p4runtime_translation\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[52] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[53] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (32.59732pt too wide) in paragraph at lines 4919--4925 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 in \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.MatchField\EU1/UtopiaStd-Regular(0)/m/it/10.95 , \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.Action.Param \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 p4.config.v1.ControllerPacketMetadata.Metadata\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[54] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 5026. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 5026. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[55] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[56] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[57] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[58] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.53593pt too wide) in paragraph at lines 5500--5503 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 If the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 does not match the table description in the P4Info (e.g. the \EU1/LuxiMono(0)/bx/n/8.2125 oneof \EU1/UtopiaStd-Regular(0)/m/it/10.95 is \EU1/LuxiMono(0)/bx/n/8.2125 action_profile_member_id + [] + +[59] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[60] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (54.86232pt too wide) in paragraph at lines 5673--5677 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 Unlike a table with \EU1/LuxiMono(0)/bx/n/8.2125 is_const_table = true\EU1/UtopiaStd-Regular(0)/m/it/10.95 , a client may insert entries into a table with \EU1/LuxiMono(0)/bx/n/8.2125 has_initial_entries = true + [] + +[61] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[62] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[63] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[64] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[65] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[66] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6225. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6225. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[67] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[68] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (21.53802pt too wide) in paragraph at lines 6448--6454 +[]\EU1/LuxiMono(0)/bx/n/8.2125 max_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 is the maximum sum of all members or member weights (as per the \EU1/LuxiMono(0)/bx/n/8.2125 selector_size_semantics\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[69] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (9.29865pt too wide) in paragraph at lines 6512--6514 + []\EU1/lmr/bx/n/10.95 9.2.2.1.| Rules on Setting \EU1/LuxiMono(0)/bx/n/8.2125 max_size[] \EU1/UtopiaStd-Regular(0)/m/it/10.95 The valid values for \EU1/LuxiMono(0)/bx/n/8.2125 max_size \EU1/UtopiaStd-Regular(0)/m/it/10.95 depend on the static \EU1/LuxiMono(0)/bx/n/8.2125 max_group_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[70] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[71] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[72] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[73] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6809. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6809. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6849. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6849. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1331) in paragraph at lines 6852--6859 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 A direct counter is a direct resource associated with a \EU1/LuxiMono(0)/bx/n/8.2125 TableEntry \EU1/UtopiaStd-Regular(0)/m/it/10.95 (see [][]Direct Resources[][]). The + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[74] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 6926. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 6926. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[75] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7020. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7020. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[76] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7103. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7103. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7193. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7193. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[77] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7298. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7298. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[78] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7326. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7326. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7336. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7336. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[79] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7464. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7464. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[80] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[81] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (1.93839pt too wide) in paragraph at lines 7576--7578 +[]\EU1/LuxiMono(0)/bx/n/8.2125 MODIFY\EU1/UtopiaStd-Regular(0)/m/it/10.95 : Modify the attributes of a given clone session entry, indexed by the given \EU1/LuxiMono(0)/bx/n/8.2125 clone_session_id\EU1/UtopiaStd-Regular(0)/m/it/10.95 . + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7614. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7614. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[82] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[83] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7750. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7750. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7794. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7794. + +[84] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[85] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[86] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 7992. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 7992. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[87] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/error-report.png Graphic file (type QTm) + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +LaTeX Font Info: Font shape `EU1/lmtt/bx/n' in size <14.4> not available +(Font) Font shape `EU1/lmtt/b/n' tried instead on input line 8116. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8116. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8116. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[88] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[89] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8218. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8218. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[90] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[91] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[92] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (34.34796pt too wide) in paragraph at lines 8502--8507 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If an error is encountered before even trying to attempt individual batch updates, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.66206pt too wide) in paragraph at lines 8511--8522 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 Otherwise, if one or more updates in the batch (\EU1/LuxiMono(0)/bx/n/8.2125 WriteRequest.updates\EU1/UtopiaStd-Regular(0)/m/it/10.95 ) failed, set \EU1/LuxiMono(0)/bx/n/8.2125 grpc::Status::code_ + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[93] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8558. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8558. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[94] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[95] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (2.4752pt too wide) in paragraph at lines 8793--8797 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 responding to \EU1/LuxiMono(0)/bx/n/8.2125 a \EU1/UtopiaStd-Regular(0)/m/it/10.95 and \EU1/LuxiMono(0)/bx/n/8.2125 c\EU1/UtopiaStd-Regular(0)/m/it/10.95 , followed by a status \EU1/LuxiMono(0)/bx/n/8.2125 {p4.Error(OK), p4.Error(xxx), p4.Error(yyy), p4.Error(OK)} + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[96] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 8879. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 8879. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[97] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 9002. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 9002. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[98] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 9100--9103 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If a P4Runtime server supports both \EU1/LuxiMono(0)/bx/n/8.2125 SetForwardingPipelineConfig \EU1/UtopiaStd-Regular(0)/m/it/10.95 as well as returning the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[99] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (57.64021pt too wide) in paragraph at lines 9185--9191 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If \EU1/LuxiMono(0)/bx/n/8.2125 ControllerPacketMetadata.Metadata.bitwidth \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set, or if \EU1/LuxiMono(0)/bx/n/8.2125 ControllerPacketMetadata.Metadata.type_name + [] + +[100] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (44.6621pt too wide) in paragraph at lines 9193--9205 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 If \EU1/LuxiMono(0)/bx/n/8.2125 ControllerPacketMetadata.Metadata.type_name \EU1/UtopiaStd-Regular(0)/m/it/10.95 is set and \EU1/LuxiMono(0)/bx/n/8.2125 P4NewTypeSpec.translated_type.sdn_string + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[101] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[102] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[103] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 9500. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 9500. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[104] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hyphenchar' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\font' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\mdfontfamily' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\hbox' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\presp' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\wd' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\setbox' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\@tempboxa' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\box' on input line 9568. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\voidb@x' on input line 9568. + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[105] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +File: build/psa-metadata-translation.png Graphic file (type QTm) + [106] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[107] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[108] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[109] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[110] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[111] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 3460) in paragraph at lines 10079--10086 +[]\EU1/UtopiaStd-Regular(0)/m/it/10.95 p4info-ext should include a Protobuf message definition for every extern type that can + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 10130. + + +Package longbox Warning: Cannot split box; it seems you are using a non-splittable contents on input line 10130. + +[112] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 4036) in paragraph at lines 10134--10141 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 P4Runtime also supports streaming arbitrary Protobuf messages between the server and the + [] + + +Underfull \hbox (badness 1629) in paragraph at lines 10134--10141 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 client, by including an \EU1/LuxiMono(0)/bx/n/8.2125 Any \EU1/UtopiaStd-Regular(0)/m/it/10.95 Protobuf field [[][]37[][]] named \EU1/LuxiMono(0)/bx/n/8.2125 other \EU1/UtopiaStd-Regular(0)/m/it/10.95 in both \EU1/LuxiMono(0)/bx/n/8.2125 p4.v1.StreamMessageRequest + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[113] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[114] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[115] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Underfull \hbox (badness 1997) in paragraph at lines 10467--10469 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 Table [][]7[][] lists P4$[]$ annotations introduced primarily for the purpose of adding features for the + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[116] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[117] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. + +Overfull \hbox (15.61781pt too wide) in paragraph at lines 10620--10627 +\EU1/UtopiaStd-Regular(0)/m/it/10.95 In gRPC, the status of a RPC request is sent as metadata, whose size is limited by the \EU1/LuxiMono(0)/bx/n/8.2125 grpc.max_metadata_size + [] + +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[118] +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +................................................. +. fontspec info: "no-scripts" +. +. Font LuxiMono does not contain any OpenType `Script' information. +................................................. +[119] +Underfull \hbox (badness 10000) in paragraph at lines 10770--10771 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Complex Types in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- p4- + [] + + +Underfull \hbox (badness 4001) in paragraph at lines 10782--10783 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Google Cloud APIs Versioning - Backwards-Compatibility.” [][]\EU1/lmtt/m/n/10.95 https:// cloud. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10791--10792 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “gRPC Streaming RPCs in C++.” [][]\EU1/lmtt/m/n/10.95 https:// grpc. io/ docs/ tutorials/ basic/ c. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10809--10810 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “P4 Concurrency Model.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10812--10813 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.” + [] + +[120] +Underfull \hbox (badness 10000) in paragraph at lines 10830--10831 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Protobuf OneOf Backwards-Compatibility Issues.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10836--10837 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Action Selector.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# sec- action- + [] + + +Underfull \hbox (badness 2409) in paragraph at lines 10845--10846 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “PSA Empty Group Action Appendix.” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ PSA- v1. 1. 0. html# + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10848--10849 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “Select Expressions in $\OML/cmm/m/it/10.95 P\OT1/cmr/m/n/10.95 4[]$\EU1/UtopiaStd-Regular(0)/m/it/10.95 .” [][]\EU1/lmtt/m/n/10.95 https:// p4. org/ p4- spec/ docs/ P4- 16- v1. 2. 1. html# sec- + [] + + +Underfull \hbox (badness 1668) in paragraph at lines 10866--10867 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Any Protobuf Message.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ protocol- buffers/ docs/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10872--10873 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC C++ Error Details Library.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ grpc/ grpc/ blob/ master/ + [] + +[121] +Underfull \hbox (badness 10000) in paragraph at lines 10875--10876 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The gRPC Canonical Status Codes.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ maps- booking/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10881--10882 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “The Protobuf MessageDifferencer in the C++ API.” [][]\EU1/lmtt/m/n/10.95 https:// developers. google. com/ + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 10887--10888 +[]| []| \EU1/UtopiaStd-Regular(0)/m/it/10.95 “v1model Architecture Definition.” [][]\EU1/lmtt/m/n/10.95 https:// github. com/ p4lang/ p4c/ blob/ master/ + [] + +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 10896. +[122] +Package atveryend Info: Empty hook `AfterLastShipout' on input line 10896. +(build/P4Runtime-Spec.aux) +Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 10896. +Package atveryend Info: Empty hook `AtEndAfterFileList' on input line 10896. + +LaTeX Font Warning: Some font shapes were not available, defaults substituted. + + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 27580 strings out of 493638 + 518353 string characters out of 6146796 + 568918 words of memory out of 5000000 + 30682 multiletter control sequences out of 15000+600000 + 14633 words of font info for 98 fonts, out of 8000000 for 9000 + 1328 hyphenation exceptions out of 8191 + 48i,19n,81p,10429b,768s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on build/P4Runtime-Spec.pdf (122 pages). diff --git a/spec/v1.4.0/P4Runtime-Spec.pdf b/spec/v1.4.0/P4Runtime-Spec.pdf new file mode 100644 index 00000000..c6f7697f Binary files /dev/null and b/spec/v1.4.0/P4Runtime-Spec.pdf differ diff --git a/spec/v1.4.0/P4Runtime-Spec.tex b/spec/v1.4.0/P4Runtime-Spec.tex new file mode 100644 index 00000000..972d69c0 --- /dev/null +++ b/spec/v1.4.0/P4Runtime-Spec.tex @@ -0,0 +1,10896 @@ +\documentclass[11pt]{article} +% generated by Madoko, version 1.1.4 +%mdk-data-line={1} + + +\usepackage[heading-base={2},section-num={False},bib-label={hide},fontspec={True}]{madoko2} +\usepackage[top=1in, bottom=1.25in, left=1in, right=1in]{geometry} +\usepackage{fancyhdr} +%mdk-data-line={11} + + \setlength{\headheight}{30pt} + \setlength{\emergencystretch}{2em} + +\begin{document} + + + +{\mdfontfamily{UtopiaStd-Regular} +%mdk-data-line={203} +\mdxtitleblockstart{} +%mdk-data-line={203} +\mdxtitle{{\sffamily{\bfseries\mdline{203}P4Runtime Specification}}}%mdk + +%mdk-data-line={206} +\mdxtitlenote{{\sffamily{\bfseries\mdline{206}version 1.4.0-dev}}}%mdk +\mdxauthorstart{} +%mdk-data-line={211} +\mdxauthorname{\mdline{211}The P4.org API Working Group}%mdk +\mdxauthorend +%mdk-data-line={220} +\mdxtitlefooter{{\sffamily{\bfseries\mdline{220}2024-09-13}}}%mdk +\mdtitleauthorrunning{}{}\mdxtitleblockend%mdk + +%mdk-data-line={205} +\begin{abstract}%mdk + +%mdk-data-line={206} +\noindent\mdline{206}P4 is a language for programming the data plane of network devices. The +P4Runtime API is a control plane specification for controlling the data plane +elements of a device defined or described by a P4 program. This document +provides a precise definition of the P4Runtime API. The target audience for this +document includes developers who want to write controller applications for P4 +devices or switches.%mdk +%mdk +\end{abstract}%mdk +\mdline{214} +\begin{mdtoc}%mdk + +\section*{Contents}\label{sec-contents}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-introduction-and-scope}{\mdref{sec-introduction-and-scope}{1.\hspace*{0.5em}Introduction and Scope}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-language-version-applicability}{\mdref{sec-p4-language-version-applicability}{1.1.\hspace*{0.5em}P4 Language Version Applicability}}%mdk + +\mdtocitemx{sec-in-scope}{\mdref{sec-in-scope}{1.2.\hspace*{0.5em}In Scope}}%mdk + +\mdtocitemx{sec-not-in-scope}{\mdref{sec-not-in-scope}{1.3.\hspace*{0.5em}Not In Scope}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-terms-and-definitions}{\mdref{sec-terms-and-definitions}{2.\hspace*{0.5em}Terms and Definitions}}%mdk + +\mdtocitemx{sec-reference-architecture}{\mdref{sec-reference-architecture}{3.\hspace*{0.5em}Reference Architecture}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-service-implementation}{\mdref{sec-p4runtime-service-implementation}{3.1.\hspace*{0.5em}P4Runtime Service Implementation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-security-concerns}{\mdref{sec-security-concerns}{3.1.1.\hspace*{0.5em}Security concerns}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-idealized-workflow}{\mdref{sec-idealized-workflow}{3.2.\hspace*{0.5em}Idealized Workflow}}%mdk + +\mdtocitemx{sec-p4-as-behavioral-description-language}{\mdref{sec-p4-as-behavioral-description-language}{3.3.\hspace*{0.5em}P4 as a Behavioral Description Language}}%mdk + +\mdtocitemx{sec-alternative-workflows}{\mdref{sec-alternative-workflows}{3.4.\hspace*{0.5em}Alternative Workflows}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{\mdref{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}{3.4.1.\hspace*{0.5em}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}}%mdk + +\mdtocitemx{sec-no-p4-source-available-p4info-available}{\mdref{sec-no-p4-source-available-p4info-available}{3.4.2.\hspace*{0.5em}No P4 Source Available, P4Info Available}}%mdk + +\mdtocitemx{sec-partial-p4info-and-p4-source-are-available}{\mdref{sec-partial-p4info-and-p4-source-are-available}{3.4.3.\hspace*{0.5em}Partial P4Info and P4 Source are Available}}%mdk + +\mdtocitemx{sec-p4info-role-based-subsets}{\mdref{sec-p4info-role-based-subsets}{3.4.4.\hspace*{0.5em}P4Info Role-Based Subsets}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-restarts}{\mdref{sec-restarts}{3.5.\hspace*{0.5em}P4Runtime State Across Restarts}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-controller-use-cases}{\mdref{sec-controller-use-cases}{4.\hspace*{0.5em}Controller Use-cases}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-single-embedded-controller}{\mdref{sec-single-embedded-controller}{4.1.\hspace*{0.5em}Single Embedded Controller}}%mdk + +\mdtocitemx{sec-single-remote-controller}{\mdref{sec-single-remote-controller}{4.2.\hspace*{0.5em}Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-single-remote-controller}{\mdref{sec-embedded-single-remote-controller}{4.3.\hspace*{0.5em}Embedded + Single Remote Controller}}%mdk + +\mdtocitemx{sec-embedded-two-remote-controllers}{\mdref{sec-embedded-two-remote-controllers}{4.4.\hspace*{0.5em}Embedded + Two Remote Controllers}}%mdk + +\mdtocitemx{sec-embedded-controller-two-high-availability-remote-controllers}{\mdref{sec-embedded-controller-two-high-availability-remote-controllers}{4.5.\hspace*{0.5em}Embedded Controller + Two High-Availability Remote Controllers}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-client-arbitration-and-controller-replication}{\mdref{sec-client-arbitration-and-controller-replication}{5.\hspace*{0.5em}Client Arbitration and Controller Replication}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-default-role}{\mdref{sec-default-role}{5.1.\hspace*{0.5em}Default Role}}%mdk + +\mdtocitemx{sec-arbitration-role-config}{\mdref{sec-arbitration-role-config}{5.2.\hspace*{0.5em}Role Config}}%mdk + +\mdtocitemx{sec-arbitration-updates}{\mdref{sec-arbitration-updates}{5.3.\hspace*{0.5em}Rules for Handling \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}} Messages Received from Controllers}}%mdk + +\mdtocitemx{sec-arbitration-notification}{\mdref{sec-arbitration-notification}{5.4.\hspace*{0.5em}Client Arbitration Notifications}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-the-p4info-message}{\mdref{sec-the-p4info-message}{6.\hspace*{0.5em}The P4Info Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-common-messages}{\mdref{sec-common-messages}{6.1.\hspace*{0.5em}Common Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-documentation-message}{\mdref{sec-documentation-message}{6.1.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}} Message}}%mdk + +\mdtocitemx{sec-preamble-message}{\mdref{sec-preamble-message}{6.1.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}} Message}}%mdk + +\mdtocitemx{sec-annotating-p4-entities-with-documentation}{\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3.\hspace*{0.5em}Annotating P4 Entities with \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}}%mdk + +\mdtocitemx{sec-structured-annotations}{\mdref{sec-structured-annotations}{6.1.4.\hspace*{0.5em}Structured Annotations}}%mdk + +\mdtocitemx{sec-sourcelocation-message}{\mdref{sec-sourcelocation-message}{6.1.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}} Message}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-pkginfo-message}{\mdref{sec-pkginfo-message}{6.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}} Message}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-annotating-p4-code-with-pkginfo}{\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1.\hspace*{0.5em}Annotating P4 code with PkgInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-id-allocation}{\mdref{sec-id-allocation}{6.3.\hspace*{0.5em}ID Allocation for P4Info Objects}}%mdk + +\mdtocitemx{sec-p4info-objects}{\mdref{sec-p4info-objects}{6.4.\hspace*{0.5em}P4Info Objects}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table}{\mdref{sec-table}{6.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}}%mdk + +\mdtocitemx{sec-action}{\mdref{sec-action}{6.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}}%mdk + +\mdtocitemx{sec-p4info-action-profile}{\mdref{sec-p4info-action-profile}{6.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}}%mdk + +\mdtocitemx{sec-counter-directcounter}{\mdref{sec-counter-directcounter}{6.4.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}}%mdk + +\mdtocitemx{sec-meter-directmeter}{\mdref{sec-meter-directmeter}{6.4.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}}%mdk + +\mdtocitemx{sec-controller-packet-meta}{\mdref{sec-controller-packet-meta}{6.4.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}}%mdk + +\mdtocitemx{sec-valueset}{\mdref{sec-valueset}{6.4.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}}%mdk + +\mdtocitemx{sec-register}{\mdref{sec-register}{6.4.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}}%mdk + +\mdtocitemx{sec-digest}{\mdref{sec-digest}{6.4.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}}%mdk + +\mdtocitemx{sec-p4info-extern}{\mdref{sec-p4info-extern}{6.4.10.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{\mdref{sec-support-for-arbitrary-p4-types-with-p4typeinfo}{6.5.\hspace*{0.5em}Support for Arbitrary P4 Types with P4TypeInfo}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-fwd-pipe-config}{\mdref{sec-p4-fwd-pipe-config}{7.\hspace*{0.5em}P4 Forwarding-Pipeline Configuration}}%mdk + +\mdtocitemx{sec-message-formatting-principles}{\mdref{sec-message-formatting-principles}{8.\hspace*{0.5em}General Principles for Message Formatting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-default-valued-fields}{\mdref{sec-default-valued-fields}{8.1.\hspace*{0.5em}Default-valued Fields}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-set-unset-scalar-fields}{\mdref{sec-set-unset-scalar-fields}{8.1.1.\hspace*{0.5em}Set / Unset Scalar Fields}}%mdk + +\mdtocitemx{sec-set-unset-message-fields}{\mdref{sec-set-unset-message-fields}{8.1.2.\hspace*{0.5em}Set / Unset Message Fields}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-read-write-symmetry}{\mdref{sec-read-write-symmetry}{8.2.\hspace*{0.5em}Read-Write Symmetry}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-data-plane-volatile-objects}{\mdref{sec-data-plane-volatile-objects}{8.2.1.\hspace*{0.5em}Data plane volatile objects}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-bytestrings}{\mdref{sec-bytestrings}{8.3.\hspace*{0.5em}Bytestrings}}%mdk + +\mdtocitemx{sec-representation-of-arbitrary-p4-types}{\mdref{sec-representation-of-arbitrary-p4-types}{8.4.\hspace*{0.5em}Representation of Arbitrary P4 Types}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-problem-statement}{\mdref{sec-problem-statement}{8.4.1.\hspace*{0.5em}Problem Statement}}%mdk + +\mdtocitemx{sec-p4-type-specifications-in-p4infoproto}{\mdref{sec-p4-type-specifications-in-p4infoproto}{8.4.2.\hspace*{0.5em}P4 Type Specifications in p4info.proto}}%mdk + +\mdtocitemx{sec-p4data-in-p4runtime-proto}{\mdref{sec-p4data-in-p4runtime-proto}{8.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}} in p4runtime.proto}}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{8.4.4.\hspace*{0.5em}Example}}%mdk + +\mdtocitemx{sec-enum-serializable-enum-and-error}{\mdref{sec-enum-serializable-enum-and-error}{8.4.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}, serializable \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}}%mdk + +\mdtocitemx{sec-user-defined-types}{\mdref{sec-user-defined-types}{8.4.6.\hspace*{0.5em}User-defined types}}%mdk + +\mdtocitemx{sec-trade-off-for-v1x-releases}{\mdref{sec-trade-off-for-v1x-releases}{8.4.7.\hspace*{0.5em}Trade-off for v1.x Releases}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-entity-msgs}{\mdref{sec-p4-entity-msgs}{9.\hspace*{0.5em}P4 Entity Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-table-entry}{\mdref{sec-table-entry}{9.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-match-format}{\mdref{sec-match-format}{9.1.1.\hspace*{0.5em}Match Format}}%mdk + +\mdtocitemx{sec-action-specification}{\mdref{sec-action-specification}{9.1.2.\hspace*{0.5em}Action Specification}}%mdk + +\mdtocitemx{sec-default-entry}{\mdref{sec-default-entry}{9.1.3.\hspace*{0.5em}Default Entry}}%mdk + +\mdtocitemx{sec-constant-tables}{\mdref{sec-constant-tables}{9.1.4.\hspace*{0.5em}Constant Tables}}%mdk + +\mdtocitemx{sec-preinitialized-tables}{\mdref{sec-preinitialized-tables}{9.1.5.\hspace*{0.5em}Preinitialized tables}}%mdk + +\mdtocitemx{sec-table-wildcard-reads}{\mdref{sec-table-wildcard-reads}{9.1.6.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-direct-resources}{\mdref{sec-direct-resources}{9.1.7.\hspace*{0.5em}Direct Resources}}%mdk + +\mdtocitemx{sec-idle-timeout}{\mdref{sec-idle-timeout}{9.1.8.\hspace*{0.5em}Idle-timeout}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-and-group}{\mdref{sec-action-profile-member-and-group}{9.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-action-profile-member-programming}{\mdref{sec-action-profile-member-programming}{9.2.1.\hspace*{0.5em}Action Profile Member Programming}}%mdk + +\mdtocitemx{sec-action-profile-group-programming}{\mdref{sec-action-profile-group-programming}{9.2.2.\hspace*{0.5em}Action Profile Group Programming}}%mdk + +\mdtocitemx{sec-oneshot}{\mdref{sec-oneshot}{9.2.3.\hspace*{0.5em}One Shot Action Selector Programming}}%mdk + +\mdtocitemx{action-selector-constraints}{\mdref{action-selector-constraints}{9.2.4.\hspace*{0.5em}Constraints on action selector programming}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-counterentry-directcounterentry}{\mdref{sec-counterentry-directcounterentry}{9.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directcounterentry}{\mdref{sec-directcounterentry}{9.3.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}}%mdk + +\mdtocitemx{sec-counterentry}{\mdref{sec-counterentry}{9.3.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-meterentry-directmeterentry}{\mdref{sec-meterentry-directmeterentry}{9.4.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}} \& \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-directmeterentry}{\mdref{sec-directmeterentry}{9.4.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}}%mdk + +\mdtocitemx{sec-meterentry}{\mdref{sec-meterentry}{9.4.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}}%mdk + +\mdtocitemx{sec-metercounterdata}{\mdref{sec-metercounterdata}{9.4.3.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-packetreplicationengineentry}{\mdref{sec-packetreplicationengineentry}{9.5.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-multicastgroupentry}{\mdref{sec-multicastgroupentry}{9.5.1.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}}%mdk + +\mdtocitemx{sec-clonesessionentry}{\mdref{sec-clonesessionentry}{9.5.2.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-valuesetentry}{\mdref{sec-valuesetentry}{9.6.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}}%mdk + +\mdtocitemx{sec-registerentry}{\mdref{sec-registerentry}{9.7.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}}%mdk + +\mdtocitemx{sec-digestentry}{\mdref{sec-digestentry}{9.8.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}}%mdk + +\mdtocitemx{sec-extern-entry}{\mdref{sec-extern-entry}{9.9.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-error-reporting-messages}{\mdref{sec-error-reporting-messages}{10.\hspace*{0.5em}Error Reporting Messages}}%mdk + +\mdtocitemx{sec-atomicity-of-individual-write-and-read-operations}{\mdref{sec-atomicity-of-individual-write-and-read-operations}{11.\hspace*{0.5em}Atomicity of Individual \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} and \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} Operations}}%mdk + +\mdtocitemx{sec-write-rpc}{\mdref{sec-write-rpc}{12.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-batching-and-ordering-of-updates}{\mdref{sec-batching-and-ordering-of-updates}{12.1.\hspace*{0.5em}Batching and Ordering of Updates}}%mdk + +\mdtocitemx{sec-batch-atomicity}{\mdref{sec-batch-atomicity}{12.2.\hspace*{0.5em}Batch Atomicity}}%mdk + +\mdtocitemx{sec-error-reporting}{\mdref{sec-error-reporting}{12.3.\hspace*{0.5em}Error Reporting}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-read-rpc}{\mdref{sec-read-rpc}{13.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} RPC}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-nomenclature}{\mdref{sec-nomenclature}{13.1.\hspace*{0.5em}Nomenclature}}%mdk + +\mdtocitemx{sec-wildcard-reads}{\mdref{sec-wildcard-reads}{13.2.\hspace*{0.5em}Wildcard Reads}}%mdk + +\mdtocitemx{sec-batch-processing}{\mdref{sec-batch-processing}{13.3.\hspace*{0.5em}Batch Processing}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-example}{\mdref{sec-example}{13.3.1.\hspace*{0.5em}Example}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-parallelism-of-read-and-write-requests}{\mdref{sec-parallelism-of-read-and-write-requests}{13.4.\hspace*{0.5em}Parallelism of Read and Write Requests}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-setforwardingpipelineconfig-rpc}{\mdref{sec-setforwardingpipelineconfig-rpc}{14.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-getforwardingpipelineconfig-rpc}{\mdref{sec-getforwardingpipelineconfig-rpc}{15.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}} RPC}}%mdk + +\mdtocitemx{sec-p4runtime-stream-messages}{\mdref{sec-p4runtime-stream-messages}{16.\hspace*{0.5em}P4Runtime Stream Messages}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-packet-i_o}{\mdref{sec-packet-i_o}{16.1.\hspace*{0.5em}Packet I/O}}%mdk + +\mdtocitemx{sec-client-arbitration-update}{\mdref{sec-client-arbitration-update}{16.2.\hspace*{0.5em}Client Arbitration Update}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-unset-election-id}{\mdref{sec-unset-election-id}{16.2.1.\hspace*{0.5em}Unset Election ID}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-digest-messages}{\mdref{sec-digest-messages}{16.3.\hspace*{0.5em}Digest Messages}}%mdk + +\mdtocitemx{sec-table-idle-timeout-notification}{\mdref{sec-table-idle-timeout-notification}{16.4.\hspace*{0.5em}Table Idle Timeout Notification}}%mdk + +\mdtocitemx{sec-architecture-specific-notifications}{\mdref{sec-architecture-specific-notifications}{16.5.\hspace*{0.5em}Architecture-Specific Notifications}}%mdk + +\mdtocitemx{sec-stream-error-reporting}{\mdref{sec-stream-error-reporting}{16.6.\hspace*{0.5em}Stream Error Reporting}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-examples-of-streamerror-messages}{\mdref{sec-examples-of-streamerror-messages}{16.6.1.\hspace*{0.5em}Examples of \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}} Messages}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-capabilities-rpc}{\mdref{sec-capabilities-rpc}{17.\hspace*{0.5em}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}} RPC}}%mdk + +\mdtocitemx{sec-portability-considerations}{\mdref{sec-portability-considerations}{18.\hspace*{0.5em}Portability Considerations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-psa-metadata-translation}{\mdref{sec-psa-metadata-translation}{18.1.\hspace*{0.5em}PSA Metadata Translation}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-translation-of-port-numbers}{\mdref{sec-translation-of-port-numbers}{18.1.1.\hspace*{0.5em}Translation of Port Numbers}}%mdk + +\mdtocitemx{sec-translation-of-packet-io-header-fields}{\mdref{sec-translation-of-packet-io-header-fields}{18.1.2.\hspace*{0.5em}Translation of Packet-IO Header Fields}}%mdk + +\mdtocitemx{sec-translation-of-match-fields}{\mdref{sec-translation-of-match-fields}{18.1.3.\hspace*{0.5em}Translation of Match Fields}}%mdk + +\mdtocitemx{sec-translation-of-action-parameters}{\mdref{sec-translation-of-action-parameters}{18.1.4.\hspace*{0.5em}Translation of Action Parameters}}%mdk + +\mdtocitemx{sec-port-translation-for-psa-extern-apis}{\mdref{sec-port-translation-for-psa-extern-apis}{18.1.5.\hspace*{0.5em}Port Translation for PSA Extern APIs}}%mdk + +\mdtocitemx{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{\mdref{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}{18.1.6.\hspace*{0.5em}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4runtime-versioning}{\mdref{sec-p4runtime-versioning}{19.\hspace*{0.5em}P4Runtime Versioning}}%mdk + +\mdtocitemx{sec-extending-p4runtime}{\mdref{sec-extending-p4runtime}{20.\hspace*{0.5em}Extending P4Runtime for non-PSA Architectures}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-p4runtime-for-architecture-specific-externs}{\mdref{sec-extending-p4runtime-for-architecture-specific-externs}{20.1.\hspace*{0.5em}Extending P4Runtime for Architecture-Specific Externs}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-extending-the-p4info-message}{\mdref{sec-extending-the-p4info-message}{20.1.1.\hspace*{0.5em}Extending the P4Info message}}%mdk + +\mdtocitemx{sec-extending-the-p4runtime-service}{\mdref{sec-extending-the-p4runtime-service}{20.1.2.\hspace*{0.5em}Extending the P4Runtime Service}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-architecture-specific-table-extensions}{\mdref{sec-architecture-specific-table-extensions}{20.2.\hspace*{0.5em}Architecture-Specific Table Extensions}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-new-match-types}{\mdref{sec-new-match-types}{20.2.1.\hspace*{0.5em}New Match Types}}%mdk + +\mdtocitemx{sec-new-table-properties}{\mdref{sec-new-table-properties}{20.2.2.\hspace*{0.5em}New Table Properties}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-known-limitations-of-current-p4runtime-version}{\mdref{sec-known-limitations-of-current-p4runtime-version}{21.\hspace*{0.5em}Known Limitations of Current P4Runtime Version}}%mdk + +\mdtocitemx{sec-appendix}{\mdref{sec-appendix}{A.\hspace*{0.5em}Appendix}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-revision-history}{\mdref{sec-revision-history}{A.1.\hspace*{0.5em}Revision History}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-changes-in-v140}{\mdref{sec-changes-in-v140}{A.1.1.\hspace*{0.5em}Changes in v1.4.0}}%mdk + +\mdtocitemx{sec-changes-in-v130}{\mdref{sec-changes-in-v130}{A.1.2.\hspace*{0.5em}Changes in v1.3.0}}%mdk + +\mdtocitemx{sec-changes-in-v120}{\mdref{sec-changes-in-v120}{A.1.3.\hspace*{0.5em}Changes in v1.2.0}}%mdk + +\mdtocitemx{sec-changes-in-v110}{\mdref{sec-changes-in-v110}{A.1.4.\hspace*{0.5em}Changes in v1.1.0}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-p4-annotations}{\mdref{sec-p4-annotations}{A.2.\hspace*{0.5em}P4 Annotations}}%mdk + +\mdtocitemx{sec-value-set-example}{\mdref{sec-value-set-example}{A.3.\hspace*{0.5em}A More Complex Value Set Example}}%mdk + +\mdtocitemx{sec-guidelines-for-implementations}{\mdref{sec-guidelines-for-implementations}{A.4.\hspace*{0.5em}Guidelines for Implementations}}%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{sec-grpc-metadata-maximum-size}{\mdref{sec-grpc-metadata-maximum-size}{A.4.1.\hspace*{0.5em}gRPC Metadata Maximum Size}}%mdk + +\mdtocitemx{sec-grpc-server-maximum-receive-message-size}{\mdref{sec-grpc-server-maximum-receive-message-size}{A.4.2.\hspace*{0.5em}gRPC Server Maximum Receive Message Size}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-entries-files}{\mdref{sec-entries-files}{A.5.\hspace*{0.5em}P4Runtime Entries files}}%mdk +%mdk +\end{mdtocblock}%mdk + +\mdtocitemx{sec-bibliography}{\mdref{sec-bibliography}{References}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{215} +\begin{mdtoc}%mdk + +\section*{Figures}\label{sec-figures}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{fig-reference-architecture}{\mdref{fig-reference-architecture}{\mdcaptionlabel{1}. P4Runtime Reference Architecture.}}%mdk + +\mdtocitemx{fig-single-embedded-controller}{\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}. Use-Case: Single Embedded Controller}}%mdk + +\mdtocitemx{fig-single-remote-controller}{\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}. Use-Case: Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-single-remote-controller}{\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}. Use-Case: Embedded Plus Single Remote Controller}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-controllers}{\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}. Use-Case: Embedded Plus Two Remote Controllers}}%mdk + +\mdtocitemx{fig-embedded-plus-two-remote-ha-controllers}{\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}. Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk + +\mdtocitemx{fig-error-report}{\mdref{fig-error-report}{\mdcaptionlabel{7}. P4Runtime Error Report Message Format}}%mdk + +\mdtocitemx{fig-psa-metadata-translation}{\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}. P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk +\mdline{216} +\begin{mdtoc}%mdk + +\section*{Tables}\label{sec-tables}%mdk%mdk + +\begin{mdtocblock}%mdk + +\mdtocitemx{tab-mapping-p4-obj-ids}{\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}. Mapping of P4Info object type to 8-bit ID prefix value}}%mdk + +\mdtocitemx{tab-format-p4-obj-ids}{\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}. Format of P4Info object IDs}}%mdk + +\mdtocitemx{tab-exmpl-p4-obj-ids}{\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}. Example of statically-assigned P4Info object IDs}}%mdk + +\mdtocitemx{tab-valid-bytestring-encoding}{\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}. Examples of Valid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-invalid-bytestring-encoding}{\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}. Examples of Invalid Bytestring Encoding}}%mdk + +\mdtocitemx{tab-p4-type-usage}{\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}. P4 Type Usage}}%mdk + +\mdtocitemx{tab-p4-annotations}{\mdref{tab-p4-annotations}{\mdcaptionlabel{7}. P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdtocblock}%mdk +%mdk +\end{mdtoc}%mdk + +%mdk-data-line={218} +\section{\mdline{218}1.\hspace*{0.5em}\mdline{218}Introduction and Scope}\label{sec-introduction-and-scope}%mdk%mdk + +%mdk-data-line={220} +\noindent\mdline{220}This document is published by the \mdline{220}\emph{P4.org API Working Group}\mdline{220}, which was +chartered\mdline{221}~[\mdcite{p4apiwgcharter}{21}]\mdline{221} to design and standardize vendor-independent, +protocol-independent runtime APIs for P4-defined or P4-described data +planes. This document specifies one such API, called \mdline{223}\emph{P4Runtime}\mdline{223}. It is meant to +disambiguate and augment the programmatic API definition expressed in Protobuf +format and available at +\mdline{226}\href{https://github.com/p4lang/p4runtime/tree/main/proto}{https://github.com/p4lang/p4runtime/tree/main/proto}\mdline{226}.%mdk + +%mdk-data-line={228} +\subsection{\mdline{228}1.1.\hspace*{0.5em}\mdline{228}P4 Language Version Applicability}\label{sec-p4-language-version-applicability}%mdk%mdk + +%mdk-data-line={230} +\noindent\mdline{230}P4Runtime is designed to be implemented in conjunction with the P4\mdline{230}\mdsub{16}\mdline{230} language +version or later. P4\mdline{231}\mdsub{14}\mdline{231} programs should be translated into P4\mdline{231}\mdsub{16}\mdline{231} to be made +compatible with P4Runtime. This version of P4Runtime utilizes features which are +not in P4\mdline{233}\mdsub{16}\mdline{233} 1.0, but were introduced in P4\mdline{233}\mdsub{16}\mdline{233} 1.2.4\mdline{233}~[\mdcite{p4revisions124}{35}]\mdline{233}. For +this version of P4Runtime, we recommend using P4\mdline{234}\mdsub{16}\mdline{234} 1.2.4\mdline{234}~[\mdcite{p4revisions124}{35}]\mdline{234}.%mdk + +%mdk-data-line={236} +\mdline{236}This version of the P4Runtime specification does not yet explicitly +address compatibility with the following P4\mdline{237}\mdsub{16}\mdline{237} language features +introduced in versions 1.2.2 or 1.2.4 of the language specification:%mdk + +%mdk-data-line={240} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={240} +\item\mdline{240}Added support for generic structures\mdline{240}~[\mdcite{p4revisions122}{34}]\mdline{240}.%mdk + +%mdk-data-line={241} +\item\mdline{241}Added support for additional enumeration types\mdline{241}~[\mdcite{p4revisions122}{34}]\mdline{241}.%mdk + +%mdk-data-line={242} +\item\mdline{242}Added support for 0-width bitstrings and varbits\mdline{242}~[\mdcite{p4revisions122}{34}]\mdline{242}.%mdk + +%mdk-data-line={243} +\item\mdline{243}Clarified restrictions for parameters with default values +\mdline{244}[\mdcite{p4revisions124}{35}]\mdline{244}.%mdk + +%mdk-data-line={245} +\item\mdline{245}Allow ranges to be specified by serializable enums +\mdline{246}[\mdcite{p4revisions124}{35}]\mdline{246}.%mdk + +%mdk-data-line={247} +\item\mdline{247}Added \mdline{247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}list}}}\mdline{247} type\mdline{247}~[\mdcite{p4revisions124}{35}]\mdline{247}.%mdk + +%mdk-data-line={248} +\item\mdline{248}Clarified behavior of table with no \mdline{248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{248} property, or if its list +of keys is empty\mdline{249}~[\mdcite{p4revisions124}{35}]\mdline{249}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={252} +\subsection{\mdline{252}1.2.\hspace*{0.5em}\mdline{252}In Scope}\label{sec-in-scope}%mdk%mdk + +%mdk-data-line={254} +\noindent\mdline{254}This specification document defines the \mdline{254}\emph{semantics}\mdline{254} of \mdline{254}\emph{P4Runtime}\mdline{254} messages, +whose syntax is defined in Protobuf format. The following are in scope of +P4Runtime:%mdk + +%mdk-data-line={258} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={258} +\item\mdline{258}Runtime control of P4 built-in objects (tables and Value Sets) and Portable +Switch Architecture (PSA)\mdline{259}~[\mdcite{psa}{24}]\mdline{259} externs (\mdline{259}e.g.\mdline{259} Counters, Meters, Action +Profiles, \mdline{260}\dots{}\mdline{260}). We recommend that this version of P4Runtime be used with +targets that are compliant with PSA version 1.1.0.%mdk + +%mdk-data-line={262} +\item\mdline{262}Runtime control of architecture-specific (non-PSA) externs, through an +extension mechanism.%mdk + +%mdk-data-line={264} +\item\mdline{264}Basic session management for Software-Defined Networking (SDN) use-cases, +including support for controller replication to enable control plane +redundancy.%mdk + +%mdk-data-line={267} +\item\mdline{267}Partition of the P4 forwarding elements into different roles, which can be +assigned to different control entities.%mdk + +%mdk-data-line={269} +\item\mdline{269}Packet I/O to enable streaming packets to \mdline{269}\&\mdline{269} from the control plane.%mdk + +%mdk-data-line={270} +\item\mdline{270}Batching support, with different atomicity guarantees.%mdk + +%mdk-data-line={271} +\item\mdline{271}In-the-field device-reconfiguration with a new P4 data plane.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={273} +\noindent\mdline{273}The following are in the scope of this specification document:%mdk + +%mdk-data-line={275} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={275} +\item\mdline{275}Rationale for the P4Runtime design.%mdk + +%mdk-data-line={276} +\item\mdline{276}Reference architecture and use-cases for deploying a P4Runtime service.%mdk + +%mdk-data-line={277} +\item\mdline{277}Detailed description of the API semantics.%mdk + +%mdk-data-line={278} +\item\mdline{278}Requirements for conformant implementations of the API.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={280} +\subsection{\mdline{280}1.3.\hspace*{0.5em}\mdline{280}Not In Scope}\label{sec-not-in-scope}%mdk%mdk + +%mdk-data-line={282} +\noindent\mdline{282}The following are not in scope of P4Runtime:%mdk + +%mdk-data-line={284} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={284} +\item\mdline{284}Runtime control of elements outside the P4 language. For example, +architecture-dependent elements such as ports, traffic management, etc. are +outside of the P4 language and are thus not covered by P4Runtime. Efforts are +underway to standardize the control of these via gNMI and gNOI APIs, using +description models defined and maintained by the OpenConfig project +\mdline{289}[\mdcite{openconfig}{41}]\mdline{289}. An open source implementation of these APIs is also in progress +as part of the Stratum project\mdline{290}~[\mdcite{stratum}{43}]\mdline{290}.%mdk + +%mdk-data-line={291} +\item\mdline{291}Protobuf message definitions for runtime control of non-PSA externs. While +P4Runtime includes an extension mechanism to support additional P4 +architectures, it does not define the syntax or semantics of any additional +control message for externs introduced by non-PSA architectures.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={296} +\noindent\mdline{296}The following are not in scope of this specification document:%mdk + +%mdk-data-line={298} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={298} +\item\mdline{298}Description of the P4 programming language; it is assumed that the reader is +already familiar with P4\mdline{299}\mdsub{16}\mdline{299}~[\mdcite{p4spec}{1}]\mdline{299}.%mdk + +%mdk-data-line={300} +\item\mdline{300}Descriptions of gRPC and Protobuf files in general.%mdk + +%mdk-data-line={301} +\item\mdline{301}Controller\mdline{301}~\mdref{sec-arbitration-role-config}{role}\mdline{301} definition (for partition of +P4 entities); the P4.org API Working Group may publish a companion document in +the future describing one possible role definition scheme.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={305} +\section{\mdline{305}2.\hspace*{0.5em}\mdline{305}Terms and Definitions}\label{sec-terms-and-definitions}%mdk%mdk + +%mdk-data-line={307} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries arbitration}}%mdk + +%mdk-data-line={307} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{307}Refers to the process through which P4Runtime ensures that at any given +time, there is a single primary controller (\mdline{308}i.e.\mdline{308} a client with write access) +for a given role. Also referred to as \mdline{309}\textquotedblleft{}client arbitration\textquotedblright{}\mdline{309}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries client}}%mdk + +%mdk-data-line={311} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{311}The gRPC client is the software entity which controls the P4 target or +device by communicating with the gRPC agent or server. The client may be +local (within the device) or remote (for example, an SDN controller). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries COS}}%mdk + +%mdk-data-line={315} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{315}Class of Service. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries device}}%mdk + +%mdk-data-line={317} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{317}Synonymous with target, although device usually connotes a physical +appliance or other hardware, whereas target can signify hardware or +software. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries entity}}%mdk + +%mdk-data-line={321} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{321}An instantiated P4 program object such as a table or an extern (from PSA or +any other architecture). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries gRPC}}%mdk + +%mdk-data-line={324} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{324}gRPC Remote Procedure Calls, an open-source client-server RPC framework. See +\mdline{325}[\mdcite{grpc}{11}]\mdline{325}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries HA}}%mdk + +%mdk-data-line={327} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{327}High-Availability. Refers to a redundancy architecture. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Instrumentation}}%mdk + +%mdk-data-line={329} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{329}The part of the P4Runtime server which implements the calls to the device or +target native \mdline{330}\textquotedblleft{}SDK\textquotedblright{}\mdline{330} or backend. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries IPC}}%mdk + +%mdk-data-line={332} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{332}Inter-Process Communication. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Blob}}%mdk + +%mdk-data-line={334} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{334}A more colloquial term for P4 Device Config (Blob = Binary Large Object). +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4 Device Config}}%mdk + +%mdk-data-line={336} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{336}The output of the P4 compiler backend, which is included in the Forwarding +Pipeline Config. This is opaque, architecture- and target-specific binary +data which can be loaded onto the device to change its \mdline{338}\textquotedblleft{}program.\textquotedblright{}\mdline{338} +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4Info}}%mdk + +%mdk-data-line={340} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{340}Metadata which specifies the P4 entities which can be accessed via +P4Runtime. These entities have a one-for-one correspondence with +instantiated objects in the P4 source code. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries P4RT}}%mdk + +%mdk-data-line={344} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{344}Abbreviation for P4Runtime. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries Protobuf (Protocol Buffers)}}%mdk + +%mdk-data-line={346} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{346}The wire serialization format for P4Runtime. Protobuf version 3 (proto3) is +used to define the P4Runtime interface. See\mdline{347}~[\mdcite{proto}{26}]\mdline{347}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries PSA}}%mdk + +%mdk-data-line={349} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{349}Portable Switch Architecture\mdline{349}~[\mdcite{psa}{24}]\mdline{349}; a target architecture that describes +common capabilities of network switch devices that process and forward +packets across multiple interface ports. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RPC}}%mdk + +%mdk-data-line={353} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{353}Remote Procedure Call. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries RTT}}%mdk + +%mdk-data-line={355} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{355}Round-trip time. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN}}%mdk + +%mdk-data-line={357} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{357}Software-Defined Networking, an approach to networking that advocates the +separation of the control and forwarding planes, as well as the abstraction +of the networking infrastructure, in order to promote programmability of the +network control. SDN is often associated with OpenFlow, a communications +protocol that enables remote control of the network infrastructure through a +programmable, centralized network \mdline{362}\emph{controller}\mdline{362}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries SDN port}}%mdk + +%mdk-data-line={364} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{364}A 32-bit port number defined by a remote Software-Defined Network (SDN) +controller. The SDN port number maps to a unique device port id, which may +be in a different number space. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries server}}%mdk + +%mdk-data-line={368} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{368}The gRPC server which accepts P4Runtime requests on the device or target. It +uses instrumentation to translate P4Runtime API calls into target-specific +actions. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries stream}}%mdk + +%mdk-data-line={372} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{372}Refers to a gRPC Stream, which is a RPC on which several messages can be +sent and received. P4Runtime defines one Stream RPC (\mdline{373}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{373}), which +is a bidirectional stream (both the client and the server can send messages) +which is used for packet I/O and client arbitration, among other things. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries switch config}}%mdk + +%mdk-data-line={377} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{377}Refers to the non-forwarding config (different from the P4 Forwarding +Pipeline Config) that is delivered to the switch via a different +interface. For example, the switch config may be captured using OpenConfig +models and delivered through a gNMI interface. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries target}}%mdk + +%mdk-data-line={382} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{382}The hardware or software entity which \mdline{382}\textquotedblleft{}executes\textquotedblright{}\mdline{382} the P4 pipeline and hosts +the P4Runtime Service; often used interchangeably with \mdline{383}\textquotedblleft{}device\textquotedblright{}\mdline{383}. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries URI}}%mdk + +%mdk-data-line={385} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{385}Uniform Resource Identifier; a string of characters designed for unambiguous +identification of resources.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={389} +\section{\mdline{389}3.\hspace*{0.5em}\mdline{389}Reference Architecture}\label{sec-reference-architecture}%mdk%mdk + +%mdk-data-line={391} +\noindent\mdline{391}Figure\mdline{391}~\mdref{fig-reference-architecture}{\mdcaptionlabel{1}}\mdline{391} represents the P4Runtime Reference +Architecture. The device or target to be controlled is at the bottom, and one or +more controllers is shown at the top. P4Runtime only grants write access to a +single primary controller for each read/write entity. A role defines a grouping +of P4 entities. P4Runtime allows for a primary controller for each role, and a +role-based client arbitration scheme ensures only one controller has +write access to each read/write entity, or the pipeline config itself. Any +controller may perform read access to any entity or the pipeline config. Later +sections describe this in detail. For the sake of brevity, the term controller +may refer to one or more controllers.%mdk + +%mdk-data-line={402} +\mdline{402}The P4Runtime API defines the messages and semantics of the interface between +the client(s) and the server. The API is specified by the p4runtime.proto +Protobuf file, which is available on GitHub as part of the standard +\mdline{405}[\mdcite{p4runtimerepo}{19}]\mdline{405}. It may be compiled via protoc\mdline{405} \mdline{405}\textemdash{}\mdline{405} the Protobuf compiler\mdline{405} \mdline{405}\textemdash{}\mdline{405} +to produce both client and server implementation stubs in a variety of +languages. It is the responsibility of target implementers to instrument the +server.%mdk + +%mdk-data-line={410} +\mdline{410}Reference implementations of P4 targets supporting P4Runtime, as well as sample +clients, may be available on the p4lang/PI GitHub repository\mdline{411}~[\mdcite{pirepo}{20}]\mdline{411}. A future +goal may be to produce a reference gRPC server which can be instrumented in a +generic way, \mdline{413}e.g.\mdline{413} via callbacks, thus reducing the burden of implementing +P4Runtime.%mdk + +%mdk-data-line={416} +\mdline{416}The controller can access the P4 entities which are declared in the P4Info +metadata. The P4Info structure is defined by p4info.proto, another Protobuf file +available as part of the standard.%mdk + +%mdk-data-line={420} +\mdline{420}The controller can also set the \mdline{420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{420}, which amounts to +installing and running the compiled P4 program output, which is included in the +\mdline{422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{422} Protobuf message field, and installing the associated P4Info +metadata. Furthermore, the controller can query the target for the +\mdline{424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{424} to retrieve the device config and the P4Info.%mdk + +%mdk-data-line={427} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={428} +\noindent\mdline{428}\includegraphics[keepaspectratio=true,height=7cm]{build/reference-architecture}{}\mdline{428}%mdk + +%mdk-data-line={429} +\mdhr{}%mdk + +%mdk-data-line={430} +\noindent\mdline{430}\mdcaption{\textbf{Figure~\mdcaptionlabel{1}.}~\mdcaptiontext{P4Runtime Reference Architecture.}}%mdk +%mdk +\end{mdcenter}\label{fig-reference-architecture}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={434} +\subsection{\mdline{434}3.1.\hspace*{0.5em}\mdline{434}P4Runtime Service Implementation}\label{sec-p4runtime-service-implementation}%mdk%mdk + +%mdk-data-line={436} +\noindent\mdline{436}The P4Runtime API is implemented by a program that runs a gRPC server which +binds an implementation of auto-generated P4Runtime Service interface. This +program is called the \mdline{438}\textquotedblleft{}P4Runtime server.\textquotedblright{}\mdline{438} The server must listen on TCP port +9559 by default, which is the port that has been allocated by IANA for the +P4Runtime service. Servers should allow users to override the default port +using a configuration file or flag when starting the server. Uses of other +port numbers as the default should be discontinued.%mdk + +%mdk-data-line={444} +\subsubsection{\mdline{444}3.1.1.\hspace*{0.5em}\mdline{444}Security concerns}\label{sec-security-concerns}%mdk%mdk + +%mdk-data-line={446} +\noindent\mdline{446}Appropriate measures and security best practices must be in place to protect +the P4Runtime server and client, and the communication channel between the two. +For example, firewalling and authenticating the incoming connections to the +P4Runtime server can prevent a malicious actor from taking over the switch. +Similarly, using TLS to authenticate and encrypt the gRPC channel can prevent +man-in-the-middle attacks between the server and client. Mutual TLS (mTLS) may +be used to facilitate the authentication of the client by the server and +vice-versa.%mdk + +%mdk-data-line={455} +\subsection{\mdline{455}3.2.\hspace*{0.5em}\mdline{455}Idealized Workflow}\label{sec-idealized-workflow}%mdk%mdk + +%mdk-data-line={457} +\noindent\mdline{457}In the idealized workflow, a P4 source program is compiled to produce both a P4 +device config and P4Info metadata. These comprise the \mdline{458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{458} +message. A P4Runtime controller chooses a configuration appropriate to a +particular target and installs it via a \mdline{460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{460} +RPC. Metadata in the P4Info describes both the overall program itself +(\mdline{462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{462}) as well as all entity instances derived from the P4 program\mdline{462} \mdline{462}\textemdash{}\mdline{462} +tables and extern instances. Each entity instance has an associated numeric ID +assigned by the P4 compiler which serves as a concise \mdline{464}\textquotedblleft{}handle\textquotedblright{}\mdline{464} used in API +calls.%mdk + +%mdk-data-line={467} +\mdline{467}In this workflow, P4 compiler backends are developed for each unique type of +target and produce P4Info and a target-specific device config. The P4Info schema +is designed to be target and architecture-independent, although the specific +contents are likely to be architecture-dependent. The compiler ensures the code +is compatible with the specific target and rejects code which is incompatible.%mdk + +%mdk-data-line={473} +\mdline{473}In some use cases, it is expected that a controller will store a +collection of multiple P4 \mdline{474}\textquotedblleft{}packages\textquotedblright{}\mdline{474}, where each package consists of +the P4 device config and P4Info, and install them at will onto the target. A +controller can also query the \mdline{476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{476} from the target via the +\mdline{477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineRequest}}}\mdline{477} RPC. This can be useful to obtain the pipeline +configuration from a running device to synchronize the controller to its current +state.%mdk + +%mdk-data-line={481} +\subsection{\mdline{481}3.3.\hspace*{0.5em}\mdline{481}P4 as a Behavioral Description Language}\label{sec-p4-as-behavioral-description-language}%mdk%mdk + +%mdk-data-line={483} +\noindent\mdline{483}P4 can be considered a behavioral description of a switching device which may or +may not execute \mdline{484}\textquotedblleft{}P4\textquotedblright{}\mdline{484} natively. There is no requirement that a P4 compiler be +used in the production of either the P4 device config or the P4Info. There is no +absolute requirement that the target accept a \mdline{486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineRequest}}}\mdline{486} to +change its pipeline \mdline{487}\textquotedblleft{}program\textquotedblright{}\mdline{487}, as some devices may be fixed in function, or +configured via means other than P4 programs. Furthermore, a controller can run +without a P4 source program, since the P4Info file provides all of the +information necessary to describe the P4Runtime API messages needed to configure +such a device.%mdk + +%mdk-data-line={493} +\mdline{493}While a P4 program does provide a precise description of the data plane +behavior, and this can prove invaluable in writing correct control plane +software, in some cases it is enough for a control plane software developer to +have the control plane API, plus good documentation of the data plane +behavior. Some device vendors may wish to keep their P4 source code private. The +minimum requirement for the controller and device to communicate properly is a +P4Info file that can be loaded by a controller in order to render the correct +P4Runtime API.%mdk + +%mdk-data-line={502} +\mdline{502}In such scenarios, it is crucial to have detailed documentation, perhaps +included in the P4Info file itself, specifically the metadata in the \mdline{503}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{503} +message as well as the embedded \mdline{504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{504} fields. Nevertheless, a P4 program which +describes the pipeline is ideally available. The contents of the P4Info file +will be described in later sections.%mdk + +%mdk-data-line={508} +\subsection{\mdline{508}3.4.\hspace*{0.5em}\mdline{508}Alternative Workflows}\label{sec-alternative-workflows}%mdk%mdk + +%mdk-data-line={510} +\noindent\mdline{510}Given the notions above concerning P4 code as behavioral description and P4Info +as API metadata, some other workflows are possible. The scenarios below are just +examples and actual situations may vary.%mdk + +%mdk-data-line={514} +\subsubsection{\mdline{514}3.4.1.\hspace*{0.5em}\mdline{514}P4 Source Available, Compiled into P4Info but not Compiled into P4 Device Config}\label{sec-p4-source-available-compiled-into-p4info-but-not-compiled-into-p4-device-config}%mdk%mdk + +%mdk-data-line={516} +\noindent\mdline{516}In this situation, P4 source code is available mainly as a behavioral model and +compiled to produce P4Info, but it is not compiled to produce the +\mdline{518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{518}. The device\mdline{518}'\mdline{518}s configuration might be derived via some other +means to implement the P4 source code\mdline{519}'\mdline{519}s intentions. The P4 code, if available, +can be studied to understand the pipeline, and the P4Info can be used to +implement the control plane.%mdk + +%mdk-data-line={523} +\subsubsection{\mdline{523}3.4.2.\hspace*{0.5em}\mdline{523}No P4 Source Available, P4Info Available}\label{sec-no-p4-source-available-p4info-available}%mdk%mdk + +%mdk-data-line={525} +\noindent\mdline{525}In this situation, P4Info is available but no P4 source is available for any +number of reasons, the most likely of which are:%mdk + +%mdk-data-line={528} +\begin{enumerate}%mdk + +%mdk-data-line={528} +\item{} +%mdk-data-line={528} +\mdline{528}The vendor or organization does not wish to divulge the P4 source code, to +protect intellectual property or maintain security.%mdk%mdk + +%mdk-data-line={531} +\item{} +%mdk-data-line={531} +\mdline{531}The target was not implemented using P4 code to begin with, although it still +obeys the control plane API specified in the P4Info.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={534} +\noindent\mdline{534}As discussed in Section\mdline{534}~\mdref{sec-p4-as-behavioral-description-language}{3.3}\mdline{534}, in the +absence of a P4 program describing the data plane behavior, the detailed +knowledge required to write correct control plane code must come from other +sources, \mdline{537}e.g.\mdline{537} documentation.%mdk + +%mdk-data-line={539} +\subsubsection{\mdline{539}3.4.3.\hspace*{0.5em}\mdline{539}Partial P4Info and P4 Source are Available}\label{sec-partial-p4info-and-p4-source-are-available}%mdk%mdk + +%mdk-data-line={541} +\noindent\mdline{541}In this situation, a subset of the target\mdline{541}'\mdline{541}s pipeline configuration is exposed as +P4 source code and P4Info. The complete device behavior might be expressed as a +larger P4 program and P4Info, but these are not exposed to everybody. This +limits API access to only certain functions and behaviors. The hidden functions +and APIs might be available to select users who would have access to the +complete P4Info and possibly P4 source code.%mdk + +%mdk-data-line={548} +\subsubsection{\mdline{548}3.4.4.\hspace*{0.5em}\mdline{548}P4Info Role-Based Subsets}\label{sec-p4info-role-based-subsets}%mdk%mdk + +%mdk-data-line={550} +\noindent\mdline{550}In this situation, P4Info is selectively packaged into role-based subsets to +allow some controllers access to just the functionality required. For example, a +controller may only need read access to statistics counters and nothing more.%mdk + +%mdk-data-line={554} +\subsection{\mdline{554}3.5.\hspace*{0.5em}\mdline{554}P4Runtime State Across Restarts}\label{sec-restarts}%mdk%mdk + +%mdk-data-line={556} +\noindent\mdline{556}All targets support full restarts, where all forwarding state is reset and the +P4Runtime server starts with a clean state. Some targets may also support +In-Service Software Upgrade (ISSU), where the software on the target can be +restarted while traffic is being forwarded. In this case, the P4Runtime server +may have the ability to access information from memory before the upgrade.%mdk + +%mdk-data-line={562} +\section{\mdline{562}4.\hspace*{0.5em}\mdline{562}Controller Use-cases}\label{sec-controller-use-cases}%mdk%mdk + +%mdk-data-line={564} +\noindent\mdline{564}P4Runtime allows for more than one controller. The mechanisms and semantics are +described in a later +\mdline{566}\mdref{sec-client-arbitration-and-controller-replication}{section}\mdline{566}. Here we +present a number of use-cases. Each use-case highlights a particular aspect of +P4Runtime\mdline{568}'\mdline{568}s flexibility and is not intended to be exhaustive. Real-world +use-cases may combine various techniques and be more complex.%mdk + +%mdk-data-line={571} +\subsection{\mdline{571}4.1.\hspace*{0.5em}\mdline{571}Single Embedded Controller}\label{sec-single-embedded-controller}%mdk%mdk + +%mdk-data-line={573} +\noindent\mdline{573}Figure\mdline{573}~\mdref{fig-single-embedded-controller}{\mdcaptionlabel{2}}\mdline{573} shows perhaps the simplest use-case. A +device or target has an embedded controller which communicates to an on-board +switch via P4Runtime. This might be appropriate for an embedded appliance which +is not intended for SDN use-cases.%mdk + +%mdk-data-line={578} +\mdline{578}P4Runtime was designed to be a viable embedded API. Complex controller +architectures typically feature multiple processes communicating with some sort +of IPC (Inter-Process Communications). P4Runtime is thus both an ideal RPC and +an IPC.%mdk + +%mdk-data-line={583} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={584} +\noindent\mdline{584}\includegraphics[keepaspectratio=true,height=6cm]{build/single-embedded-controller}{}\mdline{584}%mdk + +%mdk-data-line={585} +\mdhr{}%mdk + +%mdk-data-line={586} +\noindent\mdline{586}\mdcaption{\textbf{Figure~\mdcaptionlabel{2}.}~\mdcaptiontext{Use-Case: Single Embedded Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-embedded-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={590} +\subsection{\mdline{590}4.2.\hspace*{0.5em}\mdline{590}Single Remote Controller}\label{sec-single-remote-controller}%mdk%mdk + +%mdk-data-line={592} +\noindent\mdline{592}Figure\mdline{592}~\mdref{fig-single-remote-controller}{\mdcaptionlabel{3}}\mdline{592} shows a single remote Controller in +charge of the P4 target. In this use-case, the device has no control of the +pipeline, it just hosts the server. While this is possible, it is probably more +practical to have a hybrid use-case as described in subsequent sections.%mdk + +%mdk-data-line={597} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={598} +\noindent\mdline{598}\includegraphics[keepaspectratio=true,height=7cm]{build/single-remote-controller}{}\mdline{598}%mdk + +%mdk-data-line={599} +\mdhr{}%mdk + +%mdk-data-line={600} +\noindent\mdline{600}\mdcaption{\textbf{Figure~\mdcaptionlabel{3}.}~\mdcaptiontext{Use-Case: Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={604} +\subsection{\mdline{604}4.3.\hspace*{0.5em}\mdline{604}Embedded\mdline{604} \mdline{604}+ Single Remote Controller}\label{sec-embedded-single-remote-controller}%mdk%mdk + +%mdk-data-line={606} +\noindent\mdline{606}Figure\mdline{606}~\mdref{fig-embedded-plus-single-remote-controller}{\mdcaptionlabel{4}}\mdline{606} illustrates the use-case of +an embedded controller plus a single remote controller. Both controllers are +clients of the single server. The embedded controller is in charge of one set of +P4 entities plus the pipeline configuration. The remote controller is in charge +of the remainder of the P4 entities. An equally-valid, alternative use-case, +could assign the pipeline configuration to the remote controller.%mdk + +%mdk-data-line={613} +\mdline{613}For example, to minimize round-trip times (RTT) it might make sense for the +embedded controller to manage the contents of a fast-failover table. The remote +controller might manage the contents of routing tables.%mdk + +%mdk-data-line={617} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={618} +\noindent\mdline{618}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-single-remote-controller}{}\mdline{618}%mdk + +%mdk-data-line={619} +\mdhr{}%mdk + +%mdk-data-line={620} +\noindent\mdline{620}\mdcaption{\textbf{Figure~\mdcaptionlabel{4}.}~\mdcaptiontext{Use-Case: Embedded Plus Single Remote Controller}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-single-remote-controller}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={625} +\subsection{\mdline{625}4.4.\hspace*{0.5em}\mdline{625}Embedded\mdline{625} \mdline{625}+ Two Remote Controllers}\label{sec-embedded-two-remote-controllers}%mdk%mdk + +%mdk-data-line={627} +\noindent\mdline{627}Figure\mdline{627}~\mdref{fig-embedded-plus-two-remote-controllers}{\mdcaptionlabel{5}}\mdline{627} illustrates the case of an +embedded controller similar to the previous use-case, and two remote +controllers. One of the remote controllers is responsible for some entities, +\mdline{630}e.g.\mdline{630} routing tables, and the other remote controller is responsible for other +entities, perhaps statistics tables. Role-based access divides the ownership.%mdk + +%mdk-data-line={633} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={634} +\noindent\mdline{634}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-controllers}{}\mdline{634}%mdk + +%mdk-data-line={635} +\mdhr{}%mdk + +%mdk-data-line={636} +\noindent\mdline{636}\mdcaption{\textbf{Figure~\mdcaptionlabel{5}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={641} +\subsection{\mdline{641}4.5.\hspace*{0.5em}\mdline{641}Embedded Controller\mdline{641} \mdline{641}+ Two High-Availability Remote Controllers}\label{sec-embedded-controller-two-high-availability-remote-controllers}%mdk%mdk + +%mdk-data-line={643} +\noindent\mdline{643}Figure\mdline{643}~\mdref{fig-embedded-plus-two-remote-ha-controllers}{\mdcaptionlabel{6}}\mdline{643} illustrates a single +embedded controller plus two remote controllers in an active-standby (\mdline{644}i.e.\mdline{644} +primary-backup) HA (High-Availability) configuration. Controller \mdline{645}\#\mdline{645}1 is the +active controller and is in charge of some entities. If it fails, Controller \mdline{646}\#\mdline{646}2 +takes over and manages the tables formerly owned by Controller \mdline{647}\#\mdline{647}1. The mechanics +of HA architectures are beyond the scope of this document, but the P4Runtime +role-based client arbitration scheme supports it.%mdk + +%mdk-data-line={651} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={652} +\noindent\mdline{652}\includegraphics[keepaspectratio=true,height=7cm]{build/embedded-plus-two-remote-ha-controllers}{}\mdline{652}%mdk + +%mdk-data-line={653} +\mdhr{}%mdk + +%mdk-data-line={654} +\noindent\mdline{654}\mdcaption{\textbf{Figure~\mdcaptionlabel{6}.}~\mdcaptiontext{Use-Case: Embedded Plus Two Remote High-Availability Controllers}}%mdk +%mdk +\end{mdcenter}\label{fig-embedded-plus-two-remote-ha-controllers}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={659} +\section{\mdline{659}5.\hspace*{0.5em}\mdline{659}Client Arbitration and Controller Replication}\label{sec-client-arbitration-and-controller-replication}%mdk%mdk + +%mdk-data-line={662} +\noindent\mdline{662}The P4Runtime interface allows multiple clients (\mdline{662}i.e.\mdline{662} controllers) to be +connected to the P4Runtime server running on the device at the same time for the +following reasons:%mdk + +%mdk-data-line={666} +\begin{enumerate}%mdk + +%mdk-data-line={666} +\item{} +%mdk-data-line={666} +\mdline{666}Partitioning of the control plane: Multiple controllers may have orthogonal, +non-overlapping, \mdline{667}\textquotedblleft{}roles\textquotedblright{}\mdline{667} (or \mdline{667}\textquotedblleft{}realms\textquotedblright{}\mdline{667}) and should be able to push forwarding +entities simultaneously. The control plane can be partitioned into multiple +roles and each role will have a set of controllers, one of which is the +primary and the rest are backups. Role definition, \mdline{670}i.e.\mdline{670} how P4 entities get +assigned to each role, is \mdline{671}\textbf{out-of-scope}\mdline{671} of this document.%mdk%mdk + +%mdk-data-line={673} +\item{} +%mdk-data-line={673} +\mdline{673}Redundancy and fault tolerance: Supporting multiple controllers allows having +one or more standby backup controllers. These can already have a connection +open, which can help them become primary more quickly, especially in the case +where the control-plane traffic is in-band and connection setup might be more +involved.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={679} +\noindent\mdline{679}To support multiple controllers, P4Runtime uses the streaming channel (available +via \mdline{680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{680} RPC) for session management. The workflow is described as +follows:%mdk + +%mdk-data-line={683} +\begin{itemize}%mdk + +%mdk-data-line={683} +\item{} +%mdk-data-line={683} +\mdline{683}Each controller instance (\mdline{683}e.g.\mdline{683} a controller process) can participate in one or +more roles. For each (\mdline{684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{684}, \mdline{684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{684}), the controller receives an +\mdline{685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{685}. This \mdline{685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{685} can be the same for different roles and/or +devices, as long as the tuple (\mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{686}, \mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{686}, \mdline{686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{686}) is +unique among live controllers, as defined below. For each (\mdline{687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{687}, +\mdline{688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{688}) that the controller wishes to control, it establishes a +\mdline{689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{689} with the P4Runtime server responsible for that device, and +sends a \mdline{690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{690} message containing that tuple of +(\mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{691}, \mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{691}, \mdline{691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{691}) values. The P4Runtime server selects a +primary independently for each (\mdline{692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{692}, \mdline{692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{692}) pair. The primary is the +client that has the highest \mdline{693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{693} that the device has ever received +for the same (\mdline{694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{694}, \mdline{694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{694}) values. A connection between a controller +instance and a device id\mdline{695} \mdline{695}\textemdash{}\mdline{695} which involves a persistent \mdline{695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{695} \mdline{695}\textemdash{}\mdline{695} +can be referred to as a P4Runtime client.%mdk + +%mdk-data-line={698} +\mdline{698}Note that the P4Runtime server does not assign a \mdline{698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{698} or \mdline{698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{698} to +any controller. It is up to an arbitration mechanism outside of the server to +decide on the controller roles, and the \mdline{700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{700} values used for each +\mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{701}. The P4Runtime server only keeps track of the (\mdline{701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{701}, +\mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{702}, \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{702}) of each \mdline{702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{702} that has sent a successful +\mdline{703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{703} message, and maintains the invariant that all such +3-tuples are unique among live controllers. A server must use all three of +these values from a \mdline{705}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{705} message to identify which client is making +the \mdline{706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{706}, not only the \mdline{706}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{706}. This enables controllers to +re-use the same numeric \mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{707} values across different (\mdline{707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{707}, +\mdline{708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{708}) pairs. P4Runtime does not require \mdline{708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{708} values be reused +across such different (\mdline{709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{709}, \mdline{709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{709}) pairs; it allows it.%mdk%mdk + +%mdk-data-line={711} +\item{} +%mdk-data-line={711} +\mdline{711}To start a controller session, a controller first opens a bidirectional stream +channel to the server via the \mdline{712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{712} RPC for each device. This stream +will be used for two purposes:%mdk + +%mdk-data-line={715} +\begin{itemize}%mdk + +%mdk-data-line={715} +\item{} +%mdk-data-line={715} +\mdline{715}\textbf{Session management:}\mdline{715} As soon as the controller opens the stream +channel, it sends a \mdline{716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{716} message to the switch. The +controller populates the \mdline{717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{717} field in this message +using its \mdline{718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{718} and \mdline{718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{718}, as well as the \mdline{718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{718} of the +device. Note that the \mdline{719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{719} field in the \mdline{719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{719} is +not populated by the controller. This field is populated by the P4Runtime +server when it sends a response back to the client, as explained below.%mdk%mdk + +%mdk-data-line={723} +\item{} +%mdk-data-line={723} +\mdline{723}\textbf{Streaming of notifications (e.g. digests) and packet I/O:}\mdline{723} The same +streaming channel will be used for streaming notifications, as well as for +packet-in and packet-out messages. Note that unless specified otherwise by +the role definitions, only the primary controller can participate in +packet I/O. This feature is explained in more details in the\mdline{727}~\mdref{sec-packet-i_o}{Packet +I/O}\mdline{728} section.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={730} +\mdline{730}Note that a controller session is only required if the controller wants to do +Packet I/O, or modify the forwarding state.%mdk%mdk + +%mdk-data-line={733} +\item{} +%mdk-data-line={733} +\mdline{733}Note that the stream is opened per device. In case a switching platform has +multiple devices (\mdline{734}e.g.\mdline{734} multi-ASIC line card) which are all controlled via the +same P4Runtime server, it is possible to have different primary clients for +different devices. In this case, it is the responsibility of the P4Runtime +server to keep track of the primary for each device (and role). More +specifically, the P4Runtime server will know which stream corresponds to the +primary controller for each pair of (\mdline{739}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{739}, \mdline{739}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{739}) at any point of +time.%mdk%mdk + +%mdk-data-line={742} +\item{} +%mdk-data-line={742} +\mdline{742}The streaming channel between the controller and the server defines the +liveness of the controller session. The controller is considered \mdline{743}\textquotedblleft{}offline\textquotedblright{}\mdline{743}, +\mdline{744}\textquotedblleft{}disconnected\textquotedblright{}\mdline{744}, or \mdline{744}\textquotedblleft{}dead\textquotedblright{}\mdline{744} as soon as its stream channel to the switch is +broken. When a primary channel gets broken:%mdk + +%mdk-data-line={747} +\begin{enumerate}%mdk + +%mdk-data-line={747} +\item{} +%mdk-data-line={747} +\mdline{747}An advisory message is sent to all other controllers for that \mdline{747}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{747} +and \mdline{748}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{748}, as described in a +\mdline{749}\mdref{sec-arbitration-notification}{later section}\mdline{749}; and%mdk%mdk + +%mdk-data-line={751} +\item{} +%mdk-data-line={751} +\mdline{751}The P4Runtime server will be without a primary controller, until a client +sends a successful \mdline{752}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{752} (as per the rules in a +\mdline{753}\mdref{sec-arbitration-updates}{later section}\mdline{753}).%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={755} +\item{} +%mdk-data-line={755} +\mdline{755}The mechanism through which the controller receives the P4Runtime server +details are implementation specific and beyond the scope of this +specification. This includes the \mdline{757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{757}, \mdline{757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip}}}\mdline{757} and \mdline{757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{757}, as +well as the Forwarding Pipeline Config. Similarly, the mechanism through +which the P4Runtime server receives its switch config (which notably includes +the \mdline{760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{760}) is beyond the scope of this specification. Nevertheless, if +the server details or switch config are transferred via the network, it is +recommended to use TLS or similar encryption and authentication mechanisms to +prevent eavesdropping attacks.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={765} +\noindent\mdline{765}gRPC enables the server to identify which client originated each message in the +\mdline{766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{766} stream. For example, the C++ gRPC library\mdline{766}~[\mdcite{grpcstreamc}{12}]\mdline{766} in +synchronous mode enables a server process to cause a function to be called when +a new client creates a \mdline{768}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{768} stream. This function should not return +until the stream is closed and the server has completed any cleanup required +when a \mdline{770}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{770} is closed normally (or broken, \mdline{770}e.g.\mdline{770} because a client +process unexpectedly terminated). Thus the server can easily associate all +\mdline{772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{772} messages received from the same client, because they are +processed within the context of the same function call.%mdk + +%mdk-data-line={775} +\mdline{775}A P4Runtime implementation need not rely on the gRPC library providing +information with unary RPC messages that identify which client they came from. +Unary RPC messages include requests to write table entries in the data plane, or +read state from the data plane, among others described later. P4Runtime relies +on clients identifying themselves in every write request, by including the +values \mdline{780}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{780}, \mdline{780}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{780}, and \mdline{780}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{780} in all write requests. The +server trusts clients not to use a triple of values other than their own in +their write requests. gRPC provides authentication methods\mdline{782}~[\mdcite{grpcauth}{10}]\mdline{782} that +should be deployed to prevent untrusted clients from creating channels, and thus +from making changes or even reading the state of the server.%mdk + +%mdk-data-line={786} +\subsection{\mdline{786}5.1.\hspace*{0.5em}\mdline{786}Default Role}\label{sec-default-role}%mdk%mdk + +%mdk-data-line={788} +\noindent\mdline{788}A controller can omit the role message in \mdline{788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{788}. This +implies the \mdline{789}\textquotedblleft{}default role\textquotedblright{}\mdline{789}, which corresponds to \mdline{789}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{789}. +This also implies that a default role has a \mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role\_id}}}\mdline{790} of \mdline{790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}""}}}\mdline{790} (default). +If using a default role, all RPCs from the controller (\mdline{791}e.g.\mdline{791} \mdline{791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{791}) must +leave the \mdline{792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{792} unset.%mdk + +%mdk-data-line={794} +\subsection{\mdline{794}5.2.\hspace*{0.5em}\mdline{794}Role Config}\label{sec-arbitration-role-config}%mdk%mdk + +%mdk-data-line={796} +\noindent\mdline{796}The \mdline{796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{796} field in the \mdline{796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{796} message sent by the +controller describes the role configuration, \mdline{797}i.e.\mdline{797} which operations are in the +scope of a given role. In particular, the definition of a role may include the +following:%mdk + +%mdk-data-line={801} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={801} +\item\mdline{801}A list of P4 entities for which the controller may issue \mdline{801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{801} updates and +receive notification messages (\mdline{802}e.g.\mdline{802} \mdline{802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{802} and +\mdline{803}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{803}).%mdk + +%mdk-data-line={804} +\item\mdline{804}Whether the controller is able to receive \mdline{804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{804} messages, along with a +filtering mechanism based on the values of the \mdline{805}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{805} fields to +select which \mdline{806}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{806} messages should be sent to the controller.%mdk + +%mdk-data-line={807} +\item\mdline{807}Whether the controller is able to send \mdline{807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{807} messages, along with a +filtering mechanism based on the values of the \mdline{808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{808} fields to +select which \mdline{809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{809} messages are allowed to be sent by the controller.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={811} +\noindent\mdline{811}An unset \mdline{811}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{811} implies \mdline{811}\textquotedblleft{}full pipeline access\textquotedblright{}\mdline{811} (similar to the default +role explained above). In order to support different role definition schemes, +\mdline{813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{813} is defined as an \mdline{813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{813} Protobuf message\mdline{813}~[\mdcite{protoany}{37}]\mdline{813}. Such schemes +are out-of-scope of this document. When partitioning of the control plane is +desired, the P4Runtime client(s) and server need to agree on a role definition +scheme in an out-of-band fashion.%mdk + +%mdk-data-line={818} +\mdline{818}It is the job of the P4Runtime server to remember the \mdline{818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{818} for every +\mdline{819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{819} and \mdline{819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{819} pair.%mdk + +%mdk-data-line={821} +\subsection{\mdline{821}5.3.\hspace*{0.5em}\mdline{821}Rules for Handling \mdline{821}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{821} Messages Received from Controllers}\label{sec-arbitration-updates}%mdk%mdk + +%mdk-data-line={823} +\begin{enumerate}%mdk + +%mdk-data-line={823} +\item{} +%mdk-data-line={823} +\mdline{823}If the \mdline{823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{823} message is received for the first time on +this particular channel (\mdline{824}i.e.\mdline{824} for a newly connected controller):%mdk + +%mdk-data-line={826} +\begin{enumerate}%mdk + +%mdk-data-line={826} +\item{} +%mdk-data-line={826} +\mdline{826}If \mdline{826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{826} does not match any of the devices known to the P4Runtime +server, the server shall terminate the stream by returning a +\mdline{828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{828} error.%mdk%mdk + +%mdk-data-line={830} +\item{} +%mdk-data-line={830} +\mdline{830}If the \mdline{830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{830} is set and is already used by another live +controller for the same (\mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{831}, \mdline{831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{831}), the P4Runtime server shall +terminate the stream by returning an \mdline{832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{832} error.%mdk%mdk + +%mdk-data-line={834} +\item{} +%mdk-data-line={834} +\mdline{834}If \mdline{834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{834} does not match the \mdline{834}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{834} scheme previously +agreed upon, the server must return an \mdline{835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{835} error.%mdk%mdk + +%mdk-data-line={837} +\item{} +%mdk-data-line={837} +\mdline{837}If the number of open streams for the given (\mdline{837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{837}, \mdline{837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{837}) +exceeds the supported limit, the P4Runtime server shall terminate the +stream by returning a \mdline{839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{839} error.%mdk%mdk + +%mdk-data-line={841} +\item{} +%mdk-data-line={841} +\mdline{841}Otherwise, the controller is added to a list of live controllers for +the given (\mdline{842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{842}, \mdline{842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{842}) and the server remembers the +controllers \mdline{843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{843}, \mdline{843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{843} and \mdline{843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{843} for this gRPC +channel. See below for the rules to determine if this controller becomes +a primary or backup, and what notifications are sent as a consequence.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={847} +\item{} +%mdk-data-line={847} +\mdline{847}Otherwise, if the \mdline{847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{847} message is received from an +already live controller:%mdk + +%mdk-data-line={850} +\begin{enumerate}%mdk + +%mdk-data-line={850} +\item{} +%mdk-data-line={850} +\mdline{850}If the \mdline{850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{850} does not match the one already assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{852} error.%mdk%mdk + +%mdk-data-line={854} +\item{} +%mdk-data-line={854} +\mdline{854}If the \mdline{854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{854} does not match the current \mdline{854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{854} assigned to this +stream, the P4Runtime server shall terminate the stream by returning a +\mdline{856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{856} error. If the controller wishes to change its role, +it must close the current stream channel and open a new one.%mdk%mdk + +%mdk-data-line={859} +\item{} +%mdk-data-line={859} +\mdline{859}If \mdline{859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{859} does not match the \mdline{859}\textquotedblleft{}out-of-band\textquotedblright{}\mdline{859} scheme previously +agreed upon, the server must return an \mdline{860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{860} error.%mdk%mdk + +%mdk-data-line={862} +\item{} +%mdk-data-line={862} +\mdline{862}If the \mdline{862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{862} is set and is already used by another live +controller (excluding the controller making the request) for the same +(\mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{864}, \mdline{864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{864}), the P4Runtime server shall terminate the stream +by returning an \mdline{865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{865} error.%mdk%mdk + +%mdk-data-line={867} +\item{} +%mdk-data-line={867} +\mdline{867}Otherwise, the server updates the \mdline{867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{867} it has stored for this +controller. This change might cause a change in the primary client (this +controller might become primary, or the controller might have downgraded +itself to a backup, see below), as well as notifications being sent to +one or more controllers.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={873} +\noindent\mdline{873}If the \mdline{873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{873} is accepted by either of the two steps above +(cases 1.5. and 2.5. above), then the server determines if there are changes in +the primary client. Let \mdline{875}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{875} be the highest election ID the server +has ever seen for the given \mdline{876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{876} and \mdline{876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{876} (including the one of the +current primary if there is one).%mdk + +%mdk-data-line={879} +\begin{enumerate}%mdk + +%mdk-data-line={879} +\item{} +%mdk-data-line={879} +\mdline{879}If \mdline{879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{879} is greater than or equal to \mdline{879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{879}, then the +controller becomes, or stays, primary. The server updates the role +configuration to \mdline{881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{881} for the given \mdline{881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{881}. Furthermore:%mdk + +%mdk-data-line={883} +\begin{enumerate}%mdk + +%mdk-data-line={883} +\item{} +%mdk-data-line={883} +\mdline{883}If there was no primary for this \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{883} and \mdline{883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{883} before and +there are no \mdline{884}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{884} requests still processing from a previous primary, +then the server immediately sends an advisory notification to all +controllers for this \mdline{886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{886} and \mdline{886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{886}. See the +\mdline{887}\mdref{sec-arbitration-notification}{following section}\mdline{887} for the format of the +advisory message.%mdk%mdk + +%mdk-data-line={890} +\item{} +%mdk-data-line={890} +\mdline{890}If there was a previous primary, including this controller, or \mdline{890}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{890} +requests in flight, then the server carries out the following steps +(in this order):%mdk + +%mdk-data-line={894} +\begin{enumerate}%mdk + +%mdk-data-line={894} +\item{} +%mdk-data-line={894} +\mdline{894}The server stops accepting \mdline{894}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{894} requests from the previous primary +(if there is one). At this point, the server will reject all \mdline{895}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{895} +requests with \mdline{896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{896}.%mdk%mdk + +%mdk-data-line={898} +\item{} +%mdk-data-line={898} +\mdline{898}The server notifies all controllers other than the new primary client +of the change by sending the advisory notification described in +the\mdline{900}~\mdref{sec-arbitration-notification}{following section}\mdline{900}.%mdk%mdk + +%mdk-data-line={902} +\item{} +%mdk-data-line={902} +\mdline{902}The server will finish processing any \mdline{902}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{902} requests that have +already started. If there are errors, they are reported as usual to +the previous primary. If the previous primary has already +disconnected, any possible errors are dropped and not reported.%mdk%mdk + +%mdk-data-line={907} +\item{} +%mdk-data-line={907} +\mdline{907}The server now accepts the current controller as the new primary, +thus accepting \mdline{908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{908} requests from this controller. The server +updates the highest election ID (\mdline{909}i.e.\mdline{909} \mdline{909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id\_past}}}\mdline{909}) it has seen +for this \mdline{910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{910} and \mdline{910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{910} to \mdline{910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{910}.%mdk%mdk + +%mdk-data-line={912} +\item{} +%mdk-data-line={912} +\mdline{912}The server notifies the new primary by sending the advisory message +described in the\mdline{913}~\mdref{sec-arbitration-notification}{following section}\mdline{913}.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={915} +\item{} +%mdk-data-line={915} +\mdline{915}Otherwise, the controller becomes a backup. If the controller was previously +a primary (and downgraded itself), then an advisory message is sent to all +controllers for this \mdline{917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{917} and \mdline{917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{917}. Otherwise, the advisory +message is only sent to the controller that sent the initial +\mdline{919}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{919}. See the +\mdline{920}\mdref{sec-arbitration-notification}{following section}\mdline{920} for the format of the +advisory message.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={923} +\subsection{\mdline{923}5.4.\hspace*{0.5em}\mdline{923}Client Arbitration Notifications}\label{sec-arbitration-notification}%mdk%mdk + +%mdk-data-line={925} +\noindent\mdline{925}For any given \mdline{925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{925} and \mdline{925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{925}, any time a new primary is chosen, a +primary downgrades its status to a backup, a primary disconnects, or the +\mdline{927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{927} is updated by the primary, all controllers for that +(\mdline{928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{928}, \mdline{928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{928}) are informed of this by sending a +\mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{929}. The \mdline{929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{929} is populated as follows:%mdk + +%mdk-data-line={931} +\begin{itemize}%mdk + +%mdk-data-line={931} +\item{} +%mdk-data-line={931} +\mdline{931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{931} and \mdline{931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{931} as given.%mdk%mdk + +%mdk-data-line={933} +\item{} +%mdk-data-line={933} +\mdline{933}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role.config}}}\mdline{933} is set to the role configuration the server received most +recently in a \mdline{934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{934} from a primary.%mdk%mdk + +%mdk-data-line={936} +\item{} +%mdk-data-line={936} +\mdline{936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{936} is populated as follows:%mdk + +%mdk-data-line={938} +\begin{itemize}%mdk + +%mdk-data-line={938} +\item{} +%mdk-data-line={938} +\mdline{938}If there has not been any primary at all, the election\mdline{938}\_\mdline{938}id is left unset.%mdk%mdk + +%mdk-data-line={940} +\item{} +%mdk-data-line={940} +\mdline{940}Otherwise, \mdline{940}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{940} is set to the highest election ID that the server +has seen for this \mdline{941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{941} and \mdline{941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{941} (which is the \mdline{941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{941} of +the current primary if there is any).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={944} +\item{} +%mdk-data-line={944} +\mdline{944}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{944} is set differently based on whether the notification is sent to the +primary or a backup controller:%mdk + +%mdk-data-line={947} +\begin{itemize}%mdk + +%mdk-data-line={947} +\item{} +%mdk-data-line={947} +\mdline{947}If there is a primary:%mdk + +%mdk-data-line={949} +\begin{itemize}%mdk + +%mdk-data-line={949} +\item{} +%mdk-data-line={949} +\mdline{949}For the primary, \mdline{949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{949} is OK (with \mdline{949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{949} set to +\mdline{950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.OK}}}\mdline{950}).%mdk%mdk + +%mdk-data-line={952} +\item{} +%mdk-data-line={952} +\mdline{952}For all backup controllers, \mdline{952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{952} is set to non-OK (with +\mdline{953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{953} set to \mdline{953}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.ALREADY\_EXISTS}}}\mdline{953}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={955} +\item{} +%mdk-data-line={955} +\mdline{955}Otherwise, if there is no primary currently, for all backup controllers, +\mdline{956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{956} is set to non-OK (with \mdline{956}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status.code}}}\mdline{956} set to +\mdline{957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.NOT\_FOUND}}}\mdline{957}).%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={959} +\noindent\mdline{959}Note that on primary client changes with outstanding \mdline{959}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{959} request, some +notifications might be delayed, see the +\mdline{961}\mdref{sec-arbitration-updates}{previous section}\mdline{961} for details.%mdk + +%mdk-data-line={963} +\section{\mdline{963}6.\hspace*{0.5em}\mdline{963}The P4Info Message}\label{sec-the-p4info-message}%mdk%mdk + +%mdk-data-line={965} +\noindent\mdline{965}The purpose of P4Info was described under +\mdline{966}\mdref{sec-reference-architecture}{Reference Architecture}\mdline{966}. +Here we describe the various +components.%mdk + +%mdk-data-line={970} +\subsection{\mdline{970}6.1.\hspace*{0.5em}\mdline{970}Common Messages}\label{sec-common-messages}%mdk%mdk + +%mdk-data-line={972} +\noindent\mdline{972}These messages appear nested within many other messages.%mdk + +%mdk-data-line={974} +\subsubsection{\mdline{974}6.1.1.\hspace*{0.5em}\mdline{974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{974} Message}\label{sec-documentation-message}%mdk%mdk + +%mdk-data-line={976} +\noindent\mdline{976}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{976} is used to carry both brief and long descriptions of something. +Good content within a documentation field is extremely helpful to P4Runtime +application developers.%mdk + +%mdk-data-line={980} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={981} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Documentation~\{\\ +~~{\mdcolor{darkgreen}//~A~brief~description~of~something,~e.g.~one~sentence}\\ +~~{\bfseries{\mdcolor{navy}string}}~brief~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~A~more~verbose~description~of~something.}\\ +~~{\mdcolor{darkgreen}//~Multiline~is~accepted.~Markup~format~(if~any)~is~TBD.}\\ +~~{\bfseries{\mdcolor{navy}string}}~description~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={990} +\subsubsection{\mdline{990}6.1.2.\hspace*{0.5em}\mdline{990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{990} Message}\label{sec-preamble-message}%mdk%mdk + +%mdk-data-line={992} +\noindent\mdline{992}The preamble serves as the \mdline{992}\textquotedblleft{}descriptor\textquotedblright{}\mdline{992} for each entity and contains the unique +instance ID, name, alias, annotations and documentation.%mdk + +%mdk-data-line={995} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={996} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Preamble~\{\\ +~~{\mdcolor{darkgreen}//~ids~share~the~same~number-space;~e.g.~table~ids~cannot~overlap~with~counter}\\ +~~{\mdcolor{darkgreen}//~ids.~Even~though~this~is~irrelevant~to~this~proto~definition,~the~ids~are}\\ +~~{\mdcolor{darkgreen}//~allocated~in~such~a~way~that~it~is~possible~based~on~an~id~to~deduce~the}\\ +~~{\mdcolor{darkgreen}//~resource~type~(e.g.~table,~action,~counter,~...).~This~means~that~code}\\ +~~{\mdcolor{darkgreen}//~using~these~ids~can~detect~if~the~wrong~resource~type~is~used}\\ +~~{\mdcolor{darkgreen}//~somewhere.~This~also~means~that~ids~of~different~types~can~be~mixed}\\ +~~{\mdcolor{darkgreen}//~(e.g.~direct~resource~list~for~a~table)~without~ambiguity.~Note~that~id~0}\\ +~~{\mdcolor{darkgreen}//~is~reserved~and~means~"invalid~id".}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name~of~the~P4~object,~e.g.~c1.c2.ipv4\_lpm}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~an~alias~(alternative~name)~for~the~P4~object,~probably~shorter~than~its}\\ +~~{\mdcolor{darkgreen}//~fully~qualified~name.~The~only~constraint~is~for~it~to~be~unique~with}\\ +~~{\mdcolor{darkgreen}//~respect~to~other~P4~objects~of~the~same~type.~By~default,~the~compiler~uses}\\ +~~{\mdcolor{darkgreen}//~the~shortest~suffix~of~the~name~that~uniquely~identifies~the~object.~For}\\ +~~{\mdcolor{darkgreen}//~example~if~the~P4~program~contains~two~tables~with~names~s.c1.t~and~s.c2.t,}\\ +~~{\mdcolor{darkgreen}//~the~default~aliases~will~respectively~be~c1.t~and~c2.t.~In~the~future,~the}\\ +~~{\mdcolor{darkgreen}//~P4~programmer~may~also~be~able~to~override~the~default~alias~for~any~P4}\\ +~~{\mdcolor{darkgreen}//~object~(TBD).}\\ +~~{\bfseries{\mdcolor{navy}string}}~alias~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~Optional.~If~present,~the~location~of~`annotations{}[i]`~is~given~by}\\ +~{\mdcolor{darkgreen}//~`annotation\_locations{}[i]`.}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~SourceLocation~annotation\_locations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~Documentation~of~the~entity}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1027} +\subsubsection{\mdline{1027}6.1.3.\hspace*{0.5em}\mdline{1027}Annotating P4 Entities with \mdline{1027}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}}\label{sec-annotating-p4-entities-with-documentation}%mdk%mdk + +%mdk-data-line={1029} +\noindent\mdline{1029}P4 entities may be annotated using the following annotations:%mdk + +%mdk-data-line={1031} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1032} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}(string...)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}(string...)}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1036} +\noindent\mdline{1036}Attaching either or both of these annotations to an entity will generate a +P4Info\mdline{1037}~\mdref{sec-documentation-message}{Documentation Message}\mdline{1037}, which in turn will +appear in the\mdline{1038}~\mdref{sec-preamble-message}{Preamble Message}\mdline{1038} for the entity.%mdk + +%mdk-data-line={1040} +\mdline{1040}The P4 compiler should not emit \mdline{1040}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation}}}\mdline{1040} messages in the P4Info for these +specific cases; instead, it should generate the \mdline{1041}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1041} messages as +described.%mdk + +%mdk-data-line={1044} +\mdline{1044}The following example shows documentation annotations for a \mdline{1044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table}}}\mdline{1044} entity:%mdk + +%mdk-data-line={1046} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1047} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("Match~IPv4~addresses~to~next-hop~MAC~and~port.~\textbackslash{}}\\ +Uses~LPM~match~{\bfseries{\mdcolor{navy}type}}.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}table~my\_ipv4\_lkup~\{}\\ +{\mdcolor{maroon}~~...}\\ +{\mdcolor{maroon}\}}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1055} +\subsubsection{\mdline{1055}6.1.4.\hspace*{0.5em}\mdline{1055}Structured Annotations}\label{sec-structured-annotations}%mdk%mdk + +%mdk-data-line={1057} +\noindent\mdline{1057}P4 supports both unstructured and structured annotations\mdline{1057}~[\mdcite{p4annotations}{17}]\mdline{1057}. +Unstructured annotations of the form \mdline{1058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno1}}}\mdline{1058} or \mdline{1058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno2(body-content)}}}\mdline{1058} can +either be empty, or contain free-form content; anything between the pair of +matched parentheses is legal. Conversely, structured annotations of the form +\mdline{1061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno3{}[]}}}\mdline{1061} or \mdline{1061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyAnno4{}[kvList\textbar{}expressionList]}}}\mdline{1061} have a more prescribed syntax, +which allows declaring key-value lists or expression lists. Both unstructured +and structured annotations may be used simultaneously on a P4 element and +P4Info supports this.%mdk + +%mdk-data-line={1066} +\mdline{1066}The annotations described up to this point, \mdline{1066}e.g.\mdline{1066} \mdline{1066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief()}}}\mdline{1066}, have all been +unstructured annotations, or simply annotations. These are represented in +P4Info as \mdline{1068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1068} fields in the various \mdline{1068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{1068}s. +Similarly, structured annotations are represented in \mdline{1069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated\\ +StructuredAnnotation~structured\_annotations}}}\mdline{1070} fields which are siblings to the +unstructured \mdline{1071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1071}. The \mdline{1071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations}}}\mdline{1071} contain parsed +representations of the original annotation source. This parsing includes +expression-evaluation, so the resulting P4Info may contain a simplified +replica of the original structured annotations.%mdk + +%mdk-data-line={1076} +\mdline{1076}The structured annotation messages are defined in p4types.proto.%mdk + +%mdk-data-line={1078} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1079} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~KeyValuePair~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~key~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Expression~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~KeyValuePairList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~KeyValuePair~kv\_pairs~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Expression~\{\\ +~~{\bfseries{\mdcolor{navy}oneof}}~value~\{\\ +~~~~{\bfseries{\mdcolor{navy}string}}~string\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~{\bfseries{\mdcolor{navy}int64}}~int64\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~{\bfseries{\mdcolor{navy}bool}}~bool\_value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~ExpressionList~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Expression~expressions~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~StructuredAnnotation~\{\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}oneof}}~body~\{\\ +~~~~ExpressionList~expression\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~KeyValuePairList~kv\_pair\_list~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~Optional.~Location~of~the~'@'~symbol~of~this~annotation~in~the~source~code.}\\ +~~SourceLocation~source\_location~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1111} +\noindent\mdline{1111}The \mdline{1111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1111} message can represent either a \mdline{1111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1111} +or an \mdline{1112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExpressionList}}}\mdline{1112}.%mdk + +%mdk-data-line={1114} +\mdline{1114}The type of an expression is intentionally limited to one of the following +base types: string literal, 64-bit signed integer, or boolean. The \mdline{1115}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{1115} +compiler frontend which generates P4Info will evaluate all expressions and +simplify them to one of the valid types. Any expressions which don\mdline{1117}'\mdline{1117}t match one +of the valid types will generate an error. For integers exceeding 64 bits, +besides issuing an error, the compiler \mdline{1119}\emph{may}\mdline{1119} print a suggestion to use a +string representation, and the P4Info consumer may perform any necessary +conversions.%mdk + +%mdk-data-line={1123} +\mdline{1123}The following invariants hold:%mdk + +%mdk-data-line={1125} +\begin{enumerate}%mdk + +%mdk-data-line={1125} +\item{} +%mdk-data-line={1125} +\mdline{1125}For any P4 entity, there are no two \mdline{1125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1125}s that have the +same name.%mdk%mdk + +%mdk-data-line={1128} +\item{} +%mdk-data-line={1128} +\mdline{1128}Within a \mdline{1128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePairList}}}\mdline{1128}, there are no two \mdline{1128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}KeyValuePair}}}\mdline{1128}s that have the +same \mdline{1129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key.}}}\mdline{1129}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1131} +\paragraph{\mdline{1131}6.1.4.1.\hspace*{0.5em}\mdline{1131}Structured Annotation Examples}\label{sec-structured-annotation-examples}%mdk%mdk + +%mdk-data-line={1133} +\noindent\mdline{1133}We omit the \mdline{1133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}source\_location}}}\mdline{1133} field in the following examples.%mdk + +%mdk-data-line={1135} +\mdline{1135}\textbf{Empty Expression List}\mdline{1135}%mdk + +%mdk-data-line={1137} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1138} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}Empty}{\mdcolor{maroon}{}[]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1144} +\noindent\mdline{1144}The generated P4Info will contain the following.%mdk + +%mdk-data-line={1146} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1147} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}Empty}{\mdcolor{maroon}"}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1152} +\noindent\mdline{1152}\textbf{Mixed Expression List}\mdline{1152}%mdk + +%mdk-data-line={1154} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1155} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~TEXT\_CONST~"hello"}\\ +{\mdcolor{navy}\#}{\mdcolor{navy}define}{\mdcolor{maroon}~NUM\_CONST~6}\\ +{\mdcolor{gray}@}{\mdcolor{gray}MixedExprList}{\mdcolor{maroon}{}[1,TEXT\_CONST,true,1==2,5+NUM\_CONST]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1163} +\noindent\mdline{1163}The generated P4Info will contain:%mdk + +%mdk-data-line={1165} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1166} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedExprList}{\mdcolor{maroon}"}\\ +~~expression\_list~\{\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}1}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}hello}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~true\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~bool\_value:~false\\ +~~~~\}\\ +~~~~expressions~\{\\ +~~~~~~int64\_value:~{\mdcolor{purple}11}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1188} +\noindent\mdline{1188}\textbf{kvList of Mixed Expressions}\mdline{1188}%mdk + +%mdk-data-line={1190} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1191} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}MixedKV}{\mdcolor{maroon}{}[label="text",~my\_bool=true,~int\_val=2*3]}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1197} +\noindent\mdline{1197}The generated P4Info will contain:%mdk + +%mdk-data-line={1199} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1200} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}structured\_annotations~\{\\ +~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}MixedKV}{\mdcolor{maroon}"}\\ +~~kv\_pair\_list~\{\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}label}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~string\_value:~{\mdcolor{maroon}"}{\mdcolor{maroon}text}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}my\_bool}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~bool\_value:~true\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~kv\_pairs~\{\\ +~~~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}int\_val}{\mdcolor{maroon}"}\\ +~~~~~~value~\{\\ +~~~~~~~~int64\_value:~{\mdcolor{purple}6}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1225} +\subsubsection{\mdline{1225}6.1.5.\hspace*{0.5em}\mdline{1225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1225} Message}\label{sec-sourcelocation-message}%mdk%mdk + +%mdk-data-line={1227} +\noindent\mdline{1227}A source location describes a location within a \mdline{1227}\emph{.p4}\mdline{1227}-source file. The +\mdline{1228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1228} message is defined in p4types.proto as follows:%mdk + +%mdk-data-line={1230} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1231} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Location~of~code~relative~to~a~given~source~file.}\\ +{\bfseries{\mdcolor{navy}message}}~SourceLocation~\{\\ +~~{\mdcolor{darkgreen}//~Path~to~the~source~file~(absolute~or~relative~to~the~working~directory).}\\ +~~{\bfseries{\mdcolor{navy}string}}~file~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~Line~and~column~numbers~within~the~source~file,~1-based.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~line~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}int32}}~column~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1241} +\noindent\mdline{1241}We provide source locations for structured and unstructured annotations. This +information may be useful when annotations require further parsing or +processing, as it allows tools to point out the precise source of errors for +invalid annotations.%mdk + +%mdk-data-line={1246} +\mdline{1246}The \mdline{1246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation}}}\mdline{1246} message associated with an annotation holds the location of +the \mdline{1247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@}}}\mdline{1247} symbol introducing the annotation in the P4 source code; the message can +be found in the following place:%mdk + +%mdk-data-line={1250} +\begin{itemize}%mdk + +%mdk-data-line={1250} +\item{} +%mdk-data-line={1250} +\mdline{1250}For \mdline{1250}\textbf{unstructured annotations}\mdline{1250}, every message containing a field +\mdline{1251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~string~annotations}}}\mdline{1251} also contains a field +\mdline{1252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}repeated~SourceLocation~annotation\_locations}}}\mdline{1252}. The field must either be empty + or match the size of \mdline{1253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1253}. In the latter case, the i-th member of +\mdline{1254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotation\_locations}}}\mdline{1254} is the source location of the i-th member of +\mdline{1255}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1255}.%mdk%mdk + +%mdk-data-line={1257} +\item{} +%mdk-data-line={1257} +\mdline{1257}For \mdline{1257}\textbf{structured annotations}\mdline{1257}, every \mdline{1257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StructuredAnnotation}}}\mdline{1257} message contains +an optional field \mdline{1258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SourceLocation~source\_location}}}\mdline{1258} holding its source +location, if present.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1262} +\subsection{\mdline{1262}6.2.\hspace*{0.5em}\mdline{1262}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1262} Message}\label{sec-pkginfo-message}%mdk%mdk + +%mdk-data-line={1264} +\noindent\mdline{1264}The \mdline{1264}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1264} message contains package-level metadata which describes the +overall P4 program itself, as opposed to P4 entities. \mdline{1265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1265} can be extracted +and used to facilitate \mdline{1266}\textquotedblleft{}browsing\textquotedblright{}\mdline{1266} of available P4 programs from a +library. Although all fields are technically \mdline{1267}\textquotedblleft{}optional,\textquotedblright{}\mdline{1267} every implementation +should include as a minimum the name, version, doc and arch fields. The other +fields are recommended to be included.%mdk + +%mdk-data-line={1271} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1272} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Can~be~used~to~manage~multiple~P4~packages.}\\ +{\bfseries{\mdcolor{navy}message}}~PkgInfo~\{\\ +~~{\mdcolor{darkgreen}//~a~definitive~name~for~this~configuration,~e.g.~switch.p4\_v1.0}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~configuration~version,~free-format~string}\\ +~~{\bfseries{\mdcolor{navy}string}}~version~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~brief~and~detailed~descriptions}\\ +~~Documentation~doc~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~free-form;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~{\bfseries{\mdcolor{navy}string}}~annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\mdcolor{darkgreen}//~Optional.~If~present,~the~location~of~`annotations{}[i]`~is~given~by}\\ +~~{\mdcolor{darkgreen}//~`annotation\_locations{}[i]`.}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~SourceLocation~annotation\_locations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}10};\\ +~~{\mdcolor{darkgreen}//~the~target~architecture,~e.g.~"psa"}\\ +~~{\bfseries{\mdcolor{navy}string}}~arch~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~{\mdcolor{darkgreen}//~organization~which~produced~the~configuration,~e.g.~"p4.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~organization~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~{\mdcolor{darkgreen}//~contact~info~for~support,e.g.~"tech-support@acme.org"}\\ +~~{\bfseries{\mdcolor{navy}string}}~contact~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}7};\\ +~~{\mdcolor{darkgreen}//~url~for~more~information,~e.g.~"http://support.p4.org/ref/p4/switch.p4\_v1.0"}\\ +~~{\bfseries{\mdcolor{navy}string}}~url~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}8};\\ +~~{\mdcolor{darkgreen}//~Miscellaneous~metadata,~structured;~a~way~to~extend~PkgInfo}\\ +~~{\bfseries{\mdcolor{navy}repeated}}~StructuredAnnotation~structured\_annotations~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}9};\\ +~~{\mdcolor{darkgreen}//~If~set,~specifies~the~properties~that~the~underlying~platform~should~have.}\\ +~~{\mdcolor{darkgreen}//~If~the~platform~does~not~conform~to~these~properties,~the~server~should}\\ +~~{\mdcolor{darkgreen}//~reject~the~P4Info~when~used~with~a~SetForwardingPipelineConfigRequest.}\\ +~~PlatformProperties~platform\_properties~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}11};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1302} +\noindent\mdline{1302}where the \mdline{1302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PlatformProperties}}}\mdline{1302} message looks as follows:%mdk + +%mdk-data-line={1303} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1304} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Used~to~describe~the~required~properties~of~the~underlying~platform.}\\ +{\bfseries{\mdcolor{navy}message}}~PlatformProperties~\{\\ +~~{\mdcolor{darkgreen}//~The~minimum~number~of~multicast~entries~(i.e.~multicast~groups)~that~the}\\ +~~{\mdcolor{darkgreen}//~platform~is~required~to~support.~If~0,~there~are~no~requirements.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~multicast\_group\_table\_size~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~The~minimum~number~of~replicas~that~the~platform~is~required~to~support}\\ +~~{\mdcolor{darkgreen}//~across~all~~groups.~If~0,~there~are~no~requirements.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~multicast\_group\_table\_total\_replicas~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~The~number~of~replicas~that~the~platform~is~required~to~support~per}\\ +~~{\mdcolor{darkgreen}//~group/entry.~If~0,~`multicast\_group\_table\_total\_replicas`~should~be~used.}\\ +~~{\mdcolor{darkgreen}//~Must~be~no~larger~than~`multicast\_group\_table\_total\_replicas`.}\\ +~~{\bfseries{\mdcolor{navy}int32}}~multicast\_group\_table\_max\_replicas\_per\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1319} +\subsubsection{\mdline{1319}6.2.1.\hspace*{0.5em}\mdline{1319}Annotating P4 code with PkgInfo}\label{sec-annotating-p4-code-with-pkginfo}%mdk%mdk + +%mdk-data-line={1321} +\noindent\mdline{1321}A P4 program\mdline{1321}'\mdline{1321}s \mdline{1321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1321} may be declared using one or more of the following +annotations, attached to the \mdline{1322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1322} block only:%mdk + +%mdk-data-line={1324} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1325} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value)}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(key=value{}[,key=value,...])}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("A~brief~description")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("A~longer\textbackslash{}}\\ +description{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@custom\_annotation(...)}\\ +{\mdcolor{maroon}@another\_custom\_annotation(...)}\\ +{\mdcolor{maroon}@platform\_property(key=value)}\\ +{\mdcolor{maroon}@platform\_property(key=value{}[,key=value,...])}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1336} +\noindent\mdline{1336}Above we see several different types of annotations:%mdk + +%mdk-data-line={1338} +\begin{itemize}%mdk + +%mdk-data-line={1338} +\item{} +%mdk-data-line={1338} +\mdline{1338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1338} \mdline{1338}- This is used to populate a specific field within the \mdline{1338}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1338} +message. Multiple \mdline{1339}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1339} annotations are allowed. For compactness, +multiple key-value pairs can appear in a single \mdline{1340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1340} annotation, +separated by commas. Each key must only appear once and the compiler must +reject the program if one appears multiple times. The \mdline{1342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{1342}s must be from +among the message fields inside \mdline{1343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1343}, for example, \mdline{1343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1343}, \mdline{1343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}version}}}\mdline{1343}, +etc. Each key-value pair assigns a value to the corresponding field inside the +single \mdline{1345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1345} message for the program\mdline{1345}'\mdline{1345}s P4Info. One exception is that the +\mdline{1346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1346} field of \mdline{1346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1346} must be expressed as individual +\mdline{1347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1347} and \mdline{1347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1347} annotations, see next bullets. The key \mdline{1347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}arch}}}\mdline{1347} will +be ignored (with a warning) by the compiler. The value for this should come +from the compiler itself.%mdk%mdk + +%mdk-data-line={1351} +\item{} +%mdk-data-line={1351} +\mdline{1351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1351} \mdline{1351}- This will populate the \mdline{1351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.brief}}}\mdline{1351} message field.%mdk%mdk + +%mdk-data-line={1353} +\item{} +%mdk-data-line={1353} +\mdline{1353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1353} \mdline{1353}- This will populate the \mdline{1353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.doc.description}}}\mdline{1353} message +field%mdk%mdk + +%mdk-data-line={1356} +\item{} +%mdk-data-line={1356} +\mdline{1356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@platform\_property}}}\mdline{1356} \mdline{1356}- This is used to populate a specific field within the +\mdline{1357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PlatformProperty}}}\mdline{1357} message in \mdline{1357}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.platform\_property}}}\mdline{1357}. Multiple +\mdline{1358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@platform\_property}}}\mdline{1358} annotations are allowed. For compactness, +multiple key-value pairs can appear in a single \mdline{1359}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@platform\_property}}}\mdline{1359} +annotation, separated by commas. Each key must only appear once and the +compiler must reject the program if one appears multiple times. The \mdline{1361}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}key}}}\mdline{1361}s +must be from among the message fields inside \mdline{1362}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PlatformProperty}}}\mdline{1362}, for example, +\mdline{1363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_table\_size}}}\mdline{1363} or \mdline{1363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_table\_total\_replicas}}}\mdline{1363}. Each +key-value pair assigns a value to the corresponding field inside the single +\mdline{1365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PlatformProperty}}}\mdline{1365} message inside the program\mdline{1365}'\mdline{1365}s P4Info.%mdk%mdk + +%mdk-data-line={1367} +\item{} +%mdk-data-line={1367} +\mdline{1367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@\textless{}anything~else\textgreater{}}}}\mdline{1367} \mdline{1367}- This will create a \mdline{1367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotation}}}\mdline{1367} entry%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1369} +\noindent\mdline{1369}Declaring one or more of these annotations on \mdline{1369}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}main}}}\mdline{1369} will +generate a single corresponding \mdline{1370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1370} message in the P4Info as described in +\mdline{1371}\mdref{sec-pkginfo-message}{PkgInfo Message}\mdline{1371}.%mdk + +%mdk-data-line={1373} +\mdline{1373}The following example shows \mdline{1373}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{1373} annotations using a mixture of single and +multiple key-value pairs. It also shows \mdline{1374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{1374} and \mdline{1374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{1374} annotations, +plus some additional custom annotations. The well-known annotations will produce +corresponding fields inside the \mdline{1376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{1376} message. The custom annotations will +be appended to the \mdline{1377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo.annotations}}}\mdline{1377} list.%mdk + +%mdk-data-line={1379} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1380} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(name="switch.p4",version="2")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(organization="p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(contact="info@p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}pkginfo}{\mdcolor{maroon}(url="www.p4.org")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}brief}{\mdcolor{maroon}("L2/L3~switch")}\\ +{\mdcolor{gray}@}{\mdcolor{gray}description}{\mdcolor{maroon}("L2/L3~switch.\textbackslash{}}\\ +Built~for~data-center~profile.{\mdcolor{maroon}"}{\mdcolor{maroon})}\\ +{\mdcolor{maroon}@my\_annotation1(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}@my\_annotation2(...)~//~Not~well-known,~this~will~appear~in~PkgInfo~annotations}\\ +{\mdcolor{maroon}PSA\_Switch(IgPipeline,~PacketReplicationEngine(),~EgPipeline,}\\ +{\mdcolor{maroon}~~~~~~~~~~~BufferingQueueingEngine())~main;}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1393} +\subsection{\mdline{1393}6.3.\hspace*{0.5em}\mdline{1393}ID Allocation for P4Info Objects}\label{sec-id-allocation}%mdk%mdk + +%mdk-data-line={1395} +\noindent\mdline{1395}P4Info objects receive a unique ID, which is used to identify the object in +P4Runtime messages. IDs are 32-bit unsigned integers which are assigned by the +compiler during the P4Info generation process. IDs are assigned in such a way +that it is possible based on the ID value alone to deduce the type of the object +(\mdline{1399}e.g.\mdline{1399} table, action, counter, \mdline{1399}\dots{}\mdline{1399}). The most significant 8 bits of the ID +encodes the object type (as per Table\mdline{1400}~\mdref{tab-mapping-p4-obj-ids}{\mdcaptionlabel{1}}\mdline{1400}). The +p4info.proto file includes a mapping from object type to 8-bit prefix value, +encoded as an enum definition (\mdline{1402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.P4Ids.Prefix}}}\mdline{1402}). These values must +be used (\mdline{1403}e.g.\mdline{1403} by the compiler) when allocating IDs. The remaining 24 bits must +be generated in such a way that the resulting IDs must be globally unique in +the scope of the P4Info message. Table\mdline{1405}~\mdref{tab-format-p4-obj-ids}{\mdcaptionlabel{2}}\mdline{1405} shows the ID +layout.%mdk + +%mdk-data-line={1408} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1410} 8-bit prefix value}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1410} P4 object type}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{1412} 0x00}&\multicolumn{1}{|l|}{\mdline{1412} Reserved (unspecified)}\\ +\multicolumn{1}{|l}{\mdline{1413} 0x01}&\multicolumn{1}{|l|}{\mdline{1413} Action}\\ +\multicolumn{1}{|l}{\mdline{1414} 0x02}&\multicolumn{1}{|l|}{\mdline{1414} Table}\\ +\multicolumn{1}{|l}{\mdline{1415} 0x03}&\multicolumn{1}{|l|}{\mdline{1415} Value-set}\\ +\multicolumn{1}{|l}{\mdline{1416} 0x04}&\multicolumn{1}{|l|}{\mdline{1416} Controller header (header type with \mdline{1416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1416} annotation)}\\ +\multicolumn{1}{|l}{\mdline{1417} 0x05\mdline{1417}\dots{}\mdline{1417}0x0f}&\multicolumn{1}{|l|}{\mdline{1417} Reserved (for future P4 built-in objects)}\\ +\multicolumn{1}{|l}{\mdline{1418} 0x10}&\multicolumn{1}{|l|}{\mdline{1418} Reserved (start of PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1419} 0x11}&\multicolumn{1}{|l|}{\mdline{1419} PSA Action profiles / selectors}\\ +\multicolumn{1}{|l}{\mdline{1420} 0x12}&\multicolumn{1}{|l|}{\mdline{1420} PSA Counter}\\ +\multicolumn{1}{|l}{\mdline{1421} 0x13}&\multicolumn{1}{|l|}{\mdline{1421} PSA Direct counter}\\ +\multicolumn{1}{|l}{\mdline{1422} 0x14}&\multicolumn{1}{|l|}{\mdline{1422} PSA Meter}\\ +\multicolumn{1}{|l}{\mdline{1423} 0x15}&\multicolumn{1}{|l|}{\mdline{1423} PSA Direct meter}\\ +\multicolumn{1}{|l}{\mdline{1424} 0x16}&\multicolumn{1}{|l|}{\mdline{1424} PSA Register}\\ +\multicolumn{1}{|l}{\mdline{1425} 0x17}&\multicolumn{1}{|l|}{\mdline{1425} PSA Digest}\\ +\multicolumn{1}{|l}{\mdline{1426} 0x18\mdline{1426}\dots{}\mdline{1426}0x7f}&\multicolumn{1}{|l|}{\mdline{1426} Reserved (for future PSA extern types)}\\ +\multicolumn{1}{|l}{\mdline{1427} 0x80}&\multicolumn{1}{|l|}{\mdline{1427} Reserved (start of vendor-specific extern types)}\\ +\multicolumn{1}{|l}{\mdline{1428} 0x81\mdline{1428}\dots{}\mdline{1428}0xfe}&\multicolumn{1}{|l|}{\mdline{1428} Vendor-specific extern types}\\ +\multicolumn{1}{|l}{\mdline{1429} 0xff}&\multicolumn{1}{|l|}{\mdline{1429} Reserved (max prefix value)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1431} +\mdhr{}%mdk + +%mdk-data-line={1432} +\noindent\mdline{1432}\mdcaption{\textbf{Table~\mdcaptionlabel{1}.}~\mdcaptiontext{Mapping of P4Info object type to 8-bit ID prefix value}}%mdk +%mdk +\end{mdcenter}\label{tab-mapping-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1435} +\begin{table}[h!]%mdk +\begin{mdblock}{text-align=center,breakable=true}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{cc}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{1437} MSB bit 31 \mdline{1437}\dots{}\mdline{1437}\dots{}\mdline{1437}.. bit 24}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1437} bit 23 \mdline{1437}\dots{}\mdline{1437}\dots{}\mdline{1437}\dots{}\mdline{1437}\dots{}\mdline{1437}\dots{}\mdline{1437}\dots{}\mdline{1437}\dots{}\mdline{1437}.. bit 0 LSB}}\\ + +\midrule +\multicolumn{1}{|c}{\mdline{1439} Object type prefix}&\multicolumn{1}{|c|}{\mdline{1439} Generated suffix (\mdline{1439}e.g.\mdline{1439} by the compiler)}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1441} +\mdhr{}%mdk + +%mdk-data-line={1442} +\noindent\mdline{1442}\mdcaption{\textbf{Table~\mdcaptionlabel{2}.}~\mdcaptiontext{Format of P4Info object IDs}}%mdk%mdk +\end{mdblock}\label{tab-format-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1446} +\mdline{1446}It is possible to statically set the least-significant 24 bits of the ID in the +P4 program source by annotating the object with \mdline{1447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1447} (see Table +\mdline{1448}\mdref{tab-exmpl-p4-obj-ids}{\mdcaptionlabel{3}}\mdline{1448}). The compiler must honor the \mdline{1448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1448} annotations when +generating the P4Info message and must fail the compilation if +statically-assigned ID suffixes lead to non-unique IDs (\mdline{1450}i.e.\mdline{1450} if the P4 +programmer tries to assign the same ID suffix to two different P4 objects of the +same type by annotating them with the same \mdline{1452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1452} value). Note that it is not +possible for the P4 programmer to change the value of the 8-bit ID prefix, which +encodes the object type. The programmer is free to leave the 8-bit prefix as 0, +in which case the compiler will replace the 0 with the correct value for the +kind of object the annotation is annotating. The programmer may also fill in +the 8-bit prefix with a non-zero value, in which case the compiler will give an +error if the 8-bit prefix does not contain the correct value, or leave it as is +if it is correct.%mdk + +%mdk-data-line={1461} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth-7cm)/1}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{\mdinline{width=7cm}{{\bfseries\mdline{1463} P4 declaration(s)}}}&\multicolumn{1}{|c|}{{\bfseries\mdline{1463} Compiler-allocated ID(s)}}\\ + +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1465} \mdline{1465}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1465}}}&\multicolumn{1}{|l|}{\mdline{1465} 0x0212ab34}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1467} \mdline{1467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1467}}}&\multicolumn{1}{|l|}{\mdline{1467} \mdline{1467}\textbf{Error}\mdline{1467}(same ID suffixes for 2 objects of the same type)}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1468} \mdline{1468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tB...}}}\mdline{1468}}}&\multicolumn{1}{|l|}{\mdline{1468}}\\ +\midrule +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1470} \mdline{1470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~table~tA...}}}\mdline{1470}}}&\multicolumn{1}{|l|}{\mdline{1470} 0x0212ab34}\\ +\multicolumn{1}{|l}{\mdinline{width=7cm}{\mdline{1471} \mdline{1471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id(0x12ab34)~action~act1...}}}\mdline{1471}}}&\multicolumn{1}{|l|}{\mdline{1471} 0x0112ab34}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={1473} +\mdhr{}%mdk + +%mdk-data-line={1474} +\noindent\mdline{1474}\mdcaption{\textbf{Table~\mdcaptionlabel{3}.}~\mdcaptiontext{Example of statically-assigned P4Info object IDs}}%mdk +%mdk +\end{mdcenter}\label{tab-exmpl-p4-obj-ids}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={1477} +\mdline{1477}The \mdline{1477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1477} annotation can also be used to choose the ID for match fields, +action parameters, and packet metadata. In this case, there is no 8-bit prefix +and the programmer is free to choose any 32-bit number. The compiler must fail +if the IDs chosen by the programmer are not unique (within a table, action, or +header, respectively).%mdk + +%mdk-data-line={1483} +\subsection{\mdline{1483}6.4.\hspace*{0.5em}\mdline{1483}P4Info Objects}\label{sec-p4info-objects}%mdk%mdk + +%mdk-data-line={1485} +\subsubsection{\mdline{1485}6.4.1.\hspace*{0.5em}\mdline{1485}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}}\label{sec-table}%mdk%mdk + +%mdk-data-line={1487} +\noindent\mdline{1487}Table messages are used to specify all possible match-action tables exposed to a +control plane. This message contains the following fields:%mdk + +%mdk-data-line={1490} +\begin{itemize}%mdk + +%mdk-data-line={1490} +\item{} +%mdk-data-line={1490} +\mdline{1490}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1490}, a \mdline{1490}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1490} message with the ID, name, and alias of this table.%mdk%mdk + +%mdk-data-line={1492} +\item{} +%mdk-data-line={1492} +\mdline{1492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1492}, a repeated field of type \mdline{1492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1492} representing the data to +be used to construct the lookup key matched in this table. Each \mdline{1493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1493} +message is defined with the following fields:%mdk + +%mdk-data-line={1496} +\begin{itemize}%mdk + +%mdk-data-line={1496} +\item{} +%mdk-data-line={1496} +\mdline{1496}id, the \mdline{1496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1496} identifier of this \mdline{1496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1496}, unique in the scope of +this table. No rules are prescribed on the way \mdline{1497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1497} IDs should be +allocated, as long as two \mdline{1498}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1498} of the same table do not have the +same ID. Nonetheless, if the P4Info message was generated from a P4 +compiler, we recommend that the IDs be assigned incrementally, starting +from 1, in the same order as in the P4 key declaration. The P4 programmer +can either choose the IDs using the \mdline{1502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1502} annotation, or let the compiler +choose them.%mdk%mdk + +%mdk-data-line={1505} +\item{} +%mdk-data-line={1505} +\mdline{1505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1505}, the string representing the name of this \mdline{1505}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1505}.%mdk%mdk + +%mdk-data-line={1507} +\item{} +%mdk-data-line={1507} +\mdline{1507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1507}, a repeated field of strings, each one representing a P4 +annotation associated to this match field.%mdk%mdk + +%mdk-data-line={1510} +\item{} +%mdk-data-line={1510} +\mdline{1510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1510}, an \mdline{1510}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1510} value set to the size in bits of this match field.%mdk%mdk + +%mdk-data-line={1512} +\item{} +%mdk-data-line={1512} +\mdline{1512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1512}, a \mdline{1512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{1512} describing the match behavior for this field; it can be +either:%mdk + +%mdk-data-line={1514} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1514} +\item\mdline{1514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1514}, an enum field of type \mdline{1514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchType}}}\mdline{1514}, which includes all +possible PSA match kinds.%mdk + +%mdk-data-line={1516} +\item\mdline{1516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_match\_type}}}\mdline{1516}, a string field which can be used to encode any +architecture-specific match type.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1519} +\item{} +%mdk-data-line={1519} +\mdline{1519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1519}, a \mdline{1519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1519} message describing this match field.%mdk%mdk + +%mdk-data-line={1521} +\item{} +%mdk-data-line={1521} +\mdline{1521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1521}, which indicates whether the match field has a\mdline{1521}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1522}; this is useful for +\mdline{1523}\mdref{sec-psa-metadata-translation}{translation}\mdline{1523}.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1525} +\item{} +%mdk-data-line={1525} +\mdline{1525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_refs}}}\mdline{1525}, a repeated \mdline{1525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1525} field representing the set of possible +actions for this table. The \mdline{1526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionRef}}}\mdline{1526} message is used to reference an action +specified in the same P4Info message and it includes the following fields:%mdk + +%mdk-data-line={1528} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1528} +\item\mdline{1528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1528}, the \mdline{1528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1528} identifier of the action.%mdk + +%mdk-data-line={1529} +\item\mdline{1529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1529}, an enum value which can take one of three values: + \mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1530}, \mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1530} and \mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1530}. The \mdline{1530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}scope}}}\mdline{1530} of the + action is determined by the use of the P4 standard annotations + \mdline{1532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1532} and \mdline{1532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1532}~[\mdcite{p4actionannotations}{22}]\mdline{1532}. \mdline{1532}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{1532} + (\mdline{1533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@tableonly}}}\mdline{1533} annotation) means that the action can only appear within + the table, and never as the default action. \mdline{1534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEFAULT\_ONLY}}}\mdline{1534} + (\mdline{1535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@defaultonly}}}\mdline{1535} annotation) means that the action can only be used as the + default action. \mdline{1536}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_AND\_DEFAULT}}}\mdline{1536} is the default value for the enum and + means that neither annotation was used in P4 and that the action can be + used both within the table and as the default action.%mdk + +%mdk-data-line={1539} +\item\mdline{1539}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1539}, a repeated string field, each one representing a P4 +annotation associated to the action \mdline{1540}\emph{reference}\mdline{1540} in this table.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1542} +\item{} +%mdk-data-line={1542} +\mdline{1542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\_default\_action\_id}}}\mdline{1542}, if this table has a constant default action, this +field will carry the \mdline{1543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1543} identifier of that action, otherwise its value +will be 0. A default action is executed when a matching table entry is not +found for a given packet. Being constant means that the control plane cannot +set a different default action at runtime or change the default action\mdline{1546}'\mdline{1546}s +arguments.%mdk%mdk + +%mdk-data-line={1549} +\item{} +%mdk-data-line={1549} +\mdline{1549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}initial\_default\_action}}}\mdline{1549}, the default action that is executed with the + specified arguments when the table does not match. If no explicit + default action is set, the identifier of this field will default to + the id of the \mdline{1552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{1552} action.%mdk%mdk + +%mdk-data-line={1554} +\item{} +%mdk-data-line={1554} +\mdline{1554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation\_id}}}\mdline{1554}, the \mdline{1554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1554} identifier of the \mdline{1554}\textquotedblleft{}implementation\textquotedblright{}\mdline{1554} of this +table. 0 (default value) means that the table is a regular (direct) match +table. Otherwise, this field will carry the ID of an extern instance specified +in the same P4Info message (\mdline{1557}e.g.\mdline{1557} a PSA \mdline{1557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1557} or \mdline{1557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{1557} +instance). The table is then referred to as an indirect match table.%mdk%mdk + +%mdk-data-line={1560} +\item{} +%mdk-data-line={1560} +\mdline{1560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_resource\_ids}}}\mdline{1560}, repeated \mdline{1560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1560} identifiers for all the direct +resources attached to this table, such as \mdline{1561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1561} and \mdline{1561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1561} +instances, specified in the same P4Info message. In this version of the +P4Runtime specification only one direct resource of each type can be +associated to a table, hence for PSA programs this field is expected to have a +maximum size of 2.%mdk%mdk + +%mdk-data-line={1567} +\item{} +%mdk-data-line={1567} +\mdline{1567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1567}, an \mdline{1567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1567} describing the desired number of table entries that the +target should support for the table. See the \mdline{1568}\textquotedblleft{}Size\textquotedblright{}\mdline{1568} subsection within the +\mdline{1569}\textquotedblleft{}Table Properties\textquotedblright{}\mdline{1569} section of the P4\mdline{1569}\mdsub{16}\mdline{1569} language specification for details +\mdline{1570}[\mdcite{p4tableproperties}{36}]\mdline{1570}.%mdk%mdk + +%mdk-data-line={1572} +\item{} +%mdk-data-line={1572} +\mdline{1572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_behavior}}}\mdline{1572}, which describes the behavior of the data plane when +the idle timeout of a table entry expires (see +\mdline{1574}\mdref{sec-idle-timeout}{Idle-Timeout}\mdline{1574} section). Value can be any of the +\mdline{1575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutBehavior}}}\mdline{1575} enum:%mdk + +%mdk-data-line={1576} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1576} +\item\mdline{1576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NO\_TIMEOUT}}}\mdline{1576} (default value), which means that idle timeout is not +supported for this table.%mdk + +%mdk-data-line={1578} +\item\mdline{1578}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOTIFY\_CONTROL}}}\mdline{1578}, which means that the control plane should be notified of +the expiration of a table entry by means of a notification (see section on +\mdline{1580}\mdref{sec-table-idle-timeout-notification}{Table Idle Timeout Notifications}\mdline{1580}).%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={1582} +\item{} +%mdk-data-line={1582} +\mdline{1582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{1582}, a boolean flag indicating that the table is filled with +static entries and cannot be modified by the control plane at runtime.%mdk%mdk + +%mdk-data-line={1585} +\item{} +%mdk-data-line={1585} +\mdline{1585}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}has\_initial\_entries}}}\mdline{1585}, a boolean flag indicating that the table has +entries populated into it when the P4 program is loaded, which is +true for tables in the P4 source code with either the \mdline{1587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{1587} or +\mdline{1588}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const~entries}}}\mdline{1588} properties, and there is at least one entry in the +list.%mdk%mdk + +%mdk-data-line={1591} +\item{} +%mdk-data-line={1591} +\mdline{1591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{1591}, an \mdline{1591}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{1591} Protobuf message\mdline{1591}~[\mdcite{protoany}{37}]\mdline{1591} to embed +architecture-specific table properties\mdline{1592}~[\mdcite{p4tableproperties}{36}]\mdline{1592} which are not part +of the core P4 language or of the PSA architecture.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1595} +\subsubsection{\mdline{1595}6.4.2.\hspace*{0.5em}\mdline{1595}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}}\label{sec-action}%mdk%mdk + +%mdk-data-line={1597} +\noindent\mdline{1597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1597} messages are used to specify all possible actions of all match-action +tables.%mdk + +%mdk-data-line={1600} +\mdline{1600}The \mdline{1600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{1600} message defines the following fields:%mdk + +%mdk-data-line={1602} +\begin{itemize}%mdk + +%mdk-data-line={1602} +\item{} +%mdk-data-line={1602} +\mdline{1602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1602}, a \mdline{1602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1602} message with the ID, name, and alias of this action%mdk%mdk + +%mdk-data-line={1604} +\item{} +%mdk-data-line={1604} +\mdline{1604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{1604}, a repeated field of \mdline{1604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1604} messages representing the set of runtime +parameters that should be provided by the control plane when inserting or +modifying a table entry with this action. Each \mdline{1606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1606} message contains the +following fields:%mdk + +%mdk-data-line={1608} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1608} +\item\mdline{1608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1608}, the \mdline{1608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1608} identifier of this parameter. No rules are prescribed +on the way \mdline{1609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1609} IDs should be allocated, as long as two \mdline{1609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{1609} of the +same action do not have the same ID. Nonetheless, if the P4Info message +was generated from a P4 compiler, we recommend that the IDs be assigned +incrementally, starting from 1, in the same order as in the P4 action +declaration. The programmer can either choose the IDs using the \mdline{1613}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1613} +annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1615} +\item\mdline{1615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1615}, the string representing the name of this parameter.%mdk + +%mdk-data-line={1616} +\item\mdline{1616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1616}, a repeated field of strings, each one representing a P4 +annotation associated to this parameter.%mdk + +%mdk-data-line={1618} +\item\mdline{1618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1618}, an \mdline{1618}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1618} value set to the size in bits of this parameter.%mdk + +%mdk-data-line={1619} +\item\mdline{1619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{1619}, which describes this parameter using a \mdline{1619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Documentation}}}\mdline{1619} message.%mdk + +%mdk-data-line={1620} +\item\mdline{1620}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1620}, which indicates whether the action parameter has a +\mdline{1621}\mdref{sec-user-defined-types}{user-defined type}\mdline{1621}; this is useful for +\mdline{1622}\mdref{sec-psa-metadata-translation}{translation}\mdline{1622}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1624} +\subsubsection{\mdline{1624}6.4.3.\hspace*{0.5em}\mdline{1624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}}\label{sec-p4info-action-profile}%mdk%mdk + +%mdk-data-line={1626} +\noindent\mdline{1626}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1626} messages are used to specify all available instances of Action +Profile and Action Selector PSA externs.%mdk + +%mdk-data-line={1629} +\mdline{1629}PSA Action Profiles are used to describe implementations of match-action tables +where multiple table entries can share the same action instance. Indeed, +differently from a regular match-action table where each entry contains the +action specification, when using Action Profile-based tables, the control plane +can insert entries pointing to an Action Profile \mdline{1633}\emph{member}\mdline{1633}, where each member +then points to an action instance. The control plane is responsible for +creating, modifying, or deleting members at runtime.%mdk + +%mdk-data-line={1637} +\mdline{1637}PSA Action Selectors extend Action Profiles with the capability of bundling +together multiple members into \mdline{1638}\emph{groups}\mdline{1638}. Match-action table entries can point to +a member or group. When processing a packet, if the table entry points to a +group, a dynamic selection algorithm is used to select a member from the group +and apply the corresponding action to the packet. The dynamic selection +algorithm is typically specified in the P4 program when instantiating the Action +Selector, however it is not specified in the P4Info. The control plane is +responsible for creating, modifying, or deleting both members and groups at +runtime.%mdk + +%mdk-data-line={1647} +\mdline{1647}While PSA defines Action Profile and Action Selector as two different externs, +P4Info uses the same \mdline{1648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1648} message to describe both.%mdk + +%mdk-data-line={1650} +\mdline{1650}The \mdline{1650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{1650} message includes the following fields:%mdk + +%mdk-data-line={1652} +\begin{itemize}%mdk + +%mdk-data-line={1652} +\item{} +%mdk-data-line={1652} +\mdline{1652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1652}, a \mdline{1652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1652} message with the ID, name, and alias of this Action +Profile or Selector.%mdk%mdk + +%mdk-data-line={1655} +\item{} +%mdk-data-line={1655} +\mdline{1655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_ids}}}\mdline{1655}, a repeated field of uint32 identifiers used to reference tables +whose implementation uses this Action Profile or Selector.%mdk%mdk + +%mdk-data-line={1658} +\item{} +%mdk-data-line={1658} +\mdline{1658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}with\_selector}}}\mdline{1658}, a boolean flag indicating whether this message describes an +instance of a PSA Action Selector extern.%mdk%mdk + +%mdk-data-line={1661} +\item{} +%mdk-data-line={1661} +\mdline{1661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1661}, an \mdline{1661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1661} representing the maximum number of member entries that the +Action Profile can hold. For Action Selectors, its semantics is specified by +the \mdline{1663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{1663} value as described below.%mdk%mdk + +%mdk-data-line={1665} +\item{} +%mdk-data-line={1665} +\mdline{1665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1665}, an \mdline{1665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1665} which is 0 for an Action Profile, or, for an +Action Selector, its semantics is specified by the \mdline{1666}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{1666} +value as described below. +The \mdline{1668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1668} must be no larger than \mdline{1668}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1668}. PSA programs can use the +\mdline{1669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{1669} annotation to provide this value for Action Selectors. +If the annotation is omitted, the P4Info field will default to 0.%mdk%mdk + +%mdk-data-line={1672} +\item{} +%mdk-data-line={1672} +\mdline{1672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{1672}, a oneof for Action Selectors that +specifies how \mdline{1673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1673} and \mdline{1673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1673} are interpreted. It can be either:%mdk + +%mdk-data-line={1674} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1674} +\item\mdline{1674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_weights}}}\mdline{1674}, indicating that \mdline{1674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1674} and \mdline{1674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1674} represent +the maximum sum of weights that can be present across all selector groups +and within a single selector group respectively.%mdk + +%mdk-data-line={1677} +\item\mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_members}}}\mdline{1677}, indicating that \mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1677} and \mdline{1677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{1677} represent +the maximum number of members that can be present across all selector +groups and within a single selector group respectively, irrespective of +their weight. The \mdline{1680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SumOfMembers}}}\mdline{1680} message used to represent this value also +contains an optional int32 \mdline{1681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_member\_weight}}}\mdline{1681}, which indicates the +maximum weight of each individual member. If unset, any 32-bit integer is +allowed for weight.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1686} +\noindent\mdline{1686} PSA programs can use the \mdline{1686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@selector\_size\_semantics}}}\mdline{1686} annotation with one of + \mdline{1687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_weights}}}\mdline{1687} or \mdline{1687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_members}}}\mdline{1687} to specify this value for Action + Selectors. In the \mdline{1688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_members}}}\mdline{1688} case, the \mdline{1688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_member\_weight}}}\mdline{1688} annotation + can be used to specify \mdline{1689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_member\_weight}}}\mdline{1689}. Unless otherwise specified, the + value of \mdline{1690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{1690} should default to \mdline{1690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_weights}}}\mdline{1690}. + However, an unset \mdline{1691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{1691} should also be treated as + \mdline{1692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_weights}}}\mdline{1692} for backwards compatibility in Action Selectors. In Action + Profiles, this value must be unset.%mdk + +%mdk-data-line={1695} +\subsubsection{\mdline{1695}6.4.4.\hspace*{0.5em}\mdline{1695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1695} \mdline{1695}\&\mdline{1695} \mdline{1695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}}\label{sec-counter-directcounter}%mdk%mdk + +%mdk-data-line={1697} +\noindent\mdline{1697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1697} and \mdline{1697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1697} messages are used to specify all possible +instances of Counter and Direct Counter PSA externs respectively. Both externs +are used to represent data plane counters that keep statistics such as the +number of packets or bytes. The main difference between (indexed) counters and +direct counters is:%mdk + +%mdk-data-line={1703} +\begin{itemize}%mdk + +%mdk-data-line={1703} +\item{} +%mdk-data-line={1703} +\mdline{1703}Indexed counters provide a fixed number of independent counter values, also +called cells. Each cell can be read by the control plane using an integer +index.%mdk%mdk + +%mdk-data-line={1707} +\item{} +%mdk-data-line={1707} +\mdline{1707}Direct counters are associated a given match-action table, providing as many +cells as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1710} +\noindent\mdline{1710}Both \mdline{1710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1710} and \mdline{1710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1710} messages share the following fields:%mdk + +%mdk-data-line={1712} +\begin{itemize}%mdk + +%mdk-data-line={1712} +\item{} +%mdk-data-line={1712} +\mdline{1712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1712}, a \mdline{1712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1712} message with the ID, name, and alias of this counter +extern instance.%mdk%mdk + +%mdk-data-line={1715} +\item{} +%mdk-data-line={1715} +\mdline{1715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1715}, a message of of type \mdline{1715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1715} used to describe the compile-time +configuration of this counter. Currently, the \mdline{1716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec}}}\mdline{1716} message is used to +carry only the counter unit, which can be any of the \mdline{1717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterSpec.Unit}}}\mdline{1717} enum +values:%mdk + +%mdk-data-line={1719} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1719} +\item\mdline{1719}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1719}: reserved value.%mdk + +%mdk-data-line={1720} +\item\mdline{1720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1720}: byte counter.%mdk + +%mdk-data-line={1721} +\item\mdline{1721}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1721}: packet counter.%mdk + +%mdk-data-line={1722} +\item\mdline{1722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BOTH}}}\mdline{1722}: combination of both byte and packet counter.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1724} +\noindent\mdline{1724}For indexed counters, the \mdline{1724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1724} message contains also a \mdline{1724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1724} field, an +\mdline{1725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1725} representing the maximum number of independent values that can be held +by this counter array. Conversely, the \mdline{1726}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{1726} message contains a +\mdline{1727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1727} field that carries the \mdline{1727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}unit32}}}\mdline{1727} identifier of the table to +which this direct counter is attached.%mdk + +%mdk-data-line={1730} +\mdline{1730}For indexed counters, the \mdline{1730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter}}}\mdline{1730} message contains also an \mdline{1730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1730} +field, which indicates whether the index has a\mdline{1731}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1732}. This is useful for +\mdline{1733}\mdref{sec-psa-metadata-translation}{translation}\mdline{1733}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1734}).%mdk + +%mdk-data-line={1736} +\subsubsection{\mdline{1736}6.4.5.\hspace*{0.5em}\mdline{1736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1736} \mdline{1736}\&\mdline{1736} \mdline{1736}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}}\label{sec-meter-directmeter}%mdk%mdk + +%mdk-data-line={1738} +\noindent\mdline{1738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1738} and \mdline{1738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1738} messages are used to specify all possible instances of +Meter and Direct Meter PSA externs. Both externs provide mechanism to keep data +plane statistics typically used to mark or drop packets that exceed a given +packet or bit rate. Similarly to counters, the main difference between (indexed) +meters and direct meters is:%mdk + +%mdk-data-line={1744} +\begin{itemize}%mdk + +%mdk-data-line={1744} +\item{} +%mdk-data-line={1744} +\mdline{1744}Indexed meters provide a fixed number of independent meter values, also called +cells. Each cell can be accessed by the control plane using an integer index, +\mdline{1746}e.g.\mdline{1746} to set the rate threshold.%mdk%mdk + +%mdk-data-line={1748} +\item{} +%mdk-data-line={1748} +\mdline{1748}Direct meters are associated to match-action tables, providing as many cells +as the number of entries in the table.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1751} +\noindent\mdline{1751}Both \mdline{1751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1751} and \mdline{1751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1751} messages share the following fields:%mdk + +%mdk-data-line={1753} +\begin{itemize}%mdk + +%mdk-data-line={1753} +\item{} +%mdk-data-line={1753} +\mdline{1753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1753}, a \mdline{1753}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1753} message with the ID, name, and alias of this meter +extern instance.%mdk%mdk + +%mdk-data-line={1756} +\item{} +%mdk-data-line={1756} +\mdline{1756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}spec}}}\mdline{1756}, a message of type \mdline{1756}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1756} used to describe the capabilities of +this meter extern instance. The \mdline{1757}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{1757} message is used to describe the +meter unit and the meter type. The meter unit can be any of the +\mdline{1759}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Unit}}}\mdline{1759} enum values:%mdk + +%mdk-data-line={1760} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1760} +\item\mdline{1760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNSPECIFIED}}}\mdline{1760}: reserved value.%mdk + +%mdk-data-line={1761} +\item\mdline{1761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{1761}, which signifies that this meter can be configured with rates +expressed in bytes/second.%mdk + +%mdk-data-line={1763} +\item\mdline{1763}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{1763}, for rates expressed in packets/second.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1765} +\mdline{1765}The meter type can be any of the \mdline{1765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Type}}}\mdline{1765} enum values:%mdk + +%mdk-data-line={1766} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1766} +\item\mdline{1766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TWO\_RATE\_THREE\_COLOR}}}\mdline{1766}: This is the \mdline{1766}\emph{Two Rate Three Color Marker}\mdline{1766} (trTCM) +defined in RFC 2698\mdline{1767}~[\mdcite{rfc2698}{3}]\mdline{1767}. This is the standard P4Runtime meter type +and allows meters to use two rates to split packets into three potential +colors: GREEN, YELLOW, or RED. This mode is the default, but can also be +set explicitly in a P4 program by adding the \mdline{1770}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@two\_rate\_three\_color}}}\mdline{1770} +annotation to the meter definition. +For example, in a V1Model P4 program, we might define a trTCM direct meter +as follows: + +%mdk-data-line={1774} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1775} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}two\_rate\_three\_color}\\ +direct\_meter\textless{}color\_type\textgreater{}(MeterType.bytes)~my\_meter;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={1778} +\item\mdline{1778}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SINGLE\_RATE\_THREE\_COLOR}}}\mdline{1778}: This is the \mdline{1778}\emph{Single Rate Three Color Marker}\mdline{1778} +(srTCM) defined in RFC 2697\mdline{1779}~[\mdcite{rfc2697}{2}]\mdline{1779}. This allows meters to use one rate +and an Excess Burst Size (EBS) to split packets into three potential +colors: GREEN, YELLOW, or RED. In a P4 program, this mode can be set by +adding the \mdline{1782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@single\_rate\_three\_color}}}\mdline{1782} annotation to the meter definition.%mdk + +%mdk-data-line={1783} +\item\mdline{1783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SINGLE\_RATE\_TWO\_COLOR}}}\mdline{1783}: This is a simplified version of RFC 2697 +\mdline{1784}[\mdcite{rfc2697}{2}]\mdline{1784}, and the \mdline{1784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SINGLE\_RATE\_THREE\_COLOR}}}\mdline{1784} mode above. +\mdline{1785}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SINGLE\_RATE\_TWO\_COLOR}}}\mdline{1785} restricts meters to use only a single rate +specified by the Committed Information Rate (CIR) and Committed Burst Size +(CBS) to mark packets GREEN or RED. In a P4 program, this mode can be set +by adding the \mdline{1788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@single\_rate\_two\_color}}}\mdline{1788} annotation to the meter definition.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1790} +\noindent\mdline{1790}For indexed meters, the \mdline{1790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1790} message contains also a \mdline{1790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1790} field, an \mdline{1790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{1790} +representing the maximum number of independent cells that can be held by this +meter. Conversely, the \mdline{1792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{1792} message contains a \mdline{1792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}direct\_table\_id}}}\mdline{1792} field +that carries the \mdline{1793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1793} identifier of the table to which this direct meter is +attached.%mdk + +%mdk-data-line={1796} +\mdline{1796}For indexed meters, the \mdline{1796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Meter}}}\mdline{1796} message contains also an \mdline{1796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{1796} +field, which indicates whether the index has a\mdline{1797}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1798}. This is useful for +\mdline{1799}\mdref{sec-psa-metadata-translation}{translation}\mdline{1799}. The underlying built-in type must +be a fixed-width unsigned bitstring (\mdline{1800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1800}).%mdk + +%mdk-data-line={1802} +\subsubsection{\mdline{1802}6.4.6.\hspace*{0.5em}\mdline{1802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\label{sec-controller-packet-meta}%mdk%mdk + +%mdk-data-line={1804} +\noindent\mdline{1804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1804} messages are used to describe any metadata associated +with controller packet-in and packet-out. A packet-in is defined as a data plane +packet that is sent by the P4Runtime server to the control plane for further +inspection. Similarly, a packet-out is defined as a data packet generated by the +control plane and injected in the data plane via the P4Runtime server.%mdk + +%mdk-data-line={1810} +\mdline{1810}When inspecting a packet-in, the control plane might need to have access to +additional information such as the original data plane port where the packet was +received, the timestamp when the packet was received, if the packet is a clone, +etc. Similarly, when sending a packet-out, the control plane might need to +specify additional information used by the device to process the data packet.%mdk + +%mdk-data-line={1816} +\mdline{1816}Such additional information for packet-in and packet-out can be expressed by +means of P4 headers carrying P4 standard annotations +\mdline{1818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_in")}}}\mdline{1818} and \mdline{1818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header("packet\_out")}}}\mdline{1818}, +respectively. \mdline{1819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1819} messages capture the information +contained within these special headers and are needed by the P4Runtime server to +process packet-in and packet-out stream messages (see section on Packet I/O +stream messages).%mdk + +%mdk-data-line={1824} +\mdline{1824}A P4Info message can contain at most two \mdline{1824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata~messages}}}\mdline{1824}, +one describing the packet-in header, and the other the packet-out header. Each +message contains the following fields:%mdk + +%mdk-data-line={1828} +\begin{itemize}%mdk + +%mdk-data-line={1828} +\item{} +%mdk-data-line={1828} +\mdline{1828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1828}, a \mdline{1828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1828} message where \mdline{1828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble.name}}}\mdline{1828} is set to \mdline{1828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_in"}}}\mdline{1828} +and \mdline{1829}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}"packet\_out"}}}\mdline{1829} for packet-in and packet-out metadata, respectively.%mdk%mdk + +%mdk-data-line={1831} +\item{} +%mdk-data-line={1831} +\mdline{1831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{1831}, a repeated field of type \mdline{1831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1831}, where each \mdline{1831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1831} message +includes the following fields:%mdk + +%mdk-data-line={1833} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1833} +\item\mdline{1833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1833}, a \mdline{1833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{1833} identifier of this metadata. No rules are prescribed on +the way metadata IDs should be allocated, as long as two \mdline{1834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Metadata}}}\mdline{1834} of the +same \mdline{1835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1835} message do not have the same ID. If the +P4Info message was generated from a P4 compiler, we recommend that the IDs +be assigned incrementally, starting from 1, in the same order as the +fields in the P4 header declaration. The P4 programmer can either choose +the IDs using the \mdline{1839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1839} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1840} +\item\mdline{1840}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1840}, a string representation of the name of this metadata. If the +P4Info message was generated from a P4 compiler, then this field is +expected to be set to the name of the P4 controller header field (see +example below).%mdk + +%mdk-data-line={1844} +\item\mdline{1844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1844}, a repeated field of strings, each one representing a P4 +annotation associated to this metadata.%mdk + +%mdk-data-line={1846} +\item\mdline{1846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1846}, an \mdline{1846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{1846} representing the size in bits of this metadata.%mdk + +%mdk-data-line={1847} +\item\mdline{1847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1847}, which indicates whether the metadata field has a +\mdline{1848}\mdref{sec-user-defined-types}{user-defined type}\mdline{1848}; this is useful for +\mdline{1849}\mdref{sec-psa-metadata-translation}{translation}\mdline{1849}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1851} +\noindent\mdline{1851}As an example, consider the following snippet of a P4 program where controller +headers are specified and we show the corresponding \mdline{1852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{1852} +messages.%mdk + +%mdk-data-line={1855} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1856} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~egress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~port~where~the~packet}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~should~be~sent~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~queue\_id;~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~suggested~queue~ID~}{\mdcolor{darkgreen}*/}\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~ingress\_port;~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~data~plane~port~ID~where}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~the~original~packet~was~received~}{\mdcolor{darkgreen}*/}\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}1}\textgreater{}~is\_clone;~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~1~if~this~is~a~clone~of~the}\\ +{\mdcolor{darkgreen}~~~~~~~~~~~~~~~~~~~~~~~~~~original~packet~}{\mdcolor{darkgreen}*/}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1871} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1872} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868916615}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_out}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_out}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}egress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}queue\_id}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~\}\\ +\}\\ +\\ +controller\_packet\_metadata~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}2868941301}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}packet\_in}{\mdcolor{maroon}"}\\ +~~~~annotations:~{\mdcolor{maroon}"}{\mdcolor{maroon}@controller\_header(}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon}packet\_in}{\mdcolor{gray}\textbackslash{}"}{\mdcolor{maroon})}{\mdcolor{maroon}"}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ingress\_port}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}9}\\ +~~\}\\ +~~metadata~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}is\_clone}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}1}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1909} +\noindent\mdline{1909}Note that the use of \mdline{1909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{1909} is optional for Packet I/O. The P4 +program may define controller headers without this annotation and use them to +encapsulate controller packets. However, in this case the client will be +responsible for extracting the metadata from the serialized header in packet-in +messages and for serializing the metadata when generating packet-out messages.%mdk + +%mdk-data-line={1915} +\subsubsection{\mdline{1915}6.4.7.\hspace*{0.5em}\mdline{1915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}}\label{sec-valueset}%mdk%mdk + +%mdk-data-line={1917} +\noindent\mdline{1917}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1917} messages are used to specify all possible P4 Parser Value +Sets. Parser Value Sets can be used by the control plane to specify runtime +matches used by the P4 parser to determine transitions from one state to +another. For more information on Parser Value Sets, refer to the P4\mdline{1920}\mdsub{16}\mdline{1920} +specification\mdline{1921}~[\mdcite{p4valuesets}{45}]\mdline{1921}.%mdk + +%mdk-data-line={1923} +\mdline{1923}The \mdline{1923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1923} message defines the following fields:%mdk + +%mdk-data-line={1925} +\begin{itemize}%mdk + +%mdk-data-line={1925} +\item{} +%mdk-data-line={1925} +\mdline{1925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{1925}, a \mdline{1925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{1925} message with the ID, name, and alias of this Value +Set.%mdk%mdk + +%mdk-data-line={1928} +\item{} +%mdk-data-line={1928} +\mdline{1928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1928}, a repeated field of \mdline{1928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1928} messages, representing the list of +matches performed when looking up an expression in a Value Set. This +determines the format of the members which can be inserted into the Value Set +by the control plane, similarly to the \mdline{1931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_fields}}}\mdline{1931} repeated field in the +\mdline{1932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{1932} message.%mdk%mdk + +%mdk-data-line={1934} +\item{} +%mdk-data-line={1934} +\mdline{1934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{1934}, an int32 representing the maximum number of entries (values) in the +Value Set. It corresponds to the value of the size argument of the P4 +\mdline{1936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set}}}\mdline{1936} constructor call.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={1938} +\noindent\mdline{1938}According to the P4 specification, the type parameter of a Value Set, which +defines the type of the expression that can be matched against the Value Set in +a parser transition, and therefore determines the format of the members that can +be inserted into the Value Set by the control plane, must be one of \mdline{1941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1941}, +\mdline{1942}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1942}, or \mdline{1942}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1942}~[\mdcite{p4selectexpr}{31}]\mdline{1942}. The rest of this section looks at all 3 of +these cases and gives an example \mdline{1943}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSet}}}\mdline{1943} message when appropriate.%mdk + +%mdk-data-line={1945} +\begin{enumerate}%mdk + +%mdk-data-line={1945} +\item{} +%mdk-data-line={1945} +\mdline{1945}If the type parameter is \mdline{1945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1945}, \mdline{1945}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1945} will include exactly one +\mdline{1946}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1946} message, with the following fields (if a field is omitted here, +it means the default Protobuf value should be used):%mdk + +%mdk-data-line={1949} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1949} +\item\mdline{1949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1949}: set to 1%mdk + +%mdk-data-line={1950} +\item\mdline{1950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1950}: set to the value of \mdline{1950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1950}%mdk + +%mdk-data-line={1951} +\item\mdline{1951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1951}: set to \mdline{1951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1951}%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={1953} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={1954} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}bit\textless{}8\textgreater{}~\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(hdr.f8)~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1957} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={1958} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={1972} +\begin{enumerate}[,start=2]%mdk + +%mdk-data-line={1972} +\item{} +%mdk-data-line={1972} +\mdline{1972}If the type parameter is a \mdline{1972}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{1972}, this version of P4Runtime does not +support runtime programming of the Value Set. If the P4Info message is +generated by a compiler, and the P4 program includes such a Value Set, the +compiler must reject the program.%mdk%mdk + +%mdk-data-line={1977} +\item{} +%mdk-data-line={1977} +\mdline{1977}If the type parameter is a \mdline{1977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{1977}, this version of P4Runtime requires that +all the fields of the struct be of type \mdline{1978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{1978} (where \mdline{1978}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1978} can be different +for each field). Otherwise, if the P4Info message is generated by a compiler, +the compiler must reject the program. If the Value Set is supported, the +\mdline{1981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1981} field will include one \mdline{1981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{1981} message for each field in the +struct, with the following fields:%mdk + +%mdk-data-line={1984} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={1984} +\item\mdline{1984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{1984}: must be unique with respect to the other \mdline{1984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1984} entries. If the P4Info +message was generated from a P4 compiler, we recommend that the IDs be +assigned incrementally, starting from 1, in the same order as the fields in +the P4 struct declaration. The P4 programmer can choose the IDs using the +\mdline{1988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{1988} annotation, or let the compiler choose them.%mdk + +%mdk-data-line={1989} +\item\mdline{1989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}name}}}\mdline{1989}: set to the name of the corresponding struct field.%mdk + +%mdk-data-line={1990} +\item\mdline{1990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{1990}: set to the list of P4 annotations associated with the struct +field, except for the \mdline{1991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1991} annotation, if present (see the \mdline{1991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1991} field +below).%mdk + +%mdk-data-line={1993} +\item\mdline{1993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{1993}: set to the value of \mdline{1993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{1993} for the corresponding struct field.%mdk + +%mdk-data-line={1994} +\item\mdline{1994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{1994}, which indicates whether the struct field has a\mdline{1994}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{1995}; this is useful for +\mdline{1996}\mdref{sec-psa-metadata-translation}{translation}\mdline{1996}.%mdk + +%mdk-data-line={1997} +\item\mdline{1997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{1997}: by default \mdline{1997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_type}}}\mdline{1997} is set to \mdline{1997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{1997}; the P4 programmer can +specify a different match type by using the \mdline{1998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@match}}}\mdline{1998} annotation +\mdline{1999}[\mdcite{p4selectexpr}{31}]\mdline{1999}.%mdk + +%mdk-data-line={2000} +\item\mdline{2000}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}doc}}}\mdline{2000}: documentation associated with the struct field.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={2002} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2003} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~bit\textless{}8\textgreater{}~f8;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(2)~@match(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(3)~@match(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2011} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2012} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2039} +\noindent\mdline{2039}In the above example, the \mdline{2039}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{2039} annotations on the P4 struct fields are +optional. When omitted, the compiler will choose appropriate IDs.%mdk + +%mdk-data-line={2042} +\mdline{2042}Although not mentioned in the P4 specification, P4Runtime also supports the +cases where the Value Set type parameter is a\mdline{2043}~\mdref{sec-user-defined-types}{user-defined +type}\mdline{2044} that resolves to a \mdline{2044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2044}, or a \mdline{2044}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2044} where +one or more fields is a\mdline{2045}~\mdref{sec-user-defined-types}{user-defined type}\mdline{2045} that +resolves to a \mdline{2046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2046}. For each \mdline{2046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MatchField}}}\mdline{2046} that corresponds to a user-defined +type, the \mdline{2047}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2047} field must be set to the appropriate value (\mdline{2047}i.e.\mdline{2047} the name +of the type).%mdk + +%mdk-data-line={2050} +\subsubsection{\mdline{2050}6.4.8.\hspace*{0.5em}\mdline{2050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}}\label{sec-register}%mdk%mdk + +%mdk-data-line={2052} +\noindent\mdline{2052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{2052} messages are used to specify all possible instances of Register PSA +externs.%mdk + +%mdk-data-line={2055} +\mdline{2055}Registers are stateful memories that can be read and written by data plane +during packet forwarding. The control plane can also access registers at +runtime.%mdk + +%mdk-data-line={2059} +\mdline{2059}The \mdline{2059}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Register}}}\mdline{2059} message defines the following fields:%mdk + +%mdk-data-line={2061} +\begin{itemize}%mdk + +%mdk-data-line={2061} +\item{} +%mdk-data-line={2061} +\mdline{2061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{2061}, a \mdline{2061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{2061} message with the ID, name, and alias of this register +instance.%mdk%mdk + +%mdk-data-line={2064} +\item{} +%mdk-data-line={2064} +\mdline{2064}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{2064}, which specifies the data type stored by this register, expressed +using a \mdline{2065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2065} message (see section on\mdline{2065}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary +P4 Types}\mdline{2066}).%mdk%mdk + +%mdk-data-line={2068} +\item{} +%mdk-data-line={2068} +\mdline{2068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{2068}, an \mdline{2068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{2068} value representing the total number of independent register +cells available.%mdk%mdk + +%mdk-data-line={2071} +\item{} +%mdk-data-line={2071} +\mdline{2071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{2071}, which indicates whether the register index has a +\mdline{2072}\mdref{sec-user-defined-types}{user-defined type}\mdline{2072}. This is useful for +\mdline{2073}\mdref{sec-psa-metadata-translation}{translation}\mdline{2073}. The underlying built-in type +must be a fixed-width unsigned bitstring (\mdline{2074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2074}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2076} +\subsubsection{\mdline{2076}6.4.9.\hspace*{0.5em}\mdline{2076}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}}\label{sec-digest}%mdk%mdk + +%mdk-data-line={2078} +\noindent\mdline{2078}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{2078} messages are used to specify all possible instances of Packet Digest +PSA externs.%mdk + +%mdk-data-line={2081} +\mdline{2081}A packet digest is a mechanism to efficiently send notifications from the data +plane to the control plane. This mechanism differs from packet-in which is +generally used to send entire packets (headers plus payload), each one as a +separate P4Runtime stream message. A digest for a packet has a size typically +much smaller than the packet itself, as it can be used to send only a subset of +the headers or P4 metadata associated with the packet. To reduce the rate of +messages sent to the control plane, a P4Runtime server can combine digests for +multiple packets into larger messages.%mdk + +%mdk-data-line={2090} +\mdline{2090}The \mdline{2090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{2090} message defines the following fields:%mdk + +%mdk-data-line={2092} +\begin{itemize}%mdk + +%mdk-data-line={2092} +\item{} +%mdk-data-line={2092} +\mdline{2092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{2092}, a \mdline{2092}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{2092} message with the ID, name, and alias of this digest +instance.%mdk%mdk + +%mdk-data-line={2095} +\item{} +%mdk-data-line={2095} +\mdline{2095}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{2095}, which specifies the data type of an individual digest +notification using a \mdline{2096}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2096} message (see section on\mdline{2096}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation +of Arbitrary P4 Types}\mdline{2097}).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2099} +\subsubsection{\mdline{2099}6.4.10.\hspace*{0.5em}\mdline{2099}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}}\label{sec-p4info-extern}%mdk%mdk + +%mdk-data-line={2101} +\noindent\mdline{2101}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2101} messages are used to specify all extern instances across all extern +types for a non-PSA architecture. This is useful when extending P4Runtime to +support a new architecture. Each architecture-specific extern type corresponds +to at most one \mdline{2104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2104} message instance in P4Info. The \mdline{2104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2104} message defines +the following fields:%mdk + +%mdk-data-line={2107} +\begin{itemize}%mdk + +%mdk-data-line={2107} +\item{} +%mdk-data-line={2107} +\mdline{2107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{2107}, a 32-bit unsigned integer which uniquely identifies the +extern type in the context of the architecture. It must be in the\mdline{2108}~\mdref{sec-id-allocation}{reserved +range}\mdline{2109} \mdline{2109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{}[0x81,~0xfe]}}}\mdline{2109}. Note that this value does not need +to be unique across all architectures from all organizations, since at any +given time every device managed by a P4Runtime server maps to a single P4Info +message and a single architecture.%mdk%mdk + +%mdk-data-line={2114} +\item{} +%mdk-data-line={2114} +\mdline{2114}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_name}}}\mdline{2114}, which specifies the fully-qualified P4 name of the extern +type.%mdk%mdk + +%mdk-data-line={2117} +\item{} +%mdk-data-line={2117} +\mdline{2117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instances}}}\mdline{2117}, a repeated field of \mdline{2117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{2117} Protobuf messages, with each +entry corresponding to a separate P4 instance of the extern. The +\mdline{2119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{2119} in turn defines the following fields:%mdk + +%mdk-data-line={2121} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2121} +\item\mdline{2121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{2121}, a \mdline{2121}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Preamble}}}\mdline{2121} message with the ID, name, and alias of this digest +instance.%mdk + +%mdk-data-line={2123} +\item\mdline{2123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{2123}, an \mdline{2123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{2123} Protobuf message\mdline{2123}~[\mdcite{protoany}{37}]\mdline{2123} which is used to embed +arbitrary information specific to the extern instance. Note that the +underlying Protobuf message type for \mdline{2125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{2125} should be the same for all +instances of this extern type. That Protobuf message should be defined in a +separate architecture-specific Protobuf file. See section on\mdline{2127}~\mdref{sec-extending-p4runtime}{Extending +P4Runtime for non-PSA Architectures}\mdline{2128} for more +information.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2131} +\noindent\mdline{2131}If the P4 program does not include any instance of a given extern type, the +\mdline{2132}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{2132} message instance for that type should be omitted from the P4Info.%mdk + +%mdk-data-line={2134} +\subsection{\mdline{2134}6.5.\hspace*{0.5em}\mdline{2134}Support for Arbitrary P4 Types with P4TypeInfo}\label{sec-support-for-arbitrary-p4-types-with-p4typeinfo}%mdk%mdk + +%mdk-data-line={2136} +\noindent\mdline{2136}See section on\mdline{2136}~\mdref{sec-representation-of-arbitrary-p4-types}{Representation of Arbitrary P4 +Types}\mdline{2137}.%mdk + +%mdk-data-line={2139} +\section{\mdline{2139}7.\hspace*{0.5em}\mdline{2139}P4 Forwarding-Pipeline Configuration}\label{sec-p4-fwd-pipe-config}%mdk%mdk + +%mdk-data-line={2141} +\noindent\mdline{2141}The \mdline{2141}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2141} captures data needed to realize a P4 +forwarding-pipeline and map various IDs passed in P4Runtime entity messages. It +is formally called the \mdline{2143}\textquotedblleft{}Device Configuration\textquotedblright{}\mdline{2143} and sometimes also referred to as +the \mdline{2144}\textquotedblleft{}P4 Blob\textquotedblright{}\mdline{2144}. It is defined as:%mdk + +%mdk-data-line={2146} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2147} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ForwardingPipelineConfig~\{\\ +~~config.P{\mdcolor{purple}4}Info~p4info~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~p4\_device\_config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\bfseries{\mdcolor{navy}message}}~Cookie~\{\\ +~~~~{\bfseries{\mdcolor{navy}uint64}}~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~\}\\ +~~Cookie~cookie~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2157} +\noindent\mdline{2157}The \mdline{2157}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{2157} field captures the P4 program metadata as described by the P4Info. +This message is the output of the P4 compiler and is target-agnostic.%mdk + +%mdk-data-line={2160} +\mdline{2160}The \mdline{2160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{2160} is opaque binary data which contains the target-specific +configuration to realize the P4 program. The P4 program running on a target is +changed by loading a new \mdline{2162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{2162} on that target.%mdk + +%mdk-data-line={2164} +\mdline{2164}The \mdline{2164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{2164} field is opaque data which may be used by a control plane to +uniquely identify a forwarding-pipeline configuration among others managed by +the same control plane. For example, a controller can compute its value using a +hash function over the P4Info and/or target-specific binary data. However, there +are no restrictions on how such value is computed, or where this is stored on +the target, as long as it is returned with a \mdline{2169}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{2169} RPC. +When writing the config via a \mdline{2170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{2170} RPC, the cookie +field is optional. For this reason, the actual value is wrapped in its own +message to clearly identify cases where a cookie is not present.%mdk + +%mdk-data-line={2174} +\section{\mdline{2174}8.\hspace*{0.5em}\mdline{2174}General Principles for Message Formatting}\label{sec-message-formatting-principles}%mdk%mdk + +%mdk-data-line={2176} +\subsection{\mdline{2176}8.1.\hspace*{0.5em}\mdline{2176}Default-valued Fields}\label{sec-default-valued-fields}%mdk%mdk + +%mdk-data-line={2178} +\noindent\mdline{2178}There is a subtle distinction between the treatment of default-valued scalar +fields vs default-valued message fields in P4Runtime.%mdk + +%mdk-data-line={2181} +\subsubsection{\mdline{2181}8.1.1.\hspace*{0.5em}\mdline{2181}Set / Unset Scalar Fields}\label{sec-set-unset-scalar-fields}%mdk%mdk + +%mdk-data-line={2183} +\noindent\mdline{2183}In Protobuf version 3 (\mdline{2183}\emph{proto3}\mdline{2183}), the default value of scalar fields is \mdline{2183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0}}}\mdline{2183} for +numeric types such as \mdline{2184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int32}}}\mdline{2184}, and the empty string \mdline{2184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}""}}}\mdline{2184} for string types +(\mdline{2185}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{2185} and \mdline{2185}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2185}). An application, such as the P4Runtime client or +server, is \mdline{2186}\textbf{unable to distinguish}\mdline{2186} between an unset scalar field and a scalar +field set to its default value. Therefore, we usually reserve the default +values 0 and \mdline{2188}\textquotedblleft{}\textquotedblright{}\mdline{2188} of scalar fields to mean \mdline{2188}\textquotedblleft{}unset\textquotedblright{}\mdline{2188}.%mdk + +%mdk-data-line={2190} +\mdline{2190}In particular, 0 is not a valid P4 object ID and it +is an error to specify 0 for any P4 object ID in a non-read request towards the +server, such as in a \mdline{2192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{2192} or a \mdline{2192}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfigRequest}}}\mdline{2192}.%mdk + +%mdk-data-line={2194} +\mdline{2194}In contrast to scalar fields, note that for message fields, we often do make +a distinction between an unset message field vs a message field set to its +default value, see the next section.%mdk + +%mdk-data-line={2198} +\subsubsection{\mdline{2198}8.1.2.\hspace*{0.5em}\mdline{2198}Set / Unset Message Fields}\label{sec-set-unset-message-fields}%mdk%mdk + +%mdk-data-line={2200} +\noindent\mdline{2200}In Protobuf version 3 (\mdline{2200}\emph{proto3}\mdline{2200}), the default value for a message field is +\mdline{2201}\textquotedblleft{}unset\textquotedblright{}\mdline{2201}~[\mdcite{protodefaults}{6}]\mdline{2201}. An application, such as the P4Runtime client or +server, is \mdline{2202}\textbf{able to distinguish}\mdline{2202} between an unset message field and a message +field set to its default value. We often use this distinction in P4Runtime +and the meaning of a message can vary based on which of its message fields are +set. For example, when reading values from an indirect PSA counter using the +\mdline{2206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2206} message, an \mdline{2206}\textquotedblleft{}unset\textquotedblright{}\mdline{2206} \mdline{2206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2206} field means that all entries in the +counter array should be read and returned to the P4Runtime client (we refer to +this as a wildcard read). On the other hand, if the \mdline{2208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2208} message field is +set, a single entry will be read.%mdk + +%mdk-data-line={2211} +\mdline{2211}Let\mdline{2211}'\mdline{2211}s look at the counter example in more details. Based on this specification +document, the C++ server code which processes \mdline{2212}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2212} messages may look +like this:%mdk + +%mdk-data-line={2214} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2215} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}auto}}~*counter\_entry~=~...\\ +{\bfseries{\mdcolor{navy}if}}~(counter\_entry-\textgreater{}has\_index())~\{\\ +~~{\bfseries{\mdcolor{navy}auto}}~index~=~counter\_entry-\textgreater{}index().index();\\ +~~read\_one\_entry(counter\_entry-\textgreater{}id(),~index);\\ +\}~{\bfseries{\mdcolor{navy}else}}~\{\\ +~~read\_all\_entries(counter\_entry-\textgreater{}id());\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2224} +\begin{enumerate}%mdk + +%mdk-data-line={2224} +\item{} +%mdk-data-line={2224} +\mdline{2224}Reading a single counter entry at index 0 in the counter array with id +\mdline{2225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textless{}id\textgreater{}}}}\mdline{2225}:%mdk + +%mdk-data-line={2226} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2226} +\item\mdline{2226}Here is the C++ client code: + +%mdk-data-line={2227} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2228} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});\\ +entry.mutable\_index();\\ +{\mdcolor{darkgreen}//~The~above~line~sets~the~index~field;~it~is~equivalent~to:}\\ +{\mdcolor{darkgreen}//~auto~*index~=~entry.mutable\_index();}\\ +{\mdcolor{darkgreen}//~index-\textgreater{}set\_index(0);}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2235} +\item\mdline{2235}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2236} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2237} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}\\ +index~\{\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2240} +\item\mdline{2240}\textbf{Expected behavior}\mdline{2240}: Counter entry at index 0 is read. Notice that the +\mdline{2241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2241} subfield is missing under the \mdline{2241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2241} field message of +\mdline{2242}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{2242} in the text dump of the message. This is because the +subfield is a scalar numeric type and 0 is therefore its default +value. Scalar fields with default values are omitted from the textual +representation of Protobuf messages.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2247} +\item{} +%mdk-data-line={2247} +\mdline{2247}Reading all counter entries by leaving the \mdline{2247}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2247} field unset%mdk + +%mdk-data-line={2248} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={2248} +\item\mdline{2248}Here is the C++ client code: + +%mdk-data-line={2249} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2250} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{navy}p4::}{\mdcolor{navy}v1::}CounterEntry~entry;\\ +entry.set\_counter\_id(\textless{}id\textgreater{});}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2253} +\item\mdline{2253}Here is the corresponding Protobuf message in text format: + +%mdk-data-line={2254} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2255} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id:~\textless{}id\textgreater{}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={2257} +\item\mdline{2257}\textbf{Expected behavior}\mdline{2257}: All counter entries for the provided counter +instance are read. Notice that the \mdline{2258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{2258} message field is unset (default +value) and is therefore omitted from the textual representation of the +message.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={2262} +\subsection{\mdline{2262}8.2.\hspace*{0.5em}\mdline{2262}Read-Write Symmetry}\label{sec-read-write-symmetry}%mdk%mdk + +%mdk-data-line={2264} +\noindent\mdline{2264}The reads and writes a client issues towards a server should be symmetrical and +unambiguous. More specifically, if a client writes a P4 entity and then reads it +back then the client should expect that the message it wrote and the message it +read should match if the RPCs finished successfully (with the exception of parts +of the response known to be data plane volatile, as explained in section +\mdline{2269}\mdref{sec-data-plane-volatile-objects}{8.2.1}\mdline{2269}). Consider the following pseudocode as an +example:%mdk + +%mdk-data-line={2272} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2273} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}intended\_value~=~value\\ +\\ +status~=~server.write(intended\_value,~p4\_entity)\\ +observed\_value~=~server.read(p4\_entity)\\ +\\ +assert(intended\_value~==~observed\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2281} +\noindent\mdline{2281}To ensure read-write symmetry, the rest of this document tries to offer +canonical representations for various data types, but this principle should be +thought of where it falls short. Ensuring this will allow client software to +recover programmatically from failures that can affect the switch stack +software, communication channel, or the client replicas. If \mdline{2285}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{2285} RPC returns a +semantically-same but syntactically-different response then the client would +have to canonicalize the read values to check its internal state, which only +pushes the protocol\mdline{2288}'\mdline{2288}s complexities to the client implementations.%mdk + +%mdk-data-line={2290} +\mdline{2290}In order to avoid placing too much burden on the P4Runtime server +implementation, we do not in general mandate that the order of values in a +Protobuf repeated field be preserved. For example, the server is not required to +preserve the order of the \mdline{2293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{2293} fields in a \mdline{2293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2293} message. If there is +a specific case for which the order is significant and / or needs to be +preserved, it will be explicitly stated in this document. The +\mdline{2296}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MessageDifferencer}}}\mdline{2296} class\mdline{2296}~[\mdcite{protomessagedifferencer}{42}]\mdline{2296} included in the Protobuf +C++ API supports comparing messages while treating repeated fields as sets, so +that different orderings of the same elements are considered equal. This method +of comparing Protobuf messages may come at a cost in performance.%mdk + +%mdk-data-line={2301} +\subsubsection{\mdline{2301}8.2.1.\hspace*{0.5em}\mdline{2301}Data plane volatile objects}\label{sec-data-plane-volatile-objects}%mdk%mdk + +%mdk-data-line={2303} +\noindent\mdline{2303}An exception to read-write symmetry are objects whose contents or +fields can change by the action of the data plane alone, even if no +controller modifies them. These objects are called data plane +volatile.%mdk + +%mdk-data-line={2308} +\mdline{2308}The following sections describe all possible values of an \mdline{2308}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{2308} +message, since these are the messages that a controller can use to +modify objects in the data plane via an \mdline{2310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{2310} message. For each, a +description is given of the parts of that entity that are data plane +volatile.%mdk + +%mdk-data-line={2314} +\paragraph{\mdline{2314}8.2.1.1.\hspace*{0.5em}\mdline{2314}ExternEntry}\label{sec-externentry}%mdk%mdk + +%mdk-data-line={2316} +\noindent\mdline{2316}Data plane volatility depends upon the definition of the extern and +its control plane API.%mdk + +%mdk-data-line={2319} +\paragraph{\mdline{2319}8.2.1.2.\hspace*{0.5em}\mdline{2319}TableEntry}\label{sec-tableentry}%mdk%mdk + +%mdk-data-line={2321} +\noindent\mdline{2321}For a table with a direct counter associated with it, the \mdline{2321}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2321} +field of a \mdline{2322}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2322} can be modified by the data plane when packets +match the entry.%mdk + +%mdk-data-line={2325} +\mdline{2325}For a table with a direct meter associated with it, the +\mdline{2326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{2326} field of a \mdline{2326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2326} can be modified by the data +plane when packets match the entry.%mdk + +%mdk-data-line={2329} +\mdline{2329}For a PSA\mdline{2329}~[\mdcite{psa}{24}]\mdline{2329} table with property \mdline{2329}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_idle\_timeout}}}\mdline{2329} equal to +\mdline{2330}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PSA\_IdleTimeout\_t.NOTIFY\_CONTROL}}}\mdline{2330}, the data plane can modify the +\mdline{2331}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{2331} field of a \mdline{2331}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2331} when \mdline{2331}\emph{no}\mdline{2331} packets match the entry +for an implementation-specific amount of time.%mdk + +%mdk-data-line={2334} +\mdline{2334}For a PNA\mdline{2334}~[\mdcite{pna}{23}]\mdline{2334} table with property \mdline{2334}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}pna\_idle\_timeout}}}\mdline{2334} equal to +\mdline{2335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PNA\_IdleTimeout\_t.NOTIFY\_CONTROL}}}\mdline{2335} or \mdline{2335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PNA\_IdleTimeout\_t.AUTO\_DELETE}}}\mdline{2335} +the data plane can modify the \mdline{2336}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{2336} field of a \mdline{2336}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2336} +when \mdline{2337}\emph{no}\mdline{2337} packets cause the extern function \mdline{2337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}restart\_expire\_timer}}}\mdline{2337} to +be called for an implementation-specific amount of time (nor any other +extern function defined to also have the same effect as +\mdline{2340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}restart\_expire\_timer}}}\mdline{2340}).%mdk + +%mdk-data-line={2342} +\mdline{2342}Similarly, for a table in PNA with any of the values of +\mdline{2343}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}pna\_idle\_timeout}}}\mdline{2343} listed above, the data plane can modify the +\mdline{2344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{2344} field of a \mdline{2344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{2344} when packets match the entry +and the action calls the \mdline{2345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}set\_entry\_expire\_time}}}\mdline{2345} extern function (or any +of the other extern functions defined to have an effect similar to +calling \mdline{2347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}set\_entry\_expire\_time}}}\mdline{2347}).%mdk + +%mdk-data-line={2349} +\mdline{2349}For a PNA\mdline{2349}~[\mdcite{pna}{23}]\mdline{2349} table with the property \mdline{2349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}add\_on\_miss}}}\mdline{2349} equal to \mdline{2349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}true}}}\mdline{2349} +the data plane can insert new entries into the table without any +controller\mdline{2351}'\mdline{2351}s involvement.%mdk + +%mdk-data-line={2353} +\mdline{2353}For a PNA\mdline{2353}~[\mdcite{pna}{23}]\mdline{2353} table with the property \mdline{2353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}pna\_idle\_timeout}}}\mdline{2353} equal to +\mdline{2354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PNA\_IdleTimeout\_t.AUTO\_DELETE}}}\mdline{2354}, the data plane can delete existing +entries from the table without any controller\mdline{2355}'\mdline{2355}s involvement.%mdk + +%mdk-data-line={2357} +\paragraph{\mdline{2357}8.2.1.3.\hspace*{0.5em}\mdline{2357}ActionProfileMember}\label{sec-actionprofilemember}%mdk%mdk + +%mdk-data-line={2359} +\noindent\mdline{2359}Not data plane volatile in any architectures defined by P4.org +specifications.%mdk + +%mdk-data-line={2362} +\paragraph{\mdline{2362}8.2.1.4.\hspace*{0.5em}\mdline{2362}ActionProfileGroup}\label{sec-actionprofilegroup}%mdk%mdk + +%mdk-data-line={2364} +\noindent\mdline{2364}Not data plane volatile in any architectures defined by P4.org +specifications. The \mdline{2365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{2365} feature does affect how action +selectors behave while processing packets, but this feature does not +affect what a P4Runtime client sees when it reads the configuration.%mdk + +%mdk-data-line={2369} +\paragraph{\mdline{2369}8.2.1.5.\hspace*{0.5em}\mdline{2369}MeterEntry}\label{sec-meterentry}%mdk%mdk + +%mdk-data-line={2371} +\noindent\mdline{2371}The field \mdline{2371}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2371} is modified by the data plane when the +corresponding meter is updated in the data plane.%mdk + +%mdk-data-line={2374} +\paragraph{\mdline{2374}8.2.1.6.\hspace*{0.5em}\mdline{2374}DirectMeterEntry}\label{sec-directmeterentry}%mdk%mdk + +%mdk-data-line={2376} +\noindent\mdline{2376}The field \mdline{2376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{2376} is modified by the data plane when the +corresponding meter is updated in the data plane.%mdk + +%mdk-data-line={2379} +\paragraph{\mdline{2379}8.2.1.7.\hspace*{0.5em}\mdline{2379}CounterEntry}\label{sec-counterentry}%mdk%mdk + +%mdk-data-line={2381} +\noindent\mdline{2381}The field \mdline{2381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{2381} is modified by the data plane when the corresponding +counter is updated in the data plane.%mdk + +%mdk-data-line={2384} +\paragraph{\mdline{2384}8.2.1.8.\hspace*{0.5em}\mdline{2384}DirectCounterEntry}\label{sec-directcounterentry}%mdk%mdk + +%mdk-data-line={2386} +\noindent\mdline{2386}The field \mdline{2386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{2386} is modified by the data plane when the corresponding +counter is updated in the data plane.%mdk + +%mdk-data-line={2389} +\paragraph{\mdline{2389}8.2.1.9.\hspace*{0.5em}\mdline{2389}PacketReplicationEngineEntry}\label{sec-packetreplicationengineentry}%mdk%mdk + +%mdk-data-line={2391} +\noindent\mdline{2391}Not data plane volatile in any architectures defined by P4.org +specifications.%mdk + +%mdk-data-line={2394} +\paragraph{\mdline{2394}8.2.1.10.\hspace*{0.5em}\mdline{2394}ValueSetEntry}\label{sec-valuesetentry}%mdk%mdk + +%mdk-data-line={2396} +\noindent\mdline{2396}Not data plane volatile in any architectures defined by P4.org +specifications.%mdk + +%mdk-data-line={2399} +\paragraph{\mdline{2399}8.2.1.11.\hspace*{0.5em}\mdline{2399}RegisterEntry}\label{sec-registerentry}%mdk%mdk + +%mdk-data-line={2401} +\noindent\mdline{2401}The field \mdline{2401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{2401} can be modified by the data plane when the +corresponding register entry is updated in the data plane.%mdk + +%mdk-data-line={2404} +\paragraph{\mdline{2404}8.2.1.12.\hspace*{0.5em}\mdline{2404}DigestEntry}\label{sec-digestentry}%mdk%mdk + +%mdk-data-line={2406} +\noindent\mdline{2406}Not data plane volatile in any architectures defined by P4.org +specifications.%mdk + +%mdk-data-line={2409} +\subsection{\mdline{2409}8.3.\hspace*{0.5em}\mdline{2409}Bytestrings}\label{sec-bytestrings}%mdk%mdk + +%mdk-data-line={2411} +\noindent\mdline{2411}P4Runtime integer values may be too large to fit in Protobuf primitive data +types (32-bit and 64-bit words). The P4 language does not put any limit on the +size of integer values, whether unsigned (\mdline{2413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2413}) or signed (\mdline{2413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2413}), and it +is up to the P4 programmer to choose the appropriate sizes. Because of this +flexibility, P4Runtime represents P4 integer values as binary strings, using the +\mdline{2416}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2416} Protobuf type. The correct bitwidth\mdline{2416} \mdline{2416}\textemdash{}\mdline{2416} as per the P4 program\mdline{2416} \mdline{2416}\textemdash{}\mdline{2416} of +each integer variable exposed through P4Runtime is specified in the P4Info +message.%mdk + +%mdk-data-line={2420} +\mdline{2420}The canonical binary string representation uses the shortest string that +fits the encoded integer value. This representation achieves three goals:%mdk + +%mdk-data-line={2423} +\begin{itemize}%mdk + +%mdk-data-line={2423} +\item{} +%mdk-data-line={2423} +\mdline{2423}It ensures that a properly encoded binary string\mdline{2423}'\mdline{2423}s integer value conforms +to the P4Info-specified bitwidth.%mdk%mdk + +%mdk-data-line={2426} +\item{} +%mdk-data-line={2426} +\mdline{2426}It supports\mdline{2426}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2426}.%mdk%mdk + +%mdk-data-line={2428} +\item{} +%mdk-data-line={2428} +\mdline{2428}It helps facilitate non-disruptive P4 program updates.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2430} +\noindent\mdline{2430}In particular, the kinds of P4 program updates that this representation +facilitates are those where a P4Runtime server and client can continue to +transmit P4Runtime messages between them when one has a P4Info file for version +A of a P4 program, at the same time that the other has a P4Info file for version +B of a P4 program, and those P4 programs differ in the bitwidths of some values +of type \mdline{2435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2435} and/or \mdline{2435}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2435}.%mdk + +%mdk-data-line={2437} +\mdline{2437}Note that this representation does \mdline{2437}\emph{not}\mdline{2437} make it possible to seamlessly change +the type of a value from signed to unsigned, or vice versa. If you attempt to +do so, this mechanism can quietly change negative signed values to positive +unsigned values, or vice versa. It also limits the magnitude of the values +transmitted to those that fit within the smaller of the bitwidths supported by +either end of the message transmission. If a message sender attempts to send a +value larger than the receiver expects, the receiver will detect it as out of +range.%mdk + +%mdk-data-line={2446} +\mdline{2446}In the P4Runtime API version 1.0 (including minor version revisions), values +of table key fields, action parameters, and fields in packet-in and packet-out +headers between a device and the controller (see\mdline{2448}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{2448}), +may not be of type \mdline{2449}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2449}. The rules for encoding signed values thus only +apply to messages of type \mdline{2450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2450} (see\mdline{2450}~\mdref{sec-p4data-in-p4runtime-proto}{8.4.3}\mdline{2450}).%mdk + +%mdk-data-line={2452} +\mdline{2452}For a value of type \mdline{2452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2452}, the fewest number of bits required to represent +the integer value \mdline{2453}$V > 0$\mdline{2453} is the smallest integer \mdline{2453}$A$\mdline{2453} such that \mdline{2453}$V \leq 2^A -1$\mdline{2454}.%mdk + +%mdk-data-line={2456} +\mdline{2456}For a value of type \mdline{2456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2456}, the fewest number of bits required to represent +the integer value \mdline{2457}$V \neq 0$\mdline{2457} in 2\mdline{2457}'\mdline{2457}s complement form is the smallest integer \mdline{2457}$A$\mdline{2457} +such that \mdline{2458}$-2^{A-1} \leq V \leq 2^{A-1} - 1$\mdline{2458}.%mdk + +%mdk-data-line={2460} +\mdline{2460}As a special case, define that the value \mdline{2460}$V=0$\mdline{2460} requires at least \mdline{2460}$A=1$\mdline{2460} bit to +represent, regardless of whether it is signed or unsigned.%mdk + +%mdk-data-line={2463} +\mdline{2463}The shortest possible binary string for an integer \mdline{2463}$V$\mdline{2463} that needs \mdline{2463}$A$\mdline{2463} bits to +represent it is computed as:%mdk + +%mdk-data-line={2465} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={2466} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size~=~floor(({\mdcolor{teal}A}~+~{\mdcolor{purple}7})~/~{\mdcolor{purple}8})}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2469} +\noindent\mdline{2469}Binary strings with the byte length computed as \mdline{2469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2469} promote +P4Runtime read-write symmetry in both client-to-server requests and +server-to-client replies.%mdk + +%mdk-data-line={2473} +\mdline{2473}Any additional bits in the bytes sent for an unsigned integer value (type +\mdline{2474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2474}) must be 0. If additional bytes are transmitted above the +\mdline{2475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2475} minimum required, they must be filled with 0.%mdk + +%mdk-data-line={2477} +\mdline{2477}Any additional bits in the bytes sent for a signed integer value (type \mdline{2477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2477}) +must be copies of the sign bit, \mdline{2478}i.e.\mdline{2478} 0 for non-negative values, or 1 for +negative values. If additional bytes are transmitted above the +\mdline{2480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}minimum\_string\_size}}}\mdline{2480} minimum required, they must be filled with copies of the +sign bit, \mdline{2481}i.e.\mdline{2481} 0 for non-negative values, or 0xff for negative values. In 2\mdline{2481}'\mdline{2481}s +complement representation, this is called \mdline{2482}\textquotedblleft{}sign extension\textquotedblright{}\mdline{2482}, and leaves the +numeric value represented unchanged.%mdk + +%mdk-data-line={2485} +\mdline{2485}Upon receiving a binary string, the P4Runtime receiver (whether the server or +the client) does not impose any restrictions on the maximum length of the string +itself. Instead, the receiver verifies that the value encoded by the string fits +within the expected type (signed or unsigned) and P4Info-specified bitwidth for +the P4 object value.%mdk + +%mdk-data-line={2491} +\mdline{2491}For a received bitstring expected to fit within a \mdline{2491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2491} type, the value it +represents is in range if, after removing all most significant 0 bits, the +remaining bitstring\mdline{2493}'\mdline{2493}s width is \mdline{2493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2493} bits or less.%mdk + +%mdk-data-line={2495} +\mdline{2495}For a received bitstring expected to fit within an \mdline{2495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2495} type, the value it +represents is in range if, after \mdline{2496}\textquotedblleft{}undoing sign extension\textquotedblright{}\mdline{2496}, the remaining bit +string\mdline{2497}'\mdline{2497}s width is \mdline{2497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2497} bits or less. To undo sign extension, start by eliminating +the most significant bit, but only if it is equal to the bit that follows it +(otherwise removing the most significant bit would change the sign of the +value). Repeat that process until either only a single bit remains, or until the +two most significant bits are different from each other.%mdk + +%mdk-data-line={2503} +\mdline{2503}If the string\mdline{2503}'\mdline{2503}s byte length is zero, the server always rejects the string.%mdk + +%mdk-data-line={2505} +\mdline{2505}When the server rejects a binary string due to any of the previous criteria, +it returns an \mdline{2506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2506} error.%mdk + +%mdk-data-line={2508} +\mdline{2508}For all binary strings, P4Runtime uses big-endian (\mdline{2508}i.e.\mdline{2508} network) byte-order. +For signed integer values (\mdline{2509}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2509} P4 type), P4Runtime uses the same two\mdline{2509}'\mdline{2509}s +complement bitwise representation as P4. Table\mdline{2510}~\mdref{tab-valid-bytestring-encoding}{\mdcaptionlabel{4}}\mdline{2510} +shows various examples of integer values that the server accepts as valid +P4Runtime binary strings according to the criteria in the list above.%mdk + +%mdk-data-line={2514} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2516} P4 type}}&\multicolumn{1}{|c}{{\bfseries\mdline{2516} Integer value}}&\multicolumn{1}{|c}{{\bfseries\mdline{2516} P4Runtime binary string}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2516} Read-write symmetry}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2518} \mdline{2518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2518}}&\multicolumn{1}{|l}{\mdline{2518} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2518} \mdline{2518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2518}}&\multicolumn{1}{|l|}{\mdline{2518} yes}\\ +\multicolumn{1}{|l}{\mdline{2519} \mdline{2519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2519}}&\multicolumn{1}{|l}{\mdline{2519} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2519} \mdline{2519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2519}}&\multicolumn{1}{|l|}{\mdline{2519} no}\\ +\multicolumn{1}{|l}{\mdline{2520} \mdline{2520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2520}}&\multicolumn{1}{|l}{\mdline{2520} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2520} \mdline{2520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2520}}&\multicolumn{1}{|l|}{\mdline{2520} yes}\\ +\multicolumn{1}{|l}{\mdline{2521} \mdline{2521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2521}}&\multicolumn{1}{|l}{\mdline{2521} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2521} \mdline{2521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x30\textbackslash{}x64}}}\mdline{2521}}&\multicolumn{1}{|l|}{\mdline{2521} yes}\\ +\multicolumn{1}{|l}{\mdline{2522} \mdline{2522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2522}}&\multicolumn{1}{|l}{\mdline{2522} 12388 (0x3064)}&\multicolumn{1}{|l}{\mdline{2522} \mdline{2522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x30\textbackslash{}x64}}}\mdline{2522}}&\multicolumn{1}{|l|}{\mdline{2522} no}\\ +\multicolumn{1}{|l}{\mdline{2523} \mdline{2523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2523}}&\multicolumn{1}{|l}{\mdline{2523} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2523} \mdline{2523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x63}}}\mdline{2523}}&\multicolumn{1}{|l|}{\mdline{2523} no}\\ +\multicolumn{1}{|l}{\mdline{2524} \mdline{2524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2524}}&\multicolumn{1}{|l}{\mdline{2524} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2524} \mdline{2524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2524}}&\multicolumn{1}{|l|}{\mdline{2524} yes}\\ +\multicolumn{1}{|l}{\mdline{2525} \mdline{2525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2525}}&\multicolumn{1}{|l}{\mdline{2525} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2525} \mdline{2525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00\textbackslash{}x63}}}\mdline{2525}}&\multicolumn{1}{|l|}{\mdline{2525} no}\\ +\multicolumn{1}{|l}{\mdline{2526} \mdline{2526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2526}}&\multicolumn{1}{|l}{\mdline{2526} 99 (0x63)}&\multicolumn{1}{|l}{\mdline{2526} \mdline{2526}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x63}}}\mdline{2526}}&\multicolumn{1}{|l|}{\mdline{2526} yes}\\ +\multicolumn{1}{|l}{\mdline{2527} \mdline{2527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2527}}&\multicolumn{1}{|l}{\mdline{2527} \mdline{2527}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2527} \mdline{2527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x9d}}}\mdline{2527}}&\multicolumn{1}{|l|}{\mdline{2527} yes}\\ +\multicolumn{1}{|l}{\mdline{2528} \mdline{2528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2528}}&\multicolumn{1}{|l}{\mdline{2528} \mdline{2528}-99 (-0x63)}&\multicolumn{1}{|l}{\mdline{2528} \mdline{2528}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xff\textbackslash{}x9d}}}\mdline{2528}}&\multicolumn{1}{|l|}{\mdline{2528} no}\\ +\multicolumn{1}{|l}{\mdline{2529} \mdline{2529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2529}}&\multicolumn{1}{|l}{\mdline{2529} \mdline{2529}-739 (-0x2e3)}&\multicolumn{1}{|l}{\mdline{2529} \mdline{2529}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}xfd\textbackslash{}x1d}}}\mdline{2529}}&\multicolumn{1}{|l|}{\mdline{2529} yes}\\ +\multicolumn{1}{|l}{\mdline{2530} \mdline{2530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2530}}&\multicolumn{1}{|l}{\mdline{2530} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2530} \mdline{2530}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x00}}}\mdline{2530}}&\multicolumn{1}{|l|}{\mdline{2530} no}\\ +\multicolumn{1}{|l}{\mdline{2531} \mdline{2531}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2531}}&\multicolumn{1}{|l}{\mdline{2531} 0 (0x0)}&\multicolumn{1}{|l}{\mdline{2531} \mdline{2531}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00}}}\mdline{2531}}&\multicolumn{1}{|l|}{\mdline{2531} yes}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2533} +\mdhr{}%mdk + +%mdk-data-line={2534} +\noindent\mdline{2534}\mdcaption{\textbf{Table~\mdcaptionlabel{4}.}~\mdcaptiontext{Examples of Valid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-valid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2536} +\mdline{2536}Table\mdline{2536}~\mdref{tab-invalid-bytestring-encoding}{\mdcaptionlabel{5}}\mdline{2536} shows some examples of invalid +P4Runtime binary strings:%mdk + +%mdk-data-line={2539} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{2541} P4 type}}&\multicolumn{1}{|c|}{{\bfseries\mdline{2541} P4Runtime binary string}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2543} \mdline{2543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2543}}&\multicolumn{1}{|l|}{\mdline{2543} \mdline{2543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x63}}}\mdline{2543}}\\ +\multicolumn{1}{|l}{\mdline{2544} \mdline{2544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2544}}&\multicolumn{1}{|l|}{\mdline{2544} \mdline{2544}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2544}}\\ +\multicolumn{1}{|l}{\mdline{2545} \mdline{2545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}16\textgreater{}}}}\mdline{2545}}&\multicolumn{1}{|l|}{\mdline{2545} \mdline{2545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2545}}\\ +\multicolumn{1}{|l}{\mdline{2546} \mdline{2546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2546}}&\multicolumn{1}{|l|}{\mdline{2546} \mdline{2546}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x10\textbackslash{}x63}}}\mdline{2546}}\\ +\multicolumn{1}{|l}{\mdline{2547} \mdline{2547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2547}}&\multicolumn{1}{|l|}{\mdline{2547} \mdline{2547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x01\textbackslash{}x00\textbackslash{}x63}}}\mdline{2547}}\\ +\multicolumn{1}{|l}{\mdline{2548} \mdline{2548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}12\textgreater{}}}}\mdline{2548}}&\multicolumn{1}{|l|}{\mdline{2548} \mdline{2548}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x40\textbackslash{}x63}}}\mdline{2548}}\\ +\multicolumn{1}{|l}{\mdline{2549} \mdline{2549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}8\textgreater{}}}}\mdline{2549}}&\multicolumn{1}{|l|}{\mdline{2549} \mdline{2549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x00\textbackslash{}x9d}}}\mdline{2549}}\\ +\multicolumn{1}{|l}{\mdline{2550} \mdline{2550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}12\textgreater{}}}}\mdline{2550}}&\multicolumn{1}{|l|}{\mdline{2550} \mdline{2550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\textbackslash{}x8d\textbackslash{}x1d}}}\mdline{2550}}\\ +\multicolumn{1}{|l}{\mdline{2551} \mdline{2551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}16\textgreater{}}}}\mdline{2551}}&\multicolumn{1}{|l|}{\mdline{2551} \mdline{2551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}empty~string}}}\mdline{2551}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2553} +\mdhr{}%mdk + +%mdk-data-line={2554} +\noindent\mdline{2554}\mdcaption{\textbf{Table~\mdcaptionlabel{5}.}~\mdcaptiontext{Examples of Invalid Bytestring Encoding}}%mdk +%mdk +\end{mdcenter}\label{tab-invalid-bytestring-encoding}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2556} +\mdline{2556}As the preceding examples illustrate, a P4Runtime server must accept a wide +assortment of possible binary string encodings for the same integer value. +This requirement addresses P4 program upgrade scenarios where binary string +widths can expand or contract. In some P4Runtime environments, the changes +cannot be deployed simultaneously to all P4Runtime clients and servers. Given +a hypothetical match field type change from \mdline{2561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2561} to \mdline{2561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2561}, a server +running the \mdline{2562}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}9\textgreater{}}}}\mdline{2562} version of the P4 program will accept requests from +clients that remain on the \mdline{2563}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}8\textgreater{}}}}\mdline{2563} P4Runtime version.%mdk + +%mdk-data-line={2565} +\mdline{2565}Despite the server\mdline{2565}'\mdline{2565}s binary string flexibility for P4 program update support, +the client and server must both remain aware of the +\mdline{2567}\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{2567} +requirements. As described earlier, read-write symmetry requires that +the encoder of a P4Runtime request or reply uses the shortest strings that +fit the encoded integer values.%mdk + +%mdk-data-line={2572} +\mdline{2572}Representation of variable-length integer values (\mdline{2572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2572} P4 type) is +similar to the representation of fixed-width unsigned integers. We use a binary +string, whose length is the \mdline{2574}\emph{dynamic-length}\mdline{2574} of the expression. When the value +is provided by the P4Runtime client, the server must verify that the length of +the binary string is less than the maximum length specified in the P4 program, +and return an \mdline{2577}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{2577} error code otherwise.%mdk + +%mdk-data-line={2579} +\subsection{\mdline{2579}8.4.\hspace*{0.5em}\mdline{2579}Representation of Arbitrary P4 Types}\label{sec-representation-of-arbitrary-p4-types}%mdk%mdk + +%mdk-data-line={2581} +\subsubsection{\mdline{2581}8.4.1.\hspace*{0.5em}\mdline{2581}Problem Statement}\label{sec-problem-statement}%mdk%mdk + +%mdk-data-line={2583} +\noindent\mdline{2583}The P4\mdline{2583}\mdsub{16}\mdline{2583} language includes more complex types than just binary strings +\mdline{2584}[\mdcite{p4complextypes}{5}]\mdline{2584}. Most of these complex data types can be exposed to the +control plane through table key expressions, Value Set lookup expressions, +Register (PSA extern type) value types, etc. Not supporting these more complex +types can be very limiting. Table\mdline{2587}~\mdref{tab-p4-type-usage}{\mdcaptionlabel{6}}\mdline{2587} shows the different +P4\mdline{2588}\mdsub{16}\mdline{2588} types and how they are allowed to be used, as per the P4\mdline{2588}\mdsub{16}\mdline{2588} +specification.%mdk + +%mdk-data-line={2591} +\begin{table}[tbp]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{4}{\dimeval{(\linewidth)/4}}{1ex}%mdk +\begin{tabular}{llll}\midrule +\multicolumn{1}{|l}{{\bfseries\mdline{2593}}}&\multicolumn{3}{|c|}{{\bfseries\mdline{2593} Container type}}\\ +\cmidrule{2-2}\cmidrule{3-3}\cmidrule{4-4} +\multicolumn{1}{|l}{{\bfseries\mdline{2595} Element type}}&\multicolumn{1}{|l}{{\bfseries\mdline{2595} header}}&\multicolumn{1}{|l}{{\bfseries\mdline{2595} header\mdline{2595}\_\mdline{2595}union}}&\multicolumn{1}{|l|}{{\bfseries\mdline{2595} struct or tuple}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{2597} \mdline{2597}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2597}}&\multicolumn{1}{|l}{\mdline{2597} allowed}&\multicolumn{1}{|l}{\mdline{2597} error}&\multicolumn{1}{|l|}{\mdline{2597} allowed}\\ +\multicolumn{1}{|l}{\mdline{2598} \mdline{2598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2598}}&\multicolumn{1}{|l}{\mdline{2598} allowed}&\multicolumn{1}{|l}{\mdline{2598} error}&\multicolumn{1}{|l|}{\mdline{2598} allowed}\\ +\multicolumn{1}{|l}{\mdline{2599} \mdline{2599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2599}}&\multicolumn{1}{|l}{\mdline{2599} allowed}&\multicolumn{1}{|l}{\mdline{2599} error}&\multicolumn{1}{|l|}{\mdline{2599} allowed}\\ +\multicolumn{1}{|l}{\mdline{2600} \mdline{2600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int}}}\mdline{2600}}&\multicolumn{1}{|l}{\mdline{2600} error}&\multicolumn{1}{|l}{\mdline{2600} error}&\multicolumn{1}{|l|}{\mdline{2600} error}\\ +\multicolumn{1}{|l}{\mdline{2601} \mdline{2601}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}void}}}\mdline{2601}}&\multicolumn{1}{|l}{\mdline{2601} error}&\multicolumn{1}{|l}{\mdline{2601} error}&\multicolumn{1}{|l|}{\mdline{2601} error}\\ +\multicolumn{1}{|l}{\mdline{2602} \mdline{2602}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2602}}&\multicolumn{1}{|l}{\mdline{2602} error}&\multicolumn{1}{|l}{\mdline{2602} error}&\multicolumn{1}{|l|}{\mdline{2602} allowed}\\ +\multicolumn{1}{|l}{\mdline{2603} \mdline{2603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match\_kind}}}\mdline{2603}}&\multicolumn{1}{|l}{\mdline{2603} error}&\multicolumn{1}{|l}{\mdline{2603} error}&\multicolumn{1}{|l|}{\mdline{2603} error}\\ +\multicolumn{1}{|l}{\mdline{2604} \mdline{2604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2604}}&\multicolumn{1}{|l}{\mdline{2604} error}&\multicolumn{1}{|l}{\mdline{2604} error}&\multicolumn{1}{|l|}{\mdline{2604} allowed}\\ +\multicolumn{1}{|l}{\mdline{2605} \mdline{2605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2605}}&\multicolumn{1}{|l}{\mdline{2605} allowed\mdline{2605}\mdfootnote{1}{%mdk-data-line={2615} +%mdk-data-line={2615} +\noindent\mdline{2615}an \mdline{2615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2615} type used as a field in a \mdline{2615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2615} must specify a +underlying type and representation for \mdline{2616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2616} elements.%mdk +\label{fn-enum_header}%mdk%mdk +}\mdline{2605}}&\multicolumn{1}{|l}{\mdline{2605} error}&\multicolumn{1}{|l|}{\mdline{2605} allowed}\\ +\multicolumn{1}{|l}{\mdline{2606} \mdline{2606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2606}}&\multicolumn{1}{|l}{\mdline{2606} error}&\multicolumn{1}{|l}{\mdline{2606} allowed}&\multicolumn{1}{|l|}{\mdline{2606} allowed}\\ +\multicolumn{1}{|l}{\mdline{2607} header stack}&\multicolumn{1}{|l}{\mdline{2607} error}&\multicolumn{1}{|l}{\mdline{2607} error}&\multicolumn{1}{|l|}{\mdline{2607} allowed}\\ +\multicolumn{1}{|l}{\mdline{2608} \mdline{2608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2608}}&\multicolumn{1}{|l}{\mdline{2608} error}&\multicolumn{1}{|l}{\mdline{2608} error}&\multicolumn{1}{|l|}{\mdline{2608} allowed}\\ +\multicolumn{1}{|l}{\mdline{2609} \mdline{2609}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2609}}&\multicolumn{1}{|l}{\mdline{2609} error}&\multicolumn{1}{|l}{\mdline{2609} error}&\multicolumn{1}{|l|}{\mdline{2609} allowed}\\ +\multicolumn{1}{|l}{\mdline{2610} \mdline{2610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2610}}&\multicolumn{1}{|l}{\mdline{2610} error}&\multicolumn{1}{|l}{\mdline{2610} error}&\multicolumn{1}{|l|}{\mdline{2610} allowed}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={2612} +\mdhr{}%mdk + +%mdk-data-line={2613} +\noindent\mdline{2613}\mdcaption{\textbf{Table~\mdcaptionlabel{6}.}~\mdcaptiontext{P4 Type Usage}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-type-usage}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={2618} +\mdline{2618}For example, the following P4\mdline{2618}\mdsub{16}\mdline{2618} objects involve complex types that need to be +exposed in P4Runtime in order to support runtime operations on these objects.%mdk + +%mdk-data-line={2621} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2622} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}{\bfseries{\mdcolor{navy}tuple}}\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}4}\textgreater{},~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~\textgreater{}~\textgreater{}()~digest\_complex;\\ +digest\_complex.pack(\{~hdr.ipv4.version,~hdr.ipv4.protocol~\});\\ +{\mdcolor{darkgreen}//~...}\\ +{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2632} +\noindent\mdline{2632}One solution would be to use only binary string (\mdline{2632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2632} type) in +p4runtime.proto and to define a custom serialization format for complex P4\mdline{2633}\mdsub{16}\mdline{2633} +types. The serialization would maybe be trivial for header types but would +require some work for header unions, header stacks, etc. For example, in the +case of a PSA Register storing header unions, a client reading from that +Register would need to receive information about which member header is valid, +in addition to the binary contents of this header. Rather than coming-up with a +serialization format from scratch, we decided to use a Protobuf representation +for all P4\mdline{2640}\mdsub{16}\mdline{2640} types.%mdk + +%mdk-data-line={2642} +\subsubsection{\mdline{2642}8.4.2.\hspace*{0.5em}\mdline{2642}P4 Type Specifications in p4info.proto}\label{sec-p4-type-specifications-in-p4infoproto}%mdk%mdk + +%mdk-data-line={2644} +\noindent\mdline{2644}In order for the P4Runtime client to generate correctly-formatted messages and +for the P4Runtime service implementation to validate them, P4Info needs to +specify the type of each P4 expression which is exposed to the control plane. In +the Register example above, client and server need to know that each element of +the register has type \mdline{2648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ip\_t}}}\mdline{2648}, which is a header union with 2 possible headers: +\mdline{2649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4}}}\mdline{2649} with type \mdline{2649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv4\_t}}}\mdline{2649} and \mdline{2649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6}}}\mdline{2649} with type \mdline{2649}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ipv6\_t}}}\mdline{2649}. Similarly, they need to +know the field layout for both of these header types.%mdk + +%mdk-data-line={2652} +\mdline{2652}To achieve this we introduce 2 main Protobuf messages: \mdline{2652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2652} and +\mdline{2653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2653}.%mdk + +%mdk-data-line={2655} +\mdline{2655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2655} is a top-level member of P4Info and includes Protobuf maps storing +the type specification for all the named types in the P4\mdline{2656}\mdsub{16}\mdline{2656} program. These +named types are \mdline{2657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2657}, \mdline{2657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2657}, \mdline{2657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2657}, \mdline{2657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2657} and +\mdline{2658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2658}; for each of these we have a type specification message, +respectively \mdline{2659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructTypeSpec}}}\mdline{2659}, \mdline{2659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderTypeSpec}}}\mdline{2659}, \mdline{2659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionTypeSpec}}}\mdline{2659}, +\mdline{2660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4EnumTypeSpec}}}\mdline{2660} and \mdline{2660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4SerializableEnumTypeSpec}}}\mdline{2660}. We preserve P4 annotations +for named types, which is useful to identify well-known headers, such as IPv4 or +IPv6. \mdline{2662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2662} also includes the list of parser errors for the program, as +a \mdline{2663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4ErrorTypeSpec}}}\mdline{2663} message.%mdk + +%mdk-data-line={2665} +\mdline{2665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2665} is meant to be used in P4Info, to specify the expected format +of the P4-dependent values being exchanged between the P4Runtime client and +server. Each \mdline{2667}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2667} message corresponds to a compile-time type in the +original P4\mdline{2668}\mdsub{16}\mdline{2668} program (\mdline{2668}e.g.\mdline{2668} the type parameter of an extern). This +compile-time type is represented as a Protobuf \mdline{2669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2669}, which can be:%mdk + +%mdk-data-line={2671} +\begin{itemize}%mdk + +%mdk-data-line={2671} +\item{} +%mdk-data-line={2671} +\mdline{2671}a string representing the name of the type in case of a named type (\mdline{2671}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2671}, +\mdline{2672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2672}, \mdline{2672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2672}, \mdline{2672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2672}, \mdline{2672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}serializable\_enum}}}\mdline{2672} or user-defined \mdline{2672}\textquotedblleft{}new\textquotedblright{}\mdline{2672} +\mdline{2673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2673}),%mdk%mdk + +%mdk-data-line={2675} +\item{} +%mdk-data-line={2675} +\mdline{2675}an empty Protobuf message for \mdline{2675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{2675} and \mdline{2675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2675}, or%mdk%mdk + +%mdk-data-line={2677} +\item{} +%mdk-data-line={2677} +\mdline{2677}a Protobuf message for other anonymous types (\mdline{2677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2677}, \mdline{2677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2677}, \mdline{2677}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2677}, +\mdline{2678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2678} or stack). The \mdline{2678}\textquotedblleft{}binary string\textquotedblright{}\mdline{2678} types (\mdline{2678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2678}, \mdline{2678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{2678}, and +\mdline{2679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}varbit\textless{}W\textgreater{}}}}\mdline{2679}) are grouped together in the \mdline{2679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4BitstringLikeTypeSpec}}}\mdline{2679} message, +since they are the only sub-types allowed in headers and values with one of +these types are represented similarly in P4Runtime (with the Protobuf \mdline{2681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2681} +type).%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2684} +\noindent\mdline{2684}For all P4\mdline{2684}\mdsub{16}\mdline{2684} compound types (\mdline{2684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tuple}}}\mdline{2684}, \mdline{2684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}struct}}}\mdline{2684}, \mdline{2684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header}}}\mdline{2684}, and \mdline{2684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}header\_union}}}\mdline{2684}), +the order of \mdline{2685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2685} in the repeated field of the Protobuf type specification +is guaranteed to be the same as the order of the members in the corresponding +P4\mdline{2687}\mdsub{16}\mdline{2687} declaration. The same goes for the order of members of an \mdline{2687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2687} +(serializable or not) or members of \mdline{2688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2688}.%mdk + +%mdk-data-line={2690} +\subsubsection{\mdline{2690}8.4.3.\hspace*{0.5em}\mdline{2690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2690} in p4runtime.proto}\label{sec-p4data-in-p4runtime-proto}%mdk%mdk + +%mdk-data-line={2692} +\noindent\mdline{2692}P4Runtime uses the \mdline{2692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2692} message to represent values of arbitrary types. The +P4Runtime client must generate correct \mdline{2693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2693} messages based on the type +specification information included in P4Info. The \mdline{2694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2694} message was designed +to introduce little overhead compared to using binary strings in the most common +case (P4\mdline{2696}\mdsub{16}\mdline{2696} \mdline{2696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2696} type).%mdk + +%mdk-data-line={2698} +\mdline{2698}Just like its P4Info counterpart\mdline{2698} \mdline{2698}- \mdline{2698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4DataTypeSpec}}}\mdline{2698} \mdline{2698}-, \mdline{2698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2698} uses a Protobuf +\mdline{2699}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2699} to represent all possible values.%mdk + +%mdk-data-line={2701} +\mdline{2701}We define a canonical representation for \mdline{2701}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2701} messages\mdline{2701} \mdline{2701}\textemdash{}\mdline{2701} therefore +guaranteeing read-write symmetry\mdline{2702} \mdline{2702}\textemdash{}\mdline{2702} by introducing the following requirements:%mdk + +%mdk-data-line={2704} +\begin{itemize}%mdk + +%mdk-data-line={2704} +\item{} +%mdk-data-line={2704} +\mdline{2704}The order of \mdline{2704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{2704} in \mdline{2704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4StructLike}}}\mdline{2704} and the order of \mdline{2704}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2704} in +\mdline{2705}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2705} must match the order in the corresponding p4info.proto type +specification and hence the order in the corresponding P4\mdline{2706}\mdsub{16}\mdline{2706} type +declaration.%mdk%mdk + +%mdk-data-line={2709} +\item{} +%mdk-data-line={2709} +\mdline{2709}An invalid header is represented by a \mdline{2709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Header}}}\mdline{2709} message where the \mdline{2709}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_valid}}}\mdline{2709} +field is false and the \mdline{2710}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitstrings}}}\mdline{2710} repeated field is empty.%mdk%mdk + +%mdk-data-line={2712} +\item{} +%mdk-data-line={2712} +\mdline{2712}An invalid header union (\mdline{2712}i.e.\mdline{2712} all headers in the union are invalid) is +represented by a \mdline{2713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnion}}}\mdline{2713} message where the \mdline{2713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header\_name}}}\mdline{2713} is the +empty string (default value for the field) and the \mdline{2714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}valid\_header}}}\mdline{2714} is unset.%mdk%mdk + +%mdk-data-line={2716} +\item{} +%mdk-data-line={2716} +\mdline{2716}The order of \mdline{2716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2716} in \mdline{2716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStack}}}\mdline{2716} and \mdline{2716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStack}}}\mdline{2716} is from +element at index 0 of the stack to last element of the stack, in ascending +order of index. The length of the \mdline{2718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{2718} field must always be equal to the +compile-time size of the corresponding P4 stack declaration. This size is +included in the P4Info, in the corresponding \mdline{2720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderStackTypeSpec}}}\mdline{2720} or +\mdline{2721}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4HeaderUnionStackTypeSpec}}}\mdline{2721} message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2723} +\subsubsection{\mdline{2723}8.4.4.\hspace*{0.5em}\mdline{2723}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={2725} +\noindent\mdline{2725}Let\mdline{2725}'\mdline{2725}s look at the Register example again:%mdk + +%mdk-data-line={2727} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2728} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}header\_union}}~ip\_t~\{\\ +~~~ipv4\_t~ipv4;\\ +~~~ipv6\_t~ipv6;\\ +\}\\ +Register\textless{}ip\_t,~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~\textgreater{}({\mdcolor{purple}128})~register\_ip;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2735} +\noindent\mdline{2735}Here\mdline{2735}'\mdline{2735}s the corresponding entry in the P4Info message:%mdk + +%mdk-data-line={2737} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2738} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}registers~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}369119267}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}register\_ip}{\mdcolor{maroon}"}\\ +~~\}\\ +~~type\_spec~\{\\ +~~~~header\_union~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~size:~{\mdcolor{purple}128}\\ +\}\\ +type\_info~\{\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~headers~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}version}{\mdcolor{maroon}"}\\ +~~~~~~~~type\_spec~\{\\ +~~~~~~~~~~bit~\{\\ +~~~~~~~~~~~~bitwidth:~{\mdcolor{purple}4}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}~{\mdcolor{darkgreen}\#~...}\\ +~~header\_unions~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}ip\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~~~members~\{\\ +~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6}{\mdcolor{maroon}"}\\ +~~~~~~~~header~\{\\ +~~~~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv6\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2794} +\noindent\mdline{2794}Here\mdline{2794}'\mdline{2794}s a \mdline{2794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.WriteRequest}}}\mdline{2794} to set the value of \mdline{2794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_ip{}[12]}}}\mdline{2794}:%mdk + +%mdk-data-line={2796} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2797} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}update~\{\\ +~~type:~INSERT\\ +~~entity~\{\\ +~~~~register\_entry~\{\\ +~~~~~~register\_id:~{\mdcolor{purple}369119267}\\ +~~~~~~index~\{\\ +~~~~~~~~index:~{\mdcolor{purple}12}\\ +~~~~~~\}\\ +~~~~~~data~\{\\ +~~~~~~~~header\_union~\{\\ +~~~~~~~~~~valid\_header\_name:~{\mdcolor{maroon}"}{\mdcolor{maroon}ipv4}{\mdcolor{maroon}"}\\ +~~~~~~~~~~valid\_header~\{\\ +~~~~~~~~~~~~is\_valid:~true\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x04}{\mdcolor{maroon}"}\\ +~~~~~~~~~~~~bitstrings:~{\mdcolor{darkgreen}\#~...}\\ +~~~~~~~~~~\}\\ +~~~~~~~~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2820} +\subsubsection{\mdline{2820}8.4.5.\hspace*{0.5em}\mdline{2820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2820}, serializable \mdline{2820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2820} and \mdline{2820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}}\label{sec-enum-serializable-enum-and-error}%mdk%mdk + +%mdk-data-line={2822} +\noindent\mdline{2822}P4\mdline{2822}\mdsub{16}\mdline{2822} supports 2 different classes of enumeration types: without underlying +type (safe enum) and with underlying type (serializable enum or \mdline{2823}\textquotedblleft{}unsafe\textquotedblright{}\mdline{2823} enum) +\mdline{2824}[\mdcite{p4enums}{7}]\mdline{2824}. For \mdline{2824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2824} types with no underlying type\mdline{2824} \mdline{2824}\textemdash{}\mdline{2824} as well as \mdline{2824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2824} \mdline{2824}\textemdash{}\mdline{2824} +there is no integer value associated with each symbolic member entry (whether +assigned automatically by the compiler or directly in the P4 source). We +therefore use a human-readable string in \mdline{2827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2827} to represent \mdline{2827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2827} and +\mdline{2828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{2828} values.%mdk + +%mdk-data-line={2830} +\mdline{2830}Serializable \mdline{2830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{2830} types have an underlying fixed-width unsigned integer +representation (\mdline{2831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2831}). All named enum members must be assigned an integer +value by the P4 programmer, but \mdline{2832}\emph{not all}\mdline{2832} valid numeric values for the +underlying type need to have a corresponding name. \mdline{2833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2833} includes the +mapping between entry name and entry value. When providing serializable enum +values through \mdline{2835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2835}, one must use the assigned integer value (\mdline{2835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum\_value}}}\mdline{2835} +bytestring field). P4Runtime does not provide a way for the client to use the +name\mdline{2837} \mdline{2837}\textemdash{}\mdline{2837} even when the enum member has one\mdline{2837} \mdline{2837}\textemdash{}\mdline{2837} instead of the value, as it makes +it easier for the server to respect the\mdline{2838}~\mdref{sec-read-write-symmetry}{read-write +symmetry}\mdline{2839} principle.%mdk + +%mdk-data-line={2841} +\subsubsection{\mdline{2841}8.4.6.\hspace*{0.5em}\mdline{2841}User-defined types}\label{sec-user-defined-types}%mdk%mdk + +%mdk-data-line={2843} +\noindent\mdline{2843}P4\mdline{2843}\mdsub{16}\mdline{2843} enables programmers to introduce new types\mdline{2843}~[\mdcite{p4newtypes}{13}]\mdline{2843}. While similar +to \mdline{2844}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{2844}, this mechanism introduces in fact a new type, which is not a +strict synonym of the original type. It is important to preserve this +distinction in the P4Info message, in particular for the purposes of +\mdline{2847}\mdref{sec-psa-metadata-translation}{translation}\mdline{2847}. When introducing a new type, the +declaration can be annotated with \mdline{2848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2848} to indicate that the +type exposed to the P4Runtime client is different from the original P4 type. One +important use-case is for\mdline{2850}~\mdref{sec-translation-of-port-numbers}{port numbers}\mdline{2850}, +whose underlying data plane representation may vary on different targets, but +for which it may be convenient to present a unified representation and numbering +scheme to the control plane. \mdline{2853}\textbf{The \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}} annotation can only +be used if the underlying P4 built-in type is a fixed-width unsigned bitstring +type (\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}})}\mdline{2855}. The type exposed to the control plane (referred to as the +\mdline{2856}\emph{controller\_type}\mdline{2856}) can be either a fixed-width unsigned bitstring, with a +potentially different bitwidth, or a string. The annotation takes two +parameters: a \mdline{2858}\emph{URI}\mdline{2858} (Uniform Resource Identifier) which uniquely identifies the +translation being performed on entities of the new type to the P4Runtime server +and the \mdline{2860}\emph{controller\_type}\mdline{2860} of the values exposed to the control plane. The +\mdline{2861}\emph{controller\_type}\mdline{2861} can be either \mdline{2861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2861} where \mdline{2861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2861} is any positive integer, or +\mdline{2862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{2862}, or a positive integer \mdline{2862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{2862} which has the same meaning as \mdline{2862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2862}. +Specifying just an integer is deprecated.%mdk + +%mdk-data-line={2865} +\mdline{2865}It is recommended that the URI includes at least the P4 architecture name and +the type name.%mdk + +%mdk-data-line={2868} +\mdline{2868}A \mdline{2868}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2868} annotation need not have any effect if it is used to +annotate anything in a P4 program other than a \mdline{2869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2869} declaration. It is +recommended that P4 development tools have an option to issue a warning if such +an annotation is used in a part of a P4 program where it has no effect.%mdk + +%mdk-data-line={2873} +\mdline{2873}User-defined types are specified using the \mdline{2873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{2873} message, which has +the following fields:%mdk + +%mdk-data-line={2876} +\begin{itemize}%mdk + +%mdk-data-line={2876} +\item{} +%mdk-data-line={2876} +\mdline{2876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}representation}}}\mdline{2876}, a Protobuf \mdline{2876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{2876} specifying how values of this type are +exchanged between client and server; it can be either:%mdk + +%mdk-data-line={2879} +\begin{itemize}%mdk + +%mdk-data-line={2879} +\item{} +%mdk-data-line={2879} +\mdline{2879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2879}, if and only if no \mdline{2879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2879} annotation is +present. It specifies the underlying built-in P4 type for the user-defined +type. If the underlying type used in the P4 \mdline{2881}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2881} declaration is itself a +user-defined type, \mdline{2882}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}original\_type}}}\mdline{2882} is obtained by \mdline{2882}\textquotedblleft{}walking\textquotedblright{}\mdline{2882} the chain of +\mdline{2883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2883} declarations recursively until a built-in type (\mdline{2883}e.g.\mdline{2883} \mdline{2883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{2883}) is +found.%mdk%mdk + +%mdk-data-line={2886} +\item{} +%mdk-data-line={2886} +\mdline{2886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}translated\_type}}}\mdline{2886}, if and only if the P4 \mdline{2886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{2886} declaration was annotated +with \mdline{2887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2887}. It is of type \mdline{2887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeTranslation}}}\mdline{2887}, +which itself has two fields\mdline{2888} \mdline{2888}\textemdash{}\mdline{2888} \mdline{2888}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uri}}}\mdline{2888} and either \mdline{2888}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_string}}}\mdline{2888} or +\mdline{2889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sdn\_bitwidth}}}\mdline{2889} \mdline{2889}\textemdash{}\mdline{2889}, which map to the two input parameters to the +annotation.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={2892} +\item{} +%mdk-data-line={2892} +\mdline{2892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}annotations}}}\mdline{2892}, a repeated field of strings, each one representing a P4 +annotation associated to the type declaration.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2895} +\noindent\mdline{2895}For example, an architecture\mdline{2895} \mdline{2895}\textemdash{}\mdline{2895} in this case PSA\mdline{2895} \mdline{2895}\textemdash{}\mdline{2895} may introduce a new type +for port numbers:%mdk + +%mdk-data-line={2897} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2898} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~string,~e.g.~"eth0".}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{darkgreen}//~Controller~refers~to~ports~as~a~32-bit~integer,~e.g.~0xffffffff.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{darkgreen}//~Same~as~above.}\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_32\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_32\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2911} +\noindent\mdline{2911}In this case, the P4Info message would include the following \mdline{2911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2911} +messages:%mdk + +%mdk-data-line={2914} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={2915} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_string:~\{\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}\\ +\\ +type\_info~\{\\ +~~new\_types~\{\\ +~~~~key:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~value~\{~~{\mdcolor{darkgreen}\#~P4NewTypeSpec}\\ +~~~~~~translated\_type~\{~~{\mdcolor{darkgreen}\#~P4NewTypeTranslation}\\ +~~~~~~~~uri:~{\mdcolor{maroon}"}{\mdcolor{maroon}p4.org/psa/v1/PortId\_32\_t}{\mdcolor{maroon}"}\\ +~~~~~~~~sdn\_bitwidth:~{\mdcolor{purple}32}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={2952} +\noindent\mdline{2952}Note that a P4 compiler may provide a mechanism external to the language to +specify if and how a user-defined type is to be translated (\mdline{2953}e.g.\mdline{2953} through some +configuration file passed on the command-line when invoking the compiler). This +mechanism should take precedence over \mdline{2955}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{2955} to enable users +to overwrite annotations included as part of the P4 architecture definition.%mdk + +%mdk-data-line={2958} +\subsubsection{\mdline{2958}8.4.7.\hspace*{0.5em}\mdline{2958}Trade-off for v1.x Releases}\label{sec-trade-off-for-v1x-releases}%mdk%mdk + +%mdk-data-line={2960} +\noindent\mdline{2960}For the v1.x release ofs P4Runtime, it was decided not to replace occurrences of +\mdline{2961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2961} with \mdline{2961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2961} in the \mdline{2961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{2961} message, which is used to +represent table and Value Set entries. This is to avoid breaking pre-v1.0 +implementations of P4Runtime. Similarly it has been decided to keep using +\mdline{2964}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{2964} to provide action parameter values and controller metadata +values. However \mdline{2965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2965} is used whenever appropriate for PSA externs and we +encourage the use of \mdline{2966}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{2966} in architecture-specific extensions.%mdk + +%mdk-data-line={2968} +\mdline{2968}In order to support\mdline{2968}~\mdref{sec-psa-metadata-translation}{translation}\mdline{2968} for action +parameters and match fields, we include a \mdline{2969}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2969} field in +\mdline{2970}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{2970}, \mdline{2970}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Action.Param}}}\mdline{2970} and +\mdline{2971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ControllerPacketMetadata.Metadata}}}\mdline{2971}. In addition, the \mdline{2971}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2971} +field for all of these message types must abide by the following rule when +\mdline{2973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_name}}}\mdline{2973} names a translated user-defined type:%mdk + +%mdk-data-line={2975} +\begin{itemize}%mdk + +%mdk-data-line={2975} +\item{} +%mdk-data-line={2975} +\mdline{2975}If the \mdline{2975}\emph{controller\_type}\mdline{2975} is a fixed-width unsigned bitstring, the \mdline{2975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2975} +field must be set to the bitwidth of the \mdline{2976}\emph{controller\_type}\mdline{2976}. This information +is redundant with the one included in the \mdline{2977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4TypeInfo}}}\mdline{2977} entry for the +user-defined type, but we believe that it may simplify P4Runtime server +implementations by making this information more readily available. We also +believe that using the bitwidth of the underlying type here would be +inappropriate as it would make the P4Info message target-dependent.%mdk%mdk + +%mdk-data-line={2983} +\item{} +%mdk-data-line={2983} +\mdline{2983}Otherwise (\mdline{2983}i.e.\mdline{2983}, if the \mdline{2983}\emph{controller\_type}\mdline{2983} is a string), the \mdline{2983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bitwidth}}}\mdline{2983} must +be \mdline{2984}\textquotedblleft{}unset\textquotedblright{}\mdline{2984}, which, in Protobuf version 3, is the same as setting the field to +0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={2987} +\noindent\mdline{2987}For example, consider the following P4 snippet, which declares a P4 table +matching on two expressions with translated user-defined types:%mdk + +%mdk-data-line={2989} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={2990} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_String\_t",~string)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_String\_t;\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_Bit32\_t",~bit\textless{}32\textgreater{})}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_Bit32\_t;\\ +\\ +{\mdcolor{navy}@}{\mdcolor{navy}name}{\mdcolor{maroon}(".t")}\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~meta.port1:~exact;~~{\mdcolor{darkgreen}//~meta.port1~has~type~PortId\_String\_t}\\ +~~~~meta.port2:~exact;~~{\mdcolor{darkgreen}//~meta.port2~has~type~PortId\_Bit32\_t}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3008} +\noindent\mdline{3008}This table would have the following representation in the generated P4Info +message:%mdk + +%mdk-data-line={3010} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3011} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tables~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}34728461}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~~~alias:~{\mdcolor{maroon}"}{\mdcolor{maroon}t}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port1}{\mdcolor{maroon}"}\\ +~~~~{\mdcolor{darkgreen}\#~notice~that~bitwidth~is~unset}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_String\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~match\_fields~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}meta.port2}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~match\_type:~EXACT\\ +~~~~type\_name~\{\\ +~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_Bit32\_t}{\mdcolor{maroon}"}\\ +~~~~\}\\ +~~\}\\ +~~{\mdcolor{darkgreen}\#~...}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3039} +\section{\mdline{3039}9.\hspace*{0.5em}\mdline{3039}P4 Entity Messages}\label{sec-p4-entity-msgs}%mdk%mdk + +%mdk-data-line={3041} +\noindent\mdline{3041}P4Runtime covers P4 entities that are either part of the P4\mdline{3041}\mdsub{16}\mdline{3041} language, or +defined as PSA externs. The sections below describe the messages for each +supported entity.%mdk + +%mdk-data-line={3045} +\subsection{\mdline{3045}9.1.\hspace*{0.5em}\mdline{3045}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}}\label{sec-table-entry}%mdk%mdk + +%mdk-data-line={3047} +\noindent\mdline{3047}The match-action table is the core packet-processing construct of the P4 +language. It consists of a collection of table entries, or flow rules, each +mapping a key value to a P4 action along with input values for the action\mdline{3049}'\mdline{3049}s +parameters. Packets are looked-up in the table by matching them against the flow +rules. In case of a match, the corresponding action is applied on the packet, +otherwise, a default action is applied. The exact behavior of P4 tables is +described in the P4 specification.%mdk + +%mdk-data-line={3055} +\mdline{3055}P4Runtime supports inserting, modifying, deleting and reading table entries with +the \mdline{3056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3056} entity, which has the following fields:%mdk + +%mdk-data-line={3058} +\begin{itemize}%mdk + +%mdk-data-line={3058} +\item{} +%mdk-data-line={3058} +\mdline{3058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3058}, which identifies the table instance; the \mdline{3058}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3058} is determined +by the P4Info message.%mdk%mdk + +%mdk-data-line={3061} +\item{} +%mdk-data-line={3061} +\mdline{3061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3061}, a repeated field of \mdline{3061}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3061} messages. Each element in the +repeated field is used to provide a value for the corresponding element in the +key property of the P4 table declaration.%mdk%mdk + +%mdk-data-line={3065} +\item{} +%mdk-data-line={3065} +\mdline{3065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3065}, which indicates which of the table\mdline{3065}'\mdline{3065}s actions to execute in case of +match and with which argument values.%mdk%mdk + +%mdk-data-line={3068} +\item{} +%mdk-data-line={3068} +\mdline{3068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3068}, a 32-bit integer used to order entries when the table\mdline{3068}'\mdline{3068}s match key +includes an optional, ternary or range match.%mdk%mdk + +%mdk-data-line={3071} +\item{} +%mdk-data-line={3071} +\mdline{3071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3071}, a 64-bit cookie value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry. This is deprecated in favor of the more flexible +\mdline{3075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3075} field.%mdk%mdk + +%mdk-data-line={3077} +\item{} +%mdk-data-line={3077} +\mdline{3077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3077}, an arbitrary \mdline{3077}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{3077} value which is opaque to the +target. There is no requirement of where this is stored, but it must be +returned by the server along with the rest of the entry when the client +performs a read on the entry.%mdk%mdk + +%mdk-data-line={3082} +\item{} +%mdk-data-line={3082} +\mdline{3082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3082}, which is used to read and write the configuration for the +direct meter entry attached to this table entry, if any. See\mdline{3083}~\mdref{sec-direct-resources}{Direct +resources}\mdline{3084} section for more information.%mdk%mdk + +%mdk-data-line={3086} +\item{} +%mdk-data-line={3086} +\mdline{3086}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3086}, which is used to read and write the value for the direct +counter entry attached to this table entry, if any. See\mdline{3087}~\mdref{sec-direct-resources}{Direct +resources}\mdline{3088} section for more information.%mdk%mdk + +%mdk-data-line={3090} +\item{} +%mdk-data-line={3090} +\mdline{3090}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3090}, which is used to read and write the per-color counter +values for the direct meter entry attached to this table entry, if any. +See\mdline{3092}~\mdref{sec-direct-resources}{Direct resources}\mdline{3092} section for more information.%mdk%mdk + +%mdk-data-line={3094} +\item{} +%mdk-data-line={3094} +\mdline{3094}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3094}, a boolean flag which indicates whether the table entry is +the default entry for the table. See\mdline{3095}~\mdref{sec-default-entry}{Default entry}\mdline{3095} +section for more information.%mdk%mdk + +%mdk-data-line={3098} +\item{} +%mdk-data-line={3098} +\mdline{3098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3098} and \mdline{3098}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3098}, which are two fields used to +implement idle-timeout support for the table, if applicable. See +\mdline{3100}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{3100} section for more information.%mdk%mdk + +%mdk-data-line={3102} +\item{} +%mdk-data-line={3102} +\mdline{3102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const}}}\mdline{3102}, a boolean value that is \mdline{3102}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}true}}}\mdline{3102} if and only if the entry +cannot be modified or deleted by the client.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3105} +\noindent\mdline{3105}The \mdline{3105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3105} field must be set to a non-zero value if the match key includes a +ternary match (\mdline{3106}i.e.\mdline{3106} in the case of PSA if the P4Info entry for the table +indicates that one or more of its match fields has an \mdline{3107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3107}, \mdline{3107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3107} or +\mdline{3108}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3108} match +type) or to zero otherwise. A higher priority number indicates that the entry +must be given higher priority when performing a table lookup. Clients must allow +multiple entries to be added with the same priority value. If a packet can +match multiple entries with the same priority, it is not deterministic in the +data plane which entry a packet will match. If a client wishes to make the +matching behavior deterministic, it must use different priority values for any +pair of table entries that the same packet matches.%mdk + +%mdk-data-line={3117} +\mdline{3117}The \mdline{3117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3117} and \mdline{3117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3117} fields are used to uniquely identify an entry within +a table. Therefore, these fields cannot be modified after the entry has been +inserted and must be provided for \mdline{3119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3119} and \mdline{3119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3119} updates. When deleting +an entry, these key fields (along with \mdline{3120}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3120}) are the only fields +considered by the server. All other fields must be ignored, even if they have +nonsensical values (such as an invalid action field). In the case of a \mdline{3122}\emph{keyless}\mdline{3122} +table (the table has an empty match key), the server must reject all attempts to +\mdline{3124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3124} a match entry and return an \mdline{3124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3124} error.%mdk + +%mdk-data-line={3126} +\mdline{3126}The number of match entries that a table \mdline{3126}\emph{should}\mdline{3126} support is indicated in P4Info +(\mdline{3127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{3127} field of \mdline{3127}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Table}}}\mdline{3127} message). The guarantees provided to the P4Runtime +client are the same as the ones described in the P4\mdline{3128}\mdsub{16}\mdline{3128} specification for the +\mdline{3129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{3129} property\mdline{3129}~[\mdcite{p4tableproperties}{36}]\mdline{3129}. In particular, some implementations may +not be able to always accommodate an arbitrary set of entries up to the +requested size, and other implementations may provide the P4Runtime client with +more entries than requested. The P4Runtime server must return +\mdline{3133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3133} when a table entry cannot be inserted because of a size +limitation. It is recommended that, for the sake of portability, P4Runtime +clients do not try to insert additional entries once the size indicated in +P4Info has been reached.%mdk + +%mdk-data-line={3138} +\mdline{3138}The \mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const}}}\mdline{3138} field must be \mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}false}}}\mdline{3138} in any \mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3138}, \mdline{3138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3138}, or +\mdline{3139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3139} write request of a table entry. If it is true, the server +must reject the operation and return an \mdline{3140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3140} error.%mdk + +%mdk-data-line={3142} +\subsubsection{\mdline{3142}9.1.1.\hspace*{0.5em}\mdline{3142}Match Format}\label{sec-match-format}%mdk%mdk + +%mdk-data-line={3144} +\noindent\mdline{3144}The bytes fields in the \mdline{3144}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3144} message follow the format described in +\mdline{3145}\mdref{sec-bytestrings}{Bytestrings}\mdline{3145}.%mdk + +%mdk-data-line={3147} +\mdline{3147}For \mdline{3147}\textquotedblleft{}don't care\textquotedblright{}\mdline{3147} matches, the P4Runtime client must omit the field\mdline{3147}'\mdline{3147}s entire +\mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{3148} entry when building the \mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3148} repeated field of the \mdline{3148}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3148} +message. This requirement leads to smaller Protobuf messages overall, while +enabling a canonical representation for \mdline{3150}\textquotedblleft{}don't care\textquotedblright{}\mdline{3150} matches, which is needed +to ensure\mdline{3151}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{3151}. For PSA match types, +a \mdline{3152}\textquotedblleft{}don't care\textquotedblright{}\mdline{3152} match for a specific match key field is defined as follows:%mdk + +%mdk-data-line={3154} +\begin{itemize}%mdk + +%mdk-data-line={3154} +\item{} +%mdk-data-line={3154} +\mdline{3154}For a \mdline{3154}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3154} match, it is logically equivalent to a mask of zeros.%mdk%mdk + +%mdk-data-line={3156} +\item{} +%mdk-data-line={3156} +\mdline{3156}For a \mdline{3156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3156} match, it is logically equivalent to a wildcard match.%mdk%mdk + +%mdk-data-line={3158} +\item{} +%mdk-data-line={3158} +\mdline{3158}For an \mdline{3158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{3158} match, it is logically equivalent to a prefix\mdline{3158}\_\mdline{3158}len of zero.%mdk%mdk + +%mdk-data-line={3160} +\item{} +%mdk-data-line={3160} +\mdline{3160}For a \mdline{3160}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3160} match, it is logically equivalent to a range which includes all +possible values for the field.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3163} +\noindent\mdline{3163}Note that there is no \mdline{3163}\textquotedblleft{}don't care\textquotedblright{}\mdline{3163} value for \mdline{3163}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3163} matches and therefore exact +match fields can never be omitted from the \mdline{3164}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3164} message.%mdk + +%mdk-data-line={3166} +\mdline{3166}The following example shows a P4Runtime message that treats a \mdline{3166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3166} field +as a \mdline{3167}\textquotedblleft{}don't care\textquotedblright{}\mdline{3167} match. The P4 program defines table \mdline{3167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3167} with \mdline{3167}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3167} +and \mdline{3168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3168} fields in its match key:%mdk + +%mdk-data-line={3170} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3171} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~ternary;\\ +~~~~istd.ingress\_port:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3182} +\noindent\mdline{3182}In this P4Runtime request, the client omits the table\mdline{3182}'\mdline{3182}s \mdline{3182}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3182} field +from the repeated \mdline{3183}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3183} field to indicate a \mdline{3183}\textquotedblleft{}don't care\textquotedblright{}\mdline{3183} match. As shown +below, the \mdline{3184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3184} specifies only the \mdline{3184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3184} field given by \mdline{3184}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id:~2}}}\mdline{3184}.%mdk + +%mdk-data-line={3186} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3187} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}33554439}~~{\mdcolor{darkgreen}\#~Table~t's~ID.}\\ +~~~~match~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~field\_id~1~is~not~present~to~use~the~don't~care~ternary~value.}\\ +~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~exact~\{\\ +~~~~~~~~value:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x20}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~action~\{\\ +~~~~~~{\mdcolor{darkgreen}\#~Action~selection~goes~here.}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3205} +\noindent\mdline{3205}For every member of the \mdline{3205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3205} repeated \mdline{3205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3205} field, \mdline{3205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_id}}}\mdline{3205} must be +a valid id for the table, as per the P4Info, and one of the fields in +\mdline{3207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{3207} must be set. We summarize additional constraints which depend +on the match-type in the following list. If any one of them is violated, the +P4Runtime server must return an \mdline{3209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3209} error code.%mdk + +%mdk-data-line={3211} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3211} +\item\mdline{3211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3211} match + +%mdk-data-line={3212} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3212} +\item\mdline{3212}The binary string encoding of the value must conform to the +\mdline{3213}\mdref{sec-bytestrings}{Bytestrings}\mdline{3213} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3215} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3216} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.exact().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3219} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3219} +\item\mdline{3219}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{3219} match + +%mdk-data-line={3220} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3220} +\item\mdline{3220}The binary string encoding of the value (when present) must conform to the +\mdline{3221}\mdref{sec-bytestrings}{Bytestrings}\mdline{3221} requirements.%mdk + +%mdk-data-line={3222} +\item\mdline{3222}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3222} match must be omitted.%mdk + +%mdk-data-line={3223} +\item\mdline{3223}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3223} bits must be 0 in value.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3225} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3226} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.lpm().value()))\\ +\\ +pLen~=~match.lpm().prefix\_len()\\ +assert(pLen~\textgreater{}~0)\\ +\\ +trailing\_zeros~=~countTrailingZeros(match.lpm().value())\\ +assert(trailing\_zeros~\textgreater{}=~field\_bits~-~pLen)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3235} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3235} +\item\mdline{3235}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3235} match + +%mdk-data-line={3236} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3236} +\item\mdline{3236}The binary string encoding of the value (when present) and mask (when +present) must conform to the\mdline{3237}~\mdref{sec-bytestrings}{Bytestrings}\mdline{3237} requirements.%mdk + +%mdk-data-line={3238} +\item\mdline{3238}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3238} match must be omitted.%mdk + +%mdk-data-line={3239} +\item\mdline{3239}Masked bits must be 0 in value. This constraint taken together +with the\mdline{3240}~\mdref{sec-bytestrings}{Bytestrings}\mdline{3240} requirements means that the +value\mdline{3241}'\mdline{3241}s binary string is never longer than the mask\mdline{3241}'\mdline{3241}s binary string. +When the value\mdline{3242}'\mdline{3242}s string is shorter than the mask string, the +most-significant value bits need zero-padding before any logical +operations with the mask.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3246} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3247} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.ternary().value()))\\ +assert(BytestringValid(match.ternary().mask()))\\ +assert(match.ternary().value().size()~\textless{}=~match.ternary().mask().size());\\ +\\ +value~=~parseInteger(match.ternary().value())\\ +mask~=~parseInteger(match.ternary().mask())\\ +\\ +assert(mask~!=~0)\\ +\\ +assert(value~\&~mask~==~value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3259} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3259} +\item\mdline{3259}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3259} match + +%mdk-data-line={3260} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3260} +\item\mdline{3260}The binary string encoding of the low bound (when present) and high bound +(when present) must conform to the\mdline{3261}~\mdref{sec-bytestrings}{Bytestrings}\mdline{3261} +requirements.%mdk + +%mdk-data-line={3263} +\item\mdline{3263}Low bound must be less than or equal to the high bound.%mdk + +%mdk-data-line={3264} +\item\mdline{3264}\textquotedblleft{}Don't care\textquotedblright{}\mdline{3264} match must be omitted.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3266} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3267} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.range().low()))\\ +assert(BytestringValid(match.range().high()))\\ +\\ +low~=~parseInteger(match.range().low())\\ +high~=~parseInteger(match.range().high())\\ +\\ +assert(low~\textless{}=~high)\\ +\\ +assert(low~!=~min\_field\_value~\textbar{}\textbar{}~high~!=~max\_field\_value)}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3278} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3278} +\item\mdline{3278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3278} match + +%mdk-data-line={3279} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3279} +\item\mdline{3279}The binary string encoding of the value must conform to the +\mdline{3280}\mdref{sec-bytestrings}{Bytestrings}\mdline{3280} requirements.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3282} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={3283} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}assert(BytestringValid(match.optional().value()))}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3286} +\subsubsection{\mdline{3286}9.1.2.\hspace*{0.5em}\mdline{3286}Action Specification}\label{sec-action-specification}%mdk%mdk + +%mdk-data-line={3288} +\noindent\mdline{3288}The \mdline{3288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3288} \mdline{3288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3288} field must be set for every \mdline{3288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3288} update but may be +left unset for \mdline{3289}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3289} updates, in which case the action specification for the +table entry will not be modified (if a \mdline{3290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3290} update has an unset action field +and does not modify any direct resource attached to the table then the \mdline{3291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3291} +update is a no-op). Based on the implementation property value of the P4 table, +the \mdline{3293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3293} in the \mdline{3293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3293} message will either be:%mdk + +%mdk-data-line={3295} +\begin{itemize}%mdk + +%mdk-data-line={3295} +\item{} +%mdk-data-line={3295} +\mdline{3295}an \mdline{3295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3295} specification for direct tables (with no P4 \mdline{3295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3295} +property)%mdk%mdk + +%mdk-data-line={3298} +\item{} +%mdk-data-line={3298} +\mdline{3298}an action profile member id for indirect tables for which the \mdline{3298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3298} +property is an action profile with no selector.%mdk%mdk + +%mdk-data-line={3301} +\item{} +%mdk-data-line={3301} +\mdline{3301}an action profile member id or group id for indirect tables for which the +\mdline{3302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3302} property is an action profile with selector.%mdk%mdk + +%mdk-data-line={3304} +\item{} +%mdk-data-line={3304} +\mdline{3304}an \mdline{3304}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3304} specification for indirect tables for +which the \mdline{3305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3305} property is an action profile with +selector. This usage is described in\mdline{3306}~\mdref{sec-oneshot}{One Shot Action Selector +Programming}\mdline{3307}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3309} +\noindent\mdline{3309}If the \mdline{3309}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3309} does not match the table description in the P4Info (\mdline{3309}e.g.\mdline{3309} the +\mdline{3310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{3310} is \mdline{3310}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member\_id}}}\mdline{3310} for a direct table), the server must +return an \mdline{3311}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3311} error code.%mdk + +%mdk-data-line={3313} +\mdline{3313}The \mdline{3313}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Action}}}\mdline{3313} Protobuf message has the following fields:%mdk + +%mdk-data-line={3315} +\begin{itemize}%mdk + +%mdk-data-line={3315} +\item{} +%mdk-data-line={3315} +\mdline{3315}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3315}, which identifies the action instance; the \mdline{3315}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3315} is +determined by the P4Info message and must match one of the possible action +choices for the table, or the server must return an \mdline{3317}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3317} error +code. If the client uses a valid \mdline{3318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3318} for the table but does not +respect the action scope specified in P4Info (\mdline{3319}e.g.\mdline{3319} tries to set a \mdline{3319}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TABLE\_ONLY}}}\mdline{3319} +action as the default action), the server must return a \mdline{3320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3320} +error code.%mdk%mdk + +%mdk-data-line={3323} +\item{} +%mdk-data-line={3323} +\mdline{3323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}params}}}\mdline{3323}: a repeated Protobuf field of action parameter values, each encoded +as a \mdline{3324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{3324} message. For each parameter, \mdline{3324}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}param\_id}}}\mdline{3324} must be valid for the +action (as per the P4Info) and value must follow the format described in +\mdline{3326}\mdref{sec-bytestrings}{Bytestrings}\mdline{3326}. The P4Runtime client must provide a valid +value for each parameter of the P4 action; we do not support default values +for action parameters. The server must return an \mdline{3328}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3328} error code +if a parameter id is missing, if an extra parameter\mdline{3329} \mdline{3329}\textemdash{}\mdline{3329} id not found in the +P4Info\mdline{3330} \mdline{3330}\textemdash{}\mdline{3330} was provided by the client, if a parameter value is missing, or if +the value provided for one of the parameters does not conform to the +\mdline{3332}\mdref{sec-bytestrings}{Bytestrings}\mdline{3332} format.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3334} +\noindent\mdline{3334}For indirect tables, if the P4Runtime client provides a member or group id which +has not been inserted in the corresponding action profile instance yet, the +P4Runtime server must return a \mdline{3336}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3336} error code.%mdk + +%mdk-data-line={3338} +\subsubsection{\mdline{3338}9.1.3.\hspace*{0.5em}\mdline{3338}Default Entry}\label{sec-default-entry}%mdk%mdk + +%mdk-data-line={3340} +\noindent\mdline{3340}According to the P4 specification, the default entry for a table is always set. +It can be set at compile-time by the P4 programmer\mdline{3341} \mdline{3341}\textemdash{}\mdline{3341} or defaults to \mdline{3341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3341} +(which is a no-op) otherwise\mdline{3342} \mdline{3342}\textemdash{}\mdline{3342} and assuming it is not declared as \mdline{3342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3342}, can +be modified by the P4Runtime client. Because the default entry is always set, we +do not allow \mdline{3344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3344} and \mdline{3344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3344} updates on the default entry and the +P4Runtime server must return an \mdline{3345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3345} error code if the client +attempts one.%mdk + +%mdk-data-line={3348} +\mdline{3348}The default entry is identified by setting the \mdline{3348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3348} boolean field +to true. When this flag is set to true, the repeated \mdline{3349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3349} field must be empty +and the \mdline{3350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3350} field must be set to zero, otherwise the P4Runtime server +must return an \mdline{3351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3351} error code. When performing a \mdline{3351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3351} update +on the default entry, the client can either provide a valid action for the table +or leave the action field unset, in which case the default entry will be reset +to its original value, as defined in the P4 program. When resetting the default +entry, its \mdline{3355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3355} and \mdline{3355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3355} value as well as the +configurations for its\mdline{3356}~\mdref{sec-direct-resources}{direct resources}\mdline{3356} will be reset +to their defaults. If the default entry is constant (as indicated by the P4 +program and the P4Info message), the server must return a \mdline{3358}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3358} +error code if the client attempts to modify it.%mdk + +%mdk-data-line={3361} +\mdline{3361}Apart from the above restrictions, the default entry is treated like a regular +entry, including with regards to\mdline{3362}~\mdref{sec-direct-resources}{direct resources}\mdline{3362}.%mdk + +%mdk-data-line={3364} +\mdline{3364}In this P4Runtime release, we have decided to restrict the default entry for +indirect tables\mdline{3365} \mdline{3365}\textemdash{}\mdline{3365} tables with an ActionProfile or ActionSelector +\mdline{3366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}implementation}}}\mdline{3366} property\mdline{3366} \mdline{3366}\textemdash{}\mdline{3366} to a constant \mdline{3366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{3366} action entry, with the +hope that it would simplify the implementation of the P4Runtime service.%mdk + +%mdk-data-line={3369} +\subsubsection{\mdline{3369}9.1.4.\hspace*{0.5em}\mdline{3369}Constant Tables}\label{sec-constant-tables}%mdk%mdk + +%mdk-data-line={3371} +\noindent\mdline{3371}Constant tables are defined as tables whose match entries are +immutable. They are identified by the table property \mdline{3372}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const~entries}}}\mdline{3372} +in the P4\mdline{3373}\mdsub{16}\mdline{3373} source code. In the P4Info, such tables have +\mdline{3374}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3374} equal to true, and if the list of entries in the +source code has at least one entry in it, they also have +\mdline{3376}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}has\_initial\_entries}}}\mdline{3376} flag equal to true. For tables declared with +the \mdline{3377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3377} property, without \mdline{3377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3377} before \mdline{3377}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3377} see Section +\mdline{3378}\mdref{sec-preinitialized-tables}{9.1.5}\mdline{3378}.%mdk + +%mdk-data-line={3380} +\mdline{3380}The only write updates which are allowed for constant tables are \mdline{3380}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3380} +operations on direct resources, and the default action (assuming the default +action itself is not constant). If the P4Runtime client attempts to perform any +other kind of write update on a constant table the server must return a +\mdline{3384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3384} error. Just like any table entry \mdline{3384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3384} request, the +request must specify the match fields and priority to identify the table +entry. Because the action of a const entry cannot be modified, the request +may not specify an action, even if the action is equal to the existing action. +If an action is specified, the switch will return a \mdline{3388}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{3388} error.%mdk + +%mdk-data-line={3390} +\mdline{3390}The contents of const tables can be queried by the client through a +\mdline{3391}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3391}. When reading static (immutable) entries from a constant table, +the following fields must be set by the server: \mdline{3392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3392}, \mdline{3392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3392}, \mdline{3392}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3392}, +\mdline{3393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3393}, and \mdline{3393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3393} (if required). This is in addition to any +direct resources that are being queried. Idle timeouts are not supported for +static entries.%mdk + +%mdk-data-line={3397} +\mdline{3397}When a priority value is required (\mdline{3397}e.g.\mdline{3397} for tables including \mdline{3397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3397}, +\mdline{3398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3398} or \mdline{3398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3398} matches), it is inferred based on the order in +which entries appear in the table declaration. As of August 2023, the +open source \mdline{3400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{3400} compiler always assigns entry priority values in a +constant table with \mdline{3401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}N}}}\mdline{3401} entries starting at \mdline{3401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}N}}}\mdline{3401} for the first entry +and decrementing the value by 1 for each successive entry. The P4\mdline{3402}\mdsub{16}\mdline{3402} +language specification does not preclude the P4 developer from +explicitly specifying priorities for entries in constant tables, but +\mdline{3405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{3405} does not yet support this.%mdk + +%mdk-data-line={3407} +\subsubsection{\mdline{3407}9.1.5.\hspace*{0.5em}\mdline{3407}Preinitialized tables}\label{sec-preinitialized-tables}%mdk%mdk + +%mdk-data-line={3409} +\noindent\mdline{3409}Preinitialized tables are those defined with an \mdline{3409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3409} table +property in the P4\mdline{3410}\mdsub{16}\mdline{3410} source code, with no \mdline{3410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3410} qualifier before +\mdline{3411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3411}, and at least one entry in that list. In the P4Info, such +tables have \mdline{3412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}has\_initial\_entries}}}\mdline{3412} flag equal to true, but +\mdline{3413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3413} is false. For tables declared with \mdline{3413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const~entries}}}\mdline{3413}, +see Section\mdline{3414}~\mdref{sec-constant-tables}{9.1.4}\mdline{3414}.%mdk + +%mdk-data-line={3416} +\mdline{3416}Every P4 table falls into one of three categories:%mdk + +%mdk-data-line={3418} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3418} +\item\mdline{3418}\emph{Normal table}\mdline{3418}: Neither \mdline{3418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3418} nor \mdline{3418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const~entries}}}\mdline{3418} are declared +in the source code, and thus \mdline{3419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3419} and +\mdline{3420}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}has\_initial\_entries}}}\mdline{3420} will both be false. A corner case is that if +it has \mdline{3421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries~=~\{~\}}}}\mdline{3421} with no \mdline{3421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3421} before \mdline{3421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3421}, \mdline{3421}i.e.\mdline{3421} an +empty list of entries, that is also a normal table.%mdk + +%mdk-data-line={3423} +\item\mdline{3423}\emph{Constant table}\mdline{3423}: The table has \mdline{3423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const~entries}}}\mdline{3423} declared, and thus a +separate \mdline{3424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3424} property is not permitted by the language. Such +a table will have \mdline{3425}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3425} true. Such a table will have +\mdline{3426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}has\_initial\_entries}}}\mdline{3426} true if there is at least one entry in the +source code, or false if the list is empty.%mdk + +%mdk-data-line={3428} +\item\mdline{3428}\emph{Preinitialized table}\mdline{3428}: The table has \mdline{3428}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3428} declared, and thus a +separate \mdline{3429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const~entries}}}\mdline{3429} property is not permitted by the language. +It also has at least one entry in the list. Such a table will have +\mdline{3431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table}}}\mdline{3431} false and \mdline{3431}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}has\_initial\_entries}}}\mdline{3431} true.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3433} +\noindent\mdline{3433}A preinitialized table is allowed to have a mix of some entries marked +\mdline{3434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3434}, and other entries not marked \mdline{3434}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3434}.%mdk + +%mdk-data-line={3436} +\mdline{3436}Entries not marked \mdline{3436}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3436} may be modified or deleted, just as a +client may do for any entry in a normal table.%mdk + +%mdk-data-line={3439} +\mdline{3439}Entries marked \mdline{3439}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3439} behave like entries in a constant table, +\mdline{3440}i.e.\mdline{3440} only \mdline{3440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3440} operations on direct resources are allowed.%mdk + +%mdk-data-line={3442} +\mdline{3442}Unlike a table with \mdline{3442}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table~=~true}}}\mdline{3442}, a client may insert +entries into a table with \mdline{3443}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}has\_initial\_entries~=~true}}}\mdline{3443} and +\mdline{3444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const\_table~=~false}}}\mdline{3444}, subject to capacity constraints on the +number of entries supported by the target for the table.%mdk + +%mdk-data-line={3447} +\mdline{3447}The contents of preinitialized tables can be queried by the client +through a \mdline{3448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3448}. The server fills in the same fields in the +response as it does for constant tables, as described in Section +\mdline{3450}\mdref{sec-constant-tables}{9.1.4}\mdline{3450}, and with the same restrictions on table +features supported.%mdk + +%mdk-data-line={3453} +\mdline{3453}If the table requires a priority value for entries, the priorities of +the initial entries are determined according to the P4\mdline{3454}\mdsub{16}\mdline{3454} language +specification. After the P4 program is initially loaded, the entries +not marked \mdline{3456}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const}}}\mdline{3456} can be modified at run time just as table entries +in a normal table can.%mdk + +%mdk-data-line={3459} +\mdline{3459}The contents of all table entries within the \mdline{3459}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{3459} table +properties in a P4 program can be written to a separate output file by +the open source \mdline{3461}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{3461} compiler. See Section\mdline{3461}~\mdref{sec-entries-files}{A.5}\mdline{3461} for +details.%mdk + +%mdk-data-line={3464} +\subsubsection{\mdline{3464}9.1.6.\hspace*{0.5em}\mdline{3464}Wildcard Reads}\label{sec-table-wildcard-reads}%mdk%mdk + +%mdk-data-line={3466} +\noindent\mdline{3466}When performing a \mdline{3466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3466}, the P4Runtime client can select all entries +from one or all tables on the target and use several of the \mdline{3467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3467} fields +to filter the results, much like when performing a SQL request. For each field +that can be used to filter the result, the client may use the default value for +the field to act as a wildcard. This default value is zero for scalar fields +such as \mdline{3471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3471} and \mdline{3471}\textquotedblleft{}unset\textquotedblright{}\mdline{3471} for message fields such as \mdline{3471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3471}. The following +fields may be used to select and filter results:%mdk + +%mdk-data-line={3474} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3474} +\item\mdline{3474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{3474}: If default (0), entries from all tables\mdline{3474} \mdline{3474}\textemdash{}\mdline{3474} including constant +tables\mdline{3475} \mdline{3475}\textemdash{}\mdline{3475} will be selected and no other filter can be used. Otherwise only +the specified table will be considered.%mdk + +%mdk-data-line={3477} +\item\mdline{3477}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3477}: If default (unset), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided match +key, which must be a valid match key for the table. The match will be exact, +which means at most one entry will be returned.%mdk + +%mdk-data-line={3481} +\item\mdline{3481}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3481}: If default (unset), all entries from the specified table will be +considered. Otherwise, the client can provide an \mdline{3482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_id}}}\mdline{3482} (for direct +tables), which will be use to filter table entries. For this P4Runtime +release, this is the only kind of action-based filtering we support: the +client cannot filter based on action parameter values and cannot filter +indirect table entries based on action profile member id / action profile +group id.%mdk + +%mdk-data-line={3488} +\item\mdline{3488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3488}: If default (0), all entries from the specified table will be +considered. Otherwise, results will be filtered based on the provided priority +value.%mdk + +%mdk-data-line={3491} +\item\mdline{3491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3491}: If default (0), all entries from the specified table +will be considered. Otherwise, results will be filtered based on the provided +\mdline{3493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{3493} value.%mdk + +%mdk-data-line={3494} +\item\mdline{3494}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3494}: If default (empty byte string), all entries from the specified +table will be considered. Otherwise, results will be filtered based on the +provided \mdline{3496}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{3496} value.%mdk + +%mdk-data-line={3497} +\item\mdline{3497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3497}: If default (false), all non-default entries from the +specified table will be considered. Otherwise, only the default entry will be +considered.%mdk + +%mdk-data-line={3500} +\item\mdline{3500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{3500}: If default (unset), all table entries will be considered. Otherwise, +table entries will be filtered based on the provided role value.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3503} +\noindent\mdline{3503}For example, in order to read all entries from all tables from device 3, the +client can use the following \mdline{3504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3504} message.%mdk + +%mdk-data-line={3506} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3507} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0}\\ +~~~~priority:~{\mdcolor{purple}0}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3518} +\noindent\mdline{3518}In order to read all entries with priority 11 from a specific table (with id +0x0212ab34) from device 3, the client can use the following \mdline{3519}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3519} +message:%mdk + +%mdk-data-line={3522} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3523} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~priority:~{\mdcolor{purple}11}\\ +~~~~controller\_metadata:~{\mdcolor{purple}0}\\ +~~~~metadata:~{\mdcolor{maroon}"}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3534} +\noindent\mdline{3534}The canonical representation of \mdline{3534}\textquotedblleft{}don't care\textquotedblright{}\mdline{3534} matches, combined with the ability +to do a wildcard read on all table entries by leaving the \mdline{3535}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3535} field unset, +means that there exists a specific ambiguous case in which the same message +could be used to either read a single \mdline{3537}\textquotedblleft{}don't care\textquotedblright{}\mdline{3537} entry or to do a wildcard +read. If a table has no fields with match kind \mdline{3538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{3538}, it is possible via +P4Runtime to add an entry that is \mdline{3539}\textquotedblleft{}don't care\textquotedblright{}\mdline{3539} for all fields (\mdline{3539}i.e.\mdline{3539} has an empty +\mdline{3540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3540} field) but is not the default entry (\mdline{3540}i.e.\mdline{3540} \mdline{3540}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3540} is +false). When reading this entry from the table, there is no way to read \mdline{3541}\emph{only}\mdline{3541} +that entry from the table, because it would require providing an unset \mdline{3542}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{3542} +field in the request, which in turn indicates that the client wishes to perform +a wildcard read on all non-default entries. Consider the following example which +uses a table with a single \mdline{3545}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{3545} match:%mdk + +%mdk-data-line={3547} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3548} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;~fwd;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3558} +\noindent\mdline{3558}The following \mdline{3558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{3558} message can be used to add 2 entries:%mdk + +%mdk-data-line={3559} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3560} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{~{\mdcolor{darkgreen}\#~don't~care~entry}\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +~~table~entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~~~match~\{\\ +~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~lpm~\{\\ +~~~~~~~~value:~{\mdcolor{purple}0x0a000000}\\ +~~~~~~~~prefix\_len:~{\mdcolor{purple}8}\\ +~~~~~~\}\\ +~~~~{\mdcolor{darkgreen}\#~...}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3579} +\noindent\mdline{3579}The first entry is a \mdline{3579}\textquotedblleft{}don't care\textquotedblright{}\mdline{3579} entry, while the second one matches all +\mdline{3580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}10.0.0.0/8}}}\mdline{3580} addresses. The second entry has higher priority than the first one.%mdk + +%mdk-data-line={3582} +\mdline{3582}The following \mdline{3582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3582} message will return \mdline{3582}\emph{all}\mdline{3582} entries in the table, not +just the \mdline{3583}\textquotedblleft{}don't care\textquotedblright{}\mdline{3583} entry.%mdk + +%mdk-data-line={3584} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={3585} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~{\mdcolor{purple}3}\\ +entities~\{\\ +~~table\_entry~\{\\ +~~~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3593} +\noindent\mdline{3593}This issue also exists for tables with \mdline{3593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{3593}, \mdline{3593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{3593}, and \mdline{3593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{3593} +matches. However, in this case the priority is also taken into account for +wildcard reads, and because a priority of 0 is not valid, in practice only the +entries with the same priority as the \mdline{3596}\textquotedblleft{}don't care\textquotedblright{}\mdline{3596} entry will be returned to the +client. If the client uses distinct priority values for all entries\mdline{3597} \mdline{3597}\textemdash{}\mdline{3597} which is +strongly recommended to achieve\mdline{3598}~\mdref{sec-table-entry}{deterministic behavior}\mdline{3598} \mdline{3598}\textemdash{}\mdline{3598}, +then there is no ambiguity because the wildcard read will actually return a +single entry (the \mdline{3600}\textquotedblleft{}don't care\textquotedblright{}\mdline{3600} entry) as long as the \mdline{3600}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{3600} field is set to +the correct value.%mdk + +%mdk-data-line={3603} +\subsubsection{\mdline{3603}9.1.7.\hspace*{0.5em}\mdline{3603}Direct Resources}\label{sec-direct-resources}%mdk%mdk + +%mdk-data-line={3605} +\noindent\mdline{3605}In addition to the \mdline{3605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3605} and \mdline{3605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3605} entities, +P4Runtime support reading and writing direct resources as part of the +\mdline{3607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3607} message. This is convenient for two reasons:%mdk + +%mdk-data-line={3609} +\begin{itemize}%mdk + +%mdk-data-line={3609} +\item{} +%mdk-data-line={3609} +\mdline{3609}A table entry and its direct resources can be read with a single entity when +doing a \mdline{3610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{3610} RPC call%mdk%mdk + +%mdk-data-line={3612} +\item{} +%mdk-data-line={3612} +\mdline{3612}The initial configuration for an entry\mdline{3612}'\mdline{3612}s direct resources can be specified +when the entry is inserted. This may enable the target to add the table entry +and configure the direct resources in an atomic fashion if supported. When the +table has a direct meter, this may help guarantee that the lifetime of the +meter entry is the same as the lifetime of the table entry, and that there is +no time gap during which data plane traffic can \mdline{3617}\textquotedblleft{}hit\textquotedblright{}\mdline{3617} the table entry without +executing the appropriate meter entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3620} +\noindent\mdline{3620}Once the table entry has been inserted, the P4Runtime client is free to use the +\mdline{3621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3621} and \mdline{3621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{3621} messages for read and write +operations on \mdline{3622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{3622} and \mdline{3622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{3622} instances. For example, it is +usually more convenient as well as more efficient to use \mdline{3623}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{3623} to +query a counter entry value rather than use \mdline{3624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3624}, assuming the client is +not interested in reading other table entry properties as well, such as the +controller metadata cookie or the action entry.%mdk + +%mdk-data-line={3628} +\mdline{3628}The PSA specification states that when a table is assigned a direct resource +(meter or counter), this direct resource does \mdline{3629}\emph{not}\mdline{3629} need to be \mdline{3629}\textquotedblleft{}executed\textquotedblright{}\mdline{3629} in +every action bound to the table. It is an error to provide a direct resource +configuration in a \mdline{3631}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3631} message when programming an action that does not +execute the direct resource, and the server must return an \mdline{3632}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3632} +error code.%mdk + +%mdk-data-line={3635} +\mdline{3635}We leverage Protobuf\mdline{3635}'\mdline{3635}s ability to differentiate between set and unset fields to +give the P4Runtime client fined-grained control over how direct resources are +read and written through the \mdline{3637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3637} message. The list below describes how +the server must handle the \mdline{3638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3638}, \mdline{3638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3638} and +\mdline{3639}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3639} fields for read and write requests, based on whether the +fields are set or not. We do not cover error cases in the list, \mdline{3640}i.e.\mdline{3640} we assume +that we are dealing with a table which is assigned a direct counter / a direct +meter, and that the action being used for the table entry \mdline{3642}\textquotedblleft{}executes\textquotedblright{}\mdline{3642} the direct +resource appropriately.%mdk + +%mdk-data-line={3645} +\begin{itemize}%mdk + +%mdk-data-line={3645} +\item{} +%mdk-data-line={3645} +\mdline{3645}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3645} field%mdk + +%mdk-data-line={3646} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3646} +\item\mdline{3646}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3646} + +%mdk-data-line={3647} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3647} +\item\mdline{3647}if \mdline{3647}\textbf{unset}\mdline{3647}: The initial configuration for the meter entry is the +default (meter returns GREEN for all packets).%mdk + +%mdk-data-line={3649} +\item\mdline{3649}if \mdline{3649}\textbf{set}\mdline{3649}: The initial configuration for the meter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3651} +\item\mdline{3651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3651} + +%mdk-data-line={3652} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3652} +\item\mdline{3652}if \mdline{3652}\textbf{unset}\mdline{3652}: The meter entry\mdline{3652}'\mdline{3652}s configuration is reset to the default +(meter returns GREEN for all packets).%mdk + +%mdk-data-line={3654} +\item\mdline{3654}if \mdline{3654}\textbf{set}\mdline{3654}: The value provided by the client is used to re-configure +the meter entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3656} +\item\mdline{3656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3656} + +%mdk-data-line={3657} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3657} +\item\mdline{3657}if \mdline{3657}\textbf{unset}\mdline{3657}: The response does not include the meter entry\mdline{3657}'\mdline{3657}s +configuration (\mdline{3658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3658} is unset in the response).%mdk + +%mdk-data-line={3659} +\item\mdline{3659}if \mdline{3659}\textbf{set}\mdline{3659}: If the meter entry\mdline{3659}'\mdline{3659}s configuration is the default +configuration, \mdline{3660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3660} is unset in the response. Otherwise, the +response includes the meter entry\mdline{3661}'\mdline{3661}s configuration that was written by +the client earlier. This respects the \mdline{3662}\textquotedblleft{}read-write symmetry\textquotedblright{}\mdline{3662} principle.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3664} +\item{} +%mdk-data-line={3664} +\mdline{3664}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3664} field%mdk + +%mdk-data-line={3665} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3665} +\item\mdline{3665}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3665} + +%mdk-data-line={3666} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3666} +\item\mdline{3666}if \mdline{3666}\textbf{unset}\mdline{3666}: The initial value for the counter entry is the default +(0).%mdk + +%mdk-data-line={3668} +\item\mdline{3668}if \mdline{3668}\textbf{set}\mdline{3668}: The initial value for the counter entry is the one +provided by the client.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3670} +\item\mdline{3670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3670} + +%mdk-data-line={3671} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3671} +\item\mdline{3671}if \mdline{3671}\textbf{unset}\mdline{3671}: The counter entry\mdline{3671}'\mdline{3671}s value is not changed.%mdk + +%mdk-data-line={3672} +\item\mdline{3672}if \mdline{3672}\textbf{set}\mdline{3672}: The value provided by the client is written to the counter +entry.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3674} +\item\mdline{3674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3674} + +%mdk-data-line={3675} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3675} +\item\mdline{3675}if \mdline{3675}\textbf{unset}\mdline{3675}: The response does not include the counter entry\mdline{3675}'\mdline{3675}s value +(\mdline{3676}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{3676} is unset in the response).%mdk + +%mdk-data-line={3677} +\item\mdline{3677}if \mdline{3677}\textbf{set}\mdline{3677}: The response includes the counter entry\mdline{3677}'\mdline{3677}s value read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3680} +\item{} +%mdk-data-line={3680} +\mdline{3680}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3680} field%mdk + +%mdk-data-line={3681} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3681} +\item\mdline{3681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(INSERT)}}}\mdline{3681} + +%mdk-data-line={3682} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3682} +\item\mdline{3682}if \mdline{3682}\textbf{unset}\mdline{3682}: The initial value for all 3 counter entries is the +default (0).%mdk + +%mdk-data-line={3684} +\item\mdline{3684}if \mdline{3684}\textbf{set}\mdline{3684}: The initial value for all 3 counter entries is the +default (0). Sub-field, if any, can only have zero (0) as its value. +\mdline{3686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3686} error is returned for any non-zero sub-field value.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3687} +\item\mdline{3687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest~(MODIFY)}}}\mdline{3687} + +%mdk-data-line={3688} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3688} +\item\mdline{3688}if \mdline{3688}\textbf{unset}\mdline{3688}: All the 3 counter entries are unchanged.%mdk + +%mdk-data-line={3689} +\item\mdline{3689}if \mdline{3689}\textbf{set}\mdline{3689}: All the 3 counters are reset to 0. Sub-field, if any, can +only have zero (0) as its value. \mdline{3690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3690} error is returned +for any non-zero sub-field value.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3692} +\item\mdline{3692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{3692} + +%mdk-data-line={3693} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3693} +\item\mdline{3693}if \mdline{3693}\textbf{unset}\mdline{3693}: The response does not include counter values +(\mdline{3694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_counter\_data}}}\mdline{3694} is unset in the response).%mdk + +%mdk-data-line={3695} +\item\mdline{3695}if \mdline{3695}\textbf{set}\mdline{3695}: The response includes all the 3 counter values read from +the target.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3698} +\noindent\mdline{3698}In its default configuration, a meter returns the GREEN color for every packet +when it is executed. This default configuration can be achieved by leaving the +\mdline{3700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3700} field unset when inserting \mdline{3700}\textbf{or modifying}\mdline{3700} a table entry. When +modifying a table entry, if the P4Runtime client wishes to maintain the same +meter configuration, it needs to be provided again in the \mdline{3702}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3702} message +(\mdline{3703}i.e.\mdline{3703} the \mdline{3703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{3703} field must be set to match the existing configuration).%mdk + +%mdk-data-line={3705} +\subsubsection{\mdline{3705}9.1.8.\hspace*{0.5em}\mdline{3705}Idle-timeout}\label{sec-idle-timeout}%mdk%mdk + +%mdk-data-line={3707} +\noindent\mdline{3707}P4Runtime supports idle timeout for table entries. When adding a table entry, +the client can specify a Time-To-Live (TTL) value. If at any time during its +lifetime, the data plane entry is not \mdline{3709}\textquotedblleft{}hit\textquotedblright{}\mdline{3709} (\mdline{3709}i.e.\mdline{3709} not selected by any packet +lookup) for a lapse of time greater or equal to its TTL, the P4Runtime should, +with best effort, generate a stream notification\mdline{3711} \mdline{3711}\textemdash{}\mdline{3711} using the +\mdline{3712}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3712} message\mdline{3712} \mdline{3712}\textemdash{}\mdline{3712} to the primary client, which can then take +action, such as remove the idle table entry.%mdk + +%mdk-data-line={3715} +\mdline{3715}Two fields of the \mdline{3715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3715} Protobuf message are used to implement idle +timeout:%mdk + +%mdk-data-line={3718} +\begin{itemize}%mdk + +%mdk-data-line={3718} +\item{} +%mdk-data-line={3718} +\mdline{3718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3718}: the configured TTL for the table entry in nanoseconds. A +value of 0 means that the entry never expires, \mdline{3719}i.e.\mdline{3719} no +\mdline{3720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3720} message will ever be generated for this entry. When +a client reads a \mdline{3721}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3721}, this field will be included in the response and +the value must match exactly the one set by the client when inserting or +modifying the entry.%mdk%mdk + +%mdk-data-line={3725} +\item{} +%mdk-data-line={3725} +\mdline{3725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3725}: a Protobuf message with a single field (\mdline{3725}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}elapsed\_ns}}}\mdline{3725}) +used to indicate the time in nanoseconds elapsed since the last time the +data plane entry was hit. The \mdline{3727}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3727} field must be unset for a +\mdline{3728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3728} write. When reading a table entry, \mdline{3728}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3728} must be +set in the response if and only if it was set (to an empty message) in the +request. If the field is set in the request, it must be set to the correct +value in the response even if the TTL value for the entry is 0.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3733} +\noindent\mdline{3733}These fields can only be set if idle timeout is supported for the table, as per +the P4Info message. If idle timeout is not supported by the table, the P4Runtime +server must return an \mdline{3735}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3735} error code if at least one of these +conditions is met:%mdk + +%mdk-data-line={3738} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3738} +\item\mdline{3738}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3738} is set to a non-zero value, or%mdk + +%mdk-data-line={3739} +\item\mdline{3739}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3739} is set%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3741} +\noindent\mdline{3741}The target should do its best to approximate the \mdline{3741}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3741} value +provided by the client. For example, most targets may not be able to accommodate +arbitrarily small values of TTL, in which case they should use the smallest +value they can support, rather than reject the \mdline{3744}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3744} write with an error +code. Similarly, each target should do its best to provide reasonably-accurate +values for \mdline{3746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3746}.%mdk + +%mdk-data-line={3748} +\mdline{3748}P4Runtime does not support idle timeout for default entries. When the +\mdline{3749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_default\_action}}}\mdline{3749} flag is set in a \mdline{3749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3749} message, \mdline{3749}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{3749} +must be set to 0 (default) and \mdline{3750}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}time\_since\_last\_hit}}}\mdline{3750} must be unset. If the +server receives a \mdline{3751}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3751} message which violates this, it must return an +\mdline{3752}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3752} error.%mdk + +%mdk-data-line={3754} +\mdline{3754}For more information about idle timeout, in particular regarding +\mdline{3755}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{3755}, please refer to the\mdline{3755}~\mdref{sec-table-idle-timeout-notification}{Table idle timeout +notifications}\mdline{3756} section.%mdk + +%mdk-data-line={3758} +\subsection{\mdline{3758}9.2.\hspace*{0.5em}\mdline{3758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3758} \mdline{3758}\&\mdline{3758} \mdline{3758}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}}\label{sec-action-profile-member-and-group}%mdk%mdk + +%mdk-data-line={3760} +\noindent\mdline{3760}P4Runtime defines an API for programming a PSA ActionProfile extern using +\mdline{3761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3761} messages. A PSA ActionSelector extern can be programmed +using both \mdline{3762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3762} and \mdline{3762}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3762} messages. PSA supports +tables that can be implemented with an action profile or selector instance. Such +tables are referred to as indirect tables, in contrast to direct tables, whose +entries are directly bound to an action instance. The following P4 snippet +illustrates an indirect table \mdline{3766}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3766} for L3 routing, implemented with an action +selector \mdline{3767}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3767}.%mdk + +%mdk-data-line={3769} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={3770} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector(HashAlgorithm.crc32,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}size~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w1024,\\ +~~~~~~~~~~~~~~~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}output\_width~=~}{\mdcolor{darkgreen}*/}~{\mdcolor{purple}32}w10)~as;\\ +\\ +{\bfseries{\mdcolor{navy}action}}~set\_nhop(PortId\_t~p,~EthAddr~smac,~EthAddr~dmac)~\{\\ +~~istd.egress\_port~=~p;\\ +~~hdr.ethernet.smac~=~smac;\\ +~~hdr.ethernet.dmac~=~dmac;\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.ipv4.dip:~lpm;~~{\mdcolor{darkgreen}//~LPM~on~destination~IP~address}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~set\_nhop;\\ +~~\}\\ +~~implementation~=~as;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={3791} +\noindent\mdline{3791}When programming table \mdline{3791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{3791} in the example above, a P4Runtime client should +specify the \mdline{3792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3792} in the \mdline{3792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{3792} to be a reference to either an +action profile member or group. The reference is a non-zero \mdline{3793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3793} identifier +that uniquely identifies a member or group programmed in the action selector +\mdline{3795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}as}}}\mdline{3795}.%mdk + +%mdk-data-line={3797} +\mdline{3797}If a table entry in an indirect table with an ActionProfile implementation is +hit, then the corresponding table action gives a member id. The member table is +looked up with the member id, and the corresponding action specification is used +to modify the packet or its metadata.%mdk + +%mdk-data-line={3802} +\mdline{3802}If a table entry in an indirect table with an ActionSelector implementation is +hit, then the corresponding table action gives either a member id or a group +id. For a member id, the member table in the selector is looked up, and the +corresponding action specification is used to modify the packet or its +metadata. For a group id, a hash algorithm, defined in the P4 ActionSelector +specification is used to obtain a member id from the set of members in the +group. For example, the hash algorithm in the P4 example above is 32-bit CRC. +The obtained member id is used to look up the member table in the selector and +obtain the action specification, which is then used to modify the packet or its +metadata.%mdk + +%mdk-data-line={3813} +\subsubsection{\mdline{3813}9.2.1.\hspace*{0.5em}\mdline{3813}Action Profile Member Programming}\label{sec-action-profile-member-programming}%mdk%mdk + +%mdk-data-line={3815} +\noindent\mdline{3815}Action profile members are entries in the ActionProfile or ActionSelector and +are referenced by a \mdline{3816}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3816} identifier that is bound to an action +specification. An action profile member for an ActionProfile or ActionSelector +extern instance may be bound only to the actions that appear in the \mdline{3818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3818} +attribute of the table implemented using the extern instance. If multiple table +implementations share an extern instance, then the \mdline{3820}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}actions}}}\mdline{3820} attributes of the +tables \mdline{3821}\emph{must have an identical list of P4 actions}\mdline{3821}. The IDs of the tables +implemented with a selector will appear in P4Info as part of the ActionProfile +message for the selector.%mdk + +%mdk-data-line={3825} +\mdline{3825}An \mdline{3825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3825} entity update message has the following fields:%mdk + +%mdk-data-line={3827} +\begin{itemize}%mdk + +%mdk-data-line={3827} +\item{} +%mdk-data-line={3827} +\mdline{3827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3827} is the \mdline{3827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3827} identifier of the PSA ActionProfile or +ActionSelector extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3830} +\item{} +%mdk-data-line={3830} +\mdline{3830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3830} is the non-zero \mdline{3830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3830} identifier of the action profile member +entry being updated.%mdk%mdk + +%mdk-data-line={3833} +\item{} +%mdk-data-line={3833} +\mdline{3833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3833} is the specification of the P4 action instance bound to the action +profile member entry.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3836} +\noindent\mdline{3836}An action profile member may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3839} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3839} +\item\mdline{3839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3839}: Add a new member entry bound to an eligible P4 action +specification. The member id must be different from ids of already programmed +entries for that extern, or the server must return an \mdline{3841}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3841} error +code. The action specification must be provided, or the server must return +\mdline{3843}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3843}. The total number of members should not exceed the maximum +specified in the P4 extern specification as a result of this insertion, or the +server should return \mdline{3845}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3845}.%mdk + +%mdk-data-line={3846} +\item\mdline{3846}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3846}: Modify the action specification of an existing member entry. An +entry with the member id must exist, or the server must return \mdline{3847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3847}, +and the action specification must be provided, or the server must return +\mdline{3849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3849}.%mdk + +%mdk-data-line={3850} +\item\mdline{3850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3850}: Delete the member entry and deallocate the member id. If the member +id is not valid the server must return a \mdline{3851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3851} error code. The member +must not be part of an action profile group, or the server must return +\mdline{3853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3853}. If needed, the action profile group should first be +modified to remove the member from the group. The member must not be +referenced in the table action of any table entry, or the server must also +return \mdline{3856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3856}. \mdline{3856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3856} and \mdline{3856}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3856} are the only +fields that are considered when performing a \mdline{3857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3857} and every other field +will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3860} +\noindent\mdline{3860}When reading, an \mdline{3860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{3860} message with \mdline{3860}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3860} and +\mdline{3861}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3861} equal to 0 will read all members of all ActionProfile and +ActionSelector objects. A message with \mdline{3862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3862} equal to the id of +an existing ActionProfile or ActionSelector object, and a \mdline{3863}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3863} equal to +0, will read all members of that specified object.%mdk + +%mdk-data-line={3866} +\subsubsection{\mdline{3866}9.2.2.\hspace*{0.5em}\mdline{3866}Action Profile Group Programming}\label{sec-action-profile-group-programming}%mdk%mdk + +%mdk-data-line={3868} +\noindent\mdline{3868}Action profile groups are entries in an ActionSelector and are referenced by a +\mdline{3869}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3869} identifier that is bound to a set of action profile members already +programmed in the selector. The action profile members in a group must be bound +to actions of the same type.%mdk + +%mdk-data-line={3873} +\mdline{3873}Within a single ActionSelector object, the \mdline{3873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3873} values used to identify its +members are in a separate \mdline{3874}\textquoteleft{}scope\textquoteright{}\mdline{3874} from the \mdline{3874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3874} values used to identify its +groups. That is, the id 5 can simultaneously be used within a single +ActionSelector object to identify a member 5, and a group 5.%mdk + +%mdk-data-line={3878} +\mdline{3878}There is not a separate scope within each group for member ids. For example, if +at the same time both groups 5 and 10 contain member 6, the action associated +with member 6 is the action for all groups containing member 6. Modifying the +action associated with member 6 updates the behavior of all groups containing +it.%mdk + +%mdk-data-line={3884} +\mdline{3884}An \mdline{3884}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3884} entity update message has the following fields:%mdk + +%mdk-data-line={3886} +\begin{itemize}%mdk + +%mdk-data-line={3886} +\item{} +%mdk-data-line={3886} +\mdline{3886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3886} is the \mdline{3886}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3886} identifier of the PSA ActionSelector +extern instance, as defined in P4Info.%mdk%mdk + +%mdk-data-line={3889} +\item{} +%mdk-data-line={3889} +\mdline{3889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3889} is the non-zero \mdline{3889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{3889} identifier of the action profile group +entry being updated.%mdk%mdk + +%mdk-data-line={3892} +\item{} +%mdk-data-line={3892} +\mdline{3892}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3892} is a repeated field defining the set of members that are part of the +group. For each member in a group, the controller must define the following +fields:%mdk + +%mdk-data-line={3895} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3895} +\item\mdline{3895}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3895} for looking up the member table in the selector.%mdk + +%mdk-data-line={3896} +\item\mdline{3896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3896} specifying the probability of the member\mdline{3896}'\mdline{3896}s selection at +runtime. 0 is not a valid \mdline{3897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3897} value and the server must return +\mdline{3898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3898} if the client attempts to use it.%mdk + +%mdk-data-line={3899} +\item\mdline{3899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3899} is the controller-defined port that the member\mdline{3899}'\mdline{3899}s +liveness depends on. At runtime, the member must be excluded from +selection if the watch port is down. See Section +\mdline{3902}\mdref{action-selector-constraints}{9.2.4}\mdline{3902} for notes on the behavior if all members in +a group are excluded for this reason. If \mdline{3903}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{3903} is empty, then the +member is always included in the selection, regardless of the status of +any port of the device. The value must be empty or the SDN port of an +existing port on the device, otherwise the server must return +\mdline{3907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3907}. If the target does not support using the SDN port as a +watch port (\mdline{3908}e.g.\mdline{3908} on some targets LAGs cannot be used for this purpose), +the server must return \mdline{3909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{3909}.%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={3911} +\item{} +%mdk-data-line={3911} +\mdline{3911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3911} is the maximum sum of all members or member weights (as per the +\mdline{3912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{3912}) for the group. This field is defined when the group +is inserted, and must not be changed in a \mdline{3913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3913} update, otherwise an +\mdline{3914}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3914} error is returned. See the subsection below for the +\mdline{3915}\mdref{sec-max-size-rules}{rules on setting \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\mdline{3915}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3917} +\noindent\mdline{3917}An action profile group may be inserted, modified or deleted as per the +following semantics.%mdk + +%mdk-data-line={3920} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={3920} +\item\mdline{3920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3920}: Add a new group entry bound to a set of existing action profile +members. \mdline{3921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}The~group\_id}}}\mdline{3921} must be different from ids of already programmed +groups for that selector, or the server must return an \mdline{3922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{3922} error +code. All members specified in the group must exist in the selector, or the +server must return \mdline{3924}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3924}. P4Runtime does not explicitly limit the number +of groups, however, such limits may be imposed out-of-band by the target.%mdk + +%mdk-data-line={3926} +\item\mdline{3926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3926}: Modify the member set specification of an existing group entry. An +entry with the \mdline{3927}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3927} must exist, or the server must return +\mdline{3928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3928}. All members specified in the group entry must exist in the +selector, or the server must return \mdline{3929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3929}. The value of \mdline{3929}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3929} must +be identical to the value used when inserting the group, otherwise an +\mdline{3931}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3931} error is returned.%mdk + +%mdk-data-line={3932} +\item\mdline{3932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3932}: Delete the group entry and deallocate the \mdline{3932}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3932}. The group must +not be referenced in the table action of any table entry, or the server must +return a \mdline{3934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{3934} error code. If the \mdline{3934}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3934} is invalid, the +server must return \mdline{3935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{3935}. \mdline{3935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3935} and \mdline{3935}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3935} are the +only fields that are considered when performing a \mdline{3936}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{3936} and every other +field will be ignored.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3939} +\noindent\mdline{3939}When setting the group membership with \mdline{3939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3939} or \mdline{3939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3939}, the \mdline{3939}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{3939} +repeated field must not include duplicates, \mdline{3940}i.e.\mdline{3940} members with the same +\mdline{3941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}member\_id}}}\mdline{3941}. The \mdline{3941}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3941} field is used instead to logically \mdline{3941}\textquotedblleft{}repeat\textquotedblright{}\mdline{3941} the member +inside the group.%mdk + +%mdk-data-line={3944} +\mdline{3944}It is explicitly allowed for the same member to be present in multiple groups at +the same time. If, as a result, an implementation \mdline{3945}\textquotedblleft{}stores\textquotedblright{}\mdline{3945} the action id and +parameters in the target in multiple locations, the server must update all of +those locations when a request to modify such a member is made.%mdk + +%mdk-data-line={3949} +\mdline{3949}When reading, an \mdline{3949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{3949} message with \mdline{3949}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3949} and +\mdline{3950}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3950} equal to 0 will read all groups of all ActionSelector objects. A +message with \mdline{3951}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{3951} equal to the id of an existing ActionSelector +object, and a \mdline{3952}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}group\_id}}}\mdline{3952} equal to 0, will read all groups of that one specified +object.%mdk + +%mdk-data-line={3955} +\paragraph{\mdline{3955}9.2.2.1.\hspace*{0.5em}\mdline{3955}Rules on Setting \mdline{3955}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}}\label{sec-max-size-rules}%mdk%mdk + +%mdk-data-line={3957} +\noindent\mdline{3957}The valid values for \mdline{3957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3957} depend on the static \mdline{3957}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3957} included +in the P4Info message:%mdk + +%mdk-data-line={3960} +\begin{itemize}%mdk + +%mdk-data-line={3960} +\item{} +%mdk-data-line={3960} +\mdline{3960}If \mdline{3960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3960} is greater than 0, then \mdline{3960}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3960} must be greater than 0, +and less than or equal to \mdline{3961}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3961}. We assume that the target can +support selector groups for which the size of the members (as defined by +\mdline{3963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{3963}) is up to \mdline{3963}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3963}, or the P4Runtime server +would have rejected the Forwarding Pipeline Config. If \mdline{3964}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3964} is greater +than \mdline{3965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3965}, the server must return \mdline{3965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3965}.%mdk%mdk + +%mdk-data-line={3967} +\item{} +%mdk-data-line={3967} +\mdline{3967}Otherwise (\mdline{3967}i.e.\mdline{3967} if \mdline{3967}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3967} is 0), the P4Runtime client can set +\mdline{3968}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3968} to any value greater than or equal to 0.%mdk + +%mdk-data-line={3970} +\begin{itemize}%mdk + +%mdk-data-line={3970} +\item{} +%mdk-data-line={3970} +\mdline{3970}A \mdline{3970}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3970} of 0 indicates that the client is not able to specify a maximum +size at group-creation time, and the target should use the maximum value it +can support. If the maximum value supported by the target is exceeded during +a write update (\mdline{3973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{3973} or \mdline{3973}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{3973}), the target must return a +\mdline{3974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3974} error.%mdk%mdk + +%mdk-data-line={3976} +\item{} +%mdk-data-line={3976} +\mdline{3976}If \mdline{3976}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_size}}}\mdline{3976} is greater than 0 and the value is not supported by the +target, the server must return a \mdline{3977}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{3977} error at +group-creation time.%mdk%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={3980} +\subsubsection{\mdline{3980}9.2.3.\hspace*{0.5em}\mdline{3980}One Shot Action Selector Programming}\label{sec-oneshot}%mdk%mdk + +%mdk-data-line={3982} +\noindent\mdline{3982}P4Runtime supports syntactic sugar to program a table, which is implemented with +an action selector, in one shot. One shot means that a table entry, an action +profile group, and a set of action profile members can be programmed with a +single update message. Using one shots has the advantage that the controller +does not need to keep track of group ids and member ids.%mdk + +%mdk-data-line={3988} +\mdline{3988}One shots are programmed by choosing the \mdline{3988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3988} message as the +\mdline{3989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableAction}}}\mdline{3989}. The \mdline{3989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{3989} message consists of a set of +\mdline{3990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3990} messages. This set should have cardinality no greater than +\mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3991} (if \mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{3991} is nonzero) if \mdline{3991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{3991} +is \mdline{3992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_members}}}\mdline{3992}, or else the server must return \mdline{3992}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3992}. Each +\mdline{3993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{3993} message has the following fields:%mdk + +%mdk-data-line={3995} +\begin{itemize}%mdk + +%mdk-data-line={3995} +\item{} +%mdk-data-line={3995} +\mdline{3995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{3995} is one of the actions specified by the table that is being +programmed.%mdk%mdk + +%mdk-data-line={3998} +\item{} +%mdk-data-line={3998} +\mdline{3998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3998} specifying the probability of the action\mdline{3998}'\mdline{3998}s selection at runtime. 0 is +not a valid \mdline{3999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{3999} value and the server must return \mdline{3999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{3999} if +the client attempts to use it. If \mdline{4000}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{4000} is +\mdline{4001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_weights}}}\mdline{4001}, then the sum of all weights across all \mdline{4001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{4001} +messages for that \mdline{4002}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{4002} message must not exceed the +\mdline{4003}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{4003} specified in the P4Info (if greater than 0), or the server +must return \mdline{4004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4004}. If \mdline{4004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{4004} is +\mdline{4005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_members}}}\mdline{4005}, the individual weight of each member must not exceed +\mdline{4006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_member\_weight}}}\mdline{4006} (if greater than 0), or the server must return +\mdline{4007}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4007}.%mdk%mdk + +%mdk-data-line={4009} +\item{} +%mdk-data-line={4009} +\mdline{4009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{4009} is the controller-defined port that the action\mdline{4009}'\mdline{4009}s liveness depends +on. At runtime, the action must be excluded from selection if the watch port +is down. See Section\mdline{4011}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{4011} for more details +on the \mdline{4012}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{4012} field, which also apply for one shot action selector +programming.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4016} +\noindent\mdline{4016}Semantically, one shots are equivalent to programming the table entry, group, +and members individually; with the necessary group id and member ids bound to +unused ids. An implementation is free to implement one shots in other ways, as +long as the implementation matches the above semantics.%mdk + +%mdk-data-line={4021} +\mdline{4021}To preserve read-write symmetry, an implementation must answer \mdline{4021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4021}s +with the original one shot messages. It may not return a desugared version of +the one shot message.%mdk + +%mdk-data-line={4025} +\mdline{4025}For example, consider the action selector table defined +\mdline{4026}\mdref{sec-action-profile-member-and-group}{here}\mdline{4026}. This table could be programmed +with the following one shot update:%mdk + +%mdk-data-line={4029} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4030} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{\\ +~~~~action\_profile\_action\_set~\{\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}1}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x01}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}2}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x02}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~~~action\_profile\_actions~\{\\ +~~~~~~~~action~\{~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +~~~~~~~~weight:~{\mdcolor{purple}3}\\ +~~~~~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x03}{\mdcolor{maroon}"}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4055} +\noindent\mdline{4055}Which would be equivalent to the following updates, where \mdline{4055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GROUP\_ID}}}\mdline{4055}, +\mdline{4056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_1}}}\mdline{4056}, \mdline{4056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_2}}}\mdline{4056}, and \mdline{4056}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MEMBER\_ID\_3}}}\mdline{4056} are unused ids:%mdk + +%mdk-data-line={4058} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4059} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_1\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}1}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_2\\ +~~action~\{~/*~set~nexthop~{\mdcolor{purple}2}~*/~\}\\ +\}\\ +action\_profile\_member~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~member\_id:~MEMBER\_ID\_3\\ +~~action~\{~~/*~set~nexthop~{\mdcolor{purple}3}~*/~\}\\ +\}\\ +action\_profile\_group~\{\\ +~~action\_profile\_id:~{\mdcolor{purple}0x11ab12cd}\\ +~~group\_id:~GROUP\_ID\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_1\\ +~~~~weight:~{\mdcolor{purple}1}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x01}{\mdcolor{maroon}"}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_2\\ +~~~~weight:~{\mdcolor{purple}2}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x02}{\mdcolor{maroon}"}\\ +~~\}\\ +~~members~\{\\ +~~~~member\_id:~MEMBER\_ID\_3\\ +~~~~weight:~{\mdcolor{purple}3}\\ +~~~~watch\_port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x03}{\mdcolor{maroon}"}\\ +~~\}\\ +\}\\ +table\_entry~\{\\ +~~table\_id:~{\mdcolor{purple}0x0212ab34}\\ +~~match~\{~/*~lpm~match~*/~\}\\ +~~action~\{~action\_profile\_group\_id:~GROUP\_ID~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4100} +\noindent\mdline{4100}Note that when using the above method (members and groups), the client also +needs to use multiple messages to ensure\mdline{4101}~\mdref{sec-batching-and-ordering-of-updates}{correct ordering between the dependent +updates}\mdline{4102}. Members need to be inserted +first, then the group needs to be created, and finally the match entry can be +inserted. Therefore, 3 distinct \mdline{4104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4104} batches are required.%mdk + +%mdk-data-line={4106} +\mdline{4106}It is possible to include several \mdline{4106}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{4106} messages with the same +exact \mdline{4107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{4107} specification in one \mdline{4107}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileActionSet}}}\mdline{4107} message. However, +the P4Runtime client is encouraged not to do so, as the same can be achieved by +using the \mdline{4109}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}weight}}}\mdline{4109} field. Note that to preserve read-write symmetry, the server +must not coalesce multiple \mdline{4110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileAction}}}\mdline{4110} messages with the same \mdline{4110}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{4110} +specification into one. Additionally, each \mdline{4111}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{4111} specification would count as +a separate member for the purposes of \mdline{4112}e.g.\mdline{4112} the \mdline{4112}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}sum\_of\_members}}}\mdline{4112} group size +calculation for Action Selectors.%mdk + +%mdk-data-line={4115} +\mdline{4115}All the tables associated with an action selector may either be programmed +exclusively with one shots, or exclusively with \mdline{4116}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4116} and +\mdline{4117}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{4117} messages. Programming some entries with one shots, and +other entries with \mdline{4118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4118} and \mdline{4118}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{4118} messages is +not allowed, and the server must return the error code \mdline{4119}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4119} in +that case.%mdk + +%mdk-data-line={4122} +\mdline{4122}A P4Runtime server \mdline{4122}\emph{must}\mdline{4122} support the one shot style of programming tables with +an action selector implementation. Support for the \mdline{4123}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4123} and +\mdline{4124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{4124} style is \mdline{4124}\emph{optional}\mdline{4124}. If \mdline{4124}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4124} and +\mdline{4125}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{4125} are not supported by a server, it must return an +\mdline{4126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4126} error for every \mdline{4126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{4126} or \mdline{4126}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileGroup}}}\mdline{4126} +message that it receives.%mdk + +%mdk-data-line={4129} +\subsubsection{\mdline{4129}9.2.4.\hspace*{0.5em}\mdline{4129}Constraints on action selector programming}\label{action-selector-constraints}%mdk%mdk + +%mdk-data-line={4131} +\noindent\mdline{4131}The PSA specification states that the following features are \mdline{4131}\emph{optional}\mdline{4131} in +action selector implementations\mdline{4132}~[\mdcite{psaactionselector}{27}]\mdline{4132}:%mdk + +%mdk-data-line={4134} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4134} +\item\mdline{4134}Support for non-empty groups where in the same group, different members are +bound to different actions.%mdk + +%mdk-data-line={4136} +\item\mdline{4136}Predictable data plane behavior when a matched table entry points to an empty +group.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={4139} +\noindent\mdline{4139}For 1., if a client tries to \mdline{4139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4139} or \mdline{4139}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4139} a group with members bound to +different actions, the server should return \mdline{4140}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4140} if not supported by +the target. This applies to the one shot style of programming as well. We +recommend that control plane implementations take into account this possible +limitation and be designed so as not to rely on this feature for the sake of +portability. A target with this restriction is also not expected to support +modifying the action function of a member which is part of one or more groups +and should return \mdline{4146}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4146} (modifying the action parameter values must be +supported, however).%mdk + +%mdk-data-line={4149} +\mdline{4149}PSA 1.1 introduces the \mdline{4149}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4149} table property in order to +enable the P4 programmer to specify the action to perform on the packet when the +matched table entry points to an empty action selector group. This action may be +different from the default action, which is performed in case of table +miss. \mdline{4153}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4153} is one possible way to achieve property 2. in the +list above. We recommend that all P4Runtime implementations support this +property. Note that this version of P4Runtime does not provide any mechanism to +modify the value of \mdline{4156}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4156} at runtime, so the value will be +constant and will either be provided by the P4 programmer or will default to +\mdline{4158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NoAction}}}\mdline{4158}. Even when \mdline{4158}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4158} is not implemented by the target, +P4Runtime does not require the server to return an error code when the client +performs an operation which results in an empty group, despite the possibility +for undeterministic or target-specific behavior. It is likely that future PSA +versions will make the implementation of \mdline{4162}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4162} mandatory and +that future P4Runtime versions will provide a mechanism to change the property +value dynamically. Note that the discussion above also applies to the one shot +style of programming.%mdk + +%mdk-data-line={4167} +\mdline{4167}The PSA specification includes a discussion on how to implement +\mdline{4168}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4168} in software in the P4Runtime server +\mdline{4169}[\mdcite{psaemptygroupactionappendix}{30}]\mdline{4169}.%mdk + +%mdk-data-line={4171} +\mdline{4171}If a P4Runtime implementation does support \mdline{4171}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4171}, that action +should be executed when an action selector group is selected that uses the watch +port feature, and every member of the group has a watch port that is down.%mdk + +%mdk-data-line={4175} +\mdline{4175}If a P4Runtime implementation does not support \mdline{4175}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{4175}, and +does support the watch port feature, we recommend that its developers document +its behavior when a group effectively becomes empty because the watch ports of +all members of a group are down.%mdk + +%mdk-data-line={4181} +\subsection{\mdline{4181}9.3.\hspace*{0.5em}\mdline{4181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4181} \mdline{4181}\&\mdline{4181} \mdline{4181}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-counterentry-directcounterentry}%mdk%mdk + +%mdk-data-line={4183} +\noindent\mdline{4183}PSA defines Counters as a mechanism for keeping statistics of bytes and packets. +Statistics may be updated as a result of an action associated with a table +entry, or a direct invocation such as from a P4 control. The \mdline{4185}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{4185} +P4Runtime message can be used for all three types of PSA counters\mdline{4186} \mdline{4186}\textemdash{}\mdline{4186} \mdline{4186}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS}}}\mdline{4186}, +\mdline{4187}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}BYTES}}}\mdline{4187} and \mdline{4187}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{4187} \mdline{4187}\textemdash{}\mdline{4187} and consists of the following fields:%mdk + +%mdk-data-line={4189} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4189} +\item\mdline{4189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{4189} is an \mdline{4189}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4189}, corresponding to the number of octets.%mdk + +%mdk-data-line={4190} +\item\mdline{4190}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{4190} is an \mdline{4190}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4190}, corresponding to the number of packets.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4192} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4193} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterData~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~byte\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}int64}}~packet\_count~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4199} +\noindent\mdline{4199}P4Runtime does not distinguish between the different PSA counter types, and +allows for simultaneous updates of \mdline{4200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}byte\_count}}}\mdline{4200} and \mdline{4200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_count}}}\mdline{4200} fields, which +is equivalent to specifying the counter type \mdline{4201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PACKETS\_AND\_BYTES}}}\mdline{4201}. Counters may +be defined as direct or indirect (indexed) instances.%mdk + +%mdk-data-line={4204} +\subsubsection{\mdline{4204}9.3.1.\hspace*{0.5em}\mdline{4204}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}}\label{sec-directcounterentry}%mdk%mdk + +%mdk-data-line={4206} +\noindent\mdline{4206}A direct counter is a direct resource associated with a \mdline{4206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4206} (see +\mdline{4207}\mdref{sec-direct-resources}{Direct Resources}\mdline{4207}). The \mdline{4207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4207} field of the +\mdline{4208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4208} message can be used to initialize the counter value at the same +time as the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct counter entry using the +\mdline{4211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{4211} message. Once the table entry is deleted the associated +direct counter entry can no longer be accessed.%mdk + +%mdk-data-line={4214} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4215} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectCounterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4221} +\noindent\mdline{4221}A \mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4221} may only include an \mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4221} message of type \mdline{4221}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4221} with a +\mdline{4222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{4222}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={4224} +\begin{itemize}%mdk + +%mdk-data-line={4224} +\item{} +%mdk-data-line={4224} +\mdline{4224}the \mdline{4224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4224} field must match \mdline{4224}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry.match}}}\mdline{4224} of the table entry +to which this direct counter entry is associated. If a matching \mdline{4225}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4225} +is not found, the server returns the error code \mdline{4226}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4226}.%mdk%mdk + +%mdk-data-line={4228} +\item{} +%mdk-data-line={4228} +\mdline{4228}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4228} is used to set the counter value to the value specified by the +client. Note that if this Protobuf field is not set, the counter value is not +modified.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4232} +\noindent\mdline{4232}Specifying \mdline{4232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{4232} in an \mdline{4232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4232} message of type \mdline{4232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4232} or +\mdline{4233}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4233} is not allowed, and the server must return the error code +\mdline{4234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4234} in that case.%mdk + +%mdk-data-line={4236} +\mdline{4236}A client may use \mdline{4236}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4236} in two ways to read the contents of a +\mdline{4237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounter}}}\mdline{4237}:%mdk + +%mdk-data-line={4239} +\begin{itemize}%mdk + +%mdk-data-line={4239} +\item{} +%mdk-data-line={4239} +\mdline{4239}As a direct resource associated with a table entry, request the server to +return the counter value in the \mdline{4240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4240} field of the \mdline{4240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4240} message +(see\mdline{4241}~\mdref{sec-direct-resources}{Direct resources}\mdline{4241}).%mdk%mdk + +%mdk-data-line={4243} +\item{} +%mdk-data-line={4243} +\mdline{4243}Explicitly request the counter value by including the \mdline{4243}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectCounterEntry}}}\mdline{4243} in +the \mdline{4244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4244}. The \mdline{4244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4244} field must match the \mdline{4244}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4244} +whose counter is being read. If no such entry is found, the server returns the +error code \mdline{4246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4246}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4248} +\subsubsection{\mdline{4248}9.3.2.\hspace*{0.5em}\mdline{4248}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}}\label{sec-counterentry}%mdk%mdk + +%mdk-data-line={4250} +\noindent\mdline{4250}An indirect or indexed counter is not associated with a specific \mdline{4250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4250} +and may be updated independently of any action. It may be read or written using +the P4Runtime \mdline{4252}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4252} message whose fields are defined as follows:%mdk + +%mdk-data-line={4254} +\begin{itemize}%mdk + +%mdk-data-line={4254} +\item{} +%mdk-data-line={4254} +\mdline{4254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4254} is a \mdline{4254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4254}, the unique identifier for the counter.%mdk%mdk + +%mdk-data-line={4256} +\item{} +%mdk-data-line={4256} +\mdline{4256}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4256} is a Protobuf message that encapsulates an \mdline{4256}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4256}, used to index into +the counter array.%mdk%mdk + +%mdk-data-line={4259} +\item{} +%mdk-data-line={4259} +\mdline{4259}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4259} is a Protobuf message of type \mdline{4259}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterData}}}\mdline{4259}, which represents the +counter value.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4262} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4263} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~CounterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~counter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4270} +\noindent\mdline{4270}The \mdline{4270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4270} can only be used in a \mdline{4270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4270} with the \mdline{4270}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4270} update +type. The P4Runtime server must return an \mdline{4271}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4271} error code for +update types \mdline{4272}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4272} and \mdline{4272}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4272}. By default all the counter entries in the +array have default value 0.%mdk + +%mdk-data-line={4275} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4275} +\item\mdline{4275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4275}: Server returns the error code \mdline{4275}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4275}.%mdk + +%mdk-data-line={4276} +\item\mdline{4276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4276}: Modify an indirect counter instance whose unique id is \mdline{4276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4276} +and array index is specified by \mdline{4277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4277}. The counter value is set to the value +specified by the client in the \mdline{4278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4278} field. Note that the counter value is +not modified if this Protobuf field is not set. If \mdline{4279}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4279} is omitted all +counter values in the array will be set to the value provided by the +client. The server must return \mdline{4281}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4281} for a negative index value +and \mdline{4282}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4282} if the index value exceeds the size of the counter array.%mdk + +%mdk-data-line={4283} +\item\mdline{4283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4283}: Server returns the error code \mdline{4283}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4283}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4285} +\noindent\mdline{4285}A P4Runtime client may request to read the counter values of one or more +indirect counter instances with a \mdline{4286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4286} by including a \mdline{4286}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{4286} +entity for each of the instances, specifying the \mdline{4287}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4287} and +\mdline{4288}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4288}. Wildcard reads are also supported as follows:%mdk + +%mdk-data-line={4290} +\begin{itemize}%mdk + +%mdk-data-line={4290} +\item{} +%mdk-data-line={4290} +\mdline{4290}If the \mdline{4290}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4290} field is set to 0 (default), the server returns the +counter values for all indirect counter instances in the \mdline{4291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4291}.%mdk%mdk + +%mdk-data-line={4293} +\item{} +%mdk-data-line={4293} +\mdline{4293}Otherwise, if the \mdline{4293}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4293} field is not set, the server returns the counter +values for all indirect counters in the array identified by the unique id +\mdline{4295}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{4295}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4297} +\subsection{\mdline{4297}9.4.\hspace*{0.5em}\mdline{4297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4297} \mdline{4297}\&\mdline{4297} \mdline{4297}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-meterentry-directmeterentry}%mdk%mdk + +%mdk-data-line={4299} +\noindent\mdline{4299}Meters are an advanced mechanism for keeping statistics, involving stateful +\mdline{4300}\textquotedblleft{}marking\textquotedblright{}\mdline{4300} and usually \mdline{4300}\textquotedblleft{}throttling\textquotedblright{}\mdline{4300} of packets based on configured rates of +traffic. The PSA metering function is based on the \mdline{4301}\emph{Two Rate Three Color Marker}\mdline{4301} +(trTCM) defined in RFC 2698\mdline{4302}~[\mdcite{rfc2698}{3}]\mdline{4302}. P4Runtime clients may additionally +restrict meter usage on a table to RFC 2697\mdline{4303}'\mdline{4303}s\mdline{4303}~[\mdcite{rfc2697}{2}]\mdline{4303} \mdline{4303}\emph{Single Rate Three +Color Marker}\mdline{4304} (srTCM) or a simplified version of it that we call \mdline{4304}\emph{Single Rate +Two Color Marker}\mdline{4305}. The type of a table\mdline{4305}'\mdline{4305}s meter is set by the \mdline{4305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec.Type}}}\mdline{4305} as +described in the\mdline{4306}~\mdref{sec-meter-directmeter}{Meter \& DirectMeter section}\mdline{4306}.%mdk + +%mdk-data-line={4308} +\mdline{4308}The trTCM meters an arbitrary packet stream using two configured rates\mdline{4308} \mdline{4308}\textemdash{}\mdline{4308} +the Peak Information Rate (PIR) and Committed Information Rate (CIR), and their +associated burst sizes\mdline{4310} \mdline{4310}\textemdash{}\mdline{4310} and \mdline{4310}\textquotedblleft{}marks\textquotedblright{}\mdline{4310} its packets as GREEN, YELLOW or RED based +on the observed rate.%mdk + +%mdk-data-line={4313} +\mdline{4313}The srTCM meters an arbitrary packet stream using a single configured rate\mdline{4313} \mdline{4313}\textemdash{}\mdline{4313} +the Committed Information Rate (CIR) and its associated burst size\mdline{4314} \mdline{4314}\textemdash{}\mdline{4314} as well +as the Excess Burst Size (EBS) and \mdline{4315}\textquotedblleft{}marks\textquotedblright{}\mdline{4315} its packets as GREEN, YELLOW or RED +based on the observed rate.%mdk + +%mdk-data-line={4318} +\mdline{4318}The \mdline{4318}\emph{Single Rate Two Color Marker}\mdline{4318} meters an arbitary packet stream using a +single configured rate\mdline{4319} \mdline{4319}\textemdash{}\mdline{4319} the Committed Information Rate (CIR) and its +associated burst size\mdline{4320} \mdline{4320}\textemdash{}\mdline{4320} and \mdline{4320}\textquotedblleft{}marks\textquotedblright{}\mdline{4320} its packets as GREEN or RED based on the +observed rate.%mdk + +%mdk-data-line={4323} +\mdline{4323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4323} \mdline{4323}\&\mdline{4323} \mdline{4323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4323} have an additional field \mdline{4323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4323} that +may hold per color counter data for targets that support it, and that must +always be unset for targets that do not support it. If set in a request and +unsupported by a target, an \mdline{4326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4326} error code should be returned. +These counters provide a granular list of the counters applicable to the +possible meter colors GREEN, YELLOW and RED. The counter associated with a +specific color is incremented when a packet is \mdline{4329}\textquotedblleft{}marked\textquotedblright{}\mdline{4329} with that color. The +primary purpose of the color counters is for debugging purposes.%mdk + +%mdk-data-line={4332} +\mdline{4332}A meter may be configured as a direct or indirect instance, similar to a +counter. The \mdline{4333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{4333} P4Runtime message represents meter configuration.%mdk + +%mdk-data-line={4335} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4336} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterConfig~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~cir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~Committed~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~cburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};~~{\mdcolor{darkgreen}//~Committed~Burst~Size}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pir~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};~~{\mdcolor{darkgreen}//~Peak~Information~Rate}\\ +~~{\bfseries{\mdcolor{navy}int64}}~pburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};~~{\mdcolor{darkgreen}//~Peak~Burst~Size}\\ +~~{\bfseries{\mdcolor{navy}int64}}~eburst~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};~{\mdcolor{darkgreen}//~Excess~burst~size~(only~used~for~srTCM)}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4345} +\noindent\mdline{4345}A MeterConfig for a trTCM typed meter must only be accepted if \mdline{4345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}eburst}}}\mdline{4345} is +unset. Otherwise, the server should return an \mdline{4346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4346} error.%mdk + +%mdk-data-line={4348} +\mdline{4348}A MeterConfig for a srTCM typed meter must only be accepted if \mdline{4348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}pir}}}\mdline{4348} and +\mdline{4349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}pburst}}}\mdline{4349} are equal to \mdline{4349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cir}}}\mdline{4349} and \mdline{4349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cburst}}}\mdline{4349} respectively. Otherwise, the server +should return an \mdline{4350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4350} error.%mdk + +%mdk-data-line={4352} +\mdline{4352}A MeterConfig for a \mdline{4352}\emph{Single Rate Two Color Marker}\mdline{4352} typed meter must only be +accepted if \mdline{4353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}pir}}}\mdline{4353} and \mdline{4353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}pburst}}}\mdline{4353} are equal to \mdline{4353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cir}}}\mdline{4353} and \mdline{4353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cburst}}}\mdline{4353} respectively and +\mdline{4354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}eburst}}}\mdline{4354} is unset. Otherwise, the server should return an \mdline{4354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4354} +error.%mdk + +%mdk-data-line={4357} +\mdline{4357}Note: Any acceptable MeterConfig for a \mdline{4357}\emph{Single Rate Two Color Marker}\mdline{4357} typed +meter is also acceptable for either of the other two meter types and will mark +packets identically in all three cases. Thus, changing the meter type from +\mdline{4360}\emph{Single Rate Two Color Marker}\mdline{4360} to \mdline{4360}\emph{Single Rate Three Color Marker}\mdline{4360} or +\mdline{4361}\emph{Two Rate Three Color Marker}\mdline{4361} is a non-breaking change.%mdk + +%mdk-data-line={4363} +\subsubsection{\mdline{4363}9.4.1.\hspace*{0.5em}\mdline{4363}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}}\label{sec-directmeterentry}%mdk%mdk + +%mdk-data-line={4365} +\noindent\mdline{4365}A direct meter is a direct resource associated with a \mdline{4365}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4365} (see\mdline{4365}~\mdref{sec-direct-resources}{Direct +resources}\mdline{4366}). The \mdline{4366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{4366} field of the \mdline{4366}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4366} +message can be used to initialize the meter configuration at the same time as +the table entry is inserted. Once the table entry has been created, the +P4Runtime client may modify the associated direct meter entry using the +\mdline{4370}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4370} message. Once the table entry is deleted the associated +direct meter entry can no longer be accessed.%mdk + +%mdk-data-line={4373} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4374} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~DirectMeterEntry~\{\\ +~~TableEntry~table\_entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterCounterData~counter\_data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4381} +\noindent\mdline{4381}A \mdline{4381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4381} may only include an \mdline{4381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4381} message of type \mdline{4381}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4381} with a +\mdline{4382}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4382}, whose fields are specified by the client as follows:%mdk + +%mdk-data-line={4384} +\begin{itemize}%mdk + +%mdk-data-line={4384} +\item{} +%mdk-data-line={4384} +\mdline{4384}the \mdline{4384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4384} field must match the match key of the \mdline{4384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4384} +message used to insert the entry and the associated direct meter entry. The +action field is ignored in this case. If a matching \mdline{4386}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4386} is not found, +the server returns the error code \mdline{4387}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4387}.%mdk%mdk + +%mdk-data-line={4389} +\item{} +%mdk-data-line={4389} +\mdline{4389}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4389} is used to set the configuration for the meter entry to the value +specified by the client. Note that if this Protobuf field is not set, the +meter config is set to execute the default behavior (GREEN for all packets).%mdk%mdk + +%mdk-data-line={4393} +\item{} +%mdk-data-line={4393} +\mdline{4393}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4393} is used to set the per color counter values to the default +value of (0), which is essentially clearing the counters. If the field is +unset, the counter values are left untouched. If the field is set, targets +supporting these counters should reset all the color counters to (0), if any +of the sub-fields are set to a non-zero value, then an \mdline{4397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4397} +error should be returned.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4400} +\noindent\mdline{4400}Specifying \mdline{4400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4400} in an \mdline{4400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4400} message of type \mdline{4400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4400} or +\mdline{4401}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4401} is not allowed, and the server must return the error code +\mdline{4402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4402} in that case.%mdk + +%mdk-data-line={4404} +\mdline{4404}A client may use \mdline{4404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4404} in two ways to read a \mdline{4404}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeter}}}\mdline{4404} config.%mdk + +%mdk-data-line={4406} +\begin{itemize}%mdk + +%mdk-data-line={4406} +\item{} +%mdk-data-line={4406} +\mdline{4406}As a direct resource associated with a table entry, request the server to +return the meter config in the \mdline{4407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_config}}}\mdline{4407} field of the \mdline{4407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4407} +message (see\mdline{4408}~\mdref{sec-direct-resources}{Direct resources}\mdline{4408}).%mdk%mdk + +%mdk-data-line={4410} +\item{} +%mdk-data-line={4410} +\mdline{4410}Explicitly request the meter configuration by including the \mdline{4410}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4410} +in the \mdline{4411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4411}. The \mdline{4411}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry.match}}}\mdline{4411} field must match the +\mdline{4412}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4412} whose meter config is being read. If no such entry is found, the +server returns the error code \mdline{4413}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{4413}. Read responses also include the +per color counter data for the meter entry, if supported and specified in +the request message.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4417} +\subsubsection{\mdline{4417}9.4.2.\hspace*{0.5em}\mdline{4417}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}}\label{sec-meterentry}%mdk%mdk + +%mdk-data-line={4419} +\noindent\mdline{4419}An indirect or indexed meter is not associated with a specific \mdline{4419}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4419} and +may be executed independently of any action. Its configuration may be read or +written using the P4Runtime \mdline{4421}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4421} message whose fields are defined as +follows:%mdk + +%mdk-data-line={4424} +\begin{itemize}%mdk + +%mdk-data-line={4424} +\item{} +%mdk-data-line={4424} +\mdline{4424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4424} is a \mdline{4424}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4424}, the unique identifier for the meter.%mdk%mdk + +%mdk-data-line={4426} +\item{} +%mdk-data-line={4426} +\mdline{4426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4426} is a Protobuf message that encapsulates an \mdline{4426}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int64}}}\mdline{4426}, used to index into +a meter array.%mdk%mdk + +%mdk-data-line={4429} +\item{} +%mdk-data-line={4429} +\mdline{4429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4429} is a Protobuf message of type \mdline{4429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{4429}, which represents the +meter configuration.%mdk%mdk + +%mdk-data-line={4432} +\item{} +%mdk-data-line={4432} +\mdline{4432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_data}}}\mdline{4432} is a Protobuf message of type \mdline{4432}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4432}, which +represents the per color counter values associated with the corresponding +meter.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4436} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4437} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~meter\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Index~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~MeterConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~MeterCounterData~counter\_data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4445} +\noindent\mdline{4445}The \mdline{4445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4445} can only be used in a \mdline{4445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4445} with the \mdline{4445}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4445} update +type. The P4Runtime server must return an \mdline{4446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4446} error code for +update types \mdline{4447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4447} and \mdline{4447}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4447}. By default all the meter entries in the +array have a default configuration (GREEN for all packets).%mdk + +%mdk-data-line={4450} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4450} +\item\mdline{4450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4450}: Server returns the error code \mdline{4450}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4450}.%mdk + +%mdk-data-line={4451} +\item\mdline{4451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4451}: Modify an indirect meter instance whose unique id is \mdline{4451}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4451} and +array index is specified by \mdline{4452}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4452}. The meter is reconfigured using the +\mdline{4453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4453} field specified by the client. Note that the meter configuration is +set to the default behavior (GREEN for all packets) if this Protobuf field is +not set. If the \mdline{4455}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4455} field is omitted all meter configurations in the array +will be set to the value provided by the client (or reset to the default value +if \mdline{4457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4457} is unset). The server must return \mdline{4457}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4457} for a +negative index value and \mdline{4458}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4458} if the index value exceeds the size of +the meter array.%mdk + +%mdk-data-line={4460} +\item\mdline{4460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4460}: Server returns the error code \mdline{4460}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4460}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4462} +\noindent\mdline{4462}A P4Runtime client may request to read the configuration of one or more indirect +meter instances with a \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{4463} by including a \mdline{4463}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4463} entity for each +of the instances, specifying the \mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4464} and \mdline{4464}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4464}. Wildcard reads are also +supported as follows:%mdk + +%mdk-data-line={4467} +\begin{itemize}%mdk + +%mdk-data-line={4467} +\item{} +%mdk-data-line={4467} +\mdline{4467}If the \mdline{4467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4467} field is set to 0 (default), the server returns the +configuration for all indirect meter instances in the \mdline{4468}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4468}.%mdk%mdk + +%mdk-data-line={4470} +\item{} +%mdk-data-line={4470} +\mdline{4470}Otherwise, if the \mdline{4470}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4470} field is not set, the server returns the +configuration for all indirect meters in the array identified by the unique id +\mdline{4472}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}meter\_id}}}\mdline{4472}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4474} +\subsubsection{\mdline{4474}9.4.3.\hspace*{0.5em}\mdline{4474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}}\label{sec-metercounterdata}%mdk%mdk + +%mdk-data-line={4476} +\noindent\mdline{4476}The \mdline{4476}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4476} P4Runtime message represents the per color counters +associated with a meter entry. Whenever a meter is executed and returns +a color, the corresponding color counter GREEN, YELLOW or RED is updated.%mdk + +%mdk-data-line={4480} +\mdline{4480}As seen above, these counters can be associated with a \mdline{4480}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DirectMeterEntry}}}\mdline{4480} or +\mdline{4481}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterEntry}}}\mdline{4481}. Targets not capable of supporting these counters should return +\mdline{4482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{4482} if a \mdline{4482}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterCounterData}}}\mdline{4482} field was set in a read or write +request.%mdk + +%mdk-data-line={4485} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4486} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MeterCounterData~\{\\ +~~CounterData~green~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~CounterData~yellow~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~CounterData~red~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4494} +\subsection{\mdline{4494}9.5.\hspace*{0.5em}\mdline{4494}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketReplicationEngineEntry}}}}\label{sec-packetreplicationengineentry}%mdk%mdk + +%mdk-data-line={4496} +\noindent\mdline{4496}The PSA Packet Replication Engine (PRE) is an extern that is implicitly +instantiated in all PSA programs. The PRE is responsible for implementing +multicasting and cloning functionality in the data plane. P4Runtime defines an +API to program the PRE with multicast groups and clone sessions to allow +replication of data plane packets.%mdk + +%mdk-data-line={4502} +\subsubsection{\mdline{4502}9.5.1.\hspace*{0.5em}\mdline{4502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}}\label{sec-multicastgroupentry}%mdk%mdk + +%mdk-data-line={4504} +\noindent\mdline{4504}Multicasting is achieved in PSA programs by setting the \mdline{4504}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4504} +ingress output metadata to a non-zero identifier. The number of replicas and +their egress ports for the multicast group is programmed at runtime by the +client using the \mdline{4507}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4507} API in P4Runtime. The following P4 +program illustrates a possible data plane behavior of multicasting ARP packets +in the ingress. Note that the data plane type of the multicast group metadata is +10 bits on the PSA device in this example.%mdk + +%mdk-data-line={4512} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4513} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~arp\_multicast({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ethernet.isValid()~\&\&\\ +~~~~~~~~hdr.ethernet.eth\_type~==~ETH\_TYPE\_ARP)~\{\\ +~~~~~~smeta.multicast\_group~=~(MulticastGroup\_t)~{\mdcolor{purple}1};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4523} +\noindent\mdline{4523}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4526} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4527} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~multicast\_group\_entry~\{\\ +~~~~~~multicast\_group\_id:~{\mdcolor{purple}1}\\ +~~~~~~replicas~\{~port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x05}{\mdcolor{maroon}"}~instance:~{\mdcolor{purple}1}~\}\\ +~~~~~~replicas~\{~port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x0c}{\mdcolor{maroon}"}~instance:~{\mdcolor{purple}2}~\}\\ +~~~~~~replicas~\{~port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x12}{\mdcolor{maroon}"}~instance:~{\mdcolor{purple}3}~\}\\ +~~~~~~replicas~\{~port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}x18}{\mdcolor{maroon}"}~instance:~{\mdcolor{purple}4}~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4541} +\noindent\mdline{4541}As a result of the above P4Runtime programming, the target device will create +four replicas of an ARP packet. These replicas will appear in the egress +pipeline as independent packets with egress port set to PSA device port numbers +corresponding to SDN port numbers 5, 12, 18 and 24. For more discussion on the +translation between SDN ports and PSA device ports, refer to the +\mdline{4546}\mdref{sec-translation-of-port-numbers}{PSA Metadata Translation}\mdline{4546} section.%mdk + +%mdk-data-line={4548} +\mdline{4548}The egress packets may be distinguished for further processing in the egress +using the \mdline{4549}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4549} metadata. Note that a packet may not be both unicast and +multicast; if the multicast group is set, it will override the unicast egress +port. If the P4 \mdline{4551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4551} metadata is set to a value that is not +programmed in the PRE, then the packet is dropped.%mdk + +%mdk-data-line={4554} +\mdline{4554}A multicast group may be inserted, modified or deleted as per the following +semantics.%mdk + +%mdk-data-line={4557} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4557} +\item\mdline{4557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4557}: Add a new multicast group entry bound to a set of egress ports and +replica IDs. The \mdline{4558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4558} field is a \mdline{4558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4558} and must be greater +than 0 (see explanation\mdline{4559}~\mdref{sec-valid-values-for-mg-id}{below}\mdline{4559}), or the +P4Runtime server must return an \mdline{4560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4560} error. The replica +\mdline{4561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4561} ID is also a \mdline{4561}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4561}, and its value may not exceed the maximum +allowed by the target for the \mdline{4562}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4562} type (0 is allowed), or the +server must return an \mdline{4563}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4563} error. The egress port (\mdline{4563}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{4563} field) +must be an SDN port and must refer to a singleton port. No two replicas may +have identical values of \mdline{4565}\emph{both}\mdline{4565} \mdline{4565}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{4565} and \mdline{4565}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4565}, or the server must +return \mdline{4566}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4566}. The \mdline{4566}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{4566} field is an arbitrary \mdline{4566}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{4566} value +which is opaque to the target. There is no requirement of where this is +stored, but it must be returned by the server along with the rest of the entry +when the client performs a read on the entry.%mdk + +%mdk-data-line={4570} +\item\mdline{4570}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4570}: Modify the set of replicas and metadata for a given multicast group +entry, indexed by the given \mdline{4571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4571}. Same restrictions as +\mdline{4572}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4572} apply here.%mdk + +%mdk-data-line={4573} +\item\mdline{4573}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4573}: Delete the multicast group indexed by the given +\mdline{4574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4574}. The \mdline{4574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}replicas}}}\mdline{4574} and \mdline{4574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{4574} fields need not be +provided for this operation. Any packets with their \mdline{4575}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group}}}\mdline{4575} +metadata in the data plane set to the deleted \mdline{4576}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4576} will be +dropped.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4579} +\noindent\mdline{4579}When reading a multicast group, only \mdline{4579}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4579} is considered. All +other fields in \mdline{4580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{4580} are ignored. To perform a \mdline{4580}\emph{wildcard}\mdline{4580} +\mdline{4581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4581} on all configured multicast group entries, the \mdline{4581}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4581} field +must be set to 0, its default value.%mdk + +%mdk-data-line={4584} +\paragraph{\mdline{4584}9.5.1.1.\hspace*{0.5em}\mdline{4584}Valid Values for \mdline{4584}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}}\label{sec-valid-values-for-mg-id}%mdk%mdk + +%mdk-data-line={4586} +\noindent\mdline{4586}The PSA specification states that the valid \mdline{4586}\emph{data plane}\mdline{4586} values for multicast +group ids (\mdline{4587}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroup\_t}}}\mdline{4587}) range from 1 (0 is a special value that indicates +no multicast replication is to be performed for a packet) to the maximum value +supported by the target\mdline{4589}~[\mdcite{psatranslation}{29}]\mdline{4589}. This means that, in the absence of +translation, the client must set the \mdline{4590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4590} field to a value in +this range when inserting a multicast group. However, because P4Runtime reserves +0 as a special \mdline{4592}\emph{wildcard}\mdline{4592} value which is used to read all the multicast groups +configured in the target, the \mdline{4593}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}multicast\_group\_id}}}\mdline{4593} field must never be set to 0 +when performing a \mdline{4594}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4594} RPC, even when numerical translation is enabled for +multicast group ids. In other words, it is not possible to map (using +translation) a zero SDN multicast group id value to a non-zero data plane +multicast group id value.%mdk + +%mdk-data-line={4599} +\subsubsection{\mdline{4599}9.5.2.\hspace*{0.5em}\mdline{4599}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}}\label{sec-clonesessionentry}%mdk%mdk + +%mdk-data-line={4601} +\noindent\mdline{4601}PSA supports cloning of packets in both the ingress and egress pipeline. Ingress +cloning creates a mirror of the packet as seen in the beginning of the ingress +pipeline, while egress cloning creates a mirror of the packet as seen at the end +of the egress pipeline. A packet is cloned in the data plane by setting a +\mdline{4605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4605} identifier and a boolean flag \mdline{4605}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone}}}\mdline{4605} in the packet +metadata. The \mdline{4606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4606} serves as a handle to the clone attributes, +namely a set \mdline{4607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}replicas}}}\mdline{4607} of \mdline{4607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(egress~port,~instance)}}}\mdline{4607} pairs to which +cloned packets should be sent, a packet length, and class of +service. These are programmed at runtime via the P4Runtime +\mdline{4610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4610} API.%mdk + +%mdk-data-line={4612} +\mdline{4612}The following P4 program illustrates a possible data plane behavior of sending +clones of low TTL packets to the CPU for monitoring. Note that the data plane +type of the clone session metadata is 10 bits on the PSA device in this example. +We assume that the \mdline{4615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_low\_ttl}}}\mdline{4615} control block is applied in the ingress +pipeline to create an ingress-to-egress clone.%mdk + +%mdk-data-line={4618} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4619} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~clone\_low\_ttl({\bfseries{\mdcolor{navy}inout}}~H~hdr,~{\bfseries{\mdcolor{navy}inout}}~M~smeta)~\{\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(hdr.ipv4.isValid()~\&\&\\ +~~~~~~~~hdr.ipv4.ttl~\textless{}=~LOW\_TTL\_THRESHOLD)~\{\\ +~~~~~~smeta.clone\_session\_id~=~{\mdcolor{purple}10}w100;\\ +~~~~~~smeta.clone~=~{\bfseries{\mdcolor{navy}true}};\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4631} +\noindent\mdline{4631}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4634} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4635} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~INSERT\\ +entity~\{\\ +~~packet\_replication\_engine\_entry~\{\\ +~~~~clone\_session\_entry~\{\\ +~~~~~~session\_id:~{\mdcolor{purple}100}\\ +~~~~~~replicas~\{~port:~{\mdcolor{maroon}"}{\mdcolor{gray}\textbackslash{}xff}{\mdcolor{gray}\textbackslash{}xff}{\mdcolor{gray}\textbackslash{}xff}{\mdcolor{gray}\textbackslash{}xfd}{\mdcolor{maroon}"}~instance:~{\mdcolor{purple}1}~\}~{\mdcolor{darkgreen}\#~to~CPU}\\ +~~~~~~class\_of\_service:~{\mdcolor{purple}2}\\ +~~~~~~packet\_length\_bytes:~{\mdcolor{purple}4096}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4648} +\noindent\mdline{4648}As a result of the above P4Runtime programming, the target device will create +one replica of a low TTL packet from the ingress to the egress. Note that the +clone session ID of the programmed PRE entry is identical to the value used in +the data plane in this example (no numerical translation, which is the default +for values of type \mdline{4652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4652}~[\mdcite{psatranslation}{29}]\mdline{4652}). The clone will be +treated for scheduling in the PRE with a class of service value of 2. If the +packet is larger than 4096 bytes, it will be truncated to carry at most 4096 +bytes.%mdk + +%mdk-data-line={4657} +\mdline{4657}The cloned replica will appear in the egress pipeline as an independent packet +with egress port set to CPU (corresponding to SDN port \mdline{4658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfffffffd}}}\mdline{4658}; see +\mdline{4659}\mdref{sec-translation-of-port-numbers}{Translation of Port Numbers}\mdline{4659}). Note that the +egress port (\mdline{4660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{4660} field) must be an SDN port and must refer to a singleton +port.%mdk + +%mdk-data-line={4663} +\mdline{4663}If the \mdline{4663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4663} data plane metadata is set to a value that is not +programmed in the PRE, then no clones are created.%mdk + +%mdk-data-line={4666} +\mdline{4666}A clone session may be inserted, modified or deleted as per the following +semantics:%mdk + +%mdk-data-line={4669} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4669} +\item\mdline{4669}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4669}: Add a new clone session entry bound to a set of egress ports and +replica IDs. The \mdline{4670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4670} is a \mdline{4670}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4670} and must be greater than 0 (see +explanation\mdline{4671}~\mdref{sec-valid-values-for-session-id}{below}\mdline{4671}), or the P4Runtime +server must return an \mdline{4672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4672} error. The replica \mdline{4672}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}instance}}}\mdline{4672} ID is +also a \mdline{4673}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4673}, and its value may not exceed the maximum allowed by the +target for the \mdline{4674}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EgressInstance\_t}}}\mdline{4674} type (0 is allowed), or the server must also +return an \mdline{4675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4675} error. The egress port (\mdline{4675}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{4675} field) in the +replica must be an SDN port and must refer to a singleton port. The class of +service for each clone packet instance will be set to the value programmed in +the clone session entry (\mdline{4678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}class\_of\_service}}}\mdline{4678} field). This value must be a valid +value for the PSA \mdline{4679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ClassOfService\_t}}}\mdline{4679} type, which supports runtime translation +by default\mdline{4680}~[\mdcite{psatranslation}{29}]\mdline{4680}, or the server must return +\mdline{4681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4681}. See\mdline{4681}~\mdref{sec-translation-of-port-numbers}{PSA Metadata +Translation}\mdline{4682} for more information. The +\mdline{4683}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4683} field must be set to a non-zero value if the clone +packet should be truncated to the given value (in bytes). If the +\mdline{4685}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_length\_bytes}}}\mdline{4685} field is 0 (default), no truncation on the clone will be +performed.%mdk + +%mdk-data-line={4687} +\item\mdline{4687}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4687}: Modify the attributes of a given clone session entry, indexed by the +given \mdline{4688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4688}. Same restrictions as \mdline{4688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4688} apply here.%mdk + +%mdk-data-line={4689} +\item\mdline{4689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4689}: Delete the clone session indexed by the given +\mdline{4690}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4690}. Other fields need not be provided for this operation. Any +packet with their \mdline{4691}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}clone\_session\_id}}}\mdline{4691} metadata in the data plane set to the +deleted \mdline{4692}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4692} will no longer be cloned.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4694} +\noindent\mdline{4694}When reading a clone session, only \mdline{4694}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4694} is considered. All other fields +in \mdline{4695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionEntry}}}\mdline{4695} are ignored. To perform a \mdline{4695}\emph{wildcard}\mdline{4695} \mdline{4695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{4695} on all +configured clone session entries, the \mdline{4696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4696} field must be set to 0, its +default value. The \mdline{4697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4697} field can never be equal to 0 in a \mdline{4697}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{4697} +RPC. If it does, the server must return an \mdline{4698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4698} error.%mdk + +%mdk-data-line={4700} +\paragraph{\mdline{4700}9.5.2.1.\hspace*{0.5em}\mdline{4700}Valid Values for \mdline{4700}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}}\label{sec-valid-values-for-session-id}%mdk%mdk + +%mdk-data-line={4702} +\noindent\mdline{4702}The PSA specification states that the valid \mdline{4702}\emph{data plane}\mdline{4702} values for clone +session ids (\mdline{4703}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4703}) range from 0 to the maximum value supported by +the target\mdline{4704}~[\mdcite{psatranslation}{29}]\mdline{4704}. Note that unlike for\mdline{4704}~\mdref{sec-valid-values-for-mg-id}{multicast group +ids}\mdline{4705}, 0 is a valid \mdline{4705}\emph{data plane}\mdline{4705} value for clone +session ids. However, just like for multicast group ids, P4Runtime reserves 0 as +a special \mdline{4707}\emph{wildcard}\mdline{4707} value which is used to read all the clone sessions +configured in the target. This means that 0 can never be used as a \mdline{4708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}session\_id}}}\mdline{4708} +value when inserting a clone session, whether or not numeric translation is +enabled for clone session ids. If translation is \mdline{4710}\emph{not}\mdline{4710} enabled, we effectively +\mdline{4711}\textquotedblleft{}lose\textquotedblright{}\mdline{4711} one clone session, assuming the target supports 0 as mandated by the PSA +specification. If this is an issue (\mdline{4712}e.g.\mdline{4712} because the target supports a very +limited number of clone sessions), one can enable translation on +\mdline{4714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CloneSessionId\_t}}}\mdline{4714} and map any non-zero SDN session id to the data plane clone +session with id 0, then insert a clone session with the chosen SDN session id.%mdk + +%mdk-data-line={4717} +\subsection{\mdline{4717}9.6.\hspace*{0.5em}\mdline{4717}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}}\label{sec-valuesetentry}%mdk%mdk + +%mdk-data-line={4719} +\noindent\mdline{4719}Parser Value Set is a construct in P4 that is used to support programmability of +parser state transitions. A transition select statement in P4 can use a parser +Value Set to define a runtime programmable state transition as shown in the +example below. A runtime programmable set of TRILL Ethertypes is used to +transition the parser state machine to the \mdline{4723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4723} state.%mdk + +%mdk-data-line={4725} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={4726} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}state}}~parse\_l2~\{\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}(MAX\_TRILL\_TYPES)~trill\_types;}\\ +~~extract(hdr.ethernet);\\ +~~{\bfseries{\mdcolor{navy}select}}~(hdr.ethernet.eth\_type)~\{\\ +~~~~ETH\_TYPE\_IPV4:~parse\_ipv4;\\ +~~~~ETH\_TYPE\_IPV6:~parse\_ipv6;\\ +~~~~trill\_types:~~~parse\_trill\_types;\\ +~~~~\_:~~~~~~~~~~~~~reject;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4738} +\noindent\mdline{4738}The corresponding entry in the P4Info for this Value Set is:%mdk + +%mdk-data-line={4740} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4741} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}trill\_types}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~bitwidth:~\textless{}ETH\_TYPE\_BITWIDTH\textgreater{}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~size:~\textless{}MAX\_TRILL\_TYPES\textgreater{}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4755} +\noindent\mdline{4755}At runtime, the client writes the following update in the target (shown in +Protobuf text format).%mdk + +%mdk-data-line={4758} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4759} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x22f3}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0x893b}~\}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4777} +\noindent\mdline{4777}As a result of the above P4Runtime programming, all packets with EtherType +values of 0x22f3 and 0x893b will be parsed as per the state machine starting at +the \mdline{4779}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}parse\_trill\_types}}}\mdline{4779} state.%mdk + +%mdk-data-line={4781} +\mdline{4781}A \mdline{4781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4781} entity update message has the following fields:%mdk + +%mdk-data-line={4783} +\begin{itemize}%mdk + +%mdk-data-line={4783} +\item{} +%mdk-data-line={4783} +\mdline{4783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4783} is the \mdline{4783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}uint32}}}\mdline{4783} identifier of the Value Set instance, as +defined in P4Info.%mdk%mdk + +%mdk-data-line={4786} +\item{} +%mdk-data-line={4786} +\mdline{4786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4786} is a repeated field of type \mdline{4786}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4786}. When \mdline{4786}\textquotedblleft{}selecting\textquotedblright{}\mdline{4786} +against a Value Set, every member will be considered and if at least one +\mdline{4788}\textquotedblleft{}matches\textquotedblright{}\mdline{4788}, the corresponding parser transition will be taken. Each +\mdline{4789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4789} contains a repeated field of \mdline{4789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4789} messages, each one +used to provide a value for the corresponding match in the P4Info message for +this Value Set. Note that a packet matches a \mdline{4791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetMember}}}\mdline{4791} if and only if +it matches all its \mdline{4792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4792} messages. This is similar to how a packet +matches a table entry if and only if it matches all the components of the +match key for this entry. \mdline{4794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{4794} messages in a \mdline{4794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4794} follow +the\mdline{4795}~\mdref{sec-match-format}{same rules}\mdline{4795} as in a \mdline{4795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{4795}.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4797} +\noindent\mdline{4797}A \mdline{4797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ValueSetEntry}}}\mdline{4797} may only be modified. If the update type is \mdline{4797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4797} or +\mdline{4798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4798}, the server must return an \mdline{4798}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4798} error. If the update type +is \mdline{4799}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4799}, the server writes the members given in the repeated field to the +Value Set entry indexed by the given \mdline{4800}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_set\_id}}}\mdline{4800}. The maximum number of +matches must not exceed the maximum size given by the \mdline{4801}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{4801} field in P4Info of +the Value Set, otherwise the server must return a \mdline{4802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{4802} error. To +empty a Value Set (\mdline{4803}i.e.\mdline{4803} restore it to its initial state), the P4Runtime client +can perform a \mdline{4804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4804} update with an empty \mdline{4804}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}members}}}\mdline{4804} repeated field.%mdk + +%mdk-data-line={4806} +\mdline{4806}To facilitate\mdline{4806}~\mdref{sec-read-write-symmetry}{read-write symmetry}\mdline{4806}, the server must +return an \mdline{4807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{4807} error in case of duplicate members. Unlike for match +tables, a priority value is not required for ternary, range and optional +matches: overlapping entries do not need to be ordered and the parse state +transition is determined by whether or not the packet matches at least one entry +in the set.%mdk + +%mdk-data-line={4813} +\mdline{4813}See Appendix\mdline{4813}~\mdref{sec-value-set-example}{A.3}\mdline{4813} for a more complex Value Set example.%mdk + +%mdk-data-line={4815} +\subsection{\mdline{4815}9.7.\hspace*{0.5em}\mdline{4815}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}}\label{sec-registerentry}%mdk%mdk + +%mdk-data-line={4817} +\noindent\mdline{4817}The PSA Register extern is a stateful memory array that can be read and written +during packet forwarding. The \mdline{4818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4818} P4Runtime entity is used by the +client to read and write the contents of a Register instance as part of +control plane operations.%mdk + +%mdk-data-line={4822} +\mdline{4822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4822} has the following fields:%mdk + +%mdk-data-line={4824} +\begin{itemize}%mdk + +%mdk-data-line={4824} +\item{} +%mdk-data-line={4824} +\mdline{4824}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4824}, which identifies the PSA Register extern instance which is +being accessed by the client; the \mdline{4825}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}register\_id}}}\mdline{4825} is specified by the P4Info +message.%mdk%mdk + +%mdk-data-line={4828} +\item{} +%mdk-data-line={4828} +\mdline{4828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4828}, which identifies the array offset which is being accessed. It is +possible for the P4Runtime client to perform wildcard reads and writes on the +register array by leaving the index field unset in the \mdline{4830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4830} message +used for the request. When an \mdline{4831}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{4831} is provided , the server must validate +its value, and return \mdline{4832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4832} for a negative index or +\mdline{4833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OUT\_OF\_RANGE}}}\mdline{4833} if the index exceeds the size of the register array.%mdk%mdk + +%mdk-data-line={4835} +\item{} +%mdk-data-line={4835} +\mdline{4835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4835}: the data to be written to the array (if \mdline{4835}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4835} is part of a +\mdline{4836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{4836} message) or the data read from the array (if \mdline{4836}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RegisterEntry}}}\mdline{4836} is +part of a \mdline{4837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{4837} message). The \mdline{4837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}data}}}\mdline{4837} field is a \mdline{4837}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{4837} message and +must match the format described by the \mdline{4838}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type\_spec}}}\mdline{4838} field of the corresponding +Register entry in the P4Info, or the server must return an \mdline{4839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{4839} +error.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4842} +\subsection{\mdline{4842}9.8.\hspace*{0.5em}\mdline{4842}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}}\label{sec-digestentry}%mdk%mdk + +%mdk-data-line={4844} +\noindent\mdline{4844}A digest is one mechanism to send a message from the data plane to the +control plane. It is traditionally used for MAC address learning: when a packet +with an unknown source MAC address is received by the device, the control plane +is notified and can populate the L2 forwarding tables accordingly.%mdk + +%mdk-data-line={4849} +\mdline{4849}The \mdline{4849}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4849} P4Runtime entity is used to \mdline{4849}\textbf{configure}\mdline{4849} how the device must +generate digest messages. The \mdline{4850}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4850} Protobuf message is not used to +carry digest data, which is done on the \mdline{4851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{4851} bidirectional stream +using the \mdline{4852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4852} (digest data sent by the target to the client) and +\mdline{4853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4853} (digest data acknowledgments sent by the client to the target) +Protobuf messages.%mdk + +%mdk-data-line={4856} +\mdline{4856}In this section, we refer to the data learned by a single data plane call to +\mdline{4857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest\textless{}T\textgreater{}::pack}}}\mdline{4857} as a \mdline{4857}\textquotedblleft{}digest message\textquotedblright{}\mdline{4857} and we use \mdline{4857}\textquotedblleft{}digest list\textquotedblright{}\mdline{4857} to designate +the list of digest messages bundled by the P4Runtime service in a single +\mdline{4859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4859} stream message. Note that all the digest messages in a single +digest list correspond to the same P4 Digest extern instance. We say that 2 +digest messages are \mdline{4861}\textquotedblleft{}duplicate\textquotedblright{}\mdline{4861} if the data emitted by the data plane is exactly +the same as per P4 equality rules. We say that 2 digest messages are \mdline{4862}\textquotedblleft{}distinct\textquotedblright{}\mdline{4862} +if they are not duplicate.%mdk + +%mdk-data-line={4865} +\mdline{4865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4865} has the following fields:%mdk + +%mdk-data-line={4867} +\begin{itemize}%mdk + +%mdk-data-line={4867} +\item{} +%mdk-data-line={4867} +\mdline{4867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4867}, which identifies the PSA Digest extern instance which emitted the +data; the \mdline{4868}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4868} is determined by the P4Info message.%mdk%mdk + +%mdk-data-line={4870} +\item{} +%mdk-data-line={4870} +\mdline{4870}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{4870}, a Protobuf message which includes different parameters to tune how +digest messages are exchanged between server and client for a given +\mdline{4872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4872}; these parameters are:%mdk + +%mdk-data-line={4874} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4874} +\item\mdline{4874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4874}: the maximum server buffering delay in nanoseconds for an +outstanding digest message.%mdk + +%mdk-data-line={4876} +\item\mdline{4876}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4876}: the maximum digest list size\mdline{4876} \mdline{4876}\textemdash{}\mdline{4876} in number of digest +messages\mdline{4877} \mdline{4877}\textemdash{}\mdline{4877} sent by the server to the client as a single \mdline{4877}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4877} +Protobuf message.%mdk + +%mdk-data-line={4879} +\item\mdline{4879}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4879}: the timeout in nanoseconds that a server must wait for a +digest list acknowledgement from the client before new digest messages can +be generated for the same learned data.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4883} +\noindent\mdline{4883}Here is the significance of the different \mdline{4883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{4883} types for \mdline{4883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestEntry}}}\mdline{4883}:%mdk + +%mdk-data-line={4885} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4885} +\item\mdline{4885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{4885}: Enable server generation of \mdline{4885}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4885} messages for given digest +instance and use provided configuration parameters.%mdk + +%mdk-data-line={4887} +\item\mdline{4887}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{4887}: Use provided configuration parameters for given digest instance, +learning must have been previously enabled for the instance.%mdk + +%mdk-data-line={4889} +\item\mdline{4889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{4889}: Disable server generation of \mdline{4889}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4889} messages for given digest +instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4892} +\noindent\mdline{4892}A server should buffer digest messages until either:%mdk + +%mdk-data-line={4894} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={4894} +\item\mdline{4894}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4894} time has passed since the first digest message was added to +the empty buffer, or%mdk + +%mdk-data-line={4896} +\item\mdline{4896}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4896} \mdline{4896}\emph{distinct}\mdline{4896} digest messages have been received from the +data plane and added to the buffer%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={4899} +\noindent\mdline{4899}At which point the server should, with best effort, generate a \mdline{4899}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4899} +stream message with the buffer contents and send it to the primary client. All +the messages in a digest list must be distinct, which means that duplicates must +either be filtered-out directly by the device or in the P4Runtime server +software.%mdk + +%mdk-data-line={4905} +\mdline{4905}To avoid sending duplicate digest messages across different \mdline{4905}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4905} +messages, which could make the channel busy, we define an acknowledgement +mechanism through which the primary client indicates that it has received the +digest list and acted on it. The server must keep a \mdline{4908}\textquotedblleft{}cache\textquotedblright{}\mdline{4908} containing the set +of all digest messages that have been sent, but not acknowledged yet by the +primary client, up-to \mdline{4910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4910} in the past. The server must delete all +cache entries for a given digest list when they are at least \mdline{4911}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4911} +old or when a matching \mdline{4912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{4912} message (\mdline{4912}i.e.\mdline{4912} with the same \mdline{4912}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{4912} +and \mdline{4913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}list\_id}}}\mdline{4913} fields as the \mdline{4913}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4913} message) is received.%mdk + +%mdk-data-line={4915} +\mdline{4915}The acknowledgement mechanism described above is not used to implement some sort +of reliable transport for digest messages. The loss of digest messages or +acknowledgement messages is considered non-critical. The P4Runtime server may +drop digest messages if they are generated from the data plane faster than the +server software, the channel or the client can handle. P4Runtime does not impose +a limit on the number of in-flight, unacknowledged \mdline{4920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4920} messages.%mdk + +%mdk-data-line={4922} +\mdline{4922}When \mdline{4922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4922} is set to 0 and / or \mdline{4922}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4922} is set to 1, the +server should, with best effort, generate a \mdline{4923}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestList}}}\mdline{4923} message for every +digest message generated by the data plane which is not already in the cache. If +\mdline{4925}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ack\_timeout\_ns}}}\mdline{4925} is set to 0, the cache must always be an empty set. If +\mdline{4926}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_list\_size}}}\mdline{4926} is set to 0, there is no limit on the maximum size of digest +lists: the server can use any non-zero value as long as it honors the +\mdline{4928}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_timeout\_ns}}}\mdline{4928} configuration parameter.%mdk + +%mdk-data-line={4930} +\mdline{4930}The P4Runtime server may empty the digest message cache in case of a client +status change.%mdk + +%mdk-data-line={4933} +\mdline{4933}Here is some pseudo-code implementing the handling of digest messages in the +P4Runtime server:%mdk + +%mdk-data-line={4936} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={4937} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestStream~stream;\\ +DigestCache~cache;\\ +DigestBuffer~buffers;\\ +\\ +{\mdcolor{darkgreen}//~sends~digest~list~when~it~is~ready}\\ +send\_buffer(Id~digest\_id)~\{\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~stream.write(DigestList(buffer));\\ +~~cache.merge(buffer);~~{\mdcolor{darkgreen}//~updates~cache~with~new~digest~list}\\ +~~buffer.clear();\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~data~plane~digest~messages~from~device}\\ +handle\_dataplane\_digest(Digest~msg)~\{\\ +~~digest\_id~=~msg.digest\_id();\\ +~~buffer~=~buffers{}[digest\_id];\\ +~~{\bfseries{\mdcolor{navy}if}}~(msg~in~cache~{\mdcolor{teal}OR}~msg~in~buffer)~{\bfseries{\mdcolor{navy}return}};\\ +~~buffer.enqueue(msg);\\ +~~{\bfseries{\mdcolor{navy}if}}~(buffer.length()~\textless{}~max\_list\_size(digest\_id))~{\bfseries{\mdcolor{navy}return}};\\ +~~send\_buffer(digest\_id);\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~callback~which~handles~ack~messages~received~on~the~stream}\\ +handle\_stream\_ack(DigestListAck~ack)~\{\\ +~~{\mdcolor{darkgreen}//~clear~all~cache~entries~matching~the~tuple~(digest\_id,~list\_id)}\\ +~~cache.erase(~(ack.digest\_id(),~ack.list\_id()~)\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~loop~to~enforce~timeouts}\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~now~=~now();\\ +~~{\mdcolor{darkgreen}//~check~for~buffers~that~need~to~be~sent}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~buffer)~in~buffers)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~buffer.first\_enq\_time()~\textgreater{}=~max\_timeout\_ns(digest\_id))\\ +~~~~~~send\_buffer(buffer\_id);\\ +~~\}\\ +~~{\mdcolor{darkgreen}//~check~for~expired~entries~in~cache}\\ +~~{\bfseries{\mdcolor{navy}for}}~((digest\_id,~list\_id,~sent\_time)~in~cache)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(now~-~sent\_time~\textgreater{}=~ack\_timeout\_ns(digest\_id))\\ +~~~~~~cache.erase(~(digest\_id,~list\_id)~);\\ +~~\}\\ +~~sleep({\mdcolor{teal}X});\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4982} +\subsection{\mdline{4982}9.9.\hspace*{0.5em}\mdline{4982}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\label{sec-extern-entry}%mdk%mdk + +%mdk-data-line={4984} +\noindent\mdline{4984}This is used to support a P4 extern entity that is not part of PSA. It is +defined as:%mdk + +%mdk-data-line={4987} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={4988} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ExternEntry~\{\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_type\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}uint32}}~extern\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~google.protobuf.Any~entry~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={4995} +\noindent\mdline{4995}Each \mdline{4995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4995} entity maps to an \mdline{4995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Extern}}}\mdline{4995} message in the +\mdline{4996}\mdref{sec-p4info-extern}{P4Info}\mdline{4996} and an \mdline{4996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4996} message within that +message. The \mdline{4997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_type\_id}}}\mdline{4997} field must be equal to the one in +\mdline{4998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}\mdline{4998}. The \mdline{4998}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}extern\_id}}}\mdline{4998} field must be equal to the ID included in the +\mdline{4999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}preamble}}}\mdline{4999} of the corresponding \mdline{4999}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternInstance}}}\mdline{4999} message.%mdk + +%mdk-data-line={5001} +\mdline{5001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entry}}}\mdline{5001} itself is embedded as an \mdline{5001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5001} Protobuf message\mdline{5001}~[\mdcite{protoany}{37}]\mdline{5001} to keep the +protocol extensible. It includes the extern-specific parameters required by the +P4Runtime server to perform the read or write operation. The underlying Protobuf +message should be defined in a separate architecture-specific Protobuf file. See +section on\mdline{5005}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{5006} for more information.%mdk + +%mdk-data-line={5008} +\section{\mdline{5008}10.\hspace*{0.5em}\mdline{5008}Error Reporting Messages}\label{sec-error-reporting-messages}%mdk%mdk + +%mdk-data-line={5010} +\noindent\mdline{5010}P4Runtime is based on gRPC and all RPCs return a status to indicate success or +failure. gRPC supports multiple language bindings; we use C++ binding below to +explain how error reporting works in the failure case.%mdk + +%mdk-data-line={5014} +\mdline{5014}gRPC uses \mdline{5014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5014}~[\mdcite{grpcstatus}{38}]\mdline{5014} to represent the status returned by an +RPC. It has 3 attributes:%mdk + +%mdk-data-line={5017} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5018} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StatusCode~code\_;\\ +{\mdcolor{navy}grpc::}string~error\_message\_;\\ +{\mdcolor{navy}grpc::}string~binary\_error\_details\_;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5023} +\noindent\mdline{5023}The \mdline{5023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{5023} represents a canonical error\mdline{5023}~[\mdcite{grpcstatuscodes}{40}]\mdline{5023} and describes the +overall RPC status. The \mdline{5024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{5024} is a developer-facing error message, +which should be in English. The \mdline{5025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}binary\_error\_details\_}}}\mdline{5025} carries a serialized +\mdline{5026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{5026} message\mdline{5026}~[\mdcite{protostatus}{33}]\mdline{5026} message, which has 3 fields:%mdk + +%mdk-data-line={5028} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5029} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}int32}}~code~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};~~{\mdcolor{darkgreen}//~see~code.proto}\\ +{\bfseries{\mdcolor{navy}string}}~{\bfseries{\mdcolor{navy}message}}~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +{\bfseries{\mdcolor{navy}repeated}}~google.protobuf.Any~details~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5034} +\noindent\mdline{5034}The code and message fields must be the same as \mdline{5034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code\_}}}\mdline{5034} and \mdline{5034}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{5034} +fields from \mdline{5035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5035} above. The \mdline{5035}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5035} field is a list that consists of +\mdline{5036}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5036} messages that carry error details for individual elements inside +batch-request RPCs (\mdline{5037}e.g.\mdline{5037} \mdline{5037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5037} and \mdline{5037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5037}). \mdline{5037}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5037} includes a canonical +error code but also enables different target vendors to additionally express +their own error codes in their chosen error-space. This specification document +tries to cover all possible generic error cases and to provide the appropriate +value for the canonical error code based on best practices\mdline{5041}~[\mdcite{grpcstatuscodes}{40}]\mdline{5041}.%mdk + +%mdk-data-line={5043} +\mdline{5043}Figure\mdline{5043}~\mdref{fig-error-report}{\mdcaptionlabel{7}}\mdline{5043} illustrates how these messages fit together.%mdk + +%mdk-data-line={5045} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={5046} +\noindent\mdline{5046}\includegraphics[keepaspectratio=true,width=\dimwidth{0.70}]{build/error-report}{}\mdline{5046}%mdk + +%mdk-data-line={5047} +\mdhr{}%mdk + +%mdk-data-line={5048} +\noindent\mdline{5048}\mdcaption{\textbf{Figure~\mdcaptionlabel{7}.}~\mdcaptiontext{P4Runtime Error Report Message Format}}%mdk +%mdk +\end{mdcenter}\label{fig-error-report}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={5050} +\noindent\mdline{5050}gRPC provides utility functions \mdline{5050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExtractErrorDetails()}}}\mdline{5050} and \mdline{5050}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetErrorDetails()}}}\mdline{5050} +\mdline{5051}[\mdcite{grpcerrordetails}{39}]\mdline{5051} to easily convert between \mdline{5051}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5051} and +\mdline{5052}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status}}}\mdline{5052}.%mdk + +%mdk-data-line={5054} +\mdline{5054}Please see sections on individual P4Runtime RPCs for details on how +\mdline{5055}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5055} is populated for reporting errors.%mdk + +%mdk-data-line={5057} +\mdline{5057}Note that P4Runtime also provides a way for the server to asynchronously report +errors which occur when processing stream messages from the client. This +error-reporting mechanism is orthogonal to the one described in this section, +which applies to unary RPCs. See the section on\mdline{5060}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{5061} for more information.%mdk + +%mdk-data-line={5063} +\section{\mdline{5063}11.\hspace*{0.5em}\mdline{5063}Atomicity of Individual \mdline{5063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5063} and \mdline{5063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5063} Operations}\label{sec-atomicity-of-individual-write-and-read-operations}%mdk%mdk + +%mdk-data-line={5065} +\noindent\mdline{5065}Each individual entity in a batch is guaranteed to be read or written atomically +relative to packet forwarding. For example, for every table data plane \mdline{5066}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{5066} +operation, and every single \mdline{5067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5067} operation on a table that inserts, deletes, +or modifies one table entry, the \mdline{5068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}apply}}}\mdline{5068} operation should behave as if that +\mdline{5069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5069} operation has not yet occurred, or as if the \mdline{5069}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5069} operation is +complete. The P4 program should never behave as if the \mdline{5070}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5070} operation is +partially complete. These guarantees also apply to extern instances: \mdline{5071}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5071} and +\mdline{5072}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5072} operations on extern entities must execute atomically relative to extern +data plane methods.%mdk + +%mdk-data-line={5075} +\mdline{5075}The atomicity guarantees provided by P4Runtime for individual \mdline{5075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5075} and \mdline{5075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5075} +operations are the same as the guarantees required by PSA and are described in +details in the PSA specification\mdline{5077}~[\mdcite{psaatomicityofcontrolplaneops}{28}]\mdline{5077}.%mdk + +%mdk-data-line={5079} +\mdline{5079}The P4\mdline{5079}\mdsub{16}\mdline{5079} language introduces an \mdline{5079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{5079} annotation\mdline{5079}~[\mdcite{p4concurrency}{18}]\mdline{5079}, to +guarantee atomic data plane execution of entire blocks of P4 code. P4Runtime +implementations are required to honor the \mdline{5081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{5081} annotation for \mdline{5081}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5081} +operations, as well as\mdline{5082}~\mdref{sec-wildcard-reads}{non-wildcard \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}} operations}\mdline{5082}, +relative to data plane execution. Consider the following P4 example written for +PSA:%mdk + +%mdk-data-line={5086} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5087} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024)~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +~~~~{\mdcolor{darkgreen}//~...}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~Value\_t~v~=~r1.read((Index\_t){\mdcolor{purple}1});\\ +~~~~~~~~v~=~v~+~{\mdcolor{purple}1};\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~v);\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5103} +\noindent\mdline{5103}If a P4Runtime server is processing messages which write to Register \mdline{5103}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{5103} at +index \mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}1}}}\mdline{5104}, these writes must not happen between the data plane \mdline{5104}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}read}}}\mdline{5104} and +\mdline{5105}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}write}}}\mdline{5105}.%mdk + +%mdk-data-line={5107} +\mdline{5107}Now let\mdline{5107}'\mdline{5107}s consider the following example:%mdk + +%mdk-data-line={5109} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={5110} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}control}}~C{\mdcolor{purple}1}~\{\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}10}\textgreater{}~Index\_t;\\ +~~{\bfseries{\mdcolor{navy}typedef}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~Value\_t;\\ +~~Register\textless{}Value\_t,~Index\_t\textgreater{}({\mdcolor{purple}32}w1024,~(Value\_t){\mdcolor{purple}0}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~initial~value~}{\mdcolor{darkgreen}*/})~r1;\\ +\\ +~~{\bfseries{\mdcolor{navy}apply}}~\{\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}100});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}100});\\ +~~~~\}\\ +{\mdcolor{navy}~~~~@}{\mdcolor{navy}atomic}{\mdcolor{maroon}~\{}\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}1},~(Value\_t){\mdcolor{purple}200});\\ +~~~~~~~~r1.write((Index\_t){\mdcolor{purple}2},~(Value\_t){\mdcolor{purple}200});\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5128} +\noindent\mdline{5128}If a P4Runtime client issues a \mdline{5128}\emph{wildcard}\mdline{5128} \mdline{5128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5128} on Register \mdline{5128}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1}}}\mdline{5128}, there is no +guarantee that \mdline{5129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]~==~r1{}[2]}}}\mdline{5129} in the response, as the read for \mdline{5129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{5129} may +occur after the data plane executes the first atomic block, but before the +second atomic block, and the read for \mdline{5131}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{5131} may occur after the data plane +executes the second atomic block. In other words, the server is explicitly +allowed to read \mdline{5133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{5133} and \mdline{5133}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{5133} separately, while allowing the data plane to +perform operations on the register between those two reads. The atomicity +guarantees for a wildcard read are the same as for the equivalent batch (as one +\mdline{5136}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5136} message) of individual read requests. Similar to a batch +\mdline{5137}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5137}, a wildcard read of a register can execute the reads of the +register array elements (\mdline{5138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[1]}}}\mdline{5138}, \mdline{5138}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}r1{}[2]}}}\mdline{5138}, \mdline{5138}\dots{}\mdline{5138}) in an arbitrary order relative +to each other.%mdk + +%mdk-data-line={5141} +\mdline{5141}If the \mdline{5141}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@atomic}}}\mdline{5141} annotation cannot be honored with the above guarantees by the +P4Runtime implementation for a P4-programmable target, we expect the P4 compiler +to reject the program.%mdk + +%mdk-data-line={5145} +\section{\mdline{5145}12.\hspace*{0.5em}\mdline{5145}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5145} RPC}\label{sec-write-rpc}%mdk%mdk + +%mdk-data-line={5147} +\noindent\mdline{5147}The \mdline{5147}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5147} RPC updates one or more P4 entities on the target. The request is +defined as follows:%mdk + +%mdk-data-line={5150} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5151} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~WriteRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Update~updates~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~{\bfseries{\mdcolor{navy}enum}}~Atomicity~\{\\ +~~~~CONTINUE\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~ROLLBACK\_ON\_ERROR~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~DATAPLANE\_ATOMIC~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~\}\\ +~~Atomicity~atomicity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5165} +\noindent\mdline{5165}The \mdline{5165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5165} uniquely identifies the target P4 device. The \mdline{5165}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5165} and +\mdline{5166}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5166} define the client role and election-id as described in the +\mdline{5167}\mdref{sec-client-arbitration-and-controller-replication}{Primary-Backup Arbitration and Controller +Replication}\mdline{5168} +section. The server is expected to perform the following checks (in this order) +before processing the \mdline{5170}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}updates}}}\mdline{5170} list:%mdk + +%mdk-data-line={5172} +\begin{enumerate}%mdk + +%mdk-data-line={5172} +\item{} +%mdk-data-line={5172} +\mdline{5172}If \mdline{5172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5172} does not match any of the devices known to the P4Runtime +server or if \mdline{5173}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5173} does not match any of the roles for the device, the +server must return a \mdline{5174}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5174} error.%mdk%mdk + +%mdk-data-line={5176} +\item{} +%mdk-data-line={5176} +\mdline{5176}If the client is not the primary for (\mdline{5176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5176}, \mdline{5176}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5176}) according to +the \mdline{5177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5177} value, the server must return a \mdline{5177}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5177} error.%mdk%mdk + +%mdk-data-line={5179} +\item{} +%mdk-data-line={5179} +\mdline{5179}If the \mdline{5179}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5179} is attempted before a \mdline{5179}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5179} has been set, +the server must return a \mdline{5180}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{5180} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5182} +\noindent\mdline{5182}The updates field is a list of P4 entity updates to be applied. Each update is +defined as:%mdk + +%mdk-data-line={5185} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5186} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~Update~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Type~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~INSERT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~MODIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DELETE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~Type~type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~Entity~entity~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5198} +\noindent\mdline{5198}This is modeled as performing an update operation on the given entity against +its entity container. The entity container is either a \mdline{5199}\emph{logical}\mdline{5199} table (\mdline{5199}e.g.\mdline{5199} +\mdline{5200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{5200}) or an actual table (\mdline{5200}e.g.\mdline{5200} \mdline{5200}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5200}) in the P4 data +plane. Each entity in the container is uniquely identified by its \mdline{5201}\emph{key}\mdline{5201}. Please +refer to the\mdline{5202}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{5202} section for details on +what parts of the entity specification make up the \mdline{5203}\emph{key}\mdline{5203} for each P4 entity.%mdk + +%mdk-data-line={5205} +\mdline{5205}An update can be one of the following types:%mdk + +%mdk-data-line={5207} +\begin{itemize}%mdk + +%mdk-data-line={5207} +\item{} +%mdk-data-line={5207} +\mdline{5207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{5207}: Inserts the given P4 entity in the entity container. +The \mdline{5208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5208} field always specifies the full state of the P4 entity. +If the entity already exists, an \mdline{5209}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALREADY\_EXISTS}}}\mdline{5209} error is returned, and +the existing entity remains unchanged. If the entity is malformed, an +\mdline{5211}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5211} error is usually returned (unless a more specific error +code applies\mdline{5212}~[\mdcite{grpcstatuscodes}{40}]\mdline{5212}). If the entity cannot be inserted because the +container is already full, a \mdline{5213}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{5213} error is returned.%mdk%mdk + +%mdk-data-line={5215} +\item{} +%mdk-data-line={5215} +\mdline{5215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MODIFY}}}\mdline{5215}: Modifies the P4 entity to its new specified state. This uses +\mdline{5216}\emph{assign}\mdline{5216} or \mdline{5216}\emph{full-snapshot}\mdline{5216} semantics, \mdline{5216}i.e.\mdline{5216} the entity field contains the +complete new state of the entity, not a diff from its previous state. If the +entity is malformed, an \mdline{5218}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5218} error is usually returned (unless a +more specific error code applies\mdline{5219}~[\mdcite{grpcstatuscodes}{40}]\mdline{5219}). If the entity does not +exist, a \mdline{5220}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5220} error is returned.%mdk%mdk + +%mdk-data-line={5222} +\item{} +%mdk-data-line={5222} +\mdline{5222}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{5222}: Deletes the specified P4 entity. If the entity does not exist, a +\mdline{5223}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5223} error is returned. In order to delete, the entity specification +only needs to include the key. Any non-key parts of entity are ignored.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5226} +\noindent\mdline{5226}If an update is not allowed under the given controller role, the server must +return a \mdline{5227}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5227} error for this update.%mdk + +%mdk-data-line={5229} +\subsection{\mdline{5229}12.1.\hspace*{0.5em}\mdline{5229}Batching and Ordering of Updates}\label{sec-batching-and-ordering-of-updates}%mdk%mdk + +%mdk-data-line={5231} +\noindent\mdline{5231}P4Runtime supports batching of \mdline{5231}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5231} operations. The list of updates in a +\mdline{5232}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5232} is referred to as a \mdline{5232}\emph{batch}\mdline{5232}. A batch can consist of arbitrary +updates on an arbitrary set of P4 entities. It is not restricted to a particular +entity or table (in the case of \mdline{5234}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5234} entities).%mdk + +%mdk-data-line={5236} +\mdline{5236}The P4Runtime server may choose to reorder updates in a batch when processing +them, and/or process updates in parallel. Updates across multiple concurrent +\mdline{5238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5238}s can also be processed interleaved and/or in parallel. +However, \mdline{5239}\textbf{the processing of requests must be strictly serializable}\mdline{5239}. That +is, given a history \mdline{5240}$S$\mdline{5240} of \mdline{5240}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5240}s including the responses to those +requests, there must exist an order \mdline{5241}$L$\mdline{5241} for all updates in \mdline{5241}$S$\mdline{5241}, such that:%mdk + +%mdk-data-line={5243} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5243} +\item\mdline{5243}All updates from the same write request must appear as a contiguous +subsequence in \mdline{5244}$L$\mdline{5244}, but the order within that subsequence can be arbitrary.%mdk + +%mdk-data-line={5245} +\item\mdline{5245}For two updates \mdline{5245}$u_1$\mdline{5245} and \mdline{5245}$u_2$\mdline{5245}, if the write request containing \mdline{5245}$u_1$\mdline{5245} +completed before the write request of \mdline{5246}$u_2$\mdline{5246} was sent, then \mdline{5246}$u_1$\mdline{5246} must appear +before \mdline{5247}$u_2$\mdline{5247} in \mdline{5247}$L$\mdline{5247}.%mdk + +%mdk-data-line={5248} +\item\mdline{5248}Executing all updates in \mdline{5248}$L$\mdline{5248} sequentially must yield the same response for +every update as in \mdline{5249}$S$\mdline{5249}.%mdk + +%mdk-data-line={5250} +\item\mdline{5250}The observable state of the switch after \mdline{5250}$S$\mdline{5250} (\mdline{5250}e.g.\mdline{5250}, through the \mdline{5250}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5250} RPC) +is identical to the one obtained by sequentially executing \mdline{5251}$L$\mdline{5251}.%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5253} +\noindent\mdline{5253}The \mdline{5253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5253} RPC demarcates the batch boundary, and can be used to ensure +ordering between dependent updates. When the \mdline{5254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5254} RPC returns, it is required +that all operations in the batch have been committed to the P4 data plane, with +the exception of any operations that return an error status. If two updates +from the client depend on each other (\mdline{5257}e.g.\mdline{5257} inserting an \mdline{5257}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfileMember}}}\mdline{5257} +followed by pointing a \mdline{5258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5258} to it) and the updates are not split into +separate batches, then the behavior may be non-deterministic. Similarly, +clients can invoke multiple outstanding \mdline{5260}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5260} RPCs. If the updates across +these RPCs have dependencies, the observed behavior may be non-deterministic, as +the server can process these RPCs in any arbitrary order, providing strict +serializability is enforced. For this reason, most clients are advised to split +dependent updates across separate \mdline{5264}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5264} calls. Additionally, if the client +wants to enforce that batches are applied in a specific order, each \mdline{5265}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5265} call +should be sent sequentially, waiting for the previous call to be acknowledged +before sending the next one.%mdk + +%mdk-data-line={5270} +\subsection{\mdline{5270}12.2.\hspace*{0.5em}\mdline{5270}Batch Atomicity}\label{sec-batch-atomicity}%mdk%mdk + +%mdk-data-line={5272} +\noindent\mdline{5272}A P4Runtime server may arbitrarily reorder messages within a batch. The +atomicity semantics of the batch operations are defined by the \mdline{5273}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{5273} +enum. A P4Runtime server is required to support only the modes marked as +\mdline{5275}\emph{Required}\mdline{5275} below:%mdk + +%mdk-data-line={5277} +\begin{itemize}%mdk + +%mdk-data-line={5277} +\item{} +%mdk-data-line={5277} +\mdline{5277}\emph{Required}\mdline{5277}: \mdline{5277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{5277}: This is the default behavior and the default +enum value. Each operation within the batch must be attempted even if one or +more encounter errors. Every data plane packet is guaranteed to be processed +according to table contents as they are between two individual operations of +the batch, but there could be several packets processed that \mdline{5281}\emph{see}\mdline{5281} each of +these intermediate stages.%mdk%mdk + +%mdk-data-line={5284} +\item{} +%mdk-data-line={5284} +\mdline{5284}\emph{Optional}\mdline{5284}: \mdline{5284}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ROLLBACK\_ON\_ERROR}}}\mdline{5284}: Operations within the batch are attempted in +an arbitrary order (each committed to data plane) until the target detects an +error. At this point, the target must roll back the operations such that both +software and data plane state is consistent with the state before the batch +was attempted. The resulting behavior is \mdline{5288}\emph{all-or-none}\mdline{5288}, except the batch is +not atomic from a data plane point of view. Every data plane packet is +guaranteed to be processed according to table contents as they are between two +individual operations of the batch, but there could be several packets +processed that \mdline{5292}\emph{see}\mdline{5292} each of these intermediate stages. The details and design +of the rollback mechanism are outside the scope of this specification. One +possibility is to create a shadow copy of both the software and hardware state +at the start, and restore it upon failure.%mdk + +%mdk-data-line={5297} +\mdline{5297}If a P4Runtime server does not support this option at all, an +\mdline{5298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5298} error is returned at all times. If a P4Runtime +supports some batches in an rollback way but not others (\mdline{5299}e.g.\mdline{5299} it is +more straightforward to implement batches that contain only \mdline{5300}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{5300} +operations, vs. those that contain \mdline{5301}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DELETE}}}\mdline{5301} operations), an +\mdline{5302}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5302} error is returned when the batch cannot be executed +in a data plane-atomic way.%mdk%mdk + +%mdk-data-line={5305} +\item{} +%mdk-data-line={5305} +\mdline{5305}\emph{Optional}\mdline{5305}: \mdline{5305}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{5305}: This is the strictest requirement where the +entire batch must be atomic from a data plane point of view. Every data plane +packet is guaranteed to be processed according to table contents before the +batch began, or after the batch completes. The batch is therefore treated as a +\mdline{5309}\emph{transaction}\mdline{5309}. The details and design of how to achieve data plane-atomicity +is outside the scope of this specification. One possibility is to limit the +target to half of the data plane\mdline{5311}'\mdline{5311}s table capacity at all times. At the start +of the batch processing, the remaining half of the table capacity can be +initialized with the current table state and used as a working area to commit +all operations within the batch. At the end (if there were no errors), a +simple pointer-swap like approach can be used to switch to this half of the +table.%mdk + +%mdk-data-line={5318} +\mdline{5318}If a P4Runtime server does not support this option at all, an \mdline{5318}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5318} +error is returned at all times. If a P4Runtime supports some batches in an +atomic way but not others, an \mdline{5320}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5320} error is returned when the batch +cannot be executed in a data plane-atomic way.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5323} +\noindent\mdline{5323}There is no expectation that a given client must always use the same \mdline{5323}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Atomicity}}}\mdline{5323} +enum value. At any given time, the client is free to compose batches and assign +atomicity mode as it sees fit. For example, for a set of entities, a client may +decide to use \mdline{5326}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DATAPLANE\_ATOMIC}}}\mdline{5326} at one time and default behavior +(\mdline{5327}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CONTINUE\_ON\_ERROR}}}\mdline{5327}) at other times.%mdk + +%mdk-data-line={5329} +\subsection{\mdline{5329}12.3.\hspace*{0.5em}\mdline{5329}Error Reporting}\label{sec-error-reporting}%mdk%mdk + +%mdk-data-line={5331} +\noindent\mdline{5331}Please see section\mdline{5331}~\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{5331} for +information on error reporting messages and guidelines. P4Runtime server will +populate \mdline{5333}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5333} as follows:%mdk + +%mdk-data-line={5335} +\begin{enumerate}%mdk + +%mdk-data-line={5335} +\item{} +%mdk-data-line={5335} +\mdline{5335}If all batch updates succeeded, set \mdline{5335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{5335} to \mdline{5335}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{5335} and do not +populate any other field.%mdk%mdk + +%mdk-data-line={5338} +\item{} +%mdk-data-line={5338} +\mdline{5338}If an error is encountered before even trying to attempt individual batch +updates, set \mdline{5339}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{5339} that best describes that RPC-wide +error. For example, use \mdline{5340}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNAVAILABLE}}}\mdline{5340} if the P4Runtime service is not yet +ready to handle requests. Set \mdline{5341}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_message\_}}}\mdline{5341} to describe the issue. Do not +set \mdline{5342}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error\_details}}}\mdline{5342} in this case.%mdk%mdk + +%mdk-data-line={5344} +\item{} +%mdk-data-line={5344} +\mdline{5344}Otherwise, if one or more updates in the batch (\mdline{5344}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest.updates}}}\mdline{5344}) +failed, set \mdline{5345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status::code\_}}}\mdline{5345} to \mdline{5345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{5345}. For example, one update in +the batch may fail with \mdline{5346}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{5346} and another with +\mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5347}. A \mdline{5347}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5347} message is used to capture the status of +each and every update in the batch. The number of \mdline{5348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5348} messages packed +into \mdline{5349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{5349} field should therefore always match the +number of updates in the \mdline{5350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5350}, and the order of +\mdline{5351}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5351} messages must be in the same order as the corresponding +updates. If some of the updates were successful, the corresponding +\mdline{5353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5353} should set the code to \mdline{5353}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{5353} and omit other fields.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5355} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5356} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}\#~Example~of~a~grpc::Status~returned~for~a~Write~RPC~with~a~batch~of~3~updates.}\\ +{\mdcolor{darkgreen}\#~The~first~and~third~updates~encountered~an~error,~while~the~second~update}\\ +{\mdcolor{darkgreen}\#~succeeded.}\\ +code\_~=~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +error\_message\_~=~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +binary\_error\_details~\{\\ +~~code:~{\mdcolor{purple}2}~~{\mdcolor{darkgreen}\#~UNKNOWN}\\ +~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Write~failure.}{\mdcolor{maroon}"}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}8}~~{\mdcolor{darkgreen}\#~RESOURCE\_EXHAUSTED}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Table~is~full.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}500}~~{\mdcolor{darkgreen}\#~ERR\_TABLE\_FULL}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}0}~~{\mdcolor{darkgreen}\#~OK}\\ +~~\}\\ +~~details~\{\\ +~~~~canonical\_code:~{\mdcolor{purple}6}~~{\mdcolor{darkgreen}\#~ALREADY\_EXISTS}\\ +~~~~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Entity~already~exists.}{\mdcolor{maroon}"}\\ +~~~~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendorY}{\mdcolor{maroon}"}\\ +~~~~code:~{\mdcolor{purple}600}~~{\mdcolor{darkgreen}\#~ERR\_ENTITY\_ALREADY\_EXISTS}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5382} +\section{\mdline{5382}13.\hspace*{0.5em}\mdline{5382}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5382} RPC}\label{sec-read-rpc}%mdk%mdk + +%mdk-data-line={5384} +\noindent\mdline{5384}The \mdline{5384}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5384} RPC retrieves one or more P4 entities from the P4Runtime server. The +request is defined as:%mdk + +%mdk-data-line={5387} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5388} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadRequest~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5395} +\noindent\mdline{5395}The \mdline{5395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5395} uniquely identifies the target P4 device. If it does not match +any of the devices known to the P4Runtime server, the server must return a +\mdline{5397}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5397} error. +If the \mdline{5398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5398} is attempted before \mdline{5398}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5398} has been set, the +server must return a \mdline{5399}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FAILED\_PRECONDITION}}}\mdline{5399} error. +The \mdline{5400}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5400} field acts as a filter, restricting the reported entities based on +the role to which the entity belongs. +The \mdline{5402}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{5402} repeated field is a list of P4 entities, each +acting as a query filter to be applied to P4 entity containers on the server.%mdk + +%mdk-data-line={5405} +\mdline{5405}Since \mdline{5405}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5405}s do not mutate any state on the switch, they do not +require an \mdline{5406}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5406}, and they do not require the presence of an open +\mdline{5407}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5407} between the server and client.%mdk + +%mdk-data-line={5409} +\mdline{5409}The \mdline{5409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read~}}}\mdline{5409}response consists of a sequence of messages (a gRPC \mdline{5409}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}stream}}}\mdline{5409}) with +each message defined as:%mdk + +%mdk-data-line={5412} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5413} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~ReadResponse~\{\\ +~~{\bfseries{\mdcolor{navy}repeated}}~Entity~entities~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5418} +\noindent\mdline{5418}The \mdline{5418}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entities}}}\mdline{5418} repeated field is a list of P4 entities retrieved. The client +reads from the returned stream until it is closed by the server when there are +no more messages. In case of error, the stream is closed prematurely by the +server and the client obtains the error status (in C++ the error status is +obtained by calling the \mdline{5422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Finish()}}}\mdline{5422} method on the stream object +\mdline{5423}[\mdcite{grpcstreamc}{12}]\mdline{5423}).%mdk + +%mdk-data-line={5425} +\subsection{\mdline{5425}13.1.\hspace*{0.5em}\mdline{5425}Nomenclature}\label{sec-nomenclature}%mdk%mdk + +%mdk-data-line={5427} +\begin{mddefinitions}%mdk + +\mddefterm{\noindent{\bfseries request}}%mdk + +%mdk-data-line={5427} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{5427}An element of the \mdline{5427}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{5427} repeated field. +%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk + +\mddefterm{\noindent{\bfseries batch}}%mdk + +%mdk-data-line={5429} +\begin{mdbmarginx}{}{}{}{1.5em}%mdk +\begin{mddefdata}%mdk +\mdline{5429}Refers to the \mdline{5429}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.ReadRequest.entities}}}\mdline{5429} repeated field.%mdk +\end{mddefdata}%mdk +\end{mdbmarginx}%mdk +%mdk +\end{mddefinitions}%mdk + +%mdk-data-line={5432} +\noindent\mdline{5432}Each \mdline{5432}\emph{request}\mdline{5432} acts as a query filter for that entity type. If a \mdline{5432}\emph{request}\mdline{5432} fully +specifies the entity key, the \mdline{5433}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5433} operation should retrieve a single P4 +entity. Please refer to the\mdline{5434}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{5434} section +for details on what parts of the entity specification make up the entity \mdline{5435}\emph{key}\mdline{5435}.%mdk + +%mdk-data-line={5437} +\subsection{\mdline{5437}13.2.\hspace*{0.5em}\mdline{5437}Wildcard Reads}\label{sec-wildcard-reads}%mdk%mdk + +%mdk-data-line={5439} +\noindent\mdline{5439}P4Runtime allows wildcard read of P4 entities. A \mdline{5439}\emph{request}\mdline{5439} may omit or use +default values for parts of the entity key to achieve wildcard behavior. Please +refer to the\mdline{5441}~\mdref{sec-p4-entity-msgs}{P4 Entity Messages}\mdline{5441} section for details on +what parts of the entity can be wildcarded in a given \mdline{5442}\emph{request}\mdline{5442}.%mdk + +%mdk-data-line={5444} +\mdline{5444}For example, in a \mdline{5444}\emph{request}\mdline{5444} of type \mdline{5444}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CounterEntry}}}\mdline{5444}:%mdk + +%mdk-data-line={5446} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5446} +\item\mdline{5446}A default \mdline{5446}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{5446} (0) implies a request to read all counter-entries for +all indirect counters.%mdk + +%mdk-data-line={5448} +\item\mdline{5448}A particular (non-default) \mdline{5448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter\_id}}}\mdline{5448} in conjunction with \mdline{5448}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index}}}\mdline{5448} unset +implies a request to read all counter-entries for the given indirect counter +ID.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5452} +\noindent\mdline{5452}To read the entire forwarding state for a given device, the P4Runtime client can +generate the following \mdline{5453}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5453}:%mdk + +%mdk-data-line={5455} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5456} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id:~\textless{}ID\textgreater{}\\ +entities~\{\\ +~~extern\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~extern~instances~for~all~supported~extern~types}\\ +~~table\_entry~\{~\}~~{\mdcolor{darkgreen}\#~read~all~table~entries~for~all~tables}\\ +~~action\_profile\_member~\{~\}~~{\mdcolor{darkgreen}\#~read~all~members~for~all~action~profiles}\\ +~~action\_profile\_group~\{~\}~~{\mdcolor{darkgreen}\#~read~all~groups~for~all~action~profiles}\\ +~~...\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5466} +\noindent\mdline{5466}The \mdline{5466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5466} oneof field in the \mdline{5466}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5466} message must always be set, or the +server must return an \mdline{5467}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5467} error. In other words, P4Runtime does +not support performing a wildcard read on the entire forwarding state by +including an empty \mdline{5469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Entity}}}\mdline{5469} message in the \mdline{5469}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5469}. The main reason for +this decision is to prevent backwards-compatibility issues if new entity types +are added to the \mdline{5471}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{5471} oneof\mdline{5471}~[\mdcite{protooneofbackwardscompatibility}{25}]\mdline{5471}.%mdk + +%mdk-data-line={5473} +\subsection{\mdline{5473}13.3.\hspace*{0.5em}\mdline{5473}Batch Processing}\label{sec-batch-processing}%mdk%mdk + +%mdk-data-line={5475} +\noindent\mdline{5475}A P4Runtime server may arbitrarily reorder requests within a batch to maximize +performance. There is no requirement that a particular entity type \mdline{5476}\emph{request}\mdline{5476} +appears only once in the batch.%mdk + +%mdk-data-line={5479} +\mdline{5479}A P4Runtime server will process the batch as follows:%mdk + +%mdk-data-line={5481} +\begin{enumerate}%mdk + +%mdk-data-line={5481} +\item{} +%mdk-data-line={5481} +\mdline{5481}Lock state (preventing new writes) and validate each \mdline{5481}\emph{request}\mdline{5481} in the batch:%mdk + +%mdk-data-line={5483} +\begin{enumerate}%mdk + +%mdk-data-line={5483} +\item{} +%mdk-data-line={5483} +\mdline{5483}If it is a valid \mdline{5483}\emph{request}\mdline{5483}, perform the read;%mdk + +%mdk-data-line={5485} +\begin{enumerate}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5485} +\item\mdline{5485}If the read was successful, return the entities read in +\mdline{5486}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5486} stream.%mdk + +%mdk-data-line={5487} +\item\mdline{5487}If the read failed (exception / critical-error), prepare a \mdline{5487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5487} +with code set to \mdline{5488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INTERNAL}}}\mdline{5488}.%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5490} +\item{} +%mdk-data-line={5490} +\mdline{5490}If the \mdline{5490}\emph{request}\mdline{5490} is invalid (invalid-argument, not-supported, etc.), +prepare a \mdline{5491}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5491} with relevant canonical code to capture the error.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk + +%mdk-data-line={5493} +\item{} +%mdk-data-line={5493} +\mdline{5493}Unlock the state (allowing new writes);%mdk%mdk + +%mdk-data-line={5495} +\item{} +%mdk-data-line={5495} +\mdline{5495}Close the \mdline{5495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5495} stream and return a \mdline{5495}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc::Status}}}\mdline{5495} as follows:%mdk + +%mdk-data-line={5497} +\begin{enumerate}%mdk + +%mdk-data-line={5497} +\item{} +%mdk-data-line={5497} +\mdline{5497}If no errors were encountered, set code to \mdline{5497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OK}}}\mdline{5497} and do not populate any +other field.%mdk%mdk + +%mdk-data-line={5500} +\item{} +%mdk-data-line={5500} +\mdline{5500}Otherwise, the overall code should be set to \mdline{5500}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNKNOWN}}}\mdline{5500}. See section +\mdline{5501}\mdref{sec-error-reporting-messages}{Error Reporting Messages}\mdline{5501} for information +on error reporting messages and guidelines. Assemble a list of \mdline{5502}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{5502} +messages (from step 1 above) such that each element reflects the status +of the request in the batch at the same location (1:1 +correspondence). This list should be packed into +\mdline{5506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}google.rpc.Status.details}}}\mdline{5506} field. This behavior also matches \mdline{5506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5506} +RPC.%mdk%mdk +%mdk +\end{enumerate}%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5509} +\subsubsection{\mdline{5509}13.3.1.\hspace*{0.5em}\mdline{5509}Example}\label{sec-example}%mdk%mdk + +%mdk-data-line={5511} +\noindent\mdline{5511}If a client asked to read \mdline{5511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{a,b,c,d\}}}}\mdline{5511} and \mdline{5511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}b}}}\mdline{5511} and \mdline{5511}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}d}}}\mdline{5511} \mdline{5511}\emph{requests}\mdline{5511} didn\mdline{5511}'\mdline{5511}t +validate, the server will return entities corresponding to \mdline{5512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{5512} and \mdline{5512}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}c}}}\mdline{5512}, followed +by a status \mdline{5513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}\{p4.Error(OK),~p4.Error(xxx),~p4.Error(yyy),~p4.Error(OK)\}}}}\mdline{5513} in the +\mdline{5514}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5514} field.%mdk + +%mdk-data-line={5516} +\mdline{5516}The P4Runtime server is not required to perform any optimization (\mdline{5516}e.g.\mdline{5516} merge two +\mdline{5517}\emph{requests}\mdline{5517} in the \mdline{5517}\emph{batch}\mdline{5517} if one is a subset of other). As a result of this, it +is possible for the \mdline{5518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5518} to contain the same entity more than once. If +performance is a concern, the P4Runtime client should handle this merging.%mdk + +%mdk-data-line={5521} +\mdline{5521}There is no requirement that each request in the batch will correspond to one +\mdline{5522}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadResponse}}}\mdline{5522} message in the stream. The stream-based design for response +message is to avoid memory pressure on the P4Runtime server when the Read +results in a very large number of entities to be returned. The P4Runtime server +is free to break them apart across multiple response messages as it sees fit.%mdk + +%mdk-data-line={5527} +\mdline{5527}A P4Runtime server must be prepared to handle multiple concurrent \mdline{5527}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5527} RPCs. +This could be from the same or multiple clients. P4Runtime is based on gRPC +which provides a concurrent server design. A server implementation that supports +concurrent RPC handlers may choose to maximize performance by using a +multi-reader lock (also known as multiple-readers/single-writer lock). +Conversely (\mdline{5532}e.g.\mdline{5532} in a single-threaded architecture), it may choose to serialize +\mdline{5533}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5533} RPC processing.%mdk + +%mdk-data-line={5535} +\subsection{\mdline{5535}13.4.\hspace*{0.5em}\mdline{5535}Parallelism of Read and Write Requests}\label{sec-parallelism-of-read-and-write-requests}%mdk%mdk + +%mdk-data-line={5537} +\noindent\mdline{5537}A P4Runtime server may be implemented to serve at most one +\mdline{5538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5538} or \mdline{5538}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5538} message at a time, sequentially. It +may also serve multiple requests in parallel, and it is expected that +some client software would be easier to implement with good +performance characteristics if a server did so.%mdk + +%mdk-data-line={5543} +\mdline{5543}For example, imagine a client that wanted to use \mdline{5543}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5543} +messages with large batches of insert, modify, and/or delete +operations on an IP route table, in order to achieve higher throughput +of updates to this table. Such a client might also wish to send +\mdline{5547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5547} messages with only a few updates to an \mdline{5547}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionSelector}}}\mdline{5547} +object that controlled which links were in which LAGs, and have those +small requests start processing even if there is a large +\mdline{5550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5550} batch currently being processed, but it will not +complete for a significant amount of time.%mdk + +%mdk-data-line={5553} +\mdline{5553}The restrictions on which a client may rely are:%mdk + +%mdk-data-line={5555} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5555} +\item\mdline{5555}The processing of any two \mdline{5555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5555} messages \mdline{5555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W1}}}\mdline{5555} and \mdline{5555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W2}}}\mdline{5555} must +result in the same state as if one of them was completed before the +other began.%mdk + +%mdk-data-line={5558} +\item\mdline{5558}For any \mdline{5558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5558} \mdline{5558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5558} and any \mdline{5558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5558} \mdline{5558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5558}, \mdline{5558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}R}}}\mdline{5558} must +return results consistent with a state where \mdline{5559}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5559} has completed +processing, or \mdline{5560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}W}}}\mdline{5560} has not yet begun processing.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5562} +\noindent\mdline{5562}For example, if a P4Runtime server maintained, independently for each +device it managed, a separate multi-reader single-writer lock for each +stateful object in the P4 program, and before starting the processing +of a \mdline{5565}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5565} message it acquired a write lock for each stateful +object affected by the \mdline{5566}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5566}, and before starting the +processing of a \mdline{5567}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5567} message it acquired a read lock for each +stateful object accessed by the \mdline{5568}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{5568}, such an implementation +meets all of the requirements above.%mdk + +%mdk-data-line={5571} +\mdline{5571}It is possible to meet the requirements of this specification and +perform even more requests in parallel than that example +implementation allows, \mdline{5573}e.g.\mdline{5573} if the server somehow determined that two +\mdline{5574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{5574} messages that inserted entries to the same table could +not affect the results of the other, they could also be performed in +parallel. It is not required that a P4Runtime server do this, and may +be difficult to implement correctly.%mdk + +%mdk-data-line={5580} +\section{\mdline{5580}14.\hspace*{0.5em}\mdline{5580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5580} RPC}\label{sec-setforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5582} +\noindent\mdline{5582}A P4Runtime client may configure the P4Runtime target with a new P4 pipeline by +invoking the \mdline{5583}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig~RPC}}}\mdline{5583}. The request is defined as:%mdk + +%mdk-data-line={5585} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5586} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~SetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Action~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~VERIFY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~VERIFY\_AND\_SAVE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~VERIFY\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~~~COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~~~RECONCILE\_AND\_COMMIT~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}string}}~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}6};\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~Action~action~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}5};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5603} +\noindent\mdline{5603}The server is expected to perform the following checks (in this order) +before performing the required \mdline{5604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action}}}\mdline{5604}:%mdk + +%mdk-data-line={5606} +\begin{enumerate}%mdk + +%mdk-data-line={5606} +\item{} +%mdk-data-line={5606} +\mdline{5606}If \mdline{5606}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5606} does not match any of the devices known to the P4Runtime +server or if \mdline{5607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5607} does not match any of the roles for the device, the +server must return a \mdline{5608}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5608} error.%mdk%mdk + +%mdk-data-line={5610} +\item{} +%mdk-data-line={5610} +\mdline{5610}If the client is not the primary for (\mdline{5610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5610}, \mdline{5610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5610}) according to +the \mdline{5611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5611} value, the server must return a \mdline{5611}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{5611} error.%mdk%mdk +%mdk +\end{enumerate}%mdk + +%mdk-data-line={5613} +\noindent\mdline{5613}The action is the type of configuration action requested, it can be one of:%mdk + +%mdk-data-line={5615} +\begin{itemize}%mdk + +%mdk-data-line={5615} +\item{} +%mdk-data-line={5615} +\mdline{5615}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY}}}\mdline{5615}: verifies that the target can realize the given config. The +forwarding state in the target is not modified. Returns an \mdline{5616}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5616} +error if config is not provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5619} +\item{} +%mdk-data-line={5619} +\mdline{5619}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5619}: saves the config if the P4Runtime target can realize +it. The forwarding state in the target is not modified. However, any +subsequent \mdline{5621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{5621} / \mdline{5621}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5621} requests must refer to fields in the new +config. Returns an \mdline{5622}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5622} error if the forwarding config is not +provided or if the provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5625} +\item{} +%mdk-data-line={5625} +\mdline{5625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_COMMIT}}}\mdline{5625}: saves and realizes the given config if the P4Runtime +target can realize it. The forwarding state in the target is cleared. Returns +an \mdline{5627}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5627} error if the forwarding config is not provided or if the +provided config cannot be realized.%mdk%mdk + +%mdk-data-line={5630} +\item{} +%mdk-data-line={5630} +\mdline{5630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COMMIT}}}\mdline{5630}: realizes the last saved, but not yet committed, config. The +forwarding state in the target is updated by replaying the write requests to +the target device since the last config was saved. Config should not be +provided for this action type. Returns a \mdline{5633}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5633} error if no saved config +is found, \mdline{5634}i.e.\mdline{5634} if no \mdline{5634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}VERIFY\_AND\_SAVE}}}\mdline{5634} action preceded this one. Returns an +\mdline{5635}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5635} error if a config is provided with this message.%mdk%mdk + +%mdk-data-line={5637} +\item{} +%mdk-data-line={5637} +\mdline{5637}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RECONCILE\_AND\_COMMIT}}}\mdline{5637}: verifies, saves and realizes the given config, while +preserving the forwarding state in the target. This is an advanced use case to +enable changes to the P4 forwarding pipeline configuration with minimal +traffic loss. P4Runtime does not impose any constraints on the duration of the +traffic loss. The support for this option is not expected to be uniform across +all P4Runtime targets. A target that does not support this option may return +an \mdline{5643}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5643} error. For targets that support this option, an +\mdline{5644}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{5644} error is returned if no config is provided, or if the +existing forwarding state cannot be preserved for the given config by the +target.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5648} +\noindent\mdline{5648}The \mdline{5648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5648} field is a message of type \mdline{5648}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5648} that carries +the P4Info, the opaque target-dependent forwarding-pipeline configuration data +(\mdline{5650}e.g.\mdline{5650} generated by the P4 compiler for the target), and, optionally, the cookie +to uniquely identify such configuration. See the\mdline{5651}~\mdref{sec-p4-fwd-pipe-config}{Forwarding-Pipeline +Configuration}\mdline{5652} section for details.%mdk + +%mdk-data-line={5654} +\mdline{5654}A P4Runtime server running on a non-programmable device may not +support \mdline{5655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5655} (\mdline{5655}e.g.\mdline{5655} the forwarding-pipeline +config is part of the device\mdline{5656}'\mdline{5656}s software image, or is supplied using a +different mechanism). In such cases, the RPC should return an +\mdline{5658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{5658} error.%mdk + +%mdk-data-line={5660} +\section{\mdline{5660}15.\hspace*{0.5em}\mdline{5660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5660} RPC}\label{sec-getforwardingpipelineconfig-rpc}%mdk%mdk + +%mdk-data-line={5662} +\noindent\mdline{5662}The forwarding-pipeline configuration of the target can be retrieved by invoking +the \mdline{5663}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig~RPC}}}\mdline{5663}. The request is defined as:%mdk + +%mdk-data-line={5665} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5666} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigRequest~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~ResponseType~\{\\ +~~~~ALL~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~COOKIE\_ONLY~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~~~P{\mdcolor{purple}4}INFO\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~~~DEVICE\_CONFIG\_AND\_COOKIE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~\}\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~ResponseType~response\_type~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5678} +\noindent\mdline{5678}The \mdline{5678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5678} uniquely identifies the target P4 device. A \mdline{5678}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}NOT\_FOUND}}}\mdline{5678} error is +returned if the \mdline{5679}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5679} is not recognized by the P4Runtime server.%mdk + +%mdk-data-line={5681} +\mdline{5681}The \mdline{5681}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5681} is used to specify which fields to populate in the response, +its value can be one of:%mdk + +%mdk-data-line={5684} +\begin{itemize}%mdk + +%mdk-data-line={5684} +\item{} +%mdk-data-line={5684} +\mdline{5684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5684}: returns a \mdline{5684}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5684} with all fields +set as stored by the target. This is the default behaviour if the +\mdline{5686}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5686} field is not set.%mdk%mdk + +%mdk-data-line={5688} +\item{} +%mdk-data-line={5688} +\mdline{5688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}COOKIE\_ONLY}}}\mdline{5688}: reply by setting only the \mdline{5688}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5688} field in the +\mdline{5689}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5689}, omitting all other fields. This mechanisms can be +used by a controller to verify that a config is the expected one, while +minimizing the amount of data in the response message.%mdk%mdk + +%mdk-data-line={5693} +\item{} +%mdk-data-line={5693} +\mdline{5693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4INFO\_AND\_COOKIE}}}\mdline{5693}: reply by setting the \mdline{5693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4info}}}\mdline{5693} and \mdline{5693}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5693} fields.%mdk%mdk + +%mdk-data-line={5695} +\item{} +%mdk-data-line={5695} +\mdline{5695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DEVICE\_CONFIG\_AND\_COOKIE}}}\mdline{5695}: reply by setting the \mdline{5695}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5695} and +\mdline{5696}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}cookie}}}\mdline{5696} fields.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5698} +\noindent\mdline{5698}The response contains the \mdline{5698}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{5698} for the specified device:%mdk + +%mdk-data-line={5700} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5701} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~GetForwardingPipelineConfigResponse~\{\\ +~~ForwardingPipelineConfig~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5706} +\noindent\mdline{5706}If a P4Runtime server is in a state where the forwarding-pipeline config is not +known, the top-level \mdline{5707}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config}}}\mdline{5707} field will be unset in the response. Examples are +(i) a server that only allows configuration via \mdline{5708}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5708} +but this RPC hasn\mdline{5709}'\mdline{5709}t been invoked yet, (ii) a server that is configured using a +different mechanism but this configuration hasn\mdline{5710}'\mdline{5710}t yet occurred.%mdk + +%mdk-data-line={5712} +\mdline{5712}Once a forwarding-pipeline config is installed on the device (either via +\mdline{5713}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5713} or a different mechanism), some P4Runtime servers +may not support retrieval of the target-dependent config, in which case +\mdline{5715}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.p4\_device\_config}}}\mdline{5715} will be empty / unset in the response, even if +\mdline{5716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}response\_type}}}\mdline{5716} in the request was set to \mdline{5716}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ALL}}}\mdline{5716}. However, all P4Runtime servers +are required to return the P4Info in this scenario. Similarly, if a cookie was +present in the \mdline{5718}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5718} RPC, the same should be returned +when reading the config. If the config is installed with a mechanism other than +\mdline{5720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5720}, the value of \mdline{5720}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}config.cookie}}}\mdline{5720} will be unset.%mdk + +%mdk-data-line={5722} +\mdline{5722}If a P4Runtime server supports both \mdline{5722}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5722} as well as +returning the \mdline{5723}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{5723}, there should be read-write symmetry between +\mdline{5724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{5724} and \mdline{5724}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}GetForwardingPipelineConfig}}}\mdline{5724} RPCs.%mdk + +%mdk-data-line={5726} +\section{\mdline{5726}16.\hspace*{0.5em}\mdline{5726}P4Runtime Stream Messages}\label{sec-p4runtime-stream-messages}%mdk%mdk + +%mdk-data-line={5728} +\subsection{\mdline{5728}16.1.\hspace*{0.5em}\mdline{5728}Packet I/O}\label{sec-packet-i_o}%mdk%mdk + +%mdk-data-line={5730} +\noindent\mdline{5730}P4Runtime supports controller packet-in and packet-out by means of \mdline{5730}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5730} +and \mdline{5731}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5731} stream messages, respectively.%mdk + +%mdk-data-line={5733} +\mdline{5733}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5733} messages are sent by the P4Runtime server to the client. Conversely, +\mdline{5734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5734} messages are sent by the client to the server. Any \mdline{5734}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5734} +message received by the server from a client which is not allowed to send such +messages based on its current role definition must be dropped. The server may +also generate a \mdline{5737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5737} message with the \mdline{5737}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5737} field set to +report the error to the client. See the section on\mdline{5738}~\mdref{sec-stream-error-reporting}{Stream Error +Reporting}\mdline{5739} for more information on \mdline{5739}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5739}.%mdk + +%mdk-data-line={5741} +\mdline{5741}As introduced in the\mdline{5741}~\mdref{sec-controller-packet-meta}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}}\mdline{5741} +section, such messages can carry arbitrary metadata specified by means of P4 +headers annotated with \mdline{5743}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{5743}. The expected metadata is described +in the P4Info using the \mdline{5744}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5744} messages.%mdk + +%mdk-data-line={5746} +\mdline{5746}Both \mdline{5746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5746} and \mdline{5746}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5746} stream messages share the same fields and are +defined as follows:%mdk + +%mdk-data-line={5749} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5750} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~Packet~sent~from~the~controller~to~the~switch.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketOut~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\mdcolor{darkgreen}//~Packet~sent~from~the~switch~to~the~controller.}\\ +{\bfseries{\mdcolor{navy}message}}~PacketIn~\{\\ +~~{\bfseries{\mdcolor{navy}bytes}}~payload~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}repeated}}~PacketMetadata~metadata~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~PacketMetadata~\{\\ +~~{\mdcolor{darkgreen}//~This~refers~to~Metadata.id~coming~from~P4Info~ControllerPacketMetadata.}\\ +~~{\bfseries{\mdcolor{navy}uint32}}~metadata\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\bfseries{\mdcolor{navy}bytes}}~value~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5769} +\begin{itemize}%mdk + +%mdk-data-line={5769} +\item{} +%mdk-data-line={5769} +\mdline{5769}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}payload}}}\mdline{5769} is used to carry the full packet content, including the headers.%mdk%mdk + +%mdk-data-line={5771} +\item{} +%mdk-data-line={5771} +\mdline{5771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5771} is a repeated field of \mdline{5771}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata}}}\mdline{5771} messages used to carry the +arbitrary controller metadata. When a P4Runtime client (or server) +generates a \mdline{5773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5773} (or \mdline{5773}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5773}) message, it must populate precisely +one \mdline{5774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5774} field for each \mdline{5774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5774} field in the +\mdline{5775}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{5775} for packet-out (or packet-in) in the P4Info, such +that the two \mdline{5776}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata.id}}}\mdline{5776} fields match. +The size and value of each \mdline{5777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{5777}/\mdline{5777}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5777} metadata entry needs +to be consistent with what is specified in the corresponding P4Info +\mdline{5779}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.Metadata}}}\mdline{5779} message with the same \mdline{5779}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}id}}}\mdline{5779}, in the +following sense:%mdk + +%mdk-data-line={5781} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5781} +\item\mdline{5781}If \mdline{5781}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.Metadata.bitwidth}}}\mdline{5781} is set, or if +\mdline{5782}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.Metadata.type\_name}}}\mdline{5782} is set and +\mdline{5783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec.translated\_type.sdn\_bitwidth}}}\mdline{5783} is set in the \mdline{5783}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{5783} +for the type name, then \mdline{5784}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata.value}}}\mdline{5784} must be a binary string of +the specified bit width conforming to the\mdline{5785}~\mdref{sec-bytestrings}{Bytestrings}\mdline{5785} +requirements.%mdk + +%mdk-data-line={5787} +\item\mdline{5787}If \mdline{5787}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata.Metadata.type\_name}}}\mdline{5787} is set and +\mdline{5788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec.translated\_type.sdn\_string}}}\mdline{5788} is set in the +\mdline{5789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4NewTypeSpec}}}\mdline{5789} message for the specified type name, then +\mdline{5790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketMetadata.value}}}\mdline{5790} can be an arbitrary SDN string subject to the +\mdline{5791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{5791}. +If a \mdline{5792}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5792} field +does not match the P4Info specification, the server must drop the \mdline{5793}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5793} +message and may generate a \mdline{5794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5794} message with the \mdline{5794}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5794} +field set to report the error to the client which issued the \mdline{5795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5795}. See +the section on\mdline{5796}~\mdref{sec-stream-error-reporting}{Stream Error Reporting}\mdline{5796} for more +information on \mdline{5797}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5797}.%mdk +%mdk +\end{itemize}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5799} +\subsection{\mdline{5799}16.2.\hspace*{0.5em}\mdline{5799}Client Arbitration Update}\label{sec-client-arbitration-update}%mdk%mdk + +%mdk-data-line={5801} +\noindent\mdline{5801}P4Runtime\mdline{5801}'\mdline{5801}s client arbitration mechanism ensures that only the current primary +can modify state on the switch, and that the \mdline{5802}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5802} is monotonically +increasing. For example, the switch must finish all previous write operations +before before selecting a different primary, and must only accept write requests +from the current primary.%mdk + +%mdk-data-line={5807} +\mdline{5807}As explained earlier in this document, the controller uses the \mdline{5807}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5807} +RPC for session management as well as Packet I/O. In fact, before a controller +becomes able to do Packet I/O or program any forwarding entry (via \mdline{5809}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{5809} RPC), +it needs to start a controller session and become a \mdline{5810}\textquotedblleft{}primary\textquotedblright{}\mdline{5810}. To do so, the +controller first opens a bidirectional stream channel to the server via +\mdline{5812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5812} for each device and sends a \mdline{5812}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5812} message. The +controller populates the \mdline{5813}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5813} field in this message using +its \mdline{5814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5814} and \mdline{5814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5814} and the \mdline{5814}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5814} of the device, as explained +in detail in the\mdline{5815}~\mdref{sec-client-arbitration-and-controller-replication}{Client Arbitration and Controller +Replication}\mdline{5816} +section. For any given \mdline{5817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role)}}}\mdline{5817}, the P4Runtime server keeps track +of the highest \mdline{5818}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5818} that it has ever received. If a controller\mdline{5818}'\mdline{5818}s +\mdline{5819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5819} is equal to the highest \mdline{5819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5819} that the server has ever +received, that controller is the primary. All other controllers are backups. +Note that it is possible that all controllers are backups, and that there is no +primary. There can be at most one primary, because for any given +\mdline{5823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}(device\_id,~role)}}}\mdline{5823}, each connected controller has a unique \mdline{5823}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5823}.%mdk + +%mdk-data-line={5825} +\mdline{5825}This invariant must be maintained across in-service software upgrades, and the +P4Runtime server must remember the highest \mdline{5826}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5826} after such a restart. +However, across a\mdline{5827}~\mdref{sec-restarts}{full restart}\mdline{5827}, the \mdline{5827}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5827} must be +reset. In fact, a full restart is the only way to reset the \mdline{5828}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5828}.%mdk + +%mdk-data-line={5830} +\mdline{5830}The \mdline{5830}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5830} message is defined as follows:%mdk + +%mdk-data-line={5832} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={5833} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MasterArbitrationUpdate~\{\\ +~~{\bfseries{\mdcolor{navy}uint64}}~device\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~The~role~for~which~the~primary~client~is~being~arbitrated.~For~use-cases}\\ +~~{\mdcolor{darkgreen}//~where~multiple~roles~are~not~needed,~the~controller~can~leave~this~unset,}\\ +~~{\mdcolor{darkgreen}//~implying~default~role~and~full~pipeline~access.}\\ +~~Role~role~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +~~{\mdcolor{darkgreen}//~The~stream~RPC~with~the~highest~election\_id~is~the~primary.~The~'primary'}\\ +~~{\mdcolor{darkgreen}//~controller~instance~populates~this~with~its~latest~election\_id.~Switch}\\ +~~{\mdcolor{darkgreen}//~populates~with~the~highest~election~ID~it~has~received~from~all~connected}\\ +~~{\mdcolor{darkgreen}//~controllers.}\\ +~~Uint128~election\_id~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Switch~populates~this~with~OK~for~the~client~that~is~the~primary,~and}\\ +~~{\mdcolor{darkgreen}//~with~an~error~status~for~all~other~connected~clients~(at~every~primary}\\ +~~{\mdcolor{darkgreen}//~client~change).~The~controller~does~not~populate~this~field.}\\ +~~.google.{\bfseries{\mdcolor{navy}rpc}}.Status~status~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}4};\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}message}}~Role~\{\\ +~~{\mdcolor{darkgreen}//~Uniquely~identifies~this~role.}\\ +~~{\bfseries{\mdcolor{navy}string}}~name~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}3};\\ +~~{\mdcolor{darkgreen}//~Describes~the~role~configuration,~i.e.~what~operations,~P4~entities,}\\ +~~{\mdcolor{darkgreen}//~behaviors,~etc.~are~in~the~scope~of~a~given~role.~If~config~is~not~set}\\ +~~{\mdcolor{darkgreen}//~(default~case),~it~implies~all~P4~objects~and~control~behaviors~are~in}\\ +~~{\mdcolor{darkgreen}//~scope,~i.e.~full~pipeline~access.~The~format~of~this~message~is}\\ +~~{\mdcolor{darkgreen}//~out-of-scope~of~P4Runtime.}\\ +~~.google.protobuf.Any~config~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5862} +\noindent\mdline{5862}Note that the \mdline{5862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5862} field in the \mdline{5862}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5862} message is not +populated by the controller. This field is populated by the P4Runtime server +when it sends a \mdline{5864}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5864} message back to the controller, in which +it populates the \mdline{5865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5865} message using the \mdline{5865}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{5865}, +\mdline{5866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{5866}, and \mdline{5866}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5866} it previously received from the controller. The server +also populates the \mdline{5867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}status}}}\mdline{5867} field in the \mdline{5867}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{5867} according to +the rules in an\mdline{5868}~\mdref{sec-arbitration-updates}{earlier section}\mdline{5868}.%mdk + +%mdk-data-line={5870} +\subsubsection{\mdline{5870}16.2.1.\hspace*{0.5em}\mdline{5870}Unset Election ID}\label{sec-unset-election-id}%mdk%mdk + +%mdk-data-line={5872} +\noindent\mdline{5872}The sender need not specify an \mdline{5872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5872}. If the \mdline{5872}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5872} is +unset, the sender\mdline{5873}'\mdline{5873}s \mdline{5873}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5873} is considered lower than any +\mdline{5874}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5874}, and the sender will thus never become primary. This way, a +controller can choose to be a standby controller, in order to avoid primary +\mdline{5876}\textquotedblleft{}flapping\textquotedblright{}\mdline{5876} (if a standby controller connects to the switch shortly before the +actual primary controller, therefore becoming primary temporarily).%mdk + +%mdk-data-line={5879} +\mdline{5879}Note that%mdk +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id~:~\{~high:~0~low:~0~\}}}%mdk +\end{mdpre}\noindent\mdline{5883}is different from an unset \mdline{5883}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{5883}, see +\mdline{5884}\mdref{sec-default-valued-fields}{the section on default-valued fields}\mdline{5884}. + +%mdk-data-line={5887} +\subsection{\mdline{5887}16.3.\hspace*{0.5em}\mdline{5887}Digest Messages}\label{sec-digest-messages}%mdk%mdk + +%mdk-data-line={5889} +\noindent\mdline{5889}See the\mdline{5889}~\mdref{sec-digestentry}{DigestEntry}\mdline{5889} section.%mdk + +%mdk-data-line={5891} +\subsection{\mdline{5891}16.4.\hspace*{0.5em}\mdline{5891}Table Idle Timeout Notification}\label{sec-table-idle-timeout-notification}%mdk%mdk + +%mdk-data-line={5893} +\noindent\mdline{5893}When a table supports idle timeout (as per the P4Info message), the primary +client can specify a TTL value for each entry in the table (see +\mdline{5895}\mdref{sec-idle-timeout}{Idle-timeout}\mdline{5895} section). If the data plane entry is not hit +for a lapse of time greater or equal to the TTL, the P4Runtime server should, +with best effort, generate an \mdline{5897}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5897} message on the +\mdline{5898}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5898} bidirectional stream to the primary client. The primary client +can then take the action of its choice, most likely remove the idle entry.%mdk + +%mdk-data-line={5901} +\mdline{5901}The \mdline{5901}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5901} Protobuf message has the following fields:%mdk + +%mdk-data-line={5903} +\begin{itemize}%mdk + +%mdk-data-line={5903} +\item{} +%mdk-data-line={5903} +\mdline{5903}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}timestamp}}}\mdline{5903}: timestamp at which the P4Runtime server generated the message (in +nanoseconds since Epoch) as per the server\mdline{5904}'\mdline{5904}s local clock.%mdk%mdk + +%mdk-data-line={5906} +\item{} +%mdk-data-line={5906} +\mdline{5906}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5906}: a repeated field of entries which have expired. Each individual +entry is identified by a single \mdline{5907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5907} message. For each \mdline{5907}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{5907}, +the \mdline{5908}\emph{key}\mdline{5908} fields (\mdline{5908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_id}}}\mdline{5908}, \mdline{5908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{5908} and \mdline{5908}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}priority}}}\mdline{5908}) must be set, along with +the \mdline{5909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{5909} field, the \mdline{5909}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{5909} field, and the +\mdline{5910}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}idle\_timeout\_ns}}}\mdline{5910} field. Other fields may be set by the server but should be +ignored by the client.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={5913} +\noindent\mdline{5913}Because we use a repeated Protobuf field, the P4Runtime server may elect to +coalesce several idle timeout notifications in the same +\mdline{5915}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5915} message if it deems it appropriate. The server should +not hold on to individual idle notifications for a significant amount of time +just for the sake of coalescing as many as possible in a single message. For +example, if the P4Runtime server periodically scans the device for idle data +plane entries, we recommend not delaying notifications by more than one scanning +interval. The P4Runtime server must not send an \mdline{5920}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutNotification}}}\mdline{5920} +message with an empty \mdline{5921}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table\_entry}}}\mdline{5921} repeated field.%mdk + +%mdk-data-line={5923} +\mdline{5923}After generating an idle notification, the P4Runtime server must \mdline{5923}\textquotedblleft{}reset\textquotedblright{}\mdline{5923} the +timer for the corresponding entry, which means a new notification will be +generated after another TTL if the entry is not hit. As a result, there is no +need to guarantee reliable delivery of idle notifications to the primary client +and the server may drop notifications if they are generated faster than the +server software, the channel or the client can handle.%mdk + +%mdk-data-line={5930} +\mdline{5930}Here is a reasonable pseudo-code implementation for idle timeout for table +entries:%mdk + +%mdk-data-line={5933} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={5934} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}IdleTimeoutStream~stream;\\ +\\ +scanning\_interval~=~{\mdcolor{purple}10}ms;\\ +\\ +{\bfseries{\mdcolor{navy}while}}~({\bfseries{\mdcolor{navy}true}})~\{\\ +~~{\mdcolor{darkgreen}//~iterate~over~all~tables~which~support~idle~timeout}\\ +~~{\bfseries{\mdcolor{navy}for}}~(table~in~tables)~\{\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(!table.idle\_timeout\_supported)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~{\mdcolor{darkgreen}//~we~coalesce~all~idle~notifications~for~the~same~table~in~one}\\ +~~~~{\mdcolor{darkgreen}//~message}\\ +~~~~IdleTimeoutNotification~msg;\\ +~~~~{\mdcolor{darkgreen}//~read~time\_since\_last\_hit~from~device}\\ +~~~~entries~=~device.load\_table\_entries\_from\_hw(table);\\ +~~~~{\bfseries{\mdcolor{navy}for}}~(entry~in~entries)~\{\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.idle\_timeout~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~TTL}\\ +~~~~~~{\bfseries{\mdcolor{navy}if}}~(entry.time\_since\_last\_hit~\textless{}~entry.idle\_timeout)~{\bfseries{\mdcolor{navy}continue}};\\ +~~~~~~msg.table\_entry\_add(entry);\\ +~~~~~~entry.reset\_time\_since\_last\_hit();\\ +~~~~\}\\ +~~~~{\bfseries{\mdcolor{navy}if}}~(msg.table\_entry\_size()~==~{\mdcolor{purple}0})~{\bfseries{\mdcolor{navy}continue}};~~{\mdcolor{darkgreen}//~no~notifications}\\ +~~~~msg.set\_timestamp(now());\\ +~~~~stream.write(msg);\\ +~~\}\\ +~~sleep(scanning\_interval);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={5961} +\subsection{\mdline{5961}16.5.\hspace*{0.5em}\mdline{5961}Architecture-Specific Notifications}\label{sec-architecture-specific-notifications}%mdk%mdk + +%mdk-data-line={5963} +\noindent\mdline{5963}P4Runtime supports streaming arbitrary Protobuf messages between the server and +the client on \mdline{5964}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamChannel}}}\mdline{5964}, by including an \mdline{5964}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{5964} Protobuf field\mdline{5964}~[\mdcite{protoany}{37}]\mdline{5964} +named \mdline{5965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5965} in both \mdline{5965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5965} and \mdline{5965}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5965}. This +enables support for architecture-specific externs which require asynchronous +streaming of data from the server to the client, much like the\mdline{5967}~\mdref{sec-digestentry}{PSA \mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}} +extern}\mdline{5968}. See section on\mdline{5968}~\mdref{sec-extending-p4runtime}{Extending P4Runtime for non-PSA +Architectures}\mdline{5969} for more information.%mdk + +%mdk-data-line={5971} +\subsection{\mdline{5971}16.6.\hspace*{0.5em}\mdline{5971}Stream Error Reporting}\label{sec-stream-error-reporting}%mdk%mdk + +%mdk-data-line={5973} +\noindent\mdline{5973}The P4Runtime server can asynchronously report errors which occur when +processing \mdline{5974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5974} messages, using the \mdline{5974}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{5974} message field (of +type \mdline{5975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5975}) in \mdline{5975}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{5975}. This error reporting is +optional and mostly used for debugging purposes. The server may provide an +out-of-band mechanism to enable / disable this feature.%mdk + +%mdk-data-line={5979} +\mdline{5979}The \mdline{5979}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{5979} message has the following fields:%mdk + +%mdk-data-line={5981} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={5981} +\item\mdline{5981}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{5981}, which must be set to the appropriate canonical error code +\mdline{5982}[\mdcite{grpcstatuscodes}{40}]\mdline{5982}.%mdk + +%mdk-data-line={5983} +\item\mdline{5983}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}message}}}\mdline{5983}, an optional developer-facing error message describing the error.%mdk + +%mdk-data-line={5984} +\item\mdline{5984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5984} and \mdline{5984}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5984}, which are optional and can be used by vendors to provide +additional details on the error. \mdline{5985}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}code}}}\mdline{5985} is a numeric error code drawn from a +vendor\mdline{5986}'\mdline{5986}s chosen error \mdline{5986}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}space}}}\mdline{5986}.%mdk + +%mdk-data-line={5987} +\item\mdline{5987}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5987}, which is a Protobuf \mdline{5987}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5987} used to help the client identify which +\mdline{5988}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageRequest}}}\mdline{5988} triggered the error. The server is required to set the +appropriate field in the \mdline{5989}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5989} so that the client can identify which type +of stream message is responsible for the error (\mdline{5990}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5990}, +\mdline{5991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_list\_ack}}}\mdline{5991} or \mdline{5991}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{5991}), and may also choose to populate the field(s) +of the selected sub-message to provide more context to the client. For +example, if the server received an invalid \mdline{5993}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5993} message from the +client, the \mdline{5994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5994} field (of type \mdline{5994}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError)}}}\mdline{5994} should be set in +the \mdline{5995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}details}}}\mdline{5995} \mdline{5995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{5995}, and the server may additionally set the \mdline{5995}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{5995} +field in the \mdline{5996}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOutError}}}\mdline{5996} sub-message (by copying it from the invalid +\mdline{5997}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{5997} message received on the stream channel) so that the client can +know exactly what packet-out triggered the error.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6000} +\noindent\mdline{6000}The appropriate canonical error code\mdline{6000}~[\mdcite{grpcstatuscodes}{40}]\mdline{6000} should be used when +populating the \mdline{6001}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}canonical\_code}}}\mdline{6001} field. For example:%mdk + +%mdk-data-line={6003} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6003} +\item\mdline{6003}if a controller is not allowed to send a \mdline{6003}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{6003} message under its +current role definition, the code should be set to \mdline{6004}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PERMISSION\_DENIED}}}\mdline{6004}.%mdk + +%mdk-data-line={6005} +\item\mdline{6005}if the \mdline{6005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6005} repeated field in \mdline{6005}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{6005} does not match the P4Info +definition, the code should be set to \mdline{6006}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6006}. It may be useful +for the server to set the \mdline{6007}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}packet\_out}}}\mdline{6007} field in this case, so that the client +can find out which set of metadata fields triggered the error.%mdk + +%mdk-data-line={6009} +\item\mdline{6009}if the \mdline{6009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}digest\_id}}}\mdline{6009} field in \mdline{6009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}DigestListAck}}}\mdline{6009} does not match any \mdline{6009}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Digest}}}\mdline{6009} entry +in P4Info, the code should be set to \mdline{6010}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6010}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6012} +\noindent\mdline{6012}The server may choose to assign a lower priority to error reporting messages and +drop them first if the stream channel comes under heavy load, \mdline{6013}e.g.\mdline{6013} because of a +burst of \mdline{6014}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketIn}}}\mdline{6014} messages.%mdk + +%mdk-data-line={6016} +\mdline{6016}Note that client arbitration errors are never reported using the \mdline{6016}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{6016} +message. Invalid \mdline{6017}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MasterArbitrationUpdate}}}\mdline{6017} messages sent by the client cause the +stream to be terminated and the appropriate error code to be returned to the +client immediately. See section\mdline{6019}~\mdref{sec-arbitration-updates}{5.3}\mdline{6019}.%mdk + +%mdk-data-line={6021} +\subsubsection{\mdline{6021}16.6.1.\hspace*{0.5em}\mdline{6021}Examples of \mdline{6021}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamError}}}\mdline{6021} Messages}\label{sec-examples-of-streamerror-messages}%mdk%mdk + +%mdk-data-line={6023} +\begin{itemize}%mdk + +%mdk-data-line={6023} +\item{} +%mdk-data-line={6023} +\mdline{6023}\textbf{Malformed packet-out metadata.}\mdline{6023} If the server receives a \mdline{6023}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{6023} +message with a \mdline{6024}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6024} field with id 7 which is not included in the P4Info +\mdline{6025}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ControllerPacketMetadata}}}\mdline{6025} message for \mdline{6025}\textquotedblleft{}packet\_out\textquotedblright{}\mdline{6025}, the server may send the +following \mdline{6026}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{6026} back to the client:%mdk + +%mdk-data-line={6027} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6028} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Unknown~metadata~field~id~7.}{\mdcolor{maroon}"}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~copied~from~the~PacketOut~message~received~from~the~client}\\ +~~~packet\_out~\{\\ +~~~~~payload:~...\\ +~~~~~metadata~\{\\ +~~~~~~~id:~{\mdcolor{purple}7}\\ +~~~~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}I\_should\_not\_be\_here}{\mdcolor{maroon}"}\\ +~~~~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~~\}\\ +~~~~~{\mdcolor{darkgreen}\#~more~metadata}\\ +~~~\}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk + +%mdk-data-line={6046} +\item{} +%mdk-data-line={6046} +\mdline{6046}\textbf{Packet-out which exceeds the MTU.}\mdline{6046} If the server receives a \mdline{6046}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PacketOut}}}\mdline{6046} +message which requires injecting a raw data plane packet that exceeds the MTU +(Maximum Transmission Unit) for the egress link, the server may generate the +following \mdline{6049}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}StreamMessageResponse}}}\mdline{6049}:%mdk + +%mdk-data-line={6050} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6051} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error~\{\\ +~canonical\_code:~{\mdcolor{purple}3}~~{\mdcolor{darkgreen}\#~INVALID\_ARGUMENT}\\ +~message:~{\mdcolor{maroon}"}{\mdcolor{maroon}Packet~exceeds~the~MTU~for~port.}{\mdcolor{maroon}"}\\ +~space:~{\mdcolor{maroon}"}{\mdcolor{maroon}targetX-psa-vendor1}{\mdcolor{maroon}"}\\ +~code:~{\mdcolor{purple}123}~~{\mdcolor{darkgreen}\#~MTU\_EXCEEDED}\\ +~packet\_out~\{\\ +~~~{\mdcolor{darkgreen}\#~we~do~not~set~the~packet\_out~field~as~it~does~not~provide~any}\\ +~~~{\mdcolor{darkgreen}\#~extra~information~to~the~client}\\ +~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6063} +\section{\mdline{6063}17.\hspace*{0.5em}\mdline{6063}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6063} RPC}\label{sec-capabilities-rpc}%mdk%mdk + +%mdk-data-line={6065} +\noindent\mdline{6065}The \mdline{6065}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6065} RPC offers a mechanism through which a P4Runtime client can +discover the capabilities of the P4Runtime server implementation. At the moment, +the \mdline{6067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesRequest}}}\mdline{6067} message is empty and the \mdline{6067}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{6067} +message only includes the \mdline{6068}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_api\_version}}}\mdline{6068} string field. This field must +be set to the full semantic version string\mdline{6069}~[\mdcite{semver}{32}]\mdline{6069} corresponding to the +version of the P4Runtime API implemented by the server, \mdline{6070}e.g.\mdline{6070} \mdline{6070}\textquotedblleft{}1.1.0-rc.1\textquotedblright{}\mdline{6070}.%mdk + +%mdk-data-line={6072} +\mdline{6072}Future versions of P4Runtime may introduce more advanced capability discovery +features. For example, P4Runtime supports three\mdline{6073}~\mdref{sec-batch-atomicity}{atomicity +modes}\mdline{6074} for \mdline{6074}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6074} batches, two of them being +optional. In the future we may decide to leverage the \mdline{6075}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{6075} +message to enable the server to report to the client which subset of these +atomicity modes is supported.%mdk + +%mdk-data-line={6079} +\mdline{6079}The semantic version string included in \mdline{6079}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}CapabilitiesResponse}}}\mdline{6079} can be used by +the client to determine which exact feature set is implemented by the server, +since\mdline{6081}~\mdref{sec-p4runtime-versioning}{minor releases}\mdline{6081} may introduce new +functionality. However, because the \mdline{6082}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6082} RPC itself was introduced in +version 1.1 of P4Runtime, the client should assume that any server which does +not implement this RPC (\mdline{6084}i.e.\mdline{6084} an \mdline{6084}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}UNIMPLEMENTED}}}\mdline{6084} error is returned by the +P4Runtime service) implements an older version of the P4Runtime specification +(1.0 or a pre-release version of 1.0).%mdk + +%mdk-data-line={6088} +\section{\mdline{6088}18.\hspace*{0.5em}\mdline{6088}Portability Considerations}\label{sec-portability-considerations}%mdk%mdk + +%mdk-data-line={6090} +\subsection{\mdline{6090}18.1.\hspace*{0.5em}\mdline{6090}PSA Metadata Translation}\label{sec-psa-metadata-translation}%mdk%mdk + +%mdk-data-line={6092} +\noindent\mdline{6092}The \mdline{6092}\emph{Portable Switch Architecture}\mdline{6092} (PSA) defines standard metadata, whose +data plane types are different on different PSA targets. In order to enable +uniform programming of multiple PSA targets, a centralized remote controller may +define its own types and numbering of such PSA standard metadata +\mdline{6096}[\mdcite{psatranslation}{29}]\mdline{6096}. For such metadata, a translation between the controller\mdline{6096}'\mdline{6096}s +metadata values and the corresponding target-specific metadata values is +required at runtime. In this section, we will base our discussions on port +metadata, although the same translation principles apply to other standard PSA +metadata such as class of service. Since the \mdline{6100}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6100} annotation +can be applied to any user-defined type, these principles also apply to +translated types which are not declared as part of the PSA architecture.%mdk + +%mdk-data-line={6104} +\begin{figure}[tbp]%mdk +\begin{mdcenter}%mdk + +%mdk-data-line={6105} +\noindent\mdline{6105}\includegraphics[keepaspectratio=true,height=7cm]{build/psa-metadata-translation}{}\mdline{6105}%mdk + +%mdk-data-line={6106} +\mdhr{}%mdk + +%mdk-data-line={6107} +\noindent\mdline{6107}\mdcaption{\textbf{Figure~\mdcaptionlabel{8}.}~\mdcaptiontext{P4Runtime Metadata Translation for the Portable Switch Architecture}}%mdk +%mdk +\end{mdcenter}\label{fig-psa-metadata-translation}%mdk +%mdk +\end{figure}%mdk + +%mdk-data-line={6111} +\noindent\mdline{6111}Figure\mdline{6111}~\mdref{fig-psa-metadata-translation}{\mdcaptionlabel{8}}\mdline{6111} illustrates a motivating example, +where a centralized controller is controlling two P4Runtime targets in a fabric. +Switch 1 and Switch 2 use different PSA devices, each defining its own port type +and number space. In this example, Switch 1 uses a device with 9-bit space for +port numbers, and Switch 2 uses a device with 10-bit space for port numbers. The +centralized SDN controller defines an independent 32-bit number space for ports +of all targets in its domain. A mapping from the controller\mdline{6117}'\mdline{6117}s 32 bit port +numbers to a target\mdline{6118}'\mdline{6118}s 9-bit or 10-bit port numbers is input to the switch via +the non-forwarding switch config data that is delivered separately to the +switch.%mdk + +%mdk-data-line={6122} +\subsubsection{\mdline{6122}18.1.1.\hspace*{0.5em}\mdline{6122}Translation of Port Numbers}\label{sec-translation-of-port-numbers}%mdk%mdk + +%mdk-data-line={6124} +\noindent\mdline{6124}In order to support the above SDN use case, P4Runtime requires translation of +port metadata values between the controller\mdline{6125}'\mdline{6125}s space and the PSA device\mdline{6125}'\mdline{6125}s space +as needed. Such translation is enabled by identifying a P4 entity (match field, +action parameter, controller-header field or other) as being a PSA port metadata +type. For this purpose, PSA defines the port metadata field type using special +\mdline{6129}\mdref{sec-user-defined-types}{user-defined P4 types}\mdline{6129}, namely \mdline{6129}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{6129} and +\mdline{6130}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{6130}, instead of standard P4 bitstrings. The P4Info entries for +all P4 entities whose type is one of the special PSA port types use a +controller-defined 32-bit type instead of the data plane bitwidth defined in the +P4 program. The following PSA port metadata types are defined in \mdline{6133}\emph{psa.p4}\mdline{6133} for +the PSA device in Switch 1.%mdk + +%mdk-data-line={6136} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6137} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortId\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}9}\textgreater{}~PortId\_t;\\ +{\mdcolor{gray}@}{\mdcolor{gray}p4runtime\_translation}{\mdcolor{maroon}("p4.org/psa/v1/PortIdInHeader\_t",~32)}\\ +{\bfseries{\mdcolor{navy}type}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~PortIdInHeader\_t;}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6143} +\noindent\mdline{6143}The first argument to the \mdline{6143}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6143} annotation is a URI that +indicates to the P4Runtime server which numerical mapping\mdline{6144} \mdline{6144}\textemdash{}\mdline{6144} provided by the +out-of-band switch configuration mechanism\mdline{6145} \mdline{6145}\textemdash{}\mdline{6145} to use to translate between the +SDN value and the data plane value. The second argument is the bitwidth of the +SDN representation of the translated entity (32-bit in the case of ports).%mdk + +%mdk-data-line={6149} +\mdline{6149}An SDN port number of 0 is invalid (while 0 may be a valid device port number +depending on the PSA device). A PSA device may define its CPU and recirculation +ports in the device-specific port number space. P4Runtime reserves +device-independent and controller-specific 32-bit constants for the CPU port and +the recirculation port as follows:%mdk + +%mdk-data-line={6155} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6156} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}enum}}~SdnPort~\{\\ +~~SDN\_PORT\_UNKNOWN~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +\\ +~~{\mdcolor{darkgreen}//~SDN~ports~are~numbered~starting~from~1.}\\ +~~SDN\_PORT\_MIN~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +\\ +~~{\mdcolor{darkgreen}//~The~maximum~value~of~an~SDN~port~(physical~or~logical).}\\ +~~SDN\_PORT\_MAX~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffeff};\\ +\\ +~~{\mdcolor{darkgreen}//~Reserved~SDN~port~numbers~(0xfffffff0~-~0xffffffff)}\\ +\\ +~~SDN\_PORT\_RECIRCULATE~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffa};\\ +~~SDN\_PORT\_CPU~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0xfffffffd};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6172} +\noindent\mdline{6172}The switch config will map \mdline{6172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_RECIRCULATE}}}\mdline{6172} and \mdline{6172}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SDN\_PORT\_CPU}}}\mdline{6172} \mdline{6172}\textemdash{}\mdline{6172} as well +as any SDN port number corresponding to a \mdline{6173}\textquotedblleft{}regular\textquotedblright{}\mdline{6173} front-panel port\mdline{6173} \mdline{6173}\textemdash{}\mdline{6173} to the +corresponding device-specific values, in order to enable the P4Runtime server to +perform the translation.%mdk + +%mdk-data-line={6177} +\mdline{6177}The sub-sections below detail the translation mechanics for different usage of +PSA port types in P4 programs.%mdk + +%mdk-data-line={6180} +\subsubsection{\mdline{6180}18.1.2.\hspace*{0.5em}\mdline{6180}Translation of Packet-IO Header Fields}\label{sec-translation-of-packet-io-header-fields}%mdk%mdk + +%mdk-data-line={6182} +\noindent\mdline{6182}Port type fields can be part of header types. For example, ports may be part of +Packet IO headers, as in the following example:.%mdk + +%mdk-data-line={6185} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6186} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_out")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketOut\_t~\{\\ +~~PortIdInHeader\_t~egress\_port;\\ +\}\\ +\\ +{\mdcolor{gray}@}{\mdcolor{gray}controller\_header}{\mdcolor{maroon}("packet\_in")}\\ +{\bfseries{\mdcolor{navy}header}}~PacketIn\_t~\{\\ +~~PortIdInHeader\_t~ingress\_port;\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6197} +\noindent\mdline{6197}The header-level annotation \mdline{6197}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{6197} is a standard P4Runtime +annotation that identifies a header type for a controller packet-out or +packet-in header. When the P4Runtime server in the target receives a packet-out +from the controller over the P4Runtime stream channel, the server will expect a +packet-out metadata (\mdline{6201}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{6201}) value of width 32-bit from the given set of +SDN port values in the switch config. The server will then translate the SDN +port value into the device-specific port value from the mapping provided in the +out-of-band switch configuration (the mapping can be identified using the +translation URI\mdline{6205} \mdline{6205}\textemdash{}\mdline{6205} first argument to the \mdline{6205}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6205} +annotation). Any subsequent reference to the \mdline{6206}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}egress\_port}}}\mdline{6206} field in the +data plane will use the translated value. \mdline{6207}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortIdInHeader\_t}}}\mdline{6207} is used in the +header definition instead of \mdline{6208}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{6208} to guarantee byte-aligned headers in +case this is required by the target.%mdk + +%mdk-data-line={6211} +\mdline{6211}A similar reverse translation is required in the P4Runtime server for packets +punted from the target to the controller as shown by the packet-in header +example above. A packet punted from the target\mdline{6213}'\mdline{6213}s PSA device will be intercepted +by the P4Runtime server before being sent to the controller. The server will +first translate the device-specific value of the \mdline{6215}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ingress\_port}}}\mdline{6215} field into the +controller-specific 32-bit value given by the port mapping defined in the switch +config. The server will then insert the translated controller-specific value in +the packet-in metadata fields before sending the packet over the stream channel +to the controller.%mdk + +%mdk-data-line={6221} +\subsubsection{\mdline{6221}18.1.3.\hspace*{0.5em}\mdline{6221}Translation of Match Fields}\label{sec-translation-of-match-fields}%mdk%mdk + +%mdk-data-line={6223} +\noindent\mdline{6223}Port type entities, particularly ingress and egress port standard metadata, may +be used as match fields in a P4 table\mdline{6224}'\mdline{6224}s match key as shown in the example below:%mdk + +%mdk-data-line={6226} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6227} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~istd.ingress\_port:~exact;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~ingress~port}\\ +~~\}\\ +~~actions~=~\{\\ +~~~~drop;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6237} +\noindent\mdline{6237}Table \mdline{6237}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{6237} has an exact match on PSA standard metadata ingress port +(\mdline{6238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}istd.ingress\_port}}}\mdline{6238}). Since the field is of type \mdline{6238}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{6238}, the P4Info +representation of the match field will present a 32-bit bitwidth to the +controller, regardless of the data plane port type. A P4Runtime write request +for a table entry in \mdline{6241}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{6241} from the controller will have the values of the match +field set to the controller-specific port value. The P4Runtime server should +intercept the write request and use the switch configuration data to translate +the SDN port value to respective device-specific value. In the data plane, the +packet metadata will carry the device-specific value and, hence, match the right +table entry. Similarly, when a read response for table \mdline{6246}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{6246} is returned to the +controller, the P4Runtime server should translate the device-specific port +values to the corresponding controller-specific values.%mdk + +%mdk-data-line={6250} +\mdline{6250}Note that it may be infeasible to translate the value-mask pair for ternary +matches: \mdline{6251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{6251}, \mdline{6251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{6251} or \mdline{6251}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{6251} match kinds. The P4Runtime server may +require that for these match kinds the port match be either \mdline{6252}\emph{de facto}\mdline{6252} \mdline{6252}\textquotedblleft{}exact\textquotedblright{}\mdline{6252} +(0xffffffff mask for \mdline{6253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{6253}, prefix-length of 32 for \mdline{6253}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{6253}, or same low and +high bounds for \mdline{6254}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{6254}) or \mdline{6254}\textquotedblleft{}don't care\textquotedblright{}\mdline{6254}.%mdk + +%mdk-data-line={6256} +\subsubsection{\mdline{6256}18.1.4.\hspace*{0.5em}\mdline{6256}Translation of Action Parameters}\label{sec-translation-of-action-parameters}%mdk%mdk + +%mdk-data-line={6258} +\noindent\mdline{6258}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{6258} type parameters can be part of a P4 action definition as shown in the +example below:%mdk + +%mdk-data-line={6261} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6262} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +\}\\ +\\ +{\bfseries{\mdcolor{navy}table}}~t~\{\\ +~~key~=~\{\\ +~~~~hdr.h.f:~exact;\\ +~~\}\\ +~~actions~=~\{\\ +~~~~a;\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6276} +\noindent\mdline{6276}The controller may write entries in table \mdline{6276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}t}}}\mdline{6276} with action \mdline{6276}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}a}}}\mdline{6276} to set the egress +port as shown in the P4 code above. The action parameter \mdline{6277}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{6277} is of type +\mdline{6278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{6278}, which leads to a 32-bit bitwidth for \mdline{6278}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p}}}\mdline{6278} being exposed in +P4Info. Furthermore, the type will be a signal to the P4Runtime server that +translation is required for this parameter. The P4Runtime server will use the +switch configuration to translate action parameter values between the controller +and the target device.%mdk + +%mdk-data-line={6284} +\subsubsection{\mdline{6284}18.1.5.\hspace*{0.5em}\mdline{6284}Port Translation for PSA Extern APIs}\label{sec-port-translation-for-psa-extern-apis}%mdk%mdk + +%mdk-data-line={6286} +\noindent\mdline{6286}The P4Runtime API for action selectors supports specifying a watch field per +member in an action profile group that is programmed in a selector. This field +is used to implement fast-failover in the target, where the P4Runtime server can +locally prune the member from the group if a port is down. This pruning does not +require intervention from the controller. Conversely, if the port comes back up, +the P4Runtime server can re-enable the member in the group. The \mdline{6291}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{6291} +field is of type \mdline{6292}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{6292} to carry the SDN representation of the port being +watched. The P4Runtime server will translate the given watch port into +the device-specific data plane port number for implementing the fast-failover +functionality on the target device.%mdk + +%mdk-data-line={6297} +\mdline{6297}The Packet Replication Engine (PRE) API in P4Runtime supports cloning and +multicasting to a set of ports. The egress \mdline{6298}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}port}}}\mdline{6298} fields defined in the PRE +multicast entry and clone session entry are of type \mdline{6299}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{6299} to carry the SDN +representation of the port(s). The P4Runtime server will translate these SDN +ports to device-specific port numbers for multicasting and cloning in the data +plane.%mdk + +%mdk-data-line={6304} +\subsubsection{\mdline{6304}18.1.6.\hspace*{0.5em}\mdline{6304}Using Port as an Index to a Register, Indirect Counter or Indirect Meter}\label{sec-using-port-as-an-index-to-a-register-indirect-counter-or-indirect-meter}%mdk%mdk + +%mdk-data-line={6306} +\noindent\mdline{6306}P4Runtime supports using a translated value (\mdline{6306}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PortId\_t}}}\mdline{6306} or any other translated +type for which the underlying built-in type is \mdline{6307}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6307}) as an index to a +register, indirect counter, or indirect meter.%mdk + +%mdk-data-line={6310} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6311} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Counter\textless{}{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~counter~entry~type~}{\mdcolor{darkgreen}*/},~PortId\_t~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~index~type~}{\mdcolor{darkgreen}*/}\textgreater{}(\\ +~~{\mdcolor{purple}32}w1024,~PSA\_CounterType\_t.PACKETS)~counter;\\ +{\bfseries{\mdcolor{navy}action}}~a(PortId\_t~p)~\{\\ +~~istd.egress\_port~=~p;~~{\mdcolor{darkgreen}//~PSA~standard~metadata~egress~port}\\ +~~counter.count(p);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6319} +\noindent\mdline{6319}This P4 Counter declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={6322} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6323} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counters~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x12000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}counter}{\mdcolor{maroon}"}\\ +~~\}\\ +~~spec~\{\\ +~~~~unit:~PACKETS\\ +~~\}\\ +~~index\_type\_name~\{\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}PortId\_t}{\mdcolor{maroon}"}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6337} +\noindent\mdline{6337}The controller may read and write counter values from indexed counter \mdline{6337}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}counter}}}\mdline{6337} +using SDN port numbers as indices, and not device-specific port numbers. The +\mdline{6339}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}index\_type\_name}}}\mdline{6339} field in the P4Info message is a signal to the P4Runtime +server that translation is required.%mdk + +%mdk-data-line={6342} +\section{\mdline{6342}19.\hspace*{0.5em}\mdline{6342}P4Runtime Versioning}\label{sec-p4runtime-versioning}%mdk%mdk + +%mdk-data-line={6344} +\noindent\mdline{6344}P4Runtime follows the Google guidelines for versioning cloud APIs +\mdline{6345}[\mdcite{apiversioning}{8}]\mdline{6345}. We use a \mdline{6345}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR.MINOR.PATCH}}}\mdline{6345} style version number scheme and +we increment the:%mdk + +%mdk-data-line={6348} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6348} +\item\mdline{6348}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{6348} version when we make incompatible API changes,%mdk + +%mdk-data-line={6349} +\item\mdline{6349}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MINOR}}}\mdline{6349} version when we add functionality in a backwards-compatible manner,%mdk + +%mdk-data-line={6350} +\item\mdline{6350}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PATCH}}}\mdline{6350} version when we make backwards-compatible bug fixes.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6352} +\noindent\mdline{6352}The major version number is encoded as the last component of the Protobuf +package name for every P4Runtime version, including version 1 (v1), which is why +currently the package name for the P4Runtime service is \mdline{6354}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1}}}\mdline{6354} and the package +name for P4Info is \mdline{6355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1}}}\mdline{6355}. Even though \mdline{6355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{6355} and \mdline{6355}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{6355} are two +different Protobuf packages, \mdline{6356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4}}}\mdline{6356} depends on \mdline{6356}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config}}}\mdline{6356} and is not meant to be +used without it, which is why both packages use the same versioning scheme and +the same versioning cadence.%mdk + +%mdk-data-line={6360} +\mdline{6360}As recommended in\mdline{6360}~[\mdcite{apiversioning}{8}]\mdline{6360}, we may consider using pre-GA release +suffixes (such as \mdline{6361}\emph{alpha}\mdline{6361} or \mdline{6361}\emph{beta}\mdline{6361}) in the Protobuf package name for future +major versions, although we have chosen not to do so when developing version 1 +(v1).%mdk + +%mdk-data-line={6365} +\mdline{6365}Within a major version, the API must be evolved in a Protobuf +backwards-compatible manner.\mdline{6366}~[\mdcite{apiversioningbackwardscompatibility}{9}]\mdline{6366} describes +what constitute a backwards-compatible change. We expect \mdline{6367}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MAJOR}}}\mdline{6367} version bumps +to be a \mdline{6368}\textbf{rare}\mdline{6368} event.%mdk + +%mdk-data-line={6370} +\mdline{6370}Note that a P4Runtime server may support multiple major versions of P4Runtime, +although a client is expected to use the same version of the P4Runtime service +for all its operations with a given device, during the lifetime of its session +with the device. A client can check if a major version is supported by +attempting to connect to the corresponding service. We may consider including a +P4Runtime RPC to query minor\mdline{6375} \mdline{6375}+ patch version numbers in future releases.%mdk + +%mdk-data-line={6377} +\mdline{6377}All versions of P4Runtime, including pre-release versions, are tagged in the +P4Runtime Github repository\mdline{6378}~[\mdcite{p4runtimerepo}{19}]\mdline{6378} and the version label follows +semantic versioning rules\mdline{6379}~[\mdcite{semver}{32}]\mdline{6379}.%mdk + +%mdk-data-line={6381} +\section{\mdline{6381}20.\hspace*{0.5em}\mdline{6381}Extending P4Runtime for non-PSA Architectures}\label{sec-extending-p4runtime}%mdk%mdk + +%mdk-data-line={6383} +\noindent\mdline{6383}P4Runtime includes native support for PSA programs and in particular support for +runtime control of PSA extern instances. While the definition of Protobuf +messages for runtime control of non-PSA externs is out-of-scope of this +specification, P4Runtime provides an extension mechanism for other +architectures, through different hooks in the protocol definition. These hooks +are described in various parts of this document and the goal of this section is +to offer a comprehensive list of them in a single place.%mdk + +%mdk-data-line={6391} +\mdline{6391}When extending P4Runtime for a new P4 architecture, one will need to write two +additional Protobuf files to extend p4info.proto and p4runtime.proto +respectively. We suggest the following Protobuf package names:%mdk + +%mdk-data-line={6395} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6395} +\item\mdline{6395}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/config/\textless{}major~version\textgreater{}/p4info.proto}}}\mdline{6395}%mdk + +%mdk-data-line={6396} +\item\mdline{6396}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4/{}[organization]/arch/\textless{}major~version\textgreater{}/p4runtime.proto}}}\mdline{6396}%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6398} +\noindent\mdline{6398}We also recommend that the major version number for these packages be the same +as the major version number for the P4Runtime version they \mdline{6399}\textquotedblleft{}extend\textquotedblright{}\mdline{6399}.%mdk + +%mdk-data-line={6401} +\mdline{6401}For the remainder of this section, we will refer to these two files as +\mdline{6402}\emph{p4info-ext}\mdline{6402} and \mdline{6402}\emph{p4runtime-ext}\mdline{6402} respectively.%mdk + +%mdk-data-line={6404} +\subsection{\mdline{6404}20.1.\hspace*{0.5em}\mdline{6404}Extending P4Runtime for Architecture-Specific Externs}\label{sec-extending-p4runtime-for-architecture-specific-externs}%mdk%mdk + +%mdk-data-line={6406} +\noindent\mdline{6406}Each P4 architecture can define its own set of extern types. Controlling them at +runtime requires defining new Protobuf messages in both \mdline{6407}\emph{p4info-ext}\mdline{6407} and +\mdline{6408}\emph{p4runtime-ext}\mdline{6408}. To make things more concrete for this section, we will assume +that the new architecture we are trying to support in P4Runtime includes the +following extern definition, which we will use as a running example:%mdk + +%mdk-data-line={6412} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6413} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~T~must~be~a~bit\textless{}W\textgreater{}~type,~it~indicates~the~width~of~each~counter~cell}\\ +{\bfseries{\mdcolor{navy}extern}}~MyNewPacketCounter\textless{}T\textgreater{}~\{\\ +~~counter({\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~size);\\ +~~increment({\bfseries{\mdcolor{navy}in}}~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}32}\textgreater{}~index);\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6420} +\subsubsection{\mdline{6420}20.1.1.\hspace*{0.5em}\mdline{6420}Extending the P4Info message}\label{sec-extending-the-p4info-message}%mdk%mdk + +%mdk-data-line={6422} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6422} +\item\mdline{6422}Id prefixes \mdline{6422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0x81}}}\mdline{6422} through \mdline{6422}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}0xfe}}}\mdline{6422} are reserved for architecture-specific +externs. It is recommended that \mdline{6423}\emph{p4info-ext}\mdline{6423} include a \mdline{6423}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Ids}}}\mdline{6423} message based +on the one in p4info.proto that the P4 compiler can refer to when\mdline{6424}~\mdref{sec-id-allocation}{assigning +IDs}\mdline{6425} to each extern instance.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6427} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6428} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~P{\mdcolor{purple}4}Ids~\{\\ +~~{\bfseries{\mdcolor{navy}enum}}~Prefix~\{\\ +~~~~UNSPECIFIED~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0};\\ +~~~~MY\_NEW\_PACKET\_COUNTER~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}0x81};\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6436} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6436} +\item\mdline{6436}\emph{p4info-ext}\mdline{6436} should include a Protobuf message definition for every extern +type that can be controlled at runtime. For every extern instance of this +type, the compiler will generate an instance of this Protobuf message and +embed it appropriately in the corresponding +\mdline{6440}\mdref{sec-p4info-extern}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.ExternInstance}}}}\mdline{6440} message as the \mdline{6440}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}info}}}\mdline{6440} +field, which is of type \mdline{6441}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6441}~[\mdcite{protoany}{37}]\mdline{6441}.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6443} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6444} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\mdcolor{darkgreen}//~corresponds~to~the~T~type~parameter~in~the~P4~extern~definition}\\ +~~p4.config.v1.P{\mdcolor{purple}4}DataTypeSpec~type\_spec~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~{\mdcolor{darkgreen}//~constructor~argument}\\ +~~{\bfseries{\mdcolor{navy}int64}}~size~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6452} +\subsubsection{\mdline{6452}20.1.2.\hspace*{0.5em}\mdline{6452}Extending the P4Runtime Service}\label{sec-extending-the-p4runtime-service}%mdk%mdk + +%mdk-data-line={6454} +\noindent\mdline{6454}Just like \mdline{6454}\emph{p4info-ext}\mdline{6454}, \mdline{6454}\emph{p4runtime-ext}\mdline{6454} should include a Protobuf message +definition for every extern type that can be controlled at runtime. This message +should include the extern-specific parameters defining the read or write +operation to be performed by the P4Runtime server on the corresponding extern +instance. Instances of this architecture-specific message are meant to be +embedded in an\mdline{6459}~\mdref{sec-extern-entry}{\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ExternEntry}}}}\mdline{6459} message generated by the +P4Runtime client.%mdk + +%mdk-data-line={6462} +\mdline{6462}Here is a possible Protobuf message for our \mdline{6462}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MyNewPacketCounter}}}\mdline{6462} P4 extern:%mdk + +%mdk-data-line={6463} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6464} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\mdcolor{darkgreen}//~This~message~enables~reading~/~writing~data~to~the~counter~at~the~provided}\\ +{\mdcolor{darkgreen}//~index}\\ +{\bfseries{\mdcolor{navy}message}}~MyNewPacketCounter~\{\\ +~~{\bfseries{\mdcolor{navy}int64}}~index~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}1};\\ +~~p4.v1.P{\mdcolor{purple}4}Data~data~{\bfseries{\mdcolor{navy}=}}~{\mdcolor{purple}2};\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6472} +\noindent\mdline{6472}P4Runtime also supports streaming arbitrary Protobuf messages between the server +and the client, by including an \mdline{6473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6473} Protobuf field\mdline{6473}~[\mdcite{protoany}{37}]\mdline{6473} named \mdline{6473}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6473} +in both \mdline{6474}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{6474} and +\mdline{6475}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{6475}. Architectures that wish to leverage this support +should define the appropriate Protobuf messages for this bidirectional streaming +in \mdline{6477}\emph{p4runtime-ext}\mdline{6477} and embed instances of these messages in +\mdline{6478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageRequest}}}\mdline{6478} and \mdline{6478}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.StreamMessageResponse}}}\mdline{6478} as appropriate.%mdk + +%mdk-data-line={6480} +\subsection{\mdline{6480}20.2.\hspace*{0.5em}\mdline{6480}Architecture-Specific Table Extensions}\label{sec-architecture-specific-table-extensions}%mdk%mdk + +%mdk-data-line={6482} +\subsubsection{\mdline{6482}20.2.1.\hspace*{0.5em}\mdline{6482}New Match Types}\label{sec-new-match-types}%mdk%mdk + +%mdk-data-line={6484} +\noindent\mdline{6484}An architecture may introduce new table match types\mdline{6484}~[\mdcite{p4matchtypes}{14}]\mdline{6484}. P4Runtime +accounts for this by providing the following hooks:%mdk + +%mdk-data-line={6487} +\begin{itemize}%mdk + +%mdk-data-line={6487} +\item{} +%mdk-data-line={6487} +\mdline{6487}The \mdline{6487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}match}}}\mdline{6487} field in \mdline{6487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.MatchField}}}\mdline{6487} (p4info.proto) is a \mdline{6487}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6487} +which can be either one of the default match types (\mdline{6488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}EXACT}}}\mdline{6488}, \mdline{6488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}LPM}}}\mdline{6488}, \mdline{6488}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TERNARY}}}\mdline{6488}, +\mdline{6489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RANGE}}}\mdline{6489}, or \mdline{6489}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6489}) or an architecture-specific match type encoded as a +string.%mdk%mdk + +%mdk-data-line={6492} +\item{} +%mdk-data-line={6492} +\mdline{6492}The \mdline{6492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}field\_match\_type}}}\mdline{6492} field in \mdline{6492}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6492} (p4runtime.proto) is a +\mdline{6493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}oneof}}}\mdline{6493} which includes an \mdline{6493}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6493} Protobuf message\mdline{6493}~[\mdcite{protoany}{37}]\mdline{6493} field +(\mdline{6494}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6494}). \mdline{6494}\emph{p4info-ext}\mdline{6494} should include a Protobuf message definition for each +architecture-specific match type, which can be used to encode values for match +key elements which use this match type type in the P4 table +declaration. These match values are embedded in \mdline{6497}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.FieldMatch}}}\mdline{6497} as the +\mdline{6498}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other}}}\mdline{6498} field, which can then be decoded by the P4Runtime server using the +match type name included in P4Info.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6501} +\subsubsection{\mdline{6501}20.2.2.\hspace*{0.5em}\mdline{6501}New Table Properties}\label{sec-new-table-properties}%mdk%mdk + +%mdk-data-line={6503} +\noindent\mdline{6503}An architecture may introduce additional table properties +\mdline{6504}[\mdcite{p4tableproperties}{36}]\mdline{6504}. In some instances, it can be desirable to include the +information contained in table properties in P4Info, which is why the +\mdline{6506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.config.v1.Table}}}\mdline{6506} message includes the \mdline{6506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}other\_properties}}}\mdline{6506} \mdline{6506}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Any}}}\mdline{6506} Protobuf +field\mdline{6507}~[\mdcite{protoany}{37}]\mdline{6507}. At the moment, there is not any mechanism to extend the +\mdline{6508}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.v1.TableEntry}}}\mdline{6508} message based on the value of architecture-specific table +properties, but we may include on in future versions of the API.%mdk + +%mdk-data-line={6511} +\section{\mdline{6511}21.\hspace*{0.5em}\mdline{6511}Known Limitations of Current P4Runtime Version}\label{sec-known-limitations-of-current-p4runtime-version}%mdk%mdk + +%mdk-data-line={6513} +\begin{itemize}%mdk + +%mdk-data-line={6513} +\item{} +%mdk-data-line={6513} +\mdline{6513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6513}, action \mdline{6513}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6513}, and controller packet metadata fields only +support unsigned bitstrings, \mdline{6514}i.e.\mdline{6514} values of one of the following types (not +the more general \mdline{6515}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Data}}}\mdline{6515}):%mdk + +%mdk-data-line={6516} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6516} +\item\mdline{6516}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6516}%mdk + +%mdk-data-line={6517} +\item\mdline{6517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6517}. Note that as far as the \mdline{6517}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}P4Info}}}\mdline{6517} message contents and +thus controller software is concerned, such fields of type \mdline{6518}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bool}}}\mdline{6518} +will be indistinguishable from those that have been declared with +type \mdline{6520}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6520}. P4Runtime server software will automatically +perform any conversion needed between the type \mdline{6521}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}1\textgreater{}}}}\mdline{6521} values in +P4Runtime messages and the data plane representation.%mdk + +%mdk-data-line={6523} +\item\mdline{6523}an \mdline{6523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}enum}}}\mdline{6523} with underlying type \mdline{6523}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bit\textless{}W\textgreater{}}}}\mdline{6523}%mdk + +%mdk-data-line={6524} +\item\mdline{6524}a \mdline{6524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6524} or \mdline{6524}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6524} with an underlying type that is one of the above (or +in general a \mdline{6525}\textquotedblleft{}chain\textquotedblright{}\mdline{6525} of \mdline{6525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6525} and/or \mdline{6525}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}typedef}}}\mdline{6525} that eventually ends with +one of the types above)%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6528} +\item{} +%mdk-data-line={6528} +\mdline{6528}Support for PSA Random \mdline{6528}\&\mdline{6528} Timestamp externs is postponed to a future minor +version update.%mdk%mdk + +%mdk-data-line={6531} +\item{} +%mdk-data-line={6531} +\mdline{6531}P4Info does not include information about which of a table\mdline{6531}'\mdline{6531}s actions execute +which direct resource(s).%mdk%mdk + +%mdk-data-line={6534} +\item{} +%mdk-data-line={6534} +\mdline{6534}The default action for indirect match tables is restricted to a \mdline{6534}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}const\\ +NoAction}}}\mdline{6535} known at compile-time.%mdk%mdk + +%mdk-data-line={6537} +\item{} +%mdk-data-line={6537} +\mdline{6537}There is no mechanism for changing the value of the \mdline{6537}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}psa\_empty\_group\_action}}}\mdline{6537} +table property at runtime.%mdk%mdk + +%mdk-data-line={6540} +\item{} +%mdk-data-line={6540} +\mdline{6540}There is no RPC to query the capabilities of a given P4Runtime implementation; +in particular, there is no way for a client to query the supported minor\mdline{6541} \mdline{6541}+ +patch version numbers.%mdk%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6544} +\section{\mdline{6544}A.\hspace*{0.5em}\mdline{6544}Appendix}\label{sec-appendix}%mdk%mdk + +%mdk-data-line={6546} +\subsection{\mdline{6546}A.1.\hspace*{0.5em}\mdline{6546}Revision History}\label{sec-revision-history}%mdk%mdk + +%mdk-data-line={6548} +\subsubsection{\mdline{6548}A.1.1.\hspace*{0.5em}\mdline{6548}Changes in v1.4.0}\label{sec-changes-in-v140}%mdk%mdk + +%mdk-data-line={6550} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6550} +\item\mdline{6550}Add a \mdline{6550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Type}}}\mdline{6550} field to the \mdline{6550}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{6550} message allowing users to restrict the +type of meters that can be used for a table and a new \mdline{6551}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}eburst}}}\mdline{6551} field to the +\mdline{6552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterConfig}}}\mdline{6552} message for use with one of the new \mdline{6552}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MeterSpec}}}\mdline{6552} types.%mdk + +%mdk-data-line={6553} +\item\mdline{6553}Add a \mdline{6553}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PlatformProperties}}}\mdline{6553} message specifying desired underlying platform +properties to the \mdline{6554}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}PkgInfo}}}\mdline{6554} message.%mdk + +%mdk-data-line={6555} +\item\mdline{6555}Add a \mdline{6555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6555} field to the \mdline{6555}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}MulticastGroupEntry}}}\mdline{6555} message.%mdk + +%mdk-data-line={6556} +\item\mdline{6556}Clarify that the limitation on supported types for \mdline{6556}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6556}, action +\mdline{6557}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6557}, and Packet IO metadata fields (no support for signed integers, with +type \mdline{6558}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}int\textless{}W\textgreater{}}}}\mdline{6558}) apply to all minor revisions of P4Runtime v1, not just to +P4Runtime v1.0.%mdk + +%mdk-data-line={6560} +\item\mdline{6560}Fix invalid \mdline{6560}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}action\_profile\_id}}}\mdline{6560} in the One Shot Action Selector Programming +example.%mdk + +%mdk-data-line={6562} +\item\mdline{6562}Specify Read behavior in the absence of a P4Info (\mdline{6562}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ForwardingPipelineConfig}}}\mdline{6562} +not set yet).%mdk + +%mdk-data-line={6564} +\item\mdline{6564}Clarify that for updates of type \mdline{6564}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{6564}, error codes other than +\mdline{6565}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6565} can be returned when applicable.%mdk + +%mdk-data-line={6566} +\item\mdline{6566}Enable C++ Arena Allocation\mdline{6566}~[\mdcite{arenaallocation}{4}]\mdline{6566} by default in p4runtime.proto.%mdk + +%mdk-data-line={6567} +\item\mdline{6567}Add support for string role identifiers and deprecate integer role +identifiers.%mdk + +%mdk-data-line={6569} +\item\mdline{6569}Add support for specifying a role in \mdline{6569}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ReadRequest}}}\mdline{6569} messages: if present, only +entities belonging to this specific role are returned.%mdk + +%mdk-data-line={6571} +\item\mdline{6571}Specify that \mdline{6571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}max\_group\_size}}}\mdline{6571} must be less than or equal to \mdline{6571}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}size}}}\mdline{6571} for Action +Selectors.%mdk + +%mdk-data-line={6573} +\item\mdline{6573}Simplify specification for arbitration updates for which there is no change to +the controller\mdline{6574}'\mdline{6574}s \mdline{6574}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{6574}; in particular, a \mdline{6574}\textquotedblleft{}no-op\textquotedblright{}\mdline{6574} arbitration update +from a primary controller (the controller already was, and remains, the +primary controller) is essentially treated the same way as an arbitration +update which leads to the election of a new primary controller.%mdk + +%mdk-data-line={6578} +\item\mdline{6578}Enable P4Runtime servers to provide per-color counter values when direct or +indirect meter entries are read.%mdk + +%mdk-data-line={6580} +\item\mdline{6580}Clarify that the (\mdline{6580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}device\_id}}}\mdline{6580}, \mdline{6580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}role}}}\mdline{6580}, \mdline{6580}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}election\_id}}}\mdline{6580}) 3-tuples are only unique +for live controllers.%mdk + +%mdk-data-line={6582} +\item\mdline{6582}Add a \mdline{6582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}selector\_size\_semantics}}}\mdline{6582} field to the \mdline{6582}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}ActionProfile}}}\mdline{6582} message +in P4Info.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6585} +\subsubsection{\mdline{6585}A.1.2.\hspace*{0.5em}\mdline{6585}Changes in v1.3.0}\label{sec-changes-in-v130}%mdk%mdk + +%mdk-data-line={6587} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6587} +\item\mdline{6587}Add IANA assigned TCP port, 9559, to P4Runtime server discussion.%mdk + +%mdk-data-line={6588} +\item\mdline{6588}Move \mdline{6588}\textquotedblleft{}Security considerations\textquotedblright{}\mdline{6588} section to P4Runtime server discussion.%mdk + +%mdk-data-line={6589} +\item\mdline{6589}Deprecate \mdline{6589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch}}}\mdline{6589} field (int32) in favor of \mdline{6589}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}watch\_port}}}\mdline{6589} (bytes). This allows +using the watch port feature with the \mdline{6590}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4runtime\_translation}}}\mdline{6590} feature.%mdk + +%mdk-data-line={6591} +\item\mdline{6591}Replace master, slave, master arbitration with more inclusive language: +primary, backup, and client arbitration%mdk + +%mdk-data-line={6593} +\item\mdline{6593}Clarify that source locations for annotations are optional in the P4Info +message.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6596} +\subsubsection{\mdline{6596}A.1.3.\hspace*{0.5em}\mdline{6596}Changes in v1.2.0}\label{sec-changes-in-v120}%mdk%mdk + +%mdk-data-line={6598} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6598} +\item\mdline{6598}Add new \mdline{6598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6598} match kind. At the moment, \mdline{6598}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}OPTIONAL}}}\mdline{6598} is only supported by +the v1model architecture\mdline{6599}~[\mdcite{v1model}{44}]\mdline{6599}, and not by PSA. It will eventually be +included in the core P4 language.%mdk + +%mdk-data-line={6601} +\item\mdline{6601}Add support in P4Info for structured annotations, which are used to annotate +objects with key-value lists or expression lists.%mdk + +%mdk-data-line={6603} +\item\mdline{6603}Add a new \mdline{6603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}metadata}}}\mdline{6603} field of type \mdline{6603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}bytes}}}\mdline{6603} to \mdline{6603}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{6603}. This is more +flexible than the now deprecated \mdline{6604}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}controller\_metadata}}}\mdline{6604} field.%mdk + +%mdk-data-line={6605} +\item\mdline{6605}Add the ability to change the ID of table match fields, action parameters, +Packet IO metadata fields, and Value Set match fields in P4Info by using the +\mdline{6607}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6607} annotation.%mdk + +%mdk-data-line={6608} +\item\mdline{6608}Clarify the behavior of some corner cases involving action profiles and +selectors, including the watch port feature.%mdk + +%mdk-data-line={6610} +\item\mdline{6610}Support using \mdline{6610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}string}}}\mdline{6610} as the controller type in the \mdline{6610}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6610} +annotation. Update syntax when using a fixed-width unsigned bitstring as the +controller type.%mdk + +%mdk-data-line={6613} +\item\mdline{6613}Add optional P4 source locations to both structured and unstructured +annotations.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6616} +\subsubsection{\mdline{6616}A.1.4.\hspace*{0.5em}\mdline{6616}Changes in v1.1.0}\label{sec-changes-in-v110}%mdk%mdk + +%mdk-data-line={6618} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6618} +\item\mdline{6618}Major overhaul of master-arbitration: while the Protobuf messages did not +change, the state machine that the server needs to implement is significantly +different. Upon the master disconnection, the server no longer chooses the +controller with the second highest election id as the new master. Instead, +there will not be a new master until one of the controllers advertises an +election id higher than any election id seen previously.%mdk + +%mdk-data-line={6624} +\item\mdline{6624}Add \mdline{6624}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}error}}}\mdline{6624} field to stream messages sent by the server.%mdk + +%mdk-data-line={6625} +\item\mdline{6625}Add \mdline{6625}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Capabilities}}}\mdline{6625} RPC to query the P4Runtime API version implemented by the +server.%mdk + +%mdk-data-line={6627} +\item\mdline{6627}Support wildcard reads for multicast groups and clone sessions.%mdk + +%mdk-data-line={6628} +\item\mdline{6628}Support for modifying direct resources of const tables.%mdk + +%mdk-data-line={6629} +\item\mdline{6629}Support P4 user-defined types for Packet IO metadata fields.%mdk + +%mdk-data-line={6630} +\item\mdline{6630}Clarify consistency requirements for \mdline{6630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6630} and \mdline{6630}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Read}}}\mdline{6630} RPCs.%mdk + +%mdk-data-line={6631} +\item\mdline{6631}Add Appendix providing implementation advice for avoiding common pitfalls: + +%mdk-data-line={6632} +\begin{itemize}[noitemsep,topsep=\mdcompacttopsep]%mdk + +%mdk-data-line={6632} +\item\mdline{6632}advice on setting gRPC Metadata Maximum Size%mdk + +%mdk-data-line={6633} +\item\mdline{6633}advice on setting gRPC Server Maximum Receive Message Size%mdk +%mdk +\end{itemize}%mdk%mdk + +%mdk-data-line={6634} +\item\mdline{6634}Clarify limitations on supported types for \mdline{6634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}FieldMatch}}}\mdline{6634}, action \mdline{6634}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Param}}}\mdline{6634}, and +Packet IO metadata fields.%mdk + +%mdk-data-line={6636} +\item\mdline{6636}Clarify that reading entire forwarding state with empty \mdline{6636}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{6636} is not +supported.%mdk + +%mdk-data-line={6638} +\item\mdline{6638}Document that \mdline{6638}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6638} need only be supported when applied to +type declarations in P4.%mdk +%mdk +\end{itemize}%mdk + +%mdk-data-line={6641} +\subsection{\mdline{6641}A.2.\hspace*{0.5em}\mdline{6641}P4 Annotations}\label{sec-p4-annotations}%mdk%mdk + +%mdk-data-line={6643} +\noindent\mdline{6643}Table\mdline{6643}~\mdref{tab-p4-annotations}{\mdcaptionlabel{7}}\mdline{6643} lists P4\mdline{6643}\mdsub{16}\mdline{6643} annotations introduced primarily for +the purpose of adding features for the P4Runtime API.%mdk + +%mdk-data-line={6646} +\begin{table}[h!]%mdk +\begin{mdcenter}%mdk +\begin{mdtabular}{2}{\dimeval{(\linewidth)/2}}{1ex}%mdk +\begin{tabular}{ll}\midrule +\multicolumn{1}{|c}{{\bfseries\mdline{6648} Annotation}}&\multicolumn{1}{|c|}{{\bfseries\mdline{6648} Description}}\\ + +\midrule +\multicolumn{1}{|l}{\mdline{6650} \mdline{6650}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@brief}}}\mdline{6650}}&\multicolumn{1}{|l|}{\mdline{6650} See section\mdline{6650}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6650}}\\ +\multicolumn{1}{|l}{\mdline{6651} \mdline{6651}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@controller\_header}}}\mdline{6651}}&\multicolumn{1}{|l|}{\mdline{6651} See section\mdline{6651}~\mdref{sec-controller-packet-meta}{6.4.6}\mdline{6651}}\\ +\multicolumn{1}{|l}{\mdline{6652} \mdline{6652}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@description}}}\mdline{6652}}&\multicolumn{1}{|l|}{\mdline{6652} See section\mdline{6652}~\mdref{sec-annotating-p4-entities-with-documentation}{6.1.3}\mdline{6652}}\\ +\multicolumn{1}{|l}{\mdline{6653} \mdline{6653}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@id}}}\mdline{6653}}&\multicolumn{1}{|l|}{\mdline{6653} See section\mdline{6653}~\mdref{sec-id-allocation}{6.3}\mdline{6653}}\\ +\multicolumn{1}{|l}{\mdline{6654} \mdline{6654}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_group\_size}}}\mdline{6654}}&\multicolumn{1}{|l|}{\mdline{6654} See sections\mdline{6654}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{6654},\mdline{6654}~\mdref{sec-action-profile-group-programming}{9.2.2}\mdline{6654}}\\ +\multicolumn{1}{|l}{\mdline{6655} \mdline{6655}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@selector\_size\_semantics}}}\mdline{6655}}&\multicolumn{1}{|l|}{\mdline{6655} See section\mdline{6655}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{6655}}\\ +\multicolumn{1}{|l}{\mdline{6656} \mdline{6656}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@max\_member\_weight}}}\mdline{6656}}&\multicolumn{1}{|l|}{\mdline{6656} See section\mdline{6656}~\mdref{sec-p4info-action-profile}{6.4.3}\mdline{6656}}\\ +\multicolumn{1}{|l}{\mdline{6657} \mdline{6657}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@two\_rate\_three\_color}}}\mdline{6657}}&\multicolumn{1}{|l|}{\mdline{6657} See section\mdline{6657}~\mdref{sec-meter-directmeter}{6.4.5}\mdline{6657}}\\ +\multicolumn{1}{|l}{\mdline{6658} \mdline{6658}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@single\_rate\_three\_color}}}\mdline{6658}}&\multicolumn{1}{|l|}{\mdline{6658} See section\mdline{6658}~\mdref{sec-meter-directmeter}{6.4.5}\mdline{6658}}\\ +\multicolumn{1}{|l}{\mdline{6659} \mdline{6659}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@single\_rate\_two\_color}}}\mdline{6659}}&\multicolumn{1}{|l|}{\mdline{6659} See section\mdline{6659}~\mdref{sec-meter-directmeter}{6.4.5}\mdline{6659}}\\ +\multicolumn{1}{|l}{\mdline{6660} \mdline{6660}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@pkginfo}}}\mdline{6660}}&\multicolumn{1}{|l|}{\mdline{6660} See section\mdline{6660}~\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1}\mdline{6660}}\\ +\multicolumn{1}{|l}{\mdline{6661} \mdline{6661}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@platform\_property}}}\mdline{6661}}&\multicolumn{1}{|l|}{\mdline{6661} See section\mdline{6661}~\mdref{sec-annotating-p4-code-with-pkginfo}{6.2.1}\mdline{6661}}\\ +\multicolumn{1}{|l}{\mdline{6662} \mdline{6662}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}@p4runtime\_translation}}}\mdline{6662}}&\multicolumn{1}{|l|}{\mdline{6662} See sections\mdline{6662}~\mdref{sec-user-defined-types}{8.4.6}\mdline{6662},\mdline{6662}~\mdref{sec-translation-of-port-numbers}{18.1.1}\mdline{6662}}\\ +\midrule +\end{tabular}\end{mdtabular} + +%mdk-data-line={6664} +\mdhr{}%mdk + +%mdk-data-line={6665} +\noindent\mdline{6665}\mdcaption{\textbf{Table~\mdcaptionlabel{7}.}~\mdcaptiontext{P4 annotations introduced by P4Runtime}}%mdk +%mdk +\end{mdcenter}\label{tab-p4-annotations}%mdk +%mdk +\end{table}%mdk + +%mdk-data-line={6668} +\subsection{\mdline{6668}A.3.\hspace*{0.5em}\mdline{6668}A More Complex Value Set Example}\label{sec-value-set-example}%mdk%mdk + +%mdk-data-line={6670} +\noindent\mdline{6670}This section includes a more complex Value Set example, with multiple matches of +different kinds.%mdk + +%mdk-data-line={6673} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#FFFFDD,breakable=true}%mdk +%mdk-data-line={6674} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}struct}}~match\_t~\{\\ +~~{\bfseries{\mdcolor{navy}bit}}\textless{}{\mdcolor{purple}8}\textgreater{}~f8;\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(ternary)~bit\textless{}16\textgreater{}~f16;}\\ +{\mdcolor{gray}~~@}{\mdcolor{gray}match}{\mdcolor{maroon}(custom)~bit\textless{}32\textgreater{}~f32;}\\ +\}\\ +{\mdcolor{gray}@}{\mdcolor{gray}id}{\mdcolor{maroon}(1)~value\_set\textless{}match\_t\textgreater{}(4)~pvs;}\\ +{\bfseries{\mdcolor{navy}select}}~(\{~hdr.f8,~hdr.f16,~hdr.f32~\})~\{~{\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}~...~}{\mdcolor{darkgreen}*/}~\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6683} +\noindent\mdline{6683}This P4 Value Set declaration will translate into the following entry in the +P4Info messsage:%mdk + +%mdk-data-line={6686} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6687} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}value\_sets~\{\\ +~~preamble~\{\\ +~~~~id:~{\mdcolor{purple}0x03000001}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}pvs}{\mdcolor{maroon}"}\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}1}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f8}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}8}\\ +~~~~match\_type:~EXACT\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}2}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f16}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}16}\\ +~~~~match\_type:~TERNARY\\ +~~\}\\ +~~match~\{\\ +~~~~id:~{\mdcolor{purple}3}\\ +~~~~name:~{\mdcolor{maroon}"}{\mdcolor{maroon}f32}{\mdcolor{maroon}"}\\ +~~~~bitwidth:~{\mdcolor{purple}32}\\ +~~~~other\_match\_type:~{\mdcolor{maroon}"}{\mdcolor{maroon}custom}{\mdcolor{maroon}"}\\ +~~\}\\ +~~size:~{\mdcolor{purple}4}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6714} +\noindent\mdline{6714}A P4Runtime client can set the membership for this Value Set with \mdline{6714}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6714} +messages similar to this one:%mdk + +%mdk-data-line={6717} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E6FFFF,breakable=true}%mdk +%mdk-data-line={6718} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type:~MODIFY\\ +entity~\{\\ +~~value\_set\_entry~\{\\ +~~~~value\_set\_id:~{\mdcolor{purple}0x03000001}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xac}~\}\\ +~~~~~~\}\\ +~~~~~~{\mdcolor{darkgreen}\#~match~for~field\_id~2~is~missing~=\textgreater{}~don't~care~match}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~~~members~\{\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}1}\\ +~~~~~~~~exact~\{~value:~{\mdcolor{purple}0xdc}~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}2}\\ +~~~~~~~~ternary~\{~value:~{\mdcolor{purple}0x88}~mask:~{\mdcolor{purple}8}f~\}\\ +~~~~~~\}\\ +~~~~~~match~\{\\ +~~~~~~~~field\_id:~{\mdcolor{purple}3}\\ +~~~~~~~~other~\{~...~\}~~{\mdcolor{darkgreen}\#~some~serialized~Any~message~(architecture-specific)}\\ +~~~~~~\}\\ +~~~~\}\\ +~~\}\\ +\}}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6752} +\subsection{\mdline{6752}A.4.\hspace*{0.5em}\mdline{6752}Guidelines for Implementations}\label{sec-guidelines-for-implementations}%mdk%mdk + +%mdk-data-line={6754} +\noindent\mdline{6754}This section contains practical advice for implementing P4Runtime clients and +servers.%mdk + +%mdk-data-line={6757} +\subsubsection{\mdline{6757}A.4.1.\hspace*{0.5em}\mdline{6757}gRPC Metadata Maximum Size}\label{sec-grpc-metadata-maximum-size}%mdk%mdk + +%mdk-data-line={6759} +\noindent\mdline{6759}In gRPC, the status of a RPC request is sent as metadata, whose size is limited +by the \mdline{6760}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6760} gRPC channel argument. By default, this limit +is 8KB, which can be a problem for the \mdline{6761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6761} P4Runtime RPC. The \mdline{6761}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6761} RPC +returns an individual error for every item in a batch (see Section +\mdline{6763}\mdref{sec-write-rpc}{12}\mdline{6763}), which can quickly result in a status size over 8KB. In that +case, the gRPC server would not send the status, but instead send a +\mdline{6765}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}RESOURCE\_EXHAUSTED}}}\mdline{6765} error, without any of the individual errors.%mdk + +%mdk-data-line={6767} +\mdline{6767}To fix this problem, one can set the \mdline{6767}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_metadata\_size}}}\mdline{6767} option on the +client channel. This allows the client to receive more than 8KB of metadata, +based on the new limit. Note that the gRPC server does not have to change it\mdline{6769}'\mdline{6769}s +limit, as only the receiving side\mdline{6770}'\mdline{6770}s limit is relevant. The exact limit that is +required depends on the maximum batch size, the length of error messages inside +every \mdline{6772}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4.Error}}}\mdline{6772}, as well as any other metadata that is being sent over the gRPC +channel. As a rule of thumb, it might make sense to allow for at least +\mdline{6774}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}8192~+~MAX\_UPDATES\_PER\_WRITE~*~100}}}\mdline{6774} bytes of metadata.%mdk + +%mdk-data-line={6776} +\mdline{6776}For example, in C++, one can create a client channel as follows:%mdk + +%mdk-data-line={6777} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6778} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}~=~{\mdcolor{purple}100};\\ +::{\mdcolor{navy}grpc::}ChannelArguments~arguments;\\ +arguments{\bfseries{\mdcolor{navy}.}}SetInt({\mdcolor{teal}GRPC\_ARG\_MAX\_METADATA\_SIZE},~{\mdcolor{purple}8192}~+~{\mdcolor{teal}MAX\_UPDATES\_PER\_WRITE}*{\mdcolor{purple}100});\\ +{\bfseries{\mdcolor{navy}return}}~{\mdcolor{navy}grpc::}CreateCustomChannel(address,~credentials,~arguments);}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6784} +\subsubsection{\mdline{6784}A.4.2.\hspace*{0.5em}\mdline{6784}gRPC Server Maximum Receive Message Size}\label{sec-grpc-server-maximum-receive-message-size}%mdk%mdk + +%mdk-data-line={6786} +\noindent\mdline{6786}At the time of writing, the default maximum receive message size in gRPC is 4MB +\mdline{6787}\textemdash{}\mdline{6787} while the default maximum send message size is unlimited. This can be a +problem for the \mdline{6788}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}SetForwardingPipelineConfig}}}\mdline{6788} RPC, since for some targets the +binary \mdline{6789}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6789} can exceed 4MB, in which case by default the P4Runtime +server would return an \mdline{6790}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INVALID\_ARGUMENT}}}\mdline{6790} error. To a lesser extent, this may +affect the \mdline{6791}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6791} RPC as well, in case of extremely large batches.%mdk + +%mdk-data-line={6793} +\mdline{6793}To fix this problem, we recommend that vendors implementing a P4Runtime server +ensure that the maximum receive message size be large enough to accomodate all +possible values of \mdline{6795}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4\_device\_config}}}\mdline{6795} for their target(s). This can be done by +setting the \mdline{6796}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}grpc.max\_receive\_message\_length}}}\mdline{6796} when building the gRPC server.%mdk + +%mdk-data-line={6798} +\mdline{6798}For example, in C++, one can set the maximum receive message size as follows:%mdk + +%mdk-data-line={6799} +\begin{mdbmargintb}{6pt}{6pt}%mdk +\begin{mdblock}{padding=6pt,border-width=0.5pt,border-style=solid,background-color=\#E9FCE9,breakable=true}%mdk +%mdk-data-line={6800} +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}{\bfseries{\mdcolor{navy}const}}~{\bfseries{\mdcolor{navy}int}}~{\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE}~=~{\mdcolor{purple}128}~*~{\mdcolor{purple}1024}~*~{\mdcolor{purple}1024};~~{\mdcolor{darkgreen}//~128MB}\\ +::{\mdcolor{navy}grpc::}ServerBuilder~server\_builder;\\ +builder{\bfseries{\mdcolor{navy}.}}AddListeningPort({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});\\ +builder{\bfseries{\mdcolor{navy}.}}RegisterService({\mdcolor{darkgreen}/*}{\mdcolor{darkgreen}...}{\mdcolor{darkgreen}*/});~~{\mdcolor{darkgreen}//~register~P4Runtime~service}\\ +builder{\bfseries{\mdcolor{navy}.}}SetMaxReceiveMessageSize({\mdcolor{teal}MAX\_RECEIVE\_MESSAGE\_SIZE});\\ +builder{\bfseries{\mdcolor{navy}.}}BuildAndStart();}}%mdk +\end{mdpre}%mdk%mdk +\end{mdblock}%mdk +\end{mdbmargintb}%mdk + +%mdk-data-line={6808} +\noindent\mdline{6808}On the client side, we recommend that P4Runtime clients do not use \mdline{6808}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Write}}}\mdline{6808} +batches larger than the default maximum receive message size (4MB)\mdline{6809} \mdline{6809}\textemdash{}\mdline{6809} in case +the server did not deem necessary to increase the default value\mdline{6810} \mdline{6810}\textemdash{}\mdline{6810}, unless the +clients are aware that the server is using a larger maximum receive message +size. The gRPC server running the P4Runtime service must not set the maximum +receive message size to a value smaller than the default (4MB).%mdk + +%mdk-data-line={6815} +\subsection{\mdline{6815}A.5.\hspace*{0.5em}\mdline{6815}P4Runtime Entries files}\label{sec-entries-files}%mdk%mdk + +%mdk-data-line={6817} +\noindent\mdline{6817}The open source P4 compiler \mdline{6817}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{6817}~[\mdcite{p4c}{15}]\mdline{6817} implements an option to +generate an \mdline{6818}\textquotedblleft{}entries file\textquotedblright{}\mdline{6818}, \mdline{6818}i.e.\mdline{6818} a file that contains all table +entries declared via the \mdline{6819}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{6819} table property within the program.%mdk + +%mdk-data-line={6821} +\mdline{6821}An example P4\mdline{6821}\mdsub{16}\mdline{6821} program that can be used to demonstrate this +capability is \mdline{6822}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}table-entries-ternary-bmv2.p4}}}\mdline{6822}~[\mdcite{p4ctestprogramforconstentries}{16}]\mdline{6822}:%mdk +\begin{mdpre}%mdk +\noindent{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}git~clone~https://github.com/p4lang/p4c\\ +cd~p4c/testdata/p4\_16\_samples\\ +mkdir~tmp\\ +p4test~--arch~v1model~\textbackslash{}\\ +\preindent{4}--p4runtime-files~tmp/p4info.txt~\textbackslash{}\\ +\preindent{4}--p4runtime-entries-files~tmp/entries.txt~\textbackslash{}\\ +\preindent{4}table-entries-ternary-bmv2.p4}}%mdk +\end{mdpre}\noindent\mdline{6832}You can replace the \mdline{6832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}.txt}}}\mdline{6832} suffix of the file name \mdline{6832}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}tmp/entries.txt}}}\mdline{6832} +in the example command above with \mdline{6833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}.json}}}\mdline{6833} or \mdline{6833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}.bin}}}\mdline{6833}. The \mdline{6833}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}.bin}}}\mdline{6833} +format is a binary P4Runtime API protobuf message format. The \mdline{6834}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}.txt}}}\mdline{6834} +format is the text encoding of the same Protobuf messages. + +%mdk-data-line={6837} +\mdline{6837}Target devices are \mdline{6837}\emph{not}\mdline{6837} required to use this file. For example, if a +target has a P4 compiler back end that encodes all of the necessary +details from the P4 source program, including the \mdline{6839}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{6839} of tables, +in a target-specific binary format, then that target might have no +reason to generate these entries files.%mdk + +%mdk-data-line={6843} +\mdline{6843}Some target devices might choose to generate entries files, and also +to require doing so in order to have a correct implementation. For +example, a target runtime implementation might take a target-specific +binary format for the compiled P4 program that does \mdline{6846}\emph{not}\mdline{6846} contain any +data describing the \mdline{6847}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{6847} of tables, plus the entries file +generated by \mdline{6848}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}p4c}}}\mdline{6848}, and use the entries file to load the initial +entries of tables into the device.%mdk + +%mdk-data-line={6851} +\mdline{6851}The format of the entries file is a single \mdline{6851}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6851} message +containing one \mdline{6852}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{6852} sub-message per entry in the P4 source program +defined via an \mdline{6853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entries}}}\mdline{6853} table property. All \mdline{6853}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}Update}}}\mdline{6853} sub-messages +have \mdline{6854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}type}}}\mdline{6854} equal to \mdline{6854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}INSERT}}}\mdline{6854}, and \mdline{6854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}entity}}}\mdline{6854} is a \mdline{6854}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}TableEntry}}}\mdline{6854} message +containing the data for one table entry.%mdk + +%mdk-data-line={6857} +\mdline{6857}Note that if a P4Runtime client attempted to send a \mdline{6857}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}WriteRequest}}}\mdline{6857} to +a P4Runtime server with the contents of the entries file, the server +must return an error for each entry that has \mdline{6859}\mdcode{{\mdfontfamily{LuxiMono}{\mdfontsize{\dimfont{0.75}}is\_const}}}\mdline{6859} true, as +described in Section\mdline{6860}~\mdref{sec-table-entry}{9.1}\mdline{6860}.%mdk + +%mdk-data-line={6862;build/P4Runtime-Spec-bib.bbl.mdk:1} +%mdk-data-line={6862;build/P4Runtime-Spec-bib.bbl.mdk:2} +\mdsetrefname{References}%mdk +{\mdbibindent{0}%mdk +\begin{thebibliography}{45}%mdk +\label{sec-bibliography}%mdk + +%mdk-data-line={references.bib:78} +\bibitem{p4spec}\mdbibitemlabel{{}[1]}\textquotedblleft{}$P4_{16}$ 1.2.1 Specification.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html}}.\label{p4spec}%mdk%mdk + +%mdk-data-line={references.bib:154} +\bibitem{rfc2697}\mdbibitemlabel{{}[2]}\textquotedblleft{}A Single Rate Three Color Marker.\textquotedblright{} \href{https://tools.ietf.org/html/rfc2697}{{\ttfamily https://\hspace{0pt}tools.\hspace{0pt}ietf.\hspace{0pt}org/\hspace{0pt}html/\hspace{0pt}rfc2697}}.\label{rfc2697}%mdk%mdk + +%mdk-data-line={references.bib:149} +\bibitem{rfc2698}\mdbibitemlabel{{}[3]}\textquotedblleft{}A Two Rate Three Color Marker.\textquotedblright{} \href{https://tools.ietf.org/html/rfc2698}{{\ttfamily https://\hspace{0pt}tools.\hspace{0pt}ietf.\hspace{0pt}org/\hspace{0pt}html/\hspace{0pt}rfc2698}}.\label{rfc2698}%mdk%mdk + +%mdk-data-line={references.bib:224} +\bibitem{arenaallocation}\mdbibitemlabel{{}[4]}\textquotedblleft{}C++ Arena Allocation Guide.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/reference/arenas}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}reference/\hspace{0pt}arenas}}.\label{arenaallocation}%mdk%mdk + +%mdk-data-line={references.bib:32} +\bibitem{p4complextypes}\mdbibitemlabel{{}[5]}\textquotedblleft{}Complex Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-p4-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}p4-\hspace{0pt}type}}.\label{p4complextypes}%mdk%mdk + +%mdk-data-line={references.bib:37} +\bibitem{protodefaults}\mdbibitemlabel{{}[6]}\textquotedblleft{}Default Values for Protobuf 3 ($proto3$) Fields.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23default}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}default}}.\label{protodefaults}%mdk%mdk + +%mdk-data-line={references.bib:93} +\bibitem{p4enums}\mdbibitemlabel{{}[7]}\textquotedblleft{}Enums in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-enum-types}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}enum-\hspace{0pt}types}}.\label{p4enums}%mdk%mdk + +%mdk-data-line={references.bib:134} +\bibitem{apiversioning}\mdbibitemlabel{{}[8]}\textquotedblleft{}Google Cloud APIs Versioning.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning}}.\label{apiversioning}%mdk%mdk + +%mdk-data-line={references.bib:139} +\bibitem{apiversioningbackwardscompatibility}\mdbibitemlabel{{}[9]}\textquotedblleft{}Google Cloud APIs Versioning - Backwards-Compatibility.\textquotedblright{} \href{https://cloud.google.com/apis/design/versioning\%23backwards_compatibility}{{\ttfamily https://\hspace{0pt}cloud.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}apis/\hspace{0pt}design/\hspace{0pt}versioning\#\hspace{0pt}backwards\_\hspace{0pt}compatibility}}.\label{apiversioningbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:169} +\bibitem{grpcauth}\mdbibitemlabel{{}[10]}\textquotedblleft{}gRPC Authentication.\textquotedblright{} \href{https://grpc.io/docs/guides/auth.html}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}guides/\hspace{0pt}auth.\hspace{0pt}html}}.\label{grpcauth}%mdk%mdk + +%mdk-data-line={references.bib:7} +\bibitem{grpc}\mdbibitemlabel{{}[11]}\textquotedblleft{}gRPC Main Site.\textquotedblright{} \href{https://grpc.io}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io}}.\label{grpc}%mdk%mdk + +%mdk-data-line={references.bib:164} +\bibitem{grpcstreamc}\mdbibitemlabel{{}[12]}\textquotedblleft{}gRPC Streaming RPCs in C++.\textquotedblright{} \href{https://grpc.io/docs/tutorials/basic/c.html\%23streaming-rpcs}{{\ttfamily https://\hspace{0pt}grpc.\hspace{0pt}io/\hspace{0pt}docs/\hspace{0pt}tutorials/\hspace{0pt}basic/\hspace{0pt}c.\hspace{0pt}html\#\hspace{0pt}streaming-\hspace{0pt}rpcs}}.\label{grpcstreamc}%mdk%mdk + +%mdk-data-line={references.bib:129} +\bibitem{p4newtypes}\mdbibitemlabel{{}[13]}\textquotedblleft{}Introducing New Types in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-newtype}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}newtype}}.\label{p4newtypes}%mdk%mdk + +%mdk-data-line={references.bib:159} +\bibitem{p4matchtypes}\mdbibitemlabel{{}[14]}\textquotedblleft{}Match Types in P4.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-match-kind-type}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}match-\hspace{0pt}kind-\hspace{0pt}type}}.\label{p4matchtypes}%mdk%mdk + +%mdk-data-line={references.bib:229} +\bibitem{p4c}\mdbibitemlabel{{}[15]}\textquotedblleft{}P4\_16 Reference Compiler.\textquotedblright{} \href{https://github.com/p4lang/p4c}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4c}}.\label{p4c}%mdk%mdk + +%mdk-data-line={references.bib:234} +\bibitem{p4ctestprogramforconstentries}\mdbibitemlabel{{}[16]}\textquotedblleft{}P4\_16 Reference Compiler Test Program Table-Entries-Ternary-bmv2.p4.\textquotedblright{} \href{https://github.com/p4lang/p4c/blob/main/testdata/p4_16_samples/table-entries-ternary-bmv2.p4}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4c/\hspace{0pt}blob/\hspace{0pt}main/\hspace{0pt}testdata/\hspace{0pt}p4\_\hspace{0pt}16\_\hspace{0pt}samples/\hspace{0pt}table-\hspace{0pt}entries-\hspace{0pt}ternary-\hspace{0pt}bmv2.\hspace{0pt}p4}}.\label{p4ctestprogramforconstentries}%mdk%mdk + +%mdk-data-line={references.bib:214} +\bibitem{p4annotations}\mdbibitemlabel{{}[17]}\textquotedblleft{}P4 Annotations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-annotations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}annotations}}.\label{p4annotations}%mdk%mdk + +%mdk-data-line={references.bib:194} +\bibitem{p4concurrency}\mdbibitemlabel{{}[18]}\textquotedblleft{}P4 Concurrency Model.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-concurrency}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}concurrency}}.\label{p4concurrency}%mdk%mdk + +%mdk-data-line={references.bib:1} +\bibitem{p4runtimerepo}\mdbibitemlabel{{}[19]}\textquotedblleft{}p4lang/p4Runtime repository:P4Runtime Protobuf Definition Files and Specification.\textquotedblright{} \href{https://github.com/p4lang/p4runtime}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4runtime}}.\label{p4runtimerepo}%mdk%mdk + +%mdk-data-line={references.bib:42} +\bibitem{pirepo}\mdbibitemlabel{{}[20]}\textquotedblleft{}p4lang/PI repository:Legacy Repository for P4Runtime, Includes Reference Implementation.\textquotedblright{} \href{https://github.com/p4lang/PI}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}PI}}.\label{pirepo}%mdk%mdk + +%mdk-data-line={references.bib:124} +\bibitem{p4apiwgcharter}\mdbibitemlabel{{}[21]}\textquotedblleft{}P4.org API Working Group Charter.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4_API_WG_charter.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4\_\hspace{0pt}API\_\hspace{0pt}WG\_\hspace{0pt}charter.\hspace{0pt}html}}.\label{p4apiwgcharter}%mdk%mdk + +%mdk-data-line={references.bib:174} +\bibitem{p4actionannotations}\mdbibitemlabel{{}[22]}\textquotedblleft{}P4 Standard Annotations on Table Actions.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-action-anno}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}action-\hspace{0pt}anno}}.\label{p4actionannotations}%mdk%mdk + +%mdk-data-line={references.bib:88} +\bibitem{pna}\mdbibitemlabel{{}[23]}\textquotedblleft{}Portable NIC Architecture Specification (v0.7).\textquotedblright{} \href{https://p4.org/p4-spec/docs/PNA-v0.7.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PNA-\hspace{0pt}v0.\hspace{0pt}7.\hspace{0pt}html}}.\label{pna}%mdk%mdk + +%mdk-data-line={references.bib:83} +\bibitem{psa}\mdbibitemlabel{{}[24]}\textquotedblleft{}Portable Switch Architecture Specification (v1.1.0).\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html}}.\label{psa}%mdk%mdk + +%mdk-data-line={references.bib:209} +\bibitem{protooneofbackwardscompatibility}\mdbibitemlabel{{}[25]}\textquotedblleft{}Protobuf OneOf Backwards-Compatibility Issues.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23backwards-compatibility-issues}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}backwards-\hspace{0pt}compatibility-\hspace{0pt}issues}}.\label{protooneofbackwardscompatibility}%mdk%mdk + +%mdk-data-line={references.bib:12} +\bibitem{proto}\mdbibitemlabel{{}[26]}\textquotedblleft{}Protocol Buffers Main Site.\textquotedblright{} \href{https://developers.google.com/protocol-buffers}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers}}.\label{proto}%mdk%mdk + +%mdk-data-line={references.bib:179} +\bibitem{psaactionselector}\mdbibitemlabel{{}[27]}\textquotedblleft{}PSA Action Selector.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-action-selector}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}action-\hspace{0pt}selector}}.\label{psaactionselector}%mdk%mdk + +%mdk-data-line={references.bib:189} +\bibitem{psaatomicityofcontrolplaneops}\mdbibitemlabel{{}[28]}\textquotedblleft{}PSA Atomicity of Control Plane Operations.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-atomicity-of-control-plane-api-operations}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}atomicity-\hspace{0pt}of-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}api-\hspace{0pt}operations}}.\label{psaatomicityofcontrolplaneops}%mdk%mdk + +%mdk-data-line={references.bib:199} +\bibitem{psatranslation}\mdbibitemlabel{{}[29]}\textquotedblleft{}PSA Data Plane vs Control Plane Types.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23sec-data-plane-vs-control-plane-values}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}data-\hspace{0pt}plane-\hspace{0pt}vs-\hspace{0pt}control-\hspace{0pt}plane-\hspace{0pt}values}}.\label{psatranslation}%mdk%mdk + +%mdk-data-line={references.bib:184} +\bibitem{psaemptygroupactionappendix}\mdbibitemlabel{{}[30]}\textquotedblleft{}PSA Empty Group Action Appendix.\textquotedblright{} \href{https://p4.org/p4-spec/docs/PSA-v1.1.0.html\%23appendix-empty-action-selector-groups}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}PSA-\hspace{0pt}v1.\hspace{0pt}1.\hspace{0pt}0.\hspace{0pt}html\#\hspace{0pt}appendix-\hspace{0pt}empty-\hspace{0pt}action-\hspace{0pt}selector-\hspace{0pt}groups}}.\label{psaemptygroupactionappendix}%mdk%mdk + +%mdk-data-line={references.bib:58} +\bibitem{p4selectexpr}\mdbibitemlabel{{}[31]}\textquotedblleft{}Select Expressions in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-select}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}select}}.\label{p4selectexpr}%mdk%mdk + +%mdk-data-line={references.bib:144} +\bibitem{semver}\mdbibitemlabel{{}[32]}\textquotedblleft{}Semantic Versioning.\textquotedblright{} \href{https://semver.org/}{{\ttfamily https://\hspace{0pt}semver.\hspace{0pt}org/\hspace{0pt}}}.\label{semver}%mdk%mdk + +%mdk-data-line={references.bib:113} +\bibitem{protostatus}\mdbibitemlabel{{}[33]}\textquotedblleft{}Status.proto:the Protobuf Status Message.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}src/\hspace{0pt}proto/\hspace{0pt}grpc/\hspace{0pt}status/\hspace{0pt}status.\hspace{0pt}proto}}.\label{protostatus}%mdk%mdk + +%mdk-data-line={references.bib:68} +\bibitem{p4revisions122}\mdbibitemlabel{{}[34]}\textquotedblleft{}Summary of Changes Made in $P4_{16}$ Version 1.2.2.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.4.html\%23sec-summary-of-changes-made-in-version-122-released-may-17-2021}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}4.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}summary-\hspace{0pt}of-\hspace{0pt}changes-\hspace{0pt}made-\hspace{0pt}in-\hspace{0pt}version-\hspace{0pt}122-\hspace{0pt}released-\hspace{0pt}may-\hspace{0pt}17-\hspace{0pt}2021}}.\label{p4revisions122}%mdk%mdk + +%mdk-data-line={references.bib:73} +\bibitem{p4revisions124}\mdbibitemlabel{{}[35]}\textquotedblleft{}Summary of Changes Made in $P4_{16}$ Version 1.2.4.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.4.html\%23sec-summary-of-changes-made-in-version-124}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}4.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}summary-\hspace{0pt}of-\hspace{0pt}changes-\hspace{0pt}made-\hspace{0pt}in-\hspace{0pt}version-\hspace{0pt}124}}.\label{p4revisions124}%mdk%mdk + +%mdk-data-line={references.bib:48} +\bibitem{p4tableproperties}\mdbibitemlabel{{}[36]}\textquotedblleft{}Table Properties in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-table-props}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}table-\hspace{0pt}props}}.\label{p4tableproperties}%mdk%mdk + +%mdk-data-line={references.bib:98} +\bibitem{protoany}\mdbibitemlabel{{}[37]}\textquotedblleft{}The Any Protobuf Message.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/proto3\%23any}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}proto3\#\hspace{0pt}any}}.\label{protoany}%mdk%mdk + +%mdk-data-line={references.bib:103} +\bibitem{grpcstatus}\mdbibitemlabel{{}[38]}\textquotedblleft{}The gRPC $Status$ Class.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/status.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}impl/\hspace{0pt}codegen/\hspace{0pt}status.\hspace{0pt}h}}.\label{grpcstatus}%mdk%mdk + +%mdk-data-line={references.bib:119} +\bibitem{grpcerrordetails}\mdbibitemlabel{{}[39]}\textquotedblleft{}The gRPC C++ Error Details Library.\textquotedblright{} \href{https://github.com/grpc/grpc/blob/master/include/grpcpp/support/error_details.h}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}grpc/\hspace{0pt}grpc/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}include/\hspace{0pt}grpcpp/\hspace{0pt}support/\hspace{0pt}error\_\hspace{0pt}details.\hspace{0pt}h}}.\label{grpcerrordetails}%mdk%mdk + +%mdk-data-line={references.bib:108} +\bibitem{grpcstatuscodes}\mdbibitemlabel{{}[40]}\textquotedblleft{}The gRPC Canonical Status Codes.\textquotedblright{} \href{https://developers.google.com/maps-booking/reference/grpc-api/status_codes}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}maps-\hspace{0pt}booking/\hspace{0pt}reference/\hspace{0pt}grpc-\hspace{0pt}api/\hspace{0pt}status\_\hspace{0pt}codes}}.\label{grpcstatuscodes}%mdk%mdk + +%mdk-data-line={references.bib:22} +\bibitem{openconfig}\mdbibitemlabel{{}[41]}\textquotedblleft{}The OpenConfig Project.\textquotedblright{} \href{http://openconfig.net}{{\ttfamily http://\hspace{0pt}openconfig.\hspace{0pt}net}}.\label{openconfig}%mdk%mdk + +%mdk-data-line={references.bib:204} +\bibitem{protomessagedifferencer}\mdbibitemlabel{{}[42]}\textquotedblleft{}The Protobuf MessageDifferencer in the C++ API.\textquotedblright{} \href{https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.util.message_differencer}{{\ttfamily https://\hspace{0pt}developers.\hspace{0pt}google.\hspace{0pt}com/\hspace{0pt}protocol-\hspace{0pt}buffers/\hspace{0pt}docs/\hspace{0pt}reference/\hspace{0pt}cpp/\hspace{0pt}google.\hspace{0pt}protobuf.\hspace{0pt}util.\hspace{0pt}message\_\hspace{0pt}differencer}}.\label{protomessagedifferencer}%mdk%mdk + +%mdk-data-line={references.bib:27} +\bibitem{stratum}\mdbibitemlabel{{}[43]}\textquotedblleft{}The Stratum Project.\textquotedblright{} \href{https://stratumproject.org/}{{\ttfamily https://\hspace{0pt}stratumproject.\hspace{0pt}org/\hspace{0pt}}}.\label{stratum}%mdk%mdk + +%mdk-data-line={references.bib:219} +\bibitem{v1model}\mdbibitemlabel{{}[44]}\textquotedblleft{}v1model Architecture Definition.\textquotedblright{} \href{https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4}{{\ttfamily https://\hspace{0pt}github.\hspace{0pt}com/\hspace{0pt}p4lang/\hspace{0pt}p4c/\hspace{0pt}blob/\hspace{0pt}master/\hspace{0pt}p4include/\hspace{0pt}v1model.\hspace{0pt}p4}}.\label{v1model}%mdk%mdk + +%mdk-data-line={references.bib:53} +\bibitem{p4valuesets}\mdbibitemlabel{{}[45]}\textquotedblleft{}Value Sets in $P4_{16}$.\textquotedblright{} \href{https://p4.org/p4-spec/docs/P4-16-v1.2.1.html\%23sec-value-set}{{\ttfamily https://\hspace{0pt}p4.\hspace{0pt}org/\hspace{0pt}p4-\hspace{0pt}spec/\hspace{0pt}docs/\hspace{0pt}P4-\hspace{0pt}16-\hspace{0pt}v1.\hspace{0pt}2.\hspace{0pt}1.\hspace{0pt}html\#\hspace{0pt}sec-\hspace{0pt}value-\hspace{0pt}set}}.\label{p4valuesets}%mdk%mdk +\par%mdk +\end{thebibliography}}%mdk%mdk +}%mdk + + +\end{document} diff --git a/spec/v1.4.0/ellipse.sty b/spec/v1.4.0/ellipse.sty new file mode 100644 index 00000000..7c0ecb3e --- /dev/null +++ b/spec/v1.4.0/ellipse.sty @@ -0,0 +1,318 @@ +%% +%% This is file `ellipse.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ellipse.dtx (with options: `package') +%% +%% Copyright (C) 2015 +%% Daan Leijen +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". +%% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{ellipse} + [2004/11/05 v1.0 .dtx ellipse file] +\RequirePackage{pict2e} + +\providecommand*\pIIe@csedef[1]{\expandafter\edef\csname #1\endcsname} +\newcommand*\pIIe@ellip@csqrt[3]{% + \@ovxx=#1\relax + \ifdim\@ovxx<\z@\@ovxx-\@ovxx\fi + \@ovyy=#2\relax + \ifdim\@ovyy<\z@\@ovyy-\@ovyy\fi + \edef\pIIe@csname{@csqrt(\number\@ovxx,\number\@ovyy)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@ellip@csqrt@% + \pIIe@csedef{\pIIe@csname}{\the\dimen@}% + #3\dimen@ + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} +\newcommand*\pIIe@ellip@csqrt@{% + \@ovdx\@ovxx + \advance\@ovdx by \@ovyy + \dimen@0.7071067\@ovdx + \ifdim\dimen@<\@ovyy\dimen@\@ovyy\fi + \ifdim\dimen@<\@ovxx\dimen@\@ovxx\fi + \ifdim\@ovdx<128\p@ + \edef\@tempa{\strip@pt\@ovxx}% + \@ovxx\@tempa\@ovxx + \edef\@tempa{\strip@pt\@ovyy}% + \@ovyy\@tempa\@ovyy + \advance\@ovxx by \@ovyy + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax + \divide\dimen@ by 2% + \fi +} + +\newcommand*\pIIe@atan@{% + \@tempdima\dimen@ + \@tempdimb\@tempdima + \ifdim\@tempdimb<\z@\@tempdimb-\@tempdimb\fi + \dimen@0.0663\@tempdimb + \advance\dimen@ 0.2447pt\relax + \advance\@tempdimb -1pt\relax + \edef\@tempa{\strip@pt\@tempdimb}% + \dimen@\@tempa\dimen@ + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \dimen@-\dimen@ + \advance\dimen@ 0.7853\@tempdima +} + +\newcommand*\pIIe@atantwo[3]{% + \edef\pIIe@csname{@atan2(\number\dimexpr#1\relax,\number\dimexpr#2\relax)}% + \expandafter\ifx\csname\pIIe@csname\endcsname\relax + \pIIe@atantwo@{#1}{#2}{#3}% + \pIIe@csedef{\pIIe@csname}{\the\dimexpr#3\relax}% + \else + #3\dimexpr\csname\pIIe@csname\endcsname\relax + \fi +} + +\newcommand*\pIIe@atantwo@[3]{% + \@tempdima\dimexpr#2\relax + \@tempdimb\dimexpr#1\relax + \ifdim\@tempdima=\z@\relax + \ifdim\@tempdimb>\z@\relax\dimen@90\p@ + \else\ifdim\@tempdimb<\z@\relax\dimen@-90\p@ + \else\dimen@0\p@ + \fi\fi + \else + \@tempdimd\z@ + \ifdim\@tempdima<\z@\relax + \ifdim\@tempdimb<\z@\relax\@tempdimd-180\p@ + \else\@tempdimd180\p@ + \fi + \fi + \dimen@\dimexpr1pt * \@tempdimb/\@tempdima\relax + \@tempdimc\dimen@ + \ifdim\@tempdimc<\z@\relax\@tempdimc-\@tempdimc\fi + \ifdim\@tempdimc>\p@\relax + \dimen@\dimexpr1pt * \@tempdima/\@tempdimb\relax + \ifdim\dimen@<\z@\relax\def\@tempsign{-}\else\def\@tempsign{}\fi + \pIIe@atan@ + \dimen@-\dimen@ + \advance\dimen@ by \@tempsign1.5707pt\relax + \else + \pIIe@atan@ + \fi + \dimen@57.29578\dimen@ + \advance\dimen@ by \@tempdimd + \fi + #3\dimen@% +} + +\newcommand*\pIIe@noneto[2]{} +\newcommand*\pIIe@ellip@sincost@[2]{% + \CalculateSin{#1}% + \CalculateCos{#1}% + \@tempdima\UseSin{#1}\p@ + \@tempdimb\UseCos{#1}\p@ + \ifdim\@tempdima=\p@\relax + \pIIe@csedef{@ellipsin#2}{1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else\ifdim\@tempdima=-\p@\relax + \pIIe@csedef{@ellipsin#2}{-1}% + \pIIe@csedef{@ellipcos#2}{0}% + \else + \@tempdimc\@ellipratio\dimexpr1pt * \@tempdima/\@tempdimb\relax + %\typeout{ i#2=\the\@tempdimc, sin(#1)=\the\@tempdima}% + \pIIe@ellip@csqrt{\p@}{\@tempdimc}\@tempdimd + \ifdim\@tempdimb<\z@\relax\@tempdimd-\@tempdimd\fi + \pIIe@csedef{@ellipsin#2}{\strip@pt\dimexpr1pt * \@tempdimc/\@tempdimd\relax}% + \pIIe@csedef{@ellipcos#2}{\strip@pt\dimexpr1pt * \p@/\@tempdimd\relax}% + \fi\fi +} + +\newcommand*\pIIe@ellip@sincost[2]{% + %\typeout{ calc sin cos: angles (#1,#2), radii: (\the\@ovro,\the\@ovri)}% + \edef\@ellipratio{\strip@pt\dimexpr1pt * \@ovro/\@ovri\relax}% + \pIIe@ellip@sincost@{#1}{one}% + \pIIe@ellip@sincost@{#2}{two}% + %\typeout{ sincos(a=#1)=(\@ellipsinone,\@ellipcosone), sincos(a=#2)=(\@ellipsintwo,\@ellipcostwo), }% +} +\newcommand*\pIIe@omega[3]{% + \@tempdima\csname @ellipcos#3\endcsname\@ovro + \advance\@tempdima by #1\relax + \@tempdimb\csname @ellipsin#3\endcsname\@ovri + \advance\@tempdimb by #2\relax +} + +\newcommand*\pIIe@omegai[1]{% + \@tempdimc\csname @ellipsin#1\endcsname\@ovro + \@tempdimc-\@tempdimc + \@tempdimd\csname @ellipcos#1\endcsname\@ovri +} + +\newcommand*\pIIe@ellip@kappa{% + \@ovyy\@ellipsinone\p@ + \@ovxx\@ellipcosone\p@ + \@tempdima\@ellipcostwo\@ovyy + \@tempdima-\@tempdima + \advance\@tempdima by \@ellipsintwo\@ovxx + \@tempdimb\@ellipcostwo\@ovxx + \advance\@tempdimb by \@ellipsintwo\@ovyy + \ifdim\@tempdima=\z@\relax + \edef\@ellipkappa{0}% + \else + \dimen@\dimexpr1pt - \@tempdimb\relax + \dimen@\dimexpr1pt * \dimen@/\@tempdima\relax + \pIIe@ellip@csqrt{2\p@}{1.73205\dimen@}{\dimen@}% + \advance\dimen@ by -\p@ + \divide\dimen@ by 3% + \edef\@tempa{\strip@pt\@tempdima}% + \dimen@\@tempa\dimen@ + \edef\@ellipkappa{\strip@pt\dimen@}% + \fi + %\typeout{ calculated kappa: \@ellipkappa}% +} + +\newcommand*\pIIe@elliparc@[5]{% + %\typeout{elliparc: #1, center: (#2, #3), radius (\the\@ovro, \the\@ovri),angle (#4, #5)}% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \pIIe@ellip@sincost{#4}{#5}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@t[5]{% + \ifcase #1\relax + \let\@ellip@startto\pIIe@lineto + \or \let\@ellip@startto\pIIe@moveto + \or \let\@ellip@startto\pIIe@noneto% + \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: % + must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}% + \fi + \ifdim\@ovro=\z@\relax\@ovri\z@\fi + \ifdim\@ovri=\z@\relax + \@ellip@startto{#2}{#3}% + \else + \CalculateSin{#4}\CalculateCos{#4}% + \edef\@ellipsinone{\UseSin{#4}}% + \edef\@ellipcosone{\UseCos{#4}}% + \CalculateSin{#5}\CalculateCos{#5}% + \edef\@ellipsintwo{\UseSin{#5}}% + \edef\@ellipcostwo{\UseCos{#5}}% + \pIIe@elliparc@draw{#2}{#3}% + \fi +} +\newcommand*\pIIe@elliparc@draw[2]{% + \pIIe@ellip@kappa% + \pIIe@omega{#1}{#2}{one}% + %\typeout{ point one: (\the\@tempdima,\the\@tempdimb)}% + \@ellip@startto\@tempdima\@tempdimb + \pIIe@omegai{one}% + \advance\@tempdima by \@ellipkappa\@tempdimc + \advance\@tempdimb by \@ellipkappa\@tempdimd + \pIIe@add@nums\@tempdima\@tempdimb + %\typeout{ control one: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@omega{#1}{#2}{two}% + \pIIe@omegai{two}% + \@tempdimc\@ellipkappa\@tempdimc + \@tempdimd\@ellipkappa\@tempdimd + \@tempdimc-\@tempdimc + \@tempdimd-\@tempdimd + \advance\@tempdimc by \@tempdima + \advance\@tempdimd by \@tempdimb + \pIIe@add@nums\@tempdimc\@tempdimd + %\typeout{ control two: (\the\@tempdimc,\the\@tempdimd)}% + \pIIe@add@CP\@tempdima\@tempdimb + %\typeout{ point two: (\the\@tempdima,\the\@tempdimb)}% + \pIIe@addtoGraph\pIIe@curveto@op +} +\newcommand*\pIIe@elliparc[7][0]{% + \@ovro #4\relax + \@ovri #5\relax + \iffalse%dim\@ovro=\@ovri + \pIIe@arc[#1]{#2}{#3}{#4}{#6}{#7} + \else + \ifdim \@ovro<\z@ \pIIe@badcircarg\else + \ifdim \@ovri<\z@ \pIIe@badcircarg\else + \@arclen #7\p@ \advance\@arclen -#6\p@ + \ifdim \@arclen<\z@ \def\@tempsign{-}\else\def\@tempsign{}\fi + \ifdim \@tempsign\@arclen>720\p@ + \PackageWarning {ellipse}{The arc angle is reduced to -720..720}% + \@whiledim \@tempsign\@arclen>720\p@ \do {\advance\@arclen-\@tempsign360\p@}% + \@tempdima #6\p@ \advance\@tempdima \@arclen + \edef\@angleend{\strip@pt\@tempdima}% + \pIIe@@elliparc{#1}{#2}{#3}{#6}{\@angleend}% + \else + \pIIe@@elliparc{#1}{#2}{#3}{#6}{#7}% + \fi + \fi + \fi + \fi +} +\newcommand*\pIIe@@elliparc[5]{% + \begingroup + \ifdim \@tempsign\@arclen>90\p@ + \divide\@arclen 2% + \@tempdima #4\p@\advance\@tempdima by \@arclen + \edef\@anglemid{\strip@pt\@tempdima}% + \def\@tempa{\pIIe@@elliparc{#1}{#2}{#3}{#4}}% + \expandafter\@tempa\expandafter{\@anglemid}% + \def\@tempa{\pIIe@@elliparc{2}{#2}{#3}}% + \expandafter\@tempa\expandafter{\@anglemid}{#5}% + \else + \pIIe@elliparc@{#1}{#2}{#3}{#4}{#5}% + \fi + \endgroup +}% + +\newcommand*\pIIeelliparc[7][0]{% + \@killglue + \pIIe@elliparc[#1]{#2\unitlength}{#3\unitlength}{#4\unitlength}{#5\unitlength}{#6}{#7}% + \ignorespaces% +} +\ifx\undefined\elliparc\else + \PackageWarning{ellipse}{\protect\elliparc\space is redefined}% +\fi +\let\elliparc\pIIeelliparc + +\newcommand*\pIIeearc + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\newcommand*\pIIe@earc@[3][0,360]{\pIIe@earc@@(#1){#2}{#3}} +\def\pIIe@earc@@(#1,#2)#3#4{% + \if@tempswa + \pIIe@moveto\z@\z@ + \pIIe@elliparc{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@closepath\pIIe@fillGraph + \else + \pIIe@elliparc[1]{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}% + \pIIe@strokeGraph + \fi} +\ifx\undefined\earc\else + \PackageWarning{ellipse}{\protect\earc\space is redefined}% +\fi +\let\earc\pIIeearc + +\newcommand*\pIIeellipse + {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}} +\let\ellipse\pIIeellipse + +\endinput +%% +%% End of file `ellipse.sty'. diff --git a/spec/v1.4.0/embedded-plus-single-remote-controller.png b/spec/v1.4.0/embedded-plus-single-remote-controller.png new file mode 100644 index 00000000..2e0f1803 Binary files /dev/null and b/spec/v1.4.0/embedded-plus-single-remote-controller.png differ diff --git a/spec/v1.4.0/embedded-plus-single-remote-controller.svg b/spec/v1.4.0/embedded-plus-single-remote-controller.svg new file mode 100644 index 00000000..9fe2ce9c --- /dev/null +++ b/spec/v1.4.0/embedded-plus-single-remote-controller.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0/embedded-plus-two-remote-controllers.png b/spec/v1.4.0/embedded-plus-two-remote-controllers.png new file mode 100644 index 00000000..b6dc04fc Binary files /dev/null and b/spec/v1.4.0/embedded-plus-two-remote-controllers.png differ diff --git a/spec/v1.4.0/embedded-plus-two-remote-controllers.svg b/spec/v1.4.0/embedded-plus-two-remote-controllers.svg new file mode 100644 index 00000000..0f97ba38 --- /dev/null +++ b/spec/v1.4.0/embedded-plus-two-remote-controllers.svg @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + + + Entities + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0/embedded-plus-two-remote-ha-controllers.png b/spec/v1.4.0/embedded-plus-two-remote-ha-controllers.png new file mode 100644 index 00000000..392f8963 Binary files /dev/null and b/spec/v1.4.0/embedded-plus-two-remote-ha-controllers.png differ diff --git a/spec/v1.4.0/embedded-plus-two-remote-ha-controllers.svg b/spec/v1.4.0/embedded-plus-two-remote-ha-controllers.svg new file mode 100644 index 00000000..97ab6fc3 --- /dev/null +++ b/spec/v1.4.0/embedded-plus-two-remote-ha-controllers.svg @@ -0,0 +1,511 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Server + + + + + + + + Instrumentation + + + + + + + + Platform Drivers + + + + + + P4 Target + + + + + + + + gRPC Client + + + + + + P4 EmbeddedController + + + + + + + + Entities + + + + + + + + Config + + + + + + + + + + + + + + P4Runtime + + + + + + P4 Pipeline + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #2 + + + + + + + + + + + + + + P4Runtime + + + + + + + + Entities + + + + + + + + + + + + + + + + + + + + + + + gRPC Client + + + + + + P4 RemoteController #1 + + + + + + + + + + + + + + Primary (Active) + + + + + + Backup (Standby) + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0/error-report.png b/spec/v1.4.0/error-report.png new file mode 100644 index 00000000..766cb77f Binary files /dev/null and b/spec/v1.4.0/error-report.png differ diff --git a/spec/v1.4.0/error-report.svg b/spec/v1.4.0/error-report.svg new file mode 100644 index 00000000..a2709a72 --- /dev/null +++ b/spec/v1.4.0/error-report.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StatusCode error_code_; // canonical error codestring error_message_;string binary_error_details_; // serialized google.rpc.Status + + + + + + + + + + + + + google.rpc.Status + + + + + + int32 error_code; // canonical error codestring message;repeated Any details; // P4Error + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + + + p4.Error + + + + + + p4.Error + + + + + + + + + + + + + + + + + + + + + + + + + + + int32 canonical_codestring message;string space;int32 code; // vendor-specific codeAny details; // reserved + + + + + + + + + + + + grpc::Status + + + + + + + \ No newline at end of file diff --git a/spec/v1.4.0/longbox.sty b/spec/v1.4.0/longbox.sty new file mode 100644 index 00000000..cab48934 --- /dev/null +++ b/spec/v1.4.0/longbox.sty @@ -0,0 +1,853 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longbox}[2015/12/01, Daan Leijen, Provides basic longbox that can break over pages] +\RequirePackage{options} + +\@ifclassloaded{beamer}{% + \newcommand\lb@savefootnotes{}% + \newcommand\lb@restorefootnotes{}% +}% +{\RequirePackage{footnote}% + \newcommand\lb@savefootnotes{\savenotes}% + \newcommand\lb@restorefootnotes{\spewnotes}% +} + + +% -------------------------------------------------------- +% Debugging +% -------------------------------------------------------- + +\newcommand*\lb@debug[1]{% + \ontoggle{lb@debug}{\typeout{longbox debug: #1}}% +} +\newcommand*\lb@typeout[1]{% + \ontoggle{lb@verbose}{\typeout{longbox: #1}}% +} +\newcommand*\lb@warncannotsplit{% + \PackageWarning{longbox}{Cannot split box; it seems you are using a non-splittable contents}% +} +\newcommand*\lb@warnbadsplit[1]{% + \PackageWarning{longbox}{Bad split (underful vbox by \the#1)}% +} + + +% -------------------------------------------------------- +% Utilities for LaTeX internals +% -------------------------------------------------------- + +% Suppress the indentation on the following paragraph +\providecommand\nofirstindent{\@afterindentfalse\@afterheading} + +% Suppress the paragraph skip on the following paragraph +\providecommand\nofirstparskip{\addvskip{-\parskip}} + +% In contrast to addvspace, addvskip is not suppressed in a minipage +\providecommand\addvskip[1]{% + \ifvmode + \ifdim\lastskip=\z@ + \vskip #1\relax + \else + \@tempskipb#1\relax\@xaddvskip + \fi + \else\@noitemerr\fi +} + + +% Skip to 0.3\baselineskip multiple taking prevdepth into account. +\newskip\lb@prevdepth +\newcommand\lb@skiptobaseline{% + \global\lb@prevdepth=-\@m\p@\relax + \ifvmode + \ifdim\lastskip=\z@\relax + \ifdim\prevdepth=-\@m\p@\else + \dimen@\prevdepth + % Calculate the modulus of the previous depth with 0.3|\baselineskip| in |\dimen@|. + \@tempcnta\prevdepth + \@tempskipa=0.3\baselineskip\relax + \@tempcntb=\@tempskipa\relax + \divide \@tempcnta by \@tempcntb + \dimen@\prevdepth + \advance\dimen@ -\@tempcnta\@tempskipa + % Skip back by that amount, and then skip by 0.3|\baselineskip|. + \vskip -\dimen@ + \vskip \@tempskipa\relax + \global\lb@prevdepth=\@tempskipa\relax + \fi + \fi + \fi +} + +% unvbox a box, and return a vbox with a given background color +% \unvcolorbox{}{} +\newcommand\unvcolorbox[2]{% + \ifoptionblank{#1}{\vbox{\unvbox#2}}{% + \lb@debug{vcolorbox: #1}% + \vbox{\offinterlineskip + \hbox to \z@{\vbox to \z@{\optioncolor{#1}\hrule\@width\wd#2\@height\ht#2\@depth\dp#2\vss}\hss}% + \unvbox#2% + }% + }% +} + +% create a vbox with a given background color +\newcommand\vcolorbox[2]{% + \eifblank{#1}{\vbox{#2}}{% + \setbox\z@=\vbox{#2}\relax + \unvcolorbox{#1}{\z@}% + }% +}% + +% -------------------------------------------------------- +% The following macros come from mdframed +% -------------------------------------------------------- + +% Determine the amount of free space left on the current page +\newlength\lb@freevspace +\newcommand*\lb@setfreevspace@page{% + \lb@debug{ determine free space}% + \bgroup\@nobreakfalse\addpenalty\z@\egroup% + \penalty\@M\relax\vskip 2\baselineskip\relax% + \penalty9999\relax\vskip -2\baselineskip\relax% + \penalty9999% + \ifdim\pagegoal=\maxdimen\relax% + \lb@freevspace=\vsize% + \else + \lb@freevspace=\dimexpr\pagegoal-\pagetotal-\parskip\relax% + \fi + \lb@debug{free space: \the\lb@freevspace, in page: \the\textheight, vsize=\the\vsize}% +} + +\newcommand*\lb@shiftdim[2]{% + %\letoption{#1}\lb@list + \expandafter\lb@setheadtail@#1,\relax + \eifblank{\lb@head}{}{\option@invoke{/longbox/@breakat-previous}{\lb@head}}% + #2\option{/longbox/@breakat-previous}% + \eifblank{\lb@tail}{}{\let#1\lb@tail}% push back tail +} +\def\lb@comma{,}% +\def\lb@setheadtail@#1,#2\relax{% + \def\lb@head{#1}% + \def\lb@tail{#2}% adds commas! +} + +\newcommand*\lb@setfreevspace{% + \eifblank{\lb@breakat}{\lb@setfreevspace@page}{% + \def\lb@eject{\par}%no eject + \lb@extrasplit=\z@\relax% + \lb@shiftdim{\lb@breakat}\lb@freevspace + \ifdim\lb@freevspace>\z@\else\lb@setfreevspace@page\fi + }% +} + + +% Suppress overfull-underfull vbox messages +\newcommand*\lb@ignorevbadness{% + \edef\lb@currentvbadness{\the\vbadness}% + \edef\lb@currentvfuzz{\the\vfuzz}% + \vbadness=\@M\relax% + \vfuzz=\maxdimen\relax% + \afterassignment\lb@restorevbadness +} +\newcommand*\lb@restorevbadness{% + \vbadness=\lb@currentvbadness\relax + \vfuzz=\lb@currentvfuzz\relax +} + + +% -------------------------------------------------------- +% The 'long vbox' (lvbox) environment collects long material +% into a long \vbox, instead of a \hbox like a lrbox in latex. +% The collected box can contain any box, minipage, lrbox, fbox etc, +% but not outer-par material like a figure. Footnotes can be +% dealt with useing lb@savefootnotes. +% +% The material is typeset in a \vbox according to a given width. +% inside the environment, the boolean 'inlvbox' is true. +% +% \begin{lvbox}{}{} +% -------------------------------------------------------- + +\newif\ifinlvbox +\newcommand\lvbox[4]{% + \setbox#1\vbox\bgroup + \begingroup + \inlvboxtrue + % reset defaults + \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\par\@@par + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + % set margin and linewidth + \leftmargin=#2\relax\rightmargin=#4\relax + \@totalleftmargin=\leftmargin% + %\leftskip=#2\relax\rightskip=#4\relax\@rightskip=#4\relax + \linewidth=#3\relax + % set primitive tex margins + \leftskip=\@totalleftmargin% + \rightskip=\rightmargin% + \@rightskip=\rightmargin% + \hsize=\dimexpr\@totalleftmargin+\linewidth+\rightmargin\relax + \columnwidth\hsize + \textwidth\hsize + \nofirstindent + %\nofirstparskip +} +\def\endlvbox{\endgroup\egroup} + + + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + + +\newsavebox\lb@headbox +\newsavebox\lb@savebox +\newsavebox\lb@mainbox + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@setbaseline[1]{% + %\typeout{ set baseline, \the\dp#1,\the\ht#1}% + \ifcase\lb@baseline% + \relax%bottom + \or%middle + \setbox#1=\vbox{\hbox{\lower \dimexpr(\dp#1 + \ht#1)/2 - \dp#1\relax\vbox{\unvbox#1}}}% + \or%top + \setbox#1=\vtop{\unvbox#1}% + \fi + %\typeout{ .new dim: \the\dp#1, \the\ht#1}% +} + + +\@ifundefined{define@key}{}% + {\define@key{longbox}{options}{\options{#1}\option{/longbox/adjust-options}}}% + +\newcommand*\lb@render@breakbox{% + %\typeout{render breakbox entry (in output routine), height=\the\bb@height}% + \bb@restorekeys{longbox}% + \lb@skiptop=\ifbb@isfirst\option{/longbox/skip-top}\else\option{/longbox/skip-break-top}\fi\relax + \lb@skipbottom=\ifbb@islast\option{/longbox/skip-bottom}\else\option{/longbox/skip-break-bottom}\fi\relax + \lb@skipbreaktop=\ifbb@isfirst 0pt\else\option{/longbox/skip-break-top}\fi + \lb@skipbreakbottom=\ifbb@islast 0pt\else\option{/longbox/skip-break-bottom}\fi + %\typeout{ render: skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom, break-top=\the\dimexpr\option{/longbox/skip-bottom}}% + \options{% + /longbox/@part-height=\bb@height + \lb@skipbreaktop + \lb@skipbreakbottom, + /longbox/@part-width=\option{/longbox/width} + \option{/longbox/skip-left} + \option{/longbox/skip-right},%\bb@width, + /longbox/@part-depth=0pt, + /longbox/@part-needtop=\ifbb@isfirst true\else false\fi, + /longbox/@part-needbottom=\ifbb@islast true\else false\fi, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-depth=\option{/longbox/@part-depth}, + }% + %\typeout{breakbox: width=\expandafter\the\option{/longbox/width}, \the\bb@width, \the\dimexpr\option{/longbox/@part-width}}% + \vbox{% + \kern -\lb@skipbreaktop% todo: move to breakbox? + \option{/longbox/render}% + \kern -\lb@skipbreakbottom + }% +} + +\newcommand*\lb@render@vbox[1]{% + \lb@debug{render vbox entry}% + \lb@restoreoptions + \lb@skiptop=\dimexpr\iftoggle{/longbox/@part-needtop}{\option{/longbox/skip-top}}{\option{/longbox/skip-break-top}}\relax + \lb@skipbottom=\dimexpr\iftoggle{/longbox/@part-needbottom}{\option{/longbox/skip-bottom}}{\option{/longbox/skip-break-bottom}}\relax + %\typeout{ skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom}% + % add top skip while maintaining the baseline. + \ifdim\lb@skiptop=\z@\relax\else + \setbox\z@=\vtop{\unvcopy#1}% + \dimen@=\ht\z@ + \setbox#1=\vbox{\offinterlineskip + \hrule width \z@ height \dimexpr\dimen@ + \lb@skiptop\relax depth -\dimen@ + \unvbox#1% + }% + \fi + % add bottom skip while maintaining the baseline. + \ifdim\lb@skipbottom=\z@\relax\else + \dimen@=\dp#1% + \setbox#1=\vbox{\offinterlineskip\unvbox#1\hrule width \z@ height -\dimen@ depth \dimexpr\dimen@ + \lb@skipbottom\relax}% + \fi + \lb@setbaseline{#1}% + \options{% + /longbox/@part-height=\dimexpr\ht#1 + \dp#1\relax, + /longbox/@part-width=\dimexpr\wd#1 + \option{/longbox/skip-left} + \option{/longbox/skip-right}\relax, + /longbox/@part-depth=\dp#1, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-depth=\option{/longbox/@part-depth} - \lb@skipbottom, + }% + %\typeout{ longbox: height=\the\dimexpr\option{/longbox/@content-box-height}, outer height=\the\dimexpr\option{/longbox/@part-height}\relax}% + % lower the box depending on vertical alignment + \ifcase\option{/longbox/vertical-align/@ord}\relax + \@tempdima\z@ + \or + %bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%middle + \@tempdima\dimexpr0.5\option{/longbox/@part-height} - \option{/longbox/@part-depth}\relax + \or%top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%text-bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%text-top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%super + \@tempdima=-0.9ex% + \or%sub + \@tempdima=0.7ex% + \else + \@tempdima\z@ + \fi + \advance\@tempdima by -\option{/longbox/raise}% + \option@invoke{/longbox/@lower}{\@tempdima}% + \noindent\hbox{\lower \@tempdima\vbox{\offinterlineskip + \hbox to \z@{% + \vbox to \z@{% + \hbox{\lower \option{/longbox/@part-height}\vbox{\offinterlineskip{\option{/longbox/render}}}}% + \vss}% + \hss + }% + \hbox{% + \ifdim\option{/longbox/skip-left}=\z@\else\hskip\option{/longbox/skip-left}\fi + \box#1% + \ifdim\option{/longbox/skip-right}=\z@\else\hskip\option{/longbox/skip-right}\fi + %$\box#1% + }% + }}% +} + +\newcommand*\lb@single@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} +\newcommand*\lb@first@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@middle@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@last@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand*\lb@env@start{% + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore +} + +\newcount\lb@usevbox +\newlength\lb@width +\newlength\lb@height +\newlength\lb@skiptop +\newlength\lb@skipright +\newlength\lb@skipbottom +\newlength\lb@skipleft +\newlength\lb@skipbreaktop +\newlength\lb@skipbreakbottom +\newlength\lb@outerwidth +\newlength\lb@extrasplit +\newcount\lb@textalign +\newcount\lb@baseline +\newtoggle{lb@baselineskip}% +\newtoggle{lb@breakable}% +\newtoggle{lb@debug}% +\newtoggle{lb@verbose}% +\def\lb@breakat{}% +\def\lb@halign{}% +\def\lb@eject{}% +\def\lb@insertafter{} +\def\lb@insertbefore{} + +\newcommand*\lb@peekoptions[1]{% + % process options inside a group and just set necessary parameters + % this way, nested boxes don't influence each other's parameters + \begingroup + \options{#1}% + \option{/longbox/adjust-options}% + \protected@edef\lb@temp{\endgroup + \lb@width=\the\dimexpr\option{/longbox/width}\relax + \lb@height=\the\dimexpr\option{/longbox/height}\relax + \lb@textalign=\the\numexpr\option{/longbox/text-align/@ord}\relax + \lb@baseline=\the\numexpr\option{/longbox/baseline/@ord}\relax + \lb@skiptop=\the\dimexpr\option{/longbox/skip-top}\relax + \lb@skipright=\the\dimexpr\option{/longbox/skip-right}\relax + \lb@skipbottom=\the\dimexpr\option{/longbox/skip-bottom}\relax + \lb@skipleft=\the\dimexpr\option{/longbox/skip-left}\relax + \lb@skipbreaktop=\the\dimexpr\option{/longbox/skip-break-top}\relax + \lb@skipbreakbottom=\the\dimexpr\option{/longbox/skip-break-bottom}\relax + \lb@usevbox=\iftoggle{/longbox/use-vbox}{1}{0}\relax + \lb@outerwidth=\the\dimexpr\option{/longbox/outer-width}\relax + \lb@extrasplit=\the\dimexpr\option{/longbox/split-minimum}\relax + \def\noexpand\lb@insertafter{\option{/longbox/insert-after}}% + \def\noexpand\lb@insertbefore{\option{/longbox/insert-before}}% + \def\noexpand\lb@breakat{\option{/longbox/breakat}}% + \def\noexpand\lb@halign{\option{/longbox/height-align}}% + \def\noexpand\lb@eject{\option{/longbox/eject}}% + \noexpand\csname toggle\iftoggle{/longbox/baseline-skip}{true}{false}\endcsname{lb@baselineskip}% + \noexpand\csname toggle\iftoggle{/longbox/breakable}{true}{false}\endcsname{lb@breakable}% + \noexpand\csname toggle\iftoggle{/longbox/debug}{true}{false}\endcsname{lb@debug}% + \noexpand\csname toggle\iftoggle{/longbox/verbose}{true}{false}\endcsname{lb@verbose}% + }% + \lb@temp +} + +\newenvironment{longbox@env}[2]{% + % save options + \lb@peekoptions{#1,#2}% + % + \ifnum\lb@usevbox=0\relax + \lb@debug{start breakbox}% + \let\bb@render\lb@render@breakbox + \bb@savekeys{longbox}{options={#1,#2,outer-width=\the\lb@outerwidth}}% + \iftoggle{lb@baselineskip}{\typeout{**insert bskip}}{\typeout{**suppress bskip}\vskip 1pt}% + \begin{breakbox}% + \ifdim\lb@skiptop=\z@\relax\else\vspace{\lb@skiptop}\fi% + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \begin{bb@margins}{\lb@skipleft}{\dimen@}% + \else + \lb@debug{start vbox}% + \def\lb@restoreoptions{\options{#1,#2}\option{/longbox/adjust-options}}% + \lb@savefootnotes + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \lb@debug{ width=\the\lb@width, linewidth=\the\linewidth, skipleft=\the\lb@skipleft, right=\the\lb@skipright, total right=\the\dimen@}% + \iftoggle{lb@baselineskip}{\lb@skiptobaseline}{\lb@prevdepth=-\@m pt}% + \lvbox{\lb@mainbox}{0pt}{\lb@width}{0pt}%{\lb@skipleft}{\lb@width}{\lb@skipright}% + \prevdepth=\lb@prevdepth + \fi + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore + \begingroup +}{% + \par\unskip + \endgroup + \lb@insertafter + %\ifdim\lb@skipbottom=\z@\relax\else\vskip\lb@skipbottom\fi% + \ifnum\lb@usevbox=0\relax + \end{bb@margins}% + \ifdim\lb@skipbottom=\z@\relax\else\hrule width \z@ height \lb@skipbottom\fi%\vspace{\lb@skipbottom}\fi% + \iftoggle{lb@baselineskip}{}{\vskip 1sp}% + \end{breakbox}% + \lb@debug{end breakbox}% + \else + \ontoggle{lb@baselineskip}{\lb@skiptobaseline}% + \endlvbox% + \lb@debug{initial lvbox: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@processbox + %\setbox\lb@mainbox=\hbox{\lower \lb@skipbottom\vbox{\offinterlineskip\unvbox\lb@mainbox}}% + \lb@restorefootnotes + \lb@debug{end vbox}% + \fi +} + +\newcommand\longbox@cmd[3]{% + \begingroup + %\options{/options/collectunknown,/longbox/scoped,#2}% set scoped options first + %\option{/longbox/scoped/@adjust-options}% + \lb@peekoptions{#1,#2}% + \leavevmode + %\setbox\lb@mainbox=\hbox{% + % \begingroup + % #3% + % \endgroup + %}% + \setbox\lb@mainbox=\hbox{% + \begingroup + \ifcase\lb@textalign\relax + %default=left + \or%left + \or\hss%center + \or\hss%right + \else%justify + \fi + \lb@insertbefore + #3% + \lb@insertafter + \ifnum\lb@textalign<3\relax\hss\fi% default,left,center + \endgroup + }% + \options{#1,#2}% + \ifdim\option{/longbox/width}=-1sp\relax + \options{/longbox/width=\wd\lb@mainbox}%set to natural width + \fi + \option{/longbox/adjust-options}% + % make it a vbox + \setbox\lb@mainbox=\vbox{\offinterlineskip% + \hbox to \option{/longbox/width}{% + \unhbox\lb@mainbox + }% + }% + \def\lb@restoreoptions{}% + \letoption{/longbox/height-align}\lb@halign + \lb@height=\option{/longbox/height}\relax + \lb@baseline=\option{/longbox/baseline/@ord}\relax + \lb@processbox + \endgroup +} + +\newcommand\lb@processbox{% + \ifdim\lb@height<0pt\relax + \lb@setbaseline{\lb@mainbox}% + \else + \lb@restrictheight + \fi + \lb@typesetbox +} + +\newcommand\lb@typesetbox{% + \ifinlvbox + \iftoggle{lb@breakable}{% + %\lb@debug{disable breakable due to nesting of long-boxes}% + \togglefalse{lb@breakable}% + }{}% + \fi + \ifhmode\lb@single@{\lb@mainbox}\else\lb@typeset\fi +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@restrictheight{% + \lb@typeout{restrict height to \the\lb@height}% + \lb@splitheight=\lb@height% + %lb@debug{before height split: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + %split failed.. do nothing + \lb@debug{could not restrict height}% + \else + % store splitted off content in the mainbox (and discard the rest) + \setbox\lb@mainbox\vbox{\unvbox\lb@headbox}% + \lb@debug{restricted height to \the\ht\lb@mainbox}% + \fi + % set baseline + \lb@setbaseline{\lb@mainbox}% + % height align + %\letoption{/longbox/height-align}\lb@halign + \eifstrequal{\lb@halign}{bottom}% + {\setbox\lb@mainbox=\vbox{\hbox{\vbox to \lb@splitheight{\vss\unvbox\lb@mainbox}}}}% + {\eifstrequal{\lb@halign}{middle}% + {\dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\hbox{% + \lower \dimexpr0.5\dimen@ + \dp\lb@mainbox\relax% + \vbox to \lb@splitheight{\vss\unvbox\lb@mainbox\vss}}}}% + {% default is top + \dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\vtop to \lb@splitheight{\box\lb@mainbox\vss}}% + }% + }% +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newlength\lb@neededvspace +\newcommand\lb@typeset[1][0pt]{% + \iftoggle{lb@breakable}{% + \lb@setfreevspace + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skiptop+\lb@skipbottom\relax}% + \lb@debug{needed: \the\lb@neededvspace, available: \the\lb@freevspace}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@single@{\lb@mainbox}% + \else + \lb@typeout{longbox needs splitting}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skiptop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \ifdim\dimexpr\lb@freevspace + #1\relax<\textheight\relax % test if we were at a fresh page.. (and prevent infinite recursion) + \lb@debug{failed to split the box, inserting a page break}% + \hrule \@height\z@ \@width\hsize + \lb@eject% + \lb@typeset[\textheight]% try again, but pass \textheight to guard against infinite recursion + \else + % on a fresh page we should not fail anymore.. just output as is.. + % lb@warncannotsplit + \lb@single@{\lb@mainbox}% + \fi + \else + % first part success + \lb@typeout{first part splitted}% + \lb@first@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest + \fi + \fi + }{%\else + \lb@debug{unbreakable box}% + \lb@single@{\lb@mainbox}% always directly output an unbreakable box + }% +} + +\newcommand\lb@typesetrest{% + \lb@setfreevspace% + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skipbottom+\lb@skipbreaktop\relax}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@typeout{output last part of box}% + \lb@last@{\lb@mainbox}% + \else + \lb@debug{split box further}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skipbreaktop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \lb@typeout{failed to split box!}% + \lb@last@{\lb@mainbox}% + \else + % middle part success + \lb@typeout{output middle part of box}% + \lb@middle@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest% continue the iteration... + \fi + \fi +} + +% -------------------------------------------------------- +% Split a long vbox over multiple pages. +% This code is based on similar code in the mdframed package +% -------------------------------------------------------- + +\newlength\lb@splitheight +\newlength\lb@insurance % tiny extra space to ensure our box will really fit +\setlength\lb@insurance{1pt} + +% expects split target height in lb@splitheight, and splits off the start of lb@mainbox to lb@headbox +\newcommand\lb@splitbox{% + \ifdim\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax>\lb@splitheight\relax + % the main box is larger than our target split height.. + \ifdim\lb@extrasplit>\lb@splitheight\relax + % not enough space to bother + \lb@typeout{not enough space on page for a split}% + \setbox\lb@headbox=\vbox{}% empty head + \else + % try a split; lower the split height a bit so we are sure to fit + \advance\lb@splitheight -\lb@insurance\relax + \lb@debug{split: \the\lb@splitheight, from \the\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax}% + \setbox\lb@savebox=\vbox{\unvcopy\lb@mainbox}% save original + \lb@trysplit{\lb@splitheight}% + \ifdim\dimexpr\ht\lb@headbox + \dp\lb@headbox>\lb@splitheight\relax + % too big, bad split. Try other splits.. iterate N times with 1 or 5pt less before giving up + \dimen@=\lb@splitheight\relax + \@tempcnta=\z@\relax + \loop + \ifdim\dimexpr\ht\lb@headbox+\dp\lb@headbox\relax>\lb@splitheight\relax + \ifnum\@tempcnta<50% + \advance\dimen@ by -\p@\relax% try a slightly smaller height.. + \else + \advance\dimen@ by -5\p@\relax% try larger increase after 50pt.. + \fi + \advance\@tempcnta by \@ne\relax + \lb@ignorevbadness + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \lb@trysplit{\dimen@}% + \ifdim\lb@extrasplit<\dimen@\relax\else\lb@splitstop\fi % don't try to split too small + \ifnum\@tempcnta<100\relax\else\lb@splitstop\fi % and not more than N attempts + \repeat% + \ifnum\@tempcnta<100\relax + \dimen@=\dimexpr\lb@splitheight - \ht\lb@headbox - \dp\lb@headbox\relax + \ifdim\dimen@>\option{/longbox/split-badness}\relax + \lb@warnbadsplit{\dimen@}% + \fi + \fi + \fi + \fi + \else + % mainbox fits in our target lb@splitheight + \setbox\lb@headbox=\vbox{\unvbox\lb@mainbox}% + \setbox\lb@mainbox=\vbox{}% + \fi +} + +\newcommand\lb@splitstop{% + \lb@typeout{cannot find a good split}% + \let\iterate\relax + \lb@warncannotsplit + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \setbox\lb@headbox=\vbox{}% empty head + \@tempcnta=\@M\relax +} + +\newcommand\lb@trysplit[1]{% try to split at given height + \lb@typeout{try to split at: \the\dimexpr #1\relax}% + \lb@ignorevbadness + \setbox\lb@headbox=\vsplit\lb@mainbox to #1\relax% + \setbox\lb@headbox=\vbox{\unvbox\lb@headbox}% + \setbox\lb@mainbox=\vbox{\unvbox\lb@mainbox}% +} + +% -------------------------------------------------------- +% The longbox environment uses options to set its options +% -------------------------------------------------------- + + +% keys and styles that can be set once globally +\options{% + /longbox/.new family, +}% + +\options{/longbox,% + % computed + @part-needtop/.new toggle, + @part-needbottom/.new toggle, + @part-height/.new length, + @part-width/.new length, + @part-depth/.new length, + @content-box-height/.new length, + @content-box-width/.new length, + @content-box-depth/.new length, + @breakat-previous/.new length, + @lower/.new length, + % + debug/.new toggle, + verbose/.new toggle, + render/.new value =\lb@render@fbox, + adjust-options/.new value = {\longbox@adjustoptions}, + eject/.new value = {\protect\vfill\protect\eject}, + use-vbox/.new toggle = true, + split-minimum/.new length = {1.5\baselineskip}, + split-badness/.new length = \baselineskip, + % + height-align/.new choice= {top,middle,bottom}, + baseline/.new choice = {bottom,middle,top}, + text-align/.new choice = {default,left,center,right,justify}, + vertical-align/.new choice = {baseline,bottom,middle,top,text-bottom,text-top,super,sub}, + raise/.new length = {0pt}, + baseline-skip/.new toggle =true, + % + height/.new length = -1sp, + width/.new length = -1sp, + outer-height/.new length= -1sp, + outer-width/.new length = -1sp, + insert-before/.new value= {}, + insert-after/.new value = {}, + breakat/.new value = {}, + breakable/.new toggle = false, + skip/.new style = {skip-top=#1,skip-right=#1,skip-bottom=#1,skip-left=#1}, + skip-top/.new length, + skip-right/.new length, + skip-bottom/.new length, + skip-left/.new length, + skip-break-bottom/.new length, + skip-break-top/.new length, +} + +\newcommand\longbox@adjustoptions{% + %\typeout{ standard longbox adjustoptions}% + \lb@debug{ current width=\the\dimexpr\option{/longbox/width}, outer=\the\dimexpr\option{/longbox/outer-width}, linewidth=\the\linewidth}% + \ontoggle{/longbox/debug}{\option@invoke{/longbox/verbose}{true}}% + % adjust height + \ifdim\option{/longbox/height}=-1sp\relax + \ifdim\option{/longbox/outer-height}=-1sp\else + \option@invoke{/longbox/height}% + {\option{/longbox/outer-height}-\option{/longbox/skip-top}-\option{/longbox/skip-bottom}}% + \fi + \fi + % set width + \ifdim\option{/longbox/width}=-1sp\relax + \ifdim\option{/longbox/outer-width}=-1sp\relax + \option@invoke{/longbox/outer-width}{\linewidth}% + \fi + \dimen@=\dimexpr\option{/longbox/outer-width}-\option{/longbox/skip-left}-\option{/longbox/skip-right}\relax + \ifdim\dimen@<\z@\relax\dimen@=\z@\fi + \option@invoke{/longbox/width}{\dimen@}% + \fi + % use a breakbox whenever we are in external vertical mode and not width or height restricted. + \iftoggle{/longbox/use-vbox}{}{% + \ifinner\toggletrue{/longbox/use-vbox}\else + \ifhmode\toggletrue{/longbox/use-vbox}\else + \ifdim\option{/longbox/height}>-1sp\toggletrue{/longbox/use-vbox}\else + \iftoggle{/longbox/breakable}{}{\toggletrue{/longbox/use-vbox}}% + \ifoptionblank{/longbox/breakat}{}{\toggletrue{/longbox/use-vbox}}% + \fi\fi\fi + }% +} + +\newenvironment{longbox}[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \begin{longbox@env}{/longbox}{#1}% +}{\end{longbox@env}} + +\newcommand\lbox[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \longbox@cmd{/longbox}{#1}% +} + +\newcommand*\lb@render@fbox{% + %\typeout{render defaultbox: bgcolor=\bb@bgcolor, needtop=\iftoggle{/longbox/@part-needtop}{true}{false}}% + \@ovdx=\dimexpr\option{/longbox/@part-width} - 2\fboxrule\relax% + \@ovdy=\dimexpr\option{/longbox/@part-height}\relax% + \iftoggle{/longbox/@part-needbottom}% + {\@tempdima=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdima=\dimexpr\fboxrule + \bb@stickout\relax + \advance\bb@height by \@tempdima + \advance\@ovdy by \@tempdima}% + \iftoggle{/longbox/@part-needtop}% + {\@tempdimb=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdimb=\dimexpr\bb@stickout\relax + \advance\bb@height by \@tempdimb + \advance\@ovdy by \@tempdimb}% + % + \hbox{\lower \@tempdima\vbox{% + \vskip -\@tempdimb + \ontoggle{/longbox/@part-needtop}{\lb@debug{toprule wd=\expandafter\the\option{/longbox/width}}\hrule width \option{/longbox/@part-width} height \fboxrule}% + \hbox{% + \vrule width \fboxrule height \@ovdy% + \ifx\bb@bgcolor\@empty + \vrule width \@ovdx height \z@\relax + \else + {\color{\bb@bgcolor}\vrule width \@ovdx height \@ovdy}% + \fi + \vrule width \fboxrule height \@ovdy% + }% + \ontoggle{/longbox/@part-needbottom}{\hrule width \option{/longbox/@part-width} height \fboxrule}% + }}% +} \ No newline at end of file diff --git a/spec/v1.4.0/longfbox.sty b/spec/v1.4.0/longfbox.sty new file mode 100644 index 00000000..0df01331 --- /dev/null +++ b/spec/v1.4.0/longfbox.sty @@ -0,0 +1,1344 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longfbox}[2015/12/01, Daan Leijen, Provides long fbox that can break over pages] + +\RequirePackage{options} +\RequirePackage{longbox} +\RequirePackage{pict2e} +\RequirePackage{ellipse} + +% -------------------------------------------------------- +% Dimension calulations +% -------------------------------------------------------- + +% dimmin/dimmax return minimum or maximum dimension +\providecommand\dim@min[2]{\ifdim#1>#2#2\else #1\fi} +\providecommand\dim@max[2]{\ifdim#1>#2#1\else #2\fi} + +\newcommand*\option@dimmin[2]{\dim@min{\option{#1}}{\option{#2}}} +\newcommand*\option@dimmax[2]{\dim@max{\option{#1}}{\option{#2}}} + + +% -------------------------------------------------------- +% Add a new 'sides' option type +% -------------------------------------------------------- + +\options{ + /handlers/new sides/.new handler = []{ + \ifblank{#2}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#1-top={##1}, #1-right={##2}, #1-bottom={##3}, #1-left={##4}}}}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#2}}}% + \optionsalso{ + #1/.new cmdx = {##1,##2,##3,##4,##5\relax}{,,,,\relax}{% + \ifblank{##2##3##4}{\option{#1/@cmd@sides}{##1}{##1}{##1}{##1}}% + {\ifblank{##3##4}{\option{#1/@cmd@sides}{##1}{##2}{##1}{##2}}% + {\ifblank{##4}{\option{#1/@cmd@sides}{##1}{##2}{##3}{##2}}% + {\option{#1/@cmd@sides}{##1}{##2}{##3}{##4}}% + }% + }% + }, + #1/.type = sides, + }% + },% +} + +\newcommand*\optionlengthlimit[3]{% len, min, max + \letoption{#1}\opt@temp + \ifdim\opt@temp<\dimexpr#2\relax + \option@invoke{#1}{#2}% + \else\ifdim\opt@temp>\dimexpr#3\relax + \option@invoke{#1}{#3}% + \fi\fi +} + +\newcommand*\optionradiuslimit[4]{% r1, r2, min, max + \letoption{#1}\opt@tempa + \letoption{#2}\opt@tempb + \ifdim\opt@tempa<\dimexpr#3\relax\option@invoke{#1}{#3}\fi + \ifdim\opt@tempb<\dimexpr#3\relax\option@invoke{#2}{#3}\fi + \ifdim\dimexpr\opt@tempa + \opt@tempb\relax=\z@\relax\else + \ifdim\dimexpr\opt@tempa+\opt@tempb\relax>\dimexpr#4\relax + \edef\opt@perc{\the\numexpr(\number\dimexpr#4\relax)/% + (\number\dimexpr(\opt@tempa+\opt@tempb)/100\relax)}% + %\typeout{scale:\the\opt@tempa,\the\opt@tempb, by \opt@perc percent to make \the\dimexpr#4\relax}% + \edef\opt@temp{\dimexpr\opt@perc\dimexpr\the\opt@tempa\relax / 100\relax}% + \option@einvoke{#1}{\opt@temp}% + \option@einvoke{#2}{\dimexpr#4 - \opt@temp\relax}% + %\typeout{ scaled to: \the\opt@temp,\the\dimexpr#4 - \opt@temp\relax}% + \fi + \fi +} + + +% \begin{macro}{\trig@atantan} +% \marg{a}\marg{b}\marg{$\alpha$}{dimen$_\mathit{reg}$}\\ +% Assigns $\atan_2(\frac{\sin(\alpha)}{b},\frac{\cos(\alpha)}{a})$ to dimension register \textit{dimen$_\mathit{reg}$}, +% where $a$ and $b$ are dimensions. +% Returns $\alpha$ when $a = b$, or when $a=0$ or $b=0$. +% \begin{macrocode} +\newcommand*\trig@atantan[4]{% + %\typeout{ atantan:(\the#1,\the#2,\the#3, #4)}% + \@tempdima\dimexpr#1\relax + \@tempdimb\dimexpr#2\relax +% \end{macrocode} +% If $a = b$, we have a circle and the result is $\alpha$. +% \begin{macrocode} + \ifdim\@tempdima=\@tempdimb + #4\dimexpr#3\relax + \else\ifdim\@tempdima=\z@ + #4\dimexpr#3\relax + \else\ifdim\@tempdimb=\z@ + #4\dimexpr#3\relax + \else + \edef\trig@temp{\strip@pt\dimexpr#3\relax}% + \CalculateSin{\trig@temp}\CalculateCos{\trig@temp}% + \@tempdimc\dimexpr1\p@ * \dimexpr\UseSin{\trig@temp}\p@\relax/\@tempdimb\relax + \@tempdimd\dimexpr1\p@ * \dimexpr\UseCos{\trig@temp}\p@\relax/\@tempdima\relax + \pIIe@atantwo{\@tempdimc}{\@tempdimd}\dimen@ + \ifdim\dimen@<\z@ + \ifdim\dimexpr#3\relax<\z@\else\advance\dimen@360\p@\fi + \fi + \@tempdima\dimexpr#3 - \dimen@\relax + \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi + \ifdim\@tempdima<360\p@\else\advance\dimen@360\p@\fi + %\typeout{atan: \the\dimexpr#3\relax versus. \the\dimen@ }% + #4\dimen@ + \fi\fi\fi +} +% \end{macrocode} +% \end{macro} + +% rough approximation of the perimeter; +% if |radius-x == radius-y| = 0 (a circle), the approximation is precise. +% otherwise, works best when |angle2-angle1| <= 45 and gets worse from there on. +\newcommand*\ellip@letarcperimeter[5]{% 'radius-x', 'radius-y', 'angle-1', 'angle-2', '\result' + \@tempdima\dimexpr#3\relax + \@tempdimb\dimexpr#4\relax + \@tempdimc\dimexpr\@tempdima - \@tempdimb\relax + \ifdim\@tempdimc<\z@\@tempdimc-\@tempdimc\fi + \ifdim#1=#2\relax% circle? + \edef\@tempa{\strip@pt\@tempdimc}% angle difference delta as factor + \dimen@\@tempa\dimexpr#1\relax% r*delta + \dimen@0.017453\dimen@% (2*pi/360) * r * delta = 2*pi*r * (delta/360) + \else% ellipse: take the distance between the points on the ellipse, works pretty good if delta <= 45, and ok'ish for delta <= 90 + \@ovro\dimexpr#1\relax + \@ovri\dimexpr#2\relax + \edef\fbox@tempa{\strip@pt\@tempdima}% + \edef\fbox@tempb{\strip@pt\@tempdimb}% + \pIIe@ellip@sincost{\fbox@tempa}{\fbox@tempb}% + \@tempdima\@ellipcosone\@ovro + \@tempdimb\@ellipsinone\@ovri + \@tempdimc\@ellipcostwo\@ovro + \@tempdimd\@ellipsintwo\@ovri + \advance\@tempdimc by -\@tempdima% + \advance\@tempdimd by -\@tempdimb% + \pIIe@ellip@csqrt{\@tempdimc}{\@tempdimd}{\dimen@}% + %\typeout{ distance: \the\dimen@, from (x,y)=(\the\@tempdimc,\the\@tempdimd), radii=(\the#1,\the#2), angles=(\the#3,\the#4)}% + \fi + \edef#5{\the\dimen@}% +} + + +% ------------------------------------------------------------------------------ +% Borders using the picture environment +% ------------------------------------------------------------------------------ + +\newcommand*\fbox@border@pict{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \begingroup + \hbox{% + \unitlength\p@ + \begin{picture}(0,0)(0,\optionunit{/fbox/@border-box-height})% bottom-left is origin + % markers + \ontoggle{/fbox/show-markers}{% + \linethickness{\option{/fbox/marker-width}}% + \optioncolor{/fbox/marker-color}% + \fbox@rect{0pt}{0pt}{\option{/fbox/@border-box-width}}{\option{/fbox/@border-box-height}}% + \fbox@rect{\option{/fbox/border-left-width}}{\option{/fbox/border-\fbox@bottom-width}}% + {\option{/fbox/@border-box-width}-\option{/fbox/border-right-width}}% + {\option{/fbox/@border-box-height}-\option{/fbox/border-\fbox@top-width}}%S + }% + %compute corner coordinates + \fbox@border@calccorners + %put down the background color + \fbox@border@colorbackground + \option{/fbox/picture-insert-before}% + %put down the sides + \fbox@border@side{3}{-2}{0}%top + \fbox@border@side{5}{-4}{3}%left + \fbox@border@side{-6}{7}{2}%bottom + \fbox@border@side{-8}{1}{1}%right + \end{picture}% + }% + \endgroup + \fi +} + +\newcommand*\fbox@border@pict@after{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \letoption{/fbox/picture-insert-after}\fbox@insertafter + \eifblank{\fbox@insertafter}{}{% + \begingroup + \hbox{% + \begin{picture}(0,0)(0,0)% bottom-left is origin + \fbox@insertafter + \end{picture}% + }% + \endgroup + }% + \fi +} + +\newcommand*\fbox@border@side[3]{% + \fbox@setoct@angles{#1}% + \edef\fbox@style{\option{/fbox/border-\fbox@side-style}}% + \optioncolor{/fbox/border-\fbox@side-color}% + \option{/fbox/picture-side-insert-before}% + \ifcsdef{fbox@border@pict@\fbox@style}% + {\csuse{fbox@border@pict@\fbox@style}{#1}{#2}{#3}}% + {\PackageWarning{longfbox}{Unknown style "\fbox@style". Using "solid" instead.}% + \fbox@border@pict@solid{#1}{#2}{#3}}% + \option{/fbox/picture-side-insert-after}% +} + +% ------------------------------------------------------------------------------ +% Define standard border styles for the picture environment +% +% a style has the form \fbox@border@pict@